Skip to content

Commit

Permalink
Merge pull request #1481: Transient Stores
Browse files Browse the repository at this point in the history
move gasconfig to types, make GetKVStoreWithGas take GasConfig

fix lint

modify transientstore

in progress

add test for transientstore

fix errors

fix test

fix errors and lint

last fix

in progress

move transient to KVStore

fix syntax errors

finalize rebase

remove NewMemDBStoreAdapter for lint

apply requests
  • Loading branch information
mossid committed Jul 5, 2018
1 parent 586ab68 commit a8a1acf
Show file tree
Hide file tree
Showing 19 changed files with 405 additions and 135 deletions.
16 changes: 12 additions & 4 deletions server/mock/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

var _ sdk.MultiStore = multiStore{}

type multiStore struct {
kv map[sdk.StoreKey]kvStore
}
Expand Down Expand Up @@ -50,10 +52,6 @@ func (ms multiStore) GetKVStore(key sdk.StoreKey) sdk.KVStore {
return ms.kv[key]
}

func (ms multiStore) GetKVStoreWithGas(meter sdk.GasMeter, key sdk.StoreKey) sdk.KVStore {
panic("not implemented")
}

func (ms multiStore) GetStore(key sdk.StoreKey) sdk.Store {
panic("not implemented")
}
Expand All @@ -62,6 +60,8 @@ func (ms multiStore) GetStoreType() sdk.StoreType {
panic("not implemented")
}

var _ sdk.KVStore = kvStore{}

type kvStore struct {
store map[string][]byte
}
Expand Down Expand Up @@ -99,6 +99,14 @@ func (kv kvStore) Prefix(prefix []byte) sdk.KVStore {
panic("not implemented")
}

func (kv kvStore) Gas(meter sdk.GasMeter, config sdk.GasConfig) sdk.KVStore {
panic("not implmeneted")
}

func (kv kvStore) Transient() sdk.KVStore {
panic("not implemented")
}

func (kv kvStore) Iterator(start, end []byte) sdk.Iterator {
panic("not implemented")
}
Expand Down
90 changes: 62 additions & 28 deletions store/cachekvstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,41 @@ import (
cmn "github.com/tendermint/tendermint/libs/common"
)

var _ CacheKVStore = (*cacheKVStore)(nil)

type cacheKVStore struct {
*cache
transient *cache
}

// nolint
func NewCacheKVStore(parent KVStore) CacheKVStore {
ci := &cache{
cache: make(map[string]cValue),
parent: parent,
}
return &cacheKVStore{ci, nil}
}

func (ci *cacheKVStore) Transient() KVStore {
if ci.transient == nil {
ci.transient = &cache{
cache: make(map[string]cValue),
parent: ci.parent.Transient(),
}
}
return ci.transient
}

func (ci *cacheKVStore) Write() {
ci.cache.Write()
if ci.transient != nil {
ci.transient.Write()
}
}

var _ CacheKVStore = (*cache)(nil)

// If value is nil but deleted is false, it means the parent doesn't have the
// key. (No need to delete upon Write())
type cValue struct {
Expand All @@ -16,31 +51,20 @@ type cValue struct {
dirty bool
}

// cacheKVStore wraps an in-memory cache around an underlying KVStore.
type cacheKVStore struct {
// cache wraps an in-memory cache around an underlying KVStore.
type cache struct {
mtx sync.Mutex
cache map[string]cValue
parent KVStore
}

var _ CacheKVStore = (*cacheKVStore)(nil)

// nolint
func NewCacheKVStore(parent KVStore) *cacheKVStore {
ci := &cacheKVStore{
cache: make(map[string]cValue),
parent: parent,
}
return ci
}

// Implements Store.
func (ci *cacheKVStore) GetStoreType() StoreType {
func (ci *cache) GetStoreType() StoreType {
return ci.parent.GetStoreType()
}

// Implements KVStore.
func (ci *cacheKVStore) Get(key []byte) (value []byte) {
func (ci *cache) Get(key []byte) (value []byte) {
ci.mtx.Lock()
defer ci.mtx.Unlock()
ci.assertValidKey(key)
Expand All @@ -57,7 +81,7 @@ func (ci *cacheKVStore) Get(key []byte) (value []byte) {
}

// Implements KVStore.
func (ci *cacheKVStore) Set(key []byte, value []byte) {
func (ci *cache) Set(key []byte, value []byte) {
ci.mtx.Lock()
defer ci.mtx.Unlock()
ci.assertValidKey(key)
Expand All @@ -66,13 +90,13 @@ func (ci *cacheKVStore) Set(key []byte, value []byte) {
}

// Implements KVStore.
func (ci *cacheKVStore) Has(key []byte) bool {
func (ci *cache) Has(key []byte) bool {
value := ci.Get(key)
return value != nil
}

// Implements KVStore.
func (ci *cacheKVStore) Delete(key []byte) {
func (ci *cache) Delete(key []byte) {
ci.mtx.Lock()
defer ci.mtx.Unlock()
ci.assertValidKey(key)
Expand All @@ -81,12 +105,22 @@ func (ci *cacheKVStore) Delete(key []byte) {
}

// Implements KVStore
func (ci *cacheKVStore) Prefix(prefix []byte) KVStore {
func (ci *cache) Prefix(prefix []byte) KVStore {
return prefixStore{ci, prefix}
}

// Implements KVStore
func (ci *cache) Gas(meter GasMeter, config GasConfig) KVStore {
return NewGasKVStore(meter, config, ci)
}

// Implements KVStore
func (ci *cache) Transient() KVStore {
panic("Transient() called on cache")
}

// Implements CacheKVStore.
func (ci *cacheKVStore) Write() {
func (ci *cache) Write() {
ci.mtx.Lock()
defer ci.mtx.Unlock()

Expand Down Expand Up @@ -118,27 +152,27 @@ func (ci *cacheKVStore) Write() {
}

//----------------------------------------
// To cache-wrap this cacheKVStore further.
// To cache-wrap this cache further.

// Implements CacheWrapper.
func (ci *cacheKVStore) CacheWrap() CacheWrap {
func (ci *cache) CacheWrap() CacheWrap {
return NewCacheKVStore(ci)
}

//----------------------------------------
// Iteration

// Implements KVStore.
func (ci *cacheKVStore) Iterator(start, end []byte) Iterator {
func (ci *cache) Iterator(start, end []byte) Iterator {
return ci.iterator(start, end, true)
}

// Implements KVStore.
func (ci *cacheKVStore) ReverseIterator(start, end []byte) Iterator {
func (ci *cache) ReverseIterator(start, end []byte) Iterator {
return ci.iterator(start, end, false)
}

func (ci *cacheKVStore) iterator(start, end []byte, ascending bool) Iterator {
func (ci *cache) iterator(start, end []byte, ascending bool) Iterator {
var parent, cache Iterator
if ascending {
parent = ci.parent.Iterator(start, end)
Expand All @@ -151,7 +185,7 @@ func (ci *cacheKVStore) iterator(start, end []byte, ascending bool) Iterator {
}

// Constructs a slice of dirty items, to use w/ memIterator.
func (ci *cacheKVStore) dirtyItems(ascending bool) []cmn.KVPair {
func (ci *cache) dirtyItems(ascending bool) []cmn.KVPair {
items := make([]cmn.KVPair, 0, len(ci.cache))
for key, cacheValue := range ci.cache {
if !cacheValue.dirty {
Expand All @@ -172,14 +206,14 @@ func (ci *cacheKVStore) dirtyItems(ascending bool) []cmn.KVPair {
//----------------------------------------
// etc

func (ci *cacheKVStore) assertValidKey(key []byte) {
func (ci *cache) assertValidKey(key []byte) {
if key == nil {
panic("key is nil")
}
}

// Only entrypoint to mutate ci.cache.
func (ci *cacheKVStore) setCacheValue(key, value []byte, deleted bool, dirty bool) {
func (ci *cache) setCacheValue(key, value []byte, deleted bool, dirty bool) {
cacheValue := cValue{
value: value,
deleted: deleted,
Expand Down
4 changes: 2 additions & 2 deletions store/cachemultistore.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,6 @@ func (cms cacheMultiStore) GetKVStore(key StoreKey) KVStore {
}

// Implements MultiStore.
func (cms cacheMultiStore) GetKVStoreWithGas(meter sdk.GasMeter, key StoreKey) KVStore {
return NewGasKVStore(meter, cms.GetKVStore(key))
func (cms cacheMultiStore) GetKVStoreWithGas(meter sdk.GasMeter, config sdk.GasConfig, key StoreKey) KVStore {
return NewGasKVStore(meter, config, cms.GetKVStore(key))
}
14 changes: 13 additions & 1 deletion store/dbstoreadapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
dbm "github.com/tendermint/tendermint/libs/db"
)

// Wrapper type for dbm.Db with implementation of KVStore
type dbStoreAdapter struct {
dbm.DB
}
Expand All @@ -24,5 +25,16 @@ func (dsa dbStoreAdapter) Prefix(prefix []byte) KVStore {
return prefixStore{dsa, prefix}
}

// Implements KVStore
func (dsa dbStoreAdapter) Gas(meter GasMeter, config GasConfig) KVStore {
return NewGasKVStore(meter, config, dsa)
}

// Implements KVStore
// TODO: Transient() must be defined for CommitKVStores
func (dsa dbStoreAdapter) Transient() KVStore {
panic("Transient() on dbStoreAdapter")
}

// dbm.DB implements KVStore so we can CacheKVStore it.
var _ KVStore = dbStoreAdapter{dbm.DB(nil)}
var _ KVStore = dbStoreAdapter{}
Loading

0 comments on commit a8a1acf

Please sign in to comment.