Conversation
|
Thanks for this. The range-filter design holds up: I could not find a path where a filtered load is persisted or seeds a sealed day, and the guards read well. It cannot merge yet though. Blocker: this PR does not build on its own. On this head, Then, before we look again:
|
01d856c to
24ff6c0
Compare
Session month shards decode incrementally (one turn at a time, keeping only in-range turns with the exact kept/dropped/carry contract); shard loads run serially with the pre-lock snapshot released before the canonical reload. Out-of-range turns contribute raw dedup keys to cross-file suppression markers; retained strings detach from tokenizer buffers. The codex result cache rewrite, digest wiring, and aggregate parse mode follow as stacked PRs.
24ff6c0 to
9986edb
Compare
|
Thank you for splitting this. The split worked: this head compiles on its own, tsc is clean, and the 111 touched tests pass against this commit alone. The numbers are exact too. I diffed the full JSON export leaf by leaf against main, cold and warm, for today, week, 30days, month and all. The only difference is the known But as it stands this cannot merge. It is about 12 times slower than main and, on its own, uses more memory too. That is not acceptable for us: this is the path the desktop app and the menu bar poll all day, and we have just spent a release cutting their CPU use. Warm cache, medians of 3, this head vs main:
So on I profiled it ( The comparison that settles it: the whole 166MB of session shards parses in 333ms with plain What I am asking for: gate on file size. Rebase after 0.9.25 lands please. Against main you conflict in |
Per-string flattening at assembly copied every string of every turn (kept or dropped): ~829k turns x dozens of strings of Buffer + string churn that GC could not retire under a heap cap, dying in the sept shard at ~500MB live. streamShardArrayField takes detachStrings (default true); the filtered loader passes false and flattens only what it keeps (kept turns + meta at fold time, carry refs + first project in finishSlice). (cherry picked from commit 1b30177)
The streaming walk costs 15-20s where JSON.parse needs milliseconds (525MB of shards in ~11s on this corpus); it exists for the one shard past V8's max string length. Shards at or under 256MB now take plain JSON.parse through the same per-record projection (filterShardFile / validateCachedFile); larger ones stream exactly as before. A single readFile is already an atomic snapshot, so the small path needs no fingerprint guard. Byte-identical results on both paths are pinned by the size-gate parity suite (kept, sliced, PR-whole, key-overlap, all-dropped, invalid).
|
Gate is in: |
Fixes #1504 (session-shard half; the codex-cache rewrite and digest wiring follow as stacked PRs).
What was wrong
Ranged loads assembled whole multi-hundred-MB month shards before filtering, and the pre-lock snapshot overlapped the canonical reload (~787MB duplicate live at once). Retained strings were tokenizer slices pinning whole input chunks.
What changed (this PR)
SHARD_STREAM_GATE_BYTES = 256MB, shared inshard-stream.ts): shards at or under the gate decode with plain JSON.parse through the same per-record projection; larger ones stream exactly as before. Byte-identical results on both paths are pinned by the size-gate parity suite (kept, sliced, PR-whole, key-overlap, all-dropped, invalid).Out of scope here by design: the codex result-cache rewrite (stacked PR #1508, follows the same gate), digest wiring of the marker keys (stacked follow-up), aggregate parse mode (stacked PR #1503).
Verification
Timings (warm cache, medians of 3, 1.2GB shard corpus with one 697MB shard)
overview -p todayreport --period today --format jsonThe gate restores speed to ~1.3x main (from ~5.5x). The residual is the one over-gate shard still streaming plus per-turn filtering; memory on a corpus this size is dominated by the retained result set itself (main peaks 3GB here). On smaller corpora the detach commit is where the memory win lands (see the stack top).