Merge 61153de0bc30be830ab88ac680fc4e27f11d54b6 into 26c6f1af9b29d525831c7fa9840ab3e47ed7b700
This commit is contained in:
commit
0a2f808623
@ -10509,6 +10509,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
|
||||
@ -10689,6 +10713,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
|
||||
@ -11287,6 +11337,7 @@ 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},
|
||||
@ -11294,6 +11345,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},
|
||||
|
80
src/commands/getpxt.json
Normal file
80
src/commands/getpxt.json
Normal file
@ -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
src/commands/mgetpxt.json
Normal file
88
src/commands/mgetpxt.json
Normal file
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -3623,6 +3623,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);
|
||||
@ -3695,6 +3696,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);
|
||||
|
@ -393,6 +393,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]
|
||||
*
|
||||
@ -608,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;
|
||||
|
||||
|
@ -138,6 +138,7 @@ typedef struct _client {
|
||||
redisContext *context;
|
||||
sds obuf;
|
||||
char **randptr; /* Pointers to :rand: strings inside the command buf */
|
||||
bool *randlast; /* Pointer to flag indicating whether :rand: should be last used or new */
|
||||
size_t randlen; /* Number of pointers in client->randptr */
|
||||
size_t randfree; /* Number of unused pointers in client->randptr */
|
||||
char **stagptr; /* Pointers to slot hashtags (cluster mode only) */
|
||||
@ -361,6 +362,7 @@ static void freeClient(client c) {
|
||||
redisFree(c->context);
|
||||
sdsfree(c->obuf);
|
||||
zfree(c->randptr);
|
||||
zfree(c->randlast);
|
||||
zfree(c->stagptr);
|
||||
zfree(c);
|
||||
if (config.num_threads) pthread_mutex_lock(&(config.liveclients_mutex));
|
||||
@ -392,11 +394,18 @@ static void resetClient(client c) {
|
||||
|
||||
static void randomizeClientKey(client c) {
|
||||
size_t i;
|
||||
size_t last_rand = 0;
|
||||
|
||||
for (i = 0; i < c->randlen; i++) {
|
||||
char *p = c->randptr[i] + 11;
|
||||
size_t r = 0;
|
||||
if (config.randomkeys_keyspacelen != 0) r = random() % config.randomkeys_keyspacelen;
|
||||
// If last random is requested then use the last random
|
||||
if(c->randlast[i]) {
|
||||
r = last_rand;
|
||||
} else if (config.randomkeys_keyspacelen != 0) {
|
||||
r = random() % config.randomkeys_keyspacelen;
|
||||
last_rand = r;
|
||||
}
|
||||
size_t j;
|
||||
|
||||
for (j = 0; j < 12; j++) {
|
||||
@ -741,6 +750,7 @@ static client createClient(char *cmd, size_t len, client from, int thread_id) {
|
||||
c->written = 0;
|
||||
c->pending = config.pipeline + c->prefix_pending;
|
||||
c->randptr = NULL;
|
||||
c->randlast = NULL;
|
||||
c->randlen = 0;
|
||||
c->stagptr = NULL;
|
||||
c->staglen = 0;
|
||||
@ -751,11 +761,13 @@ static client createClient(char *cmd, size_t len, client from, int thread_id) {
|
||||
c->randlen = from->randlen;
|
||||
c->randfree = 0;
|
||||
c->randptr = zmalloc(sizeof(char *) * c->randlen);
|
||||
c->randlast = zmalloc(sizeof(bool) * c->randlen);
|
||||
/* copy the offsets. */
|
||||
for (j = 0; j < (int)c->randlen; j++) {
|
||||
c->randptr[j] = c->obuf + (from->randptr[j] - from->obuf);
|
||||
/* Adjust for the different select prefix length. */
|
||||
c->randptr[j] += c->prefixlen - from->prefixlen;
|
||||
c->randlast[j] = from->randlast[j];
|
||||
}
|
||||
} else {
|
||||
char *p = c->obuf;
|
||||
@ -763,14 +775,23 @@ static client createClient(char *cmd, size_t len, client from, int thread_id) {
|
||||
c->randlen = 0;
|
||||
c->randfree = RANDPTR_INITIAL_SIZE;
|
||||
c->randptr = zmalloc(sizeof(char *) * c->randfree);
|
||||
while ((p = strstr(p, "__rand_int__")) != NULL) {
|
||||
c->randlast = zmalloc(sizeof(bool) * c->randfree);
|
||||
while ((p = strstr(p, "__rand_")) != NULL) {
|
||||
bool rand_int = !(bool)strncmp("__rand_int__", p, 12);
|
||||
bool rand_last = !(bool)strncmp("__rand_lst__", p, 12);
|
||||
if(!rand_int && ! rand_last)
|
||||
continue;
|
||||
|
||||
if (c->randfree == 0) {
|
||||
c->randptr = zrealloc(c->randptr, sizeof(char *) * c->randlen * 2);
|
||||
c->randlast = zrealloc(c->randlast, sizeof(bool) * c->randlen * 2);
|
||||
c->randfree += c->randlen;
|
||||
}
|
||||
c->randptr[c->randlen++] = p;
|
||||
c->randptr[c->randlen] = p;
|
||||
c->randlast[c->randlen] = rand_last;
|
||||
c->randlen++;
|
||||
c->randfree--;
|
||||
p += 12; /* 12 is strlen("__rand_int__). */
|
||||
p += 12; /* 12 is strlen("__rand_int__), same for "__rand_lst__". */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1569,8 +1590,10 @@ usage:
|
||||
" $ valkey-benchmark -r 10000 -n 10000 eval 'return redis.call(\"ping\")' 0\n\n"
|
||||
" Fill a list with 10000 random elements:\n"
|
||||
" $ valkey-benchmark -r 10000 -n 10000 lpush mylist __rand_int__\n\n"
|
||||
" On user specified command lines __rand_int__ is replaced with a random integer\n"
|
||||
" with a range of values selected by the -r option.\n");
|
||||
" On user-specified command lines __rand_int__ is replaced with a random integer\n"
|
||||
" with a range of values selected by the -r option.\n"
|
||||
" On user-specified command lines __rand_lst__ is replaced with the last value\n"
|
||||
" of __rand_int__ or zero if no such value is available.\n");
|
||||
exit(exit_status);
|
||||
}
|
||||
|
||||
@ -1958,6 +1981,39 @@ int main(int argc, char **argv) {
|
||||
free(cmd);
|
||||
}
|
||||
|
||||
if (test_is_selected("set_pxat")) {
|
||||
len = redisFormatCommand(&cmd, "SET key%s:__rand_int__ %s PXAT 17344823940230", tag, data);
|
||||
benchmark("SET w/ PXAT", cmd, len);
|
||||
free(cmd);
|
||||
}
|
||||
|
||||
if (test_is_selected("getpxt")) {
|
||||
len = redisFormatCommand(&cmd, "GETPXT key%s:__rand_int__", tag);
|
||||
benchmark("GETPXT", cmd, len);
|
||||
free(cmd);
|
||||
}
|
||||
|
||||
if (test_is_selected("getpxt_simulated")) {
|
||||
redisFormatCommand(&cmd, "MULTI");
|
||||
sds pipeline = sdscatprintf(sdsempty(), "%s", cmd);
|
||||
free(cmd);
|
||||
|
||||
redisFormatCommand(&cmd, "GET key%s:__rand_int__", tag);
|
||||
pipeline = sdscatprintf(pipeline, "%s", cmd);
|
||||
free(cmd);
|
||||
|
||||
redisFormatCommand(&cmd, "PEXPIRETIME key%s:__rand_lst__", tag);
|
||||
pipeline = sdscatprintf(pipeline, "%s", cmd);
|
||||
free(cmd);
|
||||
|
||||
redisFormatCommand(&cmd, "EXEC");
|
||||
pipeline = sdscatprintf(pipeline, "%s", cmd);
|
||||
free(cmd);
|
||||
|
||||
benchmark("GETPXT Simulated", pipeline, sdslen(pipeline));
|
||||
sdsfree(pipeline);
|
||||
}
|
||||
|
||||
if (!config.csv) printf("\n");
|
||||
} while (config.loop);
|
||||
|
||||
|
@ -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]
|
||||
@ -658,6 +680,23 @@ if {[string match {*jemalloc*} [s mem_allocator]]} {
|
||||
assert_range [r ttl foo] 5 10
|
||||
}
|
||||
|
||||
test "GETPXT after SET PXAT" {
|
||||
r del foo
|
||||
r set foo bar pxat 17344823940230
|
||||
r getpxt foo
|
||||
} {bar 17344823940230}
|
||||
|
||||
test "GETPXT after SET with no expiration" {
|
||||
r del foo
|
||||
r set foo bar
|
||||
r getpxt foo
|
||||
} {bar -1}
|
||||
|
||||
test "GETPXT with no entry" {
|
||||
r del foo
|
||||
r getpxt foo
|
||||
} {}
|
||||
|
||||
test "SET EXAT / PXAT Expiration time is expired" {
|
||||
r debug set-active-expire 0
|
||||
set repl [attach_to_replication_stream]
|
||||
|
Loading…
x
Reference in New Issue
Block a user