From 0316b6e10ebb59dd67161337e69a94e624683b83 Mon Sep 17 00:00:00 2001 From: chen quan Date: Wed, 24 Aug 2022 21:02:16 +0800 Subject: [PATCH] feat(redis): add ZaddFloat & ZaddFloatCtx (#2291) --- core/stores/kv/store.go | 12 +++++++- core/stores/kv/store_test.go | 52 ++++++++++++++++----------------- core/stores/redis/redis.go | 13 ++++++++- core/stores/redis/redis_test.go | 12 ++++---- 4 files changed, 55 insertions(+), 34 deletions(-) diff --git a/core/stores/kv/store.go b/core/stores/kv/store.go index f7ee6b42..fcaf07c1 100644 --- a/core/stores/kv/store.go +++ b/core/stores/kv/store.go @@ -110,7 +110,9 @@ type ( Ttl(key string) (int, error) TtlCtx(ctx context.Context, key string) (int, error) Zadd(key string, score int64, value string) (bool, error) + ZaddFloat(key string, score float64, value string) (bool, error) ZaddCtx(ctx context.Context, key string, score int64, value string) (bool, error) + ZaddFloatCtx(ctx context.Context, key string, score float64, value string) (bool, error) Zadds(key string, ps ...redis.Pair) (int64, error) ZaddsCtx(ctx context.Context, key string, ps ...redis.Pair) (int64, error) Zcard(key string) (int, error) @@ -787,13 +789,21 @@ func (cs clusterStore) Zadd(key string, score int64, value string) (bool, error) return cs.ZaddCtx(context.Background(), key, score, value) } +func (cs clusterStore) ZaddFloat(key string, score float64, value string) (bool, error) { + return cs.ZaddFloatCtx(context.Background(), key, score, value) +} + func (cs clusterStore) ZaddCtx(ctx context.Context, key string, score int64, value string) (bool, error) { + return cs.ZaddFloatCtx(ctx, key, float64(score), value) +} + +func (cs clusterStore) ZaddFloatCtx(ctx context.Context, key string, score float64, value string) (bool, error) { node, err := cs.getRedis(key) if err != nil { return false, err } - return node.ZaddCtx(ctx, key, score, value) + return node.ZaddFloatCtx(ctx, key, score, value) } func (cs clusterStore) Zadds(key string, ps ...redis.Pair) (int64, error) { diff --git a/core/stores/kv/store_test.go b/core/stores/kv/store_test.go index 1803d015..96d0e29b 100644 --- a/core/stores/kv/store_test.go +++ b/core/stores/kv/store_test.go @@ -22,7 +22,7 @@ func TestRedis_Decr(t *testing.T) { _, err := store.Decr("a") assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { val, err := client.Decr("a") assert.Nil(t, err) assert.Equal(t, int64(-1), val) @@ -37,7 +37,7 @@ func TestRedis_DecrBy(t *testing.T) { _, err := store.Incrby("a", 2) assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { val, err := client.Decrby("a", 2) assert.Nil(t, err) assert.Equal(t, int64(-2), val) @@ -52,7 +52,7 @@ func TestRedis_Exists(t *testing.T) { _, err := store.Exists("foo") assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { ok, err := client.Exists("a") assert.Nil(t, err) assert.False(t, ok) @@ -68,7 +68,7 @@ func TestRedis_Eval(t *testing.T) { _, err := store.Eval(`redis.call("EXISTS", KEYS[1])`, "key1") assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { _, err := client.Eval(`redis.call("EXISTS", KEYS[1])`, "notexist") assert.Equal(t, redis.Nil, err) err = client.Set("key1", "value1") @@ -88,7 +88,7 @@ func TestRedis_Hgetall(t *testing.T) { _, err = store.Hgetall("a") assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { assert.Nil(t, client.Hset("a", "aa", "aaa")) assert.Nil(t, client.Hset("a", "bb", "bbb")) vals, err := client.Hgetall("a") @@ -105,7 +105,7 @@ func TestRedis_Hvals(t *testing.T) { _, err := store.Hvals("a") assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { assert.Nil(t, client.Hset("a", "aa", "aaa")) assert.Nil(t, client.Hset("a", "bb", "bbb")) vals, err := client.Hvals("a") @@ -119,7 +119,7 @@ func TestRedis_Hsetnx(t *testing.T) { _, err := store.Hsetnx("a", "dd", "ddd") assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { assert.Nil(t, client.Hset("a", "aa", "aaa")) assert.Nil(t, client.Hset("a", "bb", "bbb")) ok, err := client.Hsetnx("a", "bb", "ccc") @@ -141,7 +141,7 @@ func TestRedis_HdelHlen(t *testing.T) { _, err = store.Hlen("a") assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { assert.Nil(t, client.Hset("a", "aa", "aaa")) assert.Nil(t, client.Hset("a", "bb", "bbb")) num, err := client.Hlen("a") @@ -161,7 +161,7 @@ func TestRedis_HIncrBy(t *testing.T) { _, err := store.Hincrby("key", "field", 3) assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { val, err := client.Hincrby("key", "field", 2) assert.Nil(t, err) assert.Equal(t, 2, val) @@ -176,7 +176,7 @@ func TestRedis_Hkeys(t *testing.T) { _, err := store.Hkeys("a") assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { assert.Nil(t, client.Hset("a", "aa", "aaa")) assert.Nil(t, client.Hset("a", "bb", "bbb")) vals, err := client.Hkeys("a") @@ -190,7 +190,7 @@ func TestRedis_Hmget(t *testing.T) { _, err := store.Hmget("a", "aa", "bb") assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { assert.Nil(t, client.Hset("a", "aa", "aaa")) assert.Nil(t, client.Hset("a", "bb", "bbb")) vals, err := client.Hmget("a", "aa", "bb") @@ -209,7 +209,7 @@ func TestRedis_Hmset(t *testing.T) { }) assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { assert.Nil(t, client.Hmset("a", map[string]string{ "aa": "aaa", "bb": "bbb", @@ -225,7 +225,7 @@ func TestRedis_Incr(t *testing.T) { _, err := store.Incr("a") assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { val, err := client.Incr("a") assert.Nil(t, err) assert.Equal(t, int64(1), val) @@ -240,7 +240,7 @@ func TestRedis_IncrBy(t *testing.T) { _, err := store.Incrby("a", 2) assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { val, err := client.Incrby("a", 2) assert.Nil(t, err) assert.Equal(t, int64(2), val) @@ -267,7 +267,7 @@ func TestRedis_List(t *testing.T) { _, err = store.Lindex("key", 0) assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { val, err := client.Lpush("key", "value1", "value2") assert.Nil(t, err) assert.Equal(t, 2, val) @@ -316,7 +316,7 @@ func TestRedis_Persist(t *testing.T) { err = store.Expireat("key", time.Now().Unix()+5) assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { ok, err := client.Persist("key") assert.Nil(t, err) assert.False(t, ok) @@ -348,7 +348,7 @@ func TestRedis_Sscan(t *testing.T) { _, err = store.Del(key) assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { var list []string for i := 0; i < 1550; i++ { list = append(list, stringx.Randn(i)) @@ -390,7 +390,7 @@ func TestRedis_Set(t *testing.T) { _, err = store.Spop("key") assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { num, err := client.Sadd("key", 1, 2, 3, 4) assert.Nil(t, err) assert.Equal(t, 4, num) @@ -434,7 +434,7 @@ func TestRedis_SetGetDel(t *testing.T) { _, err = store.Del("hello") assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { err := client.Set("hello", "world") assert.Nil(t, err) val, err := client.Get("hello") @@ -457,7 +457,7 @@ func TestRedis_SetExNx(t *testing.T) { _, err = store.SetnxEx("newhello", "newworld", 5) assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { err := client.Setex("hello", "world", 5) assert.Nil(t, err) ok, err := client.Setnx("hello", "newworld") @@ -495,7 +495,7 @@ func TestRedis_Getset(t *testing.T) { _, err := store.GetSet("hello", "world") assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { val, err := client.GetSet("hello", "world") assert.Nil(t, err) assert.Equal(t, "", val) @@ -524,7 +524,7 @@ func TestRedis_SetGetDelHashField(t *testing.T) { _, err = store.Hdel("key", "field") assert.NotNil(t, err) - runOnCluster(t, func(client Store) { + runOnCluster(func(client Store) { err := client.Hset("key", "field", "value") assert.Nil(t, err) val, err := client.Hget("key", "field") @@ -587,8 +587,8 @@ func TestRedis_SortedSet(t *testing.T) { }) assert.NotNil(t, err) - runOnCluster(t, func(client Store) { - ok, err := client.Zadd("key", 1, "value1") + runOnCluster(func(client Store) { + ok, err := client.ZaddFloat("key", 1, "value1") assert.Nil(t, err) assert.True(t, ok) ok, err = client.Zadd("key", 2, "value1") @@ -724,7 +724,7 @@ func TestRedis_HyperLogLog(t *testing.T) { _, err = store.Pfcount("key") assert.NotNil(t, err) - runOnCluster(t, func(cluster Store) { + runOnCluster(func(cluster Store) { ok, err := cluster.Pfadd("key", "value") assert.Nil(t, err) assert.True(t, ok) @@ -734,7 +734,7 @@ func TestRedis_HyperLogLog(t *testing.T) { }) } -func runOnCluster(t *testing.T, fn func(cluster Store)) { +func runOnCluster(fn func(cluster Store)) { s1.FlushAll() s2.FlushAll() diff --git a/core/stores/redis/redis.go b/core/stores/redis/redis.go index b31eb874..c4d9c401 100644 --- a/core/stores/redis/redis.go +++ b/core/stores/redis/redis.go @@ -1836,8 +1836,19 @@ func (s *Redis) Zadd(key string, score int64, value string) (bool, error) { return s.ZaddCtx(context.Background(), key, score, value) } +// ZaddFloat is the implementation of redis zadd command. +func (s *Redis) ZaddFloat(key string, score float64, value string) (bool, error) { + return s.ZaddFloatCtx(context.Background(), key, score, value) +} + // ZaddCtx is the implementation of redis zadd command. func (s *Redis) ZaddCtx(ctx context.Context, key string, score int64, value string) ( + val bool, err error) { + return s.ZaddFloatCtx(ctx, key, float64(score), value) +} + +// ZaddFloatCtx is the implementation of redis zadd command. +func (s *Redis) ZaddFloatCtx(ctx context.Context, key string, score float64, value string) ( val bool, err error) { err = s.brk.DoWithAcceptable(func() error { conn, err := getRedis(s) @@ -1846,7 +1857,7 @@ func (s *Redis) ZaddCtx(ctx context.Context, key string, score int64, value stri } v, err := conn.ZAdd(ctx, key, &red.Z{ - Score: float64(score), + Score: score, Member: value, }).Result() if err != nil { diff --git a/core/stores/redis/redis_test.go b/core/stores/redis/redis_test.go index fdf90e71..4f960909 100644 --- a/core/stores/redis/redis_test.go +++ b/core/stores/redis/redis_test.go @@ -810,7 +810,7 @@ func TestRedis_SetGetDelHashField(t *testing.T) { func TestRedis_SortedSet(t *testing.T) { runOnRedis(t, func(client *Redis) { - ok, err := client.Zadd("key", 1, "value1") + ok, err := client.ZaddFloat("key", 1, "value1") assert.Nil(t, err) assert.True(t, ok) ok, err = client.Zadd("key", 2, "value1") @@ -988,8 +988,8 @@ func TestRedis_SortedSet(t *testing.T) { assert.Equal(t, 0, len(pairs)) _, err = New(client.Addr, badType()).Zrevrank("key", "value") assert.NotNil(t, err) - client.Zadd("second", 2, "aa") - client.Zadd("third", 3, "bbb") + _, _ = client.Zadd("second", 2, "aa") + _, _ = client.Zadd("third", 3, "bbb") val, err = client.Zunionstore("union", &ZStore{ Keys: []string{"second", "third"}, Weights: []float64{1, 2}, @@ -1176,7 +1176,7 @@ func runOnRedis(t *testing.T, fn func(client *Redis)) { } if client != nil { - client.Close() + _ = client.Close() } }() fn(New(s.Addr())) @@ -1198,7 +1198,7 @@ func runOnRedisTLS(t *testing.T, fn func(client *Redis)) { t.Error(err) } if client != nil { - client.Close() + _ = client.Close() } }() fn(New(s.Addr(), WithTLS())) @@ -1214,6 +1214,6 @@ type mockedNode struct { RedisNode } -func (n mockedNode) BLPop(ctx context.Context, timeout time.Duration, keys ...string) *red.StringSliceCmd { +func (n mockedNode) BLPop(_ context.Context, _ time.Duration, _ ...string) *red.StringSliceCmd { return red.NewStringSliceCmd(context.Background(), "foo", "bar") }