Skip to content

Commit

Permalink
distinguish KVStoreKey and MultiStoreKey, basemulti in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
mossid committed Oct 26, 2018
1 parent 1abb0bf commit 3b3349c
Show file tree
Hide file tree
Showing 10 changed files with 255 additions and 94 deletions.
147 changes: 147 additions & 0 deletions store/basemulti/store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package basemulti

import (
"fmt"

"github.com/tendermint/tendermint/crypto/merkle"
dbm "github.com/tendermint/tendermint/libs/db"

"github.com/cosmos/cosmos-sdk/store/types"
)

type Store struct {
db dbm.DB

kvstores map[types.KVStoreKey]types.CommitKVStore
kvkeysByName map[string]types.KVStoreKey

pruning types.PruningStrategy
}

func (store *Store) MountKVStoreWithDB(key types.KVStoreKey, db dbm.DB) {
if key == nil {
panic("MountStoreWithDB() key cannot be nil")
}
if _, ok := store.kvkeysByName[key.Name()]; ok {
panic(fmt.Sprintf("Store duplicate store key %v", key))
}

store.kvkeysByName[key.Name()] = key
}

func (store *Store) GetCommitKVStore(key types.KVStoreKey) types.CommitKVStore {
return store.kvstores[key]
}

func (store *Store) LoadMultiStoreVersion(ver int64) (err error) {
// Convert StoreInfos slice to map
var lastCommitID types.CommitID
infos := make(map[types.KVStoreKey]storeInfo)
if ver != 0 {
// Get commitInfo
cInfo, err := getCommitInfo(store.db, ver)
if err != nil {
return err
}

for _, sInfo := range cInfo.storeInfos {
infos[store.nameToKVKey(sInfo.Name)] = sInfo
}

lastCommitID = cInfo.CommitID()
}

for _, key := range store.kvkeysByName {
var id types.CommitID
if info, ok := infos[key]; ok {
id = info.Core.CommitID
}
kvstore := key.NewStore()
db := dbm.NewPrefixDB(store.db, []byte("s/k:"+key.Name()+"/"))
err = kvstore.LoadKVStoreVersion(db, id)
if err != nil {
return
}

kvstore.SetPruning(store.pruning)
}
}

func (store *Store) nameToKVKey(name string) types.KVStoreKey {
for key := range kvstores {
if key.Name() == name {
return key
}
}
}

// -------------------------------
// storeInfo

// storeInfo contains the name and core reference for an
// underlying store. It is the leaf of the Stores top
// level simple merkle tree

type storeInfo struct {
Name string
Core storeCore
}

type storeCore struct {
CommitID types.CommitID
// ... maybe add more state
}

// ------------------------------
// commitInfo

// NOTE: keep commitInfo a simple immutable struct.
type commitInfo struct {
// Version
Version int64

// types.Store info for
storeInfos []storeInfo
}

// Hash returns the simple merkle root hash of the stores sorted by name.
func (ci commitInfo) Hash() []byte {
// TODO cache to ci.hash []byte
m := make(map[string]merkle.Hasher, len(ci.StoreInfos))
for _, storeInfo := range ci.StoreInfos {
m[storeInfo.Name] = storeInfo
}
return merkle.SimpleHashFromMap(m)
}

func (ci commitInfo) CommitID() types.CommitID {
return types.CommitID{
Version: ci.Version,
Hash: ci.Hash(),
}
}

// -------------------------------
// Misc.

func getLatestVestoreion(db dbm.DB) (latest int64) {
latestBytes := db.Get([]byte("s/latest"))
if latestBytes == nil {
return 0
}
cdc.MustUnmarshalBinary(latestBytes, &latest)
return
}

func getCommitInfo(db dbm.DB, ver int64) (cInfo commitInfo, err error) {
cInfoBytes := db.Get([]byte(fmt.Sprintf("s/%d", ver)))
if cInfoBytes == nil {
err = fmt.Errorf("failed to get Store: no data")
}

err = cdc.UnmarshalBinary(cInfoBytes, &cInfo)
if err != nil {
err = fmt.Errorf("failed to get Store: %v", err)
}
return
}
7 changes: 7 additions & 0 deletions store/basemulti/wire.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package basemulti

import (
"github.com/cosmos/cosmos-sdk/codec"
)

var cdc = codec.New()
36 changes: 18 additions & 18 deletions store/cachemulti/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,35 @@ import (
//----------------------------------------
// Store

// Store holds many cache-wrapped stores.
// Store holds many cache-wrapped kvstores.
// Implements MultiStore.
// TODO: support recursive multistores,
// TODO: support recursive multikvstores,
// currently only using CacheKVStores
type Store struct {
db types.CacheKVStore
stores map[types.StoreKey]types.CacheKVStore
keysByName map[string]types.StoreKey
kvstores map[types.KVStoreKey]types.CacheKVStore
keysByName map[string]types.KVStoreKey

tracer *types.Tracer
tank *types.GasTank
}

var _ types.CacheMultiStore = Store{}

func NewStore(db dbm.DB, keysByName map[string]types.StoreKey, stores map[types.StoreKey]types.CommitKVStore, tracer *types.Tracer, tank *types.GasTank) Store {
func NewStore(db dbm.DB, keysByName map[string]types.KVStoreKey, kvstores map[types.KVStoreKey]types.CommitKVStore, tracer *types.Tracer, tank *types.GasTank) Store {
cms := Store{
db: cache.NewStore(dbadapter.NewStore(db)),
stores: make(map[types.StoreKey]types.CacheKVStore, len(stores)),
kvstores: make(map[types.KVStoreKey]types.CacheKVStore, len(kvstores)),
keysByName: keysByName,
tracer: tracer,
tank: tank,
}

for key, store := range stores {
for key, store := range kvstores {
if tracer.Enabled() {
cms.stores[key] = cache.NewStore(trace.NewStore(store, tracer))
cms.kvstores[key] = cache.NewStore(trace.NewStore(store, tracer))
} else {
cms.stores[key] = cache.NewStore(store)
cms.kvstores[key] = cache.NewStore(store)
}
}

Expand All @@ -49,16 +49,16 @@ func NewStore(db dbm.DB, keysByName map[string]types.StoreKey, stores map[types.

func newCacheMultiStoreFromCMS(cms Store) Store {
cms2 := Store{
db: cache.NewStore(cms.db),
stores: make(map[types.StoreKey]types.CacheKVStore, len(cms.stores)),
tracer: cms.tracer,
db: cache.NewStore(cms.db),
kvstores: make(map[types.KVStoreKey]types.CacheKVStore, len(cms.kvstores)),
tracer: cms.tracer,
}

for key, store := range cms.stores {
for key, store := range cms.kvstores {
if cms2.tracer.Enabled() {
cms2.stores[key] = cache.NewStore(trace.NewStore(store, cms.tracer))
cms2.kvstores[key] = cache.NewStore(trace.NewStore(store, cms.tracer))
} else {
cms2.stores[key] = cache.NewStore(store)
cms2.kvstores[key] = cache.NewStore(store)
}
}

Expand All @@ -78,7 +78,7 @@ func (cms Store) GetGasTank() *types.GasTank {
// Implements CacheMultiStore.
func (cms Store) Write() {
cms.db.Write()
for _, store := range cms.stores {
for _, store := range cms.kvstores {
store.Write()
}
}
Expand All @@ -89,6 +89,6 @@ func (cms Store) CacheWrap() types.CacheMultiStore {
}

// Implements MultiStore.
func (cms Store) GetKVStore(key types.StoreKey) types.KVStore {
return cms.stores[key].(types.KVStore)
func (cms Store) GetKVStore(key types.KVStoreKey) types.KVStore {
return cms.kvstores[key].(types.KVStore)
}
4 changes: 2 additions & 2 deletions store/iavl/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/cosmos/cosmos-sdk/store/types"
)

var _ types.StoreKey = (*StoreKey)(nil)
var _ types.KVStoreKey = (*StoreKey)(nil)

// StoreKey is used for accessing substores.
// Only the pointer value should ever be used - it functions as a capabilities key.
Expand All @@ -33,6 +33,6 @@ func (key *StoreKey) String() string {
}

// Implements StoreKey
func (key *StoreKey) NewStore() types.CommitStore {
func (key *StoreKey) NewStore() types.CommitKVStore {
return &Store{}
}
25 changes: 25 additions & 0 deletions store/iavlmulti/store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package iavlmulti

import (
dbm "github.com/tendermint/tendermint/libs/db"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/cosmos/cosmos-sdk/store/cachemulti"
"github.com/cosmos/cosmos-sdk/store/iavl"
"github.com/cosmos/cosmos-sdk/store/types"
)

// iavlmulti.Store works similar with rootmulti.Store
// but stores
type Store struct {
db dbm.DB

kvstores map[types.KVStoreKey]iavl.KVStore
}

var _ types.CommitMultiStore = (*Store)(nil)

func (store *Store) CacheWrap() types.CacheMultiStore {
return cachemulti.NewStore(store.db, store.keysByName, store.iavlstores)
}
Loading

0 comments on commit 3b3349c

Please sign in to comment.