Skip to content

Commit

Permalink
chore(cachemulti): add Copy method (#52)
Browse files Browse the repository at this point in the history
Co-authored-by: tom <[email protected]>
Co-authored-by: Tom <[email protected]>
  • Loading branch information
3 people authored Jul 1, 2024
1 parent 58ce259 commit 782b016
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ Ref: https://keepachangelog.com/en/1.0.0/

# Changelog

## Unreleased

* (cache-store) [#52](https://github.com/evmos/cosmos-sdk/pull/52) Add a deep copy method for the store.

## [v0.47.12-evmos](https://github.com/cosmos/evmos/releases/tag/v0.47.12-evmos) - 2024-06-20

## [v0.47.12](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.12) - 2024-06-10
Expand Down
32 changes: 32 additions & 0 deletions store/cachekv/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,38 @@ func (store *Store) CacheWrapWithTrace(w io.Writer, tc types.TraceContext) types
return NewStore(tracekv.NewStore(store, w, tc))
}

// Copy creates a deep copy of the Store object
func (store *Store) Copy() *Store {
store.mtx.Lock()
defer store.mtx.Unlock()

// Copy cache
cacheCopy := make(map[string]*cValue, len(store.cache))
for key, val := range store.cache {
newVal := *val // Create a copy of the cValue
cacheCopy[key] = &newVal
}

// Copy unsortedCache
unsortedCacheCopy := make(map[string]struct{}, len(store.unsortedCache))
for key := range store.unsortedCache {
unsortedCacheCopy[key] = struct{}{}
}

// Copy sortedCache
sortedCacheCopy := store.sortedCache.Copy()

// Create new Store with copied values
newStore := &Store{
cache: cacheCopy,
unsortedCache: unsortedCacheCopy,
sortedCache: sortedCacheCopy,
parent: store.parent,
}

return newStore
}

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

Expand Down
32 changes: 32 additions & 0 deletions store/cachemulti/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,35 @@ func (cms Store) GetKVStore(key types.StoreKey) types.KVStore {
}
return store.(types.KVStore)
}

// Copy creates a deep copy of the Store object
func (cms Store) Copy() types.CacheMultiStore {
// Deep copy the db field
newDB := cms.db.(*cachekv.Store).Copy()

// Deep copy the cachekv stores map
newStores := make(map[types.StoreKey]types.CacheWrap, len(cms.stores))
for key, store := range cms.stores {
store, ok := store.(*cachekv.Store)
if ok {
newStores[key] = store.Copy()
}
}

// Deep copy the keys map
newKeys := make(map[string]types.StoreKey, len(cms.keys))
for key, value := range cms.keys {
newKeys[key] = value
}

// Create new Store with copied values
newStore := Store{
db: newDB,
stores: newStores,
keys: newKeys,
traceWriter: cms.traceWriter,
traceContext: cms.traceContext,
}

return newStore
}
3 changes: 2 additions & 1 deletion store/types/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ type MultiStore interface {
// From MultiStore.CacheMultiStore()....
type CacheMultiStore interface {
MultiStore
Write() // Writes operations to underlying KVStore
Write() // Writes operations to underlying KVStore
Copy() CacheMultiStore // Returns a deep copy of the CacheMultiStore
}

// CommitMultiStore is an interface for a MultiStore without cache capabilities.
Expand Down

0 comments on commit 782b016

Please sign in to comment.