@@ -3,6 +3,9 @@ package geche
3
3
import (
4
4
"errors"
5
5
"fmt"
6
+ "math/rand"
7
+ "sort"
8
+ "strings"
6
9
"testing"
7
10
)
8
11
@@ -23,7 +26,7 @@ func ExampleNewKV() {
23
26
func compareSlice (t * testing.T , exp , got []string ) {
24
27
t .Helper ()
25
28
26
- t .Log (got )
29
+ // t.Log(got)
27
30
if len (exp ) != len (got ) {
28
31
t .Fatalf ("expected length %d, got %d" , len (exp ), len (got ))
29
32
}
@@ -137,6 +140,122 @@ func TestKVEmptyPrefix(t *testing.T) {
137
140
compareSlice (t , expected , got )
138
141
}
139
142
143
+ func TestKVEmptyPrefixDiffLen (t * testing.T ) {
144
+ cache := NewMapCache [string , string ]()
145
+ kv := NewKV [string ](cache )
146
+
147
+ kv .Set ("12345" , "12345" )
148
+ kv .Set ("123" , "123" )
149
+ kv .Set ("3" , "3" )
150
+ kv .Set ("2" , "2" )
151
+ kv .Set ("33333" , "33333" )
152
+ kv .Set ("1" , "1" )
153
+
154
+ expected := []string {"1" , "123" , "12345" , "2" , "3" , "33333" }
155
+
156
+ got , err := kv .ListByPrefix ("" )
157
+ if err != nil {
158
+ t .Fatalf ("unexpected error in ListByPrefix: %v" , err )
159
+ }
160
+
161
+ compareSlice (t , expected , got )
162
+ }
163
+
164
+ func genRandomString (n int ) string {
165
+ b := make ([]byte , n )
166
+ for i := range b {
167
+ b [i ] = byte (rand .Intn (256 ))
168
+ }
169
+ return string (b )
170
+ }
171
+
172
+ func TestKVEmptyPrefixFuzz (t * testing.T ) {
173
+ cache := NewMapCache [string , string ]()
174
+ kv := NewKV [string ](cache )
175
+
176
+ set := map [string ]struct {}{}
177
+ for i := 0 ; i < 10000 ; i ++ {
178
+ key := genRandomString (rand .Intn (300 ) + 1 )
179
+ set [key ] = struct {}{}
180
+ kv .Set (key , key )
181
+ }
182
+
183
+ expected := []string {}
184
+ for key := range set {
185
+ expected = append (expected , key )
186
+ }
187
+ sort .Strings (expected )
188
+
189
+ got , err := kv .ListByPrefix ("" )
190
+ if err != nil {
191
+ t .Fatalf ("unexpected error in ListByPrefix: %v" , err )
192
+ }
193
+
194
+ compareSlice (t , expected , got )
195
+ }
196
+
197
+ // This test creates 10k random KV pairs. Each key is prefixed with one of 10
198
+ // random prefixes. Then it deletes 10% of keys and checks that ListByPrefix
199
+ // returns correct results.
200
+ func TestKVPrefixFuzz (t * testing.T ) {
201
+ prefixes := []string {}
202
+ for i := 0 ; i < 10 ; i ++ {
203
+ prefixes = append (prefixes , genRandomString (rand .Intn (20 )+ 1 ))
204
+ }
205
+ cache := NewMapCache [string , string ]()
206
+ kv := NewKV [string ](cache )
207
+
208
+ set := map [string ]struct {}{}
209
+ for i := 0 ; i < 10000 ; i ++ {
210
+ prefix := prefixes [rand .Intn (len (prefixes ))]
211
+ pl := rand .Intn (len (prefix ))
212
+ key := prefix [:pl ] + genRandomString (rand .Intn (300 )+ 1 )
213
+ set [key ] = struct {}{}
214
+ kv .Set (key , key )
215
+ }
216
+
217
+ // Delete 10% of keys.
218
+ for key := range set {
219
+ if rand .Float64 () < 0.1 {
220
+ delete (set , key )
221
+ _ = kv .Del (key )
222
+ }
223
+ }
224
+
225
+ expected := []string {}
226
+ for key := range set {
227
+ expected = append (expected , key )
228
+ }
229
+ sort .Strings (expected )
230
+
231
+ got , err := kv .ListByPrefix ("" )
232
+ if err != nil {
233
+ t .Fatalf ("unexpected error in ListByPrefix: %v" , err )
234
+ }
235
+
236
+ compareSlice (t , expected , got )
237
+
238
+ for i := 1 ; i < len (prefixes ); i ++ {
239
+ prefix := prefixes [i ]
240
+ for j := 1 ; j < len (prefix ); j ++ {
241
+ q := prefix [:j ]
242
+ expected2 := make ([]string , 0 , len (expected ))
243
+ for _ , key := range expected {
244
+ if strings .HasPrefix (key , q ) {
245
+ expected2 = append (expected2 , key )
246
+ }
247
+ }
248
+
249
+ got , err := kv .ListByPrefix (q )
250
+ if err != nil {
251
+ t .Fatalf ("unexpected error in ListByPrefix: %v" , err )
252
+ }
253
+
254
+ compareSlice (t , expected2 , got )
255
+ }
256
+ }
257
+ }
258
+
140
259
func TestKVNonexist (t * testing.T ) {
141
260
cache := NewMapCache [string , string ]()
142
261
kv := NewKV [string ](cache )
0 commit comments