Skip to content

Commit 2189100

Browse files
authored
optimize zset conversion on large ZRANGESTORE (redis#10789)
when we know the size of the zset we're gonna store in advance, we can check if it's greater than the listpack encoding threshold, in which case we can create a skiplist from the get go, and avoid converting the listpack to skiplist later after it was already populated.
1 parent 8ef4f1d commit 2189100

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

src/t_zset.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -2952,8 +2952,10 @@ static void zrangeResultFinalizeClient(zrange_result_handler *handler,
29522952
/* Result handler methods for storing the ZRANGESTORE to a zset. */
29532953
static void zrangeResultBeginStore(zrange_result_handler *handler, long length)
29542954
{
2955-
UNUSED(length);
2956-
handler->dstobj = createZsetListpackObject();
2955+
if (length > (long)server.zset_max_listpack_entries)
2956+
handler->dstobj = createZsetObject();
2957+
else
2958+
handler->dstobj = createZsetListpackObject();
29572959
}
29582960

29592961
static void zrangeResultEmitCBufferForStore(zrange_result_handler *handler,

tests/unit/type/zset.tcl

+13-1
Original file line numberDiff line numberDiff line change
@@ -2208,7 +2208,7 @@ start_server {tags {"zset"}} {
22082208
assert_match "*syntax*" $err
22092209
}
22102210

2211-
test {ZRANGESTORE with zset-max-listpack-entries 0 dst key should use skiplist encoding} {
2211+
test {ZRANGESTORE with zset-max-listpack-entries 0 #10767 case} {
22122212
set original_max [lindex [r config get zset-max-listpack-entries] 1]
22132213
r config set zset-max-listpack-entries 0
22142214
r del z1{t} z2{t}
@@ -2217,6 +2217,18 @@ start_server {tags {"zset"}} {
22172217
r config set zset-max-listpack-entries $original_max
22182218
}
22192219

2220+
test {ZRANGESTORE with zset-max-listpack-entries 1 dst key should use skiplist encoding} {
2221+
set original_max [lindex [r config get zset-max-listpack-entries] 1]
2222+
r config set zset-max-listpack-entries 1
2223+
r del z1{t} z2{t} z3{t}
2224+
r zadd z1{t} 1 a 2 b
2225+
assert_equal 1 [r zrangestore z2{t} z1{t} 0 0]
2226+
assert_encoding listpack z2{t}
2227+
assert_equal 2 [r zrangestore z3{t} z1{t} 0 1]
2228+
assert_encoding skiplist z3{t}
2229+
r config set zset-max-listpack-entries $original_max
2230+
}
2231+
22202232
test {ZRANGE invalid syntax} {
22212233
catch {r zrange z1{t} 0 -1 limit 1 2} err
22222234
assert_match "*syntax*" $err

0 commit comments

Comments
 (0)