Unverified Commit 71676513 authored by Moti Cohen's avatar Moti Cohen Committed by GitHub
Browse files

Fix commands H*EXPIRE* and H*TTL to include `FIELDS` constant (#13270)

The same goes to: HPEXPIRE, HEXPIREAT, HPEXPIREAT, HEXPIRETIME,
HPEXPIRETIME, HPTTL, HTTL, HPERSIST
parent 80be2cc2
...@@ -3335,6 +3335,7 @@ struct COMMAND_ARG HEXPIRE_Args[] = { ...@@ -3335,6 +3335,7 @@ struct COMMAND_ARG HEXPIRE_Args[] = {
{MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("seconds",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("seconds",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("condition",ARG_TYPE_ONEOF,-1,NULL,NULL,NULL,CMD_ARG_OPTIONAL,4,NULL),.subargs=HEXPIRE_condition_Subargs}, {MAKE_ARG("condition",ARG_TYPE_ONEOF,-1,NULL,NULL,NULL,CMD_ARG_OPTIONAL,4,NULL),.subargs=HEXPIRE_condition_Subargs},
{MAKE_ARG("fields",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)}, {MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)},
}; };
...@@ -3371,6 +3372,7 @@ struct COMMAND_ARG HEXPIREAT_Args[] = { ...@@ -3371,6 +3372,7 @@ struct COMMAND_ARG HEXPIREAT_Args[] = {
{MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("unix-time-seconds",ARG_TYPE_UNIX_TIME,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("unix-time-seconds",ARG_TYPE_UNIX_TIME,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("condition",ARG_TYPE_ONEOF,-1,NULL,NULL,NULL,CMD_ARG_OPTIONAL,4,NULL),.subargs=HEXPIREAT_condition_Subargs}, {MAKE_ARG("condition",ARG_TYPE_ONEOF,-1,NULL,NULL,NULL,CMD_ARG_OPTIONAL,4,NULL),.subargs=HEXPIREAT_condition_Subargs},
{MAKE_ARG("fields",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)}, {MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)},
}; };
...@@ -3398,6 +3400,7 @@ keySpec HEXPIRETIME_Keyspecs[1] = { ...@@ -3398,6 +3400,7 @@ keySpec HEXPIRETIME_Keyspecs[1] = {
struct COMMAND_ARG HEXPIRETIME_Args[] = { struct COMMAND_ARG HEXPIRETIME_Args[] = {
{MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("fields",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)}, {MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)},
}; };
...@@ -3678,6 +3681,7 @@ keySpec HPERSIST_Keyspecs[1] = { ...@@ -3678,6 +3681,7 @@ keySpec HPERSIST_Keyspecs[1] = {
/* HPERSIST argument table */ /* HPERSIST argument table */
struct COMMAND_ARG HPERSIST_Args[] = { struct COMMAND_ARG HPERSIST_Args[] = {
{MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("fields",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)}, {MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)},
}; };
...@@ -3714,6 +3718,7 @@ struct COMMAND_ARG HPEXPIRE_Args[] = { ...@@ -3714,6 +3718,7 @@ struct COMMAND_ARG HPEXPIRE_Args[] = {
{MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("milliseconds",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("milliseconds",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("condition",ARG_TYPE_ONEOF,-1,NULL,NULL,NULL,CMD_ARG_OPTIONAL,4,NULL),.subargs=HPEXPIRE_condition_Subargs}, {MAKE_ARG("condition",ARG_TYPE_ONEOF,-1,NULL,NULL,NULL,CMD_ARG_OPTIONAL,4,NULL),.subargs=HPEXPIRE_condition_Subargs},
{MAKE_ARG("fields",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)}, {MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)},
}; };
...@@ -3750,6 +3755,7 @@ struct COMMAND_ARG HPEXPIREAT_Args[] = { ...@@ -3750,6 +3755,7 @@ struct COMMAND_ARG HPEXPIREAT_Args[] = {
{MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("unix-time-milliseconds",ARG_TYPE_UNIX_TIME,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("unix-time-milliseconds",ARG_TYPE_UNIX_TIME,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("condition",ARG_TYPE_ONEOF,-1,NULL,NULL,NULL,CMD_ARG_OPTIONAL,4,NULL),.subargs=HPEXPIREAT_condition_Subargs}, {MAKE_ARG("condition",ARG_TYPE_ONEOF,-1,NULL,NULL,NULL,CMD_ARG_OPTIONAL,4,NULL),.subargs=HPEXPIREAT_condition_Subargs},
{MAKE_ARG("fields",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)}, {MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)},
}; };
...@@ -3777,6 +3783,7 @@ keySpec HPEXPIRETIME_Keyspecs[1] = { ...@@ -3777,6 +3783,7 @@ keySpec HPEXPIRETIME_Keyspecs[1] = {
struct COMMAND_ARG HPEXPIRETIME_Args[] = { struct COMMAND_ARG HPEXPIRETIME_Args[] = {
{MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("fields",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)}, {MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)},
}; };
...@@ -3802,6 +3809,7 @@ keySpec HPTTL_Keyspecs[1] = { ...@@ -3802,6 +3809,7 @@ keySpec HPTTL_Keyspecs[1] = {
/* HPTTL argument table */ /* HPTTL argument table */
struct COMMAND_ARG HPTTL_Args[] = { struct COMMAND_ARG HPTTL_Args[] = {
{MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("fields",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)}, {MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)},
}; };
...@@ -4042,6 +4050,7 @@ keySpec HTTL_Keyspecs[1] = { ...@@ -4042,6 +4050,7 @@ keySpec HTTL_Keyspecs[1] = {
/* HTTL argument table */ /* HTTL argument table */
struct COMMAND_ARG HTTL_Args[] = { struct COMMAND_ARG HTTL_Args[] = {
{MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("fields",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)}, {MAKE_ARG("numfields",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
{MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)}, {MAKE_ARG("field",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_MULTIPLE,0,NULL)},
}; };
...@@ -11097,30 +11106,30 @@ struct COMMAND_STRUCT redisCommandTable[] = { ...@@ -11097,30 +11106,30 @@ struct COMMAND_STRUCT redisCommandTable[] = {
/* hash */ /* hash */
{MAKE_CMD("hdel","Deletes one or more fields and their values from a hash. Deletes the hash if no fields remain.","O(N) where N is the number of fields to be removed.","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HDEL_History,1,HDEL_Tips,0,hdelCommand,-3,CMD_WRITE|CMD_FAST,ACL_CATEGORY_HASH,HDEL_Keyspecs,1,NULL,2),.args=HDEL_Args}, {MAKE_CMD("hdel","Deletes one or more fields and their values from a hash. Deletes the hash if no fields remain.","O(N) where N is the number of fields to be removed.","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HDEL_History,1,HDEL_Tips,0,hdelCommand,-3,CMD_WRITE|CMD_FAST,ACL_CATEGORY_HASH,HDEL_Keyspecs,1,NULL,2),.args=HDEL_Args},
{MAKE_CMD("hexists","Determines whether a field exists in a hash.","O(1)","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HEXISTS_History,0,HEXISTS_Tips,0,hexistsCommand,3,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HEXISTS_Keyspecs,1,NULL,2),.args=HEXISTS_Args}, {MAKE_CMD("hexists","Determines whether a field exists in a hash.","O(1)","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HEXISTS_History,0,HEXISTS_Tips,0,hexistsCommand,3,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HEXISTS_Keyspecs,1,NULL,2),.args=HEXISTS_Args},
{MAKE_CMD("hexpire","Set expiry for hash field using relative time to expire (seconds)","O(N) where N is the number of arguments to the command","8.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HEXPIRE_History,0,HEXPIRE_Tips,0,hexpireCommand,-5,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HEXPIRE_Keyspecs,1,NULL,5),.args=HEXPIRE_Args}, {MAKE_CMD("hexpire","Set expiry for hash field using relative time to expire (seconds)","O(N) where N is the number of specified fields","7.4.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HEXPIRE_History,0,HEXPIRE_Tips,0,hexpireCommand,-6,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HEXPIRE_Keyspecs,1,NULL,6),.args=HEXPIRE_Args},
{MAKE_CMD("hexpireat","Set expiry for hash field using an absolute Unix timestamp (seconds)","O(N) where N is the number of arguments to the command","8.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HEXPIREAT_History,0,HEXPIREAT_Tips,0,hexpireatCommand,-5,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HEXPIREAT_Keyspecs,1,NULL,5),.args=HEXPIREAT_Args}, {MAKE_CMD("hexpireat","Set expiry for hash field using an absolute Unix timestamp (seconds)","O(N) where N is the number of specified fields","7.4.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HEXPIREAT_History,0,HEXPIREAT_Tips,0,hexpireatCommand,-6,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HEXPIREAT_Keyspecs,1,NULL,6),.args=HEXPIREAT_Args},
{MAKE_CMD("hexpiretime","Returns the expiration time of a hash field as a Unix timestamp, in seconds.","O(N) where N is the number of arguments to the command","8.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HEXPIRETIME_History,0,HEXPIRETIME_Tips,0,hexpiretimeCommand,-4,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HEXPIRETIME_Keyspecs,1,NULL,3),.args=HEXPIRETIME_Args}, {MAKE_CMD("hexpiretime","Returns the expiration time of a hash field as a Unix timestamp, in seconds.","O(N) where N is the number of specified fields","7.4.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HEXPIRETIME_History,0,HEXPIRETIME_Tips,0,hexpiretimeCommand,-5,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HEXPIRETIME_Keyspecs,1,NULL,4),.args=HEXPIRETIME_Args},
{MAKE_CMD("hget","Returns the value of a field in a hash.","O(1)","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HGET_History,0,HGET_Tips,0,hgetCommand,3,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HGET_Keyspecs,1,NULL,2),.args=HGET_Args}, {MAKE_CMD("hget","Returns the value of a field in a hash.","O(1)","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HGET_History,0,HGET_Tips,0,hgetCommand,3,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HGET_Keyspecs,1,NULL,2),.args=HGET_Args},
{MAKE_CMD("hgetall","Returns all fields and values in a hash.","O(N) where N is the size of the hash.","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HGETALL_History,0,HGETALL_Tips,1,hgetallCommand,2,CMD_READONLY,ACL_CATEGORY_HASH,HGETALL_Keyspecs,1,NULL,1),.args=HGETALL_Args}, {MAKE_CMD("hgetall","Returns all fields and values in a hash.","O(N) where N is the size of the hash.","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HGETALL_History,0,HGETALL_Tips,1,hgetallCommand,2,CMD_READONLY,ACL_CATEGORY_HASH,HGETALL_Keyspecs,1,NULL,1),.args=HGETALL_Args},
{MAKE_CMD("hgetf","For each specified field: get its value and optionally set the field's remaining time to live / UNIX expiration timestamp in seconds / milliseconds","O(N) where N is the number of arguments to the command","8.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HGETF_History,0,HGETF_Tips,0,hgetfCommand,-5,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HGETF_Keyspecs,1,NULL,6),.args=HGETF_Args}, {MAKE_CMD("hgetf","For each specified field: get its value and optionally set the field's remaining time to live / UNIX expiration timestamp in seconds / milliseconds","O(N) where N is the number of specified fields","7.4.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HGETF_History,0,HGETF_Tips,0,hgetfCommand,-5,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HGETF_Keyspecs,1,NULL,6),.args=HGETF_Args},
{MAKE_CMD("hincrby","Increments the integer value of a field in a hash by a number. Uses 0 as initial value if the field doesn't exist.","O(1)","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HINCRBY_History,0,HINCRBY_Tips,0,hincrbyCommand,4,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HINCRBY_Keyspecs,1,NULL,3),.args=HINCRBY_Args}, {MAKE_CMD("hincrby","Increments the integer value of a field in a hash by a number. Uses 0 as initial value if the field doesn't exist.","O(1)","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HINCRBY_History,0,HINCRBY_Tips,0,hincrbyCommand,4,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HINCRBY_Keyspecs,1,NULL,3),.args=HINCRBY_Args},
{MAKE_CMD("hincrbyfloat","Increments the floating point value of a field by a number. Uses 0 as initial value if the field doesn't exist.","O(1)","2.6.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HINCRBYFLOAT_History,0,HINCRBYFLOAT_Tips,0,hincrbyfloatCommand,4,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HINCRBYFLOAT_Keyspecs,1,NULL,3),.args=HINCRBYFLOAT_Args}, {MAKE_CMD("hincrbyfloat","Increments the floating point value of a field by a number. Uses 0 as initial value if the field doesn't exist.","O(1)","2.6.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HINCRBYFLOAT_History,0,HINCRBYFLOAT_Tips,0,hincrbyfloatCommand,4,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HINCRBYFLOAT_Keyspecs,1,NULL,3),.args=HINCRBYFLOAT_Args},
{MAKE_CMD("hkeys","Returns all fields in a hash.","O(N) where N is the size of the hash.","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HKEYS_History,0,HKEYS_Tips,1,hkeysCommand,2,CMD_READONLY,ACL_CATEGORY_HASH,HKEYS_Keyspecs,1,NULL,1),.args=HKEYS_Args}, {MAKE_CMD("hkeys","Returns all fields in a hash.","O(N) where N is the size of the hash.","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HKEYS_History,0,HKEYS_Tips,1,hkeysCommand,2,CMD_READONLY,ACL_CATEGORY_HASH,HKEYS_Keyspecs,1,NULL,1),.args=HKEYS_Args},
{MAKE_CMD("hlen","Returns the number of fields in a hash.","O(1)","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HLEN_History,0,HLEN_Tips,0,hlenCommand,2,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HLEN_Keyspecs,1,NULL,1),.args=HLEN_Args}, {MAKE_CMD("hlen","Returns the number of fields in a hash.","O(1)","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HLEN_History,0,HLEN_Tips,0,hlenCommand,2,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HLEN_Keyspecs,1,NULL,1),.args=HLEN_Args},
{MAKE_CMD("hmget","Returns the values of all fields in a hash.","O(N) where N is the number of fields being requested.","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HMGET_History,0,HMGET_Tips,0,hmgetCommand,-3,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HMGET_Keyspecs,1,NULL,2),.args=HMGET_Args}, {MAKE_CMD("hmget","Returns the values of all fields in a hash.","O(N) where N is the number of fields being requested.","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HMGET_History,0,HMGET_Tips,0,hmgetCommand,-3,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HMGET_Keyspecs,1,NULL,2),.args=HMGET_Args},
{MAKE_CMD("hmset","Sets the values of multiple fields.","O(N) where N is the number of fields being set.","2.0.0",CMD_DOC_DEPRECATED,"`HSET` with multiple field-value pairs","4.0.0","hash",COMMAND_GROUP_HASH,HMSET_History,0,HMSET_Tips,0,hsetCommand,-4,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HMSET_Keyspecs,1,NULL,2),.args=HMSET_Args}, {MAKE_CMD("hmset","Sets the values of multiple fields.","O(N) where N is the number of fields being set.","2.0.0",CMD_DOC_DEPRECATED,"`HSET` with multiple field-value pairs","4.0.0","hash",COMMAND_GROUP_HASH,HMSET_History,0,HMSET_Tips,0,hsetCommand,-4,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HMSET_Keyspecs,1,NULL,2),.args=HMSET_Args},
{MAKE_CMD("hpersist","Removes the expiration time for each specified field","O(N) where N is the number of arguments to the command","8.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HPERSIST_History,0,HPERSIST_Tips,0,hpersistCommand,-4,CMD_WRITE|CMD_FAST,ACL_CATEGORY_HASH,HPERSIST_Keyspecs,1,NULL,3),.args=HPERSIST_Args}, {MAKE_CMD("hpersist","Removes the expiration time for each specified field","O(N) where N is the number of specified fields","7.4.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HPERSIST_History,0,HPERSIST_Tips,0,hpersistCommand,-5,CMD_WRITE|CMD_FAST,ACL_CATEGORY_HASH,HPERSIST_Keyspecs,1,NULL,4),.args=HPERSIST_Args},
{MAKE_CMD("hpexpire","Set expiry for hash field using relative time to expire (milliseconds)","O(N) where N is the number of arguments to the command","8.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HPEXPIRE_History,0,HPEXPIRE_Tips,0,hpexpireCommand,-5,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HPEXPIRE_Keyspecs,1,NULL,5),.args=HPEXPIRE_Args}, {MAKE_CMD("hpexpire","Set expiry for hash field using relative time to expire (milliseconds)","O(N) where N is the number of specified fields","7.4.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HPEXPIRE_History,0,HPEXPIRE_Tips,0,hpexpireCommand,-6,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HPEXPIRE_Keyspecs,1,NULL,6),.args=HPEXPIRE_Args},
{MAKE_CMD("hpexpireat","Set expiry for hash field using an absolute Unix timestamp (milliseconds)","O(N) where N is the number of arguments to the command","8.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HPEXPIREAT_History,0,HPEXPIREAT_Tips,0,hpexpireatCommand,-5,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HPEXPIREAT_Keyspecs,1,NULL,5),.args=HPEXPIREAT_Args}, {MAKE_CMD("hpexpireat","Set expiry for hash field using an absolute Unix timestamp (milliseconds)","O(N) where N is the number of specified fields","7.4.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HPEXPIREAT_History,0,HPEXPIREAT_Tips,0,hpexpireatCommand,-6,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HPEXPIREAT_Keyspecs,1,NULL,6),.args=HPEXPIREAT_Args},
{MAKE_CMD("hpexpiretime","Returns the expiration time of a hash field as a Unix timestamp, in msec.","O(N) where N is the number of arguments to the command","8.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HPEXPIRETIME_History,0,HPEXPIRETIME_Tips,0,hpexpiretimeCommand,-4,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HPEXPIRETIME_Keyspecs,1,NULL,3),.args=HPEXPIRETIME_Args}, {MAKE_CMD("hpexpiretime","Returns the expiration time of a hash field as a Unix timestamp, in msec.","O(N) where N is the number of specified fields","7.4.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HPEXPIRETIME_History,0,HPEXPIRETIME_Tips,0,hpexpiretimeCommand,-5,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HPEXPIRETIME_Keyspecs,1,NULL,4),.args=HPEXPIRETIME_Args},
{MAKE_CMD("hpttl","Returns the TTL in milliseconds of a hash field.","O(N) where N is the number of arguments to the command","8.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HPTTL_History,0,HPTTL_Tips,0,hpttlCommand,-4,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HPTTL_Keyspecs,1,NULL,3),.args=HPTTL_Args}, {MAKE_CMD("hpttl","Returns the TTL in milliseconds of a hash field.","O(N) where N is the number of specified fields","7.4.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HPTTL_History,0,HPTTL_Tips,0,hpttlCommand,-5,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HPTTL_Keyspecs,1,NULL,4),.args=HPTTL_Args},
{MAKE_CMD("hrandfield","Returns one or more random fields from a hash.","O(N) where N is the number of fields returned","6.2.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HRANDFIELD_History,0,HRANDFIELD_Tips,1,hrandfieldCommand,-2,CMD_READONLY,ACL_CATEGORY_HASH,HRANDFIELD_Keyspecs,1,NULL,2),.args=HRANDFIELD_Args}, {MAKE_CMD("hrandfield","Returns one or more random fields from a hash.","O(N) where N is the number of fields returned","6.2.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HRANDFIELD_History,0,HRANDFIELD_Tips,1,hrandfieldCommand,-2,CMD_READONLY,ACL_CATEGORY_HASH,HRANDFIELD_Keyspecs,1,NULL,2),.args=HRANDFIELD_Args},
{MAKE_CMD("hscan","Iterates over fields and values of a hash.","O(1) for every call. O(N) for a complete iteration, including enough command calls for the cursor to return back to 0. N is the number of elements inside the collection.","2.8.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HSCAN_History,0,HSCAN_Tips,1,hscanCommand,-3,CMD_READONLY,ACL_CATEGORY_HASH,HSCAN_Keyspecs,1,NULL,5),.args=HSCAN_Args}, {MAKE_CMD("hscan","Iterates over fields and values of a hash.","O(1) for every call. O(N) for a complete iteration, including enough command calls for the cursor to return back to 0. N is the number of elements inside the collection.","2.8.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HSCAN_History,0,HSCAN_Tips,1,hscanCommand,-3,CMD_READONLY,ACL_CATEGORY_HASH,HSCAN_Keyspecs,1,NULL,5),.args=HSCAN_Args},
{MAKE_CMD("hset","Creates or modifies the value of a field in a hash.","O(1) for each field/value pair added, so O(N) to add N field/value pairs when the command is called with multiple field/value pairs.","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HSET_History,1,HSET_Tips,0,hsetCommand,-4,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HSET_Keyspecs,1,NULL,2),.args=HSET_Args}, {MAKE_CMD("hset","Creates or modifies the value of a field in a hash.","O(1) for each field/value pair added, so O(N) to add N field/value pairs when the command is called with multiple field/value pairs.","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HSET_History,1,HSET_Tips,0,hsetCommand,-4,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HSET_Keyspecs,1,NULL,2),.args=HSET_Args},
{MAKE_CMD("hsetf","For each specified field value pair: set field to value and optionally set the field's remaining time to live / UNIX expiration timestamp in seconds / milliseconds","O(N) where N is the number of arguments to the command","8.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HSETF_History,0,HSETF_Tips,0,hsetfCommand,-6,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HSETF_Keyspecs,1,NULL,9),.args=HSETF_Args}, {MAKE_CMD("hsetf","For each specified field value pair: set field to value and optionally set the field's remaining time to live / UNIX expiration timestamp in seconds / milliseconds","O(N) where N is the number of specified fields","7.4.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HSETF_History,0,HSETF_Tips,0,hsetfCommand,-6,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HSETF_Keyspecs,1,NULL,9),.args=HSETF_Args},
{MAKE_CMD("hsetnx","Sets the value of a field in a hash only when the field doesn't exist.","O(1)","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HSETNX_History,0,HSETNX_Tips,0,hsetnxCommand,4,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HSETNX_Keyspecs,1,NULL,3),.args=HSETNX_Args}, {MAKE_CMD("hsetnx","Sets the value of a field in a hash only when the field doesn't exist.","O(1)","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HSETNX_History,0,HSETNX_Tips,0,hsetnxCommand,4,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HASH,HSETNX_Keyspecs,1,NULL,3),.args=HSETNX_Args},
{MAKE_CMD("hstrlen","Returns the length of the value of a field.","O(1)","3.2.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HSTRLEN_History,0,HSTRLEN_Tips,0,hstrlenCommand,3,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HSTRLEN_Keyspecs,1,NULL,2),.args=HSTRLEN_Args}, {MAKE_CMD("hstrlen","Returns the length of the value of a field.","O(1)","3.2.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HSTRLEN_History,0,HSTRLEN_Tips,0,hstrlenCommand,3,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HSTRLEN_Keyspecs,1,NULL,2),.args=HSTRLEN_Args},
{MAKE_CMD("httl","Returns the TTL in seconds of a hash field.","O(N) where N is the number of arguments to the command","8.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HTTL_History,0,HTTL_Tips,0,httlCommand,-4,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HTTL_Keyspecs,1,NULL,3),.args=HTTL_Args}, {MAKE_CMD("httl","Returns the TTL in seconds of a hash field.","O(N) where N is the number of specified fields","7.4.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HTTL_History,0,HTTL_Tips,0,httlCommand,-5,CMD_READONLY|CMD_FAST,ACL_CATEGORY_HASH,HTTL_Keyspecs,1,NULL,4),.args=HTTL_Args},
{MAKE_CMD("hvals","Returns all values in a hash.","O(N) where N is the size of the hash.","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HVALS_History,0,HVALS_Tips,1,hvalsCommand,2,CMD_READONLY,ACL_CATEGORY_HASH,HVALS_Keyspecs,1,NULL,1),.args=HVALS_Args}, {MAKE_CMD("hvals","Returns all values in a hash.","O(N) where N is the size of the hash.","2.0.0",CMD_DOC_NONE,NULL,NULL,"hash",COMMAND_GROUP_HASH,HVALS_History,0,HVALS_Tips,1,hvalsCommand,2,CMD_READONLY,ACL_CATEGORY_HASH,HVALS_Keyspecs,1,NULL,1),.args=HVALS_Args},
/* hyperloglog */ /* hyperloglog */
{MAKE_CMD("pfadd","Adds elements to a HyperLogLog key. Creates the key if it doesn't exist.","O(1) to add every element.","2.8.9",CMD_DOC_NONE,NULL,NULL,"hyperloglog",COMMAND_GROUP_HYPERLOGLOG,PFADD_History,0,PFADD_Tips,0,pfaddCommand,-2,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HYPERLOGLOG,PFADD_Keyspecs,1,NULL,2),.args=PFADD_Args}, {MAKE_CMD("pfadd","Adds elements to a HyperLogLog key. Creates the key if it doesn't exist.","O(1) to add every element.","2.8.9",CMD_DOC_NONE,NULL,NULL,"hyperloglog",COMMAND_GROUP_HYPERLOGLOG,PFADD_History,0,PFADD_Tips,0,pfaddCommand,-2,CMD_WRITE|CMD_DENYOOM|CMD_FAST,ACL_CATEGORY_HYPERLOGLOG,PFADD_Keyspecs,1,NULL,2),.args=PFADD_Args},
......
{ {
"HEXPIRE": { "HEXPIRE": {
"summary": "Set expiry for hash field using relative time to expire (seconds)", "summary": "Set expiry for hash field using relative time to expire (seconds)",
"complexity": "O(N) where N is the number of arguments to the command", "complexity": "O(N) where N is the number of specified fields",
"group": "hash", "group": "hash",
"since": "8.0.0", "since": "7.4.0",
"arity": -5, "arity": -6,
"function": "hexpireCommand", "function": "hexpireCommand",
"history": [], "history": [],
"command_flags": [ "command_flags": [
...@@ -106,6 +106,10 @@ ...@@ -106,6 +106,10 @@
} }
] ]
}, },
{
"name": "FIELDS",
"type": "string"
},
{ {
"name": "numfields", "name": "numfields",
"type": "integer" "type": "integer"
......
{ {
"HEXPIREAT": { "HEXPIREAT": {
"summary": "Set expiry for hash field using an absolute Unix timestamp (seconds)", "summary": "Set expiry for hash field using an absolute Unix timestamp (seconds)",
"complexity": "O(N) where N is the number of arguments to the command", "complexity": "O(N) where N is the number of specified fields",
"group": "hash", "group": "hash",
"since": "8.0.0", "since": "7.4.0",
"arity": -5, "arity": -6,
"function": "hexpireatCommand", "function": "hexpireatCommand",
"history": [], "history": [],
"command_flags": [ "command_flags": [
...@@ -106,6 +106,10 @@ ...@@ -106,6 +106,10 @@
} }
] ]
}, },
{
"name": "FIELDS",
"type": "string"
},
{ {
"name": "numfields", "name": "numfields",
"type": "integer" "type": "integer"
......
{ {
"HEXPIRETIME": { "HEXPIRETIME": {
"summary": "Returns the expiration time of a hash field as a Unix timestamp, in seconds.", "summary": "Returns the expiration time of a hash field as a Unix timestamp, in seconds.",
"complexity": "O(N) where N is the number of arguments to the command", "complexity": "O(N) where N is the number of specified fields",
"group": "hash", "group": "hash",
"since": "8.0.0", "since": "7.4.0",
"arity": -4, "arity": -5,
"function": "hexpiretimeCommand", "function": "hexpiretimeCommand",
"history": [], "history": [],
"command_flags": [ "command_flags": [
...@@ -75,6 +75,10 @@ ...@@ -75,6 +75,10 @@
"name": "numfields", "name": "numfields",
"type": "integer" "type": "integer"
}, },
{
"name": "FIELDS",
"type": "string"
},
{ {
"name": "field", "name": "field",
"type": "string", "type": "string",
......
{ {
"HGETF": { "HGETF": {
"summary": "For each specified field: get its value and optionally set the field's remaining time to live / UNIX expiration timestamp in seconds / milliseconds", "summary": "For each specified field: get its value and optionally set the field's remaining time to live / UNIX expiration timestamp in seconds / milliseconds",
"complexity": "O(N) where N is the number of arguments to the command", "complexity": "O(N) where N is the number of specified fields",
"group": "hash", "group": "hash",
"since": "8.0.0", "since": "7.4.0",
"arity": -5, "arity": -5,
"function": "hgetfCommand", "function": "hgetfCommand",
"history": [], "history": [],
......
{ {
"HPERSIST": { "HPERSIST": {
"summary": "Removes the expiration time for each specified field", "summary": "Removes the expiration time for each specified field",
"complexity": "O(N) where N is the number of arguments to the command", "complexity": "O(N) where N is the number of specified fields",
"group": "hash", "group": "hash",
"since": "8.0.0", "since": "7.4.0",
"arity": -4, "arity": -5,
"function": "hpersistCommand", "function": "hpersistCommand",
"history": [], "history": [],
"command_flags": [ "command_flags": [
...@@ -70,6 +70,10 @@ ...@@ -70,6 +70,10 @@
"type": "key", "type": "key",
"key_spec_index": 0 "key_spec_index": 0
}, },
{
"name": "FIELDS",
"type": "string"
},
{ {
"name": "numfields", "name": "numfields",
"type": "integer" "type": "integer"
......
{ {
"HPEXPIRE": { "HPEXPIRE": {
"summary": "Set expiry for hash field using relative time to expire (milliseconds)", "summary": "Set expiry for hash field using relative time to expire (milliseconds)",
"complexity": "O(N) where N is the number of arguments to the command", "complexity": "O(N) where N is the number of specified fields",
"group": "hash", "group": "hash",
"since": "8.0.0", "since": "7.4.0",
"arity": -5, "arity": -6,
"function": "hpexpireCommand", "function": "hpexpireCommand",
"history": [], "history": [],
"command_flags": [ "command_flags": [
...@@ -106,6 +106,10 @@ ...@@ -106,6 +106,10 @@
} }
] ]
}, },
{
"name": "FIELDS",
"type": "string"
},
{ {
"name": "numfields", "name": "numfields",
"type": "integer" "type": "integer"
......
{ {
"HPEXPIREAT": { "HPEXPIREAT": {
"summary": "Set expiry for hash field using an absolute Unix timestamp (milliseconds)", "summary": "Set expiry for hash field using an absolute Unix timestamp (milliseconds)",
"complexity": "O(N) where N is the number of arguments to the command", "complexity": "O(N) where N is the number of specified fields",
"group": "hash", "group": "hash",
"since": "8.0.0", "since": "7.4.0",
"arity": -5, "arity": -6,
"function": "hpexpireatCommand", "function": "hpexpireatCommand",
"history": [], "history": [],
"command_flags": [ "command_flags": [
...@@ -106,6 +106,10 @@ ...@@ -106,6 +106,10 @@
} }
] ]
}, },
{
"name": "FIELDS",
"type": "string"
},
{ {
"name": "numfields", "name": "numfields",
"type": "integer" "type": "integer"
......
{ {
"HPEXPIRETIME": { "HPEXPIRETIME": {
"summary": "Returns the expiration time of a hash field as a Unix timestamp, in msec.", "summary": "Returns the expiration time of a hash field as a Unix timestamp, in msec.",
"complexity": "O(N) where N is the number of arguments to the command", "complexity": "O(N) where N is the number of specified fields",
"group": "hash", "group": "hash",
"since": "8.0.0", "since": "7.4.0",
"arity": -4, "arity": -5,
"function": "hpexpiretimeCommand", "function": "hpexpiretimeCommand",
"history": [], "history": [],
"command_flags": [ "command_flags": [
...@@ -75,6 +75,10 @@ ...@@ -75,6 +75,10 @@
"name": "numfields", "name": "numfields",
"type": "integer" "type": "integer"
}, },
{
"name": "FIELDS",
"type": "string"
},
{ {
"name": "field", "name": "field",
"type": "string", "type": "string",
......
{ {
"HPTTL": { "HPTTL": {
"summary": "Returns the TTL in milliseconds of a hash field.", "summary": "Returns the TTL in milliseconds of a hash field.",
"complexity": "O(N) where N is the number of arguments to the command", "complexity": "O(N) where N is the number of specified fields",
"group": "hash", "group": "hash",
"since": "8.0.0", "since": "7.4.0",
"arity": -4, "arity": -5,
"function": "hpttlCommand", "function": "hpttlCommand",
"history": [], "history": [],
"command_flags": [ "command_flags": [
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
"type": "null" "type": "null"
}, },
{ {
"description": "The keyname, popped member, and its score.", "description": "Array of results",
"type": "array", "type": "array",
"minItems": 1, "minItems": 1,
"maxItems": 4294967295, "maxItems": 4294967295,
...@@ -71,6 +71,10 @@ ...@@ -71,6 +71,10 @@
"type": "key", "type": "key",
"key_spec_index": 0 "key_spec_index": 0
}, },
{
"name": "FIELDS",
"type": "string"
},
{ {
"name": "numfields", "name": "numfields",
"type": "integer" "type": "integer"
......
{ {
"HSETF": { "HSETF": {
"summary": "For each specified field value pair: set field to value and optionally set the field's remaining time to live / UNIX expiration timestamp in seconds / milliseconds", "summary": "For each specified field value pair: set field to value and optionally set the field's remaining time to live / UNIX expiration timestamp in seconds / milliseconds",
"complexity": "O(N) where N is the number of arguments to the command", "complexity": "O(N) where N is the number of specified fields",
"group": "hash", "group": "hash",
"since": "8.0.0", "since": "7.4.0",
"arity": -6, "arity": -6,
"function": "hsetfCommand", "function": "hsetfCommand",
"history": [], "history": [],
......
{ {
"HTTL": { "HTTL": {
"summary": "Returns the TTL in seconds of a hash field.", "summary": "Returns the TTL in seconds of a hash field.",
"complexity": "O(N) where N is the number of arguments to the command", "complexity": "O(N) where N is the number of specified fields",
"group": "hash", "group": "hash",
"since": "8.0.0", "since": "7.4.0",
"arity": -4, "arity": -5,
"function": "httlCommand", "function": "httlCommand",
"history": [], "history": [],
"command_flags": [ "command_flags": [
...@@ -71,6 +71,10 @@ ...@@ -71,6 +71,10 @@
"type": "key", "type": "key",
"key_spec_index": 0 "key_spec_index": 0
}, },
{
"name": "FIELDS",
"type": "string"
},
{ {
"name": "numfields", "name": "numfields",
"type": "integer" "type": "integer"
......
...@@ -2719,19 +2719,24 @@ static ExpireMeta *hashGetExpireMeta(const eItem hash) { ...@@ -2719,19 +2719,24 @@ static ExpireMeta *hashGetExpireMeta(const eItem hash) {
serverPanic("Unknown encoding: %d", hashObj->encoding); serverPanic("Unknown encoding: %d", hashObj->encoding);
} }
} }
/* HTTL key <FIELDS count field [field ...]> */
static void httlGenericCommand(client *c, const char *cmd, long long basetime, int unit) { static void httlGenericCommand(client *c, const char *cmd, long long basetime, int unit) {
UNUSED(cmd); UNUSED(cmd);
robj *hashObj; robj *hashObj;
long numFields = 0, numFieldsAt = 2; long numFields = 0, numFieldsAt = 3;
/* Read the hash object */ /* Read the hash object */
if ((hashObj = lookupKeyReadOrReply(c, c->argv[1], shared.null[c->resp])) == NULL || if ((hashObj = lookupKeyReadOrReply(c, c->argv[1], shared.null[c->resp])) == NULL ||
checkType(c, hashObj, OBJ_HASH)) return; checkType(c, hashObj, OBJ_HASH)) return;
if (strcasecmp(c->argv[numFieldsAt-1]->ptr, "FIELDS")) {
addReplyError(c, "Mandatory argument FIELDS is missing or not at the right position");
return;
}
/* Read number of fields */ /* Read number of fields */
if (getRangeLongFromObjectOrReply(c, c->argv[numFieldsAt], 1, LONG_MAX, if (getRangeLongFromObjectOrReply(c, c->argv[numFieldsAt], 1, LONG_MAX,
&numFields, "Parameter `numFileds` should be greater than 0") != C_OK) &numFields, "Number of fields must be a positive integer") != C_OK)
return; return;
/* Verify `numFields` is consistent with number of arguments */ /* Verify `numFields` is consistent with number of arguments */
...@@ -2745,7 +2750,7 @@ static void httlGenericCommand(client *c, const char *cmd, long long basetime, i ...@@ -2745,7 +2750,7 @@ static void httlGenericCommand(client *c, const char *cmd, long long basetime, i
addReplyArrayLen(c, numFields); addReplyArrayLen(c, numFields);
for (int i = 0 ; i < numFields ; i++) { for (int i = 0 ; i < numFields ; i++) {
sds field = c->argv[3+i]->ptr; sds field = c->argv[numFieldsAt+1+i]->ptr;
void *fptr = lpFirst(lp); void *fptr = lpFirst(lp);
if (fptr != NULL) if (fptr != NULL)
fptr = lpFind(lp, fptr, (unsigned char *) field, sdslen(field), 1); fptr = lpFind(lp, fptr, (unsigned char *) field, sdslen(field), 1);
...@@ -2762,7 +2767,7 @@ static void httlGenericCommand(client *c, const char *cmd, long long basetime, i ...@@ -2762,7 +2767,7 @@ static void httlGenericCommand(client *c, const char *cmd, long long basetime, i
addReplyArrayLen(c, numFields); addReplyArrayLen(c, numFields);
for (int i = 0 ; i < numFields ; i++) { for (int i = 0 ; i < numFields ; i++) {
long long expire; long long expire;
sds field = c->argv[3+i]->ptr; sds field = c->argv[numFieldsAt+1+i]->ptr;
void *fptr = lpFirst(lpt->lp); void *fptr = lpFirst(lpt->lp);
if (fptr != NULL) if (fptr != NULL)
fptr = lpFind(lpt->lp, fptr, (unsigned char *) field, sdslen(field), 2); fptr = lpFind(lpt->lp, fptr, (unsigned char *) field, sdslen(field), 2);
...@@ -2800,7 +2805,7 @@ static void httlGenericCommand(client *c, const char *cmd, long long basetime, i ...@@ -2800,7 +2805,7 @@ static void httlGenericCommand(client *c, const char *cmd, long long basetime, i
addReplyArrayLen(c, numFields); addReplyArrayLen(c, numFields);
for (int i = 0 ; i < numFields ; i++) { for (int i = 0 ; i < numFields ; i++) {
sds field = c->argv[3+i]->ptr; sds field = c->argv[numFieldsAt+1+i]->ptr;
dictEntry *de = dictFind(d, field); dictEntry *de = dictFind(d, field);
if (de == NULL) { if (de == NULL) {
addReplyLongLong(c, HFE_GET_NO_FIELD); addReplyLongLong(c, HFE_GET_NO_FIELD);
...@@ -2840,7 +2845,7 @@ static void httlGenericCommand(client *c, const char *cmd, long long basetime, i ...@@ -2840,7 +2845,7 @@ static void httlGenericCommand(client *c, const char *cmd, long long basetime, i
* *
* Additional flags are supported and parsed via parseExtendedExpireArguments */ * Additional flags are supported and parsed via parseExtendedExpireArguments */
static void hexpireGenericCommand(client *c, const char *cmd, long long basetime, int unit) { static void hexpireGenericCommand(client *c, const char *cmd, long long basetime, int unit) {
long numFields = 0, numFieldsAt = 3; long numFields = 0, numFieldsAt = 4;
long long expire; /* unix time in msec */ long long expire; /* unix time in msec */
int expireSetCond = 0; int expireSetCond = 0;
robj *hashObj, *keyArg = c->argv[1], *expireArg = c->argv[2]; robj *hashObj, *keyArg = c->argv[1], *expireArg = c->argv[2];
...@@ -2890,6 +2895,11 @@ static void hexpireGenericCommand(client *c, const char *cmd, long long basetime ...@@ -2890,6 +2895,11 @@ static void hexpireGenericCommand(client *c, const char *cmd, long long basetime
expireSetCond = HFE_LT; ++numFieldsAt; expireSetCond = HFE_LT; ++numFieldsAt;
} }
if (strcasecmp(c->argv[numFieldsAt-1]->ptr, "FIELDS")) {
addReplyError(c, "Mandatory argument FIELDS is missing or not at the right position");
return;
}
/* Read number of fields */ /* Read number of fields */
if (getRangeLongFromObjectOrReply(c, c->argv[numFieldsAt], 1, LONG_MAX, if (getRangeLongFromObjectOrReply(c, c->argv[numFieldsAt], 1, LONG_MAX,
&numFields, "Parameter `numFields` should be greater than 0") != C_OK) &numFields, "Parameter `numFields` should be greater than 0") != C_OK)
...@@ -2961,16 +2971,21 @@ void hpexpiretimeCommand(client *c) { ...@@ -2961,16 +2971,21 @@ void hpexpiretimeCommand(client *c) {
/* HPERSIST key <FIELDS count field [field ...]> */ /* HPERSIST key <FIELDS count field [field ...]> */
void hpersistCommand(client *c) { void hpersistCommand(client *c) {
robj *hashObj; robj *hashObj;
long numFields = 0, numFieldsAt = 2; long numFields = 0, numFieldsAt = 3;
int changed = 0; /* Used to determine whether to send a notification. */ int changed = 0; /* Used to determine whether to send a notification. */
/* Read the hash object */ /* Read the hash object */
if ((hashObj = lookupKeyReadOrReply(c, c->argv[1], shared.null[c->resp])) == NULL || if ((hashObj = lookupKeyReadOrReply(c, c->argv[1], shared.null[c->resp])) == NULL ||
checkType(c, hashObj, OBJ_HASH)) return; checkType(c, hashObj, OBJ_HASH)) return;
if (strcasecmp(c->argv[numFieldsAt-1]->ptr, "FIELDS")) {
addReplyError(c, "Mandatory argument FIELDS is missing or not at the right position");
return;
}
/* Read number of fields */ /* Read number of fields */
if (getRangeLongFromObjectOrReply(c, c->argv[numFieldsAt], 1, LONG_MAX, if (getRangeLongFromObjectOrReply(c, c->argv[numFieldsAt], 1, LONG_MAX,
&numFields, "Parameter `numFileds` should be greater than 0") != C_OK) &numFields, "Number of fields must be a positive integer") != C_OK)
return; return;
/* Verify `numFields` is consistent with number of arguments */ /* Verify `numFields` is consistent with number of arguments */
...@@ -2982,7 +2997,7 @@ void hpersistCommand(client *c) { ...@@ -2982,7 +2997,7 @@ void hpersistCommand(client *c) {
if (hashObj->encoding == OBJ_ENCODING_LISTPACK) { if (hashObj->encoding == OBJ_ENCODING_LISTPACK) {
addReplyArrayLen(c, numFields); addReplyArrayLen(c, numFields);
for (int i = 0 ; i < numFields ; i++) { for (int i = 0 ; i < numFields ; i++) {
sds field = c->argv[3 + i]->ptr; sds field = c->argv[numFieldsAt + 1 + i]->ptr;
unsigned char *fptr, *zl = hashObj->ptr; unsigned char *fptr, *zl = hashObj->ptr;
fptr = lpFirst(zl); fptr = lpFirst(zl);
...@@ -3002,7 +3017,7 @@ void hpersistCommand(client *c) { ...@@ -3002,7 +3017,7 @@ void hpersistCommand(client *c) {
addReplyArrayLen(c, numFields); addReplyArrayLen(c, numFields);
for (int i = 0 ; i < numFields ; i++) { for (int i = 0 ; i < numFields ; i++) {
sds field = c->argv[3 + i]->ptr; sds field = c->argv[numFieldsAt + 1 + i]->ptr;
fptr = lpFirst(lpt->lp); fptr = lpFirst(lpt->lp);
if (fptr != NULL) if (fptr != NULL)
...@@ -3040,7 +3055,7 @@ void hpersistCommand(client *c) { ...@@ -3040,7 +3055,7 @@ void hpersistCommand(client *c) {
addReplyArrayLen(c, numFields); addReplyArrayLen(c, numFields);
for (int i = 0 ; i < numFields ; i++) { for (int i = 0 ; i < numFields ; i++) {
sds field = c->argv[3+i]->ptr; sds field = c->argv[numFieldsAt + 1 + i]->ptr;
dictEntry *de = dictFind(d, field); dictEntry *de = dictFind(d, field);
if (de == NULL) { if (de == NULL) {
addReplyLongLong(c, HFE_PERSIST_NO_FIELD); addReplyLongLong(c, HFE_PERSIST_NO_FIELD);
......
...@@ -503,7 +503,7 @@ run_solo {defrag} { ...@@ -503,7 +503,7 @@ run_solo {defrag} {
$rd_pubsub close $rd_pubsub close
} }
test "Active defrag HFE: $type" { test "Active Defrag HFE: $type" {
r flushdb r flushdb
r config resetstat r config resetstat
r config set hz 100 r config set hz 100
...@@ -526,7 +526,7 @@ run_solo {defrag} { ...@@ -526,7 +526,7 @@ run_solo {defrag} {
for {set i 0} {$i < $n} {incr i} { for {set i 0} {$i < $n} {incr i} {
for {set j 0} {$j < $fields} {incr j} { for {set j 0} {$j < $fields} {incr j} {
$rd hset h$i f$j $dummy_field $rd hset h$i f$j $dummy_field
$rd hexpire h$i 9999999 1 f$j $rd hexpire h$i 9999999 FIELDS 1 f$j
$rd set "k$i$j" $dummy_field $rd set "k$i$j" $dummy_field
} }
} }
...@@ -538,7 +538,7 @@ run_solo {defrag} { ...@@ -538,7 +538,7 @@ run_solo {defrag} {
# Coverage for listpackex. # Coverage for listpackex.
r hset h_lpex f0 $dummy_field r hset h_lpex f0 $dummy_field
r hexpire h_lpex 9999999 1 f0 r hexpire h_lpex 9999999 FIELDS 1 f0
assert_encoding listpackex h_lpex assert_encoding listpackex h_lpex
after 120 ;# serverCron only updates the info once in 100ms after 120 ;# serverCron only updates the info once in 100ms
......
...@@ -362,10 +362,10 @@ start_server {tags {"pubsub network"}} { ...@@ -362,10 +362,10 @@ start_server {tags {"pubsub network"}} {
assert_equal {1} [psubscribe $rd1 *] assert_equal {1} [psubscribe $rd1 *]
r hmset myhash yes 1 no 0 r hmset myhash yes 1 no 0
r hincrby myhash yes 10 r hincrby myhash yes 10
r hexpire myhash 999999 1 yes r hexpire myhash 999999 FIELDS 1 yes
r hexpireat myhash [expr {[clock seconds] + 999999}] NX 1 no r hexpireat myhash [expr {[clock seconds] + 999999}] NX FIELDS 1 no
r hpexpire myhash 5 1 yes r hpexpire myhash 5 FIELDS 1 yes
r hpersist myhash 1 yes r hpersist myhash FIELDS 1 yes
assert_encoding $type myhash assert_encoding $type myhash
assert_equal "pmessage * __keyspace@${db}__:myhash hset" [$rd1 read] assert_equal "pmessage * __keyspace@${db}__:myhash hset" [$rd1 read]
assert_equal "pmessage * __keyspace@${db}__:myhash hincrby" [$rd1 read] assert_equal "pmessage * __keyspace@${db}__:myhash hincrby" [$rd1 read]
......
...@@ -65,8 +65,8 @@ proc hrandfieldTest {activeExpireConfig} { ...@@ -65,8 +65,8 @@ proc hrandfieldTest {activeExpireConfig} {
set factorValgrind [expr {$::valgrind ? 2 : 1}] set factorValgrind [expr {$::valgrind ? 2 : 1}]
# Set expiration time for field1 and field2 such that field1 expires first # Set expiration time for field1 and field2 such that field1 expires first
r hpexpire myhash 1 NX 1 field1 r hpexpire myhash 1 NX FIELDS 1 field1
r hpexpire myhash 100 NX 1 field2 r hpexpire myhash 100 NX FIELDS 1 field2
# On call hrandfield command lazy expire deletes field1 first # On call hrandfield command lazy expire deletes field1 first
wait_for_condition 8 10 { wait_for_condition 8 10 {
...@@ -99,76 +99,76 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -99,76 +99,76 @@ start_server {tags {"external:skip needs:debug"}} {
test "HPEXPIRE(AT) - Test 'NX' flag ($type)" { test "HPEXPIRE(AT) - Test 'NX' flag ($type)" {
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 field3 value3 r hset myhash field1 value1 field2 value2 field3 value3
assert_equal [r hpexpire myhash 1000 NX 1 field1] [list $E_OK] assert_equal [r hpexpire myhash 1000 NX FIELDS 1 field1] [list $E_OK]
assert_equal [r hpexpire myhash 1000 NX 2 field1 field2] [list $E_FAIL $E_OK] assert_equal [r hpexpire myhash 1000 NX FIELDS 2 field1 field2] [list $E_FAIL $E_OK]
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 field3 value3 r hset myhash field1 value1 field2 value2 field3 value3
assert_equal [r hpexpireat myhash [expr {([clock seconds]+1000)*1000}] NX 1 field1] [list $E_OK] assert_equal [r hpexpireat myhash [expr {([clock seconds]+1000)*1000}] NX FIELDS 1 field1] [list $E_OK]
assert_equal [r hpexpireat myhash [expr {([clock seconds]+1000)*1000}] NX 2 field1 field2] [list $E_FAIL $E_OK] assert_equal [r hpexpireat myhash [expr {([clock seconds]+1000)*1000}] NX FIELDS 2 field1 field2] [list $E_FAIL $E_OK]
} }
test "HPEXPIRE(AT) - Test 'XX' flag ($type)" { test "HPEXPIRE(AT) - Test 'XX' flag ($type)" {
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 field3 value3 r hset myhash field1 value1 field2 value2 field3 value3
assert_equal [r hpexpire myhash 1000 NX 2 field1 field2] [list $E_OK $E_OK] assert_equal [r hpexpire myhash 1000 NX FIELDS 2 field1 field2] [list $E_OK $E_OK]
assert_equal [r hpexpire myhash 1000 XX 2 field1 field3] [list $E_OK $E_FAIL] assert_equal [r hpexpire myhash 1000 XX FIELDS 2 field1 field3] [list $E_OK $E_FAIL]
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 field3 value3 r hset myhash field1 value1 field2 value2 field3 value3
assert_equal [r hpexpireat myhash [expr {([clock seconds]+1000)*1000}] NX 2 field1 field2] [list $E_OK $E_OK] assert_equal [r hpexpireat myhash [expr {([clock seconds]+1000)*1000}] NX FIELDS 2 field1 field2] [list $E_OK $E_OK]
assert_equal [r hpexpireat myhash [expr {([clock seconds]+1000)*1000}] XX 2 field1 field3] [list $E_OK $E_FAIL] assert_equal [r hpexpireat myhash [expr {([clock seconds]+1000)*1000}] XX FIELDS 2 field1 field3] [list $E_OK $E_FAIL]
} }
test "HPEXPIRE(AT) - Test 'GT' flag ($type)" { test "HPEXPIRE(AT) - Test 'GT' flag ($type)" {
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 r hset myhash field1 value1 field2 value2
assert_equal [r hpexpire myhash 1000 NX 1 field1] [list $E_OK] assert_equal [r hpexpire myhash 1000 NX FIELDS 1 field1] [list $E_OK]
assert_equal [r hpexpire myhash 2000 NX 1 field2] [list $E_OK] assert_equal [r hpexpire myhash 2000 NX FIELDS 1 field2] [list $E_OK]
assert_equal [r hpexpire myhash 1500 GT 2 field1 field2] [list $E_OK $E_FAIL] assert_equal [r hpexpire myhash 1500 GT FIELDS 2 field1 field2] [list $E_OK $E_FAIL]
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 r hset myhash field1 value1 field2 value2
assert_equal [r hpexpireat myhash [expr {([clock seconds]+1000)*1000}] NX 1 field1] [list $E_OK] assert_equal [r hpexpireat myhash [expr {([clock seconds]+1000)*1000}] NX FIELDS 1 field1] [list $E_OK]
assert_equal [r hpexpireat myhash [expr {([clock seconds]+2000)*1000}] NX 1 field2] [list $E_OK] assert_equal [r hpexpireat myhash [expr {([clock seconds]+2000)*1000}] NX FIELDS 1 field2] [list $E_OK]
assert_equal [r hpexpireat myhash [expr {([clock seconds]+1500)*1000}] GT 2 field1 field2] [list $E_OK $E_FAIL] assert_equal [r hpexpireat myhash [expr {([clock seconds]+1500)*1000}] GT FIELDS 2 field1 field2] [list $E_OK $E_FAIL]
} }
test "HPEXPIRE(AT) - Test 'LT' flag ($type)" { test "HPEXPIRE(AT) - Test 'LT' flag ($type)" {
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 r hset myhash field1 value1 field2 value2
assert_equal [r hpexpire myhash 1000 NX 1 field1] [list $E_OK] assert_equal [r hpexpire myhash 1000 NX FIELDS 1 field1] [list $E_OK]
assert_equal [r hpexpire myhash 2000 NX 1 field2] [list $E_OK] assert_equal [r hpexpire myhash 2000 NX FIELDS 1 field2] [list $E_OK]
assert_equal [r hpexpire myhash 1500 LT 2 field1 field2] [list $E_FAIL $E_OK] assert_equal [r hpexpire myhash 1500 LT FIELDS 2 field1 field2] [list $E_FAIL $E_OK]
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 r hset myhash field1 value1 field2 value2
assert_equal [r hpexpireat myhash [expr {([clock seconds]+1000)*1000}] NX 1 field1] [list $E_OK] assert_equal [r hpexpireat myhash [expr {([clock seconds]+1000)*1000}] NX FIELDS 1 field1] [list $E_OK]
assert_equal [r hpexpireat myhash [expr {([clock seconds]+2000)*1000}] NX 1 field2] [list $E_OK] assert_equal [r hpexpireat myhash [expr {([clock seconds]+2000)*1000}] NX FIELDS 1 field2] [list $E_OK]
assert_equal [r hpexpireat myhash [expr {([clock seconds]+1500)*1000}] LT 2 field1 field2] [list $E_FAIL $E_OK] assert_equal [r hpexpireat myhash [expr {([clock seconds]+1500)*1000}] LT FIELDS 2 field1 field2] [list $E_FAIL $E_OK]
} }
test "HPEXPIREAT - field not exists or TTL is in the past ($type)" { test "HPEXPIREAT - field not exists or TTL is in the past ($type)" {
r del myhash r del myhash
r hset myhash f1 v1 f2 v2 f4 v4 r hset myhash f1 v1 f2 v2 f4 v4
r hexpire myhash 1000 NX 1 f4 r hexpire myhash 1000 NX FIELDS 1 f4
assert_equal [r hpexpireat myhash [expr {([clock seconds]-1)*1000}] NX 4 f1 f2 f3 f4] "$E_DELETED $E_DELETED $E_NO_FIELD $E_FAIL" assert_equal [r hpexpireat myhash [expr {([clock seconds]-1)*1000}] NX FIELDS 4 f1 f2 f3 f4] "$E_DELETED $E_DELETED $E_NO_FIELD $E_FAIL"
assert_equal [r hexists myhash field1] 0 assert_equal [r hexists myhash field1] 0
} }
test "HPEXPIRE - wrong number of arguments ($type)" { test "HPEXPIRE - wrong number of arguments ($type)" {
r del myhash r del myhash
r hset myhash f1 v1 r hset myhash f1 v1
assert_error {*Parameter `numFields` should be greater than 0} {r hpexpire myhash 1000 NX 0 f1 f2 f3} assert_error {*Parameter `numFields` should be greater than 0} {r hpexpire myhash 1000 NX FIELDS 0 f1 f2 f3}
assert_error {*Parameter `numFileds` is more than number of arguments} {r hpexpire myhash 1000 NX 4 f1 f2 f3} assert_error {*Parameter `numFileds` is more than number of arguments} {r hpexpire myhash 1000 NX FIELDS 4 f1 f2 f3}
} }
test "HPEXPIRE - parameter expire-time near limit of 2^48 ($type)" { test "HPEXPIRE - parameter expire-time near limit of 2^48 ($type)" {
r del myhash r del myhash
r hset myhash f1 v1 r hset myhash f1 v1
# below & above # below & above
assert_equal [r hpexpire myhash [expr (1<<48) - [clock milliseconds] - 1000 ] 1 f1] [list $E_OK] assert_equal [r hpexpire myhash [expr (1<<48) - [clock milliseconds] - 1000 ] FIELDS 1 f1] [list $E_OK]
assert_error {*invalid expire time*} {r hpexpire myhash [expr (1<<48) - [clock milliseconds] + 100 ] 1 f1} assert_error {*invalid expire time*} {r hpexpire myhash [expr (1<<48) - [clock milliseconds] + 100 ] FIELDS 1 f1}
} }
test "Lazy - doesn't delete hash that all its fields got expired ($type)" { test "Lazy - doesn't delete hash that all its fields got expired ($type)" {
...@@ -180,17 +180,17 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -180,17 +180,17 @@ start_server {tags {"external:skip needs:debug"}} {
for {set i 1} {$i <= $h} {incr i} { for {set i 1} {$i <= $h} {incr i} {
# random expiration time # random expiration time
r hset hrand$h f$i v$i r hset hrand$h f$i v$i
r hpexpire hrand$h [expr {50 + int(rand() * 50)}] 1 f$i r hpexpire hrand$h [expr {50 + int(rand() * 50)}] FIELDS 1 f$i
assert_equal 1 [r HEXISTS hrand$h f$i] assert_equal 1 [r HEXISTS hrand$h f$i]
# same expiration time # same expiration time
r hset same$h f$i v$i r hset same$h f$i v$i
r hpexpire same$h 100 1 f$i r hpexpire same$h 100 FIELDS 1 f$i
assert_equal 1 [r HEXISTS same$h f$i] assert_equal 1 [r HEXISTS same$h f$i]
# same expiration time # same expiration time
r hset mix$h f$i v$i fieldWithoutExpire$i v$i r hset mix$h f$i v$i fieldWithoutExpire$i v$i
r hpexpire mix$h 100 1 f$i r hpexpire mix$h 100 FIELDS 1 f$i
assert_equal 1 [r HEXISTS mix$h f$i] assert_equal 1 [r HEXISTS mix$h f$i]
} }
} }
...@@ -218,17 +218,17 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -218,17 +218,17 @@ start_server {tags {"external:skip needs:debug"}} {
for {set i 1} {$i <= $h} {incr i} { for {set i 1} {$i <= $h} {incr i} {
# random expiration time # random expiration time
r hset hrand$h f$i v$i r hset hrand$h f$i v$i
r hpexpire hrand$h [expr {50 + int(rand() * 50)}] 1 f$i r hpexpire hrand$h [expr {50 + int(rand() * 50)}] FIELDS 1 f$i
assert_equal 1 [r HEXISTS hrand$h f$i] assert_equal 1 [r HEXISTS hrand$h f$i]
# same expiration time # same expiration time
r hset same$h f$i v$i r hset same$h f$i v$i
r hpexpire same$h 100 1 f$i r hpexpire same$h 100 FIELDS 1 f$i
assert_equal 1 [r HEXISTS same$h f$i] assert_equal 1 [r HEXISTS same$h f$i]
# same expiration time # same expiration time
r hset mix$h f$i v$i fieldWithoutExpire$i v$i r hset mix$h f$i v$i fieldWithoutExpire$i v$i
r hpexpire mix$h 100 1 f$i r hpexpire mix$h 100 FIELDS 1 f$i
assert_equal 1 [r HEXISTS mix$h f$i] assert_equal 1 [r HEXISTS mix$h f$i]
} }
} }
...@@ -255,74 +255,74 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -255,74 +255,74 @@ start_server {tags {"external:skip needs:debug"}} {
test "HPEXPIRE - Flushall deletes all pending expired fields ($type)" { test "HPEXPIRE - Flushall deletes all pending expired fields ($type)" {
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 r hset myhash field1 value1 field2 value2
r hpexpire myhash 10000 NX 1 field1 r hpexpire myhash 10000 NX FIELDS 1 field1
r hpexpire myhash 10000 NX 1 field2 r hpexpire myhash 10000 NX FIELDS 1 field2
r flushall r flushall
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 r hset myhash field1 value1 field2 value2
r hpexpire myhash 10000 NX 1 field1 r hpexpire myhash 10000 NX FIELDS 1 field1
r hpexpire myhash 10000 NX 1 field2 r hpexpire myhash 10000 NX FIELDS 1 field2
r flushall async r flushall async
} }
test "HTTL/HPTTL - Input validation gets failed on nonexists field or field without expire ($type)" { test "HTTL/HPTTL - Input validation gets failed on nonexists field or field without expire ($type)" {
r del myhash r del myhash
r HSET myhash field1 value1 field2 value2 r HSET myhash field1 value1 field2 value2
r HPEXPIRE myhash 1000 NX 1 field1 r HPEXPIRE myhash 1000 NX FIELDS 1 field1
foreach cmd {HTTL HPTTL} { foreach cmd {HTTL HPTTL} {
assert_equal [r $cmd non_exists_key 1 f] {} assert_equal [r $cmd non_exists_key FIELDS 1 f] {}
assert_equal [r $cmd myhash 2 field2 non_exists_field] "$T_NO_EXPIRY $T_NO_FIELD" assert_equal [r $cmd myhash FIELDS 2 field2 non_exists_field] "$T_NO_EXPIRY $T_NO_FIELD"
# Set numFields less than actual number of fields. Fine. # Set numFields less than actual number of fields. Fine.
assert_equal [r $cmd myhash 1 non_exists_field1 non_exists_field2] "$T_NO_FIELD" assert_equal [r $cmd myhash FIELDS 1 non_exists_field1 non_exists_field2] "$T_NO_FIELD"
} }
} }
test "HTTL/HPTTL - returns time to live in seconds/msillisec ($type)" { test "HTTL/HPTTL - returns time to live in seconds/msillisec ($type)" {
r del myhash r del myhash
r HSET myhash field1 value1 field2 value2 r HSET myhash field1 value1 field2 value2
r HPEXPIRE myhash 2000 NX 2 field1 field2 r HPEXPIRE myhash 2000 NX FIELDS 2 field1 field2
set ttlArray [r HTTL myhash 2 field1 field2] set ttlArray [r HTTL myhash FIELDS 2 field1 field2]
assert_range [lindex $ttlArray 0] 1 2 assert_range [lindex $ttlArray 0] 1 2
set ttl [r HPTTL myhash 1 field1] set ttl [r HPTTL myhash FIELDS 1 field1]
assert_range $ttl 1000 2000 assert_range $ttl 1000 2000
} }
test "HEXPIRETIME - returns TTL in Unix timestamp ($type)" { test "HEXPIRETIME - returns TTL in Unix timestamp ($type)" {
r del myhash r del myhash
r HSET myhash field1 value1 r HSET myhash field1 value1
r HPEXPIRE myhash 1000 NX 1 field1 r HPEXPIRE myhash 1000 NX FIELDS 1 field1
set lo [expr {[clock seconds] + 1}] set lo [expr {[clock seconds] + 1}]
set hi [expr {[clock seconds] + 2}] set hi [expr {[clock seconds] + 2}]
assert_range [r HEXPIRETIME myhash 1 field1] $lo $hi assert_range [r HEXPIRETIME myhash FIELDS 1 field1] $lo $hi
assert_range [r HPEXPIRETIME myhash 1 field1] [expr $lo*1000] [expr $hi*1000] assert_range [r HPEXPIRETIME myhash FIELDS 1 field1] [expr $lo*1000] [expr $hi*1000]
} }
test "HTTL/HPTTL - Verify TTL progress until expiration ($type)" { test "HTTL/HPTTL - Verify TTL progress until expiration ($type)" {
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 r hset myhash field1 value1 field2 value2
r hpexpire myhash 1000 NX 1 field1 r hpexpire myhash 1000 NX FIELDS 1 field1
assert_range [r HPTTL myhash 1 field1] 100 1000 assert_range [r HPTTL myhash FIELDS 1 field1] 100 1000
assert_range [r HTTL myhash 1 field1] 0 1 assert_range [r HTTL myhash FIELDS 1 field1] 0 1
after 100 after 100
assert_range [r HPTTL myhash 1 field1] 1 901 assert_range [r HPTTL myhash FIELDS 1 field1] 1 901
after 910 after 910
assert_equal [r HPTTL myhash 1 field1] $T_NO_FIELD assert_equal [r HPTTL myhash FIELDS 1 field1] $T_NO_FIELD
assert_equal [r HTTL myhash 1 field1] $T_NO_FIELD assert_equal [r HTTL myhash FIELDS 1 field1] $T_NO_FIELD
} }
test "HPEXPIRE - DEL hash with non expired fields (valgrind test) ($type)" { test "HPEXPIRE - DEL hash with non expired fields (valgrind test) ($type)" {
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 r hset myhash field1 value1 field2 value2
r hpexpire myhash 10000 NX 1 field1 r hpexpire myhash 10000 NX FIELDS 1 field1
r del myhash r del myhash
} }
test "HEXPIREAT - Set time in the past ($type)" { test "HEXPIREAT - Set time in the past ($type)" {
r del myhash r del myhash
r hset myhash field1 value1 r hset myhash field1 value1
assert_equal [r hexpireat myhash [expr {[clock seconds] - 1}] NX 1 field1] $E_DELETED assert_equal [r hexpireat myhash [expr {[clock seconds] - 1}] NX FIELDS 1 field1] $E_DELETED
assert_equal [r hexists myhash field1] 0 assert_equal [r hexists myhash field1] 0
} }
...@@ -330,19 +330,19 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -330,19 +330,19 @@ start_server {tags {"external:skip needs:debug"}} {
r del myhash r del myhash
r hset myhash field1 value1 r hset myhash field1 value1
r hexpireat myhash [expr {[clock seconds] + 2}] NX 1 field1 r hexpireat myhash [expr {[clock seconds] + 2}] NX FIELDS 1 field1
assert_range [r hpttl myhash 1 field1] 1000 2000 assert_range [r hpttl myhash FIELDS 1 field1] 1000 2000
assert_range [r httl myhash 1 field1] 1 2 assert_range [r httl myhash FIELDS 1 field1] 1 2
r hexpireat myhash [expr {[clock seconds] + 5}] XX 1 field1 r hexpireat myhash [expr {[clock seconds] + 5}] XX FIELDS 1 field1
assert_range [r httl myhash 1 field1] 4 5 assert_range [r httl myhash FIELDS 1 field1] 4 5
} }
test "Lazy expire - delete hash with expired fields ($type)" { test "Lazy expire - delete hash with expired fields ($type)" {
r del myhash r del myhash
r debug set-active-expire 0 r debug set-active-expire 0
r hset myhash k v r hset myhash k v
r hpexpire myhash 1 NX 1 k r hpexpire myhash 1 NX FIELDS 1 k
after 5 after 5
r del myhash r del myhash
r debug set-active-expire 1 r debug set-active-expire 1
...@@ -358,7 +358,7 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -358,7 +358,7 @@ start_server {tags {"external:skip needs:debug"}} {
r debug set-active-expire 0 r debug set-active-expire 0
r del myhash r del myhash
r hset myhash f1 v1 f2 v2 f3 v3 f4 v4 f5 v5 r hset myhash f1 v1 f2 v2 f3 v3 f4 v4 f5 v5
r hpexpire myhash 1 NX 4 f1 f2 f3 f4 r hpexpire myhash 1 NX FIELDS 4 f1 f2 f3 f4
after 5 after 5
set res [cmp_hrandfield_result myhash "f1 f2 f3 f4 f5"] set res [cmp_hrandfield_result myhash "f1 f2 f3 f4 f5"]
assert {$res == 1} assert {$res == 1}
...@@ -372,18 +372,18 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -372,18 +372,18 @@ start_server {tags {"external:skip needs:debug"}} {
r del h1 h4 h18 h20 r del h1 h4 h18 h20
r hset h1 k1 v1 r hset h1 k1 v1
r hpexpire h1 1 NX 1 k1 r hpexpire h1 1 NX FIELDS 1 k1
r hset h4 k1 v1 k2 v2 k3 v3 k4 v4 r hset h4 k1 v1 k2 v2 k3 v3 k4 v4
r hpexpire h4 1 NX 3 k1 k3 k4 r hpexpire h4 1 NX FIELDS 3 k1 k3 k4
# beyond 16 fields: HFE DS (ebuckets) converts from list to rax # beyond 16 fields: HFE DS (ebuckets) converts from list to rax
r hset h18 k1 v1 k2 v2 k3 v3 k4 v4 k5 v5 k6 v6 k7 v7 k8 v8 k9 v9 k10 v10 k11 v11 k12 v12 k13 v13 k14 v14 k15 v15 k16 v16 k17 v17 k18 v18 r hset h18 k1 v1 k2 v2 k3 v3 k4 v4 k5 v5 k6 v6 k7 v7 k8 v8 k9 v9 k10 v10 k11 v11 k12 v12 k13 v13 k14 v14 k15 v15 k16 v16 k17 v17 k18 v18
r hpexpire h18 1 NX 18 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 k15 k16 k17 k18 r hpexpire h18 1 NX FIELDS 18 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 k15 k16 k17 k18
r hset h20 k1 v1 k2 v2 k3 v3 k4 v4 k5 v5 k6 v6 k7 v7 k8 v8 k9 v9 k10 v10 k11 v11 k12 v12 k13 v13 k14 v14 k15 v15 k16 v16 k17 v17 k18 v18 k19 v19 k20 v20 r hset h20 k1 v1 k2 v2 k3 v3 k4 v4 k5 v5 k6 v6 k7 v7 k8 v8 k9 v9 k10 v10 k11 v11 k12 v12 k13 v13 k14 v14 k15 v15 k16 v16 k17 v17 k18 v18 k19 v19 k20 v20
r hpexpire h20 1 NX 2 k1 k2 r hpexpire h20 1 NX FIELDS 2 k1 k2
after 10 after 10
...@@ -401,18 +401,18 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -401,18 +401,18 @@ start_server {tags {"external:skip needs:debug"}} {
r del h1 h20 h4 h18 h20 r del h1 h20 h4 h18 h20
r hset h1 01 01 r hset h1 01 01
r hpexpire h1 1 NX 1 01 r hpexpire h1 1 NX FIELDS 1 01
r hset h4 01 01 02 02 03 03 04 04 r hset h4 01 01 02 02 03 03 04 04
r hpexpire h4 1 NX 3 01 03 04 r hpexpire h4 1 NX FIELDS 3 01 03 04
# beyond 16 fields hash-field expiration DS (ebuckets) converts from list to rax # beyond 16 fields hash-field expiration DS (ebuckets) converts from list to rax
r hset h18 01 01 02 02 03 03 04 04 05 05 06 06 07 07 08 08 09 09 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 r hset h18 01 01 02 02 03 03 04 04 05 05 06 06 07 07 08 08 09 09 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18
r hpexpire h18 1 NX 18 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 r hpexpire h18 1 NX FIELDS 18 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18
r hset h20 01 01 02 02 03 03 04 04 05 05 06 06 07 07 08 08 09 09 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 r hset h20 01 01 02 02 03 03 04 04 05 05 06 06 07 07 08 08 09 09 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20
r hpexpire h20 1 NX 2 01 02 r hpexpire h20 1 NX FIELDS 2 01 02
after 10 after 10
...@@ -433,7 +433,7 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -433,7 +433,7 @@ start_server {tags {"external:skip needs:debug"}} {
for {set i 1} {$i <= 1000} {incr i} { for {set i 1} {$i <= 1000} {incr i} {
r hset myhash field$i value$i r hset myhash field$i value$i
if {$i > 1} { if {$i > 1} {
r hpexpire myhash 1 NX 1 field$i r hpexpire myhash 1 NX FIELDS 1 field$i
} }
} }
after 3 after 3
...@@ -467,14 +467,14 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -467,14 +467,14 @@ start_server {tags {"external:skip needs:debug"}} {
r hset h5 1 1 2 22 3 333 4 4444 5 55555 r hset h5 1 1 2 22 3 333 4 4444 5 55555
r hset h6 01 01 02 02 03 03 04 04 05 05 06 06 r hset h6 01 01 02 02 03 03 04 04 05 05 06 06
r hset h18 01 01 02 02 03 03 04 04 05 05 06 06 07 07 08 08 09 09 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 r hset h18 01 01 02 02 03 03 04 04 05 05 06 06 07 07 08 08 09 09 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18
r hpexpire h1 100 NX 1 01 r hpexpire h1 100 NX FIELDS 1 01
r hpexpire h2 100 NX 1 01 r hpexpire h2 100 NX FIELDS 1 01
r hpexpire h2 100 NX 1 02 r hpexpire h2 100 NX FIELDS 1 02
r hpexpire h3 100 NX 1 01 r hpexpire h3 100 NX FIELDS 1 01
r hpexpire h4 100 NX 1 2 r hpexpire h4 100 NX FIELDS 1 2
r hpexpire h5 100 NX 1 3 r hpexpire h5 100 NX FIELDS 1 3
r hpexpire h6 100 NX 1 05 r hpexpire h6 100 NX FIELDS 1 05
r hpexpire h18 100 NX 17 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 r hpexpire h18 100 NX FIELDS 17 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17
after 150 after 150
...@@ -507,32 +507,32 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -507,32 +507,32 @@ start_server {tags {"external:skip needs:debug"}} {
test "A field with TTL overridden with another value (TTL discarded) ($type)" { test "A field with TTL overridden with another value (TTL discarded) ($type)" {
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 field3 value3 r hset myhash field1 value1 field2 value2 field3 value3
r hpexpire myhash 10000 NX 1 field1 r hpexpire myhash 10000 NX FIELDS 1 field1
r hpexpire myhash 1 NX 1 field2 r hpexpire myhash 1 NX FIELDS 1 field2
# field2 TTL will be discarded # field2 TTL will be discarded
r hset myhash field2 value4 r hset myhash field2 value4
after 5 after 5
# Expected TTL will be discarded # Expected TTL will be discarded
assert_equal [r hget myhash field2] "value4" assert_equal [r hget myhash field2] "value4"
assert_equal [r httl myhash 2 field2 field3] "$T_NO_EXPIRY $T_NO_EXPIRY" assert_equal [r httl myhash FIELDS 2 field2 field3] "$T_NO_EXPIRY $T_NO_EXPIRY"
assert_not_equal [r httl myhash 1 field1] "$T_NO_EXPIRY" assert_not_equal [r httl myhash FIELDS 1 field1] "$T_NO_EXPIRY"
} }
test "Modify TTL of a field ($type)" { test "Modify TTL of a field ($type)" {
r del myhash r del myhash
r hset myhash field1 value1 r hset myhash field1 value1
r hpexpire myhash 200000 NX 1 field1 r hpexpire myhash 200000 NX FIELDS 1 field1
r hpexpire myhash 1000000 XX 1 field1 r hpexpire myhash 1000000 XX FIELDS 1 field1
after 15 after 15
assert_equal [r hget myhash field1] "value1" assert_equal [r hget myhash field1] "value1"
assert_range [r hpttl myhash 1 field1] 900000 1000000 assert_range [r hpttl myhash FIELDS 1 field1] 900000 1000000
} }
test "Test return value of set operation ($type)" { test "Test return value of set operation ($type)" {
r del myhash r del myhash
r hset myhash f1 v1 f2 v2 r hset myhash f1 v1 f2 v2
r hexpire myhash 100000 1 f1 r hexpire myhash 100000 FIELDS 1 f1
assert_equal [r hset myhash f2 v2] 0 assert_equal [r hset myhash f2 v2] 0
assert_equal [r hset myhash f3 v3] 1 assert_equal [r hset myhash f3 v3] 1
assert_equal [r hset myhash f3 v3 f4 v4] 1 assert_equal [r hset myhash f3 v3 f4 v4] 1
...@@ -544,7 +544,7 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -544,7 +544,7 @@ start_server {tags {"external:skip needs:debug"}} {
r debug set-active-expire 0 r debug set-active-expire 0
r del myhash r del myhash
r hset myhash1 f1 v1 f2 v2 f3 v3 f4 v4 f5 v5 f6 v6 r hset myhash1 f1 v1 f2 v2 f3 v3 f4 v4 f5 v5 f6 v6
r hpexpire myhash1 1 NX 3 f2 f4 f6 r hpexpire myhash1 1 NX FIELDS 3 f2 f4 f6
after 10 after 10
assert_equal [lsort [r hgetall myhash1]] "f1 f3 f5 v1 v3 v5" assert_equal [lsort [r hgetall myhash1]] "f1 f3 f5 v1 v3 v5"
...@@ -552,7 +552,7 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -552,7 +552,7 @@ start_server {tags {"external:skip needs:debug"}} {
r del myhash r del myhash
for {set i 1} {$i <= 600} {incr i} { for {set i 1} {$i <= 600} {incr i} {
r hset myhash f$i v$i r hset myhash f$i v$i
if {$i > 3} { r hpexpire myhash 1 NX 1 f$i } if {$i > 3} { r hpexpire myhash 1 NX FIELDS 1 f$i }
} }
after 10 after 10
assert_equal [lsort [r hgetall myhash]] [lsort "f1 f2 f3 v1 v2 v3"] assert_equal [lsort [r hgetall myhash]] [lsort "f1 f2 f3 v1 v2 v3"]
...@@ -563,10 +563,10 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -563,10 +563,10 @@ start_server {tags {"external:skip needs:debug"}} {
r debug set-active-expire 0 r debug set-active-expire 0
r del myhash r del myhash
r hset myhash field1 value1 r hset myhash field1 value1
r hpexpire myhash 20 NX 1 field1 r hpexpire myhash 20 NX FIELDS 1 field1
r rename myhash myhash2 r rename myhash myhash2
assert_equal [r exists myhash] 0 assert_equal [r exists myhash] 0
assert_range [r hpttl myhash2 1 field1] 1 20 assert_range [r hpttl myhash2 FIELDS 1 field1] 1 20
after 25 after 25
# Verify the renamed key exists # Verify the renamed key exists
assert_equal [r exists myhash2] 1 assert_equal [r exists myhash2] 1
...@@ -579,7 +579,7 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -579,7 +579,7 @@ start_server {tags {"external:skip needs:debug"}} {
r select 9 r select 9
r flushall r flushall
r hset myhash field1 value1 r hset myhash field1 value1
r hpexpire myhash 100 NX 1 field1 r hpexpire myhash 100 NX FIELDS 1 field1
r move myhash 10 r move myhash 10
assert_equal [r exists myhash] 0 assert_equal [r exists myhash] 0
assert_equal [r dbsize] 0 assert_equal [r dbsize] 0
...@@ -598,8 +598,8 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -598,8 +598,8 @@ start_server {tags {"external:skip needs:debug"}} {
r flushall r flushall
r hset h1 f1 v1 f2 v2 r hset h1 f1 v1 f2 v2
r hset h2 f1 v1 f2 v2 f3 v3 f4 v4 f5 v5 f6 v6 f7 v7 f8 v8 f9 v9 f10 v10 f11 v11 f12 v12 f13 v13 f14 v14 f15 v15 f16 v16 f17 v17 f18 v18 r hset h2 f1 v1 f2 v2 f3 v3 f4 v4 f5 v5 f6 v6 f7 v7 f8 v8 f9 v9 f10 v10 f11 v11 f12 v12 f13 v13 f14 v14 f15 v15 f16 v16 f17 v17 f18 v18
r hpexpire h1 100 NX 1 f1 r hpexpire h1 100 NX FIELDS 1 f1
r hpexpire h2 100 NX 18 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 r hpexpire h2 100 NX FIELDS 18 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18
r COPY h1 h1copy r COPY h1 h1copy
r COPY h2 h2copy r COPY h2 h2copy
assert_equal [r hget h1 f1] "v1" assert_equal [r hget h1 f1] "v1"
...@@ -622,7 +622,7 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -622,7 +622,7 @@ start_server {tags {"external:skip needs:debug"}} {
r select 9 r select 9
r flushall r flushall
r hset myhash field1 value1 r hset myhash field1 value1
r hpexpire myhash 50 NX 1 field1 r hpexpire myhash 50 NX FIELDS 1 field1
r swapdb 9 10 r swapdb 9 10
...@@ -643,33 +643,33 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -643,33 +643,33 @@ start_server {tags {"external:skip needs:debug"}} {
# HPERSIST key <num-fields> <field [field ...]> # HPERSIST key <num-fields> <field [field ...]>
r del myhash r del myhash
r hset myhash f1 v1 f2 v2 r hset myhash f1 v1 f2 v2
r hexpire myhash 1000 NX 1 f1 r hexpire myhash 1000 NX FIELDS 1 f1
assert_error {*wrong number of arguments*} {r hpersist myhash} assert_error {*wrong number of arguments*} {r hpersist myhash}
assert_error {*wrong number of arguments*} {r hpersist myhash 1} assert_error {*wrong number of arguments*} {r hpersist myhash FIELDS 1}
assert_equal [r hpersist not-exists-key 1 f1] {} assert_equal [r hpersist not-exists-key FIELDS 1 f1] {}
assert_equal [r hpersist myhash 2 f1 not-exists-field] "$P_OK $P_NO_FIELD" assert_equal [r hpersist myhash FIELDS 2 f1 not-exists-field] "$P_OK $P_NO_FIELD"
assert_equal [r hpersist myhash 1 f2] "$P_NO_EXPIRY" assert_equal [r hpersist myhash FIELDS 1 f2] "$P_NO_EXPIRY"
} }
test "HPERSIST - verify fields with TTL are persisted ($type)" { test "HPERSIST - verify fields with TTL are persisted ($type)" {
r del myhash r del myhash
r hset myhash f1 v1 f2 v2 r hset myhash f1 v1 f2 v2
r hexpire myhash 20 NX 2 f1 f2 r hexpire myhash 20 NX FIELDS 2 f1 f2
r hpersist myhash 2 f1 f2 r hpersist myhash FIELDS 2 f1 f2
after 25 after 25
assert_equal [r hget myhash f1] "v1" assert_equal [r hget myhash f1] "v1"
assert_equal [r hget myhash f2] "v2" assert_equal [r hget myhash f2] "v2"
assert_equal [r HTTL myhash 2 f1 f2] "$T_NO_EXPIRY $T_NO_EXPIRY" assert_equal [r HTTL myhash FIELDS 2 f1 f2] "$T_NO_EXPIRY $T_NO_EXPIRY"
} }
test "HTTL/HPERSIST - Test expiry commands with non-volatile hash ($type)" { test "HTTL/HPERSIST - Test expiry commands with non-volatile hash ($type)" {
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 field3 value3 r hset myhash field1 value1 field2 value2 field3 value3
assert_equal [r httl myhash 1 field1] $T_NO_EXPIRY assert_equal [r httl myhash FIELDS 1 field1] $T_NO_EXPIRY
assert_equal [r httl myhash 1 fieldnonexist] $E_NO_FIELD assert_equal [r httl myhash FIELDS 1 fieldnonexist] $E_NO_FIELD
assert_equal [r hpersist myhash 1 field1] $P_NO_EXPIRY assert_equal [r hpersist myhash FIELDS 1 field1] $P_NO_EXPIRY
assert_equal [r hpersist myhash 1 fieldnonexist] $P_NO_FIELD assert_equal [r hpersist myhash FIELDS 1 fieldnonexist] $P_NO_FIELD
} }
test "HGETF - input validation ($type)" { test "HGETF - input validation ($type)" {
...@@ -745,15 +745,15 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -745,15 +745,15 @@ start_server {tags {"external:skip needs:debug"}} {
r hset myhash field1 value1 field2 value2 field3 value3 r hset myhash field1 value1 field2 value2 field3 value3
assert_equal [r hgetf myhash EX 1000 NX FIELDS 1 field1] [list "value1"] assert_equal [r hgetf myhash EX 1000 NX FIELDS 1 field1] [list "value1"]
assert_equal [r hgetf myhash EX 10000 NX FIELDS 2 field1 field2] [list "value1" "value2"] assert_equal [r hgetf myhash EX 10000 NX FIELDS 2 field1 field2] [list "value1" "value2"]
assert_range [r httl myhash 1 field1] 1 1000 assert_range [r httl myhash FIELDS 1 field1] 1 1000
assert_range [r httl myhash 1 field2] 5000 10000 assert_range [r httl myhash FIELDS 1 field2] 5000 10000
# A field with no expiration is treated as an infinite expiration. # A field with no expiration is treated as an infinite expiration.
# LT should set the expire time if field has no TTL. # LT should set the expire time if field has no TTL.
r del myhash r del myhash
r hset myhash field1 value1 r hset myhash field1 value1
assert_equal [r hgetf myhash EX 1500 LT FIELDS 1 field1] [list "value1"] assert_equal [r hgetf myhash EX 1500 LT FIELDS 1 field1] [list "value1"]
assert_not_equal [r httl myhash 1 field1] "$T_NO_EXPIRY" assert_not_equal [r httl myhash FIELDS 1 field1] "$T_NO_EXPIRY"
} }
test "HGETF - Test 'XX' flag ($type)" { test "HGETF - Test 'XX' flag ($type)" {
...@@ -761,8 +761,8 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -761,8 +761,8 @@ start_server {tags {"external:skip needs:debug"}} {
r hset myhash field1 value1 field2 value2 field3 value3 r hset myhash field1 value1 field2 value2 field3 value3
assert_equal [r hgetf myhash EX 1000 NX FIELDS 1 field1] [list "value1"] assert_equal [r hgetf myhash EX 1000 NX FIELDS 1 field1] [list "value1"]
assert_equal [r hgetf myhash EX 10000 XX FIELDS 2 field1 field2] [list "value1" "value2"] assert_equal [r hgetf myhash EX 10000 XX FIELDS 2 field1 field2] [list "value1" "value2"]
assert_range [r httl myhash 1 field1] 9900 10000 assert_range [r httl myhash FIELDS 1 field1] 9900 10000
assert_equal [r httl myhash 1 field2] "$T_NO_EXPIRY" assert_equal [r httl myhash FIELDS 1 field2] "$T_NO_EXPIRY"
} }
test "HGETF - Test 'GT' flag ($type)" { test "HGETF - Test 'GT' flag ($type)" {
...@@ -771,8 +771,8 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -771,8 +771,8 @@ start_server {tags {"external:skip needs:debug"}} {
assert_equal [r hgetf myhash EX 1000 NX FIELDS 1 field1] [list "value1"] assert_equal [r hgetf myhash EX 1000 NX FIELDS 1 field1] [list "value1"]
assert_equal [r hgetf myhash EX 2000 NX FIELDS 1 field2] [list "value2"] assert_equal [r hgetf myhash EX 2000 NX FIELDS 1 field2] [list "value2"]
assert_equal [r hgetf myhash EX 1500 GT FIELDS 2 field1 field2] [list "value1" "value2"] assert_equal [r hgetf myhash EX 1500 GT FIELDS 2 field1 field2] [list "value1" "value2"]
assert_range [r httl myhash 1 field1] 1400 1500 assert_range [r httl myhash FIELDS 1 field1] 1400 1500
assert_range [r httl myhash 1 field2] 1900 2000 assert_range [r httl myhash FIELDS 1 field2] 1900 2000
} }
test "HGETF - Test 'LT' flag ($type)" { test "HGETF - Test 'LT' flag ($type)" {
...@@ -781,36 +781,36 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -781,36 +781,36 @@ start_server {tags {"external:skip needs:debug"}} {
assert_equal [r hgetf myhash EX 1000 NX FIELDS 1 field1] [list "value1"] assert_equal [r hgetf myhash EX 1000 NX FIELDS 1 field1] [list "value1"]
assert_equal [r hgetf myhash EX 2000 NX FIELDS 1 field2] [list "value2"] assert_equal [r hgetf myhash EX 2000 NX FIELDS 1 field2] [list "value2"]
assert_equal [r hgetf myhash EX 1500 LT FIELDS 2 field1 field2] [list "value1" "value2"] assert_equal [r hgetf myhash EX 1500 LT FIELDS 2 field1 field2] [list "value1" "value2"]
assert_range [r httl myhash 1 field1] 1 1000 assert_range [r httl myhash FIELDS 1 field1] 1 1000
assert_range [r httl myhash 1 field2] 1000 1500 assert_range [r httl myhash FIELDS 1 field2] 1000 1500
} }
test "HGETF - Test 'EX' flag ($type)" { test "HGETF - Test 'EX' flag ($type)" {
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 field3 value3 r hset myhash field1 value1 field2 value2 field3 value3
assert_equal [r hgetf myhash EX 1000 FIELDS 1 field3] [list "value3"] assert_equal [r hgetf myhash EX 1000 FIELDS 1 field3] [list "value3"]
assert_range [r httl myhash 1 field3] 1 1000 assert_range [r httl myhash FIELDS 1 field3] 1 1000
} }
test "HGETF - Test 'EXAT' flag ($type)" { test "HGETF - Test 'EXAT' flag ($type)" {
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 field3 value3 r hset myhash field1 value1 field2 value2 field3 value3
assert_equal [r hgetf myhash EXAT 4000000000 FIELDS 1 field3] [list "value3"] assert_equal [r hgetf myhash EXAT 4000000000 FIELDS 1 field3] [list "value3"]
assert_range [expr [r httl myhash 1 field3] + [clock seconds]] 3900000000 4000000000 assert_range [expr [r httl myhash FIELDS 1 field3] + [clock seconds]] 3900000000 4000000000
} }
test "HGETF - Test 'PX' flag ($type)" { test "HGETF - Test 'PX' flag ($type)" {
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 field3 value3 r hset myhash field1 value1 field2 value2 field3 value3
assert_equal [r hgetf myhash PX 1000000 FIELDS 1 field3] [list "value3"] assert_equal [r hgetf myhash PX 1000000 FIELDS 1 field3] [list "value3"]
assert_range [r httl myhash 1 field3] 900 1000 assert_range [r httl myhash FIELDS 1 field3] 900 1000
} }
test "HGETF - Test 'PXAT' flag ($type)" { test "HGETF - Test 'PXAT' flag ($type)" {
r del myhash r del myhash
r hset myhash field1 value1 field2 value2 field3 value3 r hset myhash field1 value1 field2 value2 field3 value3
assert_equal [r hgetf myhash PXAT 4000000000000 FIELDS 1 field3] [list "value3"] assert_equal [r hgetf myhash PXAT 4000000000000 FIELDS 1 field3] [list "value3"]
assert_range [expr [r httl myhash 1 field3] + [clock seconds]] 3900000000 4000000000 assert_range [expr [r httl myhash FIELDS 1 field3] + [clock seconds]] 3900000000 4000000000
} }
test "HGETF - Test 'PERSIST' flag ($type)" { test "HGETF - Test 'PERSIST' flag ($type)" {
...@@ -819,15 +819,15 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -819,15 +819,15 @@ start_server {tags {"external:skip needs:debug"}} {
r hset myhash f1 v1 f2 v2 f3 v3 r hset myhash f1 v1 f2 v2 f3 v3
r hgetf myhash PX 5000 FIELDS 3 f1 f2 f3 r hgetf myhash PX 5000 FIELDS 3 f1 f2 f3
assert_not_equal [r httl myhash 1 f1] "$T_NO_EXPIRY" assert_not_equal [r httl myhash FIELDS 1 f1] "$T_NO_EXPIRY"
assert_not_equal [r httl myhash 1 f2] "$T_NO_EXPIRY" assert_not_equal [r httl myhash FIELDS 1 f2] "$T_NO_EXPIRY"
assert_not_equal [r httl myhash 1 f3] "$T_NO_EXPIRY" assert_not_equal [r httl myhash FIELDS 1 f3] "$T_NO_EXPIRY"
assert_equal [r hgetf myhash PERSIST FIELDS 1 f1] "v1" assert_equal [r hgetf myhash PERSIST FIELDS 1 f1] "v1"
assert_equal [r httl myhash 1 f1] "$T_NO_EXPIRY" assert_equal [r httl myhash FIELDS 1 f1] "$T_NO_EXPIRY"
assert_equal [r hgetf myhash PERSIST FIELDS 2 f2 f3] "v2 v3" assert_equal [r hgetf myhash PERSIST FIELDS 2 f2 f3] "v2 v3"
assert_equal [r httl myhash 2 f2 f3] "$T_NO_EXPIRY $T_NO_EXPIRY" assert_equal [r httl myhash FIELDS 2 f2 f3] "$T_NO_EXPIRY $T_NO_EXPIRY"
} }
test "HGETF - Test setting expired ttl deletes key ($type)" { test "HGETF - Test setting expired ttl deletes key ($type)" {
...@@ -836,7 +836,7 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -836,7 +836,7 @@ start_server {tags {"external:skip needs:debug"}} {
# hgetf without setting ttl # hgetf without setting ttl
assert_equal [lsort [r hgetf myhash fields 3 f1 f2 f3]] [lsort "v1 v2 v3"] assert_equal [lsort [r hgetf myhash fields 3 f1 f2 f3]] [lsort "v1 v2 v3"]
assert_equal [r httl myhash 3 f1 f2 f3] "$T_NO_EXPIRY $T_NO_EXPIRY $T_NO_EXPIRY" assert_equal [r httl myhash FIELDS 3 f1 f2 f3] "$T_NO_EXPIRY $T_NO_EXPIRY $T_NO_EXPIRY"
# set expired ttl and verify key is deleted # set expired ttl and verify key is deleted
r hgetf myhash PXAT 1 fields 3 f1 f2 f3 r hgetf myhash PXAT 1 fields 3 f1 f2 f3
...@@ -865,10 +865,10 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -865,10 +865,10 @@ start_server {tags {"external:skip needs:debug"}} {
# Expected TTL will be discarded # Expected TTL will be discarded
assert_equal [r hget myhash field2] "value4" assert_equal [r hget myhash field2] "value4"
assert_equal [r httl myhash 2 field2 field3] "$T_NO_EXPIRY $T_NO_EXPIRY" assert_equal [r httl myhash FIELDS 2 field2 field3] "$T_NO_EXPIRY $T_NO_EXPIRY"
# Other field is not affected. # Other field is not affected.
assert_not_equal [r httl myhash 1 field1] "$T_NO_EXPIRY" assert_not_equal [r httl myhash FIELDS 1 field1] "$T_NO_EXPIRY"
} }
test "HSETF - input validation ($type)" { test "HSETF - input validation ($type)" {
...@@ -979,8 +979,8 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -979,8 +979,8 @@ start_server {tags {"external:skip needs:debug"}} {
r hset myhash f1 v1 f2 v2 f3 v3 r hset myhash f1 v1 f2 v2 f3 v3
assert_equal [r hsetf myhash EX 1000 NX FVS 1 f1 n1] "$S_FIELD_AND_TTL" assert_equal [r hsetf myhash EX 1000 NX FVS 1 f1 n1] "$S_FIELD_AND_TTL"
assert_equal [r hsetf myhash EX 10000 NX FVS 2 f1 n1 f2 n2] "$S_FIELD $S_FIELD_AND_TTL" assert_equal [r hsetf myhash EX 10000 NX FVS 2 f1 n1 f2 n2] "$S_FIELD $S_FIELD_AND_TTL"
assert_range [r httl myhash 1 f1] 990 1000 assert_range [r httl myhash FIELDS 1 f1] 990 1000
assert_range [r httl myhash 1 f2] 9990 10000 assert_range [r httl myhash FIELDS 1 f2] 9990 10000
} }
test "HSETF - Test 'XX' flag ($type)" { test "HSETF - Test 'XX' flag ($type)" {
...@@ -988,8 +988,8 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -988,8 +988,8 @@ start_server {tags {"external:skip needs:debug"}} {
r hset myhash f1 v1 f2 v2 f3 v3 r hset myhash f1 v1 f2 v2 f3 v3
assert_equal [r hsetf myhash EX 1000 NX FVS 1 f1 n1] "$S_FIELD_AND_TTL" assert_equal [r hsetf myhash EX 1000 NX FVS 1 f1 n1] "$S_FIELD_AND_TTL"
assert_equal [r hsetf myhash EX 10000 XX FVS 2 f1 n1 f2 n2] "$S_FIELD_AND_TTL $S_FIELD" assert_equal [r hsetf myhash EX 10000 XX FVS 2 f1 n1 f2 n2] "$S_FIELD_AND_TTL $S_FIELD"
assert_range [r httl myhash 1 f1] 9900 10000 assert_range [r httl myhash FIELDS 1 f1] 9900 10000
assert_equal [r httl myhash 1 f2] "$T_NO_EXPIRY" assert_equal [r httl myhash FIELDS 1 f2] "$T_NO_EXPIRY"
} }
test "HSETF - Test 'GT' flag ($type)" { test "HSETF - Test 'GT' flag ($type)" {
...@@ -998,8 +998,8 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -998,8 +998,8 @@ start_server {tags {"external:skip needs:debug"}} {
assert_equal [r hsetf myhash EX 1000 NX FVS 1 f1 n1] "$S_FIELD_AND_TTL" assert_equal [r hsetf myhash EX 1000 NX FVS 1 f1 n1] "$S_FIELD_AND_TTL"
assert_equal [r hsetf myhash EX 2000 NX FVS 1 f2 n2] "$S_FIELD_AND_TTL" assert_equal [r hsetf myhash EX 2000 NX FVS 1 f2 n2] "$S_FIELD_AND_TTL"
assert_equal [r hsetf myhash EX 1500 GT FVS 2 f1 n1 f2 n2] "$S_FIELD_AND_TTL $S_FIELD" assert_equal [r hsetf myhash EX 1500 GT FVS 2 f1 n1 f2 n2] "$S_FIELD_AND_TTL $S_FIELD"
assert_range [r httl myhash 1 f1] 1400 1500 assert_range [r httl myhash FIELDS 1 f1] 1400 1500
assert_range [r httl myhash 1 f2] 1600 2000 assert_range [r httl myhash FIELDS 1 f2] 1600 2000
} }
test "HSETF - Test 'LT' flag ($type)" { test "HSETF - Test 'LT' flag ($type)" {
...@@ -1008,8 +1008,8 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -1008,8 +1008,8 @@ start_server {tags {"external:skip needs:debug"}} {
assert_equal [r hsetf myhash EX 1000 NX FVS 1 f1 v1] "$S_FIELD_AND_TTL" assert_equal [r hsetf myhash EX 1000 NX FVS 1 f1 v1] "$S_FIELD_AND_TTL"
assert_equal [r hsetf myhash EX 2000 NX FVS 1 f2 v2] "$S_FIELD_AND_TTL" assert_equal [r hsetf myhash EX 2000 NX FVS 1 f2 v2] "$S_FIELD_AND_TTL"
assert_equal [r hsetf myhash EX 1500 LT FVS 2 f1 v1 f2 v2] "$S_FIELD $S_FIELD_AND_TTL" assert_equal [r hsetf myhash EX 1500 LT FVS 2 f1 v1 f2 v2] "$S_FIELD $S_FIELD_AND_TTL"
assert_range [r httl myhash 1 f1] 900 1000 assert_range [r httl myhash FIELDS 1 f1] 900 1000
assert_range [r httl myhash 1 f2] 1400 1500 assert_range [r httl myhash FIELDS 1 f2] 1400 1500
# A field with no expiration is treated as an infinite expiration. # A field with no expiration is treated as an infinite expiration.
# LT should set the expire time if field has no TTL. # LT should set the expire time if field has no TTL.
...@@ -1022,27 +1022,27 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -1022,27 +1022,27 @@ start_server {tags {"external:skip needs:debug"}} {
r del myhash r del myhash
r hset myhash f1 v1 f2 v2 r hset myhash f1 v1 f2 v2
assert_equal [r hsetf myhash EX 1000 FVS 1 f3 v3 ] "$S_FIELD_AND_TTL" assert_equal [r hsetf myhash EX 1000 FVS 1 f3 v3 ] "$S_FIELD_AND_TTL"
assert_range [r httl myhash 1 f3] 900 1000 assert_range [r httl myhash FIELDS 1 f3] 900 1000
} }
test "HSETF - Test 'EXAT' flag ($type)" { test "HSETF - Test 'EXAT' flag ($type)" {
r del myhash r del myhash
r hset myhash f1 v1 f2 v2 r hset myhash f1 v1 f2 v2
assert_equal [r hsetf myhash EXAT 4000000000 FVS 1 f3 v3] "$S_FIELD_AND_TTL" assert_equal [r hsetf myhash EXAT 4000000000 FVS 1 f3 v3] "$S_FIELD_AND_TTL"
assert_range [expr [r httl myhash 1 f3] + [clock seconds]] 3900000000 4000000000 assert_range [expr [r httl myhash FIELDS 1 f3] + [clock seconds]] 3900000000 4000000000
} }
test "HSETF - Test 'PX' flag ($type)" { test "HSETF - Test 'PX' flag ($type)" {
r del myhash r del myhash
assert_equal [r hsetf myhash PX 1000000 FVS 1 f3 v3] "$S_FIELD_AND_TTL" assert_equal [r hsetf myhash PX 1000000 FVS 1 f3 v3] "$S_FIELD_AND_TTL"
assert_range [r httl myhash 1 f3] 990 1000 assert_range [r httl myhash FIELDS 1 f3] 990 1000
} }
test "HSETF - Test 'PXAT' flag ($type)" { test "HSETF - Test 'PXAT' flag ($type)" {
r del myhash r del myhash
r hset myhash f1 v2 f2 v2 f3 v3 r hset myhash f1 v2 f2 v2 f3 v3
assert_equal [r hsetf myhash PXAT 4000000000000 FVS 1 f2 v2] "$S_FIELD_AND_TTL" assert_equal [r hsetf myhash PXAT 4000000000000 FVS 1 f2 v2] "$S_FIELD_AND_TTL"
assert_range [expr [r httl myhash 1 f2] + [clock seconds]] 3900000000 4000000000 assert_range [expr [r httl myhash FIELDS 1 f2] + [clock seconds]] 3900000000 4000000000
} }
test "HSETF - Test 'KEEPTTL' flag ($type)" { test "HSETF - Test 'KEEPTTL' flag ($type)" {
...@@ -1052,14 +1052,14 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -1052,14 +1052,14 @@ start_server {tags {"external:skip needs:debug"}} {
r hsetf myhash PX 5000 FVS 1 f2 v2 r hsetf myhash PX 5000 FVS 1 f2 v2
# f1 does not have ttl # f1 does not have ttl
assert_equal [r httl myhash 1 f1] "$T_NO_EXPIRY" assert_equal [r httl myhash FIELDS 1 f1] "$T_NO_EXPIRY"
# f2 has ttl # f2 has ttl
assert_not_equal [r httl myhash 1 f2] "$T_NO_EXPIRY" assert_not_equal [r httl myhash FIELDS 1 f2] "$T_NO_EXPIRY"
# Validate KEEPTTL preserve TTL # Validate KEEPTTL preserve TTL
assert_equal [r hsetf myhash KEEPTTL FVS 1 f2 n2] "$S_FIELD" assert_equal [r hsetf myhash KEEPTTL FVS 1 f2 n2] "$S_FIELD"
assert_not_equal [r httl myhash 1 f2] "$T_NO_EXPIRY" assert_not_equal [r httl myhash FIELDS 1 f2] "$T_NO_EXPIRY"
assert_equal [r hget myhash f2] "n2" assert_equal [r hget myhash f2] "n2"
} }
...@@ -1070,7 +1070,7 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -1070,7 +1070,7 @@ start_server {tags {"external:skip needs:debug"}} {
r hsetf myhash PX 5000 FVS 1 f2 v2 r hsetf myhash PX 5000 FVS 1 f2 v2
assert_equal [r hsetf myhash FVS 2 f1 v1 f2 v2] "$S_FIELD $S_FIELD_AND_TTL" assert_equal [r hsetf myhash FVS 2 f1 v1 f2 v2] "$S_FIELD $S_FIELD_AND_TTL"
assert_not_equal [r httl myhash 1 f1 f2] "$T_NO_EXPIRY $T_NO_EXPIRY" assert_not_equal [r httl myhash FIELDS 1 f1 f2] "$T_NO_EXPIRY $T_NO_EXPIRY"
} }
test "HSETF - Test 'GETNEW/GETOLD' flag ($type)" { test "HSETF - Test 'GETNEW/GETOLD' flag ($type)" {
...@@ -1136,7 +1136,7 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -1136,7 +1136,7 @@ start_server {tags {"external:skip needs:debug"}} {
test "Test listpack memory usage" { test "Test listpack memory usage" {
r hset myhash f1 v1 f2 v2 f3 v3 f4 v4 f5 v5 r hset myhash f1 v1 f2 v2 f3 v3 f4 v4 f5 v5
r hpexpire myhash 5 2 f2 f4 r hpexpire myhash 5 FIELDS 2 f2 f4
# Just to have code coverage for the new listpack encoding # Just to have code coverage for the new listpack encoding
r memory usage myhash r memory usage myhash
...@@ -1144,7 +1144,7 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -1144,7 +1144,7 @@ start_server {tags {"external:skip needs:debug"}} {
test "Test listpack object encoding" { test "Test listpack object encoding" {
r hset myhash f1 v1 f2 v2 f3 v3 f4 v4 f5 v5 r hset myhash f1 v1 f2 v2 f3 v3 f4 v4 f5 v5
r hpexpire myhash 5 2 f2 f4 r hpexpire myhash 5 FIELDS 2 f2 f4
# Just to have code coverage for the listpackex encoding # Just to have code coverage for the listpackex encoding
assert_equal [r object encoding myhash] "listpackex" assert_equal [r object encoding myhash] "listpackex"
...@@ -1163,7 +1163,7 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -1163,7 +1163,7 @@ start_server {tags {"external:skip needs:debug"}} {
r debug set-active-expire 0 r debug set-active-expire 0
r hset myhash f1 v1 f2 v2 f3 v3 f4 v4 f5 v5 r hset myhash f1 v1 f2 v2 f3 v3 f4 v4 f5 v5
r hpexpire myhash 5 2 f2 f4 r hpexpire myhash 5 FIELDS 2 f2 f4
for {set i 6} {$i < 11} {incr i} { for {set i 6} {$i < 11} {incr i} {
r hset myhash f$i v$i r hset myhash f$i v$i
...@@ -1179,14 +1179,14 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -1179,14 +1179,14 @@ start_server {tags {"external:skip needs:debug"}} {
r debug set-active-expire 0 r debug set-active-expire 0
r hset myhash f1 v1 f2 v2 f3 v3 f4 v4 f5 v5 r hset myhash f1 v1 f2 v2 f3 v3 f4 v4 f5 v5
r hpexpire myhash 10 1 f1 r hpexpire myhash 10 FIELDS 1 f1
for {set i 0} {$i < 2048} {incr i} { for {set i 0} {$i < 2048} {incr i} {
r hset myhash f$i v$i r hset myhash f$i v$i
} }
for {set i 0} {$i < 2048} {incr i} { for {set i 0} {$i < 2048} {incr i} {
r hpexpire myhash 10 1 f$i r hpexpire myhash 10 FIELDS 1 f$i
} }
r debug set-active-expire 1 r debug set-active-expire 1
...@@ -1225,11 +1225,11 @@ start_server {tags {"external:skip needs:debug"}} { ...@@ -1225,11 +1225,11 @@ start_server {tags {"external:skip needs:debug"}} {
# Test with multiple items # Test with multiple items
r hset myhash f1 $payload2 f2 v2 f3 $payload1 f4 v4 r hset myhash f1 $payload2 f2 v2 f3 $payload1 f4 v4
r hexpire myhash 100000 1 f3 r hexpire myhash 100000 FIELDS 1 f3
r hpersist myhash 1 f3 r hpersist myhash FIELDS 1 f3
assert_equal [r hpersist myhash 1 f3] $P_NO_EXPIRY assert_equal [r hpersist myhash FIELDS 1 f3] $P_NO_EXPIRY
r hpexpire myhash 10 1 f1 r hpexpire myhash 10 FIELDS 1 f1
after 20 after 20
assert_equal [lsort [r hgetall myhash]] [lsort "f2 f3 f4 v2 $payload1 v4"] assert_equal [lsort [r hgetall myhash]] [lsort "f2 f3 f4 v2 $payload1 v4"]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment