1 start_server
{tags
{"zset"}} {
2 proc create_zset
{key items
} {
4 foreach {score
entry} $items {
5 r zadd
$key $score $entry
9 proc basics
{encoding} {
10 if {$encoding == "ziplist"} {
11 r config
set zset-max-ziplist-entries
128
12 r config
set zset-max-ziplist-value
64
13 } elseif
{$encoding == "raw"} {
14 r config
set zset-max-ziplist-entries
0
15 r config
set zset-max-ziplist-value
0
17 puts "Unknown sorted set encoding"
21 test
"Check encoding - $encoding" {
24 assert_encoding
$encoding ztmp
27 test
"ZSET basic ZADD and score update - $encoding" {
32 assert_equal
{x y z
} [r zrange ztmp
0 -1]
35 assert_equal
{y x z
} [r zrange ztmp
0 -1]
38 test
"ZSET element can't be set to NaN with ZADD - $encoding" {
39 assert_error
"*not a double*" {r zadd myzset nan abc
}
42 test
"ZSET element can't be set to NaN with ZINCRBY" {
43 assert_error
"*not a double*" {r zadd myzset nan abc
}
46 test
"ZINCRBY calls leading to NaN result in error" {
47 r zincrby myzset
+inf abc
48 assert_error
"*NaN*" {r zincrby myzset
-inf abc
}
51 test
"ZCARD basics - $encoding" {
52 assert_equal
3 [r zcard ztmp
]
53 assert_equal
0 [r zcard zdoesntexist
]
56 test
"ZRANGE basics - $encoding" {
63 assert_equal
{a b c d
} [r zrange ztmp
0 -1]
64 assert_equal
{a b c
} [r zrange ztmp
0 -2]
65 assert_equal
{b c d
} [r zrange ztmp
1 -1]
66 assert_equal
{b c
} [r zrange ztmp
1 -2]
67 assert_equal
{c d
} [r zrange ztmp
-2 -1]
68 assert_equal
{c
} [r zrange ztmp
-2 -2]
70 # out of range start index
71 assert_equal
{a b c
} [r zrange ztmp
-5 2]
72 assert_equal
{a b
} [r zrange ztmp
-5 1]
73 assert_equal
{} [r zrange ztmp
5 -1]
74 assert_equal
{} [r zrange ztmp
5 -2]
76 # out of range end index
77 assert_equal
{a b c d
} [r zrange ztmp
0 5]
78 assert_equal
{b c d
} [r zrange ztmp
1 5]
79 assert_equal
{} [r zrange ztmp
0 -5]
80 assert_equal
{} [r zrange ztmp
1 -5]
83 assert_equal
{a
1 b
2 c
3 d
4} [r zrange ztmp
0 -1 withscores
]
86 test
"ZREVRANGE basics - $encoding" {
93 assert_equal
{d c b a
} [r zrevrange ztmp
0 -1]
94 assert_equal
{d c b
} [r zrevrange ztmp
0 -2]
95 assert_equal
{c b a
} [r zrevrange ztmp
1 -1]
96 assert_equal
{c b
} [r zrevrange ztmp
1 -2]
97 assert_equal
{b a
} [r zrevrange ztmp
-2 -1]
98 assert_equal
{b
} [r zrevrange ztmp
-2 -2]
100 # out of range start index
101 assert_equal
{d c b
} [r zrevrange ztmp
-5 2]
102 assert_equal
{d c
} [r zrevrange ztmp
-5 1]
103 assert_equal
{} [r zrevrange ztmp
5 -1]
104 assert_equal
{} [r zrevrange ztmp
5 -2]
106 # out of range end index
107 assert_equal
{d c b a
} [r zrevrange ztmp
0 5]
108 assert_equal
{c b a
} [r zrevrange ztmp
1 5]
109 assert_equal
{} [r zrevrange ztmp
0 -5]
110 assert_equal
{} [r zrevrange ztmp
1 -5]
113 assert_equal
{d
4 c
3 b
2 a
1} [r zrevrange ztmp
0 -1 withscores
]
116 test
"ZRANK/ZREVRANK basics - $encoding" {
121 assert_equal
0 [r zrank zranktmp x
]
122 assert_equal
1 [r zrank zranktmp y
]
123 assert_equal
2 [r zrank zranktmp z
]
124 assert_equal
"" [r zrank zranktmp foo
]
125 assert_equal
2 [r zrevrank zranktmp x
]
126 assert_equal
1 [r zrevrank zranktmp y
]
127 assert_equal
0 [r zrevrank zranktmp z
]
128 assert_equal
"" [r zrevrank zranktmp foo
]
131 test
"ZRANK - after deletion - $encoding" {
133 assert_equal
0 [r zrank zranktmp x
]
134 assert_equal
1 [r zrank zranktmp z
]
137 test
"ZINCRBY - can create a new sorted set - $encoding" {
140 assert_equal
{foo
} [r zrange zset
0 -1]
141 assert_equal
1 [r zscore zset foo
]
144 test
"ZINCRBY - increment and decrement - $encoding" {
147 assert_equal
{bar foo
} [r zrange zset
0 -1]
149 r zincrby zset
10 bar
150 r zincrby zset
-5 foo
151 r zincrby zset
-5 bar
152 assert_equal
{foo bar
} [r zrange zset
0 -1]
154 assert_equal
-2 [r zscore zset foo
]
155 assert_equal
6 [r zscore zset bar
]
158 proc create_default_zset
{} {
159 create_zset zset
{-inf a
1 b
2 c
3 d
4 e
5 f
+inf g
}
162 test
"ZRANGEBYSCORE/ZREVRANGEBYSCORE/ZCOUNT basics" {
166 assert_equal
{a b c
} [r zrangebyscore zset
-inf 2]
167 assert_equal
{b c d
} [r zrangebyscore zset
0 3]
168 assert_equal
{d e f
} [r zrangebyscore zset
3 6]
169 assert_equal
{e f g
} [r zrangebyscore zset
4 +inf
]
170 assert_equal
{c b a
} [r zrevrangebyscore zset
2 -inf]
171 assert_equal
{d c b
} [r zrevrangebyscore zset
3 0]
172 assert_equal
{f e d
} [r zrevrangebyscore zset
6 3]
173 assert_equal
{g f e
} [r zrevrangebyscore zset
+inf
4]
174 assert_equal
3 [r zcount zset
0 3]
177 assert_equal
{b
} [r zrangebyscore zset
(-inf (2]
178 assert_equal
{b c
} [r zrangebyscore zset
(0 (3]
179 assert_equal
{e f
} [r zrangebyscore zset
(3 (6]
180 assert_equal
{f
} [r zrangebyscore zset
(4 (+inf
]
181 assert_equal
{b
} [r zrevrangebyscore zset
(2 (-inf]
182 assert_equal
{c b
} [r zrevrangebyscore zset
(3 (0]
183 assert_equal
{f e
} [r zrevrangebyscore zset
(6 (3]
184 assert_equal
{f
} [r zrevrangebyscore zset
(+inf
(4]
185 assert_equal
2 [r zcount zset
(0 (3]
192 assert_equal
{} [r zrangebyscore zset
4 2]
193 assert_equal
{} [r zrangebyscore zset
6 +inf
]
194 assert_equal
{} [r zrangebyscore zset
-inf -6]
195 assert_equal
{} [r zrevrangebyscore zset
+inf
6]
196 assert_equal
{} [r zrevrangebyscore zset
-6 -inf]
199 assert_equal
{} [r zrangebyscore zset
(4 (2]
200 assert_equal
{} [r zrangebyscore zset
2 (2]
201 assert_equal
{} [r zrangebyscore zset
(2 2]
202 assert_equal
{} [r zrangebyscore zset
(6 (+inf
]
203 assert_equal
{} [r zrangebyscore zset
(-inf (-6]
204 assert_equal
{} [r zrevrangebyscore zset
(+inf
(6]
205 assert_equal
{} [r zrevrangebyscore zset
(-6 (-inf]
208 assert_equal
{} [r zrangebyscore zset
2.4 2.6]
209 assert_equal
{} [r zrangebyscore zset
(2.4 2.6]
210 assert_equal
{} [r zrangebyscore zset
2.4 (2.6]
211 assert_equal
{} [r zrangebyscore zset
(2.4 (2.6]
214 test
"ZRANGEBYSCORE with WITHSCORES" {
216 assert_equal
{b
1 c
2 d
3} [r zrangebyscore zset
0 3 withscores
]
217 assert_equal
{d
3 c
2 b
1} [r zrevrangebyscore zset
3 0 withscores
]
220 test
"ZRANGEBYSCORE with LIMIT" {
222 assert_equal
{b c
} [r zrangebyscore zset
0 10 LIMIT
0 2]
223 assert_equal
{d e f
} [r zrangebyscore zset
0 10 LIMIT
2 3]
224 assert_equal
{d e f
} [r zrangebyscore zset
0 10 LIMIT
2 10]
225 assert_equal
{} [r zrangebyscore zset
0 10 LIMIT
20 10]
226 assert_equal
{f e
} [r zrevrangebyscore zset
10 0 LIMIT
0 2]
227 assert_equal
{d c b
} [r zrevrangebyscore zset
10 0 LIMIT
2 3]
228 assert_equal
{d c b
} [r zrevrangebyscore zset
10 0 LIMIT
2 10]
229 assert_equal
{} [r zrevrangebyscore zset
10 0 LIMIT
20 10]
232 test
"ZRANGEBYSCORE with LIMIT and WITHSCORES" {
234 assert_equal
{e
4 f
5} [r zrangebyscore zset
2 5 LIMIT
2 3 WITHSCORES
]
235 assert_equal
{d
3 c
2} [r zrevrangebyscore zset
5 2 LIMIT
2 3 WITHSCORES
]
238 test
"ZRANGEBYSCORE with non-value min or max" {
239 assert_error
"*not a double*" {r zrangebyscore fooz str
1}
240 assert_error
"*not a double*" {r zrangebyscore fooz
1 str
}
241 assert_error
"*not a double*" {r zrangebyscore fooz
1 NaN
}
244 test
"ZREMRANGEBYSCORE basics" {
245 proc remrangebyscore
{min max
} {
246 create_zset zset
{1 a
2 b
3 c
4 d
5 e
}
247 r zremrangebyscore zset
$min $max
251 assert_equal
3 [remrangebyscore
2 4]
252 assert_equal
{a e
} [r zrange zset
0 -1]
255 assert_equal
1 [remrangebyscore
-10 1]
256 assert_equal
{b c d e
} [r zrange zset
0 -1]
259 assert_equal
1 [remrangebyscore
5 10]
260 assert_equal
{a b c d
} [r zrange zset
0 -1]
263 assert_equal
0 [remrangebyscore
4 2]
264 assert_equal
{a b c d e
} [r zrange zset
0 -1]
267 assert_equal
3 [remrangebyscore
-inf 3]
268 assert_equal
{d e
} [r zrange zset
0 -1]
271 assert_equal
3 [remrangebyscore
3 +inf
]
272 assert_equal
{a b
} [r zrange zset
0 -1]
275 assert_equal
5 [remrangebyscore
-inf +inf
]
276 assert_equal
{} [r zrange zset
0 -1]
279 assert_equal
4 [remrangebyscore
(1 5]
280 assert_equal
{a
} [r zrange zset
0 -1]
281 assert_equal
3 [remrangebyscore
(2 5]
282 assert_equal
{a b
} [r zrange zset
0 -1]
285 assert_equal
4 [remrangebyscore
1 (5]
286 assert_equal
{e
} [r zrange zset
0 -1]
287 assert_equal
3 [remrangebyscore
1 (4]
288 assert_equal
{d e
} [r zrange zset
0 -1]
290 # exclusive min and max
291 assert_equal
3 [remrangebyscore
(1 (5]
292 assert_equal
{a e
} [r zrange zset
0 -1]
295 test
"ZREMRANGEBYSCORE with non-value min or max" {
296 assert_error
"*not a double*" {r zremrangebyscore fooz str
1}
297 assert_error
"*not a double*" {r zremrangebyscore fooz
1 str
}
298 assert_error
"*not a double*" {r zremrangebyscore fooz
1 NaN
}
301 test
"ZREMRANGEBYRANK basics" {
302 proc remrangebyrank
{min max
} {
303 create_zset zset
{1 a
2 b
3 c
4 d
5 e
}
304 r zremrangebyrank zset
$min $max
308 assert_equal
3 [remrangebyrank
1 3]
309 assert_equal
{a e
} [r zrange zset
0 -1]
312 assert_equal
1 [remrangebyrank
-10 0]
313 assert_equal
{b c d e
} [r zrange zset
0 -1]
316 assert_equal
0 [remrangebyrank
10 -1]
317 assert_equal
{a b c d e
} [r zrange zset
0 -1]
320 assert_equal
0 [remrangebyrank
0 -10]
321 assert_equal
{a b c d e
} [r zrange zset
0 -1]
324 assert_equal
5 [remrangebyrank
0 10]
325 assert_equal
{} [r zrange zset
0 -1]
328 test
"ZUNIONSTORE against non-existing key doesn't set destination - $encoding" {
330 assert_equal
0 [r zunionstore dst_key
1 zseta
]
331 assert_equal
0 [r exists dst_key
]
334 test
"ZUNIONSTORE basics - $encoding" {
335 r del zseta zsetb zsetc
343 assert_equal
4 [r zunionstore zsetc
2 zseta zsetb
]
344 assert_equal
{a
1 b
3 d
3 c
5} [r zrange zsetc
0 -1 withscores
]
347 test
"ZUNIONSTORE with weights - $encoding" {
348 assert_equal
4 [r zunionstore zsetc
2 zseta zsetb weights
2 3]
349 assert_equal
{a
2 b
7 d
9 c
12} [r zrange zsetc
0 -1 withscores
]
352 test
"ZUNIONSTORE with a regular set and weights - $encoding" {
358 assert_equal
4 [r zunionstore zsetc
2 seta zsetb weights
2 3]
359 assert_equal
{a
2 b
5 c
8 d
9} [r zrange zsetc
0 -1 withscores
]
362 test
"ZUNIONSTORE with AGGREGATE MIN - $encoding" {
363 assert_equal
4 [r zunionstore zsetc
2 zseta zsetb aggregate min
]
364 assert_equal
{a
1 b
1 c
2 d
3} [r zrange zsetc
0 -1 withscores
]
367 test
"ZUNIONSTORE with AGGREGATE MAX - $encoding" {
368 assert_equal
4 [r zunionstore zsetc
2 zseta zsetb aggregate max
]
369 assert_equal
{a
1 b
2 c
3 d
3} [r zrange zsetc
0 -1 withscores
]
372 test
"ZINTERSTORE basics - $encoding" {
373 assert_equal
2 [r zinterstore zsetc
2 zseta zsetb
]
374 assert_equal
{b
3 c
5} [r zrange zsetc
0 -1 withscores
]
377 test
"ZINTERSTORE with weights - $encoding" {
378 assert_equal
2 [r zinterstore zsetc
2 zseta zsetb weights
2 3]
379 assert_equal
{b
7 c
12} [r zrange zsetc
0 -1 withscores
]
382 test
"ZINTERSTORE with a regular set and weights - $encoding" {
387 assert_equal
2 [r zinterstore zsetc
2 seta zsetb weights
2 3]
388 assert_equal
{b
5 c
8} [r zrange zsetc
0 -1 withscores
]
391 test
"ZINTERSTORE with AGGREGATE MIN - $encoding" {
392 assert_equal
2 [r zinterstore zsetc
2 zseta zsetb aggregate min
]
393 assert_equal
{b
1 c
2} [r zrange zsetc
0 -1 withscores
]
396 test
"ZINTERSTORE with AGGREGATE MAX - $encoding" {
397 assert_equal
2 [r zinterstore zsetc
2 zseta zsetb aggregate max
]
398 assert_equal
{b
2 c
3} [r zrange zsetc
0 -1 withscores
]
401 foreach cmd
{ZUNIONSTORE ZINTERSTORE
} {
402 test
"$cmd with +inf/-inf scores - $encoding" {
403 r del zsetinf1 zsetinf2
405 r zadd zsetinf1
+inf key
406 r zadd zsetinf2
+inf key
407 r
$cmd zsetinf3
2 zsetinf1 zsetinf2
408 assert_equal inf
[r zscore zsetinf3 key
]
410 r zadd zsetinf1
-inf key
411 r zadd zsetinf2
+inf key
412 r
$cmd zsetinf3
2 zsetinf1 zsetinf2
413 assert_equal
0 [r zscore zsetinf3 key
]
415 r zadd zsetinf1
+inf key
416 r zadd zsetinf2
-inf key
417 r
$cmd zsetinf3
2 zsetinf1 zsetinf2
418 assert_equal
0 [r zscore zsetinf3 key
]
420 r zadd zsetinf1
-inf key
421 r zadd zsetinf2
-inf key
422 r
$cmd zsetinf3
2 zsetinf1 zsetinf2
423 assert_equal
-inf [r zscore zsetinf3 key
]
426 test
"$cmd with NaN weights $encoding" {
427 r del zsetinf1 zsetinf2
429 r zadd zsetinf1
1.0 key
430 r zadd zsetinf2
1.0 key
431 assert_error
"*weight value is not a double*" {
432 r
$cmd zsetinf3
2 zsetinf1 zsetinf2 weights nan nan
441 proc stressers
{encoding} {
442 if {$encoding == "ziplist"} {
443 # Little extra to allow proper fuzzing in the sorting stresser
444 r config
set zset-max-ziplist-entries
256
445 r config
set zset-max-ziplist-value
64
447 } elseif
{$encoding == "raw"} {
448 r config
set zset-max-ziplist-entries
0
449 r config
set zset-max-ziplist-value
0
452 puts "Unknown sorted set encoding"
456 test
"ZSCORE - $encoding" {
459 for {set i
0} {$i < $elements} {incr i
} {
460 set score
[expr rand
()]
462 r zadd zscoretest
$score $i
465 assert_encoding
$encoding zscoretest
466 for {set i
0} {$i < $elements} {incr i
} {
467 assert_equal
[lindex $aux $i] [r zscore zscoretest
$i]
471 test
"ZSCORE after a DEBUG RELOAD - $encoding" {
474 for {set i
0} {$i < $elements} {incr i
} {
475 set score
[expr rand
()]
477 r zadd zscoretest
$score $i
481 assert_encoding
$encoding zscoretest
482 for {set i
0} {$i < $elements} {incr i
} {
483 assert_equal
[lindex $aux $i] [r zscore zscoretest
$i]
487 test
"ZSET sorting stresser - $encoding" {
489 for {set test
0} {$test < 2} {incr test
} {
490 unset -nocomplain auxarray
491 array set auxarray
{}
494 for {set i
0} {$i < $elements} {incr i
} {
496 set score
[expr rand
()]
498 set score
[expr int
(rand
()*10)]
500 set auxarray
($i) $score
501 r zadd myzset
$score $i
503 if {[expr rand
()] < .2} {
504 set j
[expr int
(rand
()*1000)]
506 set score
[expr rand
()]
508 set score
[expr int
(rand
()*10)]
510 set auxarray
($j) $score
511 r zadd myzset
$score $j
514 foreach {item score
} [array get auxarray
] {
515 lappend auxlist
[list $score $item]
517 set sorted
[lsort -command zlistAlikeSort
$auxlist]
520 lappend auxlist
[lindex $x 1]
523 assert_encoding
$encoding myzset
524 set fromredis
[r zrange myzset
0 -1]
526 for {set i
0} {$i < [llength $fromredis]} {incr i
} {
527 if {[lindex $fromredis $i] != [lindex $auxlist $i]} {
532 assert_equal
0 $delta
535 test
"ZRANGEBYSCORE fuzzy test, 100 ranges in $elements element sorted set - $encoding" {
538 for {set i
0} {$i < $elements} {incr i
} {
539 r zadd zset
[expr rand
()] $i
542 assert_encoding
$encoding zset
543 for {set i
0} {$i < 100} {incr i
} {
544 set min
[expr rand
()]
545 set max
[expr rand
()]
551 set low
[r zrangebyscore zset
-inf $min]
552 set ok
[r zrangebyscore zset
$min $max]
553 set high
[r zrangebyscore zset
$max +inf
]
554 set lowx
[r zrangebyscore zset
-inf ($min]
555 set okx
[r zrangebyscore zset
($min ($max]
556 set highx
[r zrangebyscore zset
($max +inf
]
558 if {[r zcount zset
-inf $min] != [llength $low]} {
559 append err
"Error, len does not match zcount\n"
561 if {[r zcount zset
$min $max] != [llength $ok]} {
562 append err
"Error, len does not match zcount\n"
564 if {[r zcount zset
$max +inf
] != [llength $high]} {
565 append err
"Error, len does not match zcount\n"
567 if {[r zcount zset
-inf ($min] != [llength $lowx]} {
568 append err
"Error, len does not match zcount\n"
570 if {[r zcount zset
($min ($max] != [llength $okx]} {
571 append err
"Error, len does not match zcount\n"
573 if {[r zcount zset
($max +inf
] != [llength $highx]} {
574 append err
"Error, len does not match zcount\n"
578 set score
[r zscore zset
$x]
580 append err
"Error, score for $x is $score > $min\n"
584 set score
[r zscore zset
$x]
585 if {$score >= $min} {
586 append err
"Error, score for $x is $score >= $min\n"
590 set score
[r zscore zset
$x]
591 if {$score < $min ||
$score > $max} {
592 append err
"Error, score for $x is $score outside $min-$max range\n"
596 set score
[r zscore zset
$x]
597 if {$score <= $min ||
$score >= $max} {
598 append err
"Error, score for $x is $score outside $min-$max open range\n"
602 set score
[r zscore zset
$x]
604 append err
"Error, score for $x is $score < $max\n"
608 set score
[r zscore zset
$x]
609 if {$score <= $max} {
610 append err
"Error, score for $x is $score <= $max\n"
617 test
"ZSETs skiplist implementation backlink consistency test - $encoding" {
619 for {set j
0} {$j < $elements} {incr j
} {
620 r zadd myzset
[expr rand
()] "Element-$j"
621 r zrem myzset
"Element-[expr int(rand()*$elements)]"
624 assert_encoding
$encoding myzset
625 set l1
[r zrange myzset
0 -1]
626 set l2
[r zrevrange myzset
0 -1]
627 for {set j
0} {$j < [llength $l1]} {incr j
} {
628 if {[lindex $l1 $j] ne
[lindex $l2 end-
$j]} {
635 test
"ZSETs ZRANK augmented skip list stress testing - $encoding" {
638 for {set k
0} {$k < 2000} {incr k
} {
639 set i
[expr {$k % $elements}]
640 if {[expr rand
()] < .2} {
643 set score
[expr rand
()]
644 r zadd myzset
$score $i
645 assert_encoding
$encoding myzset
648 set card
[r zcard myzset
]
650 set index
[randomInt
$card]
651 set ele
[lindex [r zrange myzset
$index $index] 0]
652 set rank
[r zrank myzset
$ele]
653 if {$rank != $index} {
654 set err
"$ele RANK is wrong! ($rank != $index)"