db: Simplify exists check, fix IsKeyInDomain signature, Iterator Close
+ *FSDB.HasKey now uses common.FileExists to test for file existence + IsKeyInDomain takes key as a []byte slice instead of as a string to avoid extraneous []byte<-->string conversions for start and end + Iterator.Close() instead of Iterator.Release() + withDB helper to encapsulate DB creation, deferred cleanups so that for loops can use opened DBs and discard them ASAP Addressing accepted changes from review with @jaekwon
This commit is contained in:
parent
a2f7898b6d
commit
a7b20d4e46
|
@ -45,14 +45,19 @@ func TestBackendsGetSetDelete(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBackendsNilKeys(t *testing.T) {
|
func withDB(t *testing.T, creator dbCreator, fn func(DB)) {
|
||||||
// test all backends
|
|
||||||
for dbType, creator := range backends {
|
|
||||||
name := cmn.Fmt("test_%x", cmn.RandStr(12))
|
name := cmn.Fmt("test_%x", cmn.RandStr(12))
|
||||||
db, err := creator(name, "")
|
db, err := creator(name, "")
|
||||||
defer cleanupDBDir("", name)
|
defer cleanupDBDir("", name)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
fn(db)
|
||||||
|
db.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBackendsNilKeys(t *testing.T) {
|
||||||
|
// test all backends
|
||||||
|
for dbType, creator := range backends {
|
||||||
|
withDB(t, creator, func(db DB) {
|
||||||
panicMsg := "expecting %s.%s to panic"
|
panicMsg := "expecting %s.%s to panic"
|
||||||
assert.Panics(t, func() { db.Get(nil) }, panicMsg, dbType, "get")
|
assert.Panics(t, func() { db.Get(nil) }, panicMsg, dbType, "get")
|
||||||
assert.Panics(t, func() { db.Has(nil) }, panicMsg, dbType, "has")
|
assert.Panics(t, func() { db.Has(nil) }, panicMsg, dbType, "has")
|
||||||
|
@ -60,8 +65,7 @@ func TestBackendsNilKeys(t *testing.T) {
|
||||||
assert.Panics(t, func() { db.SetSync(nil, []byte("abc")) }, panicMsg, dbType, "setsync")
|
assert.Panics(t, func() { db.SetSync(nil, []byte("abc")) }, panicMsg, dbType, "setsync")
|
||||||
assert.Panics(t, func() { db.Delete(nil) }, panicMsg, dbType, "delete")
|
assert.Panics(t, func() { db.Delete(nil) }, panicMsg, dbType, "delete")
|
||||||
assert.Panics(t, func() { db.DeleteSync(nil) }, panicMsg, dbType, "deletesync")
|
assert.Panics(t, func() { db.DeleteSync(nil) }, panicMsg, dbType, "deletesync")
|
||||||
|
})
|
||||||
db.Close()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,7 @@ func (db *CLevelDB) Close() {
|
||||||
|
|
||||||
func (db *CLevelDB) Print() {
|
func (db *CLevelDB) Print() {
|
||||||
itr := db.Iterator(BeginningKey(), EndingKey())
|
itr := db.Iterator(BeginningKey(), EndingKey())
|
||||||
defer itr.Release()
|
defer itr.Close()
|
||||||
for ; itr.Valid(); itr.Next() {
|
for ; itr.Valid(); itr.Next() {
|
||||||
key := itr.Key()
|
key := itr.Key()
|
||||||
value := itr.Value()
|
value := itr.Value()
|
||||||
|
@ -231,7 +231,7 @@ func (c *cLevelDBIterator) checkEndKey() []byte {
|
||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cLevelDBIterator) Release() {
|
func (c *cLevelDBIterator) Close() {
|
||||||
c.itr.Close()
|
c.itr.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
db/fsdb.go
11
db/fsdb.go
|
@ -10,6 +10,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -64,13 +65,7 @@ func (db *FSDB) Has(key []byte) bool {
|
||||||
panicNilKey(key)
|
panicNilKey(key)
|
||||||
|
|
||||||
path := db.nameToPath(key)
|
path := db.nameToPath(key)
|
||||||
_, err := read(path)
|
return cmn.FileExists(path)
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return false
|
|
||||||
} else if err != nil {
|
|
||||||
panic(errors.Wrapf(err, "Getting key %s (0x%X)", string(key), key))
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *FSDB) Set(key []byte, value []byte) {
|
func (db *FSDB) Set(key []byte, value []byte) {
|
||||||
|
@ -246,7 +241,7 @@ func list(dirPath string, start, end []byte) ([]string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to unescape %s while listing", name)
|
return nil, fmt.Errorf("Failed to unescape %s while listing", name)
|
||||||
}
|
}
|
||||||
if IsKeyInDomain(n, start, end) {
|
if IsKeyInDomain([]byte(n), start, end) {
|
||||||
paths = append(paths, n)
|
paths = append(paths, n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,10 +263,6 @@ func (it *goLevelDBIterator) Close() {
|
||||||
it.source.Release()
|
it.source.Release()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *goLevelDBIterator) Release() {
|
|
||||||
it.source.Release()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (it *goLevelDBIterator) assertNoError() {
|
func (it *goLevelDBIterator) assertNoError() {
|
||||||
if err := it.source.Error(); err != nil {
|
if err := it.source.Error(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
|
@ -157,7 +157,7 @@ func (db *MemDB) ReverseIterator(start, end []byte) Iterator {
|
||||||
func (db *MemDB) getSortedKeys(start, end []byte) []string {
|
func (db *MemDB) getSortedKeys(start, end []byte) []string {
|
||||||
keys := []string{}
|
keys := []string{}
|
||||||
for key, _ := range db.db {
|
for key, _ := range db.db {
|
||||||
if IsKeyInDomain(key, start, end) {
|
if IsKeyInDomain([]byte(key), start, end) {
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,5 +222,3 @@ func (it *memDBIterator) Close() {
|
||||||
it.db = nil
|
it.db = nil
|
||||||
it.keys = nil
|
it.keys = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *memDBIterator) Release() {}
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ func EndingKey() []byte {
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
var itr Iterator = ...
|
var itr Iterator = ...
|
||||||
defer itr.Release()
|
defer itr.Close()
|
||||||
|
|
||||||
for ; itr.Valid(); itr.Next() {
|
for ; itr.Valid(); itr.Next() {
|
||||||
k, v := itr.Key(); itr.Value()
|
k, v := itr.Key(); itr.Value()
|
||||||
|
@ -108,7 +108,7 @@ type Iterator interface {
|
||||||
Value() []byte
|
Value() []byte
|
||||||
|
|
||||||
// Release deallocates the given Iterator.
|
// Release deallocates the given Iterator.
|
||||||
Release()
|
Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// For testing convenience.
|
// For testing convenience.
|
||||||
|
|
|
@ -2,7 +2,6 @@ package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func IteratePrefix(db DB, prefix []byte) Iterator {
|
func IteratePrefix(db DB, prefix []byte) Iterator {
|
||||||
|
@ -39,8 +38,8 @@ func cpIncr(bz []byte) (ret []byte) {
|
||||||
return EndingKey()
|
return EndingKey()
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsKeyInDomain(key string, start, end []byte) bool {
|
func IsKeyInDomain(key, start, end []byte) bool {
|
||||||
leftCondition := bytes.Equal(start, BeginningKey()) || strings.Compare(key, string(start)) >= 0
|
leftCondition := bytes.Equal(start, BeginningKey()) || bytes.Compare(key, start) >= 0
|
||||||
rightCondition := bytes.Equal(end, EndingKey()) || strings.Compare(key, string(end)) < 0
|
rightCondition := bytes.Equal(end, EndingKey()) || bytes.Compare(key, end) < 0
|
||||||
return leftCondition && rightCondition
|
return leftCondition && rightCondition
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue