84 lines
1.8 KiB
Go
Executable File
84 lines
1.8 KiB
Go
Executable File
package storage
|
|
|
|
import (
|
|
"path"
|
|
"strings"
|
|
|
|
"github.com/syndtr/goleveldb/leveldb"
|
|
"github.com/syndtr/goleveldb/leveldb/filter"
|
|
"github.com/syndtr/goleveldb/leveldb/opt"
|
|
"github.com/syndtr/goleveldb/leveldb/util"
|
|
)
|
|
|
|
type LevelDB struct {
|
|
db *leveldb.DB
|
|
}
|
|
|
|
func NewLevelDB(path string) (*LevelDB, error) {
|
|
db, err := leveldb.OpenFile(path, &opt.Options{
|
|
Filter: filter.NewBloomFilter(32),
|
|
})
|
|
return &LevelDB{
|
|
db: db,
|
|
}, 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()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer snapshot.Release()
|
|
|
|
v, err := snapshot.Get([]byte(path.Join(namespace, key)), nil)
|
|
if err == leveldb.ErrNotFound {
|
|
err = ErrNotFound
|
|
} else if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return v, err
|
|
}
|
|
|
|
func (ldb *LevelDB) Set(key string, value []byte, ns ...string) error {
|
|
namespace := resolveNamespace(ns)
|
|
key = path.Join(namespace, key)
|
|
batch := &leveldb.Batch{}
|
|
if value != nil {
|
|
batch.Put([]byte(key), value)
|
|
} else {
|
|
batch.Delete([]byte(key))
|
|
}
|
|
return ldb.db.Write(batch, nil)
|
|
}
|
|
|
|
func (ldb *LevelDB) Close() error {
|
|
return ldb.db.Close()
|
|
}
|