Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions src/commands.def
Original file line number Diff line number Diff line change
Expand Up @@ -10541,6 +10541,30 @@ struct COMMAND_ARG GETEX_Args[] = {
{MAKE_ARG("expiration",ARG_TYPE_ONEOF,-1,NULL,NULL,NULL,CMD_ARG_OPTIONAL,5,NULL),.subargs=GETEX_expiration_Subargs},
};

/********** GETPXT ********************/

#ifndef SKIP_CMD_HISTORY_TABLE
/* GETPXT history */
#define GETPXT_History NULL
#endif

#ifndef SKIP_CMD_TIPS_TABLE
/* GETPXT tips */
#define GETPXT_Tips NULL
#endif

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

/* GETPXT argument table */
struct COMMAND_ARG GETPXT_Args[] = {
{MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
};

/********** GETRANGE ********************/

#ifndef SKIP_CMD_HISTORY_TABLE
Expand Down Expand Up @@ -10721,6 +10745,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 @@ -11319,13 +11369,15 @@ struct COMMAND_STRUCT serverCommandTable[] = {
{MAKE_CMD("get","Returns the string value of a key.","O(1)","1.0.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,GET_History,0,GET_Tips,0,getCommand,2,CMD_READONLY|CMD_FAST,ACL_CATEGORY_STRING,GET_Keyspecs,1,NULL,1),.args=GET_Args},
{MAKE_CMD("getdel","Returns the string value of a key after deleting the key.","O(1)","6.2.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,GETDEL_History,0,GETDEL_Tips,0,getdelCommand,2,CMD_WRITE|CMD_FAST,ACL_CATEGORY_STRING,GETDEL_Keyspecs,1,NULL,1),.args=GETDEL_Args},
{MAKE_CMD("getex","Returns the string value of a key after setting its expiration time.","O(1)","6.2.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,GETEX_History,0,GETEX_Tips,0,getexCommand,-2,CMD_WRITE|CMD_FAST,ACL_CATEGORY_STRING,GETEX_Keyspecs,1,NULL,2),.args=GETEX_Args},
{MAKE_CMD("getpxt","Returns the string value of a key and the expiration time as a Unix milliseconds timestamp, if set.","O(1)","8.0.2",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,GETPXT_History,0,GETPXT_Tips,0,getpxtCommand,2,CMD_READONLY|CMD_FAST,ACL_CATEGORY_STRING|ACL_CATEGORY_KEYSPACE,GETPXT_Keyspecs,1,NULL,1),.args=GETPXT_Args},
{MAKE_CMD("getrange","Returns a substring of the string stored at a key.","O(N) where N is the length of the returned string. The complexity is ultimately determined by the returned length, but because creating a substring from an existing string is very cheap, it can be considered O(1) for small strings.","2.4.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,GETRANGE_History,0,GETRANGE_Tips,0,getrangeCommand,4,CMD_READONLY,ACL_CATEGORY_STRING,GETRANGE_Keyspecs,1,NULL,3),.args=GETRANGE_Args},
{MAKE_CMD("getset","Returns the previous string value of a key after setting it to a new value.","O(1)","1.0.0",CMD_DOC_DEPRECATED,"`SET` with the `!GET` argument","6.2.0","string",COMMAND_GROUP_STRING,GETSET_History,0,GETSET_Tips,0,getsetCommand,3,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_STRING,GETSET_Keyspecs,1,NULL,2),.args=GETSET_Args},
{MAKE_CMD("incr","Increments the integer value of a key by one. Uses 0 as initial value if the key doesn't exist.","O(1)","1.0.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,INCR_History,0,INCR_Tips,0,incrCommand,2,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_STRING,INCR_Keyspecs,1,NULL,1),.args=INCR_Args},
{MAKE_CMD("incrby","Increments the integer value of a key by a number. Uses 0 as initial value if the key doesn't exist.","O(1)","1.0.0",CMD_DOC_NONE,NULL,NULL,"string",COMMAND_GROUP_STRING,INCRBY_History,0,INCRBY_Tips,0,incrbyCommand,3,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_STRING,INCRBY_Keyspecs,1,NULL,2),.args=INCRBY_Args},
{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
80 changes: 80 additions & 0 deletions src/commands/getpxt.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
{
"GETPXT": {
"summary": "Returns the string value of a key and the expiration time as a Unix milliseconds timestamp, if set.",
"complexity": "O(1)",
"group": "string",
"since": "8.0.2",
"arity": 2,
"function": "getpxtCommand",
"command_flags": [
"READONLY",
"FAST"
],
"acl_categories": [
"STRING",
"KEYSPACE"
],
"key_specs": [
{
"flags": [
"RO",
"ACCESS"
],
"begin_search": {
"index": {
"pos": 1
}
},
"find_keys": {
"range": {
"lastkey": 0,
"step": 1,
"limit": 0
}
}
}
],
"reply_schema": {
"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."
}
]
}
]
}
},
{
"description": "Key does not exist.",
"type": "null"
}
]
},
"arguments": [
{
"name": "key",
"type": "key",
"key_spec_index": 0
}
]
}
}
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
}
]
}
}
2 changes: 2 additions & 0 deletions src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -3622,6 +3622,7 @@ void psetexCommand(client *c);
void getCommand(client *c);
void getexCommand(client *c);
void getdelCommand(client *c);
void getpxtCommand(client *c);
void delCommand(client *c);
void unlinkCommand(client *c);
void existsCommand(client *c);
Expand Down Expand Up @@ -3694,6 +3695,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
52 changes: 52 additions & 0 deletions src/t_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,30 @@ void getCommand(client *c) {
getGenericCommand(c);
}

void getpxtCommand(client *c) {
long long expire;
robj *o;

if ((o = lookupKeyReadOrReply(c, c->argv[1], shared.null[c->resp])) == NULL)
return;

if (checkType(c, o, OBJ_STRING)) {
return;
}

addReplyArrayLen(c, 2);
addReplyBulk(c, o);

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

/*
* GETEX <key> [PERSIST][EX seconds][PX milliseconds][EXAT seconds-timestamp][PXAT milliseconds-timestamp]
*
Expand Down Expand Up @@ -623,6 +647,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
Loading
Loading