]>
Commit | Line | Data |
---|---|---|
5d4f3a8c PN |
1 | start_server { |
2 | tags {"sort"} | |
3 | overrides { | |
4 | "list-max-ziplist-value" 16 | |
5 | "list-max-ziplist-entries" 32 | |
2b9a5947 | 6 | "set-max-intset-entries" 32 |
5d4f3a8c PN |
7 | } |
8 | } { | |
9 | proc create_random_dataset {num cmd} { | |
10 | set tosort {} | |
11 | set result {} | |
12 | array set seenrand {} | |
13 | r del tosort | |
14 | for {set i 0} {$i < $num} {incr i} { | |
15 | # Make sure all the weights are different because | |
16 | # Redis does not use a stable sort but Tcl does. | |
17 | while 1 { | |
18 | randpath { | |
19 | set rint [expr int(rand()*1000000)] | |
20 | } { | |
21 | set rint [expr rand()] | |
22 | } | |
23 | if {![info exists seenrand($rint)]} break | |
24 | } | |
25 | set seenrand($rint) x | |
26 | r $cmd tosort $i | |
27 | r set weight_$i $rint | |
28 | r hset wobj_$i weight $rint | |
29 | lappend tosort [list $i $rint] | |
30 | } | |
31 | set sorted [lsort -index 1 -real $tosort] | |
32 | for {set i 0} {$i < $num} {incr i} { | |
33 | lappend result [lindex $sorted $i 0] | |
34 | } | |
35 | set _ $result | |
36 | } | |
37 | ||
ced6709c PN |
38 | foreach {num cmd enc title} { |
39 | 16 lpush ziplist "Ziplist" | |
452ccf7a | 40 | 1000 lpush linkedlist "Linked list" |
41 | 10000 lpush linkedlist "Big Linked list" | |
029e5577 | 42 | 16 sadd intset "Intset" |
452ccf7a | 43 | 1000 sadd hashtable "Hash table" |
44 | 10000 sadd hashtable "Big Hash table" | |
ced6709c PN |
45 | } { |
46 | set result [create_random_dataset $num $cmd] | |
47 | assert_encoding $enc tosort | |
48 | ||
49 | test "$title: SORT BY key" { | |
dc11daf3 | 50 | assert_equal $result [r sort tosort BY weight_*] |
ced6709c | 51 | } |
5d4f3a8c | 52 | |
f54c2990 B |
53 | test "$title: SORT BY key with limit" { |
54 | assert_equal [lrange $result 5 9] [r sort tosort BY weight_* LIMIT 5 5] | |
55 | } | |
56 | ||
ced6709c | 57 | test "$title: SORT BY hash field" { |
dc11daf3 | 58 | assert_equal $result [r sort tosort BY wobj_*->weight] |
ced6709c | 59 | } |
5d4f3a8c PN |
60 | } |
61 | ||
ced6709c | 62 | set result [create_random_dataset 16 lpush] |
5d4f3a8c PN |
63 | test "SORT GET #" { |
64 | assert_equal [lsort -integer $result] [r sort tosort GET #] | |
65 | } | |
66 | ||
67 | test "SORT GET <const>" { | |
68 | r del foo | |
69 | set res [r sort tosort GET foo] | |
70 | assert_equal 16 [llength $res] | |
71 | foreach item $res { assert_equal {} $item } | |
72 | } | |
73 | ||
74 | test "SORT GET (key and hash) with sanity check" { | |
75 | set l1 [r sort tosort GET # GET weight_*] | |
76 | set l2 [r sort tosort GET # GET wobj_*->weight] | |
77 | foreach {id1 w1} $l1 {id2 w2} $l2 { | |
78 | assert_equal $id1 $id2 | |
79 | assert_equal $w1 [r get weight_$id1] | |
80 | assert_equal $w2 [r get weight_$id1] | |
81 | } | |
82 | } | |
83 | ||
84 | test "SORT BY key STORE" { | |
dc11daf3 | 85 | r sort tosort BY weight_* store sort-res |
5d4f3a8c PN |
86 | assert_equal $result [r lrange sort-res 0 -1] |
87 | assert_equal 16 [r llen sort-res] | |
88 | assert_encoding ziplist sort-res | |
89 | } | |
90 | ||
91 | test "SORT BY hash field STORE" { | |
dc11daf3 | 92 | r sort tosort BY wobj_*->weight store sort-res |
5d4f3a8c PN |
93 | assert_equal $result [r lrange sort-res 0 -1] |
94 | assert_equal 16 [r llen sort-res] | |
95 | assert_encoding ziplist sort-res | |
96 | } | |
97 | ||
98 | test "SORT DESC" { | |
dc11daf3 | 99 | assert_equal [lsort -decreasing -integer $result] [r sort tosort DESC] |
5d4f3a8c PN |
100 | } |
101 | ||
102 | test "SORT ALPHA against integer encoded strings" { | |
98578b57 PN |
103 | r del mylist |
104 | r lpush mylist 2 | |
105 | r lpush mylist 1 | |
106 | r lpush mylist 3 | |
107 | r lpush mylist 10 | |
108 | r sort mylist alpha | |
109 | } {1 10 2 3} | |
110 | ||
5d4f3a8c PN |
111 | test "SORT sorted set" { |
112 | r del zset | |
113 | r zadd zset 1 a | |
114 | r zadd zset 5 b | |
115 | r zadd zset 2 c | |
116 | r zadd zset 10 d | |
117 | r zadd zset 3 e | |
118 | r sort zset alpha desc | |
119 | } {e d c b a} | |
98578b57 | 120 | |
2ba96271 | 121 | test "SORT sorted set BY nosort should retain ordering" { |
122 | r del zset | |
123 | r zadd zset 1 a | |
124 | r zadd zset 5 b | |
125 | r zadd zset 2 c | |
126 | r zadd zset 10 d | |
127 | r zadd zset 3 e | |
128 | r multi | |
129 | r sort zset by nosort asc | |
130 | r sort zset by nosort desc | |
131 | r exec | |
132 | } {{a c e b d} {d b e c a}} | |
133 | ||
134 | test "SORT sorted set BY nosort + LIMIT" { | |
135 | r del zset | |
136 | r zadd zset 1 a | |
137 | r zadd zset 5 b | |
138 | r zadd zset 2 c | |
139 | r zadd zset 10 d | |
140 | r zadd zset 3 e | |
141 | assert_equal [r sort zset by nosort asc limit 0 1] {a} | |
142 | assert_equal [r sort zset by nosort desc limit 0 1] {d} | |
143 | assert_equal [r sort zset by nosort asc limit 0 2] {a c} | |
144 | assert_equal [r sort zset by nosort desc limit 0 2] {d b} | |
145 | assert_equal [r sort zset by nosort limit 5 10] {} | |
146 | assert_equal [r sort zset by nosort limit -10 100] {a c e b d} | |
147 | } | |
148 | ||
149 | test "SORT sorted set BY nosort works as expected from scripts" { | |
150 | r del zset | |
151 | r zadd zset 1 a | |
152 | r zadd zset 5 b | |
153 | r zadd zset 2 c | |
154 | r zadd zset 10 d | |
155 | r zadd zset 3 e | |
156 | r eval { | |
157 | return {redis.call('sort','zset','by','nosort','asc'), | |
158 | redis.call('sort','zset','by','nosort','desc')} | |
159 | } 0 | |
160 | } {{a c e b d} {d b e c a}} | |
161 | ||
5d4f3a8c PN |
162 | test "SORT sorted set: +inf and -inf handling" { |
163 | r del zset | |
164 | r zadd zset -100 a | |
165 | r zadd zset 200 b | |
166 | r zadd zset -300 c | |
167 | r zadd zset 1000000 d | |
168 | r zadd zset +inf max | |
169 | r zadd zset -inf min | |
170 | r zrange zset 0 -1 | |
171 | } {min c a b d max} | |
98578b57 | 172 | |
5d4f3a8c PN |
173 | test "SORT regression for issue #19, sorting floats" { |
174 | r flushdb | |
175 | set floats {1.1 5.10 3.10 7.44 2.1 5.75 6.12 0.25 1.15} | |
176 | foreach x $floats { | |
177 | r lpush mylist $x | |
178 | } | |
179 | assert_equal [lsort -real $floats] [r sort mylist] | |
180 | } | |
98578b57 | 181 | |
237194b7 | 182 | test "SORT with STORE returns zero if result is empty (github isse 224)" { |
183 | r flushdb | |
184 | r sort foo store bar | |
185 | } {0} | |
186 | ||
187 | test "SORT with STORE does not create empty lists (github issue 224)" { | |
188 | r flushdb | |
189 | r lpush foo bar | |
2c861050 | 190 | r sort foo alpha limit 10 10 store zap |
237194b7 | 191 | r exists zap |
192 | } {0} | |
193 | ||
a0bf8d0a MK |
194 | test "SORT with STORE removes key if result is empty (github issue 227)" { |
195 | r flushdb | |
196 | r lpush foo bar | |
197 | r sort emptylist store foo | |
198 | r exists foo | |
199 | } {0} | |
200 | ||
de79a2ee | 201 | test "SORT with BY <constant> and STORE should still order output" { |
202 | r del myset mylist | |
44d77bb2 | 203 | r sadd myset a b c d e f g h i l m n o p q r s t u v z aa aaa azz |
de79a2ee | 204 | r sort myset alpha by _ store mylist |
205 | r lrange mylist 0 -1 | |
44d77bb2 | 206 | } {a aa aaa azz b c d e f g h i l m n o p q r s t u v z} |
de79a2ee | 207 | |
01f75bf3 | 208 | test "SORT will complain with numerical sorting and bad doubles (1)" { |
209 | r del myset | |
210 | r sadd myset 1 2 3 4 not-a-double | |
211 | set e {} | |
212 | catch {r sort myset} e | |
213 | set e | |
214 | } {*ERR*double*} | |
215 | ||
216 | test "SORT will complain with numerical sorting and bad doubles (2)" { | |
217 | r del myset | |
218 | r sadd myset 1 2 3 4 | |
219 | r mset score:1 10 score:2 20 score:3 30 score:4 not-a-double | |
220 | set e {} | |
221 | catch {r sort myset by score:*} e | |
222 | set e | |
223 | } {*ERR*double*} | |
224 | ||
225 | test "SORT BY sub-sorts lexicographically if score is the same" { | |
226 | r del myset | |
44d77bb2 | 227 | r sadd myset a b c d e f g h i l m n o p q r s t u v z aa aaa azz |
228 | foreach ele {a aa aaa azz b c d e f g h i l m n o p q r s t u v z} { | |
01f75bf3 | 229 | set score:$ele 100 |
230 | } | |
231 | r sort myset by score:* | |
44d77bb2 | 232 | } {a aa aaa azz b c d e f g h i l m n o p q r s t u v z} |
01f75bf3 | 233 | |
a1090c11 | 234 | test "SORT GET with pattern ending with just -> does not get hash field" { |
235 | r del mylist | |
236 | r lpush mylist a | |
237 | r set x:a-> 100 | |
238 | r sort mylist by num get x:*-> | |
239 | } {100} | |
240 | ||
5d4f3a8c PN |
241 | tags {"slow"} { |
242 | set num 100 | |
243 | set res [create_random_dataset $num lpush] | |
98578b57 | 244 | |
5d4f3a8c | 245 | test "SORT speed, $num element list BY key, 100 times" { |
7f7499ee PN |
246 | set start [clock clicks -milliseconds] |
247 | for {set i 0} {$i < 100} {incr i} { | |
dc11daf3 | 248 | set sorted [r sort tosort BY weight_* LIMIT 0 10] |
7f7499ee PN |
249 | } |
250 | set elapsed [expr [clock clicks -milliseconds]-$start] | |
6f8a32d5 PN |
251 | if {$::verbose} { |
252 | puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds " | |
253 | flush stdout | |
254 | } | |
5d4f3a8c | 255 | } |
98578b57 | 256 | |
5d4f3a8c | 257 | test "SORT speed, $num element list BY hash field, 100 times" { |
7f7499ee PN |
258 | set start [clock clicks -milliseconds] |
259 | for {set i 0} {$i < 100} {incr i} { | |
dc11daf3 | 260 | set sorted [r sort tosort BY wobj_*->weight LIMIT 0 10] |
7f7499ee PN |
261 | } |
262 | set elapsed [expr [clock clicks -milliseconds]-$start] | |
6f8a32d5 PN |
263 | if {$::verbose} { |
264 | puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds " | |
265 | flush stdout | |
266 | } | |
5d4f3a8c | 267 | } |
98578b57 | 268 | |
5d4f3a8c | 269 | test "SORT speed, $num element list directly, 100 times" { |
7f7499ee PN |
270 | set start [clock clicks -milliseconds] |
271 | for {set i 0} {$i < 100} {incr i} { | |
dc11daf3 | 272 | set sorted [r sort tosort LIMIT 0 10] |
7f7499ee PN |
273 | } |
274 | set elapsed [expr [clock clicks -milliseconds]-$start] | |
6f8a32d5 PN |
275 | if {$::verbose} { |
276 | puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds " | |
277 | flush stdout | |
278 | } | |
5d4f3a8c | 279 | } |
98578b57 | 280 | |
5d4f3a8c | 281 | test "SORT speed, $num element list BY <const>, 100 times" { |
7f7499ee PN |
282 | set start [clock clicks -milliseconds] |
283 | for {set i 0} {$i < 100} {incr i} { | |
dc11daf3 | 284 | set sorted [r sort tosort BY nokey LIMIT 0 10] |
7f7499ee PN |
285 | } |
286 | set elapsed [expr [clock clicks -milliseconds]-$start] | |
6f8a32d5 PN |
287 | if {$::verbose} { |
288 | puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds " | |
289 | flush stdout | |
290 | } | |
98578b57 | 291 | } |
5d4f3a8c | 292 | } |
98578b57 | 293 | } |