]> git.saurik.com Git - redis.git/blob - tests/unit/sort.tcl
Fixed SORT bugs (issue #224) with regression tests.
[redis.git] / tests / unit / sort.tcl
1 start_server {
2 tags {"sort"}
3 overrides {
4 "list-max-ziplist-value" 16
5 "list-max-ziplist-entries" 32
6 "set-max-intset-entries" 32
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
38 foreach {num cmd enc title} {
39 16 lpush ziplist "Ziplist"
40 1000 lpush linkedlist "Linked list"
41 10000 lpush linkedlist "Big Linked list"
42 16 sadd intset "Intset"
43 1000 sadd hashtable "Hash table"
44 10000 sadd hashtable "Big Hash table"
45 } {
46 set result [create_random_dataset $num $cmd]
47 assert_encoding $enc tosort
48
49 test "$title: SORT BY key" {
50 assert_equal $result [r sort tosort BY weight_*]
51 }
52
53 test "$title: SORT BY hash field" {
54 assert_equal $result [r sort tosort BY wobj_*->weight]
55 }
56 }
57
58 set result [create_random_dataset 16 lpush]
59 test "SORT GET #" {
60 assert_equal [lsort -integer $result] [r sort tosort GET #]
61 }
62
63 test "SORT GET <const>" {
64 r del foo
65 set res [r sort tosort GET foo]
66 assert_equal 16 [llength $res]
67 foreach item $res { assert_equal {} $item }
68 }
69
70 test "SORT GET (key and hash) with sanity check" {
71 set l1 [r sort tosort GET # GET weight_*]
72 set l2 [r sort tosort GET # GET wobj_*->weight]
73 foreach {id1 w1} $l1 {id2 w2} $l2 {
74 assert_equal $id1 $id2
75 assert_equal $w1 [r get weight_$id1]
76 assert_equal $w2 [r get weight_$id1]
77 }
78 }
79
80 test "SORT BY key STORE" {
81 r sort tosort BY weight_* store sort-res
82 assert_equal $result [r lrange sort-res 0 -1]
83 assert_equal 16 [r llen sort-res]
84 assert_encoding ziplist sort-res
85 }
86
87 test "SORT BY hash field STORE" {
88 r sort tosort BY wobj_*->weight store sort-res
89 assert_equal $result [r lrange sort-res 0 -1]
90 assert_equal 16 [r llen sort-res]
91 assert_encoding ziplist sort-res
92 }
93
94 test "SORT DESC" {
95 assert_equal [lsort -decreasing -integer $result] [r sort tosort DESC]
96 }
97
98 test "SORT ALPHA against integer encoded strings" {
99 r del mylist
100 r lpush mylist 2
101 r lpush mylist 1
102 r lpush mylist 3
103 r lpush mylist 10
104 r sort mylist alpha
105 } {1 10 2 3}
106
107 test "SORT sorted set" {
108 r del zset
109 r zadd zset 1 a
110 r zadd zset 5 b
111 r zadd zset 2 c
112 r zadd zset 10 d
113 r zadd zset 3 e
114 r sort zset alpha desc
115 } {e d c b a}
116
117 test "SORT sorted set: +inf and -inf handling" {
118 r del zset
119 r zadd zset -100 a
120 r zadd zset 200 b
121 r zadd zset -300 c
122 r zadd zset 1000000 d
123 r zadd zset +inf max
124 r zadd zset -inf min
125 r zrange zset 0 -1
126 } {min c a b d max}
127
128 test "SORT regression for issue #19, sorting floats" {
129 r flushdb
130 set floats {1.1 5.10 3.10 7.44 2.1 5.75 6.12 0.25 1.15}
131 foreach x $floats {
132 r lpush mylist $x
133 }
134 assert_equal [lsort -real $floats] [r sort mylist]
135 }
136
137 test "SORT with STORE returns zero if result is empty (github isse 224)" {
138 r flushdb
139 r sort foo store bar
140 } {0}
141
142 test "SORT with STORE does not create empty lists (github issue 224)" {
143 r flushdb
144 r lpush foo bar
145 r sort foo limit 10 10 store zap
146 r exists zap
147 } {0}
148
149 tags {"slow"} {
150 set num 100
151 set res [create_random_dataset $num lpush]
152
153 test "SORT speed, $num element list BY key, 100 times" {
154 set start [clock clicks -milliseconds]
155 for {set i 0} {$i < 100} {incr i} {
156 set sorted [r sort tosort BY weight_* LIMIT 0 10]
157 }
158 set elapsed [expr [clock clicks -milliseconds]-$start]
159 if {$::verbose} {
160 puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds "
161 flush stdout
162 }
163 }
164
165 test "SORT speed, $num element list BY hash field, 100 times" {
166 set start [clock clicks -milliseconds]
167 for {set i 0} {$i < 100} {incr i} {
168 set sorted [r sort tosort BY wobj_*->weight LIMIT 0 10]
169 }
170 set elapsed [expr [clock clicks -milliseconds]-$start]
171 if {$::verbose} {
172 puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds "
173 flush stdout
174 }
175 }
176
177 test "SORT speed, $num element list directly, 100 times" {
178 set start [clock clicks -milliseconds]
179 for {set i 0} {$i < 100} {incr i} {
180 set sorted [r sort tosort LIMIT 0 10]
181 }
182 set elapsed [expr [clock clicks -milliseconds]-$start]
183 if {$::verbose} {
184 puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds "
185 flush stdout
186 }
187 }
188
189 test "SORT speed, $num element list BY <const>, 100 times" {
190 set start [clock clicks -milliseconds]
191 for {set i 0} {$i < 100} {incr i} {
192 set sorted [r sort tosort BY nokey LIMIT 0 10]
193 }
194 set elapsed [expr [clock clicks -milliseconds]-$start]
195 if {$::verbose} {
196 puts -nonewline "\n Average time to sort: [expr double($elapsed)/100] milliseconds "
197 flush stdout
198 }
199 }
200 }
201 }