From 39f716a121dd66d9a13b14797ef4bdcff531e27b Mon Sep 17 00:00:00 2001 From: thomaston <411598110@qq.com> Date: Wed, 18 Nov 2020 00:35:56 +0800 Subject: [PATCH] ZREVRANGEBYSCORE Optimization for out of range offset (#5773) ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] When the offset is too large, the query is very slow. Especially when the offset is greater than the length of zset it is easy to determine whether the offset is greater than the length of zset at first, and If it exceed the length of zset, then return directly. Co-authored-by: Oran Agra --- src/t_zset.c | 6 ++++++ tests/unit/type/zset.tcl | 1 + 2 files changed, 7 insertions(+) diff --git a/src/t_zset.c b/src/t_zset.c index 07581673e..6147674ff 100644 --- a/src/t_zset.c +++ b/src/t_zset.c @@ -2906,6 +2906,12 @@ void genericZrangebyscoreCommand(client *c, int reverse) { if ((zobj = lookupKeyReadOrReply(c,key,shared.emptyarray)) == NULL || checkType(c,zobj,OBJ_ZSET)) return; + /* For invalid offset, return directly. */ + if (offset > 0 && offset >= (long)zsetLength(zobj)) { + addReply(c,shared.emptyarray); + return; + } + if (zobj->encoding == OBJ_ENCODING_ZIPLIST) { unsigned char *zl = zobj->ptr; unsigned char *eptr, *sptr; diff --git a/tests/unit/type/zset.tcl b/tests/unit/type/zset.tcl index d8fccd33c..c1406797b 100644 --- a/tests/unit/type/zset.tcl +++ b/tests/unit/type/zset.tcl @@ -432,6 +432,7 @@ start_server {tags {"zset"}} { create_default_zset assert_equal {e 4 f 5} [r zrangebyscore zset 2 5 LIMIT 2 3 WITHSCORES] assert_equal {d 3 c 2} [r zrevrangebyscore zset 5 2 LIMIT 2 3 WITHSCORES] + assert_equal {} [r zrangebyscore zset 2 5 LIMIT 12 13 WITHSCORES] } test "ZRANGEBYSCORE with non-value min or max" {