1 package redis_test
2
3 import (
4 "context"
5 "fmt"
6 "math"
7
8 . "github.com/bsm/ginkgo/v2"
9 . "github.com/bsm/gomega"
10
11 "github.com/redis/go-redis/v9"
12 )
13
14 var _ = Describe("Probabilistic commands", Label("probabilistic"), func() {
15 ctx := context.TODO()
16
17 setupRedisClient := func(protocolVersion int) *redis.Client {
18 return redis.NewClient(&redis.Options{
19 Addr: "localhost:6379",
20 DB: 0,
21 Protocol: protocolVersion,
22 })
23 }
24
25 protocols := []int{2, 3}
26 for _, protocol := range protocols {
27 protocol := protocol
28
29 Context(fmt.Sprintf("with protocol version %d", protocol), func() {
30 var client *redis.Client
31
32 BeforeEach(func() {
33 client = setupRedisClient(protocol)
34 Expect(client.FlushAll(ctx).Err()).NotTo(HaveOccurred())
35 })
36
37 AfterEach(func() {
38 if client != nil {
39 client.FlushDB(ctx)
40 client.Close()
41 }
42 })
43
44 Describe("bloom", Label("bloom"), func() {
45 It("should BFAdd", Label("bloom", "bfadd"), func() {
46 resultAdd, err := client.BFAdd(ctx, "testbf1", 1).Result()
47
48 Expect(err).NotTo(HaveOccurred())
49 Expect(resultAdd).To(BeTrue())
50
51 resultInfo, err := client.BFInfo(ctx, "testbf1").Result()
52
53 Expect(err).NotTo(HaveOccurred())
54 Expect(resultInfo).To(BeAssignableToTypeOf(redis.BFInfo{}))
55 Expect(resultInfo.ItemsInserted).To(BeEquivalentTo(int64(1)))
56 })
57
58 It("should BFCard", Label("bloom", "bfcard"), func() {
59
60
61
62
63 _, err := client.BFAdd(ctx, "testbf1", "item1").Result()
64 Expect(err).NotTo(HaveOccurred())
65 _, err = client.BFAdd(ctx, "testbf1", "item2").Result()
66 Expect(err).NotTo(HaveOccurred())
67 _, err = client.BFAdd(ctx, "testbf1", 3).Result()
68 Expect(err).NotTo(HaveOccurred())
69
70 result, err := client.BFCard(ctx, "testbf1").Result()
71
72 Expect(err).NotTo(HaveOccurred())
73 Expect(result).To(BeEquivalentTo(int64(3)))
74 })
75
76 It("should BFExists", Label("bloom", "bfexists"), func() {
77 exists, err := client.BFExists(ctx, "testbf1", "item1").Result()
78 Expect(err).NotTo(HaveOccurred())
79 Expect(exists).To(BeFalse())
80
81 _, err = client.BFAdd(ctx, "testbf1", "item1").Result()
82 Expect(err).NotTo(HaveOccurred())
83
84 exists, err = client.BFExists(ctx, "testbf1", "item1").Result()
85
86 Expect(err).NotTo(HaveOccurred())
87 Expect(exists).To(BeTrue())
88 })
89
90 It("should BFInfo and BFReserve", Label("bloom", "bfinfo", "bfreserve"), func() {
91 err := client.BFReserve(ctx, "testbf1", 0.001, 2000).Err()
92 Expect(err).NotTo(HaveOccurred())
93
94 result, err := client.BFInfo(ctx, "testbf1").Result()
95 Expect(err).NotTo(HaveOccurred())
96 Expect(result).To(BeAssignableToTypeOf(redis.BFInfo{}))
97 Expect(result.Capacity).To(BeEquivalentTo(int64(2000)))
98 })
99
100 It("should BFInfoCapacity, BFInfoSize, BFInfoFilters, BFInfoItems, BFInfoExpansion, ", Label("bloom", "bfinfocapacity", "bfinfosize", "bfinfofilters", "bfinfoitems", "bfinfoexpansion"), func() {
101 err := client.BFReserve(ctx, "testbf1", 0.001, 2000).Err()
102 Expect(err).NotTo(HaveOccurred())
103
104 result, err := client.BFInfoCapacity(ctx, "testbf1").Result()
105 Expect(err).NotTo(HaveOccurred())
106 Expect(result.Capacity).To(BeEquivalentTo(int64(2000)))
107
108 result, err = client.BFInfoItems(ctx, "testbf1").Result()
109 Expect(err).NotTo(HaveOccurred())
110 Expect(result.ItemsInserted).To(BeEquivalentTo(int64(0)))
111
112 result, err = client.BFInfoSize(ctx, "testbf1").Result()
113 Expect(err).NotTo(HaveOccurred())
114 Expect(result.Size).To(BeEquivalentTo(int64(4056)))
115
116 err = client.BFReserveExpansion(ctx, "testbf2", 0.001, 2000, 3).Err()
117 Expect(err).NotTo(HaveOccurred())
118
119 result, err = client.BFInfoFilters(ctx, "testbf2").Result()
120 Expect(err).NotTo(HaveOccurred())
121 Expect(result.Filters).To(BeEquivalentTo(int64(1)))
122
123 result, err = client.BFInfoExpansion(ctx, "testbf2").Result()
124 Expect(err).NotTo(HaveOccurred())
125 Expect(result.ExpansionRate).To(BeEquivalentTo(int64(3)))
126 })
127
128 It("should BFInsert", Label("bloom", "bfinsert"), func() {
129 options := &redis.BFInsertOptions{
130 Capacity: 2000,
131 Error: 0.001,
132 Expansion: 3,
133 NonScaling: false,
134 NoCreate: true,
135 }
136
137 _, err := client.BFInsert(ctx, "testbf1", options, "item1").Result()
138 Expect(err).To(HaveOccurred())
139 Expect(err).To(MatchError("ERR not found"))
140
141 options = &redis.BFInsertOptions{
142 Capacity: 2000,
143 Error: 0.001,
144 Expansion: 3,
145 NonScaling: false,
146 NoCreate: false,
147 }
148
149 resultInsert, err := client.BFInsert(ctx, "testbf1", options, "item1").Result()
150 Expect(err).NotTo(HaveOccurred())
151 Expect(len(resultInsert)).To(BeEquivalentTo(1))
152
153 exists, err := client.BFExists(ctx, "testbf1", "item1").Result()
154 Expect(err).NotTo(HaveOccurred())
155 Expect(exists).To(BeTrue())
156
157 result, err := client.BFInfo(ctx, "testbf1").Result()
158 Expect(err).NotTo(HaveOccurred())
159 Expect(result).To(BeAssignableToTypeOf(redis.BFInfo{}))
160 Expect(result.Capacity).To(BeEquivalentTo(int64(2000)))
161 Expect(result.ExpansionRate).To(BeEquivalentTo(int64(3)))
162 })
163
164 It("should BFMAdd", Label("bloom", "bfmadd"), func() {
165 resultAdd, err := client.BFMAdd(ctx, "testbf1", "item1", "item2", "item3").Result()
166
167 Expect(err).NotTo(HaveOccurred())
168 Expect(len(resultAdd)).To(Equal(3))
169
170 resultInfo, err := client.BFInfo(ctx, "testbf1").Result()
171
172 Expect(err).NotTo(HaveOccurred())
173 Expect(resultInfo).To(BeAssignableToTypeOf(redis.BFInfo{}))
174 Expect(resultInfo.ItemsInserted).To(BeEquivalentTo(int64(3)))
175 resultAdd2, err := client.BFMAdd(ctx, "testbf1", "item1", "item2", "item4").Result()
176 Expect(err).NotTo(HaveOccurred())
177 Expect(resultAdd2[0]).To(BeFalse())
178 Expect(resultAdd2[1]).To(BeFalse())
179 Expect(resultAdd2[2]).To(BeTrue())
180 })
181
182 It("should BFMExists", Label("bloom", "bfmexists"), func() {
183 exist, err := client.BFMExists(ctx, "testbf1", "item1", "item2", "item3").Result()
184 Expect(err).NotTo(HaveOccurred())
185 Expect(len(exist)).To(Equal(3))
186 Expect(exist[0]).To(BeFalse())
187 Expect(exist[1]).To(BeFalse())
188 Expect(exist[2]).To(BeFalse())
189
190 _, err = client.BFMAdd(ctx, "testbf1", "item1", "item2", "item3").Result()
191 Expect(err).NotTo(HaveOccurred())
192
193 exist, err = client.BFMExists(ctx, "testbf1", "item1", "item2", "item3", "item4").Result()
194
195 Expect(err).NotTo(HaveOccurred())
196 Expect(len(exist)).To(Equal(4))
197 Expect(exist[0]).To(BeTrue())
198 Expect(exist[1]).To(BeTrue())
199 Expect(exist[2]).To(BeTrue())
200 Expect(exist[3]).To(BeFalse())
201 })
202
203 It("should BFReserveExpansion", Label("bloom", "bfreserveexpansion"), func() {
204 err := client.BFReserveExpansion(ctx, "testbf1", 0.001, 2000, 3).Err()
205 Expect(err).NotTo(HaveOccurred())
206
207 result, err := client.BFInfo(ctx, "testbf1").Result()
208 Expect(err).NotTo(HaveOccurred())
209 Expect(result).To(BeAssignableToTypeOf(redis.BFInfo{}))
210 Expect(result.Capacity).To(BeEquivalentTo(int64(2000)))
211 Expect(result.ExpansionRate).To(BeEquivalentTo(int64(3)))
212 })
213
214 It("should BFReserveNonScaling", Label("bloom", "bfreservenonscaling"), func() {
215 err := client.BFReserveNonScaling(ctx, "testbfns1", 0.001, 1000).Err()
216 Expect(err).NotTo(HaveOccurred())
217
218 _, err = client.BFInfo(ctx, "testbfns1").Result()
219 Expect(err).To(HaveOccurred())
220 })
221
222 It("should BFScanDump and BFLoadChunk", Label("bloom", "bfscandump", "bfloadchunk"), func() {
223 err := client.BFReserve(ctx, "testbfsd1", 0.001, 3000).Err()
224 Expect(err).NotTo(HaveOccurred())
225 for i := 0; i < 1000; i++ {
226 client.BFAdd(ctx, "testbfsd1", i)
227 }
228 infBefore := client.BFInfoSize(ctx, "testbfsd1")
229 fd := []redis.ScanDump{}
230 sd, err := client.BFScanDump(ctx, "testbfsd1", 0).Result()
231 for {
232 if sd.Iter == 0 {
233 break
234 }
235 Expect(err).NotTo(HaveOccurred())
236 fd = append(fd, sd)
237 sd, err = client.BFScanDump(ctx, "testbfsd1", sd.Iter).Result()
238 }
239 client.Del(ctx, "testbfsd1")
240 for _, e := range fd {
241 client.BFLoadChunk(ctx, "testbfsd1", e.Iter, e.Data)
242 }
243 infAfter := client.BFInfoSize(ctx, "testbfsd1")
244 Expect(infBefore).To(BeEquivalentTo(infAfter))
245 })
246
247 It("should BFReserveWithArgs", Label("bloom", "bfreserveargs"), func() {
248 options := &redis.BFReserveOptions{
249 Capacity: 2000,
250 Error: 0.001,
251 Expansion: 3,
252 NonScaling: false,
253 }
254 err := client.BFReserveWithArgs(ctx, "testbf", options).Err()
255 Expect(err).NotTo(HaveOccurred())
256
257 result, err := client.BFInfo(ctx, "testbf").Result()
258 Expect(err).NotTo(HaveOccurred())
259 Expect(result).To(BeAssignableToTypeOf(redis.BFInfo{}))
260 Expect(result.Capacity).To(BeEquivalentTo(int64(2000)))
261 Expect(result.ExpansionRate).To(BeEquivalentTo(int64(3)))
262 })
263 })
264
265 Describe("cuckoo", Label("cuckoo"), func() {
266 It("should CFAdd", Label("cuckoo", "cfadd"), func() {
267 add, err := client.CFAdd(ctx, "testcf1", "item1").Result()
268 Expect(err).NotTo(HaveOccurred())
269 Expect(add).To(BeTrue())
270
271 exists, err := client.CFExists(ctx, "testcf1", "item1").Result()
272 Expect(err).NotTo(HaveOccurred())
273 Expect(exists).To(BeTrue())
274
275 info, err := client.CFInfo(ctx, "testcf1").Result()
276 Expect(err).NotTo(HaveOccurred())
277 Expect(info).To(BeAssignableToTypeOf(redis.CFInfo{}))
278 Expect(info.NumItemsInserted).To(BeEquivalentTo(int64(1)))
279 })
280
281 It("should CFAddNX", Label("cuckoo", "cfaddnx"), func() {
282 add, err := client.CFAddNX(ctx, "testcf1", "item1").Result()
283 Expect(err).NotTo(HaveOccurred())
284 Expect(add).To(BeTrue())
285
286 exists, err := client.CFExists(ctx, "testcf1", "item1").Result()
287 Expect(err).NotTo(HaveOccurred())
288 Expect(exists).To(BeTrue())
289
290 result, err := client.CFAddNX(ctx, "testcf1", "item1").Result()
291 Expect(err).NotTo(HaveOccurred())
292 Expect(result).To(BeFalse())
293
294 info, err := client.CFInfo(ctx, "testcf1").Result()
295 Expect(err).NotTo(HaveOccurred())
296 Expect(info).To(BeAssignableToTypeOf(redis.CFInfo{}))
297 Expect(info.NumItemsInserted).To(BeEquivalentTo(int64(1)))
298 })
299
300 It("should CFCount", Label("cuckoo", "cfcount"), func() {
301 client.CFAdd(ctx, "testcf1", "item1")
302 cnt, err := client.CFCount(ctx, "testcf1", "item1").Result()
303 Expect(err).NotTo(HaveOccurred())
304 Expect(cnt).To(BeEquivalentTo(int64(1)))
305
306 err = client.CFAdd(ctx, "testcf1", "item1").Err()
307 Expect(err).NotTo(HaveOccurred())
308
309 cnt, err = client.CFCount(ctx, "testcf1", "item1").Result()
310 Expect(err).NotTo(HaveOccurred())
311 Expect(cnt).To(BeEquivalentTo(int64(2)))
312 })
313
314 It("should CFDel and CFExists", Label("cuckoo", "cfdel", "cfexists"), func() {
315 err := client.CFAdd(ctx, "testcf1", "item1").Err()
316 Expect(err).NotTo(HaveOccurred())
317
318 exists, err := client.CFExists(ctx, "testcf1", "item1").Result()
319 Expect(err).NotTo(HaveOccurred())
320 Expect(exists).To(BeTrue())
321
322 del, err := client.CFDel(ctx, "testcf1", "item1").Result()
323 Expect(err).NotTo(HaveOccurred())
324 Expect(del).To(BeTrue())
325
326 exists, err = client.CFExists(ctx, "testcf1", "item1").Result()
327 Expect(err).NotTo(HaveOccurred())
328 Expect(exists).To(BeFalse())
329 })
330
331 It("should CFInfo and CFReserve", Label("cuckoo", "cfinfo", "cfreserve"), func() {
332 err := client.CFReserve(ctx, "testcf1", 1000).Err()
333 Expect(err).NotTo(HaveOccurred())
334 err = client.CFReserveExpansion(ctx, "testcfe1", 1000, 1).Err()
335 Expect(err).NotTo(HaveOccurred())
336 err = client.CFReserveBucketSize(ctx, "testcfbs1", 1000, 4).Err()
337 Expect(err).NotTo(HaveOccurred())
338 err = client.CFReserveMaxIterations(ctx, "testcfmi1", 1000, 10).Err()
339 Expect(err).NotTo(HaveOccurred())
340
341 result, err := client.CFInfo(ctx, "testcf1").Result()
342 Expect(err).NotTo(HaveOccurred())
343 Expect(result).To(BeAssignableToTypeOf(redis.CFInfo{}))
344 })
345
346 It("should CFScanDump and CFLoadChunk", Label("bloom", "cfscandump", "cfloadchunk"), func() {
347 err := client.CFReserve(ctx, "testcfsd1", 1000).Err()
348 Expect(err).NotTo(HaveOccurred())
349 for i := 0; i < 1000; i++ {
350 Item := fmt.Sprintf("item%d", i)
351 client.CFAdd(ctx, "testcfsd1", Item)
352 }
353 infBefore := client.CFInfo(ctx, "testcfsd1")
354 fd := []redis.ScanDump{}
355 sd, err := client.CFScanDump(ctx, "testcfsd1", 0).Result()
356 for {
357 if sd.Iter == 0 {
358 break
359 }
360 Expect(err).NotTo(HaveOccurred())
361 fd = append(fd, sd)
362 sd, err = client.CFScanDump(ctx, "testcfsd1", sd.Iter).Result()
363 }
364 client.Del(ctx, "testcfsd1")
365 for _, e := range fd {
366 client.CFLoadChunk(ctx, "testcfsd1", e.Iter, e.Data)
367 }
368 infAfter := client.CFInfo(ctx, "testcfsd1")
369 Expect(infBefore).To(BeEquivalentTo(infAfter))
370 })
371
372 It("should CFInfo and CFReserveWithArgs", Label("cuckoo", "cfinfo", "cfreserveargs"), func() {
373 args := &redis.CFReserveOptions{
374 Capacity: 2048,
375 BucketSize: 3,
376 MaxIterations: 15,
377 Expansion: 2,
378 }
379
380 err := client.CFReserveWithArgs(ctx, "testcf1", args).Err()
381 Expect(err).NotTo(HaveOccurred())
382
383 result, err := client.CFInfo(ctx, "testcf1").Result()
384 Expect(err).NotTo(HaveOccurred())
385 Expect(result).To(BeAssignableToTypeOf(redis.CFInfo{}))
386 Expect(result.BucketSize).To(BeEquivalentTo(int64(3)))
387 Expect(result.MaxIteration).To(BeEquivalentTo(int64(15)))
388 Expect(result.ExpansionRate).To(BeEquivalentTo(int64(2)))
389 })
390
391 It("should CFInsert", Label("cuckoo", "cfinsert"), func() {
392 args := &redis.CFInsertOptions{
393 Capacity: 3000,
394 NoCreate: true,
395 }
396
397 _, err := client.CFInsert(ctx, "testcf1", args, "item1", "item2", "item3").Result()
398 Expect(err).To(HaveOccurred())
399
400 args = &redis.CFInsertOptions{
401 Capacity: 3000,
402 NoCreate: false,
403 }
404
405 result, err := client.CFInsert(ctx, "testcf1", args, "item1", "item2", "item3").Result()
406 Expect(err).NotTo(HaveOccurred())
407 Expect(len(result)).To(BeEquivalentTo(3))
408 })
409
410 It("should CFInsertNX", Label("cuckoo", "cfinsertnx"), func() {
411 args := &redis.CFInsertOptions{
412 Capacity: 3000,
413 NoCreate: true,
414 }
415
416 _, err := client.CFInsertNX(ctx, "testcf1", args, "item1", "item2", "item2").Result()
417 Expect(err).To(HaveOccurred())
418
419 args = &redis.CFInsertOptions{
420 Capacity: 3000,
421 NoCreate: false,
422 }
423
424 result, err := client.CFInsertNX(ctx, "testcf2", args, "item1", "item2", "item2").Result()
425 Expect(err).NotTo(HaveOccurred())
426 Expect(len(result)).To(BeEquivalentTo(3))
427 Expect(result[0]).To(BeEquivalentTo(int64(1)))
428 Expect(result[1]).To(BeEquivalentTo(int64(1)))
429 Expect(result[2]).To(BeEquivalentTo(int64(0)))
430 })
431
432 It("should CFMexists", Label("cuckoo", "cfmexists"), func() {
433 err := client.CFInsert(ctx, "testcf1", nil, "item1", "item2", "item3").Err()
434 Expect(err).NotTo(HaveOccurred())
435
436 result, err := client.CFMExists(ctx, "testcf1", "item1", "item2", "item3", "item4").Result()
437 Expect(err).NotTo(HaveOccurred())
438 Expect(len(result)).To(BeEquivalentTo(4))
439 Expect(result[0]).To(BeTrue())
440 Expect(result[1]).To(BeTrue())
441 Expect(result[2]).To(BeTrue())
442 Expect(result[3]).To(BeFalse())
443 })
444 })
445
446 Describe("CMS", Label("cms"), func() {
447 It("should CMSIncrBy", Label("cms", "cmsincrby"), func() {
448 err := client.CMSInitByDim(ctx, "testcms1", 5, 10).Err()
449 Expect(err).NotTo(HaveOccurred())
450
451 result, err := client.CMSIncrBy(ctx, "testcms1", "item1", 1, "item2", 2, "item3", 3).Result()
452 Expect(err).NotTo(HaveOccurred())
453 Expect(len(result)).To(BeEquivalentTo(3))
454 Expect(result[0]).To(BeEquivalentTo(int64(1)))
455 Expect(result[1]).To(BeEquivalentTo(int64(2)))
456 Expect(result[2]).To(BeEquivalentTo(int64(3)))
457 })
458
459 It("should CMSInitByDim and CMSInfo", Label("cms", "cmsinitbydim", "cmsinfo"), func() {
460 err := client.CMSInitByDim(ctx, "testcms1", 5, 10).Err()
461 Expect(err).NotTo(HaveOccurred())
462
463 info, err := client.CMSInfo(ctx, "testcms1").Result()
464 Expect(err).NotTo(HaveOccurred())
465
466 Expect(info).To(BeAssignableToTypeOf(redis.CMSInfo{}))
467 Expect(info.Width).To(BeEquivalentTo(int64(5)))
468 Expect(info.Depth).To(BeEquivalentTo(int64(10)))
469 })
470
471 It("should CMSInitByProb", Label("cms", "cmsinitbyprob"), func() {
472 err := client.CMSInitByProb(ctx, "testcms1", 0.002, 0.01).Err()
473 Expect(err).NotTo(HaveOccurred())
474
475 info, err := client.CMSInfo(ctx, "testcms1").Result()
476 Expect(err).NotTo(HaveOccurred())
477 Expect(info).To(BeAssignableToTypeOf(redis.CMSInfo{}))
478 })
479
480 It("should CMSMerge, CMSMergeWithWeight and CMSQuery", Label("cms", "cmsmerge", "cmsquery", "NonRedisEnterprise"), func() {
481 err := client.CMSMerge(ctx, "destCms1", "testcms2", "testcms3").Err()
482 Expect(err).To(HaveOccurred())
483 Expect(err).To(MatchError("CMS: key does not exist"))
484
485 err = client.CMSInitByDim(ctx, "destCms1", 5, 10).Err()
486 Expect(err).NotTo(HaveOccurred())
487 err = client.CMSInitByDim(ctx, "destCms2", 5, 10).Err()
488 Expect(err).NotTo(HaveOccurred())
489 err = client.CMSInitByDim(ctx, "cms1", 2, 20).Err()
490 Expect(err).NotTo(HaveOccurred())
491 err = client.CMSInitByDim(ctx, "cms2", 3, 20).Err()
492 Expect(err).NotTo(HaveOccurred())
493
494 err = client.CMSMerge(ctx, "destCms1", "cms1", "cms2").Err()
495 Expect(err).To(MatchError("CMS: width/depth is not equal"))
496
497 client.Del(ctx, "cms1", "cms2")
498
499 err = client.CMSInitByDim(ctx, "cms1", 5, 10).Err()
500 Expect(err).NotTo(HaveOccurred())
501 err = client.CMSInitByDim(ctx, "cms2", 5, 10).Err()
502 Expect(err).NotTo(HaveOccurred())
503
504 client.CMSIncrBy(ctx, "cms1", "item1", 1, "item2", 2)
505 client.CMSIncrBy(ctx, "cms2", "item2", 2, "item3", 3)
506
507 err = client.CMSMerge(ctx, "destCms1", "cms1", "cms2").Err()
508 Expect(err).NotTo(HaveOccurred())
509
510 result, err := client.CMSQuery(ctx, "destCms1", "item1", "item2", "item3").Result()
511 Expect(err).NotTo(HaveOccurred())
512 Expect(len(result)).To(BeEquivalentTo(3))
513 Expect(result[0]).To(BeEquivalentTo(int64(1)))
514 Expect(result[1]).To(BeEquivalentTo(int64(4)))
515 Expect(result[2]).To(BeEquivalentTo(int64(3)))
516
517 sourceSketches := map[string]int64{
518 "cms1": 1,
519 "cms2": 2,
520 }
521 err = client.CMSMergeWithWeight(ctx, "destCms2", sourceSketches).Err()
522 Expect(err).NotTo(HaveOccurred())
523
524 result, err = client.CMSQuery(ctx, "destCms2", "item1", "item2", "item3").Result()
525 Expect(err).NotTo(HaveOccurred())
526 Expect(len(result)).To(BeEquivalentTo(3))
527 Expect(result[0]).To(BeEquivalentTo(int64(1)))
528 Expect(result[1]).To(BeEquivalentTo(int64(6)))
529 Expect(result[2]).To(BeEquivalentTo(int64(6)))
530 })
531 })
532
533 Describe("TopK", Label("topk"), func() {
534 It("should TopKReserve, TopKInfo, TopKAdd, TopKQuery, TopKCount, TopKIncrBy, TopKList, TopKListWithCount", Label("topk", "topkreserve", "topkinfo", "topkadd", "topkquery", "topkcount", "topkincrby", "topklist", "topklistwithcount"), func() {
535 err := client.TopKReserve(ctx, "topk1", 3).Err()
536 Expect(err).NotTo(HaveOccurred())
537
538 resultInfo, err := client.TopKInfo(ctx, "topk1").Result()
539 Expect(err).NotTo(HaveOccurred())
540 Expect(resultInfo.K).To(BeEquivalentTo(int64(3)))
541
542 resultAdd, err := client.TopKAdd(ctx, "topk1", "item1", "item2", 3, "item1").Result()
543 Expect(err).NotTo(HaveOccurred())
544 Expect(len(resultAdd)).To(BeEquivalentTo(int64(4)))
545
546 resultQuery, err := client.TopKQuery(ctx, "topk1", "item1", "item2", 4, 3).Result()
547 Expect(err).NotTo(HaveOccurred())
548 Expect(len(resultQuery)).To(BeEquivalentTo(4))
549 Expect(resultQuery[0]).To(BeTrue())
550 Expect(resultQuery[1]).To(BeTrue())
551 Expect(resultQuery[2]).To(BeFalse())
552 Expect(resultQuery[3]).To(BeTrue())
553
554 resultCount, err := client.TopKCount(ctx, "topk1", "item1", "item2", "item3").Result()
555 Expect(err).NotTo(HaveOccurred())
556 Expect(len(resultCount)).To(BeEquivalentTo(3))
557 Expect(resultCount[0]).To(BeEquivalentTo(int64(2)))
558 Expect(resultCount[1]).To(BeEquivalentTo(int64(1)))
559 Expect(resultCount[2]).To(BeEquivalentTo(int64(0)))
560
561 resultIncr, err := client.TopKIncrBy(ctx, "topk1", "item1", 5, "item2", 10).Result()
562 Expect(err).NotTo(HaveOccurred())
563 Expect(len(resultIncr)).To(BeEquivalentTo(2))
564
565 resultCount, err = client.TopKCount(ctx, "topk1", "item1", "item2", "item3").Result()
566 Expect(err).NotTo(HaveOccurred())
567 Expect(len(resultCount)).To(BeEquivalentTo(3))
568 Expect(resultCount[0]).To(BeEquivalentTo(int64(7)))
569 Expect(resultCount[1]).To(BeEquivalentTo(int64(11)))
570 Expect(resultCount[2]).To(BeEquivalentTo(int64(0)))
571
572 resultList, err := client.TopKList(ctx, "topk1").Result()
573 Expect(err).NotTo(HaveOccurred())
574 Expect(len(resultList)).To(BeEquivalentTo(3))
575 Expect(resultList).To(ContainElements("item2", "item1", "3"))
576
577 resultListWithCount, err := client.TopKListWithCount(ctx, "topk1").Result()
578 Expect(err).NotTo(HaveOccurred())
579 Expect(len(resultListWithCount)).To(BeEquivalentTo(3))
580 Expect(resultListWithCount["3"]).To(BeEquivalentTo(int64(1)))
581 Expect(resultListWithCount["item1"]).To(BeEquivalentTo(int64(7)))
582 Expect(resultListWithCount["item2"]).To(BeEquivalentTo(int64(11)))
583 })
584
585 It("should TopKReserveWithOptions", Label("topk", "topkreservewithoptions"), func() {
586 err := client.TopKReserveWithOptions(ctx, "topk1", 3, 1500, 8, 0.5).Err()
587 Expect(err).NotTo(HaveOccurred())
588
589 resultInfo, err := client.TopKInfo(ctx, "topk1").Result()
590 Expect(err).NotTo(HaveOccurred())
591 Expect(resultInfo.K).To(BeEquivalentTo(int64(3)))
592 Expect(resultInfo.Width).To(BeEquivalentTo(int64(1500)))
593 Expect(resultInfo.Depth).To(BeEquivalentTo(int64(8)))
594 Expect(resultInfo.Decay).To(BeEquivalentTo(0.5))
595 })
596 })
597
598 Describe("t-digest", Label("tdigest"), func() {
599 It("should TDigestAdd, TDigestCreate, TDigestInfo, TDigestByRank, TDigestByRevRank, TDigestCDF, TDigestMax, TDigestMin, TDigestQuantile, TDigestRank, TDigestRevRank, TDigestTrimmedMean, TDigestReset, ", Label("tdigest", "tdigestadd", "tdigestcreate", "tdigestinfo", "tdigestbyrank", "tdigestbyrevrank", "tdigestcdf", "tdigestmax", "tdigestmin", "tdigestquantile", "tdigestrank", "tdigestrevrank", "tdigesttrimmedmean", "tdigestreset"), func() {
600 err := client.TDigestCreate(ctx, "tdigest1").Err()
601 Expect(err).NotTo(HaveOccurred())
602
603 info, err := client.TDigestInfo(ctx, "tdigest1").Result()
604 Expect(err).NotTo(HaveOccurred())
605 Expect(info.Observations).To(BeEquivalentTo(int64(0)))
606
607
608 byRank, err := client.TDigestByRank(ctx, "tdigest1", 0, 1, 2, 3).Result()
609 Expect(err).NotTo(HaveOccurred())
610 Expect(len(byRank)).To(BeEquivalentTo(4))
611
612 byRevRank, err := client.TDigestByRevRank(ctx, "tdigest1", 0, 1, 2).Result()
613 Expect(err).NotTo(HaveOccurred())
614 Expect(len(byRevRank)).To(BeEquivalentTo(3))
615
616 cdf, err := client.TDigestCDF(ctx, "tdigest1", 15, 35, 70).Result()
617 Expect(err).NotTo(HaveOccurred())
618 Expect(len(cdf)).To(BeEquivalentTo(3))
619
620 max, err := client.TDigestMax(ctx, "tdigest1").Result()
621 Expect(err).NotTo(HaveOccurred())
622 Expect(math.IsNaN(max)).To(BeTrue())
623
624 min, err := client.TDigestMin(ctx, "tdigest1").Result()
625 Expect(err).NotTo(HaveOccurred())
626 Expect(math.IsNaN(min)).To(BeTrue())
627
628 quantile, err := client.TDigestQuantile(ctx, "tdigest1", 0.1, 0.2).Result()
629 Expect(err).NotTo(HaveOccurred())
630 Expect(len(quantile)).To(BeEquivalentTo(2))
631
632 rank, err := client.TDigestRank(ctx, "tdigest1", 10, 20).Result()
633 Expect(err).NotTo(HaveOccurred())
634 Expect(len(rank)).To(BeEquivalentTo(2))
635
636 revRank, err := client.TDigestRevRank(ctx, "tdigest1", 10, 20).Result()
637 Expect(err).NotTo(HaveOccurred())
638 Expect(len(revRank)).To(BeEquivalentTo(2))
639
640 trimmedMean, err := client.TDigestTrimmedMean(ctx, "tdigest1", 0.1, 0.6).Result()
641 Expect(err).NotTo(HaveOccurred())
642 Expect(math.IsNaN(trimmedMean)).To(BeTrue())
643
644
645 err = client.TDigestAdd(ctx, "tdigest1", 10, 20, 30, 40, 50, 60, 70, 80, 90, 100).Err()
646 Expect(err).NotTo(HaveOccurred())
647
648 info, err = client.TDigestInfo(ctx, "tdigest1").Result()
649 Expect(err).NotTo(HaveOccurred())
650 Expect(info.Observations).To(BeEquivalentTo(int64(10)))
651
652 byRank, err = client.TDigestByRank(ctx, "tdigest1", 0, 1, 2).Result()
653 Expect(err).NotTo(HaveOccurred())
654 Expect(len(byRank)).To(BeEquivalentTo(3))
655 Expect(byRank[0]).To(BeEquivalentTo(float64(10)))
656 Expect(byRank[1]).To(BeEquivalentTo(float64(20)))
657 Expect(byRank[2]).To(BeEquivalentTo(float64(30)))
658
659 byRevRank, err = client.TDigestByRevRank(ctx, "tdigest1", 0, 1, 2).Result()
660 Expect(err).NotTo(HaveOccurred())
661 Expect(len(byRevRank)).To(BeEquivalentTo(3))
662 Expect(byRevRank[0]).To(BeEquivalentTo(float64(100)))
663 Expect(byRevRank[1]).To(BeEquivalentTo(float64(90)))
664 Expect(byRevRank[2]).To(BeEquivalentTo(float64(80)))
665
666 cdf, err = client.TDigestCDF(ctx, "tdigest1", 15, 35, 70).Result()
667 Expect(err).NotTo(HaveOccurred())
668 Expect(len(cdf)).To(BeEquivalentTo(3))
669 Expect(cdf[0]).To(BeEquivalentTo(0.1))
670 Expect(cdf[1]).To(BeEquivalentTo(0.3))
671 Expect(cdf[2]).To(BeEquivalentTo(0.65))
672
673 max, err = client.TDigestMax(ctx, "tdigest1").Result()
674 Expect(err).NotTo(HaveOccurred())
675 Expect(max).To(BeEquivalentTo(float64(100)))
676
677 min, err = client.TDigestMin(ctx, "tdigest1").Result()
678 Expect(err).NotTo(HaveOccurred())
679 Expect(min).To(BeEquivalentTo(float64(10)))
680
681 quantile, err = client.TDigestQuantile(ctx, "tdigest1", 0.1, 0.2).Result()
682 Expect(err).NotTo(HaveOccurred())
683 Expect(len(quantile)).To(BeEquivalentTo(2))
684 Expect(quantile[0]).To(BeEquivalentTo(float64(20)))
685 Expect(quantile[1]).To(BeEquivalentTo(float64(30)))
686
687 rank, err = client.TDigestRank(ctx, "tdigest1", 10, 20).Result()
688 Expect(err).NotTo(HaveOccurred())
689 Expect(len(rank)).To(BeEquivalentTo(2))
690 Expect(rank[0]).To(BeEquivalentTo(int64(0)))
691 Expect(rank[1]).To(BeEquivalentTo(int64(1)))
692
693 revRank, err = client.TDigestRevRank(ctx, "tdigest1", 10, 20).Result()
694 Expect(err).NotTo(HaveOccurred())
695 Expect(len(revRank)).To(BeEquivalentTo(2))
696 Expect(revRank[0]).To(BeEquivalentTo(int64(9)))
697 Expect(revRank[1]).To(BeEquivalentTo(int64(8)))
698
699 trimmedMean, err = client.TDigestTrimmedMean(ctx, "tdigest1", 0.1, 0.6).Result()
700 Expect(err).NotTo(HaveOccurred())
701 Expect(trimmedMean).To(BeEquivalentTo(float64(40)))
702
703 reset, err := client.TDigestReset(ctx, "tdigest1").Result()
704 Expect(err).NotTo(HaveOccurred())
705 Expect(reset).To(BeEquivalentTo("OK"))
706 })
707
708 It("should TDigestCreateWithCompression", Label("tdigest", "tcreatewithcompression"), func() {
709 err := client.TDigestCreateWithCompression(ctx, "tdigest1", 2000).Err()
710 Expect(err).NotTo(HaveOccurred())
711
712 info, err := client.TDigestInfo(ctx, "tdigest1").Result()
713 Expect(err).NotTo(HaveOccurred())
714 Expect(info.Compression).To(BeEquivalentTo(int64(2000)))
715 })
716
717 It("should TDigestMerge", Label("tdigest", "tmerge", "NonRedisEnterprise"), func() {
718 err := client.TDigestCreate(ctx, "tdigest1").Err()
719 Expect(err).NotTo(HaveOccurred())
720 err = client.TDigestAdd(ctx, "tdigest1", 10, 20, 30, 40, 50, 60, 70, 80, 90, 100).Err()
721 Expect(err).NotTo(HaveOccurred())
722
723 err = client.TDigestCreate(ctx, "tdigest2").Err()
724 Expect(err).NotTo(HaveOccurred())
725 err = client.TDigestAdd(ctx, "tdigest2", 15, 25, 35, 45, 55, 65, 75, 85, 95, 105).Err()
726 Expect(err).NotTo(HaveOccurred())
727
728 err = client.TDigestCreate(ctx, "tdigest3").Err()
729 Expect(err).NotTo(HaveOccurred())
730 err = client.TDigestAdd(ctx, "tdigest3", 50, 60, 70, 80, 90, 100, 110, 120, 130, 140).Err()
731 Expect(err).NotTo(HaveOccurred())
732
733 options := &redis.TDigestMergeOptions{
734 Compression: 1000,
735 Override: false,
736 }
737 err = client.TDigestMerge(ctx, "tdigest1", options, "tdigest2", "tdigest3").Err()
738 Expect(err).NotTo(HaveOccurred())
739
740 info, err := client.TDigestInfo(ctx, "tdigest1").Result()
741 Expect(err).NotTo(HaveOccurred())
742 Expect(info.Observations).To(BeEquivalentTo(int64(30)))
743 Expect(info.Compression).To(BeEquivalentTo(int64(1000)))
744
745 max, err := client.TDigestMax(ctx, "tdigest1").Result()
746 Expect(err).NotTo(HaveOccurred())
747 Expect(max).To(BeEquivalentTo(float64(140)))
748 })
749 })
750 })
751 }
752 })
753
View as plain text