Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cache-store): add deep copy function #20862

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i
* (client) [#19870](https://github.com/cosmos/cosmos-sdk/pull/19870) Add new query command `wait-tx`. Alias `event-query-tx-for` to `wait-tx` for backward compatibility.
* (crypto/keyring) [#20212](https://github.com/cosmos/cosmos-sdk/pull/20212) Expose the db keyring used in the keystore.
* (genutil) [#19971](https://github.com/cosmos/cosmos-sdk/pull/19971) Allow manually setting the consensus key type in genesis
* (store) [#20862](https://github.com/cosmos/cosmos-sdk/pull/20862) Add `Copy()` method for `CacheMultiStore` and `cachekv.Store`.

### Improvements

Expand Down
32 changes: 32 additions & 0 deletions store/cachekv/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,38 @@
}
}

// Copy creates a deep copy of the Store object
func (store *Store) Copy() types.CacheKVStore {
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
}
Comment on lines +171 to +174

Check warning

Code scanning / CodeQL

Iteration over map Warning

Iteration over map may be a possible source of non-determinism

// Copy unsortedCache
unsortedCacheCopy := make(map[string]struct{}, len(store.unsortedCache))
for key := range store.unsortedCache {
unsortedCacheCopy[key] = struct{}{}
}
Comment on lines +178 to +180

Check warning

Code scanning / CodeQL

Iteration over map Warning

Iteration over map may be a possible source of non-determinism

// 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
}

// CacheWrap implements CacheWrapper.
func (store *Store) CacheWrap() types.CacheWrap {
return NewStore(store)
Expand Down
26 changes: 26 additions & 0 deletions store/cachemulti/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,32 @@
}
}

// Copy creates a deep copy of the Store object
func (cms Store) Copy() types.CacheMultiStore {
// Deep copy the db field
newDB := cms.db.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()
}
}
Comment on lines +137 to +142

Check warning

Code scanning / CodeQL

Iteration over map Warning

Iteration over map may be a possible source of non-determinism

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

return newStore
}

// Implements CacheWrapper.
func (cms Store) CacheWrap() types.CacheWrap {
return cms.CacheMultiStore().(types.CacheWrap)
Expand Down
5 changes: 4 additions & 1 deletion store/types/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,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 Expand Up @@ -284,6 +285,8 @@ type CacheKVStore interface {

// Writes operations to underlying KVStore
Write()
// Copy creates a deep copy of the Store object
Copy() CacheKVStore
}

// CommitKVStore is an interface for MultiStore.
Expand Down
Loading