Skip to content

Commit

Permalink
feat: 增加 SafeMGet 函数
Browse files Browse the repository at this point in the history
  • Loading branch information
huangqing.zhu committed Jul 25, 2024
1 parent 5eaf1b0 commit ee25aff
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 59 deletions.
9 changes: 4 additions & 5 deletions cmd_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 2 additions & 49 deletions cmd_safe.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,6 @@ import (
)

type SafeCmdable interface {
// SafeMSet
// Available since: 1.0.1
// Time complexity: O(N) where N is the number of keys to set.
// ACL categories: @write @string @slow
// Like MSet, but safe in cluster mode.
// RESP2 / RESP3 Reply:
// - Simple string reply: always OK because MSET can't fail.
SafeMSet(ctx context.Context, values ...any) StatusCmd

// SafeMGet
// Available since: 1.0.0
// Time complexity: O(N) where N is the number of keys to retrieve.
Expand All @@ -25,46 +16,8 @@ type SafeCmdable interface {
SafeMGet(ctx context.Context, keys ...string) SliceCmd
}

func (c *client) SafeMSet(ctx context.Context, values ...any) StatusCmd {
args := argsToSlice(values)
if len(args) <= 2 {
return c.MSet(ctx, values...)
}
var slot2KeyValues = make(map[uint16][]any)
for i := 0; i < len(args); i += 2 {
keySlot := slot(args[i])
slot2KeyValues[keySlot] = append(slot2KeyValues[keySlot], args[i], args[i+1])
}
if len(slot2KeyValues) == 1 {
return c.MSet(ctx, values...)
}

var wg sync.WaitGroup
var mx sync.Mutex
var errStatusCmd StatusCmd
wg.Add(len(slot2KeyValues))
for _, sameSlotKeyValues := range slot2KeyValues {
go func(_values []any) {
ret := c.MSet(context.Background(), _values...)
if err := ret.Err(); err != nil {
mx.Lock()
if errStatusCmd == nil {
errStatusCmd = ret
}
mx.Unlock()
}
wg.Done()
}(sameSlotKeyValues)
}
wg.Wait()

if errStatusCmd != nil {
return errStatusCmd
}
return newOKStatusCmdr()
}

func (c *client) SafeMGet(ctx context.Context, keys ...string) SliceCmd {
ctx = WithSkipCheck(ctx)
if len(keys) <= 1 {
return c.MGet(ctx, keys...)
}
Expand All @@ -84,7 +37,7 @@ func (c *client) SafeMGet(ctx context.Context, keys ...string) SliceCmd {
wg.Add(len(slot2Keys))
for i, sameSlotKeys := range slot2Keys {
go func(_i uint16, _keys []string) {
ret := c.MGet(context.Background(), _keys...)
ret := c.MGet(WithSkipCheck(context.Background()), _keys...)
mx.Lock()
scs[_i] = ret
mx.Unlock()
Expand Down
14 changes: 9 additions & 5 deletions cmd_safe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,27 @@ import (
"testing"
)

func testSafeMSet(ctx context.Context, c Cmdable) []string {
func testSafeMGet(ctx context.Context, c Cmdable) []string {
var key, key1, key2, key3 = "key1:{1}", "key2", "key3", "key4:{1}"
So(slot(key), ShouldNotEqual, slot(key1))
So(slot(key1), ShouldNotEqual, slot(key2))
So(slot(key), ShouldEqual, slot(key3))

mSet := c.SafeMSet(ctx, key, "hello1")
mSet := c.MSet(ctx, key, "hello1")
So(mSet.Err(), ShouldBeNil)
So(mSet.Val(), ShouldEqual, OK)

So(c.Get(ctx, key).Val(), ShouldEqual, "hello1")

mSet = c.SafeMSet(ctx, key, "hello1", key3, "hello4")
mSet = c.MSet(ctx, key3, "hello4")
So(mSet.Err(), ShouldBeNil)
So(mSet.Val(), ShouldEqual, OK)

mSet = c.SafeMSet(ctx, key, "hello1", key1, "hello2", key2, "hello3")
mSet = c.MSet(ctx, key2, "hello3")
So(mSet.Err(), ShouldBeNil)
So(mSet.Val(), ShouldEqual, OK)

mSet = c.MSet(ctx, key1, "hello2")
So(mSet.Err(), ShouldBeNil)
So(mSet.Val(), ShouldEqual, OK)

Expand All @@ -35,7 +39,7 @@ func testSafeMSet(ctx context.Context, c Cmdable) []string {

func safeTestUnits() []TestUnit {
return []TestUnit{
{CommandMSet, testSafeMSet},
{CommandMGet, testSafeMGet},
}
}

Expand Down

0 comments on commit ee25aff

Please sign in to comment.