mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 16:18:28 -05:00
Fix the bug that caused hash encoding errors when using hincrbyfloat or hincrby commands (#10479)
Fixed a bug that used the `hincrbyfloat` or `hincrby` commands to make the field or value exceed the `hash_max_listpack_value` but did not change the object encoding of the hash structure. Add a length check for field and value, check the length of value first, if the length of value does not exceed `hash_max_listpack_value` then check the length of field. If the length of field or value is too long, it will reduce the efficiency of listpack, and the object encoding will become hashtable after AOF restart, so this is also to keep the same before and after AOF restart.
This commit is contained in:
parent
8a7049d363
commit
f110de4b23
@ -205,6 +205,14 @@ int hashTypeExists(robj *o, sds field) {
|
||||
int hashTypeSet(robj *o, sds field, sds value, int flags) {
|
||||
int update = 0;
|
||||
|
||||
/* Check if the field is too long for listpack, and convert before adding the item.
|
||||
* This is needed for HINCRBY* case since in other commands this is handled early by
|
||||
* hashTypeTryConversion, so this check will be a NOP. */
|
||||
if (o->encoding == OBJ_ENCODING_LISTPACK) {
|
||||
if (sdslen(field) > server.hash_max_listpack_value || sdslen(value) > server.hash_max_listpack_value)
|
||||
hashTypeConvert(o, OBJ_ENCODING_HT);
|
||||
}
|
||||
|
||||
if (o->encoding == OBJ_ENCODING_LISTPACK) {
|
||||
unsigned char *zl, *fptr, *vptr;
|
||||
|
||||
|
@ -648,6 +648,31 @@ start_server {tags {"hash"}} {
|
||||
}
|
||||
}
|
||||
|
||||
test {HINCRBYFLOAT over hash-max-listpack-value encoded with a listpack} {
|
||||
set original_max_value [lindex [r config get hash-max-ziplist-value] 1]
|
||||
r config set hash-max-listpack-value 8
|
||||
|
||||
# hash's value exceeds hash-max-listpack-value
|
||||
r del smallhash
|
||||
r del bighash
|
||||
r hset smallhash tmp 0
|
||||
r hset bighash tmp 0
|
||||
r hincrbyfloat smallhash tmp 0.000005
|
||||
r hincrbyfloat bighash tmp 0.0000005
|
||||
assert_encoding listpack smallhash
|
||||
assert_encoding hashtable bighash
|
||||
|
||||
# hash's field exceeds hash-max-listpack-value
|
||||
r del smallhash
|
||||
r del bighash
|
||||
r hincrbyfloat smallhash abcdefgh 1
|
||||
r hincrbyfloat bighash abcdefghi 1
|
||||
assert_encoding listpack smallhash
|
||||
assert_encoding hashtable bighash
|
||||
|
||||
r config set hash-max-listpack-value $original_max_value
|
||||
}
|
||||
|
||||
test {Hash ziplist regression test for large keys} {
|
||||
r hset hash kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk a
|
||||
r hset hash kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk b
|
||||
|
Loading…
Reference in New Issue
Block a user