Skip to content

fix(memory_tree): code quality improvements on batch tree fetch (PR #2976 follow-up) - #3020

Merged
senamakel merged 5 commits into
tinyhumansai:mainfrom
staimoorulhassan:fix/pr-2976-batch-tree
May 30, 2026
Merged

senamakel merged 5 commits into
tinyhumansai:mainfrom
staimoorulhassan:fix/pr-2976-batch-tree

Conversation

@staimoorulhassan

@staimoorulhassan staimoorulhassan commented May 30, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Follow-up to PR #2976 (perf(memory_tree): batch tree fetch in flush_stale_buffers).

Update (post-merge): #2976 has since merged into main (commit 24f2b502b) with the quality fixes folded in — the SQL-injection SAFETY comment on the get_trees_batch format!(), the bounded-batch debug logging, and the multi-tree regression test all landed there. After merging current main into this branch and resolving the conflicts, this PR's only remaining net change is the dedup-ordering comment below; store.rs is now byte-identical to main.

Net change vs main

  • Dedup comment (flush_stale_buffers) — document that the HashSet+Vec dedup is purely for DB efficiency (fewer bind params), not for semantic ordering: the per-buffer loop walks stale directly and list_stale_buffers order is preserved.

The other items originally proposed here (SQL safety comment, params_from_iter vs explicit Vec<&dyn ToSql>, the regression test) are already present on main via the merged #2976, so they are intentionally not re-applied — re-churning approved-and-merged code would add divergence with no functional benefit.

Test plan

  • cargo fmt --check — clean.
  • cargo check (core) — clean.
  • All tests in memory_store::trees:: and memory_tree::tree::flush:: pass, including flush_seals_multiple_distinct_trees_via_batched_lookup (38 passed).
  • prettier --check — clean (no TS changes).

Summary by CodeRabbit

Release Notes

No user-facing changes. This release includes internal code improvements and clarifications to enhance code maintainability.

Review Change Stack

mysma-9403 and others added 3 commits May 29, 2026 20:52
`memory_tree::tree::flush::flush_stale_buffers` previously issued
`store::get_tree(config, &buf.tree_id)?` once per stale buffer — one
SQLite round-trip per row returned by `list_stale_buffers`. On hosts
with many stale L0 buffers (e.g. after a long backfill or a cron miss)
each flush pass paid N round-trips before the cascade even started.

Replace the per-buffer loop with one upfront batched read:

- `memory_store::trees::store::get_trees_batch(config, &[ids])
  -> Result<HashMap<String, Tree>>`

`flush_stale_buffers` now dedups buffer tree_ids into a `HashSet`,
issues one `SELECT … WHERE id IN (?,?,…)` (1 round-trip), then per-id
HashMap lookup routes each buffer to its own `Tree` for
`cascade_all_from`. The L0-only filter in `list_stale_buffers` keeps
the same tree_id at most once today, but the dedup is defensive
against future widenings of that filter that would otherwise re-pay
the cost.

### Defensive chunking — TREES_MAX_FETCH_BATCH = 500

`get_trees_batch` iterates via `chunks(TREES_MAX_FETCH_BATCH)`.

- SQLite's compile-time `SQLITE_MAX_VARIABLE_NUMBER` has been ≥ 32 766
  since 3.32 → 500 leaves a ~65× safety margin.
- The `flush_stale_buffers` call-site passes the deduped distinct
  tree_id set (typically << 500 in practice) → runs as one query.
- Loop is purely defensive: future callers passing larger id lists
  will not blow up against a host with a lower compile-time SQLite cap.
- No volume reduction: all input ids in → all matching rows out; the
  merged HashMap is byte-identical to one giant query.

### Semantic preservation — no behavioural change

- `get_trees_batch` reuses `row_to_tree` so decoded `Tree` values stay
  bit-identical to the per-row path.
- Missing ids stay silently absent from the HashMap, mirroring the
  per-row `get_tree` `Ok(None)` contract — the existing orphan-buffer
  warn-and-skip path keeps working unchanged.
- Per-buffer iteration order preserved by walking `stale` directly;
  HashMap lookup keys by `&buf.tree_id`.

### Tests

- `get_trees_batch_returns_present_ids_in_map` — both ids present,
  decoded `Tree` equal to the per-row path bit-for-bit.
- `get_trees_batch_empty_input_and_missing_ids` — empty input → empty
  map (no SQL); missing id silently absent so callers keep their
  `Ok(None)` skip path.
- `flush_seals_multiple_distinct_trees_via_batched_lookup` — two real
  trees each carry a stale L0 buffer; flush seals both via the batched
  fetch. Pins the HashMap-keyed-by-id contract: swapping the lookup
  key to position would route buffers to the wrong `Tree` and
  mis-write summaries against the wrong `root_id`.

### Companion to tinyhumansai#2927 / tinyhumansai#2941 / tinyhumansai#2948

Same playbook as the topic-rerank batch (tinyhumansai#2927), `fetch_leaves` batch
(tinyhumansai#2941), and `hydrate_summary_inputs` batch (tinyhumansai#2948): partition / batch
/ decorate. Different table, different call-site, same pattern.
- Add SQL-injection-safe comment on format!() in get_trees_batch
- Replace raw Vec<&dyn ToSql> with idiomatic params_from_iter
- Document that dedup in flush_stale_buffers is for DB efficiency only
- Rename and clarify the batched-flush regression test
@staimoorulhassan
staimoorulhassan requested a review from a team May 30, 2026 13:30
@coderabbitai

coderabbitai Bot commented May 30, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 495cdc9a-f454-4ac0-85bb-53abd8a76dba

📥 Commits

Reviewing files that changed from the base of the PR and between 48aa6d9 and 7a93470.

📒 Files selected for processing (1)
  • src/openhuman/memory_tree/tree/flush.rs
💤 Files with no reviewable changes (1)
  • src/openhuman/memory_tree/tree/flush.rs

📝 Walkthrough

Walkthrough

This pull request adds clarifying inline comments to the flush_stale_buffers function that document the order-preservation requirement and intent of the tree ID de-duplication used in the batched tree lookup process.

Changes

Stale buffer flush logic clarification

Layer / File(s) Summary
Batching and de-duplication comments in flush_stale_buffers
src/openhuman/memory_tree/tree/flush.rs
Inline comments document that batched-tree lookup order is preserved for stable per-buffer loop control flow, and that distinct_tree_ids de-duplication is only for reducing database parameters, not for defining semantic ordering.

Possibly related PRs

  • tinyhumansai/openhuman#2976: Introduces the batched tree retrieval logic and stale buffer flush refactor that this PR clarifies with inline comments.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

Poem

🐰 A comment, brief and bright,
Clears the logic left and right!
"Order kept, no dups for show—
Just DB params kept low."
With clarity comes peace of mind,
Future readers, wisdom find! 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically refers to code quality improvements related to batch tree fetch operations, which matches the PR's main change: a clarifying comment in flush_stale_buffers about deduplication ordering.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added the memory Memory store, memory tree, recall, summarization, and embeddings in src/openhuman/memory/. label May 30, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 30, 2026

@oxoxDev oxoxDev left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed the code — the substance is good. get_trees_batch uses positional bind params (?1,?2,…, not interpolated, so not injectable), the 500-row batch cap stays under SQLite's 999-param limit, params_from_iter(window.iter().map(String::as_str)) is the right idiom, and the HashSet dedup → batch fetch correctly replaces the per-buffer get_tree calls. Rust Quality (fmt/clippy) is green.

Two things before merge:

  1. PR Submission Checklist is failing. It's the unchecked box on line 14:
    - [ ] cargo fmt --check — not runnable in this environment…
    Rust Quality already runs cargo fmt --check in CI and it passes here, so either check the box or mark it N/A: covered by Rust Quality CI gate (note: N/A must start the item text per the checklist parser).

  2. Overlap with #2976. This PR touches the same two files (memory_store/trees/store.rs, memory_tree/tree/flush.rs) as the still-open #2976, so they'll conflict. Could you fold this into #2976 (push these review fixes onto that branch) or close #2976 in favour of this one? Right now both are open with the same change. Happy to re-approve once it's a single PR with a green checklist.

@senamakel senamakel self-assigned this May 30, 2026
# Conflicts:
#	src/openhuman/memory_store/trees/store.rs
#	src/openhuman/memory_tree/tree/flush.rs
@senamakel

Copy link
Copy Markdown
Member

Merge conflicts resolved and main merged in — the PR is now mergeable again (was CONFLICTING).

Re: the two pre-merge items from @oxoxDev:

  1. PR Submission Checklist — done. cargo fmt --check, cargo check, and the tree/flush test suite (38 passed) all run clean locally now; the checklist boxes are ticked and the body updated to reflect it.

  2. Overlap with perf(memory_tree): batch tree fetch in flush_stale_buffers #2976 — this resolved itself: perf(memory_tree): batch tree fetch in flush_stale_buffers #2976 has since merged into main (24f2b502b), and it landed with the quality fixes folded in — the SQL-injection SAFETY comment on get_trees_batch, the bounded-batch debug logging, and the multi-tree regression test are all on main. After merging main into this branch, store.rs is now byte-identical to main, and this PR's only remaining net change is the dedup-ordering comment in flush_stale_buffers.

    I deliberately did not re-apply the originally-proposed params_from_iter swap or the test rename — those would churn already-merged, approved code with no functional benefit and re-introduce divergence from main.

    So there's no longer a competing open perf(memory_tree): batch tree fetch in flush_stale_buffers #2976 to fold into. The only call left is a human one: keep this PR open for the single dedup comment, or close it as effectively absorbed by perf(memory_tree): batch tree fetch in flush_stale_buffers #2976. Happy to go either way — flagging it rather than deciding unilaterally.

@senamakel
senamakel merged commit d08882b into tinyhumansai:main May 30, 2026
21 of 22 checks passed
@staimoorulhassan

Copy link
Copy Markdown
Contributor Author

E2E status: Lane 2/4 failure is in insights-dashboard spec (looking for a Memory heading) — completely unrelated to the Rust memory_store tree-batching changes in this PR. The Playwright E2E Gate passes. CodeRabbit has no actionable comments. This PR is ready for review/merge.

@staimoorulhassan staimoorulhassan left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

senamakel added a commit to senamakel/openhuman that referenced this pull request Jun 6, 2026
…inyhumansai#2976 follow-up) (tinyhumansai#3020)

Co-authored-by: Maciej Myszkiewicz <mmyszkiewicz@bwcoders.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
Co-authored-by: Taimoor <astikkosapparel009@gmail.com>
senamakel pushed a commit to nocstah/openhuman that referenced this pull request Sep 11, 2026
Ki-Will pushed a commit to Ki-Will/openhuman that referenced this pull request Sep 24, 2026
Ki-Will pushed a commit to Ki-Will/openhuman that referenced this pull request Sep 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

memory Memory store, memory tree, recall, summarization, and embeddings in src/openhuman/memory/.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants