diff --git a/core/stores/redis/redis.go b/core/stores/redis/redis.go index 6adafd42..e188104a 100644 --- a/core/stores/redis/redis.go +++ b/core/stores/redis/redis.go @@ -501,6 +501,20 @@ func (s *Redis) Hvals(key string) (val []string, err error) { return } +func (s *Redis) Hscan(key string, cursor uint64, match string, count int64) (keys []string, cur uint64, err error) { + err = s.brk.DoWithAcceptable(func() error { + conn, err := getRedis(s) + if err != nil { + return err + } + + keys, cur, err = conn.HScan(key, cursor, match, count).Result() + return err + }, acceptable) + + return +} + func (s *Redis) Incr(key string) (val int64, err error) { err = s.brk.DoWithAcceptable(func() error { conn, err := getRedis(s) diff --git a/core/stores/redis/redis_test.go b/core/stores/redis/redis_test.go index 7bd10764..b2dd8477 100644 --- a/core/stores/redis/redis_test.go +++ b/core/stores/redis/redis_test.go @@ -3,6 +3,7 @@ package redis import ( "errors" "io" + "strconv" "testing" "time" @@ -158,6 +159,38 @@ func TestRedis_Hmset(t *testing.T) { }) } +func TestRedis_Hscan(t *testing.T) { + runOnRedis(t, func(client *Redis) { + key := "hash:test" + fieldsAndValues := make(map[string]string) + for i := 0; i < 1550; i++ { + fieldsAndValues["filed_" + strconv.Itoa(i)] = randomStr(i) + } + err := client.Hmset(key, fieldsAndValues) + assert.Nil(t, err) + + var cursor uint64 = 0 + sum := 0 + for { + _, _, err := NewRedis(client.Addr, "").Hscan(key, cursor, "*", 100) + assert.NotNil(t, err) + reMap, next, err := client.Hscan(key, cursor, "*", 100) + assert.Nil(t, err) + sum += len(reMap) + if next == 0 { + break + } + cursor = next + } + + assert.Equal(t, sum, 3100) + _, err = NewRedis(client.Addr, "").Del(key) + assert.NotNil(t, err) + _, err = client.Del(key) + assert.Nil(t, err) + }) +} + func TestRedis_Incr(t *testing.T) { runOnRedis(t, func(client *Redis) { _, err := NewRedis(client.Addr, "").Incr("a")