cleaner testing, leveldb can sort and limit
This commit is contained in:
81
leveldb.go
81
leveldb.go
@@ -2,10 +2,12 @@ package storage
|
||||
|
||||
import (
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
"github.com/syndtr/goleveldb/leveldb/filter"
|
||||
"github.com/syndtr/goleveldb/leveldb/iterator"
|
||||
"github.com/syndtr/goleveldb/leveldb/opt"
|
||||
"github.com/syndtr/goleveldb/leveldb/util"
|
||||
)
|
||||
@@ -33,31 +35,6 @@ func NewLevelDB(path string) (*LevelDB, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (ldb *LevelDB) List(ns []string, limits ...string) ([]string, error) {
|
||||
namespace := resolveNamespace(ns)
|
||||
namespace = path.Join(namespace)
|
||||
limits = resolveLimits(limits)
|
||||
limits[0] = path.Join(namespace, limits[0])
|
||||
limits[1] = path.Join(namespace, limits[1])
|
||||
|
||||
keys := []string{}
|
||||
r := util.BytesPrefix([]byte(namespace))
|
||||
it := ldb.db.NewIterator(r, nil)
|
||||
defer it.Release()
|
||||
for it.Next() {
|
||||
k := string(it.Key())
|
||||
if k < limits[0] {
|
||||
continue
|
||||
} else if k > limits[1] {
|
||||
break
|
||||
}
|
||||
k = strings.TrimPrefix(k, namespace+"/")
|
||||
keys = append(keys, k)
|
||||
}
|
||||
err := it.Error()
|
||||
return keys, err
|
||||
}
|
||||
|
||||
func (ldb *LevelDB) Get(key string, ns ...string) ([]byte, error) {
|
||||
namespace := resolveNamespace(ns)
|
||||
snapshot, err := ldb.db.GetSnapshot()
|
||||
@@ -91,3 +68,57 @@ func (ldb *LevelDB) Set(key string, value []byte, ns ...string) error {
|
||||
func (ldb *LevelDB) Close() error {
|
||||
return ldb.db.Close()
|
||||
}
|
||||
|
||||
func (ldb *LevelDB) List(ns []string, limits ...string) ([]string, error) {
|
||||
namespace := path.Join(resolveNamespace(ns))
|
||||
limits = resolveLimits(limits)
|
||||
it, next := ldb.getIterator(namespace, limits)
|
||||
defer it.Release()
|
||||
keys := ldb.useIterator(it, next, namespace, limits)
|
||||
err := it.Error()
|
||||
return keys, err
|
||||
}
|
||||
|
||||
func (ldb *LevelDB) getIterator(namespace string, limits []string) (iterator.Iterator, func() bool) {
|
||||
limits[0] = path.Join(namespace, limits[0])
|
||||
limits[1] = path.Join(namespace, limits[1])
|
||||
asc := limits[3] == "true"
|
||||
|
||||
r := util.BytesPrefix([]byte(namespace))
|
||||
it := ldb.db.NewIterator(r, nil)
|
||||
next := it.Next
|
||||
it.First()
|
||||
if !asc {
|
||||
next = it.Prev
|
||||
it.Last()
|
||||
}
|
||||
return it, next
|
||||
}
|
||||
|
||||
func (ldb *LevelDB) useIterator(it iterator.Iterator, next func() bool, namespace string, limits []string) []string {
|
||||
limits = resolveLimits(limits)
|
||||
n, _ := strconv.Atoi(limits[2])
|
||||
m := 0
|
||||
|
||||
for it.Error() == nil && !ldb.inRange(string(it.Key()), limits[0], limits[1]) && next() {
|
||||
}
|
||||
|
||||
keys := []string{}
|
||||
for it.Error() == nil && ldb.inRange(string(it.Key()), limits[0], limits[1]) {
|
||||
k := string(it.Key())
|
||||
k = strings.TrimPrefix(k, namespace+"/")
|
||||
keys = append(keys, k)
|
||||
m += 1
|
||||
if n > 0 && m >= n {
|
||||
break
|
||||
}
|
||||
if !next() {
|
||||
break
|
||||
}
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
func (ldb *LevelDB) inRange(k, start, stop string) bool {
|
||||
return k != "" && k >= start && k <= stop
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user