mirror of
https://github.com/HDT3213/godis.git
synced 2025-10-12 20:20:16 +08:00
add zlexcount, zremrangebylex, zrankbylex, zrevrankbylex to zset
This commit is contained in:
@@ -2,13 +2,14 @@ package database
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hdt3213/godis/datastruct/sortedset"
|
||||
"github.com/hdt3213/godis/interface/redis"
|
||||
"github.com/hdt3213/godis/lib/geohash"
|
||||
"github.com/hdt3213/godis/lib/utils"
|
||||
"github.com/hdt3213/godis/redis/protocol"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// execGeoAdd add a location into SortedSet
|
||||
@@ -253,7 +254,7 @@ func geoRadius0(sortedSet *sortedset.SortedSet, lat float64, lng float64, radius
|
||||
for _, area := range areas {
|
||||
lower := &sortedset.ScoreBorder{Value: float64(area[0])}
|
||||
upper := &sortedset.ScoreBorder{Value: float64(area[1])}
|
||||
elements := sortedSet.RangeByScore(lower, upper, 0, -1, true)
|
||||
elements := sortedSet.Range(lower, upper, 0, -1, true)
|
||||
for _, elem := range elements {
|
||||
members = append(members, []byte(elem.Member))
|
||||
}
|
||||
|
@@ -1,13 +1,15 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
SortedSet "github.com/hdt3213/godis/datastruct/sortedset"
|
||||
"github.com/hdt3213/godis/interface/database"
|
||||
"github.com/hdt3213/godis/interface/redis"
|
||||
"github.com/hdt3213/godis/lib/utils"
|
||||
"github.com/hdt3213/godis/redis/protocol"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (db *DB) getAsSortedSet(key string) (*SortedSet.SortedSet, protocol.ErrorReply) {
|
||||
@@ -253,7 +255,7 @@ func range0(db *DB, key string, start int64, stop int64, withScores bool, desc b
|
||||
}
|
||||
|
||||
// assert: start in [0, size - 1], stop in [start, size]
|
||||
slice := sortedSet.Range(start, stop, desc)
|
||||
slice := sortedSet.RangeByRank(start, stop, desc)
|
||||
if withScores {
|
||||
result := make([][]byte, len(slice)*2)
|
||||
i := 0
|
||||
@@ -298,13 +300,13 @@ func execZCount(db *DB, args [][]byte) redis.Reply {
|
||||
return protocol.MakeIntReply(0)
|
||||
}
|
||||
|
||||
return protocol.MakeIntReply(sortedSet.Count(min, max))
|
||||
return protocol.MakeIntReply(sortedSet.RangeCount(min, max))
|
||||
}
|
||||
|
||||
/*
|
||||
* param limit: limit < 0 means no limit
|
||||
*/
|
||||
func rangeByScore0(db *DB, key string, min *SortedSet.ScoreBorder, max *SortedSet.ScoreBorder, offset int64, limit int64, withScores bool, desc bool) redis.Reply {
|
||||
func rangeByScore0(db *DB, key string, min SortedSet.Border, max SortedSet.Border, offset int64, limit int64, withScores bool, desc bool) redis.Reply {
|
||||
// get data
|
||||
sortedSet, errReply := db.getAsSortedSet(key)
|
||||
if errReply != nil {
|
||||
@@ -314,7 +316,7 @@ func rangeByScore0(db *DB, key string, min *SortedSet.ScoreBorder, max *SortedSe
|
||||
return &protocol.EmptyMultiBulkReply{}
|
||||
}
|
||||
|
||||
slice := sortedSet.RangeByScore(min, max, offset, limit, desc)
|
||||
slice := sortedSet.Range(min, max, offset, limit, desc)
|
||||
if withScores {
|
||||
result := make([][]byte, len(slice)*2)
|
||||
i := 0
|
||||
@@ -456,7 +458,7 @@ func execZRemRangeByScore(db *DB, args [][]byte) redis.Reply {
|
||||
return &protocol.EmptyMultiBulkReply{}
|
||||
}
|
||||
|
||||
removed := sortedSet.RemoveByScore(min, max)
|
||||
removed := sortedSet.RemoveRange(min, max)
|
||||
if removed > 0 {
|
||||
db.addAof(utils.ToCmdLine3("zremrangebyscore", args...))
|
||||
}
|
||||
@@ -621,6 +623,179 @@ func undoZIncr(db *DB, args [][]byte) []CmdLine {
|
||||
return rollbackZSetFields(db, key, field)
|
||||
}
|
||||
|
||||
func execZLexCount(db *DB, args [][]byte) redis.Reply {
|
||||
key := string(args[0])
|
||||
sortedSet, errReply := db.getAsSortedSet(key)
|
||||
if errReply != nil {
|
||||
return errReply
|
||||
}
|
||||
if sortedSet == nil {
|
||||
return protocol.MakeIntReply(0)
|
||||
}
|
||||
|
||||
minEle, maxEle := string(args[1]), string(args[2])
|
||||
min, err := SortedSet.ParseLexBorder(minEle)
|
||||
if err != nil {
|
||||
return protocol.MakeErrReply(err.Error())
|
||||
}
|
||||
max, err := SortedSet.ParseLexBorder(maxEle)
|
||||
if err != nil {
|
||||
return protocol.MakeErrReply(err.Error())
|
||||
}
|
||||
|
||||
count := sortedSet.RangeCount(min, max)
|
||||
|
||||
return protocol.MakeIntReply(count)
|
||||
}
|
||||
|
||||
func execZRangeByLex(db *DB, args [][]byte) redis.Reply {
|
||||
n := len(args)
|
||||
if n > 3 && strings.ToLower(string(args[3])) != "limit" {
|
||||
return protocol.MakeErrReply("ERR syntax error")
|
||||
}
|
||||
if n != 3 && n != 6 {
|
||||
return protocol.MakeErrReply("ERR wrong number of arguments for 'zrangebylex' command")
|
||||
}
|
||||
|
||||
key := string(args[0])
|
||||
sortedSet, errReply := db.getAsSortedSet(key)
|
||||
if errReply != nil {
|
||||
return errReply
|
||||
}
|
||||
if sortedSet == nil {
|
||||
return protocol.MakeIntReply(0)
|
||||
}
|
||||
|
||||
minEle, maxEle := string(args[1]), string(args[2])
|
||||
min, err := SortedSet.ParseLexBorder(minEle)
|
||||
if err != nil {
|
||||
return protocol.MakeErrReply(err.Error())
|
||||
}
|
||||
max, err := SortedSet.ParseLexBorder(maxEle)
|
||||
if err != nil {
|
||||
return protocol.MakeErrReply(err.Error())
|
||||
}
|
||||
|
||||
offset := int64(0)
|
||||
limitCnt := int64(math.MaxInt64)
|
||||
if n > 3 {
|
||||
var err error
|
||||
offset, err = strconv.ParseInt(string(args[4]), 10, 64)
|
||||
if err != nil {
|
||||
return protocol.MakeErrReply("ERR value is not an integer or out of range")
|
||||
}
|
||||
if offset < 0 {
|
||||
return protocol.MakeEmptyMultiBulkReply()
|
||||
}
|
||||
count, err := strconv.ParseInt(string(args[5]), 10, 64)
|
||||
if err != nil {
|
||||
return protocol.MakeErrReply("ERR value is not an integer or out of range")
|
||||
}
|
||||
if count >= 0 {
|
||||
limitCnt = count
|
||||
}
|
||||
}
|
||||
|
||||
elements := sortedSet.Range(min, max, offset, limitCnt, false)
|
||||
result := make([][]byte, 0, len(elements))
|
||||
for _, ele := range elements {
|
||||
result = append(result, []byte(ele.Member))
|
||||
}
|
||||
if len(result) == 0 {
|
||||
return protocol.MakeEmptyMultiBulkReply()
|
||||
}
|
||||
return protocol.MakeMultiBulkReply(result)
|
||||
}
|
||||
|
||||
func execZRemRangeByLex(db *DB, args [][]byte) redis.Reply {
|
||||
n := len(args)
|
||||
if n != 3 {
|
||||
return protocol.MakeErrReply("ERR wrong number of arguments for 'zremrangebylex' command")
|
||||
}
|
||||
|
||||
key := string(args[0])
|
||||
sortedSet, errReply := db.getAsSortedSet(key)
|
||||
if errReply != nil {
|
||||
return errReply
|
||||
}
|
||||
if sortedSet == nil {
|
||||
return protocol.MakeIntReply(0)
|
||||
}
|
||||
|
||||
minEle, maxEle := string(args[1]), string(args[2])
|
||||
min, err := SortedSet.ParseLexBorder(minEle)
|
||||
if err != nil {
|
||||
return protocol.MakeErrReply(err.Error())
|
||||
}
|
||||
max, err := SortedSet.ParseLexBorder(maxEle)
|
||||
if err != nil {
|
||||
return protocol.MakeErrReply(err.Error())
|
||||
}
|
||||
|
||||
count := sortedSet.RemoveRange(min, max)
|
||||
|
||||
return protocol.MakeIntReply(count)
|
||||
}
|
||||
|
||||
func execZRevRangeByLex(db *DB, args [][]byte) redis.Reply {
|
||||
n := len(args)
|
||||
if n > 3 && strings.ToLower(string(args[3])) != "limit" {
|
||||
return protocol.MakeErrReply("ERR syntax error")
|
||||
}
|
||||
if n != 3 && n != 6 {
|
||||
return protocol.MakeErrReply("ERR wrong number of arguments for 'zrangebylex' command")
|
||||
}
|
||||
|
||||
key := string(args[0])
|
||||
sortedSet, errReply := db.getAsSortedSet(key)
|
||||
if errReply != nil {
|
||||
return errReply
|
||||
}
|
||||
if sortedSet == nil {
|
||||
return protocol.MakeIntReply(0)
|
||||
}
|
||||
|
||||
minEle, maxEle := string(args[2]), string(args[1])
|
||||
min, err := SortedSet.ParseLexBorder(minEle)
|
||||
if err != nil {
|
||||
return protocol.MakeErrReply(err.Error())
|
||||
}
|
||||
max, err := SortedSet.ParseLexBorder(maxEle)
|
||||
if err != nil {
|
||||
return protocol.MakeErrReply(err.Error())
|
||||
}
|
||||
|
||||
offset := int64(0)
|
||||
limitCnt := int64(math.MaxInt64)
|
||||
if n > 3 {
|
||||
var err error
|
||||
offset, err = strconv.ParseInt(string(args[4]), 10, 64)
|
||||
if err != nil {
|
||||
return protocol.MakeErrReply("ERR value is not an integer or out of range")
|
||||
}
|
||||
if offset < 0 {
|
||||
return protocol.MakeEmptyMultiBulkReply()
|
||||
}
|
||||
count, err := strconv.ParseInt(string(args[5]), 10, 64)
|
||||
if err != nil {
|
||||
return protocol.MakeErrReply("ERR value is not an integer or out of range")
|
||||
}
|
||||
if count >= 0 {
|
||||
limitCnt = count
|
||||
}
|
||||
}
|
||||
|
||||
elements := sortedSet.Range(min, max, offset, limitCnt, true)
|
||||
result := make([][]byte, 0, len(elements))
|
||||
for _, ele := range elements {
|
||||
result = append(result, []byte(ele.Member))
|
||||
}
|
||||
if len(result) == 0 {
|
||||
return protocol.MakeEmptyMultiBulkReply()
|
||||
}
|
||||
return protocol.MakeMultiBulkReply(result)
|
||||
}
|
||||
|
||||
func init() {
|
||||
registerCommand("ZAdd", execZAdd, writeFirstKey, undoZAdd, -4, flagWrite).
|
||||
attachCommandExtra([]string{redisFlagWrite, redisFlagDenyOOM, redisFlagFast}, 1, 1, 1)
|
||||
@@ -652,4 +827,12 @@ func init() {
|
||||
attachCommandExtra([]string{redisFlagWrite}, 1, 1, 1)
|
||||
registerCommand("ZRemRangeByRank", execZRemRangeByRank, writeFirstKey, rollbackFirstKey, 4, flagWrite).
|
||||
attachCommandExtra([]string{redisFlagWrite}, 1, 1, 1)
|
||||
registerCommand("ZLexCount", execZLexCount, readFirstKey, nil, 4, flagReadOnly).
|
||||
attachCommandExtra([]string{redisFlagReadonly}, 1, 1, 1)
|
||||
registerCommand("ZRangeByLex", execZRangeByLex, readFirstKey, nil, -4, flagReadOnly).
|
||||
attachCommandExtra([]string{redisFlagReadonly}, 1, 1, 1)
|
||||
registerCommand("ZRemRangeByLex", execZRemRangeByLex, writeFirstKey, rollbackFirstKey, 4, flagWrite).
|
||||
attachCommandExtra([]string{redisFlagWrite}, 1, 1, 1)
|
||||
registerCommand("ZRevRangeByLex", execZRevRangeByLex, readFirstKey, nil, -4, flagReadOnly).
|
||||
attachCommandExtra([]string{redisFlagReadonly}, 1, 1, 1)
|
||||
}
|
||||
|
@@ -1,11 +1,12 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"github.com/hdt3213/godis/lib/utils"
|
||||
"github.com/hdt3213/godis/redis/protocol/asserts"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/hdt3213/godis/lib/utils"
|
||||
"github.com/hdt3213/godis/redis/protocol/asserts"
|
||||
)
|
||||
|
||||
func TestZAdd(t *testing.T) {
|
||||
@@ -321,3 +322,444 @@ func TestZPopMin(t *testing.T) {
|
||||
result = testDB.Exec(nil, utils.ToCmdLine("ZPopMin", key+"2", "2"))
|
||||
asserts.AssertErrReply(t, result, "WRONGTYPE Operation against a key holding the wrong kind of value")
|
||||
}
|
||||
|
||||
func TestZLexCount(t *testing.T) {
|
||||
testDB.Flush()
|
||||
key := utils.RandString(10)
|
||||
// a b c d e
|
||||
result := testDB.Exec(nil, utils.ToCmdLine("ZAdd", key, "0", "e", "0", "d", "0", "c", "0", "b", "0", "a"))
|
||||
asserts.AssertNotError(t, result)
|
||||
|
||||
// case1
|
||||
result1 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "(-", "(+"))
|
||||
asserts.AssertIntReply(t, result1, 0)
|
||||
|
||||
// case2
|
||||
result2 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "(-", "(g"))
|
||||
asserts.AssertIntReply(t, result2, 5)
|
||||
|
||||
// case3
|
||||
result3 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "(-", "(c"))
|
||||
asserts.AssertIntReply(t, result3, 2)
|
||||
|
||||
// case4
|
||||
result4 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "(-", "[c"))
|
||||
asserts.AssertIntReply(t, result4, 3)
|
||||
|
||||
// case5
|
||||
result5 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "(a", "(+"))
|
||||
asserts.AssertIntReply(t, result5, 0)
|
||||
|
||||
// case6
|
||||
result6 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "[-", "[+"))
|
||||
asserts.AssertIntReply(t, result6, 0)
|
||||
|
||||
// case
|
||||
result7 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "[-", "(g"))
|
||||
asserts.AssertIntReply(t, result7, 5)
|
||||
|
||||
// case8
|
||||
result8 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "[-", "(c"))
|
||||
asserts.AssertIntReply(t, result8, 2)
|
||||
|
||||
// case9
|
||||
result9 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "[-", "[c"))
|
||||
asserts.AssertIntReply(t, result9, 3)
|
||||
|
||||
// case10
|
||||
result10 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "(a", "[+"))
|
||||
asserts.AssertIntReply(t, result10, 0)
|
||||
|
||||
// case11
|
||||
result11 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "-", "+"))
|
||||
asserts.AssertIntReply(t, result11, 5)
|
||||
|
||||
// case12
|
||||
result12 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "-", "(c"))
|
||||
asserts.AssertIntReply(t, result12, 2)
|
||||
|
||||
// case13
|
||||
result13 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "-", "[c"))
|
||||
asserts.AssertIntReply(t, result13, 3)
|
||||
|
||||
// case14
|
||||
result14 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "(aa", "(c"))
|
||||
asserts.AssertIntReply(t, result14, 1)
|
||||
|
||||
// case15
|
||||
result15 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "(aa", "[c"))
|
||||
asserts.AssertIntReply(t, result15, 2)
|
||||
|
||||
// case16
|
||||
result16 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "[aa", "(c"))
|
||||
asserts.AssertIntReply(t, result16, 1)
|
||||
|
||||
// case17
|
||||
result17 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "[aa", "[c"))
|
||||
asserts.AssertIntReply(t, result17, 2)
|
||||
|
||||
// case18
|
||||
result18 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "(a", "(ee"))
|
||||
asserts.AssertIntReply(t, result18, 4)
|
||||
|
||||
// case19
|
||||
result19 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "(a", "[ee"))
|
||||
asserts.AssertIntReply(t, result19, 4)
|
||||
|
||||
// case20
|
||||
result20 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "[a", "(ee"))
|
||||
asserts.AssertIntReply(t, result20, 5)
|
||||
|
||||
// case21
|
||||
result21 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "[a", "[ee"))
|
||||
asserts.AssertIntReply(t, result21, 5)
|
||||
|
||||
// case22
|
||||
result22 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "(aa", "(ee"))
|
||||
asserts.AssertIntReply(t, result22, 4)
|
||||
|
||||
// case23
|
||||
result23 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "(aa", "[ee"))
|
||||
asserts.AssertIntReply(t, result23, 4)
|
||||
|
||||
// case24
|
||||
result24 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "[aa", "(ee"))
|
||||
asserts.AssertIntReply(t, result24, 4)
|
||||
|
||||
// case25
|
||||
result25 := testDB.Exec(nil, utils.ToCmdLine("ZLexCount", key, "[aa", "[ee"))
|
||||
asserts.AssertIntReply(t, result25, 4)
|
||||
}
|
||||
|
||||
func TestZRangeByLex(t *testing.T) {
|
||||
testDB.Flush()
|
||||
key := utils.RandString(10)
|
||||
// a b c d e
|
||||
result := testDB.Exec(nil, utils.ToCmdLine("ZAdd", key, "0", "e", "0", "d", "0", "c", "0", "b", "0", "a"))
|
||||
asserts.AssertNotError(t, result)
|
||||
|
||||
// case1
|
||||
result1 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "-", "+"))
|
||||
asserts.AssertMultiBulkReply(t, result1, []string{"a", "b", "c", "d", "e"})
|
||||
|
||||
// case2
|
||||
result2 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "-", "(z"))
|
||||
asserts.AssertMultiBulkReply(t, result2, []string{"a", "b", "c", "d", "e"})
|
||||
|
||||
// case3
|
||||
result3 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "(-", "[z"))
|
||||
asserts.AssertMultiBulkReply(t, result3, []string{"a", "b", "c", "d", "e"})
|
||||
|
||||
// case4
|
||||
result4 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "[a", "[e"))
|
||||
asserts.AssertMultiBulkReply(t, result4, []string{"a", "b", "c", "d", "e"})
|
||||
|
||||
// case5
|
||||
result5 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "(a", "[e"))
|
||||
asserts.AssertMultiBulkReply(t, result5, []string{"b", "c", "d", "e"})
|
||||
|
||||
// case6
|
||||
result6 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "[a", "(e"))
|
||||
asserts.AssertMultiBulkReply(t, result6, []string{"a", "b", "c", "d"})
|
||||
|
||||
// case7
|
||||
result7 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "(a", "(e"))
|
||||
asserts.AssertMultiBulkReply(t, result7, []string{"b", "c", "d"})
|
||||
|
||||
// case8
|
||||
result8 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "(aa", "(ee"))
|
||||
asserts.AssertMultiBulkReply(t, result8, []string{"b", "c", "d", "e"})
|
||||
|
||||
// case9
|
||||
result9 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "(aa", "[ee"))
|
||||
asserts.AssertMultiBulkReply(t, result9, []string{"b", "c", "d", "e"})
|
||||
|
||||
// case10
|
||||
result10 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "[aa", "(ee"))
|
||||
asserts.AssertMultiBulkReply(t, result10, []string{"b", "c", "d", "e"})
|
||||
|
||||
// case11
|
||||
result11 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "[aa", "[ee"))
|
||||
asserts.AssertMultiBulkReply(t, result11, []string{"b", "c", "d", "e"})
|
||||
|
||||
// case12
|
||||
result12 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "(aa", "(e"))
|
||||
asserts.AssertMultiBulkReply(t, result12, []string{"b", "c", "d"})
|
||||
|
||||
// case13
|
||||
result13 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "(aa", "[e"))
|
||||
asserts.AssertMultiBulkReply(t, result13, []string{"b", "c", "d", "e"})
|
||||
|
||||
// case14
|
||||
result14 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "[aa", "(e"))
|
||||
asserts.AssertMultiBulkReply(t, result14, []string{"b", "c", "d"})
|
||||
|
||||
// case15
|
||||
result15 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "[aa", "[e"))
|
||||
asserts.AssertMultiBulkReply(t, result15, []string{"b", "c", "d", "e"})
|
||||
|
||||
// case16
|
||||
result16 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "(a", "(ee"))
|
||||
asserts.AssertMultiBulkReply(t, result16, []string{"b", "c", "d", "e"})
|
||||
|
||||
// case17
|
||||
result17 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "(a", "[ee"))
|
||||
asserts.AssertMultiBulkReply(t, result17, []string{"b", "c", "d", "e"})
|
||||
|
||||
// case18
|
||||
result18 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "[a", "(ee"))
|
||||
asserts.AssertMultiBulkReply(t, result18, []string{"a", "b", "c", "d", "e"})
|
||||
|
||||
// case19
|
||||
result19 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "[a", "[ee"))
|
||||
asserts.AssertMultiBulkReply(t, result19, []string{"a", "b", "c", "d", "e"})
|
||||
|
||||
// case20
|
||||
result20 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "(-", "(+"))
|
||||
asserts.AssertMultiBulkReplySize(t, result20, 0)
|
||||
|
||||
// case21
|
||||
result21 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "(a", "(+"))
|
||||
asserts.AssertMultiBulkReplySize(t, result21, 0)
|
||||
|
||||
// case22
|
||||
result22 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "[-", "[+"))
|
||||
asserts.AssertMultiBulkReplySize(t, result22, 0)
|
||||
|
||||
// case23
|
||||
result23 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "(z", "(g"))
|
||||
asserts.AssertMultiBulkReplySize(t, result23, 0)
|
||||
|
||||
// case24
|
||||
result24 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "[-", "(g"))
|
||||
asserts.AssertMultiBulkReply(t, result24, []string{"a", "b", "c", "d", "e"})
|
||||
|
||||
// case25
|
||||
result25 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "[-", "(c"))
|
||||
asserts.AssertMultiBulkReply(t, result25, []string{"a", "b"})
|
||||
|
||||
// case26
|
||||
result26 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "[-", "[c"))
|
||||
asserts.AssertMultiBulkReply(t, result26, []string{"a", "b", "c"})
|
||||
|
||||
// case27
|
||||
result27 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "(a", "(e", "limit", "0", "-1"))
|
||||
asserts.AssertMultiBulkReply(t, result27, []string{"b", "c", "d"})
|
||||
|
||||
// case28
|
||||
result28 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "(a", "(e", "limit", "0", "1"))
|
||||
asserts.AssertMultiBulkReply(t, result28, []string{"b"})
|
||||
|
||||
// case28
|
||||
result29 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "(a", "(e", "limit", "-1", "1"))
|
||||
asserts.AssertMultiBulkReplySize(t, result29, 0)
|
||||
|
||||
// case30
|
||||
result30 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "[a", "[e", "limit", "2", "100"))
|
||||
asserts.AssertMultiBulkReply(t, result30, []string{"c", "d", "e"})
|
||||
|
||||
// case30
|
||||
result31 := testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "-", "+", "limit", "2", "2"))
|
||||
asserts.AssertMultiBulkReply(t, result31, []string{"c", "d"})
|
||||
|
||||
}
|
||||
|
||||
func TestZRemRangeByLex(t *testing.T) {
|
||||
testDB.Flush()
|
||||
key := utils.RandString(10)
|
||||
// a b c d e
|
||||
asserts.AssertNotError(t, testDB.Exec(nil, utils.ToCmdLine("ZAdd", key, "0", "e", "0", "d", "0", "c", "0", "b", "0", "a")))
|
||||
|
||||
// case1
|
||||
asserts.AssertIntReply(t,
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZRemRangeByLex", key, "-", "+")),
|
||||
5)
|
||||
|
||||
asserts.AssertMultiBulkReplySize(t,
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "-", "+")),
|
||||
0)
|
||||
|
||||
// case2
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZAdd", key, "0", "e", "0", "d", "0", "c", "0", "b", "0", "a"))
|
||||
|
||||
asserts.AssertIntReply(t,
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZRemRangeByLex", key, "-", "[c")),
|
||||
3)
|
||||
|
||||
asserts.AssertMultiBulkReply(t,
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "-", "+")),
|
||||
[]string{"d", "e"})
|
||||
|
||||
// case3
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZAdd", key, "0", "a", "0", "b", "0", "c"))
|
||||
|
||||
asserts.AssertMultiBulkReply(t,
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "-", "+")),
|
||||
[]string{"a", "b", "c", "d", "e"})
|
||||
|
||||
asserts.AssertIntReply(t,
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZRemRangeByLex", key, "(c", "+")),
|
||||
2)
|
||||
|
||||
asserts.AssertMultiBulkReply(t,
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "-", "+")),
|
||||
[]string{"a", "b", "c"})
|
||||
|
||||
// case4
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZAdd", key, "0", "d", "0", "e"))
|
||||
|
||||
asserts.AssertMultiBulkReply(t,
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "-", "+")),
|
||||
[]string{"a", "b", "c", "d", "e"})
|
||||
|
||||
asserts.AssertIntReply(t,
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZRemRangeByLex", key, "(a", "(d")),
|
||||
2)
|
||||
|
||||
asserts.AssertMultiBulkReply(t,
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "-", "+")),
|
||||
[]string{"a", "d", "e"})
|
||||
|
||||
// case5
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZAdd", key, "0", "b", "0", "c"))
|
||||
|
||||
asserts.AssertMultiBulkReply(t,
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "-", "+")),
|
||||
[]string{"a", "b", "c", "d", "e"})
|
||||
|
||||
asserts.AssertIntReply(t,
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZRemRangeByLex", key, "[a", "[d")),
|
||||
4)
|
||||
|
||||
asserts.AssertMultiBulkReply(t,
|
||||
testDB.Exec(nil, utils.ToCmdLine("ZRangeByLex", key, "-", "+")),
|
||||
[]string{"e"})
|
||||
}
|
||||
|
||||
func TestZRevRangeByLex(t *testing.T) {
|
||||
testDB.Flush()
|
||||
key := utils.RandString(10)
|
||||
// a b c d e
|
||||
result := testDB.Exec(nil, utils.ToCmdLine("ZAdd", key, "0", "e", "0", "d", "0", "c", "0", "b", "0", "a"))
|
||||
asserts.AssertNotError(t, result)
|
||||
|
||||
// case1
|
||||
result1 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "+", "-"))
|
||||
asserts.AssertMultiBulkReply(t, result1, []string{"e", "d", "c", "b", "a"})
|
||||
|
||||
// case2
|
||||
result2 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "(z", "-"))
|
||||
asserts.AssertMultiBulkReply(t, result2, []string{"e", "d", "c", "b", "a"})
|
||||
|
||||
// case3
|
||||
result3 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "[z", "-"))
|
||||
asserts.AssertMultiBulkReply(t, result3, []string{"e", "d", "c", "b", "a"})
|
||||
|
||||
// case4
|
||||
result4 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "[e", "[a"))
|
||||
asserts.AssertMultiBulkReply(t, result4, []string{"e", "d", "c", "b", "a"})
|
||||
|
||||
// case5
|
||||
result5 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "[e", "(a"))
|
||||
asserts.AssertMultiBulkReply(t, result5, []string{"e", "d", "c", "b"})
|
||||
|
||||
// case6
|
||||
result6 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "(e", "[a"))
|
||||
asserts.AssertMultiBulkReply(t, result6, []string{"d", "c", "b", "a"})
|
||||
|
||||
// case7
|
||||
result7 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "(e", "(a"))
|
||||
asserts.AssertMultiBulkReply(t, result7, []string{"d", "c", "b"})
|
||||
|
||||
// case8
|
||||
result8 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "(ee", "(aa"))
|
||||
asserts.AssertMultiBulkReply(t, result8, []string{"e", "d", "c", "b"})
|
||||
|
||||
// case9
|
||||
result9 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "[ee", "(aa"))
|
||||
asserts.AssertMultiBulkReply(t, result9, []string{"e", "d", "c", "b"})
|
||||
|
||||
// case10
|
||||
result10 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "(ee", "[aa"))
|
||||
asserts.AssertMultiBulkReply(t, result10, []string{"e", "d", "c", "b"})
|
||||
|
||||
// case11
|
||||
result11 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "[ee", "[aa"))
|
||||
asserts.AssertMultiBulkReply(t, result11, []string{"e", "d", "c", "b"})
|
||||
|
||||
// case12
|
||||
result12 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "(e", "(aa"))
|
||||
asserts.AssertMultiBulkReply(t, result12, []string{"d", "c", "b"})
|
||||
|
||||
// case13
|
||||
result13 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "[e", "(aa"))
|
||||
asserts.AssertMultiBulkReply(t, result13, []string{"e", "d", "c", "b"})
|
||||
|
||||
// case14
|
||||
result14 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "(e", "[aa"))
|
||||
asserts.AssertMultiBulkReply(t, result14, []string{"d", "c", "b"})
|
||||
|
||||
// case15
|
||||
result15 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "[e", "[aa"))
|
||||
asserts.AssertMultiBulkReply(t, result15, []string{"e", "d", "c", "b"})
|
||||
|
||||
// case16
|
||||
result16 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "(ee", "(a"))
|
||||
asserts.AssertMultiBulkReply(t, result16, []string{"e", "d", "c", "b"})
|
||||
|
||||
// case17
|
||||
result17 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "[ee", "(a"))
|
||||
asserts.AssertMultiBulkReply(t, result17, []string{"e", "d", "c", "b"})
|
||||
|
||||
// case18
|
||||
result18 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "(ee", "[a"))
|
||||
asserts.AssertMultiBulkReply(t, result18, []string{"e", "d", "c", "b", "a"})
|
||||
|
||||
// case19
|
||||
result19 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "[ee", "[a"))
|
||||
asserts.AssertMultiBulkReply(t, result19, []string{"e", "d", "c", "b", "a"})
|
||||
|
||||
// case20
|
||||
result20 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "(+", "(-"))
|
||||
asserts.AssertMultiBulkReplySize(t, result20, 0)
|
||||
|
||||
// case21
|
||||
result21 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "(+", "(a"))
|
||||
asserts.AssertMultiBulkReplySize(t, result21, 0)
|
||||
|
||||
// case22
|
||||
result22 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "[+", "[-"))
|
||||
asserts.AssertMultiBulkReplySize(t, result22, 0)
|
||||
|
||||
// case23
|
||||
result23 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "(g", "[-"))
|
||||
asserts.AssertMultiBulkReply(t, result23, []string{"e", "d", "c", "b", "a"})
|
||||
|
||||
// case24
|
||||
result24 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "(c", "[-"))
|
||||
asserts.AssertMultiBulkReply(t, result24, []string{"b", "a"})
|
||||
|
||||
// case25
|
||||
result25 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "[c", "[-"))
|
||||
asserts.AssertMultiBulkReply(t, result25, []string{"c", "b", "a"})
|
||||
|
||||
// case26
|
||||
result26 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "(e", "(a", "limit", "0", "-1"))
|
||||
asserts.AssertMultiBulkReply(t, result26, []string{"d", "c", "b"})
|
||||
|
||||
// case27
|
||||
result27 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "(e", "(a", "limit", "0", "1"))
|
||||
asserts.AssertMultiBulkReply(t, result27, []string{"d"})
|
||||
|
||||
// case28
|
||||
result28 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "(e", "(a", "limit", "-1", "1"))
|
||||
asserts.AssertMultiBulkReplySize(t, result28, 0)
|
||||
|
||||
// case29
|
||||
result29 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "[e", "[a", "limit", "2", "100"))
|
||||
asserts.AssertMultiBulkReply(t, result29, []string{"c", "b", "a"})
|
||||
|
||||
// case30
|
||||
result30 := testDB.Exec(nil, utils.ToCmdLine("ZRevRangeByLex", key, "+", "-", "limit", "2", "2"))
|
||||
asserts.AssertMultiBulkReply(t, result30, []string{"c", "b"})
|
||||
}
|
||||
|
Reference in New Issue
Block a user