From d78eb0bdb436005e741bc14f545a97bb42a66186 Mon Sep 17 00:00:00 2001 From: wenyekui Date: Sat, 16 Aug 2014 16:55:36 +0800 Subject: [PATCH] add sscan/sflush --- ledis/ledis_db.go | 3 +++ ledis/scan.go | 2 ++ ledis/scan_test.go | 50 +++++++++++++++++++++++++++++++++++++++++++++ ledis/t_set.go | 17 +++++---------- ledis/t_set_test.go | 32 +++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 12 deletions(-) diff --git a/ledis/ledis_db.go b/ledis/ledis_db.go index af58927..e20a02c 100644 --- a/ledis/ledis_db.go +++ b/ledis/ledis_db.go @@ -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]) } diff --git a/ledis/scan.go b/ledis/scan.go index 5eea520..d64eae5 100644 --- a/ledis/scan.go +++ b/ledis/scan.go @@ -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 } diff --git a/ledis/scan_test.go b/ledis/scan_test.go index c2dbd34..e0a476c 100644 --- a/ledis/scan_test.go +++ b/ledis/scan_test.go @@ -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])) + } + +} diff --git a/ledis/t_set.go b/ledis/t_set.go index ae58e3a..40e4452 100644 --- a/ledis/t_set.go +++ b/ledis/t_set.go @@ -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) +} diff --git a/ledis/t_set_test.go b/ledis/t_set_test.go index 110a982..53bb3a3 100644 --- a/ledis/t_set_test.go +++ b/ledis/t_set_test.go @@ -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)) + } + +}