]> git.saurik.com Git - redis.git/blob - tests/unit/type/list.tcl
691040ece9abdc34771ce6559359b09de29c58b5
[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 test {LPUSH, RPUSH, LLENGTH, LINDEX - ziplist} {
9 # first lpush then rpush
10 assert_equal 1 [r lpush myziplist1 a]
11 assert_equal 2 [r rpush myziplist1 b]
12 assert_equal 3 [r rpush myziplist1 c]
13 assert_equal 3 [r llen myziplist1]
14 assert_equal a [r lindex myziplist1 0]
15 assert_equal b [r lindex myziplist1 1]
16 assert_equal c [r lindex myziplist1 2]
17 assert_encoding ziplist myziplist1
18
19 # first rpush then lpush
20 assert_equal 1 [r rpush myziplist2 a]
21 assert_equal 2 [r lpush myziplist2 b]
22 assert_equal 3 [r lpush myziplist2 c]
23 assert_equal 3 [r llen myziplist2]
24 assert_equal c [r lindex myziplist2 0]
25 assert_equal b [r lindex myziplist2 1]
26 assert_equal a [r lindex myziplist2 2]
27 assert_encoding ziplist myziplist2
28 }
29
30 test {LPUSH, RPUSH, LLENGTH, LINDEX - regular list} {
31 # use a string of length 17 to ensure a regular list is used
32 set large_value "aaaaaaaaaaaaaaaaa"
33
34 # first lpush then rpush
35 assert_equal 1 [r lpush mylist1 $large_value]
36 assert_encoding list mylist1
37 assert_equal 2 [r rpush mylist1 b]
38 assert_equal 3 [r rpush mylist1 c]
39 assert_equal 3 [r llen mylist1]
40 assert_equal $large_value [r lindex mylist1 0]
41 assert_equal b [r lindex mylist1 1]
42 assert_equal c [r lindex mylist1 2]
43
44 # first rpush then lpush
45 assert_equal 1 [r rpush mylist2 $large_value]
46 assert_encoding list mylist2
47 assert_equal 2 [r lpush mylist2 b]
48 assert_equal 3 [r lpush mylist2 c]
49 assert_equal 3 [r llen mylist2]
50 assert_equal c [r lindex mylist2 0]
51 assert_equal b [r lindex mylist2 1]
52 assert_equal $large_value [r lindex mylist2 2]
53 }
54
55 test {LPUSHX, RPUSHX, LPUSHXAFTER, RPUSHXAFTER - ziplist} {
56 r del xlist
57 assert_equal 0 [r lpushx xlist a]
58 assert_equal 0 [r rpushx xlist a]
59 assert_equal 1 [r rpush xlist b]
60 assert_equal 2 [r rpush xlist c]
61 assert_equal 3 [r rpushx xlist d]
62 assert_equal 4 [r lpushx xlist a]
63 assert_encoding ziplist xlist
64 assert_equal {a b c d} [r lrange xlist 0 10]
65
66 assert_equal 5 [r linsert xlist before c zz]
67 assert_equal {a b zz c d} [r lrange xlist 0 10]
68 assert_equal 6 [r linsert xlist after c yy]
69 assert_equal {a b zz c yy d} [r lrange xlist 0 10]
70 assert_equal 7 [r linsert xlist after d dd]
71 assert_equal 7 [r linsert xlist after bad ddd]
72 assert_equal {a b zz c yy d dd} [r lrange xlist 0 10]
73 assert_equal 8 [r linsert xlist before a aa]
74 assert_equal 8 [r linsert xlist before bad aaa]
75 assert_equal {aa a b zz c yy d dd} [r lrange xlist 0 10]
76 }
77
78 test {LPUSHX, RPUSHX, LPUSHXAFTER, RPUSHXAFTER - regular list} {
79 set large_value "aaaaaaaaaaaaaaaaa"
80
81 r del xlist
82 assert_equal 0 [r lpushx xlist a]
83 assert_equal 0 [r rpushx xlist a]
84 assert_equal 1 [r rpush xlist $large_value]
85 assert_equal 2 [r rpush xlist c]
86 assert_equal 3 [r rpushx xlist d]
87 assert_equal 4 [r lpushx xlist a]
88 assert_encoding list xlist
89 assert_equal {a aaaaaaaaaaaaaaaaa c d} [r lrange xlist 0 10]
90
91 assert_equal 5 [r linsert xlist before c zz]
92 assert_equal {a aaaaaaaaaaaaaaaaa zz c d} [r lrange xlist 0 10]
93 assert_equal 6 [r linsert xlist after c yy]
94 assert_equal {a aaaaaaaaaaaaaaaaa zz c yy d} [r lrange xlist 0 10]
95 assert_equal 7 [r linsert xlist after d dd]
96 assert_equal 7 [r linsert xlist after bad ddd]
97 assert_equal {a aaaaaaaaaaaaaaaaa zz c yy d dd} [r lrange xlist 0 10]
98 assert_equal 8 [r linsert xlist before a aa]
99 assert_equal 8 [r linsert xlist before bad aaa]
100 assert_equal {aa a aaaaaaaaaaaaaaaaa zz c yy d dd} [r lrange xlist 0 10]
101 }
102
103 test {DEL a list - ziplist} {
104 assert_equal 1 [r del myziplist2]
105 assert_equal 0 [r exists myziplist2]
106 assert_equal 0 [r llen myziplist2]
107 }
108
109 test {DEL a list - regular list} {
110 assert_equal 1 [r del mylist2]
111 assert_equal 0 [r exists mylist2]
112 assert_equal 0 [r llen mylist2]
113 }
114
115 proc create_ziplist {key entries} {
116 r del $key
117 foreach entry $entries { r rpush $key $entry }
118 assert_encoding ziplist $key
119 }
120
121 proc create_list {key entries} {
122 r del $key
123 r rpush $key "aaaaaaaaaaaaaaaaa"
124 foreach entry $entries { r rpush $key $entry }
125 assert_equal "aaaaaaaaaaaaaaaaa" [r lpop $key]
126 assert_encoding list $key
127 }
128
129 foreach {type num} {ziplist 250 list 500} {
130 proc check_numbered_list_consistency {key} {
131 set len [r llen $key]
132 for {set i 0} {$i < $len} {incr i} {
133 assert_equal $i [r lindex $key $i]
134 assert_equal [expr $len-1-$i] [r lindex $key [expr (-$i)-1]]
135 }
136 }
137
138 proc check_random_access_consistency {key} {
139 set len [r llen $key]
140 for {set i 0} {$i < $len} {incr i} {
141 set rint [expr int(rand()*$len)]
142 assert_equal $rint [r lindex $key $rint]
143 assert_equal [expr $len-1-$rint] [r lindex $key [expr (-$rint)-1]]
144 }
145 }
146
147 test "LINDEX consistency test - $type" {
148 r del mylist
149 for {set i 0} {$i < $num} {incr i} {
150 r rpush mylist $i
151 }
152 assert_encoding $type mylist
153 check_numbered_list_consistency mylist
154 }
155
156 test "LINDEX random access - $type" {
157 assert_encoding $type mylist
158 check_random_access_consistency mylist
159 }
160
161 test "Check if list is still ok after a DEBUG RELOAD - $type" {
162 r debug reload
163 assert_encoding $type mylist
164 check_numbered_list_consistency mylist
165 check_random_access_consistency mylist
166 }
167 }
168
169 test {LLEN against non-list value error} {
170 r del mylist
171 r set mylist foobar
172 assert_error ERR* {r llen mylist}
173 }
174
175 test {LLEN against non existing key} {
176 assert_equal 0 [r llen not-a-key]
177 }
178
179 test {LINDEX against non-list value error} {
180 assert_error ERR* {r lindex mylist 0}
181 }
182
183 test {LINDEX against non existing key} {
184 assert_equal "" [r lindex not-a-key 10]
185 }
186
187 test {LPUSH against non-list value error} {
188 assert_error ERR* {r lpush mylist 0}
189 }
190
191 test {RPUSH against non-list value error} {
192 assert_error ERR* {r rpush mylist 0}
193 }
194
195 foreach type {ziplist list} {
196 test "RPOPLPUSH base case - $type" {
197 r del mylist1 mylist2
198 create_$type mylist1 {a b c d}
199 assert_equal d [r rpoplpush mylist1 mylist2]
200 assert_equal c [r rpoplpush mylist1 mylist2]
201 assert_equal {a b} [r lrange mylist1 0 -1]
202 assert_equal {c d} [r lrange mylist2 0 -1]
203 assert_encoding ziplist mylist2
204 }
205
206 test "RPOPLPUSH with the same list as src and dst - $type" {
207 create_$type mylist {a b c}
208 assert_equal {a b c} [r lrange mylist 0 -1]
209 assert_equal c [r rpoplpush mylist mylist]
210 assert_equal {c a b} [r lrange mylist 0 -1]
211 }
212
213 foreach othertype {ziplist list} {
214 test "RPOPLPUSH with $type source and existing target $othertype" {
215 create_$type srclist {a b c d}
216 create_$othertype dstlist {x}
217 assert_equal d [r rpoplpush srclist dstlist]
218 assert_equal c [r rpoplpush srclist dstlist]
219 assert_equal {a b} [r lrange srclist 0 -1]
220 assert_equal {c d x} [r lrange dstlist 0 -1]
221 }
222 }
223 }
224
225 test {RPOPLPUSH against non existing key} {
226 r del srclist dstlist
227 assert_equal {} [r rpoplpush srclist dstlist]
228 assert_equal 0 [r exists srclist]
229 assert_equal 0 [r exists dstlist]
230 }
231
232 test {RPOPLPUSH against non list src key} {
233 r del srclist dstlist
234 r set srclist x
235 assert_error ERR* {r rpoplpush srclist dstlist}
236 assert_type string srclist
237 assert_equal 0 [r exists newlist]
238 }
239
240 test {RPOPLPUSH against non list dst key} {
241 create_ziplist srclist {a b c d}
242 r set dstlist x
243 assert_error ERR* {r rpoplpush srclist dstlist}
244 assert_type string dstlist
245 assert_equal {a b c d} [r lrange srclist 0 -1]
246 }
247
248 test {RPOPLPUSH against non existing src key} {
249 r del srclist dstlist
250 assert_equal {} [r rpoplpush srclist dstlist]
251 } {}
252
253 foreach type {ziplist list} {
254 test "Basic LPOP/RPOP - $type" {
255 create_$type mylist {0 1 2}
256 assert_equal 0 [r lpop mylist]
257 assert_equal 2 [r rpop mylist]
258 assert_equal 1 [r lpop mylist]
259 assert_equal 0 [r llen mylist]
260
261 # pop on empty list
262 assert_equal {} [r lpop mylist]
263 assert_equal {} [r rpop mylist]
264 }
265 }
266
267 test {LPOP/RPOP against non list value} {
268 r set notalist foo
269 assert_error ERR*kind* {r lpop notalist}
270 assert_error ERR*kind* {r rpop notalist}
271 }
272
273 foreach {type num} {ziplist 250 list 500} {
274 test "Mass RPOP/LPOP - $type" {
275 r del mylist
276 set sum1 0
277 for {set i 0} {$i < $num} {incr i} {
278 r lpush mylist $i
279 incr sum1 $i
280 }
281 assert_encoding $type mylist
282 set sum2 0
283 for {set i 0} {$i < [expr $num/2]} {incr i} {
284 incr sum2 [r lpop mylist]
285 incr sum2 [r rpop mylist]
286 }
287 assert_equal $sum1 $sum2
288 }
289 }
290
291 foreach type {ziplist list} {
292 test "LRANGE basics - $type" {
293 create_$type mylist {0 1 2 3 4 5 6 7 8 9}
294 assert_equal {1 2 3 4 5 6 7 8} [r lrange mylist 1 -2]
295 assert_equal {7 8 9} [r lrange mylist -3 -1]
296 assert_equal {4} [r lrange mylist 4 4]
297 }
298
299 test "LRANGE inverted indexes - $type" {
300 create_$type mylist {0 1 2 3 4 5 6 7 8 9}
301 assert_equal {} [r lrange mylist 6 2]
302 }
303
304 test "LRANGE out of range indexes including the full list - $type" {
305 create_$type mylist {1 2 3}
306 assert_equal {1 2 3} [r lrange mylist -1000 1000]
307 }
308 }
309
310 test {LRANGE against non existing key} {
311 assert_equal {} [r lrange nosuchkey 0 1]
312 }
313
314 foreach type {ziplist list} {
315 test "LTRIM basics - $type" {
316 create_$type mylist "foo"
317 for {set i 0} {$i < 100} {incr i} {
318 r lpush mylist $i
319 r ltrim mylist 0 4
320 }
321 r lrange mylist 0 -1
322 } {99 98 97 96 95}
323
324 test "LTRIM stress testing - $type" {
325 set mylist {}
326 for {set i 0} {$i < 20} {incr i} {
327 lappend mylist $i
328 }
329
330 for {set j 0} {$j < 100} {incr j} {
331 create_$type mylist $mylist
332
333 # Trim at random
334 set a [randomInt 20]
335 set b [randomInt 20]
336 r ltrim mylist $a $b
337 assert_equal [lrange $mylist $a $b] [r lrange mylist 0 -1]
338 }
339 }
340
341 }
342
343 foreach type {ziplist list} {
344 test "LSET - $type" {
345 create_$type mylist {99 98 97 96 95}
346 r lset mylist 1 foo
347 r lset mylist -1 bar
348 assert_equal {99 foo 97 96 bar} [r lrange mylist 0 -1]
349 }
350
351 test "LSET out of range index - $type" {
352 assert_error ERR*range* {r lset mylist 10 foo}
353 }
354 }
355
356 test {LSET against non existing key} {
357 assert_error ERR*key* {r lset nosuchkey 10 foo}
358 }
359
360 test {LSET against non list value} {
361 r set nolist foobar
362 assert_error ERR*value* {r lset nolist 0 foo}
363 }
364
365 foreach type {ziplist list} {
366 test "LREM remove all the occurrences - $type" {
367 create_$type mylist {foo bar foobar foobared zap bar test foo}
368 assert_equal 2 [r lrem mylist 0 bar]
369 assert_equal {foo foobar foobared zap test foo} [r lrange mylist 0 -1]
370 }
371
372 test "LREM remove the first occurrence - $type" {
373 assert_equal 1 [r lrem mylist 1 foo]
374 assert_equal {foobar foobared zap test foo} [r lrange mylist 0 -1]
375 }
376
377 test "LREM remove non existing element - $type" {
378 assert_equal 0 [r lrem mylist 1 nosuchelement]
379 assert_equal {foobar foobared zap test foo} [r lrange mylist 0 -1]
380 }
381
382 test "LREM starting from tail with negative count - $type" {
383 create_$type mylist {foo bar foobar foobared zap bar test foo foo}
384 assert_equal 1 [r lrem mylist -1 bar]
385 assert_equal {foo bar foobar foobared zap test foo foo} [r lrange mylist 0 -1]
386 }
387
388 test "LREM starting from tail with negative count (2) - $type" {
389 assert_equal 2 [r lrem mylist -2 foo]
390 assert_equal {foo bar foobar foobared zap test} [r lrange mylist 0 -1]
391 }
392
393 test "LREM deleting objects that may be int encoded - $type" {
394 create_$type myotherlist {1 2 3}
395 assert_equal 1 [r lrem myotherlist 1 2]
396 assert_equal 2 [r llen myotherlist]
397 }
398 }
399 }