Skip to content

feat: implement object stores #24159

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

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

mmsqe
Copy link
Contributor

@mmsqe mmsqe commented Mar 27, 2025

Description

replace #22893 for integrating with block stm, the series of backports branch was tested under crypto-org-chain/ethermint#564

Module parameters are loaded multiple times for each tx, although the raw bytes are cached, the decoding process is not.
Support an object store that is transient stores for interface{}, applications can cache objects directly, without doing unnecessary encoding/decoding.
Caching module parameters is an important use case for this, there are also many use cases out there.
Add prefix store support object store.

Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • included the correct type prefix in the PR title, you can find examples of the prefixes below:
  • confirmed ! in the type prefix if API or client breaking change
  • targeted the correct branch (see PR Targeting)
  • provided a link to the relevant issue or specification
  • reviewed "Files changed" and left comments if necessary
  • included the necessary unit and integration tests
  • added a changelog entry to CHANGELOG.md
  • updated the relevant documentation or specification, including comments for documenting Go code
  • confirmed all CI checks have passed

Reviewers Checklist

All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.

Please see Pull Request Reviewer section in the contributing guide for more information on how to review a pull request.

I have...

  • confirmed the correct type prefix in the PR title
  • confirmed all author checklist items have been addressed
  • reviewed state machine logic, API design and naming, documentation is accurate, tests and test coverage

Summary by CodeRabbit

  • New Features

    • Introduced support for mounting object stores and a new API, allowing users to leverage object storage for enhanced data handling.
  • Improvements

    • Overhauled the underlying storage and caching systems with a refactored, generic design. This update enhances type safety, performance, and overall system reliability.

yihuang and others added 2 commits March 27, 2025 16:15
generic interface

generic btree

generic cachekv

generic transient store

support ObjStore

changelog

Update CHANGELOG.md

Signed-off-by: yihuang <[email protected]>

object store key

Apply review suggestions

fix merge conflict

fix snapshot

revert dependers

prefix store support object store (cosmos#236)

Problem: snapshot for object store is not skipped (cosmos#585)

resolve
gs.gasMeter.ConsumeGas(gs.gasConfig.ReadCostFlat, types.GasReadCostFlatDesc)
value = gs.parent.Get(key)

// TODO overflow-safe math?
gs.gasMeter.ConsumeGas(gs.gasConfig.ReadCostPerByte*types.Gas(len(key)), types.GasReadPerByteDesc)
gs.gasMeter.ConsumeGas(gs.gasConfig.ReadCostPerByte*types.Gas(len(value)), types.GasReadPerByteDesc)
gs.gasMeter.ConsumeGas(gs.gasConfig.ReadCostPerByte*types.Gas(gs.valueLen(value)), types.GasReadPerByteDesc)

Check failure

Code scanning / gosec

integer overflow conversion uint64 -> uint32 Error

integer overflow conversion int -> uint64
gs.gasMeter.ConsumeGas(gs.gasConfig.WriteCostFlat, types.GasWriteCostFlatDesc)
// TODO overflow-safe math?
gs.gasMeter.ConsumeGas(gs.gasConfig.WriteCostPerByte*types.Gas(len(key)), types.GasWritePerByteDesc)
gs.gasMeter.ConsumeGas(gs.gasConfig.WriteCostPerByte*types.Gas(len(value)), types.GasWritePerByteDesc)
gs.gasMeter.ConsumeGas(gs.gasConfig.WriteCostPerByte*types.Gas(gs.valueLen(value)), types.GasWritePerByteDesc)

Check failure

Code scanning / gosec

integer overflow conversion uint64 -> uint32 Error

integer overflow conversion int -> uint64
if gi.Valid() {
key := gi.Key()
value := gi.Value()

gi.gasMeter.ConsumeGas(gi.gasConfig.ReadCostPerByte*types.Gas(len(key)), types.GasValuePerByteDesc)
gi.gasMeter.ConsumeGas(gi.gasConfig.ReadCostPerByte*types.Gas(len(value)), types.GasValuePerByteDesc)
gi.gasMeter.ConsumeGas(gi.gasConfig.ReadCostPerByte*types.Gas(gi.valueLen(value)), types.GasValuePerByteDesc)

Check failure

Code scanning / gosec

integer overflow conversion uint64 -> uint32 Error

integer overflow conversion int -> uint64
store, ok := cms.getCacheWrap(key).(types.KVStore)
if !ok {
panic(fmt.Sprintf("store with key %v is not KVStore", key))
}

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods Warning

Possible panics in BeginBock- or EndBlock-related consensus methods could cause a chain halt
// AssertValidValueGeneric checks if the value is valid(value is not nil and within length limit)
func AssertValidValueGeneric[V any](value V, isZero func(V) bool, valueLen func(V) int) {
if isZero(value) {
panic("value is nil")

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods Warning

Possible panics in BeginBock- or EndBlock-related consensus methods could cause a chain halt
panic("value is nil")
}
AssertValidValueLength(valueLen(value))
}

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods Warning

Possible panics in BeginBock- or EndBlock-related consensus methods could cause a chain halt
@mmsqe mmsqe marked this pull request as ready for review March 27, 2025 09:57
@mmsqe mmsqe requested a review from a team March 27, 2025 09:57
panic(fmt.Sprintf("store with key %v is not ObjKVStore", key))
}

return store

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods Warning

Possible panics in BeginBock- or EndBlock-related consensus methods could cause a chain halt
@technicallyty technicallyty changed the base branch from release/v0.53.x to main April 1, 2025 17:52
Copy link
Contributor

coderabbitai bot commented Apr 9, 2025

📝 Walkthrough

Walkthrough

This pull request introduces extensive changes across the storage and runtime components. It adds support for mounting object stores in the base application along with a corresponding ObjectStore API in the context. In addition, the codebase is refactored to adopt generics in various store implementations (cache KV, gas tracking, prefix, B-tree, transient, and multi-store), updating iterator interfaces, cache wrappers, and store type declarations. The modifications also extend to testing and validation functions, ensuring a consistent and type-safe design throughout the system.

Changes

File(s) Change Summary
CHANGELOG.md, store/CHANGELOG.md Added new feature entries documenting support for mounting object stores and the ObjectStore API.
baseapp/baseapp.go, runtime/module.go, runtime/store.go, server/mock/store.go Added support for mounting object stores (new case in BaseApp, new method MountObjectStores, and ProvideObjectStoreKey in runtime), updated iterator return types, and introduced GetObjKVStore placeholder.
store/cachekv/internal/mergeiterator.go, store/cachekv/search_benchmark_test.go, store/cachekv/store.go Refactored cache KV store components to use generics (added type parameter V, updated iterators and methods, and generic cache value types).
store/cachemulti/store.go, store/gaskv/store.go, store/prefix/store.go Redesigned multi-store, gas tracking, and prefix store implementations using generic GStore types and improved CacheWrap handling.
store/internal/btree/... Refactored BTree implementation and related files (btree.go, btree_test.go, memiterator.go, btreeadaptor.go) to support generics, including generic items and iterators.
store/listenkv/store.go, store/listenkv/store_test.go, store/tracekv/store.go, store/tracekv/store_test.go, store/rootmulti/store.go, store/rootmulti/store_test.go, store/transient/store.go Modified listen, trace, rootmulti, and transient store modules: updated CacheWrap behavior (removing panics), replaced CommitKVStore with CommitStore, and introduced generic transient store features.
store/types/store.go, store/types/validity.go Updated store interfaces to be generic (GBasicKVStore, GKVStore, GIterator), added ObjectStoreKey type and related constructors, new StoreTypeObject constant, and introduced generic value validation functions.
types/context.go, x/group/internal/orm/testsupport.go Added a new ObjectStore method on Context to access object stores and updated mock context methods to use GetCommitStore instead of GetCommitKVStore.

Sequence Diagram(s)

sequenceDiagram
    participant App as BaseApp
    participant RT as Runtime
    participant Ctx as Context
    participant OS as ObjectStore

    App->>App: MountObjectStores(keys)
    App->>RT: Register object store via ProvideObjectStoreKey
    RT-->>App: Object store key registered
    Ctx->>OS: Call ObjectStore(key)
    OS-->>Ctx: Return ObjKVStore instance
Loading
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
store/types/validity.go (1)

30-36: ⚠️ Potential issue

New generic function for value validation

This new generic function enhances flexibility by allowing validation of any type, not just byte slices. However, there's a potential issue with panic in consensus methods.

The panic at line 33 could cause a chain halt if called during BeginBlock or EndBlock consensus methods, as flagged in previous reviews. Consider using error returns instead of panics for safer error handling in consensus-critical code paths.

🧹 Nitpick comments (32)
store/internal/btree/btree.go (5)

25-26: Adopt generic type constraints or constraints to refine usage if needed.

Declaring BTree[V any] is flexible. However, consider whether you need further constraints on V (e.g., comparable) to avoid misusages of the B-tree with unsupported data types in future expansions.


39-39: Naming clarity.

Set is concise, but consider documenting in-code how collisions or overwrites are handled for new developers.


73-77: Shallow vs. deep copy semantics.

bt.tree.Copy() creates a shadow copy of the underlying structure. Document that subsequent modifications in one copy do not bleed into the other, clarifying concurrency usage.


84-86: Generic item struct.

type item[V any] is clear and consistent with the rest of the generic design. Avoid storing excessively large V values in the tree if performance or memory usage is critical.


90-92: Comparison logic.

byKeys[V any] focuses purely on the key. As you expand usage, ensure the ordering remains correct for all valid keys (including empty ones).

store/cachemulti/store.go (3)

27-27: Type change for db field.

Switching to types.CacheWrap gives more flexibility for store layering. Ensure consumers handle the new type assumption properly where an underlying KV or Obj store is expected.


53-64: Tracing logic confined to KVStore check.

Ensuring only KVStore is traced is sensible. If in future a new store type also needs tracing, consider a more extensible approach or a trait-like interface.


181-188: New method for ObjKVStore.

GetObjKVStore parallels GetKVStore. The naming is clear, although consider expanding doc comments to clarify difference from a plain KV store.

store/internal/btree/memiterator.go (6)

1-1: Package rename to “btree”.

Renaming from internal to btree can improve clarity, but guard against exposing this package beyond its intended scope.


17-18: Generic memIterator definition.

Parametric polymorphism is a clean approach here. Keep an eye on any constraints needed on V (e.g., deep copying vs. references) if iterating over complex objects.


26-30: newMemIterator with generics.

start and end checks, along with building an item[V] based on an empty V, fit the rest of the B-tree usage. Document the meaning of empty if it's semantically special.


52-58: Iterator validity on creation.

Storing the initial valid state in mi.valid ensures consistent behavior. Validate if start > end in ascending mode or end < start in descending mode is always a valid scenario.


101-109: Range checking.

keyInRange enforces ascending vs. descending constraints. Maintain consistency with the rest of the code (checking empty vs. nil).


115-117: Return generic value.

Provides direct access to V. May want to note any effect on memory usage or copying overhead for large types V.

store/types/store.go (1)

473-495: Correct the comment to reflect object store usage.

The docstring references "transient stores," which seems to be borrowed from the TransientStoreKey comment. Suggest aligning it with object store semantics. For example:

-// ObjectStoreKey is used for indexing transient stores in a MultiStore
+// ObjectStoreKey is used for indexing object stores in a MultiStore
CHANGELOG.md (1)

58-58: Consistent naming suggestion.

In some sections, the feature is referred to as “ObjectStore” or “object store.” Consider maintaining a consistent style (e.g., “ObjectStore API”) to align with other references in the repository.

baseapp/baseapp.go (1)

349-357: Added MountObjectStores method

A new MountObjectStores method has been implemented to mount object stores with the BaseApp's internal commit multi-store. The implementation follows the same pattern as other store mounting methods, sorting keys alphabetically and mounting each store with the StoreTypeObject type.

One detail to note is that this method uses memKey as the variable name when iterating through object store keys, which might be confusing since we're dealing with object stores, not memory stores. Consider renaming for clarity:

- memKey := keys[key]
+ objKey := keys[key]
server/mock/store.go (2)

117-119: Consider adding an implementation or a TODO.
This new GetObjKVStore method currently panics. If a full implementation is planned, consider adding a TODO comment or partial logic.

Would you like me to open an issue to track this method's implementation or provide a draft?


189-189: Parameters intentionally ignored.
Using underscores to ignore parameters in CacheWrapWithTrace is acceptable, but a brief code comment explaining why these parameters are unnecessary could help future maintainers.

store/internal/btreeadaptor.go (4)

25-28: Performance consideration for Has.
Invoking ts.Get(key) might have overhead if Get is expensive. However, this direct check is acceptable for simplicity.

Could cache existences or provide a dedicated approach if performance is critical.


30-36: Panic on iteration error.
Panicking in Iterator might be acceptable for internal usage. In production contexts, consider returning the error without crashing the app.

 func (ts *BTreeStore[V]) Iterator(start, end []byte) types.GIterator[V] {
   it, err := ts.BTree.Iterator(start, end)
   if err != nil {
-    panic(err)
+    // handle or return error instead of panic
   }
   return it
 }

38-44: Reverse iteration also panics on error.
Same concern as the forward iterator. Consider more graceful error handling.


56-59: Ignoring trace parameters.
Similar to other unimplemented methods, ignoring parameters is acceptable here. If tracing is needed later, ensure a proper pass-through.

store/rootmulti/store.go (2)

69-72: Refactor clarifies multi-store support.

Switching from CommitKVStore to more general CommitStore broadens store compatibility. Ensure all usage sites expecting a KV-based interface handle cases where the store might not be a KV store (e.g., object stores).


570-576: Ensure correct KV re-wrapping logic.

When re-wrapping the cache store with listenkv.NewStore, confirm that no double-wrapping occurs elsewhere, which might lead to duplicate events or unintended overhead.

store/prefix/store.go (2)

39-39: Typo check in doc comment.

The method doc references "for convinience or safety." Consider correcting "convenience" for clarity.

-// for convinience or safety
+// for convenience or safety

88-94: Trace integration in CacheWrapWithTrace.

Conditional logic to handle only the byte-slice store is typical. This avoids complexity for other types, though it’s a bit specialized. Acceptable approach.

store/gaskv/store.go (4)

9-10: Set object length for gas tracking.

ObjectValueLength = 16 is a baseline overhead for object store values. Ensure the chosen length aligns with typical object usage.


23-30: Generic object-based store.

ObjStore = GStore[any] plus NewObjStore handles gas for arbitrary value types. Consider returning different gas usage for varying object sizes if needed.


67-74: Gas usage on Get.

Charging read cost for key length plus value length is standard. Watch for potential integer overflow if len(key) or valueLen(value) becomes large.


200-209: Consume gas for iteration.

consumeSeekGas charges read costs for both key and value. Ensure that large values do not cause integer multiplication overflow. Typically not a big concern in practice.

store/cachekv/internal/mergeiterator.go (1)

29-30: Constructor improvements with generics.

The NewCacheMergeIterator function properly enforces type safety for different V types. Consider validating that isZero is not nil to prevent unexpected runtime errors.

 func NewCacheMergeIterator[V any](parent, cache types.GIterator[V], ascending bool, isZero func(V) bool) types.GIterator[V] {
+   if isZero == nil {
+       panic("isZero function must not be nil")
+   }
    iter := &cacheMergeIterator[V]{
        ...
    }

Also applies to: 34-34

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 29083cb and e64ccc0.

⛔ Files ignored due to path filters (18)
  • go.mod is excluded by !**/*.mod
  • go.sum is excluded by !**/*.sum, !**/*.sum
  • simapp/go.mod is excluded by !**/*.mod
  • simapp/go.sum is excluded by !**/*.sum, !**/*.sum
  • systemtests/go.mod is excluded by !**/*.mod
  • systemtests/go.sum is excluded by !**/*.sum, !**/*.sum
  • tests/systemtests/go.mod is excluded by !**/*.mod
  • tests/systemtests/go.sum is excluded by !**/*.sum, !**/*.sum
  • x/circuit/go.mod is excluded by !**/*.mod
  • x/circuit/go.sum is excluded by !**/*.sum, !**/*.sum
  • x/evidence/go.mod is excluded by !**/*.mod
  • x/evidence/go.sum is excluded by !**/*.sum, !**/*.sum
  • x/feegrant/go.mod is excluded by !**/*.mod
  • x/feegrant/go.sum is excluded by !**/*.sum, !**/*.sum
  • x/nft/go.mod is excluded by !**/*.mod
  • x/nft/go.sum is excluded by !**/*.sum, !**/*.sum
  • x/upgrade/go.mod is excluded by !**/*.mod
  • x/upgrade/go.sum is excluded by !**/*.sum, !**/*.sum
📒 Files selected for processing (27)
  • CHANGELOG.md (1 hunks)
  • baseapp/baseapp.go (2 hunks)
  • runtime/module.go (2 hunks)
  • runtime/store.go (1 hunks)
  • server/mock/store.go (2 hunks)
  • store/CHANGELOG.md (1 hunks)
  • store/cachekv/internal/mergeiterator.go (11 hunks)
  • store/cachekv/search_benchmark_test.go (2 hunks)
  • store/cachekv/store.go (11 hunks)
  • store/cachemulti/store.go (4 hunks)
  • store/gaskv/store.go (2 hunks)
  • store/internal/btree/btree.go (3 hunks)
  • store/internal/btree/btree_test.go (4 hunks)
  • store/internal/btree/memiterator.go (6 hunks)
  • store/internal/btreeadaptor.go (1 hunks)
  • store/listenkv/store.go (2 hunks)
  • store/listenkv/store_test.go (1 hunks)
  • store/prefix/store.go (9 hunks)
  • store/rootmulti/store.go (17 hunks)
  • store/rootmulti/store_test.go (4 hunks)
  • store/tracekv/store.go (1 hunks)
  • store/tracekv/store_test.go (1 hunks)
  • store/transient/store.go (1 hunks)
  • store/types/store.go (7 hunks)
  • store/types/validity.go (2 hunks)
  • types/context.go (1 hunks)
  • x/group/internal/orm/testsupport.go (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (17)
types/context.go (4)
store/types/store.go (1)
  • ObjKVStore (303-303)
store/gaskv/store.go (1)
  • NewObjStore (25-30)
store/prefix/store.go (1)
  • NewObjStore (31-37)
store/transient/store.go (1)
  • NewObjStore (49-54)
store/listenkv/store_test.go (1)
store/types/store.go (1)
  • CacheWrap (329-334)
baseapp/baseapp.go (1)
store/types/store.go (2)
  • ObjectStoreKey (474-476)
  • StoreTypeObject (366-366)
server/mock/store.go (1)
store/types/store.go (4)
  • StoreKey (403-406)
  • ObjKVStore (303-303)
  • TraceContext (519-519)
  • CacheWrap (329-334)
runtime/store.go (1)
store/types/store.go (1)
  • Iterator (297-297)
x/group/internal/orm/testsupport.go (1)
store/types/store.go (1)
  • KVStore (299-299)
store/internal/btree/btree_test.go (1)
store/internal/btree/btree.go (1)
  • NewBTree (30-37)
store/tracekv/store_test.go (1)
store/types/store.go (1)
  • CacheWrap (329-334)
store/internal/btreeadaptor.go (4)
store/types/store.go (5)
  • KVStore (299-299)
  • Iterator (297-297)
  • GIterator (268-294)
  • StoreType (356-356)
  • StoreTypeDB (360-360)
store/internal/btree/btree.go (1)
  • BTree (25-27)
store/cachekv/store.go (1)
  • NewGStore (60-69)
store/transient/store.go (1)
  • NewGStore (24-26)
store/rootmulti/store.go (6)
store/types/store.go (6)
  • StoreKey (403-406)
  • CommitStore (35-38)
  • Store (17-20)
  • CommitKVStore (317-320)
  • KVStore (299-299)
  • StoreTypeObject (366-366)
store/iavl/store.go (1)
  • Store (37-41)
store/gaskv/store.go (2)
  • Store (14-14)
  • ObjStore (23-23)
store/cachekv/store.go (1)
  • Store (31-31)
store/transient/store.go (4)
  • Store (29-31)
  • Store (40-42)
  • ObjStore (45-47)
  • ObjStore (56-58)
store/listenkv/store.go (1)
  • Store (15-19)
store/cachekv/search_benchmark_test.go (5)
store/gaskv/store.go (1)
  • GStore (34-41)
store/cachekv/store.go (1)
  • GStore (44-57)
store/prefix/store.go (1)
  • GStore (42-48)
store/transient/store.go (1)
  • GStore (19-21)
store/internal/btree/btree.go (1)
  • NewBTree (30-37)
store/transient/store.go (3)
store/types/store.go (6)
  • Committer (23-32)
  • Store (17-20)
  • KVStore (299-299)
  • StoreType (356-356)
  • StoreTypeTransient (362-362)
  • StoreTypeObject (366-366)
store/internal/btreeadaptor.go (2)
  • BTreeStore (14-18)
  • NewBTreeStore (21-23)
store/internal/btree/btree.go (1)
  • NewBTree (30-37)
store/internal/btree/memiterator.go (2)
store/types/store.go (1)
  • Iterator (297-297)
store/internal/btree/btree.go (1)
  • BTree (25-27)
store/internal/btree/btree.go (1)
store/types/store.go (2)
  • Iterator (297-297)
  • GIterator (268-294)
store/prefix/store.go (5)
store/gaskv/store.go (4)
  • GStore (34-41)
  • Store (14-14)
  • ObjStore (23-23)
  • NewGStore (44-59)
store/cachekv/store.go (3)
  • GStore (44-57)
  • Store (31-31)
  • NewGStore (60-69)
store/transient/store.go (6)
  • GStore (19-21)
  • Store (29-31)
  • Store (40-42)
  • ObjStore (45-47)
  • ObjStore (56-58)
  • NewGStore (24-26)
store/types/store.go (8)
  • KVStore (299-299)
  • Store (17-20)
  • ObjKVStore (303-303)
  • GKVStore (247-265)
  • StoreType (356-356)
  • CacheWrap (329-334)
  • Iterator (297-297)
  • GIterator (268-294)
store/types/validity.go (1)
  • AssertValidValueGeneric (31-36)
store/cachekv/store.go (5)
store/types/store.go (8)
  • CacheKVStore (309-314)
  • Store (17-20)
  • KVStore (299-299)
  • GKVStore (247-265)
  • CacheWrap (329-334)
  • TraceContext (519-519)
  • Iterator (297-297)
  • GIterator (268-294)
store/cachemulti/store.go (1)
  • Store (26-33)
store/internal/btree/btree.go (2)
  • BTree (25-27)
  • NewBTree (30-37)
store/types/validity.go (2)
  • AssertValidKey (13-20)
  • AssertValidValueGeneric (31-36)
store/cachekv/internal/mergeiterator.go (1)
  • NewCacheMergeIterator (29-39)
store/gaskv/store.go (4)
store/types/store.go (6)
  • KVStore (299-299)
  • Store (17-20)
  • GKVStore (247-265)
  • StoreType (356-356)
  • Iterator (297-297)
  • GIterator (268-294)
store/prefix/store.go (2)
  • Store (14-14)
  • GStore (42-48)
store/transient/store.go (3)
  • Store (29-31)
  • Store (40-42)
  • GStore (19-21)
store/types/validity.go (1)
  • AssertValidValueGeneric (31-36)
⏰ Context from checks skipped due to timeout of 90000ms (16)
  • GitHub Check: test-system-legacy
  • GitHub Check: test-system
  • GitHub Check: tests (03)
  • GitHub Check: tests (02)
  • GitHub Check: tests (01)
  • GitHub Check: tests (00)
  • GitHub Check: test-x-upgrade
  • GitHub Check: test-sim-nondeterminism
  • GitHub Check: test-integration
  • GitHub Check: test-e2e
  • GitHub Check: build (arm64)
  • GitHub Check: Analyze
  • GitHub Check: build (amd64)
  • GitHub Check: Gosec
  • GitHub Check: golangci-lint
  • GitHub Check: Summary
🔇 Additional comments (138)
runtime/store.go (2)

151-157: Return type updated from dbm.Iterator to storetypes.Iterator

This change aligns with the broader update to use generics in store implementations. The storetypes.Iterator is now a type alias for GIterator[[]byte], providing better type-safety while maintaining the same functionality.


159-165: Return type updated from dbm.Iterator to storetypes.Iterator

The return type change for the reverse iterator matches the forward iterator change, providing consistency in the API.

store/types/validity.go (3)

3-4: Added import for errors package

The errors package is now needed for creating error messages in the AssertValidValueLength function.


27-28: Modularized length validation logic

Extracting the length validation to a separate function improves code maintainability and reusability.


38-42: Added separate function for value length validation

This encapsulation creates a clear separation of concerns and allows the length validation logic to be reused in both the original and generic validation functions.

However, the same panic issue exists here. Consider returning an error instead:

-func AssertValidValueLength(l int) {
+func AssertValidValueLength(l int) error {
 	if l > MaxValueLength {
-		panic(errors.New("value is too large"))
+		return errors.New("value is too large")
 	}
+	return nil
 }
store/internal/btree/btree_test.go (4)

1-2: Package name updated from 'internal' to 'btree'

The package name change reflects the move from an internal implementation detail to a more explicitly named btree package.


12-13: Added explicit type parameter to NewBTree function call

Updated the function call to use the new generic API by specifying the type parameter []byte.


43-44: Added explicit type parameter to NewBTree function call

Consistent with the earlier change, the function call now includes the type parameter []byte.


174-175: Added explicit type parameter to NewBTree function call

Final instance of updating the NewBTree function call with the type parameter []byte, maintaining consistency throughout the test file.

store/rootmulti/store_test.go (5)

803-804: Added new test store key

Added testStoreKey4 for testing the new object store functionality.


876-886: Updated hashStores to use CommitStore instead of CommitKVStore

The function signature has been updated to use the more general types.CommitStore interface instead of the specific types.CommitKVStore. This change accommodates the new object store functionality.


931-933: Renamed commitKVStoreStub to commitStoreStub

The stub is now more generally named to reflect that it can represent any type of commit store, not just KV stores.


936-940: Updated Commit method signature

The Commit method now works with the more general CommitStore type, maintaining backward compatibility while supporting the new object store functionality.


942-966: Updated prepareStoreMap to include object store

The function now returns a map that includes the new object store type and prepares all necessary store types for testing. This change is well-structured and provides proper test coverage for the new functionality.

store/internal/btree/btree.go (7)

30-37: Initialization looks good.

The NewBTree[V any] function properly configures the B-tree with balanced defaults. The usage of byKeys[V] is consistent with the new generic approach.


43-47: Handle potential nil key.

The function gracefully returns an empty value if the key is not found. However, confirm upstream if users might mistakenly pass nil or empty slices. Possibly add a check to return early with an error if there's an unintended nil usage.


52-54: Confirm correctness for delete logic.

Deleting via a new item with an empty value works, since only the key is used for matching in the underlying btree.Delete. Ensure there's no confusion about empty vs. nil values for V.


57-62: Boundary checks for nil vs. empty keys.

The code correctly distinguishes between nil checks and zero-length checks. Confirm that calling Iterator([]byte{}, []byte{}, ...) is valid or if an error should be thrown.


64-69: Reverse range iteration logic.

The approach for seeking the end boundary, then stepping back aligns with a reverse iteration pattern. Keep an eye on performance if reversed iteration occurs frequently with large data sets.


79-81: Use caution with large data sets.

Clear() quickly empties the B-tree, which is great for performance. Just be mindful of memory usage if large sets are cleared repeatedly within short intervals.


95-97: Helper function is straightforward.

newItem[V any] is a useful constructor for clarity, reinforcing the key-value pairing.

store/cachemulti/store.go (3)

41-45: Wrap vs. double wrap.

The direct call to store.CacheWrap() ensures consistent usage. Double-check that repeated wrapping won't degrade performance if done frequently.


164-170: Added getCacheWrap.

Centralizing store retrieval with proper nil checks helps maintain consistency. The panic on a missing or invalid store is consistent with existing behavior, though it might be harsher than returning an error.


172-179: Strict KVStore retrieval.

Casting to types.KVStore and panicking if invalid is standard for this codebase. Just confirm at a higher level that the store is always guaranteed to be typed as KV before usage.

store/internal/btree/memiterator.go (9)

12-12: Validation with interface compliance.

var _ types.Iterator = (*memIterator[[]byte])(nil) is a helpful compile-time check to ensure memIterator meets the required interface.


34-46: Ascending vs. descending logic.

Using Seek for ascending or descending positioning is straightforward. Confirm that transitioning from end to Prev() does not skip any valid items in edge cases.


67-69: Implementing Domain.

The domain boundaries reflect the original iteration limits. For clarity, consider docstrings on whether these are inclusive or exclusive.


71-74: Resource release.

Releasing the underlying btree iterator is crucial. The Close() method is minimal and correct.


76-81: Error check for invalid iterator usage.

Returning an error if the iterator is invalid is fine, though sometimes code uses nil error to indicate iteration is done. Confirm usage in external code.


83-85: Valid method returns the correct flag.

No issues here—just ensure no concurrency modifies mi.valid.


87-99: Next for iteration.

Next() logic is consistent with ascending or descending. The second range check in mi.keyInRange(...) is a good safety measure.


111-113: Key retrieval.

Returning the raw byte slice is typical in the Cosmos SDK store design. Confirm that externally, no modification of the returned slice is performed.


119-123: Enforce iterator validity.

assertValid panics if invalid. This is consistent with store error handling, but do confirm that panic is desired over a simple no-op or error return.

store/types/store.go (3)

131-131: Consider documenting store type-check behavior.

While this new method aligns with the existing pattern (e.g., GetKVStore), if a StoreKey of the wrong type is passed, the method may panic. Consider documenting the panic condition or returning an error to handle these cases more gracefully.


231-294: Validate usage of generics and verify test coverage.

The introduction of GBasicKVStore[V], GKVStore[V], and GIterator[V] increases type safety and flexibility, but thoroughly verify calls and test coverage to ensure existing consumers handle the new generic APIs correctly (e.g., potential nil values, type mismatches, or serialization quirks).


590-602: Good addition for creating multiple object store keys.

This helper function aligns well with NewKVStoreKeys and NewTransientStoreKeys. No concerns here aside from ensuring any naming collisions are properly handled (the assertNoCommonPrefix call addresses this).

store/CHANGELOG.md (1)

32-35: Entry looks good.

Adding a dedicated "Features" section and listing support for object stores helps keep the changelog transparent.

store/listenkv/store_test.go (1)

273-276: Updated test to match new CacheWrap implementation behavior

The test has been updated to no longer expect a panic when calling store.CacheWrap(). This aligns with the implementation change in store/listenkv/store.go where the CacheWrap method now returns a wrapped cache store instead of panicking.

types/context.go (1)

352-355: New ObjectStore API added to Context

This addition introduces object store support to the Context, complementing the existing KVStore and TransientStore methods. The implementation correctly wraps the object store with gas metering capabilities.

The implementation follows the same pattern as the existing store access methods, maintaining consistency in the API design. This is part of a larger change to support object stores throughout the codebase.

store/listenkv/store.go (2)

6-6: New import added for cachekv package

Added the cachekv import to support the updated CacheWrap implementation.


136-136: CacheWrap now creates a cache wrapper instead of panicking

The CacheWrap method implementation has been updated to return a cache-wrapped store instead of panicking. This is a significant behavioral change that improves the functionality of the ListenKVStore by allowing it to be cache wrapped.

This change aligns with the overall architectural improvement of making store types more consistent in their support for caching operations. The corresponding test in store_test.go has been updated to reflect this behavior change.

store/tracekv/store_test.go (1)

284-287: Updated test to match new CacheWrap implementation behavior

The test has been updated to no longer expect a panic when calling store.CacheWrap(). This indicates that the CacheWrap method in the corresponding implementation file has been modified to properly return a cache-wrapped store instead of panicking.

This change is consistent with similar updates made to the ListenKVStore implementation, showing a systematic approach to improving cache wrapping support across different store types.

x/group/internal/orm/testsupport.go (1)

29-30: Updated KVStore method to use type assertion

The method has been changed to retrieve a generic store with GetCommitStore and then cast it to storetypes.KVStore. This modification aligns with the broader changes in the PR to support multiple store types, including the new object stores.

store/tracekv/store.go (1)

164-166: Fixed CacheWrap implementation to delegate to parent instead of panicking

The CacheWrap method has been updated to properly delegate to the parent store's implementation rather than panicking. This is a significant improvement as it allows trace KV stores to be used in contexts where cache-wrapping occurs, making the API more consistent with other store implementations.

runtime/module.go (2)

70-70: Added ObjectStoreKey provider to module registration

The ProvideObjectStoreKey function has been added to the list of providers in the init() method, enabling modules to request object store keys via dependency injection.


229-233: Implemented ProvideObjectStoreKey function

The ProvideObjectStoreKey function creates a new object store key with a namespaced format (object:<module_name>) and registers it with the application builder. This implementation follows the same pattern as the other store key providers, ensuring consistency in how different store types are created and registered.

baseapp/baseapp.go (1)

308-310: Added ObjectStoreKey support to MountStores method

The MountStores method has been extended to handle *storetypes.ObjectStoreKey types, routing them to the appropriate store type. This enables the application to mount object stores alongside other store types.

store/cachekv/search_benchmark_test.go (3)

7-7: New import for B-tree usage.
Importing "cosmossdk.io/store/internal/btree" aligns with the move to generic B-tree implementations.


25-30: Using generics for cValue.
Defining map[string]*cValue[[]byte]{} and storing &cValue[[]byte]{} improves type safety for byte slice values. This approach looks correct and consistent with the rest of the generics refactoring.


39-44: Returning a generic GStore.
Returning &GStore[[]byte]{...} is an appropriate way to integrate the new generics-based store. Ensure existing benchmark logic is still valid under this generic approach.

Could you confirm that the benchmark results remain consistent (or improved) with these generic changes?

store/internal/btreeadaptor.go (5)

11-12: Interface compliance check.
Declaring _ types.KVStore = (*BTreeStore[[]byte])(nil) confirms BTreeStore[[]byte] fulfills the KVStore interface, which is good practice.


13-19: Struct embedding BTree.
Embedding btree.BTree[V] and storing isZero, valueLen callbacks is a clean design for a generic store.


20-23: Factory method for BTreeStore.
NewBTreeStore is straightforward. No issues noted.


46-49: Store type set to DB.
Returning StoreTypeDB is correct if this store truly behaves like a persistent database. Confirm this type aligns with planned usage (versus transient or object store).

Do you intend for this to appear as StoreTypeDB in the multi-store?


51-54: CacheWrap bridging to GStore.
CacheWrap returning cachekv.NewGStore is consistent with the dynamic layering approach.

store/transient/store.go (14)

14-16: Additional interface checks for ObjStore.
These lines confirm ObjStore fulfills both Committer and ObjKVStore. Good for clarity.


19-21: Generic GStore type.
Embedding internal.BTreeStore[V] under GStore[V] is consistent with the new generics strategy.


23-26: NewGStore constructor.
Neatly builds on internal.NewBTreeStore. Straightforward approach to constructing a transient store.


28-31: Store struct specialized for []byte.
Wrapping GStore[[]byte] under Store is a clean composition approach.


34-38: NewStore method.
Initializes the store with default isZero and valueLen lambdas for []byte. Looks good.


40-42: GetStoreType = StoreTypeTransient.
This is consistent with an in-memory ephemeral store.


44-47: ObjStore struct specialized for any.
Wrapping GStore[any] under ObjStore is suitable for generic object usage.


49-54: NewObjStore method.
Defaults for isZero and valueLen are placeholders, but likely correct for flexible object usage.


56-57: ObjStore → StoreTypeObject.
Appropriate for a specialized object store.


62-64: Commit clears transient data.
Invoking ts.Clear() upon commit is appropriate for this ephemeral store.


67-67: No-op pruning.
Transient stores do not require standard pruning. This is consistent with the approach.


71-72: GetPruning returns undefined.
This effectively signals that pruning is not handled within transient stores.


76-76: LastCommitID returns empty.
Transient store commits do not persist, so returning an empty commit ID is logical.


80-80: WorkingHash returns empty.
Empty or zeroed hash is appropriate for a store that does not persist data.

store/rootmulti/store.go (9)

180-190: Confirm panic strategy for type mismatch.

GetCommitKVStore panics if the underlying store isn't a CommitKVStore. This is consistent with typical Cosmos SDK patterns, but consider if returning an error would benefit graceful error handling.


239-239: Use consistent map initialization.

newStores := make(map[types.StoreKey]types.CommitStore) aligns with the updated store interface. Looks good for storing various CommitStore implementations.


631-637: Parallel structure to ascending iteration logic.

Similar re-wrapping for reverse iterators is correctly handled here. No immediate concerns.


652-652: Retrieve only once.

store := rs.GetCommitStore(key) in GetStore is succinct. No further issues.


671-674: Maintain consistent error handling.

Panicking on a non-KV store is consistent with other store retrieval methods. Ensure unexpected store types are never passed here to avoid chain halts.


686-699: Introduce new ObjKVStore retrieval.

GetObjKVStore parallels GetKVStore with a panic if type assertion fails. This unblocks mounting different store types. Looks fine.


1027-1080: Load approach for object stores.

Support for StoreTypeObject in loadCommitStoreFromParams extends multi-store functionality. Validate usage of the new NewObjStore() or analogous constructor to avoid mismatched store types.


1092-1092: Transient/memory/object store skip logic.

Skipping commit logic for ephemeral or object-based stores prevents extraneous overhead. This approach appears consistent with how non-persistent data is handled.


1230-1230: Conditional commit filter.

Excluding transient, memory, and object stores from commit steps ensures correct bounding of persistent data. No issues spotted.

store/prefix/store.go (14)

13-16: Define generic store aliases.

Introducing Store as GStore[[]byte] and ObjStore as GStore[any] expands usage beyond byte arrays. Looks good.


18-21: Interfaces implemented.

Declaring that Store implements types.KVStore and ObjStore implements types.ObjKVStore clarifies type coverage. No concerns.


23-29: New prefix store constructor.

NewStore sets up a custom isZero and valueLen for byte slices, ensuring correct validations. Looks solid.


31-37: Initialize object store with generic checks.

NewObjStore leverages any for the value type with a fixed length in gas calculations. This is consistent and flexible.


42-43: Embed type-aware behavior in GStore.

Functions isZero and valueLen let the same GStore handle different type definitions across prefix sub-stores. No immediate issues.

Also applies to: 46-47


50-54: Generic constructor is consistent with store types.

NewGStore properly assigns the parent and prefix, and sets the isZero/valueLen callbacks. This design fosters reuse.


70-70: Key function enforces non-nil.

key() method panics if key is nil. This is in line with the rest of the cosmos-sdk store logic. Looks good.


79-85: Override of GetStoreType.

Maintaining the underlying parent's store type is standard. No issues found.


97-99: Delete usage is straightforward.

Nothing unusual. The prefix is appended to identify the correct subrange for deletion.


120-134: Iterator range construction.

cloneAppend usage ensures correct prefixing. The logic for newend is consistent with prefix store patterns.


138-150: Reverse iterator parallels forward iteration.

Uses the same prefixing approach but in reverse. No issues spotted.


153-153: Ensure no data race.

var _ types.Iterator = (*prefixIterator[[]byte])(nil) is a compile-time check. Harmless but helpful.


155-160: Generic prefixIterator logic.

Properly strips prefixes, maintains iteration validity, and returns typed values. The approach is consistent with existing prefix store iteration patterns.

Also applies to: 163-170, 179-211


221-229: Error method ensures uniqueness.

Returning an error if the iterator is invalid matches typical usage. No concerns about partial iteration states.

store/gaskv/store.go (15)

14-15: New type alias for Gas store.

Store = GStore[[]byte] fosters consistency with other store definitions. Good addition.


16-21: Gas-wrapped store constructor.

Initializes GStore with specialized isZero and valueLen for []byte, ensuring correct gas usage for standard KV ops.


32-41: Generic structure for gas usage.

Embedding gasMeter, gasConfig, parent, and type functions is consistent with a typed store pattern. No problems.


43-59: Parametric constructor for GStore.

Combines parent store, meter, config, and callback functions. Straightforward approach.


62-64: Respect parent's store type.

GetStoreType() defers to the underlying store. Aligns with how other composite stores are implemented.


79-86: Gas usage on Set.

Similar to Get, we have both a flat cost and a cost per byte. The callbacks isZero and valueLen ensure correctness for the stored type.


90-93: Gas usage on Has.

Has incurring a fixed cost is consistent with existing gas accounting. This is typical.


96-100: Delete cost.

Even though space is freed, some cost is consumed to deter malicious patterns. Looks appropriate.


102-115: Iterators with gas usage.

iterator() method returns a specialized gasIterator that charges appropriately. Straightforward solution.


117-125: Disable cache wrapping.

Panicking on CacheWrap or CacheWrapWithTrace is expected in a gas store setting. This is consistent with the approach to not double-wrap gas logic.


127-139: Construct gasIterator.

The nested logic for ascending/descending iterators is standard, ensuring gasIterator intercepts read calls. No issues.


141-146: gasIterator structure & constructor.

gasConfig plus valueLen callback preserve typed usage. Clean design continuing the pattern.

Also applies to: 148-154


158-165: Next usage for iteration cost.

Consuming gas for each seek step is consistent with the distributed ledger's cost model.

Also applies to: 167-173


184-186: Value accessor.

No additional gas cost for returning the current value is consistent with typical store designs.


189-191: Close & Error forwarding.

Simply delegates to the parent, as expected. No concerns.

Also applies to: 193-196

store/cachekv/internal/mergeiterator.go (13)

17-19: Fully generic struct enhancements.

Defining cacheMergeIterator[V any] and introducing the isZero function nicely generalizes zero-value detection. Ensure that implementers remember to handle any potential panics if isZero is inadvertently set to nil.

Also applies to: 24-24


27-27: Compile-time interface check.

This assignment to _ enforces a compile-time check ensuring cacheMergeIterator[[]byte] implements types.Iterator. This pattern is correct and commonly used in Go for interface compliance.


43-43: Domain method remains consistent.

No issues found with this method’s updated signature; it smoothly forwards to the parent’s domain, preserving existing domain semantics.


48-48: Valid method consistency.

The Valid() method retains expected behavior; no concerns.


53-53: Next method clarity.

The Next() logic correctly merges parent and cache iterators. No performance pitfalls detected.


80-80: Key method correctness.

Appropriately handles priority in the merge logic. No issues found.


110-110: Value method correctness.

The method merges the value logic consistently with the parent or cache. Looks good.


140-140: Close method concurrency safety.

Closing both iterators is straightforward and error handling is consolidated. This is correct and safe as no concurrency is involved here by design.


151-151: Error method alignment.

Method returns an error if invalid—consistent with the Valid() check. No concerns.


161-161: Assertion handles invalid state properly.

Panicking on an invalid iterator is consistent with the store’s approach. Proceed.


168-168: compare function inversion logic.

Flips sign for descending order; correct use of bytes.Compare. No issues.


181-183: skipCacheDeletes uses zero-value logic.

Replacing nil-check with isZero accommodates any type. Implementation is coherent. Ensure isZero remains consistent with how values are stored.


192-192: skipUntilExistsOrInvalid zero-value handling.

Handling deletes by checking isZero(valueC) is intuitive. The iteration logic properly skips invalid or deleted items. This is essential for correct cache-parent merging.

Also applies to: 217-217, 229-229

store/cachekv/store.go (18)

13-13: New btree import.

Importing "cosmossdk.io/store/internal/btree" is expected for the new generic B-tree usage. Looks good.


21-28: Generic cValue and kvPair definitions.

Introducing cValue[V any] and kvPair[V any] provides flexibility for arbitrary value types. The approach is clean and aligns with the overall generics refactor.


31-32: Type alias for backward compatibility.

type Store = GStore[[]byte] preserves existing references to Store while adopting generics under the hood. This is a good bridging strategy.


36-42: Refactored NewStore constructor.

NewStore now delegates to NewGStore, providing specialized isZero and valueLen for []byte. Implementation is straightforward.


43-58: Thread-safe GStore struct with zero-value checks.

Storing isZero and valueLen function pointers is a flexible design. No immediate concurrency issues are visible, given the sync.Mutex.


59-69: NewGStore generic constructor.

Constructs the store with typed parent and B-tree. Make sure isZero and valueLen remain consistent with any custom logic in advanced usage.


71-72: Preserved store type.

GetStoreType() defers to the parent’s store type, preserving existing semantics. No concerns.


77-77: Get method generification.

Properly locks the store, fetches values from cache or parent, and caches them. Basic logic remains unchanged except for the generic type. Good approach.


95-97: Set method with generic validation.

Using AssertValidValueGeneric is an excellent approach to ensure correctness across multiple value types. Implementation is clear and consistent.


105-107: Has method uses isZero.

Replacing nil-check with !isZero(value) is consistent with the new generic design. No issues.


111-117: Delete method sets zeroValue.

Replaces the entry with a zero value rather than removing from the map, aiding iteration logic. Implementation looks consistent with the new design.


120-120: resetCaches method.

Large cache resets are a known optimization technique. Re-initializing sortedCache = btree.NewBTree[V]() also makes sense to handle big sets. LGTM.

Also applies to: 126-126, 139-139


142-142: Write method improvements.

• Locks for thread safety.
• Rebuilds a local slice from dirty entries, sorts, and writes them to the parent.
• Uses store.resetCaches() to free memory.

Everything aligns with the new generics approach.

Also applies to: 143-143, 148-148, 155-155, 180-180


189-190: CacheWrap refactor.

CacheWrapWithTrace gracefully wraps the trace store only when working with []byte. For other generic types, it falls back to a standard cache wrap. Clever approach.

Also applies to: 193-198


205-206: Iterator methods.

Delegates domain-specific iteration to the new generic iterator function. No issues.

Also applies to: 210-211


214-215: iterator function hooking into NewCacheMergeIterator.

Combines an isolated copy of sortedCache with the parent’s iterator. The usage of internal.NewCacheMergeIterator ensures consistent detection of zero-value deletes. Nicely done.

Also applies to: 218-219, 223-224, 237-238


335-335: dirtyItems domain filtering.

Builds a slice of only the unsorted keys within [start, end), then sorts them if needed. The logic looks correct and is consistent with existing boundaries.

Also applies to: 339-339, 343-344


396-398: clearUnsortedCacheSubset & setCacheValue.

Clearing or removing from unsortedCache by referencing kvPair[V] keys, then inserting into sortedCache, is consistent with the multi-level caching approach.
The new setCacheValue design storing zero-value for deletes is also coherent.

Also applies to: 424-424, 427-428

@github-actions github-actions bot added the C:CLI label Apr 11, 2025
@aljo242 aljo242 added the v54 label Apr 14, 2025
@aljo242 aljo242 removed the v54 label May 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants