store: add some tests, fix deadlocks (#297)
This commit is contained in:
parent
af7a621440
commit
1a28c4b89c
|
@ -7,6 +7,13 @@ import (
|
||||||
dbm "github.com/tendermint/tmlibs/db"
|
dbm "github.com/tendermint/tmlibs/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// iavlStoreLoader contains info on what store we want to load from
|
||||||
|
type iavlStoreLoader struct {
|
||||||
|
db dbm.DB
|
||||||
|
cacheSize int
|
||||||
|
numHistory int64
|
||||||
|
}
|
||||||
|
|
||||||
// NewIAVLStoreLoader returns a CommitStoreLoader that returns an iavlStore
|
// NewIAVLStoreLoader returns a CommitStoreLoader that returns an iavlStore
|
||||||
func NewIAVLStoreLoader(db dbm.DB, cacheSize int, numHistory int64) CommitStoreLoader {
|
func NewIAVLStoreLoader(db dbm.DB, cacheSize int, numHistory int64) CommitStoreLoader {
|
||||||
l := iavlStoreLoader{
|
l := iavlStoreLoader{
|
||||||
|
@ -17,6 +24,19 @@ func NewIAVLStoreLoader(db dbm.DB, cacheSize int, numHistory int64) CommitStoreL
|
||||||
return l.Load
|
return l.Load
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load implements CommitLoader.
|
||||||
|
func (isl iavlStoreLoader) Load(id CommitID) (CommitStore, error) {
|
||||||
|
tree := iavl.NewVersionedTree(isl.db, isl.cacheSize)
|
||||||
|
err := tree.Load()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
store := newIAVLStore(tree, isl.numHistory)
|
||||||
|
return store, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------
|
||||||
|
|
||||||
var _ IterKVStore = (*iavlStore)(nil)
|
var _ IterKVStore = (*iavlStore)(nil)
|
||||||
var _ CommitStore = (*iavlStore)(nil)
|
var _ CommitStore = (*iavlStore)(nil)
|
||||||
|
|
||||||
|
@ -243,8 +263,6 @@ func (iter *iavlIterator) Release() {
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
|
|
||||||
func (iter *iavlIterator) setNext(key, value []byte) {
|
func (iter *iavlIterator) setNext(key, value []byte) {
|
||||||
iter.mtx.Lock()
|
|
||||||
defer iter.mtx.Unlock()
|
|
||||||
iter.assertIsValid()
|
iter.assertIsValid()
|
||||||
|
|
||||||
iter.key = key
|
iter.key = key
|
||||||
|
@ -252,8 +270,6 @@ func (iter *iavlIterator) setNext(key, value []byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (iter *iavlIterator) setInvalid() {
|
func (iter *iavlIterator) setInvalid() {
|
||||||
iter.mtx.Lock()
|
|
||||||
defer iter.mtx.Unlock()
|
|
||||||
iter.assertIsValid()
|
iter.assertIsValid()
|
||||||
|
|
||||||
iter.invalid = true
|
iter.invalid = true
|
||||||
|
@ -280,26 +296,6 @@ func (iter *iavlIterator) assertIsValid() {
|
||||||
|
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
|
|
||||||
// iavlStoreLoader contains info on what store we want to load from
|
|
||||||
type iavlStoreLoader struct {
|
|
||||||
db dbm.DB
|
|
||||||
cacheSize int
|
|
||||||
numHistory int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load implements CommitLoader.
|
|
||||||
func (isl iavlStoreLoader) Load(id CommitID) (CommitStore, error) {
|
|
||||||
tree := iavl.NewVersionedTree(isl.db, isl.cacheSize)
|
|
||||||
err := tree.Load()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
store := newIAVLStore(tree, isl.numHistory)
|
|
||||||
return store, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------
|
|
||||||
|
|
||||||
func cp(bz []byte) (ret []byte) {
|
func cp(bz []byte) (ret []byte) {
|
||||||
ret = make([]byte, len(bz))
|
ret = make([]byte, len(bz))
|
||||||
copy(ret, bz)
|
copy(ret, bz)
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
package store
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
|
dbm "github.com/tendermint/tmlibs/db"
|
||||||
|
|
||||||
|
"github.com/tendermint/iavl"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
cacheSize = 100
|
||||||
|
numHistory int64 = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
treeData = map[string]string{
|
||||||
|
"hello": "goodbye",
|
||||||
|
"aloha": "shalom",
|
||||||
|
}
|
||||||
|
nMoreData = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
// make a tree and save it
|
||||||
|
func newTree(t *testing.T, db dbm.DB) (*iavl.VersionedTree, CommitID) {
|
||||||
|
tree := iavl.NewVersionedTree(db, cacheSize)
|
||||||
|
for k, v := range treeData {
|
||||||
|
tree.Set([]byte(k), []byte(v))
|
||||||
|
}
|
||||||
|
for i := 0; i < nMoreData; i++ {
|
||||||
|
key := cmn.RandBytes(12)
|
||||||
|
value := cmn.RandBytes(50)
|
||||||
|
tree.Set(key, value)
|
||||||
|
}
|
||||||
|
hash, ver, err := tree.SaveVersion()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
return tree, CommitID{ver, hash}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIAVLStoreLoader(t *testing.T) {
|
||||||
|
db := dbm.NewMemDB()
|
||||||
|
_, id := newTree(t, db)
|
||||||
|
|
||||||
|
iavlLoader := NewIAVLStoreLoader(db, cacheSize, numHistory)
|
||||||
|
commitStore, err := iavlLoader(id)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
id2 := commitStore.Commit()
|
||||||
|
|
||||||
|
assert.Equal(t, id.Hash, id2.Hash)
|
||||||
|
assert.Equal(t, id.Version+1, id2.Version)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIAVLStoreGetSetHasRemove(t *testing.T) {
|
||||||
|
db := dbm.NewMemDB()
|
||||||
|
tree, _ := newTree(t, db)
|
||||||
|
iavlStore := newIAVLStore(tree, numHistory)
|
||||||
|
|
||||||
|
key := "hello"
|
||||||
|
|
||||||
|
exists := iavlStore.Has([]byte(key))
|
||||||
|
assert.True(t, exists)
|
||||||
|
|
||||||
|
value, exists := iavlStore.Get([]byte(key))
|
||||||
|
assert.True(t, exists)
|
||||||
|
assert.EqualValues(t, value, treeData[key])
|
||||||
|
|
||||||
|
value2 := "notgoodbye"
|
||||||
|
prev := iavlStore.Set([]byte(key), []byte(value2))
|
||||||
|
assert.EqualValues(t, value, prev)
|
||||||
|
|
||||||
|
value, exists = iavlStore.Get([]byte(key))
|
||||||
|
assert.True(t, exists)
|
||||||
|
assert.EqualValues(t, value, value2)
|
||||||
|
|
||||||
|
prev, removed := iavlStore.Remove([]byte(key))
|
||||||
|
assert.True(t, removed)
|
||||||
|
assert.EqualValues(t, value2, prev)
|
||||||
|
|
||||||
|
exists = iavlStore.Has([]byte(key))
|
||||||
|
assert.False(t, exists)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIAVLIterator(t *testing.T) {
|
||||||
|
db := dbm.NewMemDB()
|
||||||
|
tree, _ := newTree(t, db)
|
||||||
|
iavlStore := newIAVLStore(tree, numHistory)
|
||||||
|
iter := iavlStore.Iterator([]byte("aloha"), []byte("hellz"))
|
||||||
|
expected := []string{"aloha", "hello"}
|
||||||
|
for i := 0; iter.Valid(); iter.Next() {
|
||||||
|
expectedKey := expected[i]
|
||||||
|
key, value := iter.Key(), iter.Value()
|
||||||
|
assert.EqualValues(t, key, expectedKey)
|
||||||
|
assert.EqualValues(t, value, treeData[expectedKey])
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue