zset.tcl 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944
  1. start_server {tags {"zset"}} {
  2. proc create_zset {key items} {
  3. r del $key
  4. foreach {score entry} $items {
  5. r zadd $key $score $entry
  6. }
  7. }
  8. proc basics {encoding} {
  9. if {$encoding == "ziplist"} {
  10. r config set zset-max-ziplist-entries 128
  11. r config set zset-max-ziplist-value 64
  12. } elseif {$encoding == "skiplist"} {
  13. r config set zset-max-ziplist-entries 0
  14. r config set zset-max-ziplist-value 0
  15. } else {
  16. puts "Unknown sorted set encoding"
  17. exit
  18. }
  19. test "Check encoding - $encoding" {
  20. r del ztmp
  21. r zadd ztmp 10 x
  22. assert_encoding $encoding ztmp
  23. }
  24. test "ZSET basic ZADD and score update - $encoding" {
  25. r del ztmp
  26. r zadd ztmp 10 x
  27. r zadd ztmp 20 y
  28. r zadd ztmp 30 z
  29. assert_equal {x y z} [r zrange ztmp 0 -1]
  30. r zadd ztmp 1 y
  31. assert_equal {y x z} [r zrange ztmp 0 -1]
  32. }
  33. test "ZSET element can't be set to NaN with ZADD - $encoding" {
  34. assert_error "*not*float*" {r zadd myzset nan abc}
  35. }
  36. test "ZSET element can't be set to NaN with ZINCRBY" {
  37. assert_error "*not*float*" {r zadd myzset nan abc}
  38. }
  39. test "ZINCRBY calls leading to NaN result in error" {
  40. r zincrby myzset +inf abc
  41. assert_error "*NaN*" {r zincrby myzset -inf abc}
  42. }
  43. test {ZADD - Variadic version base case} {
  44. r del myzset
  45. list [r zadd myzset 10 a 20 b 30 c] [r zrange myzset 0 -1 withscores]
  46. } {3 {a 10 b 20 c 30}}
  47. test {ZADD - Return value is the number of actually added items} {
  48. list [r zadd myzset 5 x 20 b 30 c] [r zrange myzset 0 -1 withscores]
  49. } {1 {x 5 a 10 b 20 c 30}}
  50. test {ZADD - Variadic version does not add nothing on single parsing err} {
  51. r del myzset
  52. catch {r zadd myzset 10 a 20 b 30.badscore c} e
  53. assert_match {*ERR*not*float*} $e
  54. r exists myzset
  55. } {0}
  56. test {ZADD - Variadic version will raise error on missing arg} {
  57. r del myzset
  58. catch {r zadd myzset 10 a 20 b 30 c 40} e
  59. assert_match {*ERR*syntax*} $e
  60. }
  61. test {ZINCRBY does not work variadic even if shares ZADD implementation} {
  62. r del myzset
  63. catch {r zincrby myzset 10 a 20 b 30 c} e
  64. assert_match {*ERR*wrong*number*arg*} $e
  65. }
  66. test "ZCARD basics - $encoding" {
  67. assert_equal 3 [r zcard ztmp]
  68. assert_equal 0 [r zcard zdoesntexist]
  69. }
  70. test "ZREM removes key after last element is removed" {
  71. r del ztmp
  72. r zadd ztmp 10 x
  73. r zadd ztmp 20 y
  74. assert_equal 1 [r exists ztmp]
  75. assert_equal 0 [r zrem ztmp z]
  76. assert_equal 1 [r zrem ztmp y]
  77. assert_equal 1 [r zrem ztmp x]
  78. assert_equal 0 [r exists ztmp]
  79. }
  80. test "ZREM variadic version" {
  81. r del ztmp
  82. r zadd ztmp 10 a 20 b 30 c
  83. assert_equal 2 [r zrem ztmp x y a b k]
  84. assert_equal 0 [r zrem ztmp foo bar]
  85. assert_equal 1 [r zrem ztmp c]
  86. r exists ztmp
  87. } {0}
  88. test "ZREM variadic version -- remove elements after key deletion" {
  89. r del ztmp
  90. r zadd ztmp 10 a 20 b 30 c
  91. r zrem ztmp a b c d e f g
  92. } {3}
  93. test "ZRANGE basics - $encoding" {
  94. r del ztmp
  95. r zadd ztmp 1 a
  96. r zadd ztmp 2 b
  97. r zadd ztmp 3 c
  98. r zadd ztmp 4 d
  99. assert_equal {a b c d} [r zrange ztmp 0 -1]
  100. assert_equal {a b c} [r zrange ztmp 0 -2]
  101. assert_equal {b c d} [r zrange ztmp 1 -1]
  102. assert_equal {b c} [r zrange ztmp 1 -2]
  103. assert_equal {c d} [r zrange ztmp -2 -1]
  104. assert_equal {c} [r zrange ztmp -2 -2]
  105. # out of range start index
  106. assert_equal {a b c} [r zrange ztmp -5 2]
  107. assert_equal {a b} [r zrange ztmp -5 1]
  108. assert_equal {} [r zrange ztmp 5 -1]
  109. assert_equal {} [r zrange ztmp 5 -2]
  110. # out of range end index
  111. assert_equal {a b c d} [r zrange ztmp 0 5]
  112. assert_equal {b c d} [r zrange ztmp 1 5]
  113. assert_equal {} [r zrange ztmp 0 -5]
  114. assert_equal {} [r zrange ztmp 1 -5]
  115. # withscores
  116. assert_equal {a 1 b 2 c 3 d 4} [r zrange ztmp 0 -1 withscores]
  117. }
  118. test "ZREVRANGE basics - $encoding" {
  119. r del ztmp
  120. r zadd ztmp 1 a
  121. r zadd ztmp 2 b
  122. r zadd ztmp 3 c
  123. r zadd ztmp 4 d
  124. assert_equal {d c b a} [r zrevrange ztmp 0 -1]
  125. assert_equal {d c b} [r zrevrange ztmp 0 -2]
  126. assert_equal {c b a} [r zrevrange ztmp 1 -1]
  127. assert_equal {c b} [r zrevrange ztmp 1 -2]
  128. assert_equal {b a} [r zrevrange ztmp -2 -1]
  129. assert_equal {b} [r zrevrange ztmp -2 -2]
  130. # out of range start index
  131. assert_equal {d c b} [r zrevrange ztmp -5 2]
  132. assert_equal {d c} [r zrevrange ztmp -5 1]
  133. assert_equal {} [r zrevrange ztmp 5 -1]
  134. assert_equal {} [r zrevrange ztmp 5 -2]
  135. # out of range end index
  136. assert_equal {d c b a} [r zrevrange ztmp 0 5]
  137. assert_equal {c b a} [r zrevrange ztmp 1 5]
  138. assert_equal {} [r zrevrange ztmp 0 -5]
  139. assert_equal {} [r zrevrange ztmp 1 -5]
  140. # withscores
  141. assert_equal {d 4 c 3 b 2 a 1} [r zrevrange ztmp 0 -1 withscores]
  142. }
  143. test "ZRANK/ZREVRANK basics - $encoding" {
  144. r del zranktmp
  145. r zadd zranktmp 10 x
  146. r zadd zranktmp 20 y
  147. r zadd zranktmp 30 z
  148. assert_equal 0 [r zrank zranktmp x]
  149. assert_equal 1 [r zrank zranktmp y]
  150. assert_equal 2 [r zrank zranktmp z]
  151. assert_equal "" [r zrank zranktmp foo]
  152. assert_equal 2 [r zrevrank zranktmp x]
  153. assert_equal 1 [r zrevrank zranktmp y]
  154. assert_equal 0 [r zrevrank zranktmp z]
  155. assert_equal "" [r zrevrank zranktmp foo]
  156. }
  157. test "ZRANK - after deletion - $encoding" {
  158. r zrem zranktmp y
  159. assert_equal 0 [r zrank zranktmp x]
  160. assert_equal 1 [r zrank zranktmp z]
  161. }
  162. test "ZINCRBY - can create a new sorted set - $encoding" {
  163. r del zset
  164. r zincrby zset 1 foo
  165. assert_equal {foo} [r zrange zset 0 -1]
  166. assert_equal 1 [r zscore zset foo]
  167. }
  168. test "ZINCRBY - increment and decrement - $encoding" {
  169. r zincrby zset 2 foo
  170. r zincrby zset 1 bar
  171. assert_equal {bar foo} [r zrange zset 0 -1]
  172. r zincrby zset 10 bar
  173. r zincrby zset -5 foo
  174. r zincrby zset -5 bar
  175. assert_equal {foo bar} [r zrange zset 0 -1]
  176. assert_equal -2 [r zscore zset foo]
  177. assert_equal 6 [r zscore zset bar]
  178. }
  179. proc create_default_zset {} {
  180. create_zset zset {-inf a 1 b 2 c 3 d 4 e 5 f +inf g}
  181. }
  182. test "ZRANGEBYSCORE/ZREVRANGEBYSCORE/ZCOUNT basics" {
  183. create_default_zset
  184. # inclusive range
  185. assert_equal {a b c} [r zrangebyscore zset -inf 2]
  186. assert_equal {b c d} [r zrangebyscore zset 0 3]
  187. assert_equal {d e f} [r zrangebyscore zset 3 6]
  188. assert_equal {e f g} [r zrangebyscore zset 4 +inf]
  189. assert_equal {c b a} [r zrevrangebyscore zset 2 -inf]
  190. assert_equal {d c b} [r zrevrangebyscore zset 3 0]
  191. assert_equal {f e d} [r zrevrangebyscore zset 6 3]
  192. assert_equal {g f e} [r zrevrangebyscore zset +inf 4]
  193. assert_equal 3 [r zcount zset 0 3]
  194. # exclusive range
  195. assert_equal {b} [r zrangebyscore zset (-inf (2]
  196. assert_equal {b c} [r zrangebyscore zset (0 (3]
  197. assert_equal {e f} [r zrangebyscore zset (3 (6]
  198. assert_equal {f} [r zrangebyscore zset (4 (+inf]
  199. assert_equal {b} [r zrevrangebyscore zset (2 (-inf]
  200. assert_equal {c b} [r zrevrangebyscore zset (3 (0]
  201. assert_equal {f e} [r zrevrangebyscore zset (6 (3]
  202. assert_equal {f} [r zrevrangebyscore zset (+inf (4]
  203. assert_equal 2 [r zcount zset (0 (3]
  204. # test empty ranges
  205. r zrem zset a
  206. r zrem zset g
  207. # inclusive
  208. assert_equal {} [r zrangebyscore zset 4 2]
  209. assert_equal {} [r zrangebyscore zset 6 +inf]
  210. assert_equal {} [r zrangebyscore zset -inf -6]
  211. assert_equal {} [r zrevrangebyscore zset +inf 6]
  212. assert_equal {} [r zrevrangebyscore zset -6 -inf]
  213. # exclusive
  214. assert_equal {} [r zrangebyscore zset (4 (2]
  215. assert_equal {} [r zrangebyscore zset 2 (2]
  216. assert_equal {} [r zrangebyscore zset (2 2]
  217. assert_equal {} [r zrangebyscore zset (6 (+inf]
  218. assert_equal {} [r zrangebyscore zset (-inf (-6]
  219. assert_equal {} [r zrevrangebyscore zset (+inf (6]
  220. assert_equal {} [r zrevrangebyscore zset (-6 (-inf]
  221. # empty inner range
  222. assert_equal {} [r zrangebyscore zset 2.4 2.6]
  223. assert_equal {} [r zrangebyscore zset (2.4 2.6]
  224. assert_equal {} [r zrangebyscore zset 2.4 (2.6]
  225. assert_equal {} [r zrangebyscore zset (2.4 (2.6]
  226. }
  227. test "ZRANGEBYSCORE with WITHSCORES" {
  228. create_default_zset
  229. assert_equal {b 1 c 2 d 3} [r zrangebyscore zset 0 3 withscores]
  230. assert_equal {d 3 c 2 b 1} [r zrevrangebyscore zset 3 0 withscores]
  231. }
  232. test "ZRANGEBYSCORE with LIMIT" {
  233. create_default_zset
  234. assert_equal {b c} [r zrangebyscore zset 0 10 LIMIT 0 2]
  235. assert_equal {d e f} [r zrangebyscore zset 0 10 LIMIT 2 3]
  236. assert_equal {d e f} [r zrangebyscore zset 0 10 LIMIT 2 10]
  237. assert_equal {} [r zrangebyscore zset 0 10 LIMIT 20 10]
  238. assert_equal {f e} [r zrevrangebyscore zset 10 0 LIMIT 0 2]
  239. assert_equal {d c b} [r zrevrangebyscore zset 10 0 LIMIT 2 3]
  240. assert_equal {d c b} [r zrevrangebyscore zset 10 0 LIMIT 2 10]
  241. assert_equal {} [r zrevrangebyscore zset 10 0 LIMIT 20 10]
  242. }
  243. test "ZRANGEBYSCORE with LIMIT and WITHSCORES" {
  244. create_default_zset
  245. assert_equal {e 4 f 5} [r zrangebyscore zset 2 5 LIMIT 2 3 WITHSCORES]
  246. assert_equal {d 3 c 2} [r zrevrangebyscore zset 5 2 LIMIT 2 3 WITHSCORES]
  247. }
  248. test "ZRANGEBYSCORE with non-value min or max" {
  249. assert_error "*not*float*" {r zrangebyscore fooz str 1}
  250. assert_error "*not*float*" {r zrangebyscore fooz 1 str}
  251. assert_error "*not*float*" {r zrangebyscore fooz 1 NaN}
  252. }
  253. proc create_default_lex_zset {} {
  254. create_zset zset {0 alpha 0 bar 0 cool 0 down
  255. 0 elephant 0 foo 0 great 0 hill
  256. 0 omega}
  257. }
  258. test "ZRANGEBYLEX/ZREVRANGEBYLEX/ZCOUNT basics" {
  259. create_default_lex_zset
  260. # inclusive range
  261. assert_equal {alpha bar cool} [r zrangebylex zset - \[cool]
  262. assert_equal {bar cool down} [r zrangebylex zset \[bar \[down]
  263. assert_equal {great hill omega} [r zrangebylex zset \[g +]
  264. assert_equal {cool bar alpha} [r zrevrangebylex zset \[cool -]
  265. assert_equal {down cool bar} [r zrevrangebylex zset \[down \[bar]
  266. assert_equal {omega hill great foo elephant down} [r zrevrangebylex zset + \[d]
  267. assert_equal 3 [r zlexcount zset \[ele \[h]
  268. # exclusive range
  269. assert_equal {alpha bar} [r zrangebylex zset - (cool]
  270. assert_equal {cool} [r zrangebylex zset (bar (down]
  271. assert_equal {hill omega} [r zrangebylex zset (great +]
  272. assert_equal {bar alpha} [r zrevrangebylex zset (cool -]
  273. assert_equal {cool} [r zrevrangebylex zset (down (bar]
  274. assert_equal {omega hill} [r zrevrangebylex zset + (great]
  275. assert_equal 2 [r zlexcount zset (ele (great]
  276. # inclusive and exclusive
  277. assert_equal {} [r zrangebylex zset (az (b]
  278. assert_equal {} [r zrangebylex zset (z +]
  279. assert_equal {} [r zrangebylex zset - \[aaaa]
  280. assert_equal {} [r zrevrangebylex zset \[elez \[elex]
  281. assert_equal {} [r zrevrangebylex zset (hill (omega]
  282. }
  283. test "ZRANGEBYSLEX with LIMIT" {
  284. create_default_lex_zset
  285. assert_equal {alpha bar} [r zrangebylex zset - \[cool LIMIT 0 2]
  286. assert_equal {bar cool} [r zrangebylex zset - \[cool LIMIT 1 2]
  287. assert_equal {} [r zrangebylex zset \[bar \[down LIMIT 0 0]
  288. assert_equal {} [r zrangebylex zset \[bar \[down LIMIT 2 0]
  289. assert_equal {bar} [r zrangebylex zset \[bar \[down LIMIT 0 1]
  290. assert_equal {cool} [r zrangebylex zset \[bar \[down LIMIT 1 1]
  291. assert_equal {bar cool down} [r zrangebylex zset \[bar \[down LIMIT 0 100]
  292. assert_equal {omega hill great foo elephant} [r zrevrangebylex zset + \[d LIMIT 0 5]
  293. assert_equal {omega hill great foo} [r zrevrangebylex zset + \[d LIMIT 0 4]
  294. }
  295. test "ZRANGEBYLEX with invalid lex range specifiers" {
  296. assert_error "*not*string*" {r zrangebylex fooz foo bar}
  297. assert_error "*not*string*" {r zrangebylex fooz \[foo bar}
  298. assert_error "*not*string*" {r zrangebylex fooz foo \[bar}
  299. assert_error "*not*string*" {r zrangebylex fooz +x \[bar}
  300. assert_error "*not*string*" {r zrangebylex fooz -x \[bar}
  301. }
  302. test "ZREMRANGEBYSCORE basics" {
  303. proc remrangebyscore {min max} {
  304. create_zset zset {1 a 2 b 3 c 4 d 5 e}
  305. assert_equal 1 [r exists zset]
  306. r zremrangebyscore zset $min $max
  307. }
  308. # inner range
  309. assert_equal 3 [remrangebyscore 2 4]
  310. assert_equal {a e} [r zrange zset 0 -1]
  311. # start underflow
  312. assert_equal 1 [remrangebyscore -10 1]
  313. assert_equal {b c d e} [r zrange zset 0 -1]
  314. # end overflow
  315. assert_equal 1 [remrangebyscore 5 10]
  316. assert_equal {a b c d} [r zrange zset 0 -1]
  317. # switch min and max
  318. assert_equal 0 [remrangebyscore 4 2]
  319. assert_equal {a b c d e} [r zrange zset 0 -1]
  320. # -inf to mid
  321. assert_equal 3 [remrangebyscore -inf 3]
  322. assert_equal {d e} [r zrange zset 0 -1]
  323. # mid to +inf
  324. assert_equal 3 [remrangebyscore 3 +inf]
  325. assert_equal {a b} [r zrange zset 0 -1]
  326. # -inf to +inf
  327. assert_equal 5 [remrangebyscore -inf +inf]
  328. assert_equal {} [r zrange zset 0 -1]
  329. # exclusive min
  330. assert_equal 4 [remrangebyscore (1 5]
  331. assert_equal {a} [r zrange zset 0 -1]
  332. assert_equal 3 [remrangebyscore (2 5]
  333. assert_equal {a b} [r zrange zset 0 -1]
  334. # exclusive max
  335. assert_equal 4 [remrangebyscore 1 (5]
  336. assert_equal {e} [r zrange zset 0 -1]
  337. assert_equal 3 [remrangebyscore 1 (4]
  338. assert_equal {d e} [r zrange zset 0 -1]
  339. # exclusive min and max
  340. assert_equal 3 [remrangebyscore (1 (5]
  341. assert_equal {a e} [r zrange zset 0 -1]
  342. # destroy when empty
  343. assert_equal 5 [remrangebyscore 1 5]
  344. assert_equal 0 [r exists zset]
  345. }
  346. test "ZREMRANGEBYSCORE with non-value min or max" {
  347. assert_error "*not*float*" {r zremrangebyscore fooz str 1}
  348. assert_error "*not*float*" {r zremrangebyscore fooz 1 str}
  349. assert_error "*not*float*" {r zremrangebyscore fooz 1 NaN}
  350. }
  351. test "ZREMRANGEBYRANK basics" {
  352. proc remrangebyrank {min max} {
  353. create_zset zset {1 a 2 b 3 c 4 d 5 e}
  354. assert_equal 1 [r exists zset]
  355. r zremrangebyrank zset $min $max
  356. }
  357. # inner range
  358. assert_equal 3 [remrangebyrank 1 3]
  359. assert_equal {a e} [r zrange zset 0 -1]
  360. # start underflow
  361. assert_equal 1 [remrangebyrank -10 0]
  362. assert_equal {b c d e} [r zrange zset 0 -1]
  363. # start overflow
  364. assert_equal 0 [remrangebyrank 10 -1]
  365. assert_equal {a b c d e} [r zrange zset 0 -1]
  366. # end underflow
  367. assert_equal 0 [remrangebyrank 0 -10]
  368. assert_equal {a b c d e} [r zrange zset 0 -1]
  369. # end overflow
  370. assert_equal 5 [remrangebyrank 0 10]
  371. assert_equal {} [r zrange zset 0 -1]
  372. # destroy when empty
  373. assert_equal 5 [remrangebyrank 0 4]
  374. assert_equal 0 [r exists zset]
  375. }
  376. test "ZUNIONSTORE against non-existing key doesn't set destination - $encoding" {
  377. r del zseta
  378. assert_equal 0 [r zunionstore dst_key 1 zseta]
  379. assert_equal 0 [r exists dst_key]
  380. }
  381. test "ZUNIONSTORE with empty set - $encoding" {
  382. r del zseta zsetb
  383. r zadd zseta 1 a
  384. r zadd zseta 2 b
  385. r zunionstore zsetc 2 zseta zsetb
  386. r zrange zsetc 0 -1 withscores
  387. } {a 1 b 2}
  388. test "ZUNIONSTORE basics - $encoding" {
  389. r del zseta zsetb zsetc
  390. r zadd zseta 1 a
  391. r zadd zseta 2 b
  392. r zadd zseta 3 c
  393. r zadd zsetb 1 b
  394. r zadd zsetb 2 c
  395. r zadd zsetb 3 d
  396. assert_equal 4 [r zunionstore zsetc 2 zseta zsetb]
  397. assert_equal {a 1 b 3 d 3 c 5} [r zrange zsetc 0 -1 withscores]
  398. }
  399. test "ZUNIONSTORE with weights - $encoding" {
  400. assert_equal 4 [r zunionstore zsetc 2 zseta zsetb weights 2 3]
  401. assert_equal {a 2 b 7 d 9 c 12} [r zrange zsetc 0 -1 withscores]
  402. }
  403. test "ZUNIONSTORE with a regular set and weights - $encoding" {
  404. r del seta
  405. r sadd seta a
  406. r sadd seta b
  407. r sadd seta c
  408. assert_equal 4 [r zunionstore zsetc 2 seta zsetb weights 2 3]
  409. assert_equal {a 2 b 5 c 8 d 9} [r zrange zsetc 0 -1 withscores]
  410. }
  411. test "ZUNIONSTORE with AGGREGATE MIN - $encoding" {
  412. assert_equal 4 [r zunionstore zsetc 2 zseta zsetb aggregate min]
  413. assert_equal {a 1 b 1 c 2 d 3} [r zrange zsetc 0 -1 withscores]
  414. }
  415. test "ZUNIONSTORE with AGGREGATE MAX - $encoding" {
  416. assert_equal 4 [r zunionstore zsetc 2 zseta zsetb aggregate max]
  417. assert_equal {a 1 b 2 c 3 d 3} [r zrange zsetc 0 -1 withscores]
  418. }
  419. test "ZINTERSTORE basics - $encoding" {
  420. assert_equal 2 [r zinterstore zsetc 2 zseta zsetb]
  421. assert_equal {b 3 c 5} [r zrange zsetc 0 -1 withscores]
  422. }
  423. test "ZINTERSTORE with weights - $encoding" {
  424. assert_equal 2 [r zinterstore zsetc 2 zseta zsetb weights 2 3]
  425. assert_equal {b 7 c 12} [r zrange zsetc 0 -1 withscores]
  426. }
  427. test "ZINTERSTORE with a regular set and weights - $encoding" {
  428. r del seta
  429. r sadd seta a
  430. r sadd seta b
  431. r sadd seta c
  432. assert_equal 2 [r zinterstore zsetc 2 seta zsetb weights 2 3]
  433. assert_equal {b 5 c 8} [r zrange zsetc 0 -1 withscores]
  434. }
  435. test "ZINTERSTORE with AGGREGATE MIN - $encoding" {
  436. assert_equal 2 [r zinterstore zsetc 2 zseta zsetb aggregate min]
  437. assert_equal {b 1 c 2} [r zrange zsetc 0 -1 withscores]
  438. }
  439. test "ZINTERSTORE with AGGREGATE MAX - $encoding" {
  440. assert_equal 2 [r zinterstore zsetc 2 zseta zsetb aggregate max]
  441. assert_equal {b 2 c 3} [r zrange zsetc 0 -1 withscores]
  442. }
  443. foreach cmd {ZUNIONSTORE ZINTERSTORE} {
  444. test "$cmd with +inf/-inf scores - $encoding" {
  445. r del zsetinf1 zsetinf2
  446. r zadd zsetinf1 +inf key
  447. r zadd zsetinf2 +inf key
  448. r $cmd zsetinf3 2 zsetinf1 zsetinf2
  449. assert_equal inf [r zscore zsetinf3 key]
  450. r zadd zsetinf1 -inf key
  451. r zadd zsetinf2 +inf key
  452. r $cmd zsetinf3 2 zsetinf1 zsetinf2
  453. assert_equal 0 [r zscore zsetinf3 key]
  454. r zadd zsetinf1 +inf key
  455. r zadd zsetinf2 -inf key
  456. r $cmd zsetinf3 2 zsetinf1 zsetinf2
  457. assert_equal 0 [r zscore zsetinf3 key]
  458. r zadd zsetinf1 -inf key
  459. r zadd zsetinf2 -inf key
  460. r $cmd zsetinf3 2 zsetinf1 zsetinf2
  461. assert_equal -inf [r zscore zsetinf3 key]
  462. }
  463. test "$cmd with NaN weights $encoding" {
  464. r del zsetinf1 zsetinf2
  465. r zadd zsetinf1 1.0 key
  466. r zadd zsetinf2 1.0 key
  467. assert_error "*weight*not*float*" {
  468. r $cmd zsetinf3 2 zsetinf1 zsetinf2 weights nan nan
  469. }
  470. }
  471. }
  472. }
  473. basics ziplist
  474. basics skiplist
  475. test {ZINTERSTORE regression with two sets, intset+hashtable} {
  476. r del seta setb setc
  477. r sadd set1 a
  478. r sadd set2 10
  479. r zinterstore set3 2 set1 set2
  480. } {0}
  481. test {ZUNIONSTORE regression, should not create NaN in scores} {
  482. r zadd z -inf neginf
  483. r zunionstore out 1 z weights 0
  484. r zrange out 0 -1 withscores
  485. } {neginf 0}
  486. test {ZINTERSTORE #516 regression, mixed sets and ziplist zsets} {
  487. r sadd one 100 101 102 103
  488. r sadd two 100 200 201 202
  489. r zadd three 1 500 1 501 1 502 1 503 1 100
  490. r zinterstore to_here 3 one two three WEIGHTS 0 0 1
  491. r zrange to_here 0 -1
  492. } {100}
  493. test {ZUNIONSTORE result is sorted} {
  494. # Create two sets with common and not common elements, perform
  495. # the UNION, check that elements are still sorted.
  496. r del one two dest
  497. set cmd1 [list r zadd one]
  498. set cmd2 [list r zadd two]
  499. for {set j 0} {$j < 1000} {incr j} {
  500. lappend cmd1 [expr rand()] [randomInt 1000]
  501. lappend cmd2 [expr rand()] [randomInt 1000]
  502. }
  503. {*}$cmd1
  504. {*}$cmd2
  505. assert {[r zcard one] > 100}
  506. assert {[r zcard two] > 100}
  507. r zunionstore dest 2 one two
  508. set oldscore 0
  509. foreach {ele score} [r zrange dest 0 -1 withscores] {
  510. assert {$score >= $oldscore}
  511. set oldscore $score
  512. }
  513. }
  514. proc stressers {encoding} {
  515. if {$encoding == "ziplist"} {
  516. # Little extra to allow proper fuzzing in the sorting stresser
  517. r config set zset-max-ziplist-entries 256
  518. r config set zset-max-ziplist-value 64
  519. set elements 128
  520. } elseif {$encoding == "skiplist"} {
  521. r config set zset-max-ziplist-entries 0
  522. r config set zset-max-ziplist-value 0
  523. if {$::accurate} {set elements 1000} else {set elements 100}
  524. } else {
  525. puts "Unknown sorted set encoding"
  526. exit
  527. }
  528. test "ZSCORE - $encoding" {
  529. r del zscoretest
  530. set aux {}
  531. for {set i 0} {$i < $elements} {incr i} {
  532. set score [expr rand()]
  533. lappend aux $score
  534. r zadd zscoretest $score $i
  535. }
  536. assert_encoding $encoding zscoretest
  537. for {set i 0} {$i < $elements} {incr i} {
  538. assert_equal [lindex $aux $i] [r zscore zscoretest $i]
  539. }
  540. }
  541. test "ZSCORE after a DEBUG RELOAD - $encoding" {
  542. r del zscoretest
  543. set aux {}
  544. for {set i 0} {$i < $elements} {incr i} {
  545. set score [expr rand()]
  546. lappend aux $score
  547. r zadd zscoretest $score $i
  548. }
  549. r debug reload
  550. assert_encoding $encoding zscoretest
  551. for {set i 0} {$i < $elements} {incr i} {
  552. assert_equal [lindex $aux $i] [r zscore zscoretest $i]
  553. }
  554. }
  555. test "ZSET sorting stresser - $encoding" {
  556. set delta 0
  557. for {set test 0} {$test < 2} {incr test} {
  558. unset -nocomplain auxarray
  559. array set auxarray {}
  560. set auxlist {}
  561. r del myzset
  562. for {set i 0} {$i < $elements} {incr i} {
  563. if {$test == 0} {
  564. set score [expr rand()]
  565. } else {
  566. set score [expr int(rand()*10)]
  567. }
  568. set auxarray($i) $score
  569. r zadd myzset $score $i
  570. # Random update
  571. if {[expr rand()] < .2} {
  572. set j [expr int(rand()*1000)]
  573. if {$test == 0} {
  574. set score [expr rand()]
  575. } else {
  576. set score [expr int(rand()*10)]
  577. }
  578. set auxarray($j) $score
  579. r zadd myzset $score $j
  580. }
  581. }
  582. foreach {item score} [array get auxarray] {
  583. lappend auxlist [list $score $item]
  584. }
  585. set sorted [lsort -command zlistAlikeSort $auxlist]
  586. set auxlist {}
  587. foreach x $sorted {
  588. lappend auxlist [lindex $x 1]
  589. }
  590. assert_encoding $encoding myzset
  591. set fromredis [r zrange myzset 0 -1]
  592. set delta 0
  593. for {set i 0} {$i < [llength $fromredis]} {incr i} {
  594. if {[lindex $fromredis $i] != [lindex $auxlist $i]} {
  595. incr delta
  596. }
  597. }
  598. }
  599. assert_equal 0 $delta
  600. }
  601. test "ZRANGEBYSCORE fuzzy test, 100 ranges in $elements element sorted set - $encoding" {
  602. set err {}
  603. r del zset
  604. for {set i 0} {$i < $elements} {incr i} {
  605. r zadd zset [expr rand()] $i
  606. }
  607. assert_encoding $encoding zset
  608. for {set i 0} {$i < 100} {incr i} {
  609. set min [expr rand()]
  610. set max [expr rand()]
  611. if {$min > $max} {
  612. set aux $min
  613. set min $max
  614. set max $aux
  615. }
  616. set low [r zrangebyscore zset -inf $min]
  617. set ok [r zrangebyscore zset $min $max]
  618. set high [r zrangebyscore zset $max +inf]
  619. set lowx [r zrangebyscore zset -inf ($min]
  620. set okx [r zrangebyscore zset ($min ($max]
  621. set highx [r zrangebyscore zset ($max +inf]
  622. if {[r zcount zset -inf $min] != [llength $low]} {
  623. append err "Error, len does not match zcount\n"
  624. }
  625. if {[r zcount zset $min $max] != [llength $ok]} {
  626. append err "Error, len does not match zcount\n"
  627. }
  628. if {[r zcount zset $max +inf] != [llength $high]} {
  629. append err "Error, len does not match zcount\n"
  630. }
  631. if {[r zcount zset -inf ($min] != [llength $lowx]} {
  632. append err "Error, len does not match zcount\n"
  633. }
  634. if {[r zcount zset ($min ($max] != [llength $okx]} {
  635. append err "Error, len does not match zcount\n"
  636. }
  637. if {[r zcount zset ($max +inf] != [llength $highx]} {
  638. append err "Error, len does not match zcount\n"
  639. }
  640. foreach x $low {
  641. set score [r zscore zset $x]
  642. if {$score > $min} {
  643. append err "Error, score for $x is $score > $min\n"
  644. }
  645. }
  646. foreach x $lowx {
  647. set score [r zscore zset $x]
  648. if {$score >= $min} {
  649. append err "Error, score for $x is $score >= $min\n"
  650. }
  651. }
  652. foreach x $ok {
  653. set score [r zscore zset $x]
  654. if {$score < $min || $score > $max} {
  655. append err "Error, score for $x is $score outside $min-$max range\n"
  656. }
  657. }
  658. foreach x $okx {
  659. set score [r zscore zset $x]
  660. if {$score <= $min || $score >= $max} {
  661. append err "Error, score for $x is $score outside $min-$max open range\n"
  662. }
  663. }
  664. foreach x $high {
  665. set score [r zscore zset $x]
  666. if {$score < $max} {
  667. append err "Error, score for $x is $score < $max\n"
  668. }
  669. }
  670. foreach x $highx {
  671. set score [r zscore zset $x]
  672. if {$score <= $max} {
  673. append err "Error, score for $x is $score <= $max\n"
  674. }
  675. }
  676. }
  677. assert_equal {} $err
  678. }
  679. test "ZRANGEBYLEX fuzzy test, 100 ranges in $elements element sorted set - $encoding" {
  680. set lexset {}
  681. r del zset
  682. for {set j 0} {$j < $elements} {incr j} {
  683. set e [randstring 0 30 alpha]
  684. lappend lexset $e
  685. r zadd zset 0 $e
  686. }
  687. set lexset [lsort -unique $lexset]
  688. for {set j 0} {$j < 100} {incr j} {
  689. set min [randstring 0 30 alpha]
  690. set max [randstring 0 30 alpha]
  691. set mininc [randomInt 2]
  692. set maxinc [randomInt 2]
  693. if {$mininc} {set cmin "\[$min"} else {set cmin "($min"}
  694. if {$maxinc} {set cmax "\[$max"} else {set cmax "($max"}
  695. set rev [randomInt 2]
  696. if {$rev} {
  697. set cmd zrevrangebylex
  698. } else {
  699. set cmd zrangebylex
  700. }
  701. # Make sure data is the same in both sides
  702. assert {[r zrange zset 0 -1] eq $lexset}
  703. # Get the Redis output
  704. set output [r $cmd zset $cmin $cmax]
  705. if {$rev} {
  706. set outlen [r zlexcount zset $cmax $cmin]
  707. } else {
  708. set outlen [r zlexcount zset $cmin $cmax]
  709. }
  710. # Compute the same output via Tcl
  711. set o {}
  712. set copy $lexset
  713. if {(!$rev && [string compare $min $max] > 0) ||
  714. ($rev && [string compare $max $min] > 0)} {
  715. # Empty output when ranges are inverted.
  716. } else {
  717. if {$rev} {
  718. # Invert the Tcl array using Redis itself.
  719. set copy [r zrevrange zset 0 -1]
  720. # Invert min / max as well
  721. lassign [list $min $max $mininc $maxinc] \
  722. max min maxinc mininc
  723. }
  724. foreach e $copy {
  725. set mincmp [string compare $e $min]
  726. set maxcmp [string compare $e $max]
  727. if {
  728. ($mininc && $mincmp >= 0 || !$mininc && $mincmp > 0)
  729. &&
  730. ($maxinc && $maxcmp <= 0 || !$maxinc && $maxcmp < 0)
  731. } {
  732. lappend o $e
  733. }
  734. }
  735. }
  736. assert {$o eq $output}
  737. assert {$outlen eq [llength $output]}
  738. }
  739. }
  740. test "ZREMRANGEBYLEX fuzzy test, 100 ranges in $elements element sorted set - $encoding" {
  741. set lexset {}
  742. r del zset zsetcopy
  743. for {set j 0} {$j < $elements} {incr j} {
  744. set e [randstring 0 30 alpha]
  745. lappend lexset $e
  746. r zadd zset 0 $e
  747. }
  748. set lexset [lsort -unique $lexset]
  749. for {set j 0} {$j < 100} {incr j} {
  750. # Copy...
  751. r zunionstore zsetcopy 1 zset
  752. set lexsetcopy $lexset
  753. set min [randstring 0 30 alpha]
  754. set max [randstring 0 30 alpha]
  755. set mininc [randomInt 2]
  756. set maxinc [randomInt 2]
  757. if {$mininc} {set cmin "\[$min"} else {set cmin "($min"}
  758. if {$maxinc} {set cmax "\[$max"} else {set cmax "($max"}
  759. # Make sure data is the same in both sides
  760. assert {[r zrange zset 0 -1] eq $lexset}
  761. # Get the range we are going to remove
  762. set torem [r zrangebylex zset $cmin $cmax]
  763. set toremlen [r zlexcount zset $cmin $cmax]
  764. r zremrangebylex zsetcopy $cmin $cmax
  765. set output [r zrange zsetcopy 0 -1]
  766. # Remove the range with Tcl from the original list
  767. if {$toremlen} {
  768. set first [lsearch -exact $lexsetcopy [lindex $torem 0]]
  769. set last [expr {$first+$toremlen-1}]
  770. set lexsetcopy [lreplace $lexsetcopy $first $last]
  771. }
  772. assert {$lexsetcopy eq $output}
  773. }
  774. }
  775. test "ZSETs skiplist implementation backlink consistency test - $encoding" {
  776. set diff 0
  777. for {set j 0} {$j < $elements} {incr j} {
  778. r zadd myzset [expr rand()] "Element-$j"
  779. r zrem myzset "Element-[expr int(rand()*$elements)]"
  780. }
  781. assert_encoding $encoding myzset
  782. set l1 [r zrange myzset 0 -1]
  783. set l2 [r zrevrange myzset 0 -1]
  784. for {set j 0} {$j < [llength $l1]} {incr j} {
  785. if {[lindex $l1 $j] ne [lindex $l2 end-$j]} {
  786. incr diff
  787. }
  788. }
  789. assert_equal 0 $diff
  790. }
  791. test "ZSETs ZRANK augmented skip list stress testing - $encoding" {
  792. set err {}
  793. r del myzset
  794. for {set k 0} {$k < 2000} {incr k} {
  795. set i [expr {$k % $elements}]
  796. if {[expr rand()] < .2} {
  797. r zrem myzset $i
  798. } else {
  799. set score [expr rand()]
  800. r zadd myzset $score $i
  801. assert_encoding $encoding myzset
  802. }
  803. set card [r zcard myzset]
  804. if {$card > 0} {
  805. set index [randomInt $card]
  806. set ele [lindex [r zrange myzset $index $index] 0]
  807. set rank [r zrank myzset $ele]
  808. if {$rank != $index} {
  809. set err "$ele RANK is wrong! ($rank != $index)"
  810. break
  811. }
  812. }
  813. }
  814. assert_equal {} $err
  815. }
  816. }
  817. tags {"slow"} {
  818. stressers ziplist
  819. stressers skiplist
  820. }
  821. }