mirror of
https://github.com/HDT3213/godis.git
synced 2025-10-10 11:10:57 +08:00
optimize multi LPop and RPop
This commit is contained in:
@@ -152,16 +152,14 @@ func undoLPop(db *DB, args [][]byte) []CmdLine {
|
|||||||
if count > list.Len() {
|
if count > list.Len() {
|
||||||
count = list.Len()
|
count = list.Len()
|
||||||
}
|
}
|
||||||
|
elements := make([][]byte, count)
|
||||||
vals := list.Range(0, count)
|
vals := list.Range(0, count)
|
||||||
var cmds []CmdLine
|
for i := 0; i < count; i++ {
|
||||||
for i := len(vals) - 1; i >= 0; i-- {
|
elements[count-i-1] = vals[i].([]byte)
|
||||||
cmds = append(cmds, CmdLine{
|
|
||||||
lPushCmd,
|
|
||||||
args[0],
|
|
||||||
vals[i].([]byte),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return cmds
|
cmd := CmdLine{lPushCmd, args[0]}
|
||||||
|
cmd = append(cmd, elements...)
|
||||||
|
return []CmdLine{cmd}
|
||||||
}
|
}
|
||||||
element, _ := list.Get(0).([]byte)
|
element, _ := list.Get(0).([]byte)
|
||||||
return []CmdLine{
|
return []CmdLine{
|
||||||
@@ -456,16 +454,14 @@ func undoRPop(db *DB, args [][]byte) []CmdLine {
|
|||||||
if count > list.Len() {
|
if count > list.Len() {
|
||||||
count = list.Len()
|
count = list.Len()
|
||||||
}
|
}
|
||||||
|
elements := make([][]byte, count)
|
||||||
vals := list.Range(list.Len()-count, list.Len())
|
vals := list.Range(list.Len()-count, list.Len())
|
||||||
var cmds []CmdLine
|
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
cmds = append(cmds, CmdLine{
|
elements[i] = vals[i].([]byte)
|
||||||
rPushCmd,
|
|
||||||
args[0],
|
|
||||||
vals[i].([]byte),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return cmds
|
cmd := CmdLine{rPushCmd, args[0]}
|
||||||
|
cmd = append(cmd, elements...)
|
||||||
|
return []CmdLine{cmd}
|
||||||
}
|
}
|
||||||
element, _ := list.Get(list.Len() - 1).([]byte)
|
element, _ := list.Get(list.Len() - 1).([]byte)
|
||||||
return []CmdLine{
|
return []CmdLine{
|
||||||
|
@@ -496,24 +496,47 @@ func TestUndoLPush(t *testing.T) {
|
|||||||
func TestUndoLPop(t *testing.T) {
|
func TestUndoLPop(t *testing.T) {
|
||||||
testDB.Flush()
|
testDB.Flush()
|
||||||
key := utils.RandString(10)
|
key := utils.RandString(10)
|
||||||
value := utils.RandString(10)
|
size := 10
|
||||||
testDB.Exec(nil, utils.ToCmdLine("lpush", key, value, value))
|
values := make([]string, size)
|
||||||
|
pushArgs := []string{key}
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
values[i] = utils.RandString(10)
|
||||||
|
pushArgs = append(pushArgs, values[i])
|
||||||
|
}
|
||||||
|
testDB.Exec(nil, utils.ToCmdLine2("lpush", pushArgs...))
|
||||||
|
result0 := testDB.Exec(nil, utils.ToCmdLine("lrange", key, strconv.Itoa(0), strconv.Itoa(size)))
|
||||||
|
|
||||||
|
// test single lpop
|
||||||
cmdLine := utils.ToCmdLine("lpop", key)
|
cmdLine := utils.ToCmdLine("lpop", key)
|
||||||
undoCmdLines := undoLPop(testDB, cmdLine[1:])
|
undoCmdLines := undoLPop(testDB, cmdLine[1:])
|
||||||
testDB.Exec(nil, cmdLine)
|
testDB.Exec(nil, cmdLine)
|
||||||
for _, cmdLine := range undoCmdLines {
|
|
||||||
testDB.Exec(nil, cmdLine)
|
|
||||||
}
|
|
||||||
result := testDB.Exec(nil, utils.ToCmdLine("llen", key))
|
result := testDB.Exec(nil, utils.ToCmdLine("llen", key))
|
||||||
asserts.AssertIntReply(t, result, 2)
|
asserts.AssertIntReply(t, result, 9)
|
||||||
cmdLine = utils.ToCmdLine("lpop", key, strconv.Itoa(2))
|
|
||||||
undoCmdLines = undoRPop(testDB, cmdLine[1:])
|
|
||||||
testDB.Exec(nil, cmdLine)
|
|
||||||
for _, cmdLine := range undoCmdLines {
|
for _, cmdLine := range undoCmdLines {
|
||||||
testDB.Exec(nil, cmdLine)
|
testDB.Exec(nil, cmdLine)
|
||||||
}
|
}
|
||||||
result = testDB.Exec(nil, utils.ToCmdLine("llen", key))
|
result = testDB.Exec(nil, utils.ToCmdLine("llen", key))
|
||||||
asserts.AssertIntReply(t, result, 2)
|
asserts.AssertIntReply(t, result, size)
|
||||||
|
result = testDB.Exec(nil, utils.ToCmdLine("lrange", key, strconv.Itoa(0), strconv.Itoa(size)))
|
||||||
|
if !utils.Equals(result0.ToBytes(), result.ToBytes()) {
|
||||||
|
t.Errorf("expected %s, actually %s", result0.ToBytes(), result.ToBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// test multi lpop
|
||||||
|
cmdLine = utils.ToCmdLine("lpop", key, strconv.Itoa(size))
|
||||||
|
undoCmdLines = undoLPop(testDB, cmdLine[1:])
|
||||||
|
testDB.Exec(nil, cmdLine)
|
||||||
|
result = testDB.Exec(nil, utils.ToCmdLine("llen", key))
|
||||||
|
asserts.AssertIntReply(t, result, 0)
|
||||||
|
for _, cmdLine := range undoCmdLines {
|
||||||
|
testDB.Exec(nil, cmdLine)
|
||||||
|
}
|
||||||
|
result = testDB.Exec(nil, utils.ToCmdLine("llen", key))
|
||||||
|
asserts.AssertIntReply(t, result, size)
|
||||||
|
result = testDB.Exec(nil, utils.ToCmdLine("lrange", key, strconv.Itoa(0), strconv.Itoa(size)))
|
||||||
|
if !utils.Equals(result0.ToBytes(), result.ToBytes()) {
|
||||||
|
t.Errorf("expected %s, actually %s", result0.ToBytes(), result.ToBytes())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUndoLSet(t *testing.T) {
|
func TestUndoLSet(t *testing.T) {
|
||||||
@@ -535,24 +558,47 @@ func TestUndoLSet(t *testing.T) {
|
|||||||
func TestUndoRPop(t *testing.T) {
|
func TestUndoRPop(t *testing.T) {
|
||||||
testDB.Flush()
|
testDB.Flush()
|
||||||
key := utils.RandString(10)
|
key := utils.RandString(10)
|
||||||
value := utils.RandString(10)
|
size := 10
|
||||||
testDB.Exec(nil, utils.ToCmdLine("rpush", key, value, value))
|
values := make([]string, size)
|
||||||
|
pushArgs := []string{key}
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
values[i] = utils.RandString(10)
|
||||||
|
pushArgs = append(pushArgs, values[i])
|
||||||
|
}
|
||||||
|
testDB.Exec(nil, utils.ToCmdLine2("rpush", pushArgs...))
|
||||||
|
result0 := testDB.Exec(nil, utils.ToCmdLine("lrange", key, strconv.Itoa(0), strconv.Itoa(size)))
|
||||||
|
|
||||||
|
// test single rpop
|
||||||
cmdLine := utils.ToCmdLine("rpop", key)
|
cmdLine := utils.ToCmdLine("rpop", key)
|
||||||
undoCmdLines := undoRPop(testDB, cmdLine[1:])
|
undoCmdLines := undoRPop(testDB, cmdLine[1:])
|
||||||
testDB.Exec(nil, cmdLine)
|
testDB.Exec(nil, cmdLine)
|
||||||
for _, cmdLine := range undoCmdLines {
|
|
||||||
testDB.Exec(nil, cmdLine)
|
|
||||||
}
|
|
||||||
result := testDB.Exec(nil, utils.ToCmdLine("llen", key))
|
result := testDB.Exec(nil, utils.ToCmdLine("llen", key))
|
||||||
asserts.AssertIntReply(t, result, 2)
|
asserts.AssertIntReply(t, result, 9)
|
||||||
cmdLine = utils.ToCmdLine("rpop", key, strconv.Itoa(2))
|
|
||||||
undoCmdLines = undoRPop(testDB, cmdLine[1:])
|
|
||||||
testDB.Exec(nil, cmdLine)
|
|
||||||
for _, cmdLine := range undoCmdLines {
|
for _, cmdLine := range undoCmdLines {
|
||||||
testDB.Exec(nil, cmdLine)
|
testDB.Exec(nil, cmdLine)
|
||||||
}
|
}
|
||||||
result = testDB.Exec(nil, utils.ToCmdLine("llen", key))
|
result = testDB.Exec(nil, utils.ToCmdLine("llen", key))
|
||||||
asserts.AssertIntReply(t, result, 2)
|
asserts.AssertIntReply(t, result, size)
|
||||||
|
result = testDB.Exec(nil, utils.ToCmdLine("lrange", key, strconv.Itoa(0), strconv.Itoa(size)))
|
||||||
|
if !utils.Equals(result0.ToBytes(), result.ToBytes()) {
|
||||||
|
t.Errorf("expected %s, actually %s", result0.ToBytes(), result.ToBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// test multi rpop
|
||||||
|
cmdLine = utils.ToCmdLine("rpop", key, strconv.Itoa(size))
|
||||||
|
undoCmdLines = undoRPop(testDB, cmdLine[1:])
|
||||||
|
testDB.Exec(nil, cmdLine)
|
||||||
|
result = testDB.Exec(nil, utils.ToCmdLine("llen", key))
|
||||||
|
asserts.AssertIntReply(t, result, 0)
|
||||||
|
for _, cmdLine := range undoCmdLines {
|
||||||
|
testDB.Exec(nil, cmdLine)
|
||||||
|
}
|
||||||
|
result = testDB.Exec(nil, utils.ToCmdLine("llen", key))
|
||||||
|
asserts.AssertIntReply(t, result, size)
|
||||||
|
result = testDB.Exec(nil, utils.ToCmdLine("lrange", key, strconv.Itoa(0), strconv.Itoa(size)))
|
||||||
|
if !utils.Equals(result0.ToBytes(), result.ToBytes()) {
|
||||||
|
t.Errorf("expected %s, actually %s", result0.ToBytes(), result.ToBytes())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUndoRPopLPush(t *testing.T) {
|
func TestUndoRPopLPush(t *testing.T) {
|
||||||
|
Reference in New Issue
Block a user