add sscan/sflush

This commit is contained in:
wenyekui 2014-08-16 16:55:36 +08:00
parent 5b88f17470
commit d78eb0bdb4
5 changed files with 92 additions and 12 deletions

View File

@ -71,6 +71,9 @@ func (db *DB) flushType(t *tx, dataType byte) (drop int64, err error) {
case BitType:
deleteFunc = db.bDelete
metaDataType = BitMetaType
case SetType:
deleteFunc = db.sDelete
metaDataType = SSizeType
default:
return 0, fmt.Errorf("invalid data type: %s", TypeName[dataType])
}

View File

@ -78,6 +78,8 @@ func (db *DB) encodeMetaKey(dataType byte, key []byte) ([]byte, error) {
return db.zEncodeSizeKey(key), nil
case BitMetaType:
return db.bEncodeMetaKey(key), nil
case SSizeType:
return db.sEncodeSizeKey(key), nil
default:
return nil, errDataType
}

View File

@ -225,3 +225,53 @@ func TestDBBScan(t *testing.T) {
}
}
func TestDBSScan(t *testing.T) {
db := getTestDB()
db.bFlush()
k1 := []byte("k1")
if _, err := db.SAdd(k1, []byte("1")); err != nil {
t.Fatal(err.Error())
}
k2 := []byte("k2")
if _, err := db.SAdd(k2, []byte("1")); err != nil {
t.Fatal(err.Error())
}
k3 := []byte("k3")
if _, err := db.SAdd(k3, []byte("1")); err != nil {
t.Fatal(err.Error())
}
if v, err := db.SScan(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.SScan(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.SScan(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]))
}
}

View File

@ -105,23 +105,12 @@ func (db *DB) sEncodeStopKey(key []byte) []byte {
}
func (db *DB) sFlush() (drop int64, err error) {
minKey := make([]byte, 2)
minKey[0] = db.index
minKey[1] = SetType
maxKey := make([]byte, 2)
maxKey[0] = db.index
maxKey[1] = SSizeType + 1
t := db.setTx
t.Lock()
defer t.Unlock()
drop, err = db.flushRegion(t, minKey, maxKey)
err = db.expFlush(t, SetType)
err = t.Commit()
return
return db.flushType(t, SetType)
}
func (db *DB) sDelete(t *tx, key []byte) int64 {
@ -605,3 +594,7 @@ func (db *DB) SPersist(key []byte) (int64, error) {
err = t.Commit()
return n, err
}
func (db *DB) SScan(key []byte, count int, inclusive bool) ([][]byte, error) {
return db.scan(SSizeType, key, count, inclusive)
}

View File

@ -1,6 +1,7 @@
package ledis
import (
"fmt"
"testing"
"time"
)
@ -339,3 +340,34 @@ func testDiff(db *DB, t *testing.T) {
t.Fatal(v)
}
}
func TestSFlush(t *testing.T) {
db := getTestDB()
db.FlushAll()
for i := 0; i < 2000; i++ {
key := fmt.Sprintf("%d", i)
if _, err := db.SAdd([]byte(key), []byte("v")); err != nil {
t.Fatal(err.Error())
}
}
if v, err := db.SScan(nil, 3000, true); err != nil {
t.Fatal(err.Error())
} else if len(v) != 2000 {
t.Fatal("invalid value ", len(v))
}
if n, err := db.sFlush(); err != nil {
t.Fatal(err.Error())
} else if n != 2000 {
t.Fatal("invalid value ", n)
}
if v, err := db.SScan(nil, 3000, true); err != nil {
t.Fatal(err.Error())
} else if len(v) != 0 {
t.Fatal("invalid value length ", len(v))
}
}