diff options
author | Binbin <binloveplay1314@qq.com> | 2022-12-09 23:08:01 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-09 17:08:01 +0200 |
commit | 20854cb6109c23e65dca0174517f3861a55cb694 (patch) | |
tree | 4a11c1cb4f83d640e66366eadfe88ce85dbada44 /src/t_zset.c | |
parent | 528bb11d7a25cde99e6d48c418662575c64758b2 (diff) | |
download | redis-20854cb6109c23e65dca0174517f3861a55cb694.tar.gz |
Fix zuiFind crash / RM_ScanKey hang on SET object listpack encoding (#11581)
In #11290, we added listpack encoding for SET object.
But forgot to support it in zuiFind, causes ZINTER, ZINTERSTORE,
ZINTERCARD, ZIDFF, ZDIFFSTORE to crash.
And forgot to support it in RM_ScanKey, causes it hang.
This PR add support SET listpack in zuiFind, and in RM_ScanKey.
And add tests for related commands to cover this case.
Other changes:
- There is no reason for zuiFind to go into the internals of the SET.
It can simply use setTypeIsMember and don't care about encoding.
- Remove the `#include "intset.h"` from server.h reduce the chance of
accidental intset API use.
- Move setTypeAddAux, setTypeRemoveAux and setTypeIsMemberAux
interfaces to the header.
- In scanGenericCommand, use setTypeInitIterator and setTypeNext
to handle OBJ_SET scan.
- In RM_ScanKey, improve hash scan mode, use lpGetValue like zset,
they can share code and better performance.
The zuiFind part fixes #11578
Co-authored-by: Oran Agra <oran@redislabs.com>
Co-authored-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
Diffstat (limited to 'src/t_zset.c')
-rw-r--r-- | src/t_zset.c | 26 |
1 files changed, 7 insertions, 19 deletions
diff --git a/src/t_zset.c b/src/t_zset.c index 590652073..eb87c5d7d 100644 --- a/src/t_zset.c +++ b/src/t_zset.c @@ -57,6 +57,7 @@ * from tail to head, useful for ZREVRANGE. */ #include "server.h" +#include "intset.h" /* Compact integer set structure */ #include <math.h> /*----------------------------------------------------------------------------- @@ -2257,26 +2258,13 @@ int zuiFind(zsetopsrc *op, zsetopval *val, double *score) { return 0; if (op->type == OBJ_SET) { - if (op->encoding == OBJ_ENCODING_INTSET) { - if (zuiLongLongFromValue(val) && - intsetFind(op->subject->ptr,val->ell)) - { - *score = 1.0; - return 1; - } else { - return 0; - } - } else if (op->encoding == OBJ_ENCODING_HT) { - dict *ht = op->subject->ptr; - zuiSdsFromValue(val); - if (dictFind(ht,val->ele) != NULL) { - *score = 1.0; - return 1; - } else { - return 0; - } + char *str = val->ele ? val->ele : (char *)val->estr; + size_t len = val->ele ? sdslen(val->ele) : val->elen; + if (setTypeIsMemberAux(op->subject, str, len, val->ell, val->ele != NULL)) { + *score = 1.0; + return 1; } else { - serverPanic("Unknown set encoding"); + return 0; } } else if (op->type == OBJ_ZSET) { zuiSdsFromValue(val); |