Skip to content

Commit

Permalink
Add MGETPXT with the same semantics
Browse files Browse the repository at this point in the history
Remove the "overload" as non-precision timestamp isn't useful in the intended context
  • Loading branch information
arcivanov committed Dec 20, 2024
1 parent 7ccf367 commit 3f79338
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 7 deletions.
27 changes: 27 additions & 0 deletions src/commands.def
Original file line number Diff line number Diff line change
Expand Up @@ -10558,6 +10558,32 @@ struct COMMAND_ARG MGET_Args[] = {
{MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)},
};

/********** MGETPXT ********************/

#ifndef SKIP_CMD_HISTORY_TABLE
/* MGETPXT history */
#define MGETPXT_History NULL
#endif

#ifndef SKIP_CMD_TIPS_TABLE
/* MGETPXT tips */
const char *MGETPXT_Tips[] = {
"request_policy:multi_shard",
};
#endif

#ifndef SKIP_CMD_KEY_SPECS_TABLE
/* MGETPXT key specs */
keySpec MGETPXT_Keyspecs[1] = {
{NULL,CMD_KEY_RO|CMD_KEY_ACCESS,KSPEC_BS_INDEX,.bs.index={1},KSPEC_FK_RANGE,.fk.range={-1,1,0}}
};
#endif

/* MGETPXT argument table */
struct COMMAND_ARG MGETPXT_Args[] = {
{MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)},
};

/********** MSET ********************/

#ifndef SKIP_CMD_HISTORY_TABLE
Expand Down Expand Up @@ -11163,6 +11189,7 @@ struct COMMAND_STRUCT serverCommandTable[] = {
{MAKE_CMD("incrbyfloat","Increment the floating point value of a key by a number. Uses 0 as initial value if the key doesn't exist.","O(1)","2.6.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,INCRBYFLOAT_History,0,INCRBYFLOAT_Tips,0,incrbyfloatCommand,3,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_STRING,INCRBYFLOAT_Keyspecs,1,NULL,2),.args=INCRBYFLOAT_Args},
{MAKE_CMD("lcs","Finds the longest common substring.","O(N*M) where N and M are the lengths of s1 and s2, respectively","7.0.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,LCS_History,0,LCS_Tips,0,lcsCommand,-3,CMD_READONLY,ACL_CATEGORY_STRING,LCS_Keyspecs,1,NULL,6),.args=LCS_Args},
{MAKE_CMD("mget","Atomically returns the string values of one or more keys.","O(N) where N is the number of keys to retrieve.","1.0.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,MGET_History,0,MGET_Tips,1,mgetCommand,-2,CMD_READONLY|CMD_FAST,ACL_CATEGORY_STRING,MGET_Keyspecs,1,NULL,1),.args=MGET_Args},
{MAKE_CMD("mgetpxt","Atomically returns the string values of one or more keys and their millisecond expiration, if available.","O(N) where N is the number of keys to retrieve.","1.0.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,MGETPXT_History,0,MGETPXT_Tips,1,mgetpxtCommand,-2,CMD_READONLY|CMD_FAST,ACL_CATEGORY_STRING|ACL_CATEGORY_KEYSPACE,MGETPXT_Keyspecs,1,NULL,1),.args=MGETPXT_Args},
{MAKE_CMD("mset","Atomically creates or modifies the string values of one or more keys.","O(N) where N is the number of keys to set.","1.0.1",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,MSET_History,0,MSET_Tips,2,msetCommand,-3,CMD_WRITE|CMD_DENYOOM,ACL_CATEGORY_STRING,MSET_Keyspecs,1,NULL,1),.args=MSET_Args},
{MAKE_CMD("msetnx","Atomically modifies the string values of one or more keys only when all keys don't exist.","O(N) where N is the number of keys to set.","1.0.1",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,MSETNX_History,0,MSETNX_Tips,0,msetnxCommand,-3,CMD_WRITE|CMD_DENYOOM,ACL_CATEGORY_STRING,MSETNX_Keyspecs,1,NULL,1),.args=MSETNX_Args},
{MAKE_CMD("psetex","Sets both string value and expiration time in milliseconds of a key. The key is created if it doesn't exist.","O(1)","2.6.0",CMD_DOC_DEPRECATED,"`SET` with the `PX` argument","2.6.12","string",COMMAND_GROUP_STRING,PSETEX_History,0,PSETEX_Tips,0,psetexCommand,4,CMD_WRITE|CMD_DENYOOM,ACL_CATEGORY_STRING,PSETEX_Keyspecs,1,NULL,3),.args=PSETEX_Args},
Expand Down
88 changes: 88 additions & 0 deletions src/commands/mgetpxt.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
{
"MGETPXT": {
"summary": "Atomically returns the string values of one or more keys and their millisecond expiration, if available.",
"complexity": "O(N) where N is the number of keys to retrieve.",
"group": "string",
"since": "1.0.0",
"arity": -2,
"function": "mgetpxtCommand",
"command_flags": [
"READONLY",
"FAST"
],
"acl_categories": [
"STRING",
"KEYSPACE"
],
"command_tips": [
"REQUEST_POLICY:MULTI_SHARD"
],
"key_specs": [
{
"flags": [
"RO",
"ACCESS"
],
"begin_search": {
"index": {
"pos": 1
}
},
"find_keys": {
"range": {
"lastkey": -1,
"step": 1,
"limit": 0
}
}
}
],
"reply_schema": {
"description": "List of values at the specified keys.",
"type": "array",
"minItems": 1,
"items": {
"oneOf": [
{
"type": "array",
"items": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": [
{
"description": "The value of the key.",
"type": "string"
},
{
"oneOf": [
{
"type": "integer",
"description": "Expiration Unix timestamp in milliseconds.",
"minimum": 0
},
{
"const": -1,
"description": "The key exists but has no associated expiration time."
}
]
}
]
}
},
{
"type": "null"
}
]
}
},
"arguments": [
{
"name": "key",
"type": "key",
"key_spec_index": 0,
"multiple": true
}
]
}
}
1 change: 1 addition & 0 deletions src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -3856,6 +3856,7 @@ void rpoplpushCommand(client *c);
void lmoveCommand(client *c);
void infoCommand(client *c);
void mgetCommand(client *c);
void mgetpxtCommand(client *c);
void monitorCommand(client *c);
void expireCommand(client *c);
void expireatCommand(client *c);
Expand Down
36 changes: 30 additions & 6 deletions src/t_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ void getCommand(client *c) {
getGenericCommand(c);
}

void getExpireGenericCommand(client *c, int output_ms) {
void getpxtCommand(client *c) {
long long expire;
robj *o;

Expand All @@ -413,14 +413,10 @@ void getExpireGenericCommand(client *c, int output_ms) {
if (expire == -1) {
addReplyLongLong(c, -1);
} else {
addReplyLongLong(c, output_ms ? expire : ((expire + 500) / 1000));
addReplyLongLong(c, expire);
}
}

void getpxtCommand(client *c) {
getExpireGenericCommand(c, 1);
}

/*
* GETEX <key> [PERSIST][EX seconds][PX milliseconds][EXAT seconds-timestamp][PXAT milliseconds-timestamp]
*
Expand Down Expand Up @@ -636,6 +632,34 @@ void mgetCommand(client *c) {
}
}

void mgetpxtCommand(client *c) {
int j;

addReplyArrayLen(c, c->argc - 1);
for (j = 1; j < c->argc; j++) {
robj *o = lookupKeyRead(c->db, c->argv[j]);
if (o == NULL) {
addReplyNull(c);
} else {
if (o->type != OBJ_STRING) {
addReplyNull(c);
} else {
addReplyArrayLen(c, 2);
addReplyBulk(c, o);

/* The key exists. Return -1 if it has no expire, or the actual
* expire value otherwise. */
long long expire = getExpire(c->db, c->argv[j]);
if (expire == -1) {
addReplyLongLong(c, -1);
} else {
addReplyLongLong(c, expire);
}
}
}
}
}

void msetGenericCommand(client *c, int nx) {
int j;

Expand Down
24 changes: 23 additions & 1 deletion tests/unit/type/string.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,28 @@ start_server {tags {"string"}} {
r mget foo{t} baazz{t} bar{t} myset{t}
} {BAR {} FOO {}}

test {MGETPXT} {
r flushdb
r set foo{t} BAR pxat 17344823940230
r set bar{t} FOO pxat 17344823940231
r mgetpxt foo{t} bar{t}
} {{BAR 17344823940230} {FOO 17344823940231}}

test {MGETPXT against non existing key} {
r mgetpxt foo{t} baazz{t} bar{t}
} {{BAR 17344823940230} {} {FOO 17344823940231}}

test {MGETPXT against non-string key} {
r sadd myset{t} ciao
r sadd myset{t} bau
r mgetpxt foo{t} baazz{t} bar{t} myset{t}
} {{BAR 17344823940230} {} {FOO 17344823940231} {}}

test {MGETPXT against a key with no expiration} {
r set baz{t} BAZ
r mgetpxt foo{t} baz{t} bar{t}
} {{BAR 17344823940230} {BAZ -1} {FOO 17344823940231}}

test {GETSET (set new value)} {
r del foo
list [r getset foo xyz] [r get foo]
Expand Down Expand Up @@ -664,7 +686,7 @@ if {[string match {*jemalloc*} [s mem_allocator]]} {
r getpxt foo
} {bar 17344823940230}

test "GETPXT after SET" {
test "GETPXT after SET with no expiration" {
r del foo
r set foo bar
r getpxt foo
Expand Down

0 comments on commit 3f79338

Please sign in to comment.