mirror of
https://github.com/redis/go-redis.git
synced 2026-10-22 19:49:00 +03:00
feat(bloom): add cellSize param to cms init (#4023)
This commit is contained in:
@@ -2,11 +2,14 @@ package redis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/redis/go-redis/v9/internal/proto"
|
||||
)
|
||||
|
||||
var errCMSInvalidCellSize = errors.New("redis: invalid cell size (must be 1, 2, 4 or 8)")
|
||||
|
||||
type ProbabilisticCmdable interface {
|
||||
BFAdd(ctx context.Context, key string, element interface{}) *BoolCmd
|
||||
BFCard(ctx context.Context, key string) *IntCmd
|
||||
@@ -48,7 +51,9 @@ type ProbabilisticCmdable interface {
|
||||
CMSIncrBy(ctx context.Context, key string, elements ...interface{}) *IntSliceCmd
|
||||
CMSInfo(ctx context.Context, key string) *CMSInfoCmd
|
||||
CMSInitByDim(ctx context.Context, key string, width, height int64) *StatusCmd
|
||||
CMSInitByDimCellSize(ctx context.Context, key string, width, depth, cellSize int64) *StatusCmd
|
||||
CMSInitByProb(ctx context.Context, key string, errorRate, probability float64) *StatusCmd
|
||||
CMSInitByProbCellSize(ctx context.Context, key string, errorRate, probability float64, cellSize int64) *StatusCmd
|
||||
CMSMerge(ctx context.Context, destKey string, sourceKeys ...string) *StatusCmd
|
||||
CMSMergeWithWeight(ctx context.Context, destKey string, sourceKeys map[string]int64) *StatusCmd
|
||||
CMSQuery(ctx context.Context, key string, elements ...interface{}) *IntSliceCmd
|
||||
@@ -912,21 +917,55 @@ func (c cmdable) CMSInfo(ctx context.Context, key string) *CMSInfoCmd {
|
||||
// CMSInitByDim creates an empty Count-Min Sketch filter with the specified dimensions.
|
||||
// For more information - https://redis.io/commands/cms.initbydim/
|
||||
func (c cmdable) CMSInitByDim(ctx context.Context, key string, width, depth int64) *StatusCmd {
|
||||
args := []interface{}{"CMS.INITBYDIM", key, width, depth}
|
||||
args := []any{"CMS.INITBYDIM", key, width, depth}
|
||||
cmd := NewStatusCmd(ctx, args...)
|
||||
_ = c(ctx, cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// CMSInitByDimCellSize creates an empty Count-Min Sketch filter with the specified dimensions and number of bytes per cell (valid cell sizes: 1,2,4,8).
|
||||
// For more information - https://redis.io/commands/cms.initbydim/
|
||||
func (c cmdable) CMSInitByDimCellSize(ctx context.Context, key string, width, depth, cellSize int64) *StatusCmd {
|
||||
args := []any{"CMS.INITBYDIM", key, width, depth, "CELL_SIZE", cellSize}
|
||||
cmd := NewStatusCmd(ctx, args...)
|
||||
if !isValidCMSCellSize(cellSize) {
|
||||
cmd.SetErr(errCMSInvalidCellSize)
|
||||
return cmd
|
||||
}
|
||||
_ = c(ctx, cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// CMSInitByProb creates an empty Count-Min Sketch filter with the specified error rate and probability.
|
||||
// For more information - https://redis.io/commands/cms.initbyprob/
|
||||
func (c cmdable) CMSInitByProb(ctx context.Context, key string, errorRate, probability float64) *StatusCmd {
|
||||
args := []interface{}{"CMS.INITBYPROB", key, errorRate, probability}
|
||||
args := []any{"CMS.INITBYPROB", key, errorRate, probability}
|
||||
cmd := NewStatusCmd(ctx, args...)
|
||||
_ = c(ctx, cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// CMSInitByProbCellSize creates an empty Count-Min Sketch filter with the specified error rate, probability and number of bytes per cell (valid cell sizes: 1,2,4,8).
|
||||
// For more information - https://redis.io/commands/cms.initbyprob/
|
||||
func (c cmdable) CMSInitByProbCellSize(ctx context.Context, key string, errorRate, probability float64, cellSize int64) *StatusCmd {
|
||||
args := []any{"CMS.INITBYPROB", key, errorRate, probability, "CELL_SIZE", cellSize}
|
||||
cmd := NewStatusCmd(ctx, args...)
|
||||
if !isValidCMSCellSize(cellSize) {
|
||||
cmd.SetErr(errCMSInvalidCellSize)
|
||||
return cmd
|
||||
}
|
||||
_ = c(ctx, cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func isValidCMSCellSize(cellSize int64) bool {
|
||||
switch cellSize {
|
||||
case 1, 2, 4, 8:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// CMSMerge merges multiple Count-Min Sketch filters into a single filter.
|
||||
// The destination filter must not exist and will be created with the dimensions of the first source filter.
|
||||
// The number of items in each source filter must be equal.
|
||||
|
||||
@@ -502,6 +502,43 @@ var _ = Describe("Probabilistic commands", Label("probabilistic"), func() {
|
||||
Expect(info).To(BeAssignableToTypeOf(redis.CMSInfo{}))
|
||||
})
|
||||
|
||||
It("should CMSInitByDimCellSize", Label("cms", "cmsinitbydim", "cmsinfo"), func() {
|
||||
SkipBeforeRedisVersion("8.12", "CMS.INITBYDIM CELL_SIZE since Redis 8.12")
|
||||
|
||||
err := client.CMSInitByDimCellSize(ctx, "testcms1", 5, 10, 8).Err()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
info, err := client.CMSInfo(ctx, "testcms1").Result()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(info.Width).To(BeEquivalentTo(int64(5)))
|
||||
Expect(info.Depth).To(BeEquivalentTo(int64(10)))
|
||||
Expect(info.CellSize).To(BeEquivalentTo(int64(8)))
|
||||
})
|
||||
|
||||
It("should CMSInitByProbCellSize", Label("cms", "cmsinitbyprob", "cmsinfo"), func() {
|
||||
SkipBeforeRedisVersion("8.12", "CMS.INITBYPROB CELL_SIZE since Redis 8.12")
|
||||
|
||||
err := client.CMSInitByProbCellSize(ctx, "testcms1", 0.002, 0.01, 2).Err()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
info, err := client.CMSInfo(ctx, "testcms1").Result()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(info).To(BeAssignableToTypeOf(redis.CMSInfo{}))
|
||||
Expect(info.CellSize).To(BeEquivalentTo(int64(2)))
|
||||
})
|
||||
|
||||
It("should reject invalid cell size without calling the server", Label("cms", "cmsinitbydim", "cmsinitbyprob"), func() {
|
||||
err := client.CMSInitByDimCellSize(ctx, "testcms1", 5, 10, 3).Err()
|
||||
Expect(err).To(MatchError("redis: invalid cell size (must be 1, 2, 4 or 8)"))
|
||||
|
||||
err = client.CMSInitByProbCellSize(ctx, "testcms1", 0.002, 0.01, 0).Err()
|
||||
Expect(err).To(MatchError("redis: invalid cell size (must be 1, 2, 4 or 8)"))
|
||||
|
||||
exists, err := client.Exists(ctx, "testcms1").Result()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(exists).To(BeEquivalentTo(int64(0)))
|
||||
})
|
||||
|
||||
It("should CMSMerge, CMSMergeWithWeight and CMSQuery", Label("cms", "cmsmerge", "cmsquery", "NonRedisEnterprise"), func() {
|
||||
err := client.CMSMerge(ctx, "destCms1", "testcms2", "testcms3").Err()
|
||||
Expect(err).To(HaveOccurred())
|
||||
|
||||
Reference in New Issue
Block a user