This commit is contained in:
2022-01-07 20:04:12 +02:00
commit fb547b549c
10 changed files with 586 additions and 0 deletions
+161
View File
@@ -0,0 +1,161 @@
//
package pmkeyvdb
import (
"bytes"
"errors"
"fmt"
"github.com/syndtr/goleveldb/leveldb"
)
type DB struct {
db *leveldb.DB
}
func NewDB() *DB {
return &DB{}
}
func (this *DB) Open(filename string) error {
var err error
if this.db != nil {
this.Close()
}
db, err := leveldb.OpenFile(filename, nil)
if err != nil {
return errors.New(fmt.Sprintf("cannot open database: %v", err))
}
this.db = db
return err
}
func (this *DB) Set(key []byte, value []byte) error {
var err error
err = this.db.Put(key, value, nil)
if err != nil {
return errors.New("db not yet open")
return err
}
return err
}
func (this *DB) Get(key []byte) ([]byte, error) {
var err error
var value []byte
value, err = this.db.Get(key, nil)
if err != nil {
return value, err
}
return value, err
}
func (this *DB) Has(key []byte) (bool, error) {
var err error
var has bool
if this.db == nil {
return has, errors.New("db not yet open")
}
has, err = this.db.Has(key, nil)
if err != nil {
return has, err
}
return has, err
}
type Resolver = func(key []byte, val []byte) (ok bool)
func (this *DB) First(sval []byte) ([]byte, bool, error) {
compf := func(key []byte, val []byte) (ok bool) {
if bytes.Equal(val, sval) {
return true
}
return false
}
return this.comp(compf)
}
func (this *DB) comp(resolver Resolver) ([]byte, bool, error) {
var err error
var key []byte
var ok bool
iter := this.db.NewIterator(nil, nil)
defer iter.Release()
for iter.Next() {
if resolver(iter.Key(), iter.Value()) {
ok = true
key = iter.Key()
break
}
}
err = iter.Error()
if err != nil {
return key, ok, err
}
return key, ok, err
}
func (this *DB) All(resolver Resolver) ([][]byte, bool, error) {
collect := make([][]byte, 0)
var ok bool
var err error
iter := this.db.NewIterator(nil, nil)
defer iter.Release()
for iter.Next() {
if resolver(iter.Key(), iter.Value()) {
ok = true
collect = append(collect, iter.Key())
}
}
err = iter.Error()
if err != nil {
return collect, ok, err
}
return collect, ok, err
}
type Executor = func(key []byte, val []byte) (stop bool)
func (this *DB) Iter(executor Executor) error {
var err error
iter := this.db.NewIterator(nil, nil)
defer iter.Release()
for iter.Next() {
if executor(iter.Key(), iter.Value()) {
break
}
}
err = iter.Error()
if err != nil {
return err
}
return err
}
func (this *DB) Clean() error {
var err error
iter := this.db.NewIterator(nil, nil)
defer iter.Release()
for iter.Next() {
err = this.db.Delete(iter.Key(), nil)
if err != nil {
return err
}
}
err = iter.Error()
if err != nil {
return err
}
return err
}
func (this *DB) Close() {
if this.db != nil {
this.db.Close()
}
}
//EOF
+63
View File
@@ -0,0 +1,63 @@
//
package pmkeyvdb
import (
"testing"
"path/filepath"
"pmapp/tools"
"github.com/stretchr/testify/assert"
)
const dbname string = "tmp.leveldb"
const repeat int = 1024
func TestHasher01SetGetRandKey(t *testing.T) {
var err error
dbpath := filepath.Join(t.TempDir(), dbname)
db := NewDB()
err = db.Open(dbpath)
defer db.Close()
if err != nil {
t.Fatal(err)
}
for i := 0; i < repeat; i++ {
key := tools.RandBytes(16)
ival := tools.RandBytes(128)
err = db.Set(key, ival)
if err != nil {
t.Fatal(err)
}
oval, err := db.Get(key)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, ival, oval, nil)
}
}
func TestHasher02SetGetEqKey(t *testing.T) {
var err error
dbpath := filepath.Join(t.TempDir(), dbname)
db := NewDB()
err = db.Open(dbpath)
defer db.Close()
if err != nil {
t.Fatal(err)
}
key := tools.RandBytes(128)
for i := 0; i < repeat; i++ {
ival := tools.RandBytes(128)
err = db.Set(key, ival)
if err != nil {
t.Fatal(err)
}
oval, err := db.Get(key)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, ival, oval, nil)
}
}
//EOF