diff --git a/src/module.c b/src/module.c index ac558acb9..81f726602 100644 --- a/src/module.c +++ b/src/module.c @@ -11188,22 +11188,32 @@ int RM_ScanKey(RedisModuleKey *key, RedisModuleScanCursor *cursor, RedisModuleSc cursor->done = 1; ret = 0; } else if (o->type == OBJ_ZSET || o->type == OBJ_HASH) { - unsigned char *p = lpSeek(o->ptr,0); + unsigned char *lp, *p; unsigned char *vstr; unsigned int vlen; long long vll; + + if (o->type == OBJ_HASH) + lp = hashTypeListpackGetLp(o); + else + lp = o->ptr; + + p = lpSeek(lp,0); while(p) { vstr = lpGetValue(p,&vlen,&vll); robj *field = (vstr != NULL) ? createStringObject((char*)vstr,vlen) : createStringObjectFromLongLongWithSds(vll); - p = lpNext(o->ptr,p); + p = lpNext(lp,p); vstr = lpGetValue(p,&vlen,&vll); robj *value = (vstr != NULL) ? createStringObject((char*)vstr,vlen) : createStringObjectFromLongLongWithSds(vll); fn(key, field, value, privdata); - p = lpNext(o->ptr,p); + p = lpNext(lp,p); + if (o->type == OBJ_HASH && o->encoding == OBJ_ENCODING_LISTPACK_EX) + p = lpNext(lp, p); /* Skip expire time */ + decrRefCount(field); decrRefCount(value); } diff --git a/tests/unit/moduleapi/scan.tcl b/tests/unit/moduleapi/scan.tcl index 1efd6ac55..7cf8e60af 100644 --- a/tests/unit/moduleapi/scan.tcl +++ b/tests/unit/moduleapi/scan.tcl @@ -24,6 +24,14 @@ start_server {tags {"modules"}} { lsort [r scan.scan_key hh1] } {{f1 1}} + test {Module scan hash listpack with hexpire} { + r hmset hh f1 v1 f2 v2 + r hexpire hh 100000 fields 1 f1 + assert_range [r httl hh fields 1 f1] 10000 100000 + assert_encoding listpackex hh + lsort [r scan.scan_key hh] + } {{f1 v1} {f2 v2}} + test {Module scan hash dict} { r config set hash-max-ziplist-entries 2 r hmset hh f3 v3 @@ -31,6 +39,16 @@ start_server {tags {"modules"}} { lsort [r scan.scan_key hh] } {{f1 v1} {f2 v2} {f3 v3}} + test {Module scan hash dict with hexpire} { + r config set hash-max-listpack-entries 1 + r del hh + r hmset hh f1 v1 f2 v2 f3 v3 + r hexpire hh 100000 fields 1 f2 + assert_range [r httl hh fields 1 f2] 10000 100000 + assert_encoding hashtable hh + lsort [r scan.scan_key hh] + } {{f1 v1} {f2 v2} {f3 v3}} + test {Module scan zset listpack} { r zadd zz 1 f1 2 f2 assert_encoding listpack zz