Browse Source

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
pull/1842/head
Emmanuel Odeke 7 years ago
parent
commit
a7b20d4e46
No known key found for this signature in database GPG Key ID: 1CA47A292F89DD40
7 changed files with 37 additions and 45 deletions
  1. +26
    -22
      db/backend_test.go
  2. +2
    -2
      db/c_level_db.go
  3. +3
    -8
      db/fsdb.go
  4. +0
    -4
      db/go_level_db.go
  5. +1
    -3
      db/mem_db.go
  6. +2
    -2
      db/types.go
  7. +3
    -4
      db/util.go

+ 26
- 22
db/backend_test.go View File

@ -45,33 +45,37 @@ func TestBackendsGetSetDelete(t *testing.T) {
} }
} }
func withDB(t *testing.T, creator dbCreator, fn func(DB)) {
name := cmn.Fmt("test_%x", cmn.RandStr(12))
db, err := creator(name, "")
defer cleanupDBDir("", name)
assert.Nil(t, err)
fn(db)
db.Close()
}
func TestBackendsNilKeys(t *testing.T) { func TestBackendsNilKeys(t *testing.T) {
// test all backends // test all backends
for dbType, creator := range backends { for dbType, creator := range backends {
name := cmn.Fmt("test_%x", cmn.RandStr(12))
db, err := creator(name, "")
defer cleanupDBDir("", name)
assert.Nil(t, err)
panicMsg := "expecting %s.%s to panic"
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.Set(nil, []byte("abc")) }, panicMsg, dbType, "set")
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.DeleteSync(nil) }, panicMsg, dbType, "deletesync")
db.Close()
withDB(t, creator, func(db DB) {
panicMsg := "expecting %s.%s to panic"
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.Set(nil, []byte("abc")) }, panicMsg, dbType, "set")
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.DeleteSync(nil) }, panicMsg, dbType, "deletesync")
})
} }
} }
func TestGoLevelDBBackendStr(t *testing.T) { func TestGoLevelDBBackendStr(t *testing.T) {
name := cmn.Fmt("test_%x", cmn.RandStr(12))
db := NewDB(name, LevelDBBackendStr, "")
defer cleanupDBDir("", name)
if _, ok := backends[CLevelDBBackendStr]; !ok {
_, ok := db.(*GoLevelDB)
assert.True(t, ok)
}
name := cmn.Fmt("test_%x", cmn.RandStr(12))
db := NewDB(name, LevelDBBackendStr, "")
defer cleanupDBDir("", name)
if _, ok := backends[CLevelDBBackendStr]; !ok {
_, ok := db.(*GoLevelDB)
assert.True(t, ok)
}
} }

+ 2
- 2
db/c_level_db.go View File

@ -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()
} }


+ 3
- 8
db/fsdb.go View File

@ -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)
if os.IsNotExist(err) {
return false
} else if err != nil {
panic(errors.Wrapf(err, "Getting key %s (0x%X)", string(key), key))
}
return true
return cmn.FileExists(path)
} }
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)
} }
} }


+ 0
- 4
db/go_level_db.go View File

@ -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)


+ 1
- 3
db/mem_db.go View File

@ -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() {}

+ 2
- 2
db/types.go View File

@ -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.


+ 3
- 4
db/util.go View File

@ -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 {
leftCondition := bytes.Equal(start, BeginningKey()) || strings.Compare(key, string(start)) >= 0
rightCondition := bytes.Equal(end, EndingKey()) || strings.Compare(key, string(end)) < 0
func IsKeyInDomain(key, start, end []byte) bool {
leftCondition := bytes.Equal(start, BeginningKey()) || bytes.Compare(key, start) >= 0
rightCondition := bytes.Equal(end, EndingKey()) || bytes.Compare(key, end) < 0
return leftCondition && rightCondition return leftCondition && rightCondition
} }

Loading…
Cancel
Save