diff --git a/src/expire.cpp b/src/expire.cpp index 6b77a0192..2f7a0abc7 100644 --- a/src/expire.cpp +++ b/src/expire.cpp @@ -139,22 +139,8 @@ int parseUnitString(const char *sz) return -1; } -void expireMemberCommand(client *c) +void expireMemberCore(client *c, robj *key, robj *subkey, long long basetime, long long when, int unit) { - long long when; - if (getLongLongFromObjectOrReply(c, c->argv[3], &when, NULL) != C_OK) - return; - - if (c->argc > 5) { - addReplyError(c, "Invalid number of arguments"); - return; - } - - int unit = UNIT_SECONDS; - if (c->argc == 5) { - unit = parseUnitString(szFromObj(c->argv[4])); - } - switch (unit) { case UNIT_SECONDS: @@ -167,7 +153,7 @@ void expireMemberCommand(client *c) return; } - when += mstime(); + when += basetime; /* No key, return zero. */ dictEntry *de = dictFind(c->db->pdict, szFromObj(c->argv[1])); @@ -194,6 +180,35 @@ void expireMemberCommand(client *c) addReply(c, shared.ok); } +void expireMemberCommand(client *c) +{ + long long when; + if (getLongLongFromObjectOrReply(c, c->argv[3], &when, NULL) != C_OK) + return; + + if (c->argc > 5) { + addReplyError(c, "Invalid number of arguments"); + return; + } + + int unit = UNIT_SECONDS; + if (c->argc == 5) { + unit = parseUnitString(szFromObj(c->argv[4])); + } + + expireMemberCore(c, c->argv[1], c->argv[2], mstime(), when, unit); +} + +void expireMemberAtCommand(client *c) +{ + long long when; + if (getLongLongFromObjectOrReply(c, c->argv[3], &when, NULL) != C_OK) + return; + + expireMemberCore(c, c->argv[1], c->argv[2], 0, when, UNIT_SECONDS); +} + + /* Try to expire a few timed out keys. The algorithm used is adaptive and * will use few CPU cycles if there are few expiring keys, otherwise * it will get more aggressive to avoid that too much memory is used by diff --git a/src/help.h b/src/help.h index b41f6123b..34f4e77c7 100644 --- a/src/help.h +++ b/src/help.h @@ -346,6 +346,9 @@ struct commandHelp { { "EXPIREMEMBER", "key subkey delay [Unit: s,ms]", "set a subkey's time to live in seconds (or milliseconds)"}, + { "EXPIREMEMBERAT", + "key subkey timestamp", + "Set the expiration for a subkey as a UNIX timestamp"}, { "FLUSHALL", "[ASYNC]", "Remove all keys from all databases", diff --git a/src/server.cpp b/src/server.cpp index 0e5f1b8b5..b72d7e118 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -626,6 +626,10 @@ struct redisCommand redisCommandTable[] = { {"expiremember", expireMemberCommand, -4, "write fast @keyspace", 0,NULL,1,1,1,0,0,0}, + + {"expirememberat", expireMemberAtCommand, 4, + "write fast @keyspace", + 0,NULL,1,1,1,0,0,0}, {"pexpire",pexpireCommand,3, "write fast @keyspace", diff --git a/src/server.h b/src/server.h index 75648af7a..2f6dcd69a 100644 --- a/src/server.h +++ b/src/server.h @@ -2628,6 +2628,7 @@ void monitorCommand(client *c); void expireCommand(client *c); void expireatCommand(client *c); void expireMemberCommand(client *c); +void expireMemberAtCommand(client *c); void pexpireCommand(client *c); void pexpireatCommand(client *c); void getsetCommand(client *c);