Skip to content

Commit

Permalink
[add] types and store
Browse files Browse the repository at this point in the history
  • Loading branch information
camelfred committed Sep 29, 2019
1 parent 180b0e2 commit 7a351f2
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 54 deletions.
9 changes: 4 additions & 5 deletions examples/basecoin/main.go
@@ -1,7 +1,6 @@
package main

import (
"encoding/json"
"fmt"
"os"

Expand Down Expand Up @@ -36,13 +35,13 @@ func main() {
ibcLoader := store.NewIAVLStoreLoader(db, cacheSize, numHistory)

// The key to access the main KVStore.
var mainStoreKey = new(KVStoreKey)
var ibcStoreKey = new(KVStoreKey)
var mainStoreKey = sdk.NewKVStoreKey("main")
var ibcStoreKey = sdk.NewKVStoreKey("ibc")

// Create MultiStore
multiStore := store.NewCommitMultiStore(db)
multiStore.SetSubstoreLoader("main", mainStoreKey, mainLoader)
multiStore.SetSubstoreLoader("ibc", ibcStoreKey, ibcLoader)
multiStore.SetSubstoreLoader(mainStoreKey, mainLoader)
multiStore.SetSubstoreLoader(ibcStoreKey, ibcLoader)
app.SetCommitMultiStore(multiStore)

// Set Tx decoder
Expand Down
22 changes: 11 additions & 11 deletions store/cachemultistore.go
Expand Up @@ -9,18 +9,18 @@ type cacheMultiStore struct {
db CacheKVStore
nextVersion int64
lastCommitID CommitID
substores map[string]CacheWrap
substores map[SubstoreKey]CacheWrap
}

func newCacheMultiStoreFromRMS(rms *rootMultiStore) cacheMultiStore {
cms := cacheMultiStore{
db: NewCacheKVStore(rms.db),
nextVersion: rms.nextVersion,
lastCommitID: rms.lastCommitID,
substores: make(map[string]CacheWrap, len(rms.substores)),
substores: make(map[SubstoreKey]CacheWrap, len(rms.substores)),
}
for name, substore := range rms.substores {
cms.substores[name] = substore.CacheWrap()
for key, substore := range rms.substores {
cms.substores[key] = substore.CacheWrap()
}
return cms
}
Expand All @@ -30,10 +30,10 @@ func newCacheMultiStoreFromCMS(cms cacheMultiStore) cacheMultiStore {
db: NewCacheKVStore(cms.db),
nextVersion: cms.nextVersion,
lastCommitID: cms.lastCommitID,
substores: make(map[string]CacheWrap, len(cms.substores)),
substores: make(map[SubstoreKey]CacheWrap, len(cms.substores)),
}
for name, substore := range cms.substores {
cms2.substores[name] = substore.CacheWrap()
for key, substore := range cms.substores {
cms2.substores[key] = substore.CacheWrap()
}
return cms2
}
Expand Down Expand Up @@ -67,11 +67,11 @@ func (cms cacheMultiStore) CacheMultiStore() CacheMultiStore {
}

// Implements CacheMultiStore
func (cms cacheMultiStore) GetStore(name string) interface{} {
return cms.substores[name]
func (cms cacheMultiStore) GetStore(key SubstoreKey) interface{} {
return cms.substores[key]
}

// Implements CacheMultiStore
func (cms cacheMultiStore) GetKVStore(name string) KVStore {
return cms.substores[name].(KVStore)
func (cms cacheMultiStore) GetKVStore(key SubstoreKey) KVStore {
return cms.substores[key].(KVStore)
}
63 changes: 36 additions & 27 deletions store/rootmultistore.go
Expand Up @@ -22,8 +22,8 @@ type rootMultiStore struct {
db dbm.DB
nextVersion int64
lastCommitID CommitID
storeLoaders map[string]CommitStoreLoader
substores map[string]CommitStore
storeLoaders map[SubstoreKey]CommitStoreLoader
substores map[SubstoreKey]CommitStore
}

var _ CommitMultiStore = (*rootMultiStore)(nil)
Expand All @@ -32,22 +32,22 @@ func NewCommitMultiStore(db dbm.DB) *rootMultiStore {
return &rootMultiStore{
db: db,
nextVersion: 0,
storeLoaders: make(map[string]CommitStoreLoader),
substores: make(map[string]CommitStore),
storeLoaders: make(map[SubstoreKey]CommitStoreLoader),
substores: make(map[SubstoreKey]CommitStore),
}
}

// Implements CommitMultiStore.
func (rs *rootMultiStore) SetSubstoreLoader(name string, loader CommitStoreLoader) {
if _, ok := rs.storeLoaders[name]; ok {
panic(fmt.Sprintf("rootMultiStore duplicate substore name " + name))
func (rs *rootMultiStore) SetSubstoreLoader(key SubstoreKey, loader CommitStoreLoader) {
if _, ok := rs.storeLoaders[key]; ok {
panic(fmt.Sprintf("rootMultiStore duplicate substore key", key))
}
rs.storeLoaders[name] = loader
rs.storeLoaders[key] = loader
}

// Implements CommitMultiStore.
func (rs *rootMultiStore) GetSubstore(name string) CommitStore {
return rs.substores[name]
func (rs *rootMultiStore) GetSubstore(key SubstoreKey) CommitStore {
return rs.substores[key]
}

// Implements CommitMultiStore.
Expand All @@ -61,12 +61,12 @@ func (rs *rootMultiStore) LoadVersion(ver int64) error {

// Special logic for version 0
if ver == 0 {
for name, storeLoader := range rs.storeLoaders {
for key, storeLoader := range rs.storeLoaders {
store, err := storeLoader(CommitID{})
if err != nil {
return fmt.Errorf("Failed to load rootMultiStore: %v", err)
}
rs.substores[name] = store
rs.substores[key] = store
}

rs.nextVersion = 1
Expand All @@ -82,24 +82,24 @@ func (rs *rootMultiStore) LoadVersion(ver int64) error {
}

// Load each Substore
var newSubstores = make(map[string]CommitStore)
var newSubstores = make(map[SubstoreKey]CommitStore)
for _, store := range state.Substores {
name, commitID := store.Name, store.CommitID
storeLoader := rs.storeLoaders[name]
key, commitID := rs.nameToKey(store.Name), store.CommitID
storeLoader := rs.storeLoaders[key]
if storeLoader == nil {
return fmt.Errorf("Failed to load rootMultiStore substore %v for commitID %v: %v", name, commitID, err)
return fmt.Errorf("Failed to load rootMultiStore substore %v for commitID %v: %v", key, commitID, err)
}
store, err := storeLoader(commitID)
if err != nil {
return fmt.Errorf("Failed to load rootMultiStore: %v", err)
}
newSubstores[name] = store
newSubstores[key] = store
}

// If any CommitStoreLoaders were not used, return error.
for name := range rs.storeLoaders {
if _, ok := newSubstores[name]; !ok {
return fmt.Errorf("Unused CommitStoreLoader: %v", name)
for key := range rs.storeLoaders {
if _, ok := newSubstores[key]; !ok {
return fmt.Errorf("Unused CommitStoreLoader: %v", key)
}
}

Expand All @@ -110,6 +110,15 @@ func (rs *rootMultiStore) LoadVersion(ver int64) error {
return nil
}

func (rs *rootMultiStore) nameToKey(name string) SubstoreKey {
for key, _ := range rs.substores {
if key.Name() == name {
return key
}
}
panic("Unknown name " + name)
}

//----------------------------------------
// +CommitStore

Expand Down Expand Up @@ -161,13 +170,13 @@ func (rs *rootMultiStore) CacheMultiStore() CacheMultiStore {
}

// Implements MultiStore.
func (rs *rootMultiStore) GetStore(name string) interface{} {
return rs.substores[name]
func (rs *rootMultiStore) GetStore(key SubstoreKey) interface{} {
return rs.substores[key]
}

// Implements MultiStore.
func (rs *rootMultiStore) GetKVStore(name string) KVStore {
return rs.substores[name].(KVStore)
func (rs *rootMultiStore) GetKVStore(key SubstoreKey) KVStore {
return rs.substores[key].(KVStore)
}

//----------------------------------------
Expand Down Expand Up @@ -246,16 +255,16 @@ func setLatestVersion(batch dbm.Batch, version int64) {
}

// Commits each substore and returns a new commitState.
func commitSubstores(version int64, substoresMap map[string]CommitStore) commitState {
func commitSubstores(version int64, substoresMap map[SubstoreKey]CommitStore) commitState {
substores := make([]substore, 0, len(substoresMap))

for name, store := range substoresMap {
for key, store := range substoresMap {
// Commit
commitID := store.Commit()

// Record CommitID
substore := substore{}
substore.Name = name
substore.Name = key.Name()
substore.CommitID = commitID
substores = append(substores, substore)
}
Expand Down
1 change: 1 addition & 0 deletions store/types.go
Expand Up @@ -17,3 +17,4 @@ type CacheKVStore = types.CacheKVStore
type CacheWrapper = types.CacheWrapper
type CacheWrap = types.CacheWrap
type CommitID = types.CommitID
type SubstoreKey = types.SubstoreKey
11 changes: 7 additions & 4 deletions types/context.go
Expand Up @@ -2,6 +2,8 @@ package types

import (
"context"
"sync"

"github.com/golang/protobuf/proto"

wrsp "github.com/tepleton/wrsp/types"
Expand Down Expand Up @@ -83,7 +85,7 @@ func (c Context) WithProtoMsg(key interface{}, value proto.Message) Context {
return c.withValue(key, value)
}

func (c Context) WithMultiStore(key *MultiStoreKey, ms MultiStore) Context {
func (c Context) WithMultiStore(key *KVStoreKey, ms MultiStore) Context {
return c.withValue(key, ms)
}

Expand Down Expand Up @@ -218,7 +220,7 @@ type thePast struct {

func newThePast() *thePast {
return &thePast{
val: 0,
ver: 0,
ops: nil,
}
}
Expand All @@ -238,10 +240,11 @@ func (pst *thePast) version() int {

// Returns false if ver > 0.
// The first operation is version 1.
func (pst *thePast) getOp(ver int) (Op, bool) {
func (pst *thePast) getOp(ver int64) (Op, bool) {
pst.mtx.RLock()
defer pst.mtx.RUnlock()
if len(pst.ops) < ver {
l := int64(len(pst.ops))
if l < ver {
return Op{}, false
} else {
return pst.ops[ver-1], true
Expand Down
43 changes: 36 additions & 7 deletions types/store.go
Expand Up @@ -27,8 +27,8 @@ type MultiStore interface {
CacheMultiStore() CacheMultiStore

// Convenience for fetching substores.
GetStore(name string) interface{}
GetKVStore(name string) KVStore
GetStore(SubstoreKey) interface{}
GetKVStore(SubstoreKey) KVStore
}

// From MultiStore.CacheMultiStore()....
Expand All @@ -54,10 +54,10 @@ type CommitMultiStore interface {
MultiStore

// Add a substore loader.
SetSubstoreLoader(name string, loader CommitStoreLoader)
SetSubstoreLoader(key SubstoreKey, loader CommitStoreLoader)

// Gets the substore, which is a CommitSubstore.
GetSubstore(name string) CommitStore
GetSubstore(key SubstoreKey) CommitStore

// Load the latest persisted version.
// Called once after all calls to SetSubstoreLoader are complete.
Expand Down Expand Up @@ -148,7 +148,7 @@ type CacheWrap interface {
}

//----------------------------------------
// etc
// CommitID

// CommitID contains the tree version number and its merkle root.
type CommitID struct {
Expand All @@ -164,5 +164,34 @@ func (cid CommitID) String() string {
return fmt.Sprintf("CommitID{%v:%X}", cid.Hash, cid.Version)
}

// new(KVStoreKey) is a capabilities key.
type KVStoreKey struct{}
//----------------------------------------
// Keys for accessing substores

// SubstoreKey is a key used to index substores.
type SubstoreKey interface {
Name() string

String() string
}

// KVStoreKey is used for accessing substores.
// Only the pointer value should ever be used - it functions as a capabilities key.
type KVStoreKey struct {
name string
}

// NewKVStoreKey returns a new pointer to a KVStoreKey.
// Use a pointer so keys don't collide.
func NewKVStoreKey(name string) *KVStoreKey {
return &KVStoreKey{
name: name,
}
}

func (key *KVStoreKey) Name() string {
return key.name
}

func (key *KVStoreKey) String() string {
return fmt.Sprintf("KVStoreKey{%p, %s}", key, key.name)
}

0 comments on commit 7a351f2

Please sign in to comment.