4 "set-max-intset-entries" 512
7 proc create_set
{key entries
} {
9 foreach entry $entries { r sadd
$key $entry }
12 test
{SADD
, SCARD
, SISMEMBER
, SMEMBERS basics
- regular
set} {
13 create_set myset
{foo
}
14 assert_encoding hashtable myset
15 assert_equal
1 [r sadd myset bar
]
16 assert_equal
0 [r sadd myset bar
]
17 assert_equal
2 [r scard myset
]
18 assert_equal
1 [r sismember myset foo
]
19 assert_equal
1 [r sismember myset bar
]
20 assert_equal
0 [r sismember myset bla
]
21 assert_equal
{bar foo
} [lsort [r smembers myset
]]
24 test
{SADD
, SCARD
, SISMEMBER
, SMEMBERS basics
- intset
} {
26 assert_encoding intset myset
27 assert_equal
1 [r sadd myset
16]
28 assert_equal
0 [r sadd myset
16]
29 assert_equal
2 [r scard myset
]
30 assert_equal
1 [r sismember myset
16]
31 assert_equal
1 [r sismember myset
17]
32 assert_equal
0 [r sismember myset
18]
33 assert_equal
{16 17} [lsort [r smembers myset
]]
36 test
{SADD against non
set} {
38 assert_error ERR
*kind
* {r sadd mylist bar
}
41 test
"SADD a non-integer against an intset" {
42 create_set myset
{1 2 3}
43 assert_encoding intset myset
44 assert_equal
1 [r sadd myset a
]
45 assert_encoding hashtable myset
48 test
"SADD an integer larger than 64 bits" {
49 create_set myset
{213244124402402314402033402}
50 assert_encoding hashtable myset
51 assert_equal
1 [r sismember myset
213244124402402314402033402]
54 test
"SADD overflows the maximum allowed integers in an intset" {
56 for {set i
0} {$i < 512} {incr i
} { r sadd myset
$i }
57 assert_encoding intset myset
58 assert_equal
1 [r sadd myset
512]
59 assert_encoding hashtable myset
62 test
{Variadic SADD
} {
64 assert_equal
3 [r sadd myset a b c
]
65 assert_equal
2 [r sadd myset A a b c B
]
66 assert_equal
[lsort {A a b c B
}] [lsort [r smembers myset
]]
69 test
"Set encoding after DEBUG RELOAD" {
70 r del myintset myhashset mylargeintset
71 for {set i
0} {$i < 100} {incr i
} { r sadd myintset
$i }
72 for {set i
0} {$i < 1280} {incr i
} { r sadd mylargeintset
$i }
73 for {set i
0} {$i < 256} {incr i
} { r sadd myhashset
[format "i%03d" $i] }
74 assert_encoding intset myintset
75 assert_encoding hashtable mylargeintset
76 assert_encoding hashtable myhashset
79 assert_encoding intset myintset
80 assert_encoding hashtable mylargeintset
81 assert_encoding hashtable myhashset
84 test
{SREM basics
- regular
set} {
85 create_set myset
{foo bar ciao
}
86 assert_encoding hashtable myset
87 assert_equal
0 [r srem myset qux
]
88 assert_equal
1 [r srem myset foo
]
89 assert_equal
{bar ciao
} [lsort [r smembers myset
]]
92 test
{SREM basics
- intset
} {
93 create_set myset
{3 4 5}
94 assert_encoding intset myset
95 assert_equal
0 [r srem myset
6]
96 assert_equal
1 [r srem myset
4]
97 assert_equal
{3 5} [lsort [r smembers myset
]]
100 test
{SREM with multiple arguments
} {
103 assert_equal
0 [r srem myset k k k
]
104 assert_equal
2 [r srem myset b d x y
]
105 lsort [r smembers myset
]
108 test
{SREM variadic version with more args needed to
destroy the key
} {
111 r srem myset
1 2 3 4 5 6 7 8
114 foreach {type
} {hashtable intset
} {
115 for {set i
1} {$i <= 5} {incr i
} {
116 r del
[format "set%d" $i]
118 for {set i
0} {$i < 200} {incr i
} {
120 r sadd set2
[expr $i+195]
122 foreach i
{199 195 1000 2000} {
125 for {set i
5} {$i < 200} {incr i
} {
130 # To make sure the sets are encoded as the type we are testing -- also
131 # when the VM is enabled and the values may be swapped in and out
132 # while the tests are running -- an extra element is added to every
133 # set that determines its encoding.
135 if {$type eq
"hashtable"} {
139 for {set i
1} {$i <= 5} {incr i
} {
140 r sadd
[format "set%d" $i] $large
143 test
"Generated sets must be encoded as $type" {
144 for {set i
1} {$i <= 5} {incr i
} {
145 assert_encoding
$type [format "set%d" $i]
149 test
"SINTER with two sets - $type" {
150 assert_equal
[list 195 196 197 198 199 $large] [lsort [r sinter set1 set2
]]
153 test
"SINTERSTORE with two sets - $type" {
154 r sinterstore setres set1 set2
155 assert_encoding
$type setres
156 assert_equal
[list 195 196 197 198 199 $large] [lsort [r smembers setres
]]
159 test
"SINTERSTORE with two sets, after a DEBUG RELOAD - $type" {
161 r sinterstore setres set1 set2
162 assert_encoding
$type setres
163 assert_equal
[list 195 196 197 198 199 $large] [lsort [r smembers setres
]]
166 test
"SUNION with two sets - $type" {
167 set expected
[lsort -uniq "[r smembers set1] [r smembers set2]"]
168 assert_equal
$expected [lsort [r sunion set1 set2
]]
171 test
"SUNIONSTORE with two sets - $type" {
172 r sunionstore setres set1 set2
173 assert_encoding
$type setres
174 set expected
[lsort -uniq "[r smembers set1] [r smembers set2]"]
175 assert_equal
$expected [lsort [r smembers setres
]]
178 test
"SINTER against three sets - $type" {
179 assert_equal
[list 195 199 $large] [lsort [r sinter set1 set2 set3
]]
182 test
"SINTERSTORE with three sets - $type" {
183 r sinterstore setres set1 set2 set3
184 assert_equal
[list 195 199 $large] [lsort [r smembers setres
]]
187 test
"SUNION with non existing keys - $type" {
188 set expected
[lsort -uniq "[r smembers set1] [r smembers set2]"]
189 assert_equal
$expected [lsort [r sunion nokey1 set1 set2 nokey2
]]
192 test
"SDIFF with two sets - $type" {
193 assert_equal
{0 1 2 3 4} [lsort [r sdiff set1 set4
]]
196 test
"SDIFF with three sets - $type" {
197 assert_equal
{1 2 3 4} [lsort [r sdiff set1 set4 set5
]]
200 test
"SDIFFSTORE with three sets - $type" {
201 r sdiffstore setres set1 set4 set5
202 # The type is determined by type of the first key to diff against.
203 # See the implementation for more information.
204 assert_encoding
$type setres
205 assert_equal
{1 2 3 4} [lsort [r smembers setres
]]
209 test
"SDIFF with first set empty" {
213 r sdiff set1 set2 set3
216 test
"SINTER against non-set should throw error" {
218 assert_error
"ERR*wrong kind*" {r sinter key1 noset
}
221 test
"SUNION against non-set should throw error" {
223 assert_error
"ERR*wrong kind*" {r sunion key1 noset
}
226 test
"SINTER should handle non existing key as empty" {
230 r sinter set1 set2 set3
233 test
"SINTER with same integer elements but different encoding" {
238 assert_encoding intset set1
239 assert_encoding hashtable set2
240 lsort [r sinter set1 set2
]
243 test
"SINTERSTORE against non existing keys should delete dstkey" {
245 assert_equal
0 [r sinterstore setres foo111 bar222
]
246 assert_equal
0 [r exists setres
]
249 test
"SUNIONSTORE against non existing keys should delete dstkey" {
251 assert_equal
0 [r sunionstore setres foo111 bar222
]
252 assert_equal
0 [r exists setres
]
255 foreach {type contents
} {hashtable
{a b c
} intset
{1 2 3}} {
256 test
"SPOP basics - $type" {
257 create_set myset
$contents
258 assert_encoding
$type myset
259 assert_equal
$contents [lsort [list [r spop myset
] [r spop myset
] [r spop myset
]]]
260 assert_equal
0 [r scard myset
]
263 test
"SRANDMEMBER - $type" {
264 create_set myset
$contents
265 unset -nocomplain myset
267 for {set i
0} {$i < 100} {incr i
} {
268 set myset
([r srandmember myset
]) 1
270 assert_equal
$contents [lsort [array names myset
]]
276 create_set myset1
{1 a b
}
277 create_set myset2
{2 3 4}
278 assert_encoding hashtable myset1
279 assert_encoding intset myset2
282 test
"SMOVE basics - from regular set to intset" {
283 # move a non-integer element to an intset should convert encoding
285 assert_equal
1 [r smove myset1 myset2 a
]
286 assert_equal
{1 b
} [lsort [r smembers myset1
]]
287 assert_equal
{2 3 4 a
} [lsort [r smembers myset2
]]
288 assert_encoding hashtable myset2
290 # move an integer element should not convert the encoding
292 assert_equal
1 [r smove myset1 myset2
1]
293 assert_equal
{a b
} [lsort [r smembers myset1
]]
294 assert_equal
{1 2 3 4} [lsort [r smembers myset2
]]
295 assert_encoding intset myset2
298 test
"SMOVE basics - from intset to regular set" {
300 assert_equal
1 [r smove myset2 myset1
2]
301 assert_equal
{1 2 a b
} [lsort [r smembers myset1
]]
302 assert_equal
{3 4} [lsort [r smembers myset2
]]
305 test
"SMOVE non existing key" {
307 assert_equal
0 [r smove myset1 myset2 foo
]
308 assert_equal
{1 a b
} [lsort [r smembers myset1
]]
309 assert_equal
{2 3 4} [lsort [r smembers myset2
]]
312 test
"SMOVE non existing src set" {
314 assert_equal
0 [r smove noset myset2 foo
]
315 assert_equal
{2 3 4} [lsort [r smembers myset2
]]
318 test
"SMOVE from regular set to non existing destination set" {
320 assert_equal
1 [r smove myset1 myset3 a
]
321 assert_equal
{1 b
} [lsort [r smembers myset1
]]
322 assert_equal
{a
} [lsort [r smembers myset3
]]
323 assert_encoding hashtable myset3
326 test
"SMOVE from intset to non existing destination set" {
328 assert_equal
1 [r smove myset2 myset3
2]
329 assert_equal
{3 4} [lsort [r smembers myset2
]]
330 assert_equal
{2} [lsort [r smembers myset3
]]
331 assert_encoding intset myset3
334 test
"SMOVE wrong src key type" {
336 assert_error
"ERR*wrong kind*" {r smove x myset2 foo
}
339 test
"SMOVE wrong dst key type" {
341 assert_error
"ERR*wrong kind*" {r smove myset2 x foo
}
344 test
"SMOVE with identical source and destination" {
348 lsort [r smembers
set]
352 test
{intsets implementation stress testing
} {
353 for {set j
0} {$j < 20} {incr j
} {
357 set len
[randomInt
1024]
358 for {set i
0} {$i < $len} {incr i
} {
360 set data
[randomInt
65536]
362 set data
[randomInt
4294967296]
364 set data
[randomInt
18446744073709551616]
369 assert_equal
[lsort [r smembers s
]] [lsort [array names s
]]
370 set len
[array size s
]
371 for {set i
0} {$i < $len} {incr i
} {
373 if {![info exists s
($e)]} {
374 puts "Can't find '$e' on local array"
375 puts "Local array: [lsort [r smembers s]]"
376 puts "Remote array: [lsort [array names s]]"
381 assert_equal
[r scard s
] 0
382 assert_equal
[array size s
] 0