bumpFromSelf method
Adds delta to the subtree-size cache at startNid and at every
ancestor. Stops at kNoParentNid. O(depth).
Public so optimized callers (e.g. _purgeAndRemoveFromOrder Step 1)
can do their own batched cache maintenance — pre-bumping ancestors
before a downstream removal that they wrap in
runWithSubtreeSizeUpdatesSuppressed. Most callers should rely on
the inlined cache updates that fire automatically from the order
mutators.
No-op when delta is zero.
Implementation
void bumpFromSelf(int startNid, int delta) {
if (delta == 0) return;
int cur = startNid;
while (cur != kNoParentNid &&
cur >= 0 &&
cur < _subtreeSizeByNid.length) {
// Refuse to mutate a freed slot. In debug, surface the violation;
// in release, bail out — corrupting a freed slot causes downstream
// visibility-cache bugs once the nid is recycled.
if (_nids.keyOf(cur) == null) {
assert(
false,
"VisibleOrderBuffer.bumpFromSelf walked through freed nid $cur "
"from start nid $startNid (delta=$delta)",
);
break;
}
final next = _subtreeSizeByNid[cur] + delta;
assert(
next >= 0,
"subtree-size would go negative at nid $cur "
"(current=${_subtreeSizeByNid[cur]}, delta=$delta, "
"key=${_nids.keyOf(cur)})",
);
_subtreeSizeByNid[cur] = next;
cur = _parentByNidLookup(cur);
}
}