From 888cdf17b091ebc93912c920241a4962e87177e9 Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Tue, 25 Aug 2026 10:47:45 +0000 Subject: [PATCH] Compress nullified index chains by dropping trailing zeroed levels --- .../libraries/core-types/src/context.rs | 73 +++++++++++++++++-- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/node-graph/libraries/core-types/src/context.rs b/node-graph/libraries/core-types/src/context.rs index 01a5469993..2e973793cd 100644 --- a/node-graph/libraries/core-types/src/context.rs +++ b/node-graph/libraries/core-types/src/context.rs @@ -247,6 +247,11 @@ impl IndexLevels { /// The same requirement seen from outside `levels` pushed levels. An /// all-levels mask stays saturated, since its reader's level is not known at /// compile time. + /// + /// TODO: a fold overwrites the level it consumes rather than pushing one, so + /// this shift misnumbers levels above 0 across fold edges; latent until a + /// numeric level above 0 is declared. Preferred fix: folds push a level, + /// once the pass cancels the level a fold supplies. pub const fn popped(self, levels: u8) -> Self { match self.0 { u32::MAX => self, @@ -265,9 +270,10 @@ impl IndexLevels { } } -/// Zeroes every index level outside `levels`, preserving the chain's depth so -/// outer levels keep their positions for readers that do address them. Returns -/// `None` only when the arena is exhausted. +/// Zeroes every index level outside `levels` and drops zeroed levels off the +/// outer end, so equal surviving indices key a memo identically whatever depth +/// they arrived with. Interior zeroes keep their links, since outer levels are +/// addressed by position. Returns `None` only when the arena is exhausted. pub fn nullify_index_levels<'s>(head: IndexLink<'s>, levels: IndexLevels, arena: &'s crate::arena::Arena) -> Option> { if levels.is_all() { return Some(head); @@ -277,12 +283,15 @@ pub fn nullify_index_levels<'s>(head: IndexLink<'s>, levels: IndexLevels, arena: true => indices[level], false => 0, }; - if (0..indices.len()).all(|level| levels.contains_level(level) || indices[level] == 0) { + // A reader past the chain's end reads 0, so trailing zeroed levels carry + // no information. + let depth = (0..indices.len()).rev().find(|&level| masked(level) != 0).map_or(1, |level| level + 1); + if depth == indices.len() && (0..depth).all(|level| levels.contains_level(level) || indices[level] == 0) { return Some(head); } // Built outermost inwards so each link can reference the one already placed. let mut outer: Option<&'s IndexLink<'s>> = None; - for level in (1..indices.len()).rev() { + for level in (1..depth).rev() { let link = IndexLink { index: masked(level), outer }; outer = Some(arena.alloc(link)?.0); } @@ -1505,6 +1514,60 @@ mod context_impl_tests { assert_eq!(levels, vec![11, 0]); } + fn collected(head: &IndexLink) -> Vec { + core::iter::successors(Some(head), |link| link.outer).map(|link| link.index).collect() + } + + #[test] + fn nullify_drops_trailing_zeroed_levels() { + let arena = Arena::new(256).unwrap(); + let outer = IndexLink { index: 9, outer: None }; + let mid = IndexLink { index: 7, outer: Some(&outer) }; + let head = IndexLink { index: 4, outer: Some(&mid) }; + let result = nullify_index_levels(head, IndexLevels::innermost(), &arena).unwrap(); + assert_eq!(collected(&result), vec![4]); + } + + #[test] + fn nullify_canonicalizes_across_arrival_depths() { + let arena = Arena::new(256).unwrap(); + let shallow = IndexLink { index: 4, outer: None }; + let outer = IndexLink { index: 7, outer: None }; + let deep = IndexLink { index: 4, outer: Some(&outer) }; + let a = nullify_index_levels(shallow, IndexLevels::innermost(), &arena).unwrap(); + let b = nullify_index_levels(deep, IndexLevels::innermost(), &arena).unwrap(); + assert_eq!(collected(&a), collected(&b)); + } + + #[test] + fn nullify_keeps_interior_zeroes_positional() { + let arena = Arena::new(256).unwrap(); + let levels = IndexLevels::innermost().with_level(2); + let outer = IndexLink { index: 9, outer: None }; + let mid = IndexLink { index: 7, outer: Some(&outer) }; + let head = IndexLink { index: 4, outer: Some(&mid) }; + let result = nullify_index_levels(head, levels, &arena).unwrap(); + assert_eq!(collected(&result), vec![4, 0, 9]); + } + + #[test] + fn nullify_with_no_kept_levels_yields_the_root_chain() { + let arena = Arena::new(256).unwrap(); + let outer = IndexLink { index: 9, outer: None }; + let head = IndexLink { index: 4, outer: Some(&outer) }; + let result = nullify_index_levels(head, IndexLevels::empty(), &arena).unwrap(); + assert_eq!(collected(&result), vec![0]); + } + + #[test] + fn nullify_saturated_mask_is_identity() { + let arena = Arena::new(256).unwrap(); + let outer = IndexLink { index: 0, outer: None }; + let head = IndexLink { index: 4, outer: Some(&outer) }; + let result = nullify_index_levels(head, IndexLevels::all(), &arena).unwrap(); + assert_eq!(collected(&result), vec![4, 0]); + } + #[test] fn vararg_chain_concatenates_innermost_first() { let arena = Arena::new(64).unwrap();