mirror of https://github.com/ledisdb/ledisdb.git
add simple support for kv scan
This commit is contained in:
parent
7e88d0b563
commit
81a5587c99
|
@ -15,6 +15,10 @@ const (
|
||||||
zScoreType
|
zScoreType
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultScanCount int = 20
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
//we don't support too many databases
|
//we don't support too many databases
|
||||||
MaxDBNumber uint8 = 16
|
MaxDBNumber uint8 = 16
|
||||||
|
|
|
@ -35,6 +35,17 @@ func (db *DB) decodeKVKey(ek []byte) ([]byte, error) {
|
||||||
return ek[2:], nil
|
return ek[2:], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *DB) encodeKVMinKey() []byte {
|
||||||
|
ek := db.encodeKVKey(nil)
|
||||||
|
return ek
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) encodeKVMaxKey() []byte {
|
||||||
|
ek := db.encodeKVKey(nil)
|
||||||
|
ek[len(ek)-1] = kvType + 1
|
||||||
|
return ek
|
||||||
|
}
|
||||||
|
|
||||||
func (db *DB) incr(key []byte, delta int64) (int64, error) {
|
func (db *DB) incr(key []byte, delta int64) (int64, error) {
|
||||||
if err := checkKeySize(key); err != nil {
|
if err := checkKeySize(key); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -265,13 +276,8 @@ func (db *DB) KvFlush() (drop int64, err error) {
|
||||||
t.Lock()
|
t.Lock()
|
||||||
defer t.Unlock()
|
defer t.Unlock()
|
||||||
|
|
||||||
minKey := make([]byte, 2)
|
minKey := db.encodeKVMinKey()
|
||||||
minKey[0] = db.index
|
maxKey := db.encodeKVMaxKey()
|
||||||
minKey[1] = kvType
|
|
||||||
|
|
||||||
maxKey := make([]byte, 2)
|
|
||||||
maxKey[0] = db.index
|
|
||||||
maxKey[1] = kvType + 1
|
|
||||||
|
|
||||||
it := db.db.Iterator(minKey, maxKey, leveldb.RangeROpen, 0, -1)
|
it := db.db.Iterator(minKey, maxKey, leveldb.RangeROpen, 0, -1)
|
||||||
for ; it.Valid(); it.Next() {
|
for ; it.Valid(); it.Next() {
|
||||||
|
@ -282,3 +288,37 @@ func (db *DB) KvFlush() (drop int64, err error) {
|
||||||
err = t.Commit()
|
err = t.Commit()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *DB) Scan(cursor int, count int) ([]interface{}, error) {
|
||||||
|
minKey := db.encodeKVMinKey()
|
||||||
|
maxKey := db.encodeKVMaxKey()
|
||||||
|
|
||||||
|
if count <= 0 {
|
||||||
|
count = defaultScanCount
|
||||||
|
}
|
||||||
|
|
||||||
|
v := make([]interface{}, 2)
|
||||||
|
r := make([]interface{}, 0, count)
|
||||||
|
|
||||||
|
var num int = 0
|
||||||
|
it := db.db.Iterator(minKey, maxKey, leveldb.RangeROpen, cursor, count)
|
||||||
|
for ; it.Valid(); it.Next() {
|
||||||
|
num++
|
||||||
|
|
||||||
|
if key, err := db.decodeKVKey(it.Key()); err != nil {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
r = append(r, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if num < count {
|
||||||
|
v[0] = int64(0)
|
||||||
|
} else {
|
||||||
|
v[0] = int64(cursor + count)
|
||||||
|
}
|
||||||
|
|
||||||
|
v[1] = r
|
||||||
|
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/siddontang/ledisdb/ledis"
|
"github.com/siddontang/ledisdb/ledis"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getCommand(c *client) error {
|
func getCommand(c *client) error {
|
||||||
|
@ -203,6 +204,40 @@ func mgetCommand(c *client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func scanCommand(c *client) error {
|
||||||
|
args := c.args
|
||||||
|
|
||||||
|
if len(args) != 1 && len(args) != 3 {
|
||||||
|
return ErrCmdParams
|
||||||
|
}
|
||||||
|
var offset int64
|
||||||
|
var count int64
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if offset, err = ledis.StrInt64(args[0], nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
//now we only support count
|
||||||
|
if len(args) == 3 {
|
||||||
|
if strings.ToLower(ledis.String(args[1])) != "count" {
|
||||||
|
return ErrCmdParams
|
||||||
|
}
|
||||||
|
|
||||||
|
if count, err = ledis.StrInt64(args[2], nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, err := c.db.Scan(int(offset), int(count)); err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
c.writeArray(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
register("decr", decrCommand)
|
register("decr", decrCommand)
|
||||||
register("decrby", decrbyCommand)
|
register("decrby", decrbyCommand)
|
||||||
|
@ -216,4 +251,5 @@ func init() {
|
||||||
register("mset", msetCommand)
|
register("mset", msetCommand)
|
||||||
register("set", setCommand)
|
register("set", setCommand)
|
||||||
register("setnx", setnxCommand)
|
register("setnx", setnxCommand)
|
||||||
|
register("scan", scanCommand)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue