4 "list-max-ziplist-value" 16
5 "list-max-ziplist-entries" 256
8 # We need a value larger than list-max-ziplist-value to make sure
9 # the list has the right encoding when it is swapped in again.
10 array set largevalue
{}
11 set largevalue
(ziplist
) "hello"
12 set largevalue
(linkedlist
) [string repeat
"hello" 4]
14 test
{LPUSH
, RPUSH
, LLENGTH
, LINDEX
- ziplist
} {
15 # first lpush then rpush
16 assert_equal
1 [r lpush myziplist1 a
]
17 assert_equal
2 [r rpush myziplist1 b
]
18 assert_equal
3 [r rpush myziplist1 c
]
19 assert_equal
3 [r llen myziplist1
]
20 assert_equal a
[r
lindex myziplist1
0]
21 assert_equal b
[r
lindex myziplist1
1]
22 assert_equal c
[r
lindex myziplist1
2]
23 assert_encoding ziplist myziplist1
25 # first rpush then lpush
26 assert_equal
1 [r rpush myziplist2 a
]
27 assert_equal
2 [r lpush myziplist2 b
]
28 assert_equal
3 [r lpush myziplist2 c
]
29 assert_equal
3 [r llen myziplist2
]
30 assert_equal c
[r
lindex myziplist2
0]
31 assert_equal b
[r
lindex myziplist2
1]
32 assert_equal a
[r
lindex myziplist2
2]
33 assert_encoding ziplist myziplist2
36 test
{LPUSH
, RPUSH
, LLENGTH
, LINDEX
- regular
list} {
37 # first lpush then rpush
38 assert_equal
1 [r lpush mylist1
$largevalue(linkedlist
)]
39 assert_encoding linkedlist mylist1
40 assert_equal
2 [r rpush mylist1 b
]
41 assert_equal
3 [r rpush mylist1 c
]
42 assert_equal
3 [r llen mylist1
]
43 assert_equal
$largevalue(linkedlist
) [r
lindex mylist1
0]
44 assert_equal b
[r
lindex mylist1
1]
45 assert_equal c
[r
lindex mylist1
2]
47 # first rpush then lpush
48 assert_equal
1 [r rpush mylist2
$largevalue(linkedlist
)]
49 assert_encoding linkedlist mylist2
50 assert_equal
2 [r lpush mylist2 b
]
51 assert_equal
3 [r lpush mylist2 c
]
52 assert_equal
3 [r llen mylist2
]
53 assert_equal c
[r
lindex mylist2
0]
54 assert_equal b
[r
lindex mylist2
1]
55 assert_equal
$largevalue(linkedlist
) [r
lindex mylist2
2]
58 test
{DEL a
list - ziplist
} {
59 assert_equal
1 [r del myziplist2
]
60 assert_equal
0 [r exists myziplist2
]
61 assert_equal
0 [r llen myziplist2
]
64 test
{DEL a
list - regular
list} {
65 assert_equal
1 [r del mylist2
]
66 assert_equal
0 [r exists mylist2
]
67 assert_equal
0 [r llen mylist2
]
70 proc create_ziplist
{key entries
} {
72 foreach entry $entries { r rpush
$key $entry }
73 assert_encoding ziplist
$key
76 proc create_linkedlist
{key entries
} {
78 foreach entry $entries { r rpush
$key $entry }
79 assert_encoding linkedlist
$key
82 foreach {type large
} [array get largevalue
] {
83 test
"BLPOP, BRPOP: single existing list - $type" {
84 set rd
[redis_deferring_client
]
85 create_
$type blist
"a b $large c d"
88 assert_equal
{blist a
} [$rd read]
90 assert_equal
{blist d
} [$rd read]
93 assert_equal
{blist b
} [$rd read]
95 assert_equal
{blist c
} [$rd read]
98 test
"BLPOP, BRPOP: multiple existing lists - $type" {
99 set rd
[redis_deferring_client
]
100 create_
$type blist1
"a $large c"
101 create_
$type blist2
"d $large f"
103 $rd blpop blist1 blist2
1
104 assert_equal
{blist1 a
} [$rd read]
105 $rd brpop blist1 blist2
1
106 assert_equal
{blist1 c
} [$rd read]
107 assert_equal
1 [r llen blist1
]
108 assert_equal
3 [r llen blist2
]
110 $rd blpop blist2 blist1
1
111 assert_equal
{blist2 d
} [$rd read]
112 $rd brpop blist2 blist1
1
113 assert_equal
{blist2 f
} [$rd read]
114 assert_equal
1 [r llen blist1
]
115 assert_equal
1 [r llen blist2
]
118 test
"BLPOP, BRPOP: second list has an entry - $type" {
119 set rd
[redis_deferring_client
]
121 create_
$type blist2
"d $large f"
123 $rd blpop blist1 blist2
1
124 assert_equal
{blist2 d
} [$rd read]
125 $rd brpop blist1 blist2
1
126 assert_equal
{blist2 f
} [$rd read]
127 assert_equal
0 [r llen blist1
]
128 assert_equal
1 [r llen blist2
]
132 foreach {pop
} {BLPOP BRPOP
} {
133 test
"$pop: with single empty list argument" {
134 set rd
[redis_deferring_client
]
138 assert_equal
{blist1 foo
} [$rd read]
139 assert_equal
0 [r exists blist1
]
142 test
"$pop: second argument is not a list" {
143 set rd
[redis_deferring_client
]
146 $rd $pop blist1 blist2
1
147 assert_error
"ERR*wrong kind*" {$rd read}
150 test
"$pop: timeout" {
151 set rd
[redis_deferring_client
]
153 $rd $pop blist1 blist2
1
154 assert_equal
{} [$rd read]
157 test
"$pop: arguments are empty" {
158 set rd
[redis_deferring_client
]
161 $rd $pop blist1 blist2
1
163 assert_equal
{blist1 foo
} [$rd read]
164 assert_equal
0 [r exists blist1
]
165 assert_equal
0 [r exists blist2
]
167 $rd $pop blist1 blist2
1
169 assert_equal
{blist2 foo
} [$rd read]
170 assert_equal
0 [r exists blist1
]
171 assert_equal
0 [r exists blist2
]
175 test
{LPUSHX
, RPUSHX
- generic
} {
177 assert_equal
0 [r lpushx xlist a
]
178 assert_equal
0 [r llen xlist
]
179 assert_equal
0 [r rpushx xlist a
]
180 assert_equal
0 [r llen xlist
]
183 foreach {type large
} [array get largevalue
] {
184 test
"LPUSHX, RPUSHX - $type" {
185 create_
$type xlist
"$large c"
186 assert_equal
3 [r rpushx xlist d
]
187 assert_equal
4 [r lpushx xlist a
]
188 assert_equal
"a $large c d" [r
lrange xlist
0 -1]
191 test
"LINSERT - $type" {
192 create_
$type xlist
"a $large c d"
193 assert_equal
5 [r
linsert xlist before c zz
]
194 assert_equal
"a $large zz c d" [r
lrange xlist
0 10]
195 assert_equal
6 [r
linsert xlist
after c yy
]
196 assert_equal
"a $large zz c yy d" [r
lrange xlist
0 10]
197 assert_equal
7 [r
linsert xlist
after d dd
]
198 assert_equal
-1 [r
linsert xlist
after bad ddd
]
199 assert_equal
"a $large zz c yy d dd" [r
lrange xlist
0 10]
200 assert_equal
8 [r
linsert xlist before a aa
]
201 assert_equal
-1 [r
linsert xlist before bad aaa
]
202 assert_equal
"aa a $large zz c yy d dd" [r
lrange xlist
0 10]
204 # check inserting integer encoded value
205 assert_equal
9 [r
linsert xlist before aa
42]
206 assert_equal
42 [r
lrange xlist
0 0]
210 test
{LPUSHX
, RPUSHX convert from ziplist to
list} {
211 set large
$largevalue(linkedlist
)
213 # convert when a large value is pushed
214 create_ziplist xlist a
215 assert_equal
2 [r rpushx xlist
$large]
216 assert_encoding linkedlist xlist
217 create_ziplist xlist a
218 assert_equal
2 [r lpushx xlist
$large]
219 assert_encoding linkedlist xlist
221 # convert when the length threshold is exceeded
222 create_ziplist xlist
[lrepeat
256 a
]
223 assert_equal
257 [r rpushx xlist b
]
224 assert_encoding linkedlist xlist
225 create_ziplist xlist
[lrepeat
256 a
]
226 assert_equal
257 [r lpushx xlist b
]
227 assert_encoding linkedlist xlist
230 test
{LINSERT convert from ziplist to
list} {
231 set large
$largevalue(linkedlist
)
233 # convert when a large value is inserted
234 create_ziplist xlist a
235 assert_equal
2 [r
linsert xlist before a
$large]
236 assert_encoding linkedlist xlist
237 create_ziplist xlist a
238 assert_equal
2 [r
linsert xlist
after a
$large]
239 assert_encoding linkedlist xlist
241 # convert when the length threshold is exceeded
242 create_ziplist xlist
[lrepeat
256 a
]
243 assert_equal
257 [r
linsert xlist before a a
]
244 assert_encoding linkedlist xlist
245 create_ziplist xlist
[lrepeat
256 a
]
246 assert_equal
257 [r
linsert xlist
after a a
]
247 assert_encoding linkedlist xlist
249 # don't convert when the value could not be inserted
250 create_ziplist xlist
[lrepeat
256 a
]
251 assert_equal
-1 [r
linsert xlist before foo a
]
252 assert_encoding ziplist xlist
253 create_ziplist xlist
[lrepeat
256 a
]
254 assert_equal
-1 [r
linsert xlist
after foo a
]
255 assert_encoding ziplist xlist
258 foreach {type num
} {ziplist
250 linkedlist
500} {
259 proc check_numbered_list_consistency
{key
} {
260 set len
[r llen
$key]
261 for {set i
0} {$i < $len} {incr i
} {
262 assert_equal
$i [r
lindex $key $i]
263 assert_equal
[expr $len-1-$i] [r
lindex $key [expr (-$i)-1]]
267 proc check_random_access_consistency
{key
} {
268 set len
[r llen
$key]
269 for {set i
0} {$i < $len} {incr i
} {
270 set rint
[expr int
(rand
()*$len)]
271 assert_equal
$rint [r
lindex $key $rint]
272 assert_equal
[expr $len-1-$rint] [r
lindex $key [expr (-$rint)-1]]
276 test
"LINDEX consistency test - $type" {
278 for {set i
0} {$i < $num} {incr i
} {
281 assert_encoding
$type mylist
282 check_numbered_list_consistency mylist
285 test
"LINDEX random access - $type" {
286 assert_encoding
$type mylist
287 check_random_access_consistency mylist
290 test
"Check if list is still ok after a DEBUG RELOAD - $type" {
292 assert_encoding
$type mylist
293 check_numbered_list_consistency mylist
294 check_random_access_consistency mylist
298 test
{LLEN against non-list value
error} {
301 assert_error ERR
* {r llen mylist
}
304 test
{LLEN against non existing key
} {
305 assert_equal
0 [r llen not-a-key
]
308 test
{LINDEX against non-list value
error} {
309 assert_error ERR
* {r
lindex mylist
0}
312 test
{LINDEX against non existing key
} {
313 assert_equal
"" [r
lindex not-a-key
10]
316 test
{LPUSH against non-list value
error} {
317 assert_error ERR
* {r lpush mylist
0}
320 test
{RPUSH against non-list value
error} {
321 assert_error ERR
* {r rpush mylist
0}
324 foreach {type large
} [array get largevalue
] {
325 test
"RPOPLPUSH base case - $type" {
326 r del mylist1 mylist2
327 create_
$type mylist1
"a $large c d"
328 assert_equal d
[r rpoplpush mylist1 mylist2
]
329 assert_equal c
[r rpoplpush mylist1 mylist2
]
330 assert_equal
"a $large" [r
lrange mylist1
0 -1]
331 assert_equal
"c d" [r
lrange mylist2
0 -1]
332 assert_encoding ziplist mylist2
335 test
"RPOPLPUSH with the same list as src and dst - $type" {
336 create_
$type mylist
"a $large c"
337 assert_equal
"a $large c" [r
lrange mylist
0 -1]
338 assert_equal c
[r rpoplpush mylist mylist
]
339 assert_equal
"c a $large" [r
lrange mylist
0 -1]
342 foreach {othertype otherlarge
} [array get largevalue
] {
343 test
"RPOPLPUSH with $type source and existing target $othertype" {
344 create_
$type srclist
"a b c $large"
345 create_
$othertype dstlist
"$otherlarge"
346 assert_equal
$large [r rpoplpush srclist dstlist
]
347 assert_equal c
[r rpoplpush srclist dstlist
]
348 assert_equal
"a b" [r
lrange srclist
0 -1]
349 assert_equal
"c $large $otherlarge" [r
lrange dstlist
0 -1]
351 # When we rpoplpush'ed a large value, dstlist should be
352 # converted to the same encoding as srclist.
353 if {$type eq
"linkedlist"} {
354 assert_encoding linkedlist dstlist
360 test
{RPOPLPUSH against non existing key
} {
361 r del srclist dstlist
362 assert_equal
{} [r rpoplpush srclist dstlist
]
363 assert_equal
0 [r exists srclist
]
364 assert_equal
0 [r exists dstlist
]
367 test
{RPOPLPUSH against non
list src key
} {
368 r del srclist dstlist
370 assert_error ERR
* {r rpoplpush srclist dstlist
}
371 assert_type
string srclist
372 assert_equal
0 [r exists newlist
]
375 test
{RPOPLPUSH against non
list dst key
} {
376 create_ziplist srclist
{a b c d
}
378 assert_error ERR
* {r rpoplpush srclist dstlist
}
379 assert_type
string dstlist
380 assert_equal
{a b c d
} [r
lrange srclist
0 -1]
383 test
{RPOPLPUSH against non existing src key
} {
384 r del srclist dstlist
385 assert_equal
{} [r rpoplpush srclist dstlist
]
388 foreach {type large
} [array get largevalue
] {
389 test
"Basic LPOP/RPOP - $type" {
390 create_
$type mylist
"$large 1 2"
391 assert_equal
$large [r lpop mylist
]
392 assert_equal
2 [r rpop mylist
]
393 assert_equal
1 [r lpop mylist
]
394 assert_equal
0 [r llen mylist
]
397 assert_equal
{} [r lpop mylist
]
398 assert_equal
{} [r rpop mylist
]
402 test
{LPOP
/RPOP against non
list value
} {
404 assert_error ERR
*kind
* {r lpop notalist
}
405 assert_error ERR
*kind
* {r rpop notalist
}
408 foreach {type num
} {ziplist
250 linkedlist
500} {
409 test
"Mass RPOP/LPOP - $type" {
412 for {set i
0} {$i < $num} {incr i
} {
416 assert_encoding
$type mylist
418 for {set i
0} {$i < [expr $num/2]} {incr i
} {
419 incr sum2
[r lpop mylist
]
420 incr sum2
[r rpop mylist
]
422 assert_equal
$sum1 $sum2
426 foreach {type large
} [array get largevalue
] {
427 test
"LRANGE basics - $type" {
428 create_
$type mylist
"$large 1 2 3 4 5 6 7 8 9"
429 assert_equal
{1 2 3 4 5 6 7 8} [r
lrange mylist
1 -2]
430 assert_equal
{7 8 9} [r
lrange mylist
-3 -1]
431 assert_equal
{4} [r
lrange mylist
4 4]
434 test
"LRANGE inverted indexes - $type" {
435 create_
$type mylist
"$large 1 2 3 4 5 6 7 8 9"
436 assert_equal
{} [r
lrange mylist
6 2]
439 test
"LRANGE out of range indexes including the full list - $type" {
440 create_
$type mylist
"$large 1 2 3"
441 assert_equal
"$large 1 2 3" [r
lrange mylist
-1000 1000]
444 test
"LRANGE out of range negative end index - $type" {
445 create_
$type mylist
"$large 1 2 3"
446 assert_equal
$large [r
lrange mylist
0 -4]
447 assert_equal
{} [r
lrange mylist
0 -5]
451 test
{LRANGE against non existing key
} {
452 assert_equal
{} [r
lrange nosuchkey
0 1]
455 foreach {type large
} [array get largevalue
] {
456 proc trim_list
{type min max
} {
459 create_
$type mylist
"1 2 3 4 $large"
460 r ltrim mylist
$min $max
464 test
"LTRIM basics - $type" {
465 assert_equal
"1" [trim_list
$type 0 0]
466 assert_equal
"1 2" [trim_list
$type 0 1]
467 assert_equal
"1 2 3" [trim_list
$type 0 2]
468 assert_equal
"2 3" [trim_list
$type 1 2]
469 assert_equal
"2 3 4 $large" [trim_list
$type 1 -1]
470 assert_equal
"2 3 4" [trim_list
$type 1 -2]
471 assert_equal
"4 $large" [trim_list
$type -2 -1]
472 assert_equal
"$large" [trim_list
$type -1 -1]
473 assert_equal
"1 2 3 4 $large" [trim_list
$type -5 -1]
474 assert_equal
"1 2 3 4 $large" [trim_list
$type -10 10]
475 assert_equal
"1 2 3 4 $large" [trim_list
$type 0 5]
476 assert_equal
"1 2 3 4 $large" [trim_list
$type 0 10]
479 test
"LTRIM out of range negative end index - $type" {
480 assert_equal
{1} [trim_list
$type 0 -5]
481 assert_equal
{} [trim_list
$type 0 -6]
485 test
"LTRIM stress testing - $type" {
490 # Start with the large value to ensure the
491 # right encoding is used.
492 r rpush mylist
$large
493 lappend mylist
$large
495 for {set i
0} {$i < $startlen} {incr i
} {
496 set str
[randomInt
9223372036854775807]
501 for {set i
0} {$i < 1000} {incr i
} {
502 set min
[expr {int
(rand
()*$startlen)}]
503 set max
[expr {$min+int
(rand
()*$startlen)}]
504 set mylist
[lrange $mylist $min $max]
505 r ltrim mylist
$min $max
506 assert_equal
$mylist [r
lrange mylist
0 -1]
508 for {set j
[r llen mylist
]} {$j < $startlen} {incr j
} {
509 set str
[randomInt
9223372036854775807]
518 foreach {type large
} [array get largevalue
] {
519 test
"LSET - $type" {
520 create_
$type mylist
"99 98 $large 96 95"
523 assert_equal
"99 foo $large 96 bar" [r
lrange mylist
0 -1]
526 test
"LSET out of range index - $type" {
527 assert_error ERR
*range
* {r
lset mylist
10 foo
}
531 test
{LSET against non existing key
} {
532 assert_error ERR
*key
* {r
lset nosuchkey
10 foo
}
535 test
{LSET against non
list value
} {
537 assert_error ERR
*value
* {r
lset nolist
0 foo
}
540 foreach {type e
} [array get largevalue
] {
541 test
"LREM remove all the occurrences - $type" {
542 create_
$type mylist
"$e foo bar foobar foobared zap bar test foo"
543 assert_equal
2 [r lrem mylist
0 bar
]
544 assert_equal
"$e foo foobar foobared zap test foo" [r
lrange mylist
0 -1]
547 test
"LREM remove the first occurrence - $type" {
548 assert_equal
1 [r lrem mylist
1 foo
]
549 assert_equal
"$e foobar foobared zap test foo" [r
lrange mylist
0 -1]
552 test
"LREM remove non existing element - $type" {
553 assert_equal
0 [r lrem mylist
1 nosuchelement
]
554 assert_equal
"$e foobar foobared zap test foo" [r
lrange mylist
0 -1]
557 test
"LREM starting from tail with negative count - $type" {
558 create_
$type mylist
"$e foo bar foobar foobared zap bar test foo foo"
559 assert_equal
1 [r lrem mylist
-1 bar
]
560 assert_equal
"$e foo bar foobar foobared zap test foo foo" [r
lrange mylist
0 -1]
563 test
"LREM starting from tail with negative count (2) - $type" {
564 assert_equal
2 [r lrem mylist
-2 foo
]
565 assert_equal
"$e foo bar foobar foobared zap test" [r
lrange mylist
0 -1]
568 test
"LREM deleting objects that may be int encoded - $type" {
569 create_
$type myotherlist
"$e 1 2 3"
570 assert_equal
1 [r lrem myotherlist
1 2]
571 assert_equal
3 [r llen myotherlist
]