Repository navigation
perf: an appended file leaving the window stays incremental (#99) - #114
Conversation
|
🤖 Automated first-pass review The configured analysis model did not return a usable analysis for this pull request. The item has still been received and remains available for maintainer review. To help with review, please ensure the change summary, tests, and any user-facing documentation or localization updates are included. 🤖 Posted automatically by CCU Bot — not a maintainer decision. |
…deUsage#99) Follow-up to the previous window-drift fix, from the same measurement: full rebuilds became rare but did not stop, and the remaining ones each cost 50-120 s of parse time. The remaining cause is the file that is appended to in the very refresh where one of its own events leaves the window. Its stored aggregate still counts the expired event, so a tail read cannot serve it and the file has to be re-read in full. Until now that made it indistinguishable from a mid-file edit — it was planned as 'source', which rejects the analysis fast path and re-reads every body. On a machine with several agents the pairing is routine: sessions append constantly, and on a long history the window is always drifting past something. Such a file only grew. It keeps every UUID it owned and can gain only new ones, which is exactly the shape of a plain append, so it is planned as 'window' and allowed on the fast path — and, like an append, it is put through the ownership probe after parsing: if one of its lines carries a UUID owned by a later file, the full rebuild still happens. A genuine mid-file edit remains 'source', since the append prefix and boundary checks are what tell the two apart. The same reason covers the second shape of the pairing, where the cheap rebase succeeds but changes the payload: that append was already being downgraded to a rebuild, and it is a window rebuild too, not a source edit. Test: `a file that is appended to while losing an event to the window stays incremental` — it fails on the parent commit with "re-read the whole corpus: 8 bodies" and asserts the result equals what the full loader produces. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
841d542 to
79d9993
Compare
Parse changed Claude files in canonical order when an append and a window rebuild happen together. The new regression fails before this fix and matches the full loader afterward. Co-authored-by: OpenAI Codex <215057067+openai-codex[bot]@users.noreply.github.com>
|
Thanks @rsyuzyov for the careful profiling and the follow-up to #113. The append-plus-expiry case is a meaningful improvement for long Claude histories. During review I added a mixed-file UUID ownership regression and a small ordering correction in this same PR, so the incremental result still matches the full loader. I appreciate the measured results and the clear explanation. Merged after the Node, UI, and package checks passed. 🤖 Generated with OpenAI Codex |
Builds on #113 — its commit is the first of the two here, so please take #113 first and this will shrink to the second commit. Same profiling session as #109/#111/#112.
What is left after #113
#113 stopped the window's ordinary drift from forcing a full rebuild: full rebuilds went from 136 of 140 refreshes to 3 of 53. The ones that remained still cost 50-120 s each, and they had a single cause — the file that is appended to in the very refresh where one of its own events leaves the window.
Its stored aggregate still counts the expired event, so a tail read cannot serve it: the file genuinely has to be re-read in full. Until now that made it indistinguishable from a mid-file edit — it was planned as
'source', which rejects the fast path and re-reads every body. On a machine running several agents the pairing is routine, because sessions append constantly and on a long history the window is always drifting past something.Worth noting how invisible this was from the source: such a file is classified in the
needsAnalysisBodybranch, which runs before the append/rebuild classification below it, and both produce akind: 'rebuild'plan. Only a debug run made it visible that one plan was being turned into 683.Why this is safe
Such a file only grew. It keeps every UUID it owned and can gain only new ones — the same shape as a plain append. So it is planned as
'window', allowed on the fast path, and put through the same ownership probe after parsing that a plain append gets: if one of its appended lines carries a UUID owned by a later file, the full rebuild still happens.A genuine mid-file edit stays
'source': the append prefix and boundary checks are exactly what tell the two apart, and they are whatgrewOnlyevaluates.The same reason covers the other shape of the pairing, where the cheap rebase succeeds but changes the payload — that append was already being downgraded to a rebuild, and it is a window rebuild too, not a source edit.
Test
a file that is appended to while losing an event to the window stays incremental— it fails on the parent commit with "an appended file losing an event re-read the whole corpus: 8 bodies", and it assertscontentAnalysisequals what the full loader produces, so agreement is checked alongside the speed.Measured
Same machine and history as #113, one hour of ordinary work with several agents appending:
One of those three is the legitimate cold start, so the remaining full rebuilds went from roughly one every three minutes to one every half hour. I have not chased what causes the last two, and this change does not claim to.
Full test run matches
mainon my machine: the same 8 pre-existing failures (Windows symlink and file-locking tests), plus the new test.🤖 Generated with Claude Code