set.tcl 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. start_server {
  2. tags {"set"}
  3. overrides {
  4. "set-max-intset-entries" 512
  5. }
  6. } {
  7. proc create_set {key entries} {
  8. r del $key
  9. foreach entry $entries { r sadd $key $entry }
  10. }
  11. test {SADD, SCARD, SISMEMBER, SMEMBERS basics - regular set} {
  12. create_set myset {foo}
  13. assert_encoding hashtable myset
  14. assert_equal 1 [r sadd myset bar]
  15. assert_equal 0 [r sadd myset bar]
  16. assert_equal 2 [r scard myset]
  17. assert_equal 1 [r sismember myset foo]
  18. assert_equal 1 [r sismember myset bar]
  19. assert_equal 0 [r sismember myset bla]
  20. assert_equal {bar foo} [lsort [r smembers myset]]
  21. }
  22. test {SADD, SCARD, SISMEMBER, SMEMBERS basics - intset} {
  23. create_set myset {17}
  24. assert_encoding intset myset
  25. assert_equal 1 [r sadd myset 16]
  26. assert_equal 0 [r sadd myset 16]
  27. assert_equal 2 [r scard myset]
  28. assert_equal 1 [r sismember myset 16]
  29. assert_equal 1 [r sismember myset 17]
  30. assert_equal 0 [r sismember myset 18]
  31. assert_equal {16 17} [lsort [r smembers myset]]
  32. }
  33. test {SADD against non set} {
  34. r lpush mylist foo
  35. assert_error ERR*kind* {r sadd mylist bar}
  36. }
  37. test "SADD a non-integer against an intset" {
  38. create_set myset {1 2 3}
  39. assert_encoding intset myset
  40. assert_equal 1 [r sadd myset a]
  41. assert_encoding hashtable myset
  42. }
  43. test "SADD an integer larger than 64 bits" {
  44. create_set myset {213244124402402314402033402}
  45. assert_encoding hashtable myset
  46. assert_equal 1 [r sismember myset 213244124402402314402033402]
  47. }
  48. test "SADD overflows the maximum allowed integers in an intset" {
  49. r del myset
  50. for {set i 0} {$i < 512} {incr i} { r sadd myset $i }
  51. assert_encoding intset myset
  52. assert_equal 1 [r sadd myset 512]
  53. assert_encoding hashtable myset
  54. }
  55. test {Variadic SADD} {
  56. r del myset
  57. assert_equal 3 [r sadd myset a b c]
  58. assert_equal 2 [r sadd myset A a b c B]
  59. assert_equal [lsort {A a b c B}] [lsort [r smembers myset]]
  60. }
  61. test "Set encoding after DEBUG RELOAD" {
  62. r del myintset myhashset mylargeintset
  63. for {set i 0} {$i < 100} {incr i} { r sadd myintset $i }
  64. for {set i 0} {$i < 1280} {incr i} { r sadd mylargeintset $i }
  65. for {set i 0} {$i < 256} {incr i} { r sadd myhashset [format "i%03d" $i] }
  66. assert_encoding intset myintset
  67. assert_encoding hashtable mylargeintset
  68. assert_encoding hashtable myhashset
  69. r debug reload
  70. assert_encoding intset myintset
  71. assert_encoding hashtable mylargeintset
  72. assert_encoding hashtable myhashset
  73. }
  74. test {SREM basics - regular set} {
  75. create_set myset {foo bar ciao}
  76. assert_encoding hashtable myset
  77. assert_equal 0 [r srem myset qux]
  78. assert_equal 1 [r srem myset foo]
  79. assert_equal {bar ciao} [lsort [r smembers myset]]
  80. }
  81. test {SREM basics - intset} {
  82. create_set myset {3 4 5}
  83. assert_encoding intset myset
  84. assert_equal 0 [r srem myset 6]
  85. assert_equal 1 [r srem myset 4]
  86. assert_equal {3 5} [lsort [r smembers myset]]
  87. }
  88. test {SREM with multiple arguments} {
  89. r del myset
  90. r sadd myset a b c d
  91. assert_equal 0 [r srem myset k k k]
  92. assert_equal 2 [r srem myset b d x y]
  93. lsort [r smembers myset]
  94. } {a c}
  95. test {SREM variadic version with more args needed to destroy the key} {
  96. r del myset
  97. r sadd myset 1 2 3
  98. r srem myset 1 2 3 4 5 6 7 8
  99. } {3}
  100. foreach {type} {hashtable intset} {
  101. for {set i 1} {$i <= 5} {incr i} {
  102. r del [format "set%d" $i]
  103. }
  104. for {set i 0} {$i < 200} {incr i} {
  105. r sadd set1 $i
  106. r sadd set2 [expr $i+195]
  107. }
  108. foreach i {199 195 1000 2000} {
  109. r sadd set3 $i
  110. }
  111. for {set i 5} {$i < 200} {incr i} {
  112. r sadd set4 $i
  113. }
  114. r sadd set5 0
  115. # To make sure the sets are encoded as the type we are testing -- also
  116. # when the VM is enabled and the values may be swapped in and out
  117. # while the tests are running -- an extra element is added to every
  118. # set that determines its encoding.
  119. set large 200
  120. if {$type eq "hashtable"} {
  121. set large foo
  122. }
  123. for {set i 1} {$i <= 5} {incr i} {
  124. r sadd [format "set%d" $i] $large
  125. }
  126. test "Generated sets must be encoded as $type" {
  127. for {set i 1} {$i <= 5} {incr i} {
  128. assert_encoding $type [format "set%d" $i]
  129. }
  130. }
  131. test "SINTER with two sets - $type" {
  132. assert_equal [list 195 196 197 198 199 $large] [lsort [r sinter set1 set2]]
  133. }
  134. test "SINTERSTORE with two sets - $type" {
  135. r sinterstore setres set1 set2
  136. assert_encoding $type setres
  137. assert_equal [list 195 196 197 198 199 $large] [lsort [r smembers setres]]
  138. }
  139. test "SINTERSTORE with two sets, after a DEBUG RELOAD - $type" {
  140. r debug reload
  141. r sinterstore setres set1 set2
  142. assert_encoding $type setres
  143. assert_equal [list 195 196 197 198 199 $large] [lsort [r smembers setres]]
  144. }
  145. test "SUNION with two sets - $type" {
  146. set expected [lsort -uniq "[r smembers set1] [r smembers set2]"]
  147. assert_equal $expected [lsort [r sunion set1 set2]]
  148. }
  149. test "SUNIONSTORE with two sets - $type" {
  150. r sunionstore setres set1 set2
  151. assert_encoding $type setres
  152. set expected [lsort -uniq "[r smembers set1] [r smembers set2]"]
  153. assert_equal $expected [lsort [r smembers setres]]
  154. }
  155. test "SINTER against three sets - $type" {
  156. assert_equal [list 195 199 $large] [lsort [r sinter set1 set2 set3]]
  157. }
  158. test "SINTERSTORE with three sets - $type" {
  159. r sinterstore setres set1 set2 set3
  160. assert_equal [list 195 199 $large] [lsort [r smembers setres]]
  161. }
  162. test "SUNION with non existing keys - $type" {
  163. set expected [lsort -uniq "[r smembers set1] [r smembers set2]"]
  164. assert_equal $expected [lsort [r sunion nokey1 set1 set2 nokey2]]
  165. }
  166. test "SDIFF with two sets - $type" {
  167. assert_equal {0 1 2 3 4} [lsort [r sdiff set1 set4]]
  168. }
  169. test "SDIFF with three sets - $type" {
  170. assert_equal {1 2 3 4} [lsort [r sdiff set1 set4 set5]]
  171. }
  172. test "SDIFFSTORE with three sets - $type" {
  173. r sdiffstore setres set1 set4 set5
  174. # The type is determined by type of the first key to diff against.
  175. # See the implementation for more information.
  176. assert_encoding $type setres
  177. assert_equal {1 2 3 4} [lsort [r smembers setres]]
  178. }
  179. }
  180. test "SINTER against non-set should throw error" {
  181. r set key1 x
  182. assert_error "ERR*wrong kind*" {r sinter key1 noset}
  183. }
  184. test "SUNION against non-set should throw error" {
  185. r set key1 x
  186. assert_error "ERR*wrong kind*" {r sunion key1 noset}
  187. }
  188. test "SINTERSTORE against non existing keys should delete dstkey" {
  189. r set setres xxx
  190. assert_equal 0 [r sinterstore setres foo111 bar222]
  191. assert_equal 0 [r exists setres]
  192. }
  193. test "SUNIONSTORE against non existing keys should delete dstkey" {
  194. r set setres xxx
  195. assert_equal 0 [r sunionstore setres foo111 bar222]
  196. assert_equal 0 [r exists setres]
  197. }
  198. foreach {type contents} {hashtable {a b c} intset {1 2 3}} {
  199. test "SPOP basics - $type" {
  200. create_set myset $contents
  201. assert_encoding $type myset
  202. assert_equal $contents [lsort [list [r spop myset] [r spop myset] [r spop myset]]]
  203. assert_equal 0 [r scard myset]
  204. }
  205. test "SRANDMEMBER - $type" {
  206. create_set myset $contents
  207. unset -nocomplain myset
  208. array set myset {}
  209. for {set i 0} {$i < 100} {incr i} {
  210. set myset([r srandmember myset]) 1
  211. }
  212. assert_equal $contents [lsort [array names myset]]
  213. }
  214. }
  215. proc setup_move {} {
  216. r del myset3 myset4
  217. create_set myset1 {1 a b}
  218. create_set myset2 {2 3 4}
  219. assert_encoding hashtable myset1
  220. assert_encoding intset myset2
  221. }
  222. test "SMOVE basics - from regular set to intset" {
  223. # move a non-integer element to an intset should convert encoding
  224. setup_move
  225. assert_equal 1 [r smove myset1 myset2 a]
  226. assert_equal {1 b} [lsort [r smembers myset1]]
  227. assert_equal {2 3 4 a} [lsort [r smembers myset2]]
  228. assert_encoding hashtable myset2
  229. # move an integer element should not convert the encoding
  230. setup_move
  231. assert_equal 1 [r smove myset1 myset2 1]
  232. assert_equal {a b} [lsort [r smembers myset1]]
  233. assert_equal {1 2 3 4} [lsort [r smembers myset2]]
  234. assert_encoding intset myset2
  235. }
  236. test "SMOVE basics - from intset to regular set" {
  237. setup_move
  238. assert_equal 1 [r smove myset2 myset1 2]
  239. assert_equal {1 2 a b} [lsort [r smembers myset1]]
  240. assert_equal {3 4} [lsort [r smembers myset2]]
  241. }
  242. test "SMOVE non existing key" {
  243. setup_move
  244. assert_equal 0 [r smove myset1 myset2 foo]
  245. assert_equal {1 a b} [lsort [r smembers myset1]]
  246. assert_equal {2 3 4} [lsort [r smembers myset2]]
  247. }
  248. test "SMOVE non existing src set" {
  249. setup_move
  250. assert_equal 0 [r smove noset myset2 foo]
  251. assert_equal {2 3 4} [lsort [r smembers myset2]]
  252. }
  253. test "SMOVE from regular set to non existing destination set" {
  254. setup_move
  255. assert_equal 1 [r smove myset1 myset3 a]
  256. assert_equal {1 b} [lsort [r smembers myset1]]
  257. assert_equal {a} [lsort [r smembers myset3]]
  258. assert_encoding hashtable myset3
  259. }
  260. test "SMOVE from intset to non existing destination set" {
  261. setup_move
  262. assert_equal 1 [r smove myset2 myset3 2]
  263. assert_equal {3 4} [lsort [r smembers myset2]]
  264. assert_equal {2} [lsort [r smembers myset3]]
  265. assert_encoding intset myset3
  266. }
  267. test "SMOVE wrong src key type" {
  268. r set x 10
  269. assert_error "ERR*wrong kind*" {r smove x myset2 foo}
  270. }
  271. test "SMOVE wrong dst key type" {
  272. r set x 10
  273. assert_error "ERR*wrong kind*" {r smove myset2 x foo}
  274. }
  275. tags {slow} {
  276. test {intsets implementation stress testing} {
  277. for {set j 0} {$j < 20} {incr j} {
  278. unset -nocomplain s
  279. array set s {}
  280. r del s
  281. set len [randomInt 1024]
  282. for {set i 0} {$i < $len} {incr i} {
  283. randpath {
  284. set data [randomInt 65536]
  285. } {
  286. set data [randomInt 4294967296]
  287. } {
  288. set data [randomInt 18446744073709551616]
  289. }
  290. set s($data) {}
  291. r sadd s $data
  292. }
  293. assert_equal [lsort [r smembers s]] [lsort [array names s]]
  294. set len [array size s]
  295. for {set i 0} {$i < $len} {incr i} {
  296. set e [r spop s]
  297. if {![info exists s($e)]} {
  298. puts "Can't find '$e' on local array"
  299. puts "Local array: [lsort [r smembers s]]"
  300. puts "Remote array: [lsort [array names s]]"
  301. error "exception"
  302. }
  303. array unset s $e
  304. }
  305. assert_equal [r scard s] 0
  306. assert_equal [array size s] 0
  307. }
  308. }
  309. }
  310. }