diff options
author | Binbin <binloveplay1314@qq.com> | 2023-05-17 02:32:21 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-16 11:32:21 -0700 |
commit | fd566f405094c77f5b6b84195c93552b9e01d4a8 (patch) | |
tree | ce0538deaa96cc18bea56d7cafb98e91fa63fc41 /src | |
parent | e45272884e61f266662bcf0e8f3799c986236de6 (diff) | |
download | redis-fd566f405094c77f5b6b84195c93552b9e01d4a8.tar.gz |
Fix for set max entries edge case in setTypeCreate / setTypeMaybeConvert (#12183)
In the judgment in setTypeCreate, we should judge size_hint <= max_entries.
This results in the following inconsistencies:
```
127.0.0.1:6379> config set set-max-intset-entries 5 set-max-listpack-entries 5
OK
127.0.0.1:6379> sadd intset_set1 1 2 3 4 5
(integer) 5
127.0.0.1:6379> object encoding intset_set1
"hashtable"
127.0.0.1:6379> sadd intset_set2 1 2 3 4
(integer) 4
127.0.0.1:6379> sadd intset_set2 5
(integer) 1
127.0.0.1:6379> object encoding intset_set2
"intset"
127.0.0.1:6379> sadd listpack_set1 a 1 2 3 4
(integer) 5
127.0.0.1:6379> object encoding listpack_set1
"hashtable"
127.0.0.1:6379> sadd listpack_set2 a 1 2 3
(integer) 4
127.0.0.1:6379> sadd listpack_set2 4
(integer) 1
127.0.0.1:6379> object encoding listpack_set2
"listpack"
```
This was introduced in #12019, added corresponding tests.
Diffstat (limited to 'src')
-rw-r--r-- | src/t_hash.c | 2 | ||||
-rw-r--r-- | src/t_set.c | 14 |
2 files changed, 8 insertions, 8 deletions
diff --git a/src/t_hash.c b/src/t_hash.c index f7d5af649..2d50ca304 100644 --- a/src/t_hash.c +++ b/src/t_hash.c @@ -45,7 +45,7 @@ void hashTypeTryConversion(robj *o, robj **argv, int start, int end) { /* We guess that most of the values in the input are unique, so * if there are enough arguments we create a pre-sized hash, which - * might overallocate memory if their are duplicates. */ + * might over allocate memory if there are duplicates. */ size_t new_fields = (end - start + 1) / 2; if (new_fields > server.hash_max_listpack_entries) { hashTypeConvert(o, OBJ_ENCODING_HT); diff --git a/src/t_set.c b/src/t_set.c index 56ad95a53..c65203396 100644 --- a/src/t_set.c +++ b/src/t_set.c @@ -38,19 +38,19 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum, robj *dstkey, int op); /* Factory method to return a set that *can* hold "value". When the object has - * an integer-encodable value, an intset will be returned. Otherwise a regular - * hash table. + * an integer-encodable value, an intset will be returned. Otherwise a listpack + * or a regular hash table. * * The size hint indicates approximately how many items will be added which is * used to determine the initial representation. */ robj *setTypeCreate(sds value, size_t size_hint) { - if (isSdsRepresentableAsLongLong(value,NULL) == C_OK && size_hint < server.set_max_intset_entries) + if (isSdsRepresentableAsLongLong(value,NULL) == C_OK && size_hint <= server.set_max_intset_entries) return createIntsetObject(); - if (size_hint < server.set_max_listpack_entries) + if (size_hint <= server.set_max_listpack_entries) return createSetListpackObject(); /* We may oversize the set by using the hint if the hint is not accurate, - * but we will assume this is accpetable to maximize performance. */ + * but we will assume this is acceptable to maximize performance. */ robj *o = createSetObject(); dictExpand(o->ptr, size_hint); return o; @@ -59,8 +59,8 @@ robj *setTypeCreate(sds value, size_t size_hint) { /* Check if the existing set should be converted to another encoding based off the * the size hint. */ void setTypeMaybeConvert(robj *set, size_t size_hint) { - if ((set->encoding == OBJ_ENCODING_LISTPACK && size_hint >= server.set_max_listpack_entries) - || (set->encoding == OBJ_ENCODING_INTSET && size_hint >= server.set_max_intset_entries)) + if ((set->encoding == OBJ_ENCODING_LISTPACK && size_hint > server.set_max_listpack_entries) + || (set->encoding == OBJ_ENCODING_INTSET && size_hint > server.set_max_intset_entries)) { setTypeConvertAndExpand(set, OBJ_ENCODING_HT, size_hint, 1); } |