Skip to content

triedb: expose node-cache counters via FFI - #2506

Open
maxkozlovsky wants to merge 1 commit into
max/node-cache-statsfrom
max/node-cache-ffi
Open

triedb: expose node-cache counters via FFI#2506
maxkozlovsky wants to merge 1 commit into
max/node-cache-statsfrom
max/node-cache-ffi

Conversation

@maxkozlovsky

Copy link
Copy Markdown
Contributor

Add triedb_node_cache_stats_read -> TriedbHandle::node_cache_stats(), mirroring triedb_storage_stats_read, so monad-node can export the trie node cache as Prometheus metrics.

Each triedb handle owns an independent NodeCache, so these are per-handle and not comparable across handles. used_bytes and entries accompany the hit/miss/eviction counts because the cache is bounded twice -- by node_lru_max_mem and by the slot count derived from it -- and only the pair shows which bound is binding.

Copilot AI lite review requested due to automatic review settings August 20, 2026 22:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds per-handle trie node-cache statistics through the Rust/C++ FFI for Prometheus metrics.

Changes:

  • Adds NodeCacheStats and TriedbHandle::node_cache_stats().
  • Exposes the C ABI reader and generated Rust bindings.
  • Reports cache counters, memory usage, and entry counts.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Summary Final review comments
rust/crates/monad-triedb/src/lib.rs Adds the public stats type and accessor. [P2] nit (2 votes): Document synchronous traversal as uncached because it bypasses AsyncContext::node_cache and may report zero stats.
rust/crates/monad-triedb/src/ffi.rs Exposes generated FFI bindings. No final comments.
rust/crates/monad-triedb/src/ffi.cpp Implements cache-stat extraction. [P1] critical (2 votes): Snapshotting used_bytes() and size() can race with async cache mutations because AsyncContext is not thread-safe. Serialize snapshots or add synchronization/atomic state, and document calling discipline.
rust/crates/monad-triedb/include/ffi.h Declares the C ABI contract. [P2] nit (2 votes): Clarify that synchronous traversal is not cache-backed; only the async traversal paths use the cache.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread rust/crates/monad-triedb/include/ffi.h Outdated
Comment on lines +70 to +72
// Covers triedb_async_read and the traverse calls only. triedb_read is a
// blocking path that consults no cache, so a caller using it exclusively sees
// zeros here — which is not the same as an unused cache.
Comment on lines +208 to +209
out->used_bytes = static_cast<uint64_t>(cache.used_bytes());
out->entries = static_cast<uint64_t>(cache.size());
Comment thread rust/crates/monad-triedb/src/lib.rs Outdated
Comment on lines +323 to +324
/// Only the async read and traverse paths consult the cache; [`Self::read`]
/// is blocking and uncached, so a caller using it exclusively sees zeros.
Comment on lines +74 to +86
// Returns false without writing `out` if no counters are available; all-zero
// is a legitimate reading for an idle cache, so it cannot double as an error.
typedef struct triedb_node_cache_stats
{
uint64_t hits;
uint64_t misses;
uint64_t evictions;
uint64_t used_bytes;
uint64_t entries;
} triedb_node_cache_stats;

bool triedb_node_cache_stats_read(
TriedbRoInner *, triedb_node_cache_stats *out);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P2] The header advertises a "no counters available" false-return, but the implementation in ffi.cpp only returns false when db == nullptr or out == nullptr — a well-formed caller can never observe a non-null false. Cascading to TriedbHandle::node_cache_stats -> Option<NodeCacheStats>, the None branch is unreachable (self.db_ptr is non-null for any TriedbHandle produced by try_new), which defeats the commit-message intent to mirror triedb_storage_stats_read. Either drop the boolean return (and the Rust Option) to match the storage-stats shape, or tighten the doc to say the boolean signals only null-pointer misuse.

Add triedb_node_cache_stats_read -> TriedbHandle::node_cache_stats(),
mirroring triedb_storage_stats_read, so monad-node can export the trie node
cache as Prometheus metrics.

Each triedb handle owns an independent NodeCache, so these are per-handle and
not comparable across handles. used_bytes and entries accompany the
hit/miss/eviction counts because the cache is bounded twice -- by
node_lru_max_mem and by the slot count derived from it -- and only the pair
shows which bound is binding.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants