From 52d46855d90bfddb3e03d957c48101d123e4dfe7 Mon Sep 17 00:00:00 2001 From: antirez Date: Wed, 9 Nov 2011 18:05:35 +0100 Subject: [PATCH] TTL, EXPIRE and EXPIREAT now support the milliseconds input/output form --- src/db.c | 32 ++++++++++++++++++++++++++++---- src/redis.c | 6 +++--- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/db.c b/src/db.c index dc9ca8c53..755e295e5 100644 --- a/src/db.c +++ b/src/db.c @@ -514,6 +514,14 @@ int expireIfNeeded(redisDb *db, robj *key) { * Expires Commands *----------------------------------------------------------------------------*/ +/* Given an string object return true if it contains exactly the "ms" + * or "MS" string. This is used in order to check if the last argument + * of EXPIRE, EXPIREAT or TTL is "ms" to switch into millisecond input/output */ +int stringObjectEqualsMs(robj *a) { + char *arg = a->ptr; + return tolower(arg[0]) == 'm' && tolower(arg[1]) == 's' && arg[2] == '\0'; +} + void expireGenericCommand(redisClient *c, long long offset) { dictEntry *de; robj *key = c->argv[1], *param = c->argv[2]; @@ -526,9 +534,7 @@ void expireGenericCommand(redisClient *c, long long offset) { /* If no "ms" argument was passed the time is in second, so we need * to multilpy it by 1000 */ if (c->argc == 4) { - char *arg = c->argv[3]->ptr; - - if (tolower(arg[0]) != 'm' || tolower(arg[1]) != 's' || arg[2]) { + if (!stringObjectEqualsMs(c->argv[3])) { addReply(c,shared.syntaxerr); return; } @@ -572,15 +578,33 @@ void expireGenericCommand(redisClient *c, long long offset) { } void expireCommand(redisClient *c) { + if (c->argc > 4) { + addReply(c,shared.syntaxerr); + return; + } expireGenericCommand(c,0); } void expireatCommand(redisClient *c) { + if (c->argc > 4) { + addReply(c,shared.syntaxerr); + return; + } expireGenericCommand(c,mstime()); } void ttlCommand(redisClient *c) { long long expire, ttl = -1; + int output_ms = 0; + + if (c->argc == 3) { + if (stringObjectEqualsMs(c->argv[2])) { + output_ms = 1; + } else { + addReply(c,shared.syntaxerr); + return; + } + } expire = getExpire(c->db,c->argv[1]); if (expire != -1) { @@ -590,7 +614,7 @@ void ttlCommand(redisClient *c) { if (ttl == -1) { addReplyLongLong(c,-1); } else { - addReplyLongLong(c,(ttl+500)/1000); + addReplyLongLong(c,output_ms ? ttl : ((ttl+500)/1000)); } } diff --git a/src/redis.c b/src/redis.c index 7ccd823ac..b8853253d 100644 --- a/src/redis.c +++ b/src/redis.c @@ -172,8 +172,8 @@ struct redisCommand redisCommandTable[] = { {"move",moveCommand,3,"w",0,NULL,1,1,1,0,0}, {"rename",renameCommand,3,"w",0,renameGetKeys,1,2,1,0,0}, {"renamenx",renamenxCommand,3,"w",0,renameGetKeys,1,2,1,0,0}, - {"expire",expireCommand,3,"w",0,NULL,1,1,1,0,0}, - {"expireat",expireatCommand,3,"w",0,NULL,1,1,1,0,0}, + {"expire",expireCommand,-3,"w",0,NULL,1,1,1,0,0}, + {"expireat",expireatCommand,-3,"w",0,NULL,1,1,1,0,0}, {"keys",keysCommand,2,"r",0,NULL,0,0,0,0,0}, {"dbsize",dbsizeCommand,1,"r",0,NULL,0,0,0,0,0}, {"auth",authCommand,2,"r",0,NULL,0,0,0,0,0}, @@ -194,7 +194,7 @@ struct redisCommand redisCommandTable[] = { {"sort",sortCommand,-2,"wm",0,NULL,1,1,1,0,0}, {"info",infoCommand,-1,"r",0,NULL,0,0,0,0,0}, {"monitor",monitorCommand,1,"ars",0,NULL,0,0,0,0,0}, - {"ttl",ttlCommand,2,"r",0,NULL,1,1,1,0,0}, + {"ttl",ttlCommand,-2,"r",0,NULL,1,1,1,0,0}, {"persist",persistCommand,2,"w",0,NULL,1,1,1,0,0}, {"slaveof",slaveofCommand,3,"aws",0,NULL,0,0,0,0,0}, {"debug",debugCommand,-2,"aw",0,NULL,0,0,0,0,0}, -- GitLab