mirror of https://github.com/ledisdb/ledisdb.git
list/bit/zset scan
This commit is contained in:
parent
647790674b
commit
cd44095dbd
|
@ -12,10 +12,10 @@ func (db *DB) scan(dataType byte, key []byte, count int, inclusive bool) ([][]by
|
||||||
var minKey, maxKey []byte
|
var minKey, maxKey []byte
|
||||||
var err error
|
var err error
|
||||||
if key != nil {
|
if key != nil {
|
||||||
if err = db.checkKeySize(key); err != nil {
|
if err = checkKeySize(key); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if minKey, err = db.encodeOffsetKey(dataType, key); err != nil {
|
if minKey, err = db.encodeMetaKey(dataType, key); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,15 @@ func (db *DB) scan(dataType byte, key []byte, count int, inclusive bool) ([][]by
|
||||||
}
|
}
|
||||||
|
|
||||||
it := db.db.RangeLimitIterator(minKey, maxKey, rangeType, 0, count)
|
it := db.db.RangeLimitIterator(minKey, maxKey, rangeType, 0, count)
|
||||||
|
if dataType == BitMetaType {
|
||||||
|
println(minKey[1])
|
||||||
|
println(maxKey[1])
|
||||||
|
it = db.db.RangeIterator(minKey, maxKey, rangeType)
|
||||||
|
}
|
||||||
|
|
||||||
|
//println(TypeName[dataType])
|
||||||
for ; it.Valid(); it.Next() {
|
for ; it.Valid(); it.Next() {
|
||||||
|
println(TypeName[dataType])
|
||||||
if k, err := db.decodeMetaKey(dataType, it.Key()); err != nil {
|
if k, err := db.decodeMetaKey(dataType, it.Key()); err != nil {
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
|
@ -53,11 +61,14 @@ func (db *DB) scan(dataType byte, key []byte, count int, inclusive bool) ([][]by
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) encodeMinKey(dataType byte) ([]byte, error) {
|
func (db *DB) encodeMinKey(dataType byte) ([]byte, error) {
|
||||||
return db.encodeOffsetKey(dataType, nil)
|
return db.encodeMetaKey(dataType, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) encodeMaxKey(dataType byte) ([]byte, error) {
|
func (db *DB) encodeMaxKey(dataType byte) ([]byte, error) {
|
||||||
k := db.encodeOffsetKey(dataType, nil)
|
k, err := db.encodeMetaKey(dataType, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
k[len(k)-1] = dataType + 1
|
k[len(k)-1] = dataType + 1
|
||||||
return k, nil
|
return k, nil
|
||||||
}
|
}
|
||||||
|
@ -75,10 +86,10 @@ func (db *DB) encodeMetaKey(dataType byte, key []byte) ([]byte, error) {
|
||||||
case BitMetaType:
|
case BitMetaType:
|
||||||
return db.bEncodeMetaKey(key), nil
|
return db.bEncodeMetaKey(key), nil
|
||||||
default:
|
default:
|
||||||
return nil, errInvalidDataType
|
return nil, errDataType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (db *DB) decodeMetaKey(dataType, byte, ek []byte) ([]byte, error) {
|
func (db *DB) decodeMetaKey(dataType byte, ek []byte) ([]byte, error) {
|
||||||
if len(ek) < 2 || ek[0] != db.index || ek[1] != dataType {
|
if len(ek) < 2 || ek[0] != db.index || ek[1] != dataType {
|
||||||
return nil, errMetaKey
|
return nil, errMetaKey
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,3 +81,158 @@ func TestDBHScan(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDBZScan(t *testing.T) {
|
||||||
|
db := getTestDB()
|
||||||
|
|
||||||
|
db.zFlush()
|
||||||
|
|
||||||
|
k1 := []byte("k1")
|
||||||
|
db.ZAdd(k1, ScorePair{1, []byte("m")})
|
||||||
|
|
||||||
|
k2 := []byte("k2")
|
||||||
|
db.ZAdd(k2, ScorePair{2, []byte("m")})
|
||||||
|
|
||||||
|
k3 := []byte("k3")
|
||||||
|
db.ZAdd(k3, ScorePair{3, []byte("m")})
|
||||||
|
|
||||||
|
if v, err := db.ZScan(nil, 1, true); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if len(v) != 1 {
|
||||||
|
t.Fatal("invalid length ", len(v))
|
||||||
|
} else if string(v[0]) != "k1" {
|
||||||
|
t.Fatal("invalid value ", string(v[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, err := db.ZScan(k1, 2, true); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if len(v) != 2 {
|
||||||
|
t.Fatal("invalid length ", len(v))
|
||||||
|
} else if string(v[0]) != "k1" {
|
||||||
|
t.Fatal("invalid value ", string(v[0]))
|
||||||
|
} else if string(v[1]) != "k2" {
|
||||||
|
t.Fatal("invalid value ", string(v[1]))
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, err := db.ZScan(k1, 2, false); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if len(v) != 2 {
|
||||||
|
t.Fatal("invalid length ", len(v))
|
||||||
|
} else if string(v[0]) != "k2" {
|
||||||
|
t.Fatal("invalid value ", string(v[0]))
|
||||||
|
} else if string(v[1]) != "k3" {
|
||||||
|
t.Fatal("invalid value ", string(v[1]))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDBLScan(t *testing.T) {
|
||||||
|
db := getTestDB()
|
||||||
|
|
||||||
|
db.lFlush()
|
||||||
|
|
||||||
|
k1 := []byte("k1")
|
||||||
|
if _, err := db.LPush(k1, []byte("elem")); err != nil {
|
||||||
|
t.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
k2 := []byte("k2")
|
||||||
|
if _, err := db.LPush(k2, []byte("elem")); err != nil {
|
||||||
|
t.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
k3 := []byte("k3")
|
||||||
|
if _, err := db.LPush(k3, []byte("elem")); err != nil {
|
||||||
|
t.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, err := db.LScan(nil, 1, true); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if len(v) != 1 {
|
||||||
|
t.Fatal("invalid length ", len(v))
|
||||||
|
} else if string(v[0]) != "k1" {
|
||||||
|
t.Fatal("invalid value ", string(v[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, err := db.LScan(k1, 2, true); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if len(v) != 2 {
|
||||||
|
t.Fatal("invalid length ", len(v))
|
||||||
|
} else if string(v[0]) != "k1" {
|
||||||
|
t.Fatal("invalid value ", string(v[0]))
|
||||||
|
} else if string(v[1]) != "k2" {
|
||||||
|
t.Fatal("invalid value ", string(v[1]))
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, err := db.LScan(k1, 2, false); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if len(v) != 2 {
|
||||||
|
t.Fatal("invalid length ", len(v))
|
||||||
|
} else if string(v[0]) != "k2" {
|
||||||
|
t.Fatal("invalid value ", string(v[0]))
|
||||||
|
} else if string(v[1]) != "k3" {
|
||||||
|
t.Fatal("invalid value ", string(v[1]))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//func TestDBBScan(t *testing.T) {
|
||||||
|
// db := getTestDB()
|
||||||
|
//
|
||||||
|
// db.bFlush()
|
||||||
|
//
|
||||||
|
// k1 := []byte("k1")
|
||||||
|
// if _, err := db.BSetBit(k1, 1, 1); err != nil {
|
||||||
|
// t.Fatal(err.Error())
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// k2 := []byte("k2")
|
||||||
|
// if _, err := db.BSetBit(k2, 1, 1); err != nil {
|
||||||
|
// t.Fatal(err.Error())
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// k3 := []byte("k3")
|
||||||
|
// if _, err := db.BSetBit(k3, 1, 0); err != nil {
|
||||||
|
// t.Fatal(err.Error())
|
||||||
|
// }
|
||||||
|
// //ek := db.bEncodeMetaKey([]byte("k3"))
|
||||||
|
// ek2, err := db.encodeMetaKey(LMetaType, []byte("k3"))
|
||||||
|
// if err != nil {
|
||||||
|
// t.Fatal(err.Error())
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// endkey, err := db.encodeMaxKey(LMetaType)
|
||||||
|
//
|
||||||
|
// if err != nil {
|
||||||
|
// t.Fatal(err.Error())
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if v, err := db.BScan(nil, 1, true); err != nil {
|
||||||
|
// t.Fatal(err)
|
||||||
|
// } else if len(v) != 1 {
|
||||||
|
// t.Fatal("invalid length ", len(v))
|
||||||
|
// } else if string(v[0]) != "k1" {
|
||||||
|
// t.Fatal("invalid value ", string(v[0]))
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if v, err := db.BScan(k1, 2, true); err != nil {
|
||||||
|
// t.Fatal(err)
|
||||||
|
// } else if len(v) != 2 {
|
||||||
|
// t.Fatal("invalid length ", len(v))
|
||||||
|
// } else if string(v[0]) != "k1" {
|
||||||
|
// t.Fatal("invalid value ", string(v[0]))
|
||||||
|
// } else if string(v[1]) != "k2" {
|
||||||
|
// t.Fatal("invalid value ", string(v[1]))
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if v, err := db.BScan(k1, 2, false); err != nil {
|
||||||
|
// t.Fatal(err)
|
||||||
|
// } else if len(v) != 2 {
|
||||||
|
// t.Fatal("invalid length ", len(v))
|
||||||
|
// } else if string(v[0]) != "k2" {
|
||||||
|
// t.Fatal("invalid value ", string(v[0]))
|
||||||
|
// } else if string(v[1]) != "k3" {
|
||||||
|
// t.Fatal("invalid value ", string(v[1]))
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
|
|
@ -903,9 +903,9 @@ func (db *DB) BPersist(key []byte) (int64, error) {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (db *DB) BScan(key []byte, count int, inclusive bool) ([]KVPair, error) {
|
func (db *DB) BScan(key []byte, count int, inclusive bool) ([][]byte, error) {
|
||||||
|
return db.scan(BitMetaType, key, count, inclusive)
|
||||||
// }
|
}
|
||||||
|
|
||||||
func (db *DB) bFlush() (drop int64, err error) {
|
func (db *DB) bFlush() (drop int64, err error) {
|
||||||
t := db.binTx
|
t := db.binTx
|
||||||
|
|
|
@ -2,7 +2,6 @@ package ledis
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/siddontang/ledisdb/store"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -766,45 +766,6 @@ func (db *DB) zFlush() (drop int64, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) ZScan(key []byte, member []byte, count int, inclusive bool) ([]ScorePair, error) {
|
|
||||||
var minKey []byte
|
|
||||||
if member != nil {
|
|
||||||
if err := checkZSetKMSize(key, member); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
minKey = db.zEncodeSetKey(key, member)
|
|
||||||
} else {
|
|
||||||
minKey = db.zEncodeStartSetKey(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
maxKey := db.zEncodeStopSetKey(key)
|
|
||||||
|
|
||||||
if count <= 0 {
|
|
||||||
count = defaultScanCount
|
|
||||||
}
|
|
||||||
|
|
||||||
v := make([]ScorePair, 0, 2*count)
|
|
||||||
|
|
||||||
rangeType := store.RangeROpen
|
|
||||||
if !inclusive {
|
|
||||||
rangeType = store.RangeOpen
|
|
||||||
}
|
|
||||||
|
|
||||||
it := db.db.RangeLimitIterator(minKey, maxKey, rangeType, 0, count)
|
|
||||||
for ; it.Valid(); it.Next() {
|
|
||||||
if _, m, err := db.zDecodeSetKey(it.Key()); err != nil {
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
score, _ := Int64(it.Value(), nil)
|
|
||||||
v = append(v, ScorePair{Member: m, Score: score})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
it.Close()
|
|
||||||
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *DB) ZExpire(key []byte, duration int64) (int64, error) {
|
func (db *DB) ZExpire(key []byte, duration int64) (int64, error) {
|
||||||
if duration <= 0 {
|
if duration <= 0 {
|
||||||
return 0, errExpireValue
|
return 0, errExpireValue
|
||||||
|
|
|
@ -215,33 +215,6 @@ func TestZSetOrder(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDBZScan(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
|
|
||||||
db.zFlush()
|
|
||||||
|
|
||||||
key := []byte("key")
|
|
||||||
db.ZAdd(key, pair("a", 0), pair("b", 1), pair("c", 2))
|
|
||||||
|
|
||||||
if v, err := db.ZScan(key, nil, 1, true); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if len(v) != 1 {
|
|
||||||
t.Fatal(len(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, err := db.ZScan(key, []byte("a"), 2, false); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if len(v) != 2 {
|
|
||||||
t.Fatal(len(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, err := db.ZScan(key, nil, 10, true); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if len(v) != 3 {
|
|
||||||
t.Fatal(len(v))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZSetPersist(t *testing.T) {
|
func TestZSetPersist(t *testing.T) {
|
||||||
db := getTestDB()
|
db := getTestDB()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue