add zset withsocre float (#2689)

* add zset withsocre float

* update

* add IncrbyFloat,HincrbyFloat

Co-authored-by: Kevin Wan <wanjunfeng@gmail.com>
master
Alonexy 2 years ago committed by GitHub
parent 4d7fa08b0b
commit 00ff50c2cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -42,6 +42,10 @@ type (
Score int64 Score int64
} }
PairFloat struct {
Key string
Score float64
}
// Redis defines a redis node/cluster. It is thread-safe. // Redis defines a redis node/cluster. It is thread-safe.
Redis struct { Redis struct {
Addr string Addr string
@ -786,6 +790,28 @@ func (s *Redis) HincrbyCtx(ctx context.Context, key, field string, increment int
return return
} }
// HincrbyFloat is the implementation of redis hincrby command.
func (s *Redis) HincrbyFloat(key, field string, increment float64) (float64, error) {
return s.HincrbyFloatCtx(context.Background(), key, field, increment)
}
// HincrbyFloatCtx is the implementation of redis hincrby command.
func (s *Redis) HincrbyFloatCtx(ctx context.Context, key, field string, increment float64) (val float64, err error) {
err = s.brk.DoWithAcceptable(func() error {
conn, err := getRedis(s)
if err != nil {
return err
}
val, err = conn.HIncrByFloat(ctx, key, field, increment).Result()
if err != nil {
return err
}
return nil
}, acceptable)
return
}
// Hkeys is the implementation of redis hkeys command. // Hkeys is the implementation of redis hkeys command.
func (s *Redis) Hkeys(key string) ([]string, error) { func (s *Redis) Hkeys(key string) ([]string, error) {
return s.HkeysCtx(context.Background(), key) return s.HkeysCtx(context.Background(), key)
@ -976,7 +1002,6 @@ func (s *Redis) IncrCtx(ctx context.Context, key string) (val int64, err error)
return return
} }
// Incrby is the implementation of redis incrby command. // Incrby is the implementation of redis incrby command.
func (s *Redis) Incrby(key string, increment int64) (int64, error) { func (s *Redis) Incrby(key string, increment int64) (int64, error) {
return s.IncrbyCtx(context.Background(), key, increment) return s.IncrbyCtx(context.Background(), key, increment)
@ -996,7 +1021,25 @@ func (s *Redis) IncrbyCtx(ctx context.Context, key string, increment int64) (val
return return
} }
// Incrby is the implementation of redis incrby command.
func (s *Redis) IncrbyFloat(key string, increment float64) (float64, error) {
return s.IncrbyFloatCtx(context.Background(), key, increment)
}
// IncrbyFloatCtx is the implementation of redis incrby command.
func (s *Redis) IncrbyFloatCtx(ctx context.Context, key string, increment float64) (val float64, err error) {
err = s.brk.DoWithAcceptable(func() error {
conn, err := getRedis(s)
if err != nil {
return err
}
val, err = conn.IncrByFloat(ctx, key, increment).Result()
return err
}, acceptable)
return
}
// Keys is the implementation of redis keys command. // Keys is the implementation of redis keys command.
func (s *Redis) Keys(pattern string) ([]string, error) { func (s *Redis) Keys(pattern string) ([]string, error) {
return s.KeysCtx(context.Background(), pattern) return s.KeysCtx(context.Background(), pattern)
@ -2017,6 +2060,25 @@ func (s *Redis) ZscoreCtx(ctx context.Context, key, value string) (val int64, er
return return
} }
// ZscoreByFloat is the implementation of redis zscore command score by float.
func (s *Redis) ZscoreByFloat(key, value string) (float64, error) {
return s.ZscoreByFloatCtx(context.Background(), key, value)
}
// ZscoreByFloatCtx is the implementation of redis zscore command score by float.
func (s *Redis) ZscoreByFloatCtx(ctx context.Context, key, value string) (val float64, err error) {
err = s.brk.DoWithAcceptable(func() error {
conn, err := getRedis(s)
if err != nil {
return err
}
val, err = conn.ZScore(ctx, key, value).Result()
return err
}, acceptable)
return
}
// Zscan is the implementation of redis zscan command. // Zscan is the implementation of redis zscan command.
func (s *Redis) Zscan(key string, cursor uint64, match string, count int64) ( func (s *Redis) Zscan(key string, cursor uint64, match string, count int64) (
keys []string, cur uint64, err error) { keys []string, cur uint64, err error) {
@ -2184,6 +2246,32 @@ func (s *Redis) ZrangeWithScoresCtx(ctx context.Context, key string, start, stop
return return
} }
// ZrangeWithScoresByFloat is the implementation of redis zrange command with scores by float64.
func (s *Redis) ZrangeWithScoresByFloat(key string, start, stop int64) ([]PairFloat, error) {
return s.ZrangeWithScoresByFloatCtx(context.Background(), key, start, stop)
}
// ZrangeWithScoresByFloatCtx is the implementation of redis zrange command with scores by float64.
func (s *Redis) ZrangeWithScoresByFloatCtx(ctx context.Context, key string, start, stop int64) (
val []PairFloat, err error) {
err = s.brk.DoWithAcceptable(func() error {
conn, err := getRedis(s)
if err != nil {
return err
}
v, err := conn.ZRangeWithScores(ctx, key, start, stop).Result()
if err != nil {
return err
}
val = toPairsByFloat(v)
return nil
}, acceptable)
return
}
// ZRevRangeWithScores is the implementation of redis zrevrange command with scores. // ZRevRangeWithScores is the implementation of redis zrevrange command with scores.
func (s *Redis) ZRevRangeWithScores(key string, start, stop int64) ([]Pair, error) { func (s *Redis) ZRevRangeWithScores(key string, start, stop int64) ([]Pair, error) {
return s.ZRevRangeWithScoresCtx(context.Background(), key, start, stop) return s.ZRevRangeWithScoresCtx(context.Background(), key, start, stop)
@ -2210,6 +2298,32 @@ func (s *Redis) ZRevRangeWithScoresCtx(ctx context.Context, key string, start, s
return return
} }
// ZRevRangeWithScoresByFloat is the implementation of redis zrevrange command with scores by float.
func (s *Redis) ZRevRangeWithScoresByFloat(key string, start, stop int64) ([]PairFloat, error) {
return s.ZRevRangeWithScoresByFloatCtx(context.Background(), key, start, stop)
}
// ZRevRangeWithScoresByFloatCtx is the implementation of redis zrevrange command with scores by float.
func (s *Redis) ZRevRangeWithScoresByFloatCtx(ctx context.Context, key string, start, stop int64) (
val []PairFloat, err error) {
err = s.brk.DoWithAcceptable(func() error {
conn, err := getRedis(s)
if err != nil {
return err
}
v, err := conn.ZRevRangeWithScores(ctx, key, start, stop).Result()
if err != nil {
return err
}
val = toPairsByFloat(v)
return nil
}, acceptable)
return
}
// ZrangebyscoreWithScores is the implementation of redis zrangebyscore command with scores. // ZrangebyscoreWithScores is the implementation of redis zrangebyscore command with scores.
func (s *Redis) ZrangebyscoreWithScores(key string, start, stop int64) ([]Pair, error) { func (s *Redis) ZrangebyscoreWithScores(key string, start, stop int64) ([]Pair, error) {
return s.ZrangebyscoreWithScoresCtx(context.Background(), key, start, stop) return s.ZrangebyscoreWithScoresCtx(context.Background(), key, start, stop)
@ -2239,6 +2353,35 @@ func (s *Redis) ZrangebyscoreWithScoresCtx(ctx context.Context, key string, star
return return
} }
// ZrangebyscoreWithScoresByFloat is the implementation of redis zrangebyscore command with scores by float.
func (s *Redis) ZrangebyscoreWithScoresByFloat(key string, start, stop float64) ([]PairFloat, error) {
return s.ZrangebyscoreWithScoresByFloatCtx(context.Background(), key, start, stop)
}
// ZrangebyscoreWithScoresByFloatCtx is the implementation of redis zrangebyscore command with scores by float.
func (s *Redis) ZrangebyscoreWithScoresByFloatCtx(ctx context.Context, key string, start, stop float64) (
val []PairFloat, err error) {
err = s.brk.DoWithAcceptable(func() error {
conn, err := getRedis(s)
if err != nil {
return err
}
v, err := conn.ZRangeByScoreWithScores(ctx, key, &red.ZRangeBy{
Min: fmt.Sprintf("%v", start),
Max: fmt.Sprintf("%v", stop),
}).Result()
if err != nil {
return err
}
val = toPairsByFloat(v)
return nil
}, acceptable)
return
}
// ZrangebyscoreWithScoresAndLimit is the implementation of redis zrangebyscore command // ZrangebyscoreWithScoresAndLimit is the implementation of redis zrangebyscore command
// with scores and limit. // with scores and limit.
func (s *Redis) ZrangebyscoreWithScoresAndLimit(key string, start, stop int64, func (s *Redis) ZrangebyscoreWithScoresAndLimit(key string, start, stop int64,
@ -2277,6 +2420,44 @@ func (s *Redis) ZrangebyscoreWithScoresAndLimitCtx(ctx context.Context, key stri
return return
} }
// ZrangebyscoreWithScoresByFloatAndLimit is the implementation of redis zrangebyscore command
// with scores by float and limit.
func (s *Redis) ZrangebyscoreWithScoresByFloatAndLimit(key string, start, stop float64,
page, size int) ([]PairFloat, error) {
return s.ZrangebyscoreWithScoresByFloatAndLimitCtx(context.Background(), key, start, stop, page, size)
}
// ZrangebyscoreWithScoresByFloatAndLimitCtx is the implementation of redis zrangebyscore command
// with scores by float and limit.
func (s *Redis) ZrangebyscoreWithScoresByFloatAndLimitCtx(ctx context.Context, key string, start,
stop float64, page, size int) (val []PairFloat, err error) {
err = s.brk.DoWithAcceptable(func() error {
if size <= 0 {
return nil
}
conn, err := getRedis(s)
if err != nil {
return err
}
v, err := conn.ZRangeByScoreWithScores(ctx, key, &red.ZRangeBy{
Min: fmt.Sprintf("%v", start),
Max: fmt.Sprintf("%v", stop),
Offset: int64(page * size),
Count: int64(size),
}).Result()
if err != nil {
return err
}
val = toPairsByFloat(v)
return nil
}, acceptable)
return
}
// Zrevrange is the implementation of redis zrevrange command. // Zrevrange is the implementation of redis zrevrange command.
func (s *Redis) Zrevrange(key string, start, stop int64) ([]string, error) { func (s *Redis) Zrevrange(key string, start, stop int64) ([]string, error) {
return s.ZrevrangeCtx(context.Background(), key, start, stop) return s.ZrevrangeCtx(context.Background(), key, start, stop)
@ -2327,6 +2508,35 @@ func (s *Redis) ZrevrangebyscoreWithScoresCtx(ctx context.Context, key string, s
return return
} }
// ZrevrangebyscoreWithScoresByFloat is the implementation of redis zrevrangebyscore command with scores by float.
func (s *Redis) ZrevrangebyscoreWithScoresByFloat(key string, start, stop float64) ([]PairFloat, error) {
return s.ZrevrangebyscoreWithScoresByFloatCtx(context.Background(), key, start, stop)
}
// ZrevrangebyscoreWithScoresByFloatCtx is the implementation of redis zrevrangebyscore command with scores by float.
func (s *Redis) ZrevrangebyscoreWithScoresByFloatCtx(ctx context.Context, key string, start, stop float64) (
val []PairFloat, err error) {
err = s.brk.DoWithAcceptable(func() error {
conn, err := getRedis(s)
if err != nil {
return err
}
v, err := conn.ZRevRangeByScoreWithScores(ctx, key, &red.ZRangeBy{
Min: fmt.Sprintf("%v", start),
Max: fmt.Sprintf("%v", stop),
}).Result()
if err != nil {
return err
}
val = toPairsByFloat(v)
return nil
}, acceptable)
return
}
// ZrevrangebyscoreWithScoresAndLimit is the implementation of redis zrevrangebyscore command // ZrevrangebyscoreWithScoresAndLimit is the implementation of redis zrevrangebyscore command
// with scores and limit. // with scores and limit.
func (s *Redis) ZrevrangebyscoreWithScoresAndLimit(key string, start, stop int64, func (s *Redis) ZrevrangebyscoreWithScoresAndLimit(key string, start, stop int64,
@ -2365,6 +2575,44 @@ func (s *Redis) ZrevrangebyscoreWithScoresAndLimitCtx(ctx context.Context, key s
return return
} }
// ZrevrangebyscoreWithScoresByFloatAndLimit is the implementation of redis zrevrangebyscore command
// with scores by float and limit.
func (s *Redis) ZrevrangebyscoreWithScoresByFloatAndLimit(key string, start, stop float64,
page, size int) ([]PairFloat, error) {
return s.ZrevrangebyscoreWithScoresByFloatAndLimitCtx(context.Background(), key, start, stop, page, size)
}
// ZrevrangebyscoreWithScoresByFloatAndLimitCtx is the implementation of redis zrevrangebyscore command
// with scores by float and limit.
func (s *Redis) ZrevrangebyscoreWithScoresByFloatAndLimitCtx(ctx context.Context, key string,
start, stop float64, page, size int) (val []PairFloat, err error) {
err = s.brk.DoWithAcceptable(func() error {
if size <= 0 {
return nil
}
conn, err := getRedis(s)
if err != nil {
return err
}
v, err := conn.ZRevRangeByScoreWithScores(ctx, key, &red.ZRangeBy{
Min: fmt.Sprintf("%v", start),
Max: fmt.Sprintf("%v", stop),
Offset: int64(page * size),
Count: int64(size),
}).Result()
if err != nil {
return err
}
val = toPairsByFloat(v)
return nil
}, acceptable)
return
}
// Zrevrank is the implementation of redis zrevrank command. // Zrevrank is the implementation of redis zrevrank command.
func (s *Redis) Zrevrank(key, field string) (int64, error) { func (s *Redis) Zrevrank(key, field string) (int64, error) {
return s.ZrevrankCtx(context.Background(), key, field) return s.ZrevrankCtx(context.Background(), key, field)
@ -2465,7 +2713,24 @@ func toPairs(vals []red.Z) []Pair {
} }
return pairs return pairs
} }
func toPairsByFloat(vals []red.Z) []PairFloat {
pairs := make([]PairFloat, len(vals))
for i, val := range vals {
switch member := val.Member.(type) {
case string:
pairs[i] = PairFloat{
Key: member,
Score: val.Score,
}
default:
pairs[i] = PairFloat{
Key: mapping.Repr(val.Member),
Score: val.Score,
}
}
}
return pairs
}
func toStrings(vals []interface{}) []string { func toStrings(vals []interface{}) []string {
ret := make([]string, len(vals)) ret := make([]string, len(vals))
for i, val := range vals { for i, val := range vals {

@ -1008,6 +1008,111 @@ func TestRedis_SortedSet(t *testing.T) {
}) })
} }
func TestRedis_SortedSetByFloat64(t *testing.T) {
runOnRedis(t, func(client *Redis) {
ok, err := client.ZaddFloat("key", 10.345, "value1")
assert.Nil(t, err)
assert.True(t, ok)
val, err := client.ZscoreByFloat("key", "value1")
assert.Nil(t, err)
assert.Equal(t, 10.345, val)
_, _ = client.ZaddFloat("key", 10.346, "value2")
_, err = New(client.Addr, badType()).ZRevRangeWithScoresByFloat("key", 0, -1)
assert.NotNil(t, err)
pairs, err := client.ZRevRangeWithScoresByFloat("key", 0, -1)
assert.Nil(t, err)
assert.EqualValues(t, []PairFloat{
{
Key: "value2",
Score: 10.346,
},
{
Key: "value1",
Score: 10.345,
},
}, pairs)
pairs, err = client.ZrangeWithScoresByFloat("key", 0, -1)
assert.Nil(t, err)
assert.EqualValues(t, []PairFloat{
{
Key: "value1",
Score: 10.345,
},
{
Key: "value2",
Score: 10.346,
},
}, pairs)
_, err = New(client.Addr, badType()).ZrangebyscoreWithScoresByFloat("key", 0, 20)
assert.NotNil(t, err)
pairs, err = client.ZrangebyscoreWithScoresByFloat("key", 0,20)
assert.Nil(t, err)
assert.EqualValues(t, []PairFloat{
{
Key: "value1",
Score: 10.345,
},
{
Key: "value2",
Score: 10.346,
},
}, pairs)
_, err = New(client.Addr, badType()).ZrangebyscoreWithScoresByFloatAndLimit(
"key", 10.1, 12.2, 1, 1)
assert.NotNil(t, err)
pairs, err = client.ZrangebyscoreWithScoresByFloatAndLimit("key", 10.1, 12.2, 1, 1)
assert.Nil(t, err)
assert.EqualValues(t, []PairFloat{
{
Key: "value2",
Score: 10.346,
},
}, pairs)
_, err = New(client.Addr, badType()).ZrevrangebyscoreWithScoresByFloat("key", 10, 12)
assert.NotNil(t, err)
pairs, err = client.ZrevrangebyscoreWithScoresByFloat("key", 10, 12)
assert.Nil(t, err)
assert.EqualValues(t, []PairFloat{
{
Key: "value2",
Score: 10.346,
},
{
Key: "value1",
Score: 10.345,
},
}, pairs)
_, err = New(client.Addr, badType()).ZrevrangebyscoreWithScoresByFloatAndLimit(
"key", 10, 12, 1, 1)
assert.NotNil(t, err)
pairs, err = client.ZrevrangebyscoreWithScoresByFloatAndLimit("key", 10, 12, 1, 1)
assert.Nil(t, err)
assert.EqualValues(t, []PairFloat{
{
Key: "value1",
Score: 10.345,
},
}, pairs)
})
}
func TestRedis_IncrbyFloat(t *testing.T) {
runOnRedis(t, func(client *Redis) {
incrVal, err := client.IncrbyFloat("key", 0.002)
assert.Nil(t, err)
assert.Equal(t, 0.002,incrVal)
incrVal2, err := client.IncrbyFloat("key", -0.001)
assert.Nil(t, err)
assert.Equal(t, 0.001,incrVal2)
hincrVal ,err := client.HincrbyFloat("hkey","i",0.002)
assert.Nil(t, err)
assert.Equal(t, 0.002,hincrVal)
hincrVal2 ,err := client.HincrbyFloat("hkey","i",-0.001)
assert.Nil(t, err)
assert.Equal(t, 0.001,hincrVal2)
})
}
func TestRedis_Pipelined(t *testing.T) { func TestRedis_Pipelined(t *testing.T) {
runOnRedis(t, func(client *Redis) { runOnRedis(t, func(client *Redis) {
assert.NotNil(t, New(client.Addr, badType()).Pipelined(func(pipeliner Pipeliner) error { assert.NotNil(t, New(client.Addr, badType()).Pipelined(func(pipeliner Pipeliner) error {

Loading…
Cancel
Save