X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/7dcc10b65e0075fccc90d93bac5b078baefdbb07..d334281c802bc94e99475557ed341d356af0ab54:/src/db.c diff --git a/src/db.c b/src/db.c index dc9ca8c5..f7d93e08 100644 --- a/src/db.c +++ b/src/db.c @@ -40,7 +40,7 @@ robj *lookupKey(redisDb *db, robj *key) { /* Update the access time for the aging algorithm. * Don't do it if we have a saving child, as this will trigger * a copy on write madness. */ - if (server.bgsavechildpid == -1 && server.bgrewritechildpid == -1) + if (server.rdb_child_pid == -1 && server.aof_child_pid == -1) val->lru = server.lruclock; server.stat_keyspace_hits++; return val; @@ -210,15 +210,15 @@ void flushallCommand(redisClient *c) { signalFlushedDb(-1); server.dirty += emptyDb(); addReply(c,shared.ok); - if (server.bgsavechildpid != -1) { - kill(server.bgsavechildpid,SIGKILL); - rdbRemoveTempFile(server.bgsavechildpid); + if (server.rdb_child_pid != -1) { + kill(server.rdb_child_pid,SIGKILL); + rdbRemoveTempFile(server.rdb_child_pid); } if (server.saveparamslen > 0) { /* Normally rdbSave() will reset dirty, but we don't want this here * as otherwise FLUSHALL will not be replicated nor put into the AOF. */ int saved_dirty = server.dirty; - rdbSave(server.dbfilename); + rdbSave(server.rdb_filename); server.dirty = saved_dirty; } server.dirty++; @@ -328,8 +328,22 @@ void typeCommand(redisClient *c) { } void shutdownCommand(redisClient *c) { - if (prepareForShutdown() == REDIS_OK) - exit(0); + int flags = 0; + + if (c->argc > 2) { + addReply(c,shared.syntaxerr); + return; + } else if (c->argc == 2) { + if (!strcasecmp(c->argv[1]->ptr,"nosave")) { + flags |= REDIS_SHUTDOWN_NOSAVE; + } else if (!strcasecmp(c->argv[1]->ptr,"save")) { + flags |= REDIS_SHUTDOWN_SAVE; + } else { + addReply(c,shared.syntaxerr); + return; + } + } + if (prepareForShutdown(flags) == REDIS_OK) exit(0); addReplyError(c,"Errors trying to SHUTDOWN. Check logs."); } @@ -473,7 +487,7 @@ void propagateExpire(redisDb *db, robj *key) { argv[1] = key; incrRefCount(key); - if (server.appendonly) + if (server.aof_state != REDIS_AOF_OFF) feedAppendOnlyFile(server.delCommand,db->id,argv,2); if (listLength(server.slaves)) replicationFeedSlaves(server.slaves,db->id,argv,2); @@ -514,27 +528,23 @@ int expireIfNeeded(redisDb *db, robj *key) { * Expires Commands *----------------------------------------------------------------------------*/ -void expireGenericCommand(redisClient *c, long long offset) { +/* 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, int unit) { dictEntry *de; robj *key = c->argv[1], *param = c->argv[2]; long long milliseconds; - int time_in_seconds = 1; if (getLongLongFromObjectOrReply(c, param, &milliseconds, NULL) != REDIS_OK) return; - /* 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]) { - addReply(c,shared.syntaxerr); - return; - } - time_in_seconds = 0; /* "ms" argument passed. */ - } - if (time_in_seconds) milliseconds *= 1000; + if (unit == UNIT_SECONDS) milliseconds *= 1000; milliseconds -= offset; de = dictFind(c->db->dict,key->ptr); @@ -572,14 +582,22 @@ void expireGenericCommand(redisClient *c, long long offset) { } void expireCommand(redisClient *c) { - expireGenericCommand(c,0); + expireGenericCommand(c,0,UNIT_SECONDS); } void expireatCommand(redisClient *c) { - expireGenericCommand(c,mstime()); + expireGenericCommand(c,mstime(),UNIT_SECONDS); } -void ttlCommand(redisClient *c) { +void pexpireCommand(redisClient *c) { + expireGenericCommand(c,0,UNIT_MILLISECONDS); +} + +void pexpireatCommand(redisClient *c) { + expireGenericCommand(c,mstime(),UNIT_MILLISECONDS); +} + +void ttlGenericCommand(redisClient *c, int output_ms) { long long expire, ttl = -1; expire = getExpire(c->db,c->argv[1]); @@ -590,10 +608,18 @@ void ttlCommand(redisClient *c) { if (ttl == -1) { addReplyLongLong(c,-1); } else { - addReplyLongLong(c,(ttl+500)/1000); + addReplyLongLong(c,output_ms ? ttl : ((ttl+500)/1000)); } } +void ttlCommand(redisClient *c) { + ttlGenericCommand(c, 0); +} + +void pttlCommand(redisClient *c) { + ttlGenericCommand(c, 1); +} + void persistCommand(redisClient *c) { dictEntry *de;