Skip to content

Commit

Permalink
store: add some tests, fix deadlocks (#297)
Browse files Browse the repository at this point in the history
  • Loading branch information
ebuchman authored and jaekwon committed Dec 12, 2017
1 parent af7a621 commit 1a28c4b
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 24 deletions.
44 changes: 20 additions & 24 deletions store/iavlstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ import (
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
func NewIAVLStoreLoader(db dbm.DB, cacheSize int, numHistory int64) CommitStoreLoader {
l := iavlStoreLoader{
Expand All @@ -17,6 +24,19 @@ func NewIAVLStoreLoader(db dbm.DB, cacheSize int, numHistory int64) CommitStoreL
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 _ CommitStore = (*iavlStore)(nil)

Expand Down Expand Up @@ -243,17 +263,13 @@ func (iter *iavlIterator) Release() {
//----------------------------------------

func (iter *iavlIterator) setNext(key, value []byte) {
iter.mtx.Lock()
defer iter.mtx.Unlock()
iter.assertIsValid()

iter.key = key
iter.value = value
}

func (iter *iavlIterator) setInvalid() {
iter.mtx.Lock()
defer iter.mtx.Unlock()
iter.assertIsValid()

iter.invalid = true
Expand All @@ -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) {
ret = make([]byte, len(bz))
copy(ret, bz)
Expand Down
100 changes: 100 additions & 0 deletions store/iavlstore_test.go
Original file line number Diff line number Diff line change
@@ -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
}
}

0 comments on commit 1a28c4b

Please sign in to comment.