refactor HScan

This commit is contained in:
wenyekui 2014-08-14 11:23:40 +08:00
parent 4d6b42671b
commit 30b58b2b46
2 changed files with 45 additions and 23 deletions

View File

@ -472,24 +472,32 @@ func (db *DB) hFlush() (drop int64, err error) {
return return
} }
func (db *DB) HScan(key []byte, field []byte, count int, inclusive bool) ([]FVPair, error) { func (db *DB) hEncodeMinKey() []byte {
return db.hEncodeSizeKey(nil)
}
func (db *DB) hEncodeMaxKey() []byte {
ek := db.hEncodeSizeKey(nil)
ek[len(ek)-1] = HSizeType + 1
return ek
}
func (db *DB) HScan(key []byte, count int, inclusive bool) ([][]byte, error) {
var minKey []byte var minKey []byte
if field != nil { if key != nil {
if err := checkHashKFSize(key, field); err != nil { minKey = db.hEncodeSizeKey(key)
return nil, err
}
minKey = db.hEncodeHashKey(key, field)
} else { } else {
minKey = db.hEncodeStartKey(key) minKey = db.hEncodeMinKey()
} }
maxKey := db.hEncodeStopKey(key) maxKey := db.hEncodeMaxKey()
if count <= 0 { if count <= 0 {
count = defaultScanCount count = defaultScanCount
} }
v := make([]FVPair, 0, count) v := make([][]byte, 0, count)
rangeType := store.RangeROpen rangeType := store.RangeROpen
if !inclusive { if !inclusive {
@ -498,14 +506,13 @@ func (db *DB) HScan(key []byte, field []byte, count int, inclusive bool) ([]FVPa
it := db.db.RangeLimitIterator(minKey, maxKey, rangeType, 0, count) it := db.db.RangeLimitIterator(minKey, maxKey, rangeType, 0, count)
for ; it.Valid(); it.Next() { for ; it.Valid(); it.Next() {
if _, f, err := db.hDecodeHashKey(it.Key()); err != nil { if k, err := db.hDecodeSizeKey(it.Key()); err != nil {
continue continue
} else { } else {
v = append(v, FVPair{Field: f, Value: it.Value()}) v = append(v, k)
} }
} }
it.Close() it.Close()
return v, nil return v, nil
} }

View File

@ -61,28 +61,43 @@ func TestDBHScan(t *testing.T) {
db.hFlush() db.hFlush()
key := []byte("a") k1 := []byte("k1")
db.HSet(key, []byte("1"), []byte{}) db.HSet(k1, []byte("1"), []byte{})
db.HSet(key, []byte("2"), []byte{})
db.HSet(key, []byte("3"), []byte{})
if v, err := db.HScan(key, nil, 1, true); err != nil { k2 := []byte("k2")
db.HSet(k2, []byte("2"), []byte{})
k3 := []byte("k3")
db.HSet(k3, []byte("3"), []byte{})
if v, err := db.HScan(nil, 1, true); err != nil {
t.Fatal(err) t.Fatal(err)
} else if len(v) != 1 { } else if len(v) != 1 {
t.Fatal(len(v)) t.Fatal("invalid length ", len(v))
} else if string(v[0]) != "k1" {
t.Fatal("invalid value ", string(v[0]))
} }
if v, err := db.HScan(key, []byte("1"), 2, false); err != nil { if v, err := db.HScan(k1, 2, true); err != nil {
t.Fatal(err) t.Fatal(err)
} else if len(v) != 2 { } else if len(v) != 2 {
t.Fatal(len(v)) 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.HScan(key, nil, 10, true); err != nil { if v, err := db.HScan(k1, 2, false); err != nil {
t.Fatal(err) t.Fatal(err)
} else if len(v) != 3 { } else if len(v) != 2 {
t.Fatal(len(v)) 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 TestHashPersist(t *testing.T) { func TestHashPersist(t *testing.T) {