xref: /redis-3.2.3/tests/unit/scan.tcl (revision b8a48ad5)
1start_server {tags {"scan"}} {
2    test "SCAN basic" {
3        r flushdb
4        r debug populate 1000
5
6        set cur 0
7        set keys {}
8        while 1 {
9            set res [r scan $cur]
10            set cur [lindex $res 0]
11            set k [lindex $res 1]
12            lappend keys {*}$k
13            if {$cur == 0} break
14        }
15
16        set keys [lsort -unique $keys]
17        assert_equal 1000 [llength $keys]
18    }
19
20    test "SCAN COUNT" {
21        r flushdb
22        r debug populate 1000
23
24        set cur 0
25        set keys {}
26        while 1 {
27            set res [r scan $cur count 5]
28            set cur [lindex $res 0]
29            set k [lindex $res 1]
30            lappend keys {*}$k
31            if {$cur == 0} break
32        }
33
34        set keys [lsort -unique $keys]
35        assert_equal 1000 [llength $keys]
36    }
37
38    test "SCAN MATCH" {
39        r flushdb
40        r debug populate 1000
41
42        set cur 0
43        set keys {}
44        while 1 {
45            set res [r scan $cur match "key:1??"]
46            set cur [lindex $res 0]
47            set k [lindex $res 1]
48            lappend keys {*}$k
49            if {$cur == 0} break
50        }
51
52        set keys [lsort -unique $keys]
53        assert_equal 100 [llength $keys]
54    }
55
56    foreach enc {intset hashtable} {
57        test "SSCAN with encoding $enc" {
58            # Create the Set
59            r del set
60            if {$enc eq {intset}} {
61                set prefix ""
62            } else {
63                set prefix "ele:"
64            }
65            set elements {}
66            for {set j 0} {$j < 100} {incr j} {
67                lappend elements ${prefix}${j}
68            }
69            r sadd set {*}$elements
70
71            # Verify that the encoding matches.
72            assert {[r object encoding set] eq $enc}
73
74            # Test SSCAN
75            set cur 0
76            set keys {}
77            while 1 {
78                set res [r sscan set $cur]
79                set cur [lindex $res 0]
80                set k [lindex $res 1]
81                lappend keys {*}$k
82                if {$cur == 0} break
83            }
84
85            set keys [lsort -unique $keys]
86            assert_equal 100 [llength $keys]
87        }
88    }
89
90    foreach enc {ziplist hashtable} {
91        test "HSCAN with encoding $enc" {
92            # Create the Hash
93            r del hash
94            if {$enc eq {ziplist}} {
95                set count 30
96            } else {
97                set count 1000
98            }
99            set elements {}
100            for {set j 0} {$j < $count} {incr j} {
101                lappend elements key:$j $j
102            }
103            r hmset hash {*}$elements
104
105            # Verify that the encoding matches.
106            assert {[r object encoding hash] eq $enc}
107
108            # Test HSCAN
109            set cur 0
110            set keys {}
111            while 1 {
112                set res [r hscan hash $cur]
113                set cur [lindex $res 0]
114                set k [lindex $res 1]
115                lappend keys {*}$k
116                if {$cur == 0} break
117            }
118
119            set keys2 {}
120            foreach {k v} $keys {
121                assert {$k eq "key:$v"}
122                lappend keys2 $k
123            }
124
125            set keys2 [lsort -unique $keys2]
126            assert_equal $count [llength $keys2]
127        }
128    }
129
130    foreach enc {ziplist skiplist} {
131        test "ZSCAN with encoding $enc" {
132            # Create the Sorted Set
133            r del zset
134            if {$enc eq {ziplist}} {
135                set count 30
136            } else {
137                set count 1000
138            }
139            set elements {}
140            for {set j 0} {$j < $count} {incr j} {
141                lappend elements $j key:$j
142            }
143            r zadd zset {*}$elements
144
145            # Verify that the encoding matches.
146            assert {[r object encoding zset] eq $enc}
147
148            # Test ZSCAN
149            set cur 0
150            set keys {}
151            while 1 {
152                set res [r zscan zset $cur]
153                set cur [lindex $res 0]
154                set k [lindex $res 1]
155                lappend keys {*}$k
156                if {$cur == 0} break
157            }
158
159            set keys2 {}
160            foreach {k v} $keys {
161                assert {$k eq "key:$v"}
162                lappend keys2 $k
163            }
164
165            set keys2 [lsort -unique $keys2]
166            assert_equal $count [llength $keys2]
167        }
168    }
169
170    test "SCAN guarantees check under write load" {
171        r flushdb
172        r debug populate 100
173
174        # We start scanning here, so keys from 0 to 99 should all be
175        # reported at the end of the iteration.
176        set keys {}
177        while 1 {
178            set res [r scan $cur]
179            set cur [lindex $res 0]
180            set k [lindex $res 1]
181            lappend keys {*}$k
182            if {$cur == 0} break
183            # Write 10 random keys at every SCAN iteration.
184            for {set j 0} {$j < 10} {incr j} {
185                r set addedkey:[randomInt 1000] foo
186            }
187        }
188
189        set keys2 {}
190        foreach k $keys {
191            if {[string length $k] > 6} continue
192            lappend keys2 $k
193        }
194
195        set keys2 [lsort -unique $keys2]
196        assert_equal 100 [llength $keys2]
197    }
198
199    test "SSCAN with integer encoded object (issue #1345)" {
200        set objects {1 a}
201        r del set
202        r sadd set {*}$objects
203        set res [r sscan set 0 MATCH *a* COUNT 100]
204        assert_equal [lsort -unique [lindex $res 1]] {a}
205        set res [r sscan set 0 MATCH *1* COUNT 100]
206        assert_equal [lsort -unique [lindex $res 1]] {1}
207    }
208
209    test "SSCAN with PATTERN" {
210        r del mykey
211        r sadd mykey foo fab fiz foobar 1 2 3 4
212        set res [r sscan mykey 0 MATCH foo* COUNT 10000]
213        lsort -unique [lindex $res 1]
214    } {foo foobar}
215
216    test "HSCAN with PATTERN" {
217        r del mykey
218        r hmset mykey foo 1 fab 2 fiz 3 foobar 10 1 a 2 b 3 c 4 d
219        set res [r hscan mykey 0 MATCH foo* COUNT 10000]
220        lsort -unique [lindex $res 1]
221    } {1 10 foo foobar}
222
223    test "ZSCAN with PATTERN" {
224        r del mykey
225        r zadd mykey 1 foo 2 fab 3 fiz 10 foobar
226        set res [r zscan mykey 0 MATCH foo* COUNT 10000]
227        lsort -unique [lindex $res 1]
228    }
229
230    test "ZSCAN scores: regression test for issue #2175" {
231        r del mykey
232        for {set j 0} {$j < 500} {incr j} {
233            r zadd mykey 9.8813129168249309e-323 $j
234        }
235        set res [lindex [r zscan mykey 0] 1]
236        set first_score [lindex $res 1]
237        assert {$first_score != 0}
238    }
239}
240