Skip to content

Commit

Permalink
add tairbloom module (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
bigdaronlee163 authored Sep 1, 2022
1 parent 457613a commit b234af5
Show file tree
Hide file tree
Showing 5 changed files with 375 additions and 2 deletions.
5 changes: 5 additions & 0 deletions tair/arg.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,9 @@ const (
WITHSCORES = "withscores"
LIMIT = "limit"
GT = "gt"

CAPACITY = "CAPACITY"
ERROR = "ERROR"
NOCREATE = "NOCREATE"
ITEMS = "ITEMS"
)
5 changes: 3 additions & 2 deletions tair/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package tair_test

import (
"fmt"
"github.com/alibaba/tair-go/tair"
"github.com/go-redis/redis/v8"
"os"
"time"

"github.com/alibaba/tair-go/tair"
"github.com/go-redis/redis/v8"
)

const (
Expand Down
154 changes: 154 additions & 0 deletions tair/tairbloom.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package tair

import (
"context"

"github.com/go-redis/redis/v8"
)

type BfInsertArgs struct {
arg
capacity int64
errorRate float64
}

func (a *BfInsertArgs) JoinArgs(key string, items ...string) []interface{} {
args := make([]interface{}, 0)
args = append(args, key)
if _, ok := a.Set[NOCREATE]; ok {
args = append(args, NOCREATE)
}
args = append(args, CAPACITY, a.capacity, ERROR, a.errorRate)
args = append(args, ITEMS)
for _, item := range items {
args = append(args, item)
}
return args
}

func (a BfInsertArgs) New() *BfInsertArgs {
a.Set = make(map[string]bool)
return &a
}

func (a *BfInsertArgs) Capacity(initCapacity int64) *BfInsertArgs {
a.Set[CAPACITY] = true
a.capacity = initCapacity
return a
}

func (a *BfInsertArgs) ErrorRate(errorRate float64) *BfInsertArgs {
a.Set[ERROR] = true
a.errorRate = errorRate
return a
}

func (a *BfInsertArgs) NoCreate() *BfInsertArgs {
a.Set[NOCREATE] = true
return a
}

type BfMExistArgs struct {
arg
}

func (a *BfMExistArgs) JoinArgs(key string, items ...string) []interface{} {
args := make([]interface{}, 0)
args = append(args, key)
for _, item := range items {
args = append(args, item)
}
return args
}

func (a BfMExistArgs) New() *BfMExistArgs {
a.Set = make(map[string]bool)
return &a
}

type BfMAddArgs struct {
arg
}

func (a *BfMAddArgs) JoinArgs(key string, items ...string) []interface{} {
args := make([]interface{}, 0)
args = append(args, key)
for _, item := range items {
args = append(args, item)
}
return args
}

func (a BfMAddArgs) New() *BfMAddArgs {
a.Set = make(map[string]bool)
return &a
}

func (tc tairCmdable) BfReserve(ctx context.Context, key string, initCapacity int64, errorRate float64) *redis.StringCmd {
args := make([]interface{}, 4)
args[0] = "BF.RESERVE"
args[1] = key
args[2] = errorRate
args[3] = initCapacity
cmd := redis.NewStringCmd(ctx, args...)
_ = tc(ctx, cmd)
return cmd
}

func (tc tairCmdable) BfAdd(ctx context.Context, key string, item string) *redis.BoolCmd {
args := make([]interface{}, 3)
args[0] = "BF.ADD"
args[1] = key
args[2] = item
cmd := redis.NewBoolCmd(ctx, args...)
_ = tc(ctx, cmd)
return cmd
}

func (tc tairCmdable) BfMAdd(ctx context.Context, key string, items ...string) *redis.BoolSliceCmd {
args := make([]interface{}, 1)
args[0] = "BF.MADD"
a := BfMAddArgs{}.New().JoinArgs(key, items...)
args = append(args, a...)
cmd := redis.NewBoolSliceCmd(ctx, args...)
_ = tc(ctx, cmd)
return cmd
}

func (tc tairCmdable) BfExists(ctx context.Context, key string, item string) *redis.BoolCmd {
args := make([]interface{}, 3)
args[0] = "BF.EXISTS"
args[1] = key
args[2] = item
cmd := redis.NewBoolCmd(ctx, args...)
_ = tc(ctx, cmd)
return cmd
}

func (tc tairCmdable) BfMExists(ctx context.Context, key string, items ...string) *redis.BoolSliceCmd {
args := make([]interface{}, 1)
args[0] = "BF.MEXISTS"
a := BfMExistArgs{}.New().JoinArgs(key, items...)
args = append(args, a...)
cmd := redis.NewBoolSliceCmd(ctx, args...)
_ = tc(ctx, cmd)
return cmd
}

func (tc tairCmdable) BfInsert(ctx context.Context, key string, bfInsertArgs *BfInsertArgs, items ...string) *redis.BoolSliceCmd {
args := make([]interface{}, 1)
args[0] = "BF.INSERT"
args = append(args, bfInsertArgs.JoinArgs(key, items...)...)
cmd := redis.NewBoolSliceCmd(ctx, args...)
_ = tc(ctx, cmd)
return cmd
}

func (tc tairCmdable) BfDebug(ctx context.Context, key string) *redis.StringSliceCmd {
args := make([]interface{}, 2)
args[0] = "BF.DEBUG"
args[1] = key
cmd := redis.NewStringSliceCmd(ctx, args...)
_ = tc(ctx, cmd)
return cmd
}
205 changes: 205 additions & 0 deletions tair/tairbloom_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
package tair_test

import (
"math/rand"
"testing"
"time"

"github.com/alibaba/tair-go/tair"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)

type TairBloomTestSuite struct {
suite.Suite
tairClient *tair.TairClient
}

var randomkey_ string = "randomkey_" + randStr(20)

// var randomKeyBinary_ []byte

var bbf string = "bbf" + randStr(20)

// var bcf []byte

func randStr(size int) string {
str := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
bytes := []byte(str)
var result []byte
rand.Seed(time.Now().UnixNano() + int64(rand.Intn(100000)))
for i := 0; i < size; i++ {
result = append(result, bytes[rand.Intn(len(bytes))])
}
return string(result)
}

func (suite *TairBloomTestSuite) SetupTest() {
suite.tairClient = tair.NewTairClient(redisOptions())
assert.Equal(suite.T(), "OK", suite.tairClient.FlushDB(ctx).Val())
}

func (suite *TairBloomTestSuite) TearDownTest() {
assert.NoError(suite.T(), suite.tairClient.Close())
}

func (suite *TairBloomTestSuite) BeforeTest(suiteName, testName string) {
//fmt.Printf("BeforeTest: suiteName=%s,testName=%s\n", suiteName, testName)
//fmt.Println("dddddddd")
//randomkey_ = "randomkey_" + randStr(20)
////randomKeyBinary_ = []byte("randomKeyBinary_" + randStr(20))
//bbf = "bbf" + randStr(20)
//bcf = []byte("bcf" + randStr(20))
}

func (suite *TairBloomTestSuite) TestBfAdd() {
r1, err1 := suite.tairClient.BfReserve(ctx, bbf, 100, 0.001).Result()
assert.NoError(suite.T(), err1)
assert.Equal(suite.T(), r1, "OK")

r2, err2 := suite.tairClient.BfAdd(ctx, bbf, "val1").Result()
assert.NoError(suite.T(), err2)
assert.Equal(suite.T(), r2, true)

r3, err3 := suite.tairClient.BfExists(ctx, bbf, "val1").Result()
assert.NoError(suite.T(), err3)
assert.Equal(suite.T(), r3, true)

r4, err4 := suite.tairClient.BfExists(ctx, bbf, "val2").Result()
assert.NoError(suite.T(), err4)
assert.Equal(suite.T(), r4, false)
}

func (suite *TairBloomTestSuite) TestBfMAdd() {
r1, err1 := suite.tairClient.BfReserve(ctx, bbf, 100, 0.001).Result()
assert.NoError(suite.T(), err1)
assert.Equal(suite.T(), r1, "OK")

r2, err2 := suite.tairClient.BfMAdd(ctx, bbf, "val1", "val2").Result()
assert.NoError(suite.T(), err2)
assert.Equal(suite.T(), r2[0], true)
assert.Equal(suite.T(), r2[1], true)
}

func (suite *TairBloomTestSuite) TestBfInsert() {
r1, err1 := suite.tairClient.BfReserve(ctx, bbf, 100, 0.001).Result()
assert.NoError(suite.T(), err1)
assert.Equal(suite.T(), r1, "OK")
a := tair.BfInsertArgs{}.New().Capacity(100).ErrorRate(0.001)
r4, err4 := suite.tairClient.BfInsert(ctx, bbf, a, "val1", "val2").Result()
assert.NoError(suite.T(), err4)
assert.Equal(suite.T(), r4[0], true)
assert.Equal(suite.T(), r4[1], true)

r2, err2 := suite.tairClient.BfMAdd(ctx, bbf, "val3", "val4").Result()
assert.NoError(suite.T(), err2)
assert.Equal(suite.T(), r2[0], true)
assert.Equal(suite.T(), r2[1], true)

r3, err3 := suite.tairClient.BfMExists(ctx, bbf, "val3", "val4").Result()
assert.NoError(suite.T(), err3)
assert.Equal(suite.T(), r3[0], true)
assert.Equal(suite.T(), r3[1], true)
a1 := tair.BfInsertArgs{}.New().Capacity(100).ErrorRate(0.001)

b, err := suite.tairClient.BfInsert(ctx, randomkey_, a1, "item1", "item2", "item3", "item4", "item5").Result()
assert.NoError(suite.T(), err)
for _, r := range b {
assert.Equal(suite.T(), r, true)
}

b1, err1 := suite.tairClient.BfMExists(ctx, randomkey_, "item1", "item2", "item3", "item4", "item5").Result()
assert.NoError(suite.T(), err1)
for _, r := range b1 {
assert.Equal(suite.T(), r, true)
}
}

func (suite *TairBloomTestSuite) TestBfCommand() {
r1, err1 := suite.tairClient.BfReserve(ctx, bbf, 100, 0.001).Result()
assert.NoError(suite.T(), err1)
assert.Equal(suite.T(), r1, "OK")

b, err := suite.tairClient.BfAdd(ctx, randomkey_, "item1").Result()
assert.NoError(suite.T(), err)
assert.Equal(suite.T(), b, true)

b2, err2 := suite.tairClient.BfExists(ctx, randomkey_, "item1").Result()
assert.NoError(suite.T(), err2)
assert.Equal(suite.T(), b2, true)

b3, err3 := suite.tairClient.BfExists(ctx, randomkey_, "item2").Result()
assert.NoError(suite.T(), err3)
assert.Equal(suite.T(), b3, false)
}

func (suite *TairBloomTestSuite) TestBfAddException() {
suite.tairClient.BfAdd(ctx, randomkey_, randomkey_)
suite.tairClient.Set(ctx, randomkey_, "bar", 0)
res1, err1 := suite.tairClient.BfAdd(ctx, randomkey_, randomkey_).Result()
assert.Error(suite.T(), err1)
assert.Contains(suite.T(), err1, "WRONGTYPE")
assert.Equal(suite.T(), res1, false)
}

func (suite *TairBloomTestSuite) TestBfMAddException() {
suite.tairClient.BfMAdd(ctx, randomkey_, "item")
suite.tairClient.Set(ctx, randomkey_, "bar", 0)
res1, err1 := suite.tairClient.BfMAdd(ctx, randomkey_, "item").Result()
assert.Error(suite.T(), err1)
assert.Contains(suite.T(), err1, "WRONGTYPE")
for _, r := range res1 {
assert.Equal(suite.T(), r, false)
}
}

func (suite *TairBloomTestSuite) TestBfExistException() {
suite.tairClient.BfExists(ctx, randomkey_, "item")
suite.tairClient.Set(ctx, randomkey_, "bar", 0)
res1, err1 := suite.tairClient.BfExists(ctx, randomkey_, "item").Result()
assert.Error(suite.T(), err1)
assert.Contains(suite.T(), err1, "WRONGTYPE")
assert.Equal(suite.T(), res1, false)
}

func (suite *TairBloomTestSuite) TestBfMExistException() {
suite.tairClient.BfMExists(ctx, randomkey_, "item")
suite.tairClient.Set(ctx, randomkey_, "bar", 0)
res1, err1 := suite.tairClient.BfMExists(ctx, randomkey_, "item").Result()
assert.Error(suite.T(), err1)
assert.Contains(suite.T(), err1, "WRONGTYPE")
for _, r := range res1 {
assert.Equal(suite.T(), r, false)
}
}

func (suite *TairBloomTestSuite) TestBfInsertException() {
suite.tairClient.BfInsert(ctx, randomkey_, tair.BfInsertArgs{}.New(), "item")
suite.tairClient.Set(ctx, randomkey_, "bar", 0)
_, err1 := suite.tairClient.BfInsert(ctx, randomkey_, tair.BfInsertArgs{}.New(), "item").Result()
assert.Error(suite.T(), err1)
assert.Contains(suite.T(), err1, "WRONGTYPE")
}

func (suite *TairBloomTestSuite) TestBfReserveException() {
suite.tairClient.BfReserve(ctx, randomkey_, 1, 0.01)
suite.tairClient.Set(ctx, randomkey_, "bar", 0)
res1, err1 := suite.tairClient.BfReserve(ctx, randomkey_, 1, 0.01).Result()
assert.Error(suite.T(), err1)
assert.Contains(suite.T(), err1, "WRONGTYPE")
for _, r := range res1 {
assert.Equal(suite.T(), r, false)
}
}

func (suite *TairBloomTestSuite) TestBfDebugException() {
suite.tairClient.BfDebug(ctx, randomkey_)
suite.tairClient.Set(ctx, randomkey_, "bar", 0)
_, err1 := suite.tairClient.BfDebug(ctx, randomkey_).Result()
assert.Error(suite.T(), err1)
assert.Contains(suite.T(), err1, "WRONGTYPE")
}

func TestTairBloomTestSuite(t *testing.T) {
suite.Run(t, new(TairBloomTestSuite))
}
8 changes: 8 additions & 0 deletions tair/taircommands.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,12 @@ type TairCmdable interface {
TrSetBitArray(ctx context.Context, key, value string) *redis.FloatCmd
TrJaccard(ctx context.Context, key1, key2 string) *redis.FloatCmd
TrContains(ctx context.Context, key1, key2 string) *redis.BoolCmd
// TairBloom
BfReserve(ctx context.Context, key string, initCapacity int64, errorRate float64) *redis.StringCmd
BfAdd(ctx context.Context, key string, item string) *redis.BoolCmd
BfMAdd(ctx context.Context, key string, items ...string) *redis.BoolSliceCmd
BfExists(ctx context.Context, key string, item string) *redis.BoolCmd
BfMExists(ctx context.Context, key string, items ...string) *redis.BoolSliceCmd
BfInsert(ctx context.Context, key string, bfInsertArgs *BfInsertArgs, items ...string) *redis.BoolSliceCmd
BfDebug(ctx context.Context, key string) *redis.StringSliceCmd
}

0 comments on commit b234af5

Please sign in to comment.