Skip to main content

prune_dangling_block_refs

Function prune_dangling_block_refs 

Source
pub fn prune_dangling_block_refs(
    root: &mut Option<LayoutNode>,
    live_block_ids: &HashSet<String>,
) -> usize
Expand description

Removes every leaf whose data.block_id is not in live_block_ids, using the same collapse semantics as an explicit user delete (delete_node’s single-child-parent promotion). Returns the number of leaves pruned (0 = tree was already clean — the common case, so this is cheap to call unconditionally on every write).

This is the reducer’s referential-integrity enforcement for db_layout, added after docs/investigations/INVESTIGATION_LAYOUT_DEAD_SPACE_STALE_TREE_RESURRECTION_2026_07_08.md found that a single point-fix (notifying the frontend on one specific delete path) only closes the one mechanism it targets — any other current or future caller that writes a stale/bad tree without going through that same notification channel can still leave a dangling blockId behind. Calling this at every layout-tree write site in the reducer (the single writer of db_layout since SPEC_864) makes “no layout leaf ever references a nonexistent block” an unconditional invariant of the write path itself, not a property individual callers have to remember to uphold — the same shape as WRR (Window Reality Reconciliation, crates/cef/src/wrr/) enforcing “no window/pool drift” at the point where reality is observed, rather than trusting every caller to keep the model in sync.

Re-scans the tree fresh after each removal rather than working off a pre-computed list of dangling node ids, since delete_node’s single-child collapse can rewrite a surviving parent’s id out from under a stale id — see the comment on delete_recursive. Terminates because each iteration strictly shrinks the tree (bounded by leaf count).