Skip to content

refactor(state_store): per-component handle for fn-memo I/O#1990

Merged
georgeh0 merged 1 commit into
mainfrom
g/fn-memo-accessor
May 18, 2026
Merged

refactor(state_store): per-component handle for fn-memo I/O#1990
georgeh0 merged 1 commit into
mainfrom
g/fn-memo-accessor

Conversation

@georgeh0
Copy link
Copy Markdown
Member

Summary

Introduce FnMemoAccessor, a per-component handle that owns the read, write, and retain operations for FunctionMemoization entries under one component path. Engine code routes all per-component fn-memo I/O through this handle instead of calling AppStore::{read,write,retain}_fn_memo* directly.

  • The accessor is built once per ComponentProcessorContext and returned by reference (&FnMemoAccessor). Any future per-build state added to it (caching, instrumentation) persists across the many fn-memo lookups within one component's processing phase, rather than being re-created on every call.
  • The three former AppStore methods had no callers outside the accessor after the refactor, so they're inlined into it and removed from AppStore's public surface (~50 lines).
  • Three engine call sites updated to go through comp_ctx.fn_memo_accessor(): cache-probe read in read_fn_call_memo_with_txn, post-execute write in write_fn_call_memo, commit-time retain GC in Committer.

No behavior change.

Test plan

CI. Locally verified cargo test -p cocoindex_core --lib (30/30) and pytest python/tests/core/ (358/358).

- Introduce `FnMemoAccessor`, owning the read / write / retain operations
  for `FunctionMemoization` entries scoped to a single component path.
- Build it once per `ComponentProcessorContext` and return it by
  reference, so any future per-build state on the accessor (e.g. caching
  or instrumentation) persists across the many fn-memo lookups within a
  single component's processing phase, rather than being re-created per
  call.
- Inline the corresponding `AppStore::{read,write,retain}_fn_memo*`
  methods into the accessor; they had no remaining callers outside it.
  Shrinks `AppStore`'s public surface by ~50 lines.
- Update the three engine call sites (cache-probe read in
  `read_fn_call_memo_with_txn`, post-execute write in
  `write_fn_call_memo`, commit-time retain GC in `Committer`) to route
  through `comp_ctx.fn_memo_accessor()`.

No behavior change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@georgeh0 georgeh0 merged commit 192b60b into main May 18, 2026
14 checks passed
@georgeh0 georgeh0 deleted the g/fn-memo-accessor branch May 18, 2026 05:28
georgeh0 added a commit that referenced this pull request May 18, 2026
…1991)

Replace the previous `FnMemoAccessor` handle (#1990) with a `FnMemoCache`
that owns the function-memoization lifecycle at the engine layer.

- Eager prefix-scan prefetch at the start of build mode loads every
  fn-memo entry for the component into memory as `Stored(bytes)`.
- `reserve_memoization` no longer reads from the database. Cache slot is
  looked up (or inserted as `Pending` on cache miss); `Stored` entries
  are lazy-decoded on first access via `decode_stored_entry`.
- `finalize_fn_call_memoization` now walks the cache in memory and
  decodes `Stored` entries it reaches via dep chains — zero DB reads.
- Commit-time flush is one consolidated pass: per-entry write/delete
  when the cache is fully loaded; prefix-delete + write-new when it
  isn't (covers `full_reprocess` and delete mode).
- Net I/O per build: one prefix scan up front instead of O(N) point
  lookups during processing + one prefix scan at commit. Finalize's
  transitive dep walk drops from one point read per dep to zero.

Storage API changes:
- New: `list_fn_memos` (prefix read; layer-neutral name matching
  `list_child_existence` / `list_tombstones`), `delete_fn_memo`,
  `delete_all_fn_memos`.
- Drop: `read_fn_memo`, `retain_fn_memos`.
- `write_fn_memo` unchanged.

Engine API changes:
- New `FnCallMemoEntry::Stored(Vec<u8>)` variant; lazy-decoded.
- `FnMemoCache<Prof>` on `ComponentBuildingState` replaces the
  `fn_call_memos: HashMap<…>` field; carries an `is_fully_loaded` flag
  driving the flush strategy.
- `ComponentProcessorContext::prefetch_fn_memos()` runs in `execute_once`
  right after the build semaphore acquisition; idempotent and skipped
  under `full_reprocess` / delete mode.
- `Committer::commit_in_txn` / `commit` lose the
  `all_memo_fps` + `memos_without_mounts_to_store` parameters in favor
  of a single `fn_memos: FnMemoCache<Prof>` param.

Co-authored-by: Claude Opus 4.7 (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.

1 participant