del in cluster

This commit is contained in:
finley
2025-03-23 22:09:43 +08:00
parent afd06103cc
commit efb6dd04b7
2 changed files with 108 additions and 0 deletions

69
cluster/commands/del.go Normal file
View File

@@ -0,0 +1,69 @@
package commands
import (
"github.com/hdt3213/godis/cluster/core"
"github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/protocol"
)
func init() {
core.RegisterCmd("del_", execDelInLocal)
core.RegisterCmd("del", execDel)
}
func execDelInLocal(cluster *core.Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply {
if len(cmdLine) < 2 {
return protocol.MakeArgNumErrReply("del")
}
cmdLine[0] = []byte("del")
return cluster.LocalExec(c, cmdLine)
}
func execDel(cluster *core.Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply {
if len(cmdLine) < 2 {
return protocol.MakeArgNumErrReply("del")
}
var keys []string
keyValues := make(map[string][]byte)
for i := 1; i < len(cmdLine); i++ {
key := string(cmdLine[i])
keys = append(keys, key)
}
routeMap := getRouteMap(cluster, keys)
if len(routeMap) == 1 {
// only one node, do it fast
for node := range routeMap {
cmdLine[0] = []byte("del_")
return cluster.Relay(node, c, cmdLine)
}
}
// tcc
cmdLineMap := make(map[string]CmdLine)
for node, keys := range routeMap {
nodeCmdLine := utils.ToCmdLine("del")
for _, key := range keys {
val := keyValues[key]
nodeCmdLine = append(nodeCmdLine, []byte(key), val)
}
cmdLineMap[node] = nodeCmdLine
}
tx := &TccTx{
rawCmdLine: cmdLine,
routeMap: routeMap,
cmdLines: cmdLineMap,
}
results, err := doTcc(cluster, c, tx)
if err != nil {
return err
}
var count int64 = 0
for _, res := range results {
res2, ok := res.(*protocol.IntReply)
if ok {
count += res2.Code
}
}
return protocol.MakeIntReply(count)
}

View File

@@ -0,0 +1,39 @@
package commands
import (
"testing"
"github.com/hdt3213/godis/cluster/core"
"github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/connection"
"github.com/hdt3213/godis/redis/protocol/asserts"
)
func TestDel(t *testing.T) {
id1 := "1"
id2 := "2"
nodes := core.MakeTestCluster([]string{id1, id2})
node1 := nodes[id1]
c := connection.NewFakeConn()
core.RegisterDefaultCmd("set")
core.RegisterDefaultCmd("exists")
node1.Exec(c, utils.ToCmdLine("set", "1", "1"))
node1.Exec(c, utils.ToCmdLine("set", "2", "2"))
// 1, 2 will be routed to node1 and node2, see MakeTestCluster
res := execDel(node1, c, utils.ToCmdLine("del", "1", "2"))
asserts.AssertIntReply(t, res, 2)
res = node1.Exec(c, utils.ToCmdLine("exists", "1"))
asserts.AssertIntReply(t, res, 0)
res = node1.Exec(c, utils.ToCmdLine("exists", "2"))
asserts.AssertIntReply(t, res, 0)
// in one node
node1.Exec(c, utils.ToCmdLine("set", "3", "3"))
res = execDel(node1, c, utils.ToCmdLine("del", "3"))
asserts.AssertIntReply(t, res, 1)
res = node1.Exec(c, utils.ToCmdLine("exists", "3"))
asserts.AssertIntReply(t, res, 0)
}