Add adoptShadow instead of mergePreviousOrigin - #32
Open
kronaemmanuel wants to merge 2 commits into
Open
Conversation
bryntum/support#13520 When a transaction reads a committed, unchanged identifier, the shadow quark created for the read carries only the few new dependency edges - yet revision compaction merged in the opposite direction, copying every historical edge of the committed quark into the shadow (mergePreviousOrigin, O(all old edges) per identifier per commit). Project-wide identifiers such as startedTaskScheduling carry an edge per event (~27,000 in the reported dataset) and were copied wholesale on every live-update commit; profiling showed this merge as the hottest function on the main thread during scroll (~68% of long-task time). Replaced the merge with adoption: compactRevisions now folds the shadow's new edges into the previous quark (Quark.adoptShadow) and keeps the previous quark as the scope entry, materializing the same shadow-chain union that outgoingInTheFutureHelper already performs at traversal time - but in the O(new edges) direction. Committed state is only touched on the commit path, after markAndSweep has classified the previous revision unreachable, so transaction reject, branching (guarded by the existing referenceCount check) and history retention (guarded by eachReachableRevision) behave exactly as before. Measured: compaction time -96-98%, median commit 14.9 -> 5.2ms at 4k events and 23.4 -> 5.1ms at 10k (flat in dataset size); record and revision-scope digests byte-identical over 150 commits apart from a constant set of inert stale edges the merge used to prune (filtered by originId at traversal); 0 long tasks / 0ms blocking in the browser harness at the reported 26,670-event scale with live updates during dense scroll. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bryntum/support#13520 External review caught a retention gap in adoptShadow: an edge target can itself be a shadow cleared later in the same compaction pass - not a pure-read shadow (edge targets are always calculating quarks) but a reader that recalculated to its previous value, which onQuarkCalculationCompleted converts into a shadow of that previous quark (sameAsPrevious). Storing such a target verbatim retained the cleared husk on the heap for as long as the edge survived; a 5,000-reader probe retained 5,000 cleared quarks. adoptShadow now resolves each folded edge's target through its origin - the surviving quark, carrying the same originId, which is all any edge consumer reads. One property comparison per adopted edge, no lookups, no extra pass. Measured on the realistic retime workload: husk edges -90%, distinct retained husk objects 27,686 -> 23,569 - fewer than the mergePreviousOrigin design this replaced (29,361), which had its own equal-magnitude husk case in the mirror shape (readers dropping a conditional dependency). Edge sets and record digests are byte-identical; the residual husk shapes are bounded, shared by both designs, and asserted as a bound by the retention probe (a zero assertion holds for neither design). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kronaemmanuel
marked this pull request as draft
September 1, 2026 05:36
kronaemmanuel
marked this pull request as ready for review
September 3, 2026 06:33
arcady-zherdev
approved these changes
Sep 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A lot of time in the user's example in bryntum/support#13520 is being spent on the
mergePreviousOriginfunction. Specifically when we copy all the edges from the committed quarkoriginto the shadow quarkthis. Also thelatestScope.get(idn)Map.get() call takes some time.I think a good solution would be to just merge the newly created edges directly onto the committed quark. So i've added a new
adoptShadowmethod whhich does this. It has practically gotten rid of the long tasks that the main thread had to wait for.