]> git.saurik.com Git - redis.git/blob - tests/unit/type/list.tcl
a2d0edf6d836eaf1c43ec2e3d45e3a800457aa06
[redis.git] / tests / unit / type / list.tcl
1 start_server {
2 tags {"list"}
3 overrides {
4 "list-max-ziplist-value" 16
5 "list-max-ziplist-entries" 256
6 }
7 } {
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]
13
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
24
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
34 }
35
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]
46
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]
56 }
57
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]
62 }
63
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]
68 }
69
70 proc create_ziplist {key entries} {
71 r del $key
72 foreach entry $entries { r rpush $key $entry }
73 assert_encoding ziplist $key
74 }
75
76 proc create_linkedlist {key entries} {
77 r del $key
78 foreach entry $entries { r rpush $key $entry }
79 assert_encoding linkedlist $key
80 }
81
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"
86
87 $rd blpop blist 1
88 assert_equal {blist a} [$rd read]
89 $rd brpop blist 1
90 assert_equal {blist d} [$rd read]
91
92 $rd blpop blist 1
93 assert_equal {blist b} [$rd read]
94 $rd brpop blist 1
95 assert_equal {blist c} [$rd read]
96 }
97
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"
102
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]
109
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]
116 }
117
118 test "BLPOP, BRPOP: second list has an entry - $type" {
119 set rd [redis_deferring_client]
120 r del blist1
121 create_$type blist2 "d $large f"
122
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]
129 }
130
131 test "BRPOPLPUSH - $type" {
132 r del target
133
134 set rd [redis_deferring_client]
135 create_$type blist "a b $large c d"
136
137 $rd brpoplpush blist target 1
138 assert_equal d [$rd read]
139
140 assert_equal d [r rpop target]
141 assert_equal "a b $large c" [r lrange blist 0 -1]
142 }
143 }
144
145 test "BRPOPLPUSH with zero timeout should block indefinitely" {
146 set rd [redis_deferring_client]
147 r del blist target
148 $rd brpoplpush blist target 0
149 after 1000
150 r rpush blist foo
151 assert_equal foo [$rd read]
152 assert_equal {foo} [r lrange target 0 -1]
153 }
154
155 test "BRPOPLPUSH with wrong source type" {
156 set rd [redis_deferring_client]
157 r del blist target
158 r set blist nolist
159 $rd brpoplpush blist target 1
160 assert_error "ERR*wrong kind*" {$rd read}
161 }
162
163 test "BRPOPLPUSH with wrong destination type" {
164 set rd [redis_deferring_client]
165 r del blist target
166 r set target nolist
167 r lpush blist foo
168 $rd brpoplpush blist target 1
169 assert_error "ERR*wrong kind*" {$rd read}
170
171 set rd [redis_deferring_client]
172 r del blist target
173 r set target nolist
174 $rd brpoplpush blist target 0
175 after 1000
176 r rpush blist foo
177 assert_error "ERR*wrong kind*" {$rd read}
178 assert_equal {foo} [r lrange blist 0 -1]
179 }
180
181 test {BRPOPLPUSH inside a transaction} {
182 r del xlist target
183 r lpush xlist foo
184 r lpush xlist bar
185
186 r multi
187 r brpoplpush xlist target 0
188 r brpoplpush xlist target 0
189 r brpoplpush xlist target 0
190 r lrange xlist 0 -1
191 r lrange target 0 -1
192 r exec
193 } {foo bar {} {} {bar foo}}
194
195 foreach {pop} {BLPOP BRPOP} {
196 test "$pop: with single empty list argument" {
197 set rd [redis_deferring_client]
198 r del blist1
199 $rd $pop blist1 1
200 r rpush blist1 foo
201 assert_equal {blist1 foo} [$rd read]
202 assert_equal 0 [r exists blist1]
203 }
204
205 test "$pop: with negative timeout" {
206 set rd [redis_deferring_client]
207 $rd $pop blist1 -1
208 assert_error "ERR*is negative*" {$rd read}
209 }
210
211 test "$pop: with non-integer timeout" {
212 set rd [redis_deferring_client]
213 $rd $pop blist1 1.1
214 assert_error "ERR*not an integer*" {$rd read}
215 }
216
217 test "$pop: with zero timeout should block indefinitely" {
218 # To test this, use a timeout of 0 and wait a second.
219 # The blocking pop should still be waiting for a push.
220 set rd [redis_deferring_client]
221 $rd $pop blist1 0
222 after 1000
223 r rpush blist1 foo
224 assert_equal {blist1 foo} [$rd read]
225 }
226
227 test "$pop: second argument is not a list" {
228 set rd [redis_deferring_client]
229 r del blist1 blist2
230 r set blist2 nolist
231 $rd $pop blist1 blist2 1
232 assert_error "ERR*wrong kind*" {$rd read}
233 }
234
235 test "$pop: timeout" {
236 set rd [redis_deferring_client]
237 r del blist1 blist2
238 $rd $pop blist1 blist2 1
239 assert_equal {} [$rd read]
240 }
241
242 test "$pop: arguments are empty" {
243 set rd [redis_deferring_client]
244 r del blist1 blist2
245
246 $rd $pop blist1 blist2 1
247 r rpush blist1 foo
248 assert_equal {blist1 foo} [$rd read]
249 assert_equal 0 [r exists blist1]
250 assert_equal 0 [r exists blist2]
251
252 $rd $pop blist1 blist2 1
253 r rpush blist2 foo
254 assert_equal {blist2 foo} [$rd read]
255 assert_equal 0 [r exists blist1]
256 assert_equal 0 [r exists blist2]
257 }
258 }
259
260 test {BLPOP inside a transaction} {
261 r del xlist
262 r lpush xlist foo
263 r lpush xlist bar
264 r multi
265 r blpop xlist 0
266 r blpop xlist 0
267 r blpop xlist 0
268 r exec
269 } {{xlist bar} {xlist foo} {}}
270
271 test {LPUSHX, RPUSHX - generic} {
272 r del xlist
273 assert_equal 0 [r lpushx xlist a]
274 assert_equal 0 [r llen xlist]
275 assert_equal 0 [r rpushx xlist a]
276 assert_equal 0 [r llen xlist]
277 }
278
279 foreach {type large} [array get largevalue] {
280 test "LPUSHX, RPUSHX - $type" {
281 create_$type xlist "$large c"
282 assert_equal 3 [r rpushx xlist d]
283 assert_equal 4 [r lpushx xlist a]
284 assert_equal "a $large c d" [r lrange xlist 0 -1]
285 }
286
287 test "LINSERT - $type" {
288 create_$type xlist "a $large c d"
289 assert_equal 5 [r linsert xlist before c zz]
290 assert_equal "a $large zz c d" [r lrange xlist 0 10]
291 assert_equal 6 [r linsert xlist after c yy]
292 assert_equal "a $large zz c yy d" [r lrange xlist 0 10]
293 assert_equal 7 [r linsert xlist after d dd]
294 assert_equal -1 [r linsert xlist after bad ddd]
295 assert_equal "a $large zz c yy d dd" [r lrange xlist 0 10]
296 assert_equal 8 [r linsert xlist before a aa]
297 assert_equal -1 [r linsert xlist before bad aaa]
298 assert_equal "aa a $large zz c yy d dd" [r lrange xlist 0 10]
299
300 # check inserting integer encoded value
301 assert_equal 9 [r linsert xlist before aa 42]
302 assert_equal 42 [r lrange xlist 0 0]
303 }
304 }
305
306 test {LPUSHX, RPUSHX convert from ziplist to list} {
307 set large $largevalue(linkedlist)
308
309 # convert when a large value is pushed
310 create_ziplist xlist a
311 assert_equal 2 [r rpushx xlist $large]
312 assert_encoding linkedlist xlist
313 create_ziplist xlist a
314 assert_equal 2 [r lpushx xlist $large]
315 assert_encoding linkedlist xlist
316
317 # convert when the length threshold is exceeded
318 create_ziplist xlist [lrepeat 256 a]
319 assert_equal 257 [r rpushx xlist b]
320 assert_encoding linkedlist xlist
321 create_ziplist xlist [lrepeat 256 a]
322 assert_equal 257 [r lpushx xlist b]
323 assert_encoding linkedlist xlist
324 }
325
326 test {LINSERT convert from ziplist to list} {
327 set large $largevalue(linkedlist)
328
329 # convert when a large value is inserted
330 create_ziplist xlist a
331 assert_equal 2 [r linsert xlist before a $large]
332 assert_encoding linkedlist xlist
333 create_ziplist xlist a
334 assert_equal 2 [r linsert xlist after a $large]
335 assert_encoding linkedlist xlist
336
337 # convert when the length threshold is exceeded
338 create_ziplist xlist [lrepeat 256 a]
339 assert_equal 257 [r linsert xlist before a a]
340 assert_encoding linkedlist xlist
341 create_ziplist xlist [lrepeat 256 a]
342 assert_equal 257 [r linsert xlist after a a]
343 assert_encoding linkedlist xlist
344
345 # don't convert when the value could not be inserted
346 create_ziplist xlist [lrepeat 256 a]
347 assert_equal -1 [r linsert xlist before foo a]
348 assert_encoding ziplist xlist
349 create_ziplist xlist [lrepeat 256 a]
350 assert_equal -1 [r linsert xlist after foo a]
351 assert_encoding ziplist xlist
352 }
353
354 foreach {type num} {ziplist 250 linkedlist 500} {
355 proc check_numbered_list_consistency {key} {
356 set len [r llen $key]
357 for {set i 0} {$i < $len} {incr i} {
358 assert_equal $i [r lindex $key $i]
359 assert_equal [expr $len-1-$i] [r lindex $key [expr (-$i)-1]]
360 }
361 }
362
363 proc check_random_access_consistency {key} {
364 set len [r llen $key]
365 for {set i 0} {$i < $len} {incr i} {
366 set rint [expr int(rand()*$len)]
367 assert_equal $rint [r lindex $key $rint]
368 assert_equal [expr $len-1-$rint] [r lindex $key [expr (-$rint)-1]]
369 }
370 }
371
372 test "LINDEX consistency test - $type" {
373 r del mylist
374 for {set i 0} {$i < $num} {incr i} {
375 r rpush mylist $i
376 }
377 assert_encoding $type mylist
378 check_numbered_list_consistency mylist
379 }
380
381 test "LINDEX random access - $type" {
382 assert_encoding $type mylist
383 check_random_access_consistency mylist
384 }
385
386 test "Check if list is still ok after a DEBUG RELOAD - $type" {
387 r debug reload
388 assert_encoding $type mylist
389 check_numbered_list_consistency mylist
390 check_random_access_consistency mylist
391 }
392 }
393
394 test {LLEN against non-list value error} {
395 r del mylist
396 r set mylist foobar
397 assert_error ERR* {r llen mylist}
398 }
399
400 test {LLEN against non existing key} {
401 assert_equal 0 [r llen not-a-key]
402 }
403
404 test {LINDEX against non-list value error} {
405 assert_error ERR* {r lindex mylist 0}
406 }
407
408 test {LINDEX against non existing key} {
409 assert_equal "" [r lindex not-a-key 10]
410 }
411
412 test {LPUSH against non-list value error} {
413 assert_error ERR* {r lpush mylist 0}
414 }
415
416 test {RPUSH against non-list value error} {
417 assert_error ERR* {r rpush mylist 0}
418 }
419
420 foreach {type large} [array get largevalue] {
421 test "RPOPLPUSH base case - $type" {
422 r del mylist1 mylist2
423 create_$type mylist1 "a $large c d"
424 assert_equal d [r rpoplpush mylist1 mylist2]
425 assert_equal c [r rpoplpush mylist1 mylist2]
426 assert_equal "a $large" [r lrange mylist1 0 -1]
427 assert_equal "c d" [r lrange mylist2 0 -1]
428 assert_encoding ziplist mylist2
429 }
430
431 test "RPOPLPUSH with the same list as src and dst - $type" {
432 create_$type mylist "a $large c"
433 assert_equal "a $large c" [r lrange mylist 0 -1]
434 assert_equal c [r rpoplpush mylist mylist]
435 assert_equal "c a $large" [r lrange mylist 0 -1]
436 }
437
438 foreach {othertype otherlarge} [array get largevalue] {
439 test "RPOPLPUSH with $type source and existing target $othertype" {
440 create_$type srclist "a b c $large"
441 create_$othertype dstlist "$otherlarge"
442 assert_equal $large [r rpoplpush srclist dstlist]
443 assert_equal c [r rpoplpush srclist dstlist]
444 assert_equal "a b" [r lrange srclist 0 -1]
445 assert_equal "c $large $otherlarge" [r lrange dstlist 0 -1]
446
447 # When we rpoplpush'ed a large value, dstlist should be
448 # converted to the same encoding as srclist.
449 if {$type eq "linkedlist"} {
450 assert_encoding linkedlist dstlist
451 }
452 }
453 }
454 }
455
456 test {RPOPLPUSH against non existing key} {
457 r del srclist dstlist
458 assert_equal {} [r rpoplpush srclist dstlist]
459 assert_equal 0 [r exists srclist]
460 assert_equal 0 [r exists dstlist]
461 }
462
463 test {RPOPLPUSH against non list src key} {
464 r del srclist dstlist
465 r set srclist x
466 assert_error ERR* {r rpoplpush srclist dstlist}
467 assert_type string srclist
468 assert_equal 0 [r exists newlist]
469 }
470
471 test {RPOPLPUSH against non list dst key} {
472 create_ziplist srclist {a b c d}
473 r set dstlist x
474 assert_error ERR* {r rpoplpush srclist dstlist}
475 assert_type string dstlist
476 assert_equal {a b c d} [r lrange srclist 0 -1]
477 }
478
479 test {RPOPLPUSH against non existing src key} {
480 r del srclist dstlist
481 assert_equal {} [r rpoplpush srclist dstlist]
482 } {}
483
484 foreach {type large} [array get largevalue] {
485 test "Basic LPOP/RPOP - $type" {
486 create_$type mylist "$large 1 2"
487 assert_equal $large [r lpop mylist]
488 assert_equal 2 [r rpop mylist]
489 assert_equal 1 [r lpop mylist]
490 assert_equal 0 [r llen mylist]
491
492 # pop on empty list
493 assert_equal {} [r lpop mylist]
494 assert_equal {} [r rpop mylist]
495 }
496 }
497
498 test {LPOP/RPOP against non list value} {
499 r set notalist foo
500 assert_error ERR*kind* {r lpop notalist}
501 assert_error ERR*kind* {r rpop notalist}
502 }
503
504 foreach {type num} {ziplist 250 linkedlist 500} {
505 test "Mass RPOP/LPOP - $type" {
506 r del mylist
507 set sum1 0
508 for {set i 0} {$i < $num} {incr i} {
509 r lpush mylist $i
510 incr sum1 $i
511 }
512 assert_encoding $type mylist
513 set sum2 0
514 for {set i 0} {$i < [expr $num/2]} {incr i} {
515 incr sum2 [r lpop mylist]
516 incr sum2 [r rpop mylist]
517 }
518 assert_equal $sum1 $sum2
519 }
520 }
521
522 foreach {type large} [array get largevalue] {
523 test "LRANGE basics - $type" {
524 create_$type mylist "$large 1 2 3 4 5 6 7 8 9"
525 assert_equal {1 2 3 4 5 6 7 8} [r lrange mylist 1 -2]
526 assert_equal {7 8 9} [r lrange mylist -3 -1]
527 assert_equal {4} [r lrange mylist 4 4]
528 }
529
530 test "LRANGE inverted indexes - $type" {
531 create_$type mylist "$large 1 2 3 4 5 6 7 8 9"
532 assert_equal {} [r lrange mylist 6 2]
533 }
534
535 test "LRANGE out of range indexes including the full list - $type" {
536 create_$type mylist "$large 1 2 3"
537 assert_equal "$large 1 2 3" [r lrange mylist -1000 1000]
538 }
539
540 test "LRANGE out of range negative end index - $type" {
541 create_$type mylist "$large 1 2 3"
542 assert_equal $large [r lrange mylist 0 -4]
543 assert_equal {} [r lrange mylist 0 -5]
544 }
545 }
546
547 test {LRANGE against non existing key} {
548 assert_equal {} [r lrange nosuchkey 0 1]
549 }
550
551 foreach {type large} [array get largevalue] {
552 proc trim_list {type min max} {
553 upvar 1 large large
554 r del mylist
555 create_$type mylist "1 2 3 4 $large"
556 r ltrim mylist $min $max
557 r lrange mylist 0 -1
558 }
559
560 test "LTRIM basics - $type" {
561 assert_equal "1" [trim_list $type 0 0]
562 assert_equal "1 2" [trim_list $type 0 1]
563 assert_equal "1 2 3" [trim_list $type 0 2]
564 assert_equal "2 3" [trim_list $type 1 2]
565 assert_equal "2 3 4 $large" [trim_list $type 1 -1]
566 assert_equal "2 3 4" [trim_list $type 1 -2]
567 assert_equal "4 $large" [trim_list $type -2 -1]
568 assert_equal "$large" [trim_list $type -1 -1]
569 assert_equal "1 2 3 4 $large" [trim_list $type -5 -1]
570 assert_equal "1 2 3 4 $large" [trim_list $type -10 10]
571 assert_equal "1 2 3 4 $large" [trim_list $type 0 5]
572 assert_equal "1 2 3 4 $large" [trim_list $type 0 10]
573 }
574
575 test "LTRIM out of range negative end index - $type" {
576 assert_equal {1} [trim_list $type 0 -5]
577 assert_equal {} [trim_list $type 0 -6]
578 }
579
580 tags {"slow"} {
581 test "LTRIM stress testing - $type" {
582 set mylist {}
583 set startlen 32
584 r del mylist
585
586 # Start with the large value to ensure the
587 # right encoding is used.
588 r rpush mylist $large
589 lappend mylist $large
590
591 for {set i 0} {$i < $startlen} {incr i} {
592 set str [randomInt 9223372036854775807]
593 r rpush mylist $str
594 lappend mylist $str
595 }
596
597 for {set i 0} {$i < 1000} {incr i} {
598 set min [expr {int(rand()*$startlen)}]
599 set max [expr {$min+int(rand()*$startlen)}]
600 set mylist [lrange $mylist $min $max]
601 r ltrim mylist $min $max
602 assert_equal $mylist [r lrange mylist 0 -1]
603
604 for {set j [r llen mylist]} {$j < $startlen} {incr j} {
605 set str [randomInt 9223372036854775807]
606 r rpush mylist $str
607 lappend mylist $str
608 }
609 }
610 }
611 }
612 }
613
614 foreach {type large} [array get largevalue] {
615 test "LSET - $type" {
616 create_$type mylist "99 98 $large 96 95"
617 r lset mylist 1 foo
618 r lset mylist -1 bar
619 assert_equal "99 foo $large 96 bar" [r lrange mylist 0 -1]
620 }
621
622 test "LSET out of range index - $type" {
623 assert_error ERR*range* {r lset mylist 10 foo}
624 }
625 }
626
627 test {LSET against non existing key} {
628 assert_error ERR*key* {r lset nosuchkey 10 foo}
629 }
630
631 test {LSET against non list value} {
632 r set nolist foobar
633 assert_error ERR*value* {r lset nolist 0 foo}
634 }
635
636 foreach {type e} [array get largevalue] {
637 test "LREM remove all the occurrences - $type" {
638 create_$type mylist "$e foo bar foobar foobared zap bar test foo"
639 assert_equal 2 [r lrem mylist 0 bar]
640 assert_equal "$e foo foobar foobared zap test foo" [r lrange mylist 0 -1]
641 }
642
643 test "LREM remove the first occurrence - $type" {
644 assert_equal 1 [r lrem mylist 1 foo]
645 assert_equal "$e foobar foobared zap test foo" [r lrange mylist 0 -1]
646 }
647
648 test "LREM remove non existing element - $type" {
649 assert_equal 0 [r lrem mylist 1 nosuchelement]
650 assert_equal "$e foobar foobared zap test foo" [r lrange mylist 0 -1]
651 }
652
653 test "LREM starting from tail with negative count - $type" {
654 create_$type mylist "$e foo bar foobar foobared zap bar test foo foo"
655 assert_equal 1 [r lrem mylist -1 bar]
656 assert_equal "$e foo bar foobar foobared zap test foo foo" [r lrange mylist 0 -1]
657 }
658
659 test "LREM starting from tail with negative count (2) - $type" {
660 assert_equal 2 [r lrem mylist -2 foo]
661 assert_equal "$e foo bar foobar foobared zap test" [r lrange mylist 0 -1]
662 }
663
664 test "LREM deleting objects that may be int encoded - $type" {
665 create_$type myotherlist "$e 1 2 3"
666 assert_equal 1 [r lrem myotherlist 1 2]
667 assert_equal 3 [r llen myotherlist]
668 }
669
670 }
671 }
672
673 start_server {
674 tags {list ziplist}
675 overrides {
676 "list-max-ziplist-value" 200000
677 "list-max-ziplist-entries" 256
678 }
679 } {
680 test {Explicit regression for a list bug} {
681 set mylist {49376042582 {BkG2o\pIC]4YYJa9cJ4GWZalG[4tin;1D2whSkCOW`mX;SFXGyS8sedcff3fQI^tgPCC@^Nu1J6o]meM@Lko]t_jRyo<xSJ1oObDYd`ppZuW6P@fS278YaOx=s6lvdFlMbP0[SbkI^Kr\HBXtuFaA^mDx:yzS4a[skiiPWhT<nNfAf=aQVfclcuwDrfe;iVuKdNvB9kbfq>tK?tH[\EvWqS]b`o2OCtjg:?nUTwdjpcUm]y:pg5q24q7LlCOwQE^}}
682 r del l
683 r rpush l [lindex $mylist 0]
684 r rpush l [lindex $mylist 1]
685 assert_equal [r lindex l 0] [lindex $mylist 0]
686 assert_equal [r lindex l 1] [lindex $mylist 1]
687 }
688
689 tags {slow} {
690 test {ziplist implementation: value encoding and backlink} {
691 for {set j 0} {$j < 100} {incr j} {
692 r del l
693 set l {}
694 for {set i 0} {$i < 200} {incr i} {
695 randpath {
696 set data [string repeat x [randomInt 100000]]
697 } {
698 set data [randomInt 65536]
699 } {
700 set data [randomInt 4294967296]
701 } {
702 set data [randomInt 18446744073709551616]
703 }
704 lappend l $data
705 r rpush l $data
706 }
707 assert_equal [llength $l] [r llen l]
708 # Traverse backward
709 for {set i 199} {$i >= 0} {incr i -1} {
710 if {[lindex $l $i] ne [r lindex l $i]} {
711 assert_equal [lindex $l $i] [r lindex l $i]
712 }
713 }
714 }
715 }
716
717 test {ziplist implementation: encoding stress testing} {
718 for {set j 0} {$j < 200} {incr j} {
719 r del l
720 set l {}
721 set len [randomInt 400]
722 for {set i 0} {$i < $len} {incr i} {
723 set rv [randomValue]
724 randpath {
725 lappend l $rv
726 r rpush l $rv
727 } {
728 set l [concat [list $rv] $l]
729 r lpush l $rv
730 }
731 }
732 assert_equal [llength $l] [r llen l]
733 for {set i 0} {$i < 200} {incr i} {
734 if {[lindex $l $i] ne [r lindex l $i]} {
735 assert_equal [lindex $l $i] [r lindex l $i]
736 }
737 }
738 }
739 }
740 }
741 }