From 57ea58c83e92b487468e8909e0254160460b6f2f Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Fri, 8 Aug 2025 16:06:47 +0200 Subject: [PATCH 1/5] WIP: rip out summary --- crates/buffer_diff/src/buffer_diff.rs | 2 +- crates/sum_tree/src/cursor.rs | 11 +- crates/sum_tree/src/sum_tree.rs | 197 +++++++++++++++----------- 3 files changed, 121 insertions(+), 89 deletions(-) diff --git a/crates/buffer_diff/src/buffer_diff.rs b/crates/buffer_diff/src/buffer_diff.rs index 97f529fe37..df92754ed4 100644 --- a/crates/buffer_diff/src/buffer_diff.rs +++ b/crates/buffer_diff/src/buffer_diff.rs @@ -154,7 +154,7 @@ impl BufferDiffSnapshot { BufferDiffSnapshot { inner: BufferDiffInner { base_text: language::Buffer::build_empty_snapshot(cx), - hunks: SumTree::new(buffer), + hunks: SumTree::new(), pending_hunks: SumTree::new(buffer), base_text_exists: false, }, diff --git a/crates/sum_tree/src/cursor.rs b/crates/sum_tree/src/cursor.rs index 50a556a6d2..324276aeed 100644 --- a/crates/sum_tree/src/cursor.rs +++ b/crates/sum_tree/src/cursor.rs @@ -222,10 +222,15 @@ where self.position = D::zero(self.cx); self.at_end = self.tree.is_empty(); if !self.tree.is_empty() { + let position = if let Some(summary) = self.tree.0.summary() { + D::from_summary(summary, self.cx) + } else { + D::zero(self.cx) + }; self.stack.push(StackEntry { tree: self.tree, index: self.tree.0.child_summaries().len(), - position: D::from_summary(self.tree.summary(), self.cx), + position, }); } } @@ -251,6 +256,7 @@ where for summary in &entry.tree.0.child_summaries()[..entry.index] { self.position.add_summary(summary, self.cx); } + entry.position = self.position.clone(); descending = filter_node(&entry.tree.0.child_summaries()[entry.index]); @@ -405,7 +411,7 @@ where Target: SeekTarget<'a, T::Summary, D>, { let mut slice = SliceSeekAggregate { - tree: SumTree::new(self.cx), + tree: SumTree::new(), leaf_items: ArrayVec::new(), leaf_item_summaries: ArrayVec::new(), leaf_summary: ::zero(self.cx), @@ -732,7 +738,6 @@ impl SeekAggregate<'_, T> for SliceSeekAggregate { fn end_leaf(&mut self, cx: &::Context) { self.tree.append( SumTree(Arc::new(Node::Leaf { - summary: mem::replace(&mut self.leaf_summary, ::zero(cx)), items: mem::take(&mut self.leaf_items), item_summaries: mem::take(&mut self.leaf_item_summaries), })), diff --git a/crates/sum_tree/src/sum_tree.rs b/crates/sum_tree/src/sum_tree.rs index 3a12e3a681..184148fa1b 100644 --- a/crates/sum_tree/src/sum_tree.rs +++ b/crates/sum_tree/src/sum_tree.rs @@ -4,6 +4,7 @@ mod tree_map; use arrayvec::ArrayVec; pub use cursor::{Cursor, FilterCursor, Iter}; use rayon::prelude::*; +use std::borrow::Cow; use std::marker::PhantomData; use std::mem; use std::{cmp::Ordering, fmt, iter::FromIterator, sync::Arc}; @@ -39,6 +40,7 @@ pub trait Summary: Clone { fn zero(cx: &Self::Context) -> Self; fn add_summary(&mut self, summary: &Self, cx: &Self::Context); + fn sub_summary(&mut self, summary: &Self, cx: &Self::Context) {} } /// Catch-all implementation for when you need something that implements [`Summary`] without a specific type. @@ -52,6 +54,7 @@ impl Summary for &'static () { } fn add_summary(&mut self, _: &Self, _: &()) {} + // fn sub_summary(&mut self, _: &Self, _: &()) {} } /// Each [`Summary`] type can have more than one [`Dimension`] type that it measures. @@ -189,25 +192,15 @@ where } impl SumTree { - pub fn new(cx: &::Context) -> Self { + pub fn new() -> Self { SumTree(Arc::new(Node::Leaf { - summary: ::zero(cx), - items: ArrayVec::new(), - item_summaries: ArrayVec::new(), - })) - } - - /// Useful in cases where the item type has a non-trivial context type, but the zero value of the summary type doesn't depend on that context. - pub fn from_summary(summary: T::Summary) -> Self { - SumTree(Arc::new(Node::Leaf { - summary, items: ArrayVec::new(), item_summaries: ArrayVec::new(), })) } pub fn from_item(item: T, cx: &::Context) -> Self { - let mut tree = Self::new(cx); + let mut tree = Self::new(); tree.push(item, cx); tree } @@ -230,7 +223,6 @@ impl SumTree { } nodes.push(Node::Leaf { - summary, items, item_summaries, }); @@ -243,13 +235,11 @@ impl SumTree { let mut current_parent_node = None; for child_node in nodes.drain(..) { let parent_node = current_parent_node.get_or_insert_with(|| Node::Internal { - summary: ::zero(cx), height, child_summaries: ArrayVec::new(), child_trees: ArrayVec::new(), }); let Node::Internal { - summary, child_summaries, child_trees, .. @@ -257,9 +247,15 @@ impl SumTree { else { unreachable!() }; - let child_summary = child_node.summary(); - ::add_summary(summary, child_summary, cx); - child_summaries.push(child_summary.clone()); + let child_summary = child_node.summary_or_zero(cx); + let child_summary = if let Some(mut last) = child_summaries.last().cloned() { + ::add_summary(&mut last, &child_summary, cx); + last + } else { + child_summary.into_owned() + }; + + child_summaries.push(child_summary); child_trees.push(Self(Arc::new(child_node))); if child_trees.len() == 2 * TREE_BASE { @@ -271,7 +267,7 @@ impl SumTree { } if nodes.is_empty() { - Self::new(cx) + Self::new() } else { debug_assert_eq!(nodes.len(), 1); Self(Arc::new(nodes.pop().unwrap())) @@ -291,14 +287,22 @@ impl SumTree { .chunks(2 * TREE_BASE) .map(|items| { let items: ArrayVec = items.into_iter().collect(); - let item_summaries: ArrayVec = - items.iter().map(|item| item.summary(cx)).collect(); - let mut summary = item_summaries[0].clone(); - for item_summary in &item_summaries[1..] { - ::add_summary(&mut summary, item_summary, cx); - } + let item_summaries: ArrayVec = items + .iter() + .scan(None, |previous_item, item| { + let summary = item.summary(cx); + let current_item = if let Some(mut base) = previous_item.take() { + ::add_summary(&mut base, &summary, cx); + base + } else { + summary + }; + previous_item.insert(current_item.clone()); + Some(current_item) + }) + .collect(); + SumTree(Arc::new(Node::Leaf { - summary, items, item_summaries, })) @@ -316,7 +320,7 @@ impl SumTree { child_nodes.into_iter().collect(); let child_summaries: ArrayVec = child_trees .iter() - .map(|child_tree| child_tree.summary().clone()) + .map(|child_tree| child_tree.0.summary_or_zero(cx).into_owned()) .collect(); let mut summary = child_summaries[0].clone(); for child_summary in &child_summaries[1..] { @@ -324,7 +328,7 @@ impl SumTree { } SumTree(Arc::new(Node::Internal { height, - summary, + child_summaries, child_trees, })) @@ -333,7 +337,7 @@ impl SumTree { } if nodes.is_empty() { - Self::new(cx) + Self::new() } else { debug_assert_eq!(nodes.len(), 1); nodes.pop().unwrap() @@ -397,28 +401,57 @@ impl SumTree { ) -> Option { match Arc::make_mut(&mut self.0) { Node::Internal { - summary, child_summaries, child_trees, .. } => { - let last_summary = child_summaries.last_mut().unwrap(); let last_child = child_trees.last_mut().unwrap(); - *last_summary = last_child.update_last_recursive(f, cx).unwrap(); - *summary = sum(child_summaries.iter(), cx); - Some(summary.clone()) + + let mut bare_summary = last_child.update_last_recursive(f, cx).unwrap(); + + if let Some(mut second_to_last_summary) = child_summaries + .len() + .checked_sub(2) + .and_then(|ix| child_summaries.get(ix)) + .cloned() + { + ::add_summary( + &mut second_to_last_summary, + &bare_summary, + cx, + ); + bare_summary = second_to_last_summary; + } + let last_summary = child_summaries.last_mut().unwrap(); + *last_summary = bare_summary; + + Some(last_summary.clone()) } Node::Leaf { - summary, items, item_summaries, } => { + let preceding_summary = item_summaries + .len() + .checked_sub(2) + .and_then(|ix| item_summaries.get(ix)) + .cloned(); if let Some((item, item_summary)) = items.last_mut().zip(item_summaries.last_mut()) { (f)(item); - *item_summary = item.summary(cx); - *summary = sum(item_summaries.iter(), cx); - Some(summary.clone()) + let mut bare_summary = item.summary(cx); + + if let Some(mut second_to_last_summary) = preceding_summary { + ::add_summary( + &mut second_to_last_summary, + &bare_summary, + cx, + ); + bare_summary = second_to_last_summary; + } + *item_summary = bare_summary.clone(); + + Some(item_summary.clone()) } else { None } @@ -431,19 +464,11 @@ impl SumTree { cx: &::Context, ) -> D { let mut extent = D::zero(cx); - match self.0.as_ref() { - Node::Internal { summary, .. } | Node::Leaf { summary, .. } => { - extent.add_summary(summary, cx); - } + if let Some(last) = self.0.child_summaries().last() { + extent.add_summary(last, cx); } - extent - } - pub fn summary(&self) -> &T::Summary { - match self.0.as_ref() { - Node::Internal { summary, .. } => summary, - Node::Leaf { summary, .. } => summary, - } + extent } pub fn is_empty(&self) -> bool { @@ -475,7 +500,6 @@ impl SumTree { let summary = item.summary(cx); self.append( SumTree(Arc::new(Node::Leaf { - summary: summary.clone(), items: ArrayVec::from_iter(Some(item)), item_summaries: ArrayVec::from_iter(Some(summary)), })), @@ -505,13 +529,11 @@ impl SumTree { match Arc::make_mut(&mut self.0) { Node::Internal { height, - summary, child_summaries, child_trees, .. } => { let other_node = other.0.clone(); - ::add_summary(summary, other_node.summary(), cx); let height_delta = *height - other_node.height(); let mut summaries_to_append = ArrayVec::::new(); @@ -520,18 +542,22 @@ impl SumTree { summaries_to_append.extend(other_node.child_summaries().iter().cloned()); trees_to_append.extend(other_node.child_trees().iter().cloned()); } else if height_delta == 1 && !other_node.is_underflowing() { - summaries_to_append.push(other_node.summary().clone()); + summaries_to_append.push(other_node.summary_or_zero(cx).into_owned()); trees_to_append.push(other) } else { let tree_to_append = child_trees .last_mut() .unwrap() .push_tree_recursive(other, cx); - *child_summaries.last_mut().unwrap() = - child_trees.last().unwrap().0.summary().clone(); + *child_summaries.last_mut().unwrap() = child_trees + .last() + .unwrap() + .0 + .summary_or_zero(cx) + .into_owned(); if let Some(split_tree) = tree_to_append { - summaries_to_append.push(split_tree.0.summary().clone()); + summaries_to_append.push(split_tree.0.summary_or_zero(cx).into_owned()); trees_to_append.push(split_tree); } } @@ -556,13 +582,12 @@ impl SumTree { left_trees = all_trees.by_ref().take(midpoint).collect(); right_trees = all_trees.collect(); } - *summary = sum(left_summaries.iter(), cx); + *child_summaries = left_summaries; *child_trees = left_trees; Some(SumTree(Arc::new(Node::Internal { height: *height, - summary: sum(right_summaries.iter(), cx), child_summaries: right_summaries, child_trees: right_trees, }))) @@ -573,7 +598,6 @@ impl SumTree { } } Node::Leaf { - summary, items, item_summaries, } => { @@ -601,16 +625,24 @@ impl SumTree { } *items = left_items; *item_summaries = left_summaries; - *summary = sum(item_summaries.iter(), cx); + Some(SumTree(Arc::new(Node::Leaf { items: right_items, - summary: sum(right_summaries.iter(), cx), + item_summaries: right_summaries, }))) } else { - ::add_summary(summary, other_node.summary(), cx); + let baseline = item_summaries.last().cloned(); + items.extend(other_node.items().iter().cloned()); - item_summaries.extend(other_node.child_summaries().iter().cloned()); + item_summaries.extend(other_node.child_summaries().iter().map(|summary| { + if let Some(mut baseline) = baseline.clone() { + ::add_summary(&mut baseline, summary, cx); + baseline + } else { + summary.clone() + } + })); None } } @@ -624,14 +656,14 @@ impl SumTree { ) -> Self { let height = left.0.height() + 1; let mut child_summaries = ArrayVec::new(); - child_summaries.push(left.0.summary().clone()); - child_summaries.push(right.0.summary().clone()); + child_summaries.push(left.0.summary_or_zero(cx).into_owned()); + child_summaries.push(right.0.summary_or_zero(cx).into_owned()); let mut child_trees = ArrayVec::new(); child_trees.push(left); child_trees.push(right); SumTree(Arc::new(Node::Internal { height, - summary: sum(child_summaries.iter(), cx), + child_summaries, child_trees, })) @@ -718,7 +750,7 @@ impl SumTree { *self = { let mut cursor = self.cursor::(cx); - let mut new_tree = SumTree::new(cx); + let mut new_tree = SumTree::new(); let mut buffered_items = Vec::new(); cursor.seek(&T::Key::zero(cx), Bias::Left); @@ -773,13 +805,9 @@ impl SumTree { } } -impl Default for SumTree -where - T: Item, - S: Summary, -{ +impl Default for SumTree { fn default() -> Self { - Self::new(&()) + Self::new() } } @@ -787,12 +815,10 @@ where pub enum Node { Internal { height: u8, - summary: T::Summary, child_summaries: ArrayVec, child_trees: ArrayVec, { 2 * TREE_BASE }>, }, Leaf { - summary: T::Summary, items: ArrayVec, item_summaries: ArrayVec, }, @@ -807,23 +833,19 @@ where match self { Node::Internal { height, - summary, child_summaries, child_trees, } => f .debug_struct("Internal") .field("height", height) - .field("summary", summary) .field("child_summaries", child_summaries) .field("child_trees", child_trees) .finish(), Node::Leaf { - summary, items, item_summaries, } => f .debug_struct("Leaf") - .field("summary", summary) .field("items", items) .field("item_summaries", item_summaries) .finish(), @@ -843,11 +865,16 @@ impl Node { } } - fn summary(&self) -> &T::Summary { - match self { - Node::Internal { summary, .. } => summary, - Node::Leaf { summary, .. } => summary, - } + fn summary<'a>(&'a self) -> Option<&'a T::Summary> { + let child_summaries = self.child_summaries(); + child_summaries.last() + } + + fn summary_or_zero<'a>(&'a self, cx: &::Context) -> Cow<'a, T::Summary> { + self.summary().map_or_else( + || Cow::Owned(::zero(cx)), + |last_summary| Cow::Borrowed(last_summary), + ) } fn child_summaries(&self) -> &[T::Summary] { @@ -1098,7 +1125,7 @@ mod tests { cursor.seek(&Count(start), start_bias); let summary = cursor.summary::<_, Sum>(&Count(end), end_bias); - assert_eq!(summary.0, slice.summary().sum); + assert_eq!(summary.0, slice.0.summary_or_zero(&()).sum); } } } From b43153a99f89d92d5217b721d9a7c1a3ef328afd Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Fri, 8 Aug 2025 16:49:30 +0200 Subject: [PATCH 2/5] Make summaries a running sum --- crates/sum_tree/src/cursor.rs | 56 +++++++++++++++++++-------------- crates/sum_tree/src/sum_tree.rs | 4 +-- crates/sum_tree/src/tree_map.rs | 2 +- 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/crates/sum_tree/src/cursor.rs b/crates/sum_tree/src/cursor.rs index 324276aeed..31f573a895 100644 --- a/crates/sum_tree/src/cursor.rs +++ b/crates/sum_tree/src/cursor.rs @@ -205,13 +205,13 @@ where #[track_caller] pub fn prev(&mut self) { - self.search_backward(|_| true) + self.search_backward(|_| Ordering::Greater) } #[track_caller] pub fn search_backward(&mut self, mut filter_node: F) where - F: FnMut(&T::Summary) -> bool, + F: FnMut(&T::Summary) -> Ordering, { if !self.did_seek { self.did_seek = true; @@ -253,13 +253,14 @@ where } } - for summary in &entry.tree.0.child_summaries()[..entry.index] { - self.position.add_summary(summary, self.cx); + if entry.index != 0 { + self.position + .add_summary(&entry.tree.0.child_summaries()[entry.index - 1], self.cx); } entry.position = self.position.clone(); - descending = filter_node(&entry.tree.0.child_summaries()[entry.index]); + descending = filter_node(&entry.tree.0.child_summaries()[entry.index]).is_ge(); match entry.tree.0.as_ref() { Node::Internal { child_trees, .. } => { if descending { @@ -282,13 +283,13 @@ where #[track_caller] pub fn next(&mut self) { - self.search_forward(|_| true) + self.search_forward(|_| Ordering::Less) } #[track_caller] pub fn search_forward(&mut self, mut filter_node: F) where - F: FnMut(&T::Summary) -> bool, + F: FnMut(&T::Summary) -> Ordering, { let mut descend = false; @@ -318,14 +319,17 @@ where entry.position = self.position.clone(); } - while entry.index < child_summaries.len() { - let next_summary = &child_summaries[entry.index]; - if filter_node(next_summary) { - break; - } else { - entry.index += 1; - entry.position.add_summary(next_summary, self.cx); - self.position.add_summary(next_summary, self.cx); + if entry.index < child_summaries.len() { + let index = child_summaries[entry.index..] + .partition_point(|item| filter_node(item).is_lt()); + entry.index += index; + let position = Some(entry.index) + .filter(|index| *index < child_summaries.len()) + .unwrap_or(child_summaries.len()); + + if let Some(summary) = child_summaries.get(position) { + entry.position.add_summary(summary, self.cx); + self.position.add_summary(summary, self.cx); } } @@ -340,13 +344,17 @@ where } loop { - if let Some(next_item_summary) = item_summaries.get(entry.index) { - if filter_node(next_item_summary) { - return; - } else { - entry.index += 1; - entry.position.add_summary(next_item_summary, self.cx); - self.position.add_summary(next_item_summary, self.cx); + if entry.index < item_summaries.len() { + let index = item_summaries[entry.index..] + .partition_point(|item| filter_node(item).is_lt()); + entry.index += index; + let position = Some(entry.index) + .filter(|index| *index < item_summaries.len()) + .unwrap_or(item_summaries.len()); + + if let Some(summary) = item_summaries.get(position) { + entry.position.add_summary(summary, self.cx); + self.position.add_summary(summary, self.cx); } } else { break None; @@ -638,7 +646,7 @@ pub struct FilterCursor<'a, F, T: Item, D> { impl<'a, F, T: Item, D> FilterCursor<'a, F, T, D> where - F: FnMut(&T::Summary) -> bool, + F: FnMut(&T::Summary) -> Ordering, T: Item, D: Dimension<'a, T::Summary>, { @@ -681,7 +689,7 @@ where impl<'a, F, T: Item, U> Iterator for FilterCursor<'a, F, T, U> where - F: FnMut(&T::Summary) -> bool, + F: FnMut(&T::Summary) -> Ordering, U: Dimension<'a, T::Summary>, { type Item = &'a T; diff --git a/crates/sum_tree/src/sum_tree.rs b/crates/sum_tree/src/sum_tree.rs index 184148fa1b..565cfceaf2 100644 --- a/crates/sum_tree/src/sum_tree.rs +++ b/crates/sum_tree/src/sum_tree.rs @@ -375,7 +375,7 @@ impl SumTree { filter_node: F, ) -> FilterCursor<'a, F, T, U> where - F: FnMut(&T::Summary) -> bool, + F: FnMut(&T::Summary) -> Ordering, U: Dimension<'a, T::Summary>, { FilterCursor::new(self, cx, filter_node) @@ -1026,7 +1026,7 @@ mod tests { log::info!("tree items: {:?}", tree.items(&())); let mut filter_cursor = - tree.filter::<_, Count>(&(), |summary| summary.contains_even); + tree.filter::<_, Count>(&(), |summary| summary.contains_even.cmp(&false)); let expected_filtered_items = tree .items(&()) .into_iter() diff --git a/crates/sum_tree/src/tree_map.rs b/crates/sum_tree/src/tree_map.rs index 54e8ae8343..682f1e8f65 100644 --- a/crates/sum_tree/src/tree_map.rs +++ b/crates/sum_tree/src/tree_map.rs @@ -412,7 +412,7 @@ mod tests { .take_while(|(key, _)| key.starts_with("ba")) .collect::>(); - assert_eq!(result.len(), 2); + assert_eq!(result.len(), 2, "{result:?}"); assert!(result.iter().any(|(k, _)| k == &&"baa")); assert!(result.iter().any(|(k, _)| k == &&"baaab")); From 4e2907e2967cb295ab945abb487bed8f58f7bbb5 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Fri, 8 Aug 2025 16:49:42 +0200 Subject: [PATCH 3/5] Fitzery with cursor --- crates/sum_tree/src/cursor.rs | 37 ++++++++++++++++++++------------- crates/sum_tree/src/tree_map.rs | 2 +- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/crates/sum_tree/src/cursor.rs b/crates/sum_tree/src/cursor.rs index 31f573a895..fff675597c 100644 --- a/crates/sum_tree/src/cursor.rs +++ b/crates/sum_tree/src/cursor.rs @@ -322,7 +322,10 @@ where if entry.index < child_summaries.len() { let index = child_summaries[entry.index..] .partition_point(|item| filter_node(item).is_lt()); - entry.index += index; + if index < child_summaries.len() - entry.index { + entry.index += index; + } + let position = Some(entry.index) .filter(|index| *index < child_summaries.len()) .unwrap_or(child_summaries.len()); @@ -332,10 +335,12 @@ where self.position.add_summary(summary, self.cx); } } + dbg!((entry.index, child_trees.len())); child_trees.get(entry.index) } Node::Leaf { item_summaries, .. } => { + dbg!("Ayo"); if !descend { let item_summary = &item_summaries[entry.index]; entry.index += 1; @@ -343,22 +348,24 @@ where self.position.add_summary(item_summary, self.cx); } - loop { - if entry.index < item_summaries.len() { - let index = item_summaries[entry.index..] - .partition_point(|item| filter_node(item).is_lt()); + if entry.index < item_summaries.len() { + let index = item_summaries[entry.index..] + .partition_point(|item| filter_node(item).is_lt()); + if index < item_summaries.len() - entry.index { entry.index += index; - let position = Some(entry.index) - .filter(|index| *index < item_summaries.len()) - .unwrap_or(item_summaries.len()); - - if let Some(summary) = item_summaries.get(position) { - entry.position.add_summary(summary, self.cx); - self.position.add_summary(summary, self.cx); - } - } else { - break None; } + entry.index += index; + let position = Some(entry.index) + .filter(|index| *index < item_summaries.len()) + .unwrap_or(item_summaries.len()); + + if let Some(summary) = item_summaries.get(position) { + entry.position.add_summary(summary, self.cx); + self.position.add_summary(summary, self.cx); + } + return; + } else { + None } } } diff --git a/crates/sum_tree/src/tree_map.rs b/crates/sum_tree/src/tree_map.rs index 682f1e8f65..fcf6da6cd6 100644 --- a/crates/sum_tree/src/tree_map.rs +++ b/crates/sum_tree/src/tree_map.rs @@ -406,7 +406,7 @@ mod tests { map.insert("baa", 3); map.insert("baaab", 4); map.insert("c", 5); - + dbg!(&map); let result = map .iter_from(&"ba") .take_while(|(key, _)| key.starts_with("ba")) From 2be18a200fb17b90fea60adb04b2f840ff9866ca Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Fri, 8 Aug 2025 17:11:48 +0200 Subject: [PATCH 4/5] Warnings --- crates/sum_tree/src/sum_tree.rs | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/crates/sum_tree/src/sum_tree.rs b/crates/sum_tree/src/sum_tree.rs index 565cfceaf2..74fd65ab37 100644 --- a/crates/sum_tree/src/sum_tree.rs +++ b/crates/sum_tree/src/sum_tree.rs @@ -40,7 +40,7 @@ pub trait Summary: Clone { fn zero(cx: &Self::Context) -> Self; fn add_summary(&mut self, summary: &Self, cx: &Self::Context); - fn sub_summary(&mut self, summary: &Self, cx: &Self::Context) {} + fn sub_summary(&mut self, _: &Self, _: &Self::Context) {} } /// Catch-all implementation for when you need something that implements [`Summary`] without a specific type. @@ -297,7 +297,7 @@ impl SumTree { } else { summary }; - previous_item.insert(current_item.clone()); + _ = previous_item.insert(current_item.clone()); Some(current_item) }) .collect(); @@ -923,18 +923,6 @@ impl Edit { } } -fn sum<'a, T, I>(iter: I, cx: &T::Context) -> T -where - T: 'a + Summary, - I: Iterator, -{ - let mut sum = T::zero(cx); - for value in iter { - sum.add_summary(value, cx); - } - sum -} - #[cfg(test)] mod tests { use super::*; From 74a6c78fffba96f0a29f0caae384729f5ed5cf7d Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 11 Aug 2025 09:50:20 +0200 Subject: [PATCH 5/5] debugs n stuff --- crates/sum_tree/src/cursor.rs | 26 +++++++------------------- crates/sum_tree/src/sum_tree.rs | 28 ++++++++++++++++++---------- crates/sum_tree/src/tree_map.rs | 6 +++--- 3 files changed, 28 insertions(+), 32 deletions(-) diff --git a/crates/sum_tree/src/cursor.rs b/crates/sum_tree/src/cursor.rs index fff675597c..7048389d68 100644 --- a/crates/sum_tree/src/cursor.rs +++ b/crates/sum_tree/src/cursor.rs @@ -205,7 +205,7 @@ where #[track_caller] pub fn prev(&mut self) { - self.search_backward(|_| Ordering::Greater) + self.search_backward(|_| Ordering::Equal) } #[track_caller] @@ -283,7 +283,7 @@ where #[track_caller] pub fn next(&mut self) { - self.search_forward(|_| Ordering::Less) + self.search_forward(|_| Ordering::Equal) } #[track_caller] @@ -322,25 +322,18 @@ where if entry.index < child_summaries.len() { let index = child_summaries[entry.index..] .partition_point(|item| filter_node(item).is_lt()); - if index < child_summaries.len() - entry.index { - entry.index += index; - } - let position = Some(entry.index) - .filter(|index| *index < child_summaries.len()) - .unwrap_or(child_summaries.len()); + entry.index += index; - if let Some(summary) = child_summaries.get(position) { + if let Some(summary) = child_summaries.get(entry.index) { entry.position.add_summary(summary, self.cx); self.position.add_summary(summary, self.cx); } } - dbg!((entry.index, child_trees.len())); child_trees.get(entry.index) } Node::Leaf { item_summaries, .. } => { - dbg!("Ayo"); if !descend { let item_summary = &item_summaries[entry.index]; entry.index += 1; @@ -351,15 +344,10 @@ where if entry.index < item_summaries.len() { let index = item_summaries[entry.index..] .partition_point(|item| filter_node(item).is_lt()); - if index < item_summaries.len() - entry.index { - entry.index += index; - } - entry.index += index; - let position = Some(entry.index) - .filter(|index| *index < item_summaries.len()) - .unwrap_or(item_summaries.len()); - if let Some(summary) = item_summaries.get(position) { + entry.index += index; + + if let Some(summary) = item_summaries.get(entry.index) { entry.position.add_summary(summary, self.cx); self.position.add_summary(summary, self.cx); } diff --git a/crates/sum_tree/src/sum_tree.rs b/crates/sum_tree/src/sum_tree.rs index 74fd65ab37..a0074aa2bc 100644 --- a/crates/sum_tree/src/sum_tree.rs +++ b/crates/sum_tree/src/sum_tree.rs @@ -5,6 +5,7 @@ use arrayvec::ArrayVec; pub use cursor::{Cursor, FilterCursor, Iter}; use rayon::prelude::*; use std::borrow::Cow; +use std::fmt::Debug; use std::marker::PhantomData; use std::mem; use std::{cmp::Ordering, fmt, iter::FromIterator, sync::Arc}; @@ -54,7 +55,6 @@ impl Summary for &'static () { } fn add_summary(&mut self, _: &Self, _: &()) {} - // fn sub_summary(&mut self, _: &Self, _: &()) {} } /// Each [`Summary`] type can have more than one [`Dimension`] type that it measures. @@ -214,14 +214,20 @@ impl SumTree { let mut iter = iter.into_iter().fuse().peekable(); while iter.peek().is_some() { let items: ArrayVec = iter.by_ref().take(2 * TREE_BASE).collect(); - let item_summaries: ArrayVec = - items.iter().map(|item| item.summary(cx)).collect(); - - let mut summary = item_summaries[0].clone(); - for item_summary in &item_summaries[1..] { - ::add_summary(&mut summary, item_summary, cx); - } - + let item_summaries: ArrayVec = items + .iter() + .scan(None, |previous_item, item| { + let summary = item.summary(cx); + let current_item = if let Some(mut base) = previous_item.take() { + ::add_summary(&mut base, &summary, cx); + base + } else { + summary + }; + _ = previous_item.insert(current_item.clone()); + Some(current_item) + }) + .collect(); nodes.push(Node::Leaf { items, item_summaries, @@ -1189,9 +1195,11 @@ mod tests { // Multiple-element tree let mut tree = SumTree::default(); tree.extend(vec![1, 2, 3, 4, 5, 6], &()); + let mut cursor = tree.cursor::(&()); - assert_eq!(cursor.slice(&Count(2), Bias::Right).items(&()), [1, 2]); + let slice = cursor.slice(&Count(2), Bias::Right); + assert_eq!(slice.items(&()), [1, 2]); assert_eq!(cursor.item(), Some(&3)); assert_eq!(cursor.prev_item(), Some(&2)); assert_eq!(cursor.next_item(), Some(&4)); diff --git a/crates/sum_tree/src/tree_map.rs b/crates/sum_tree/src/tree_map.rs index fcf6da6cd6..c966c1050e 100644 --- a/crates/sum_tree/src/tree_map.rs +++ b/crates/sum_tree/src/tree_map.rs @@ -406,9 +406,9 @@ mod tests { map.insert("baa", 3); map.insert("baaab", 4); map.insert("c", 5); - dbg!(&map); - let result = map - .iter_from(&"ba") + + let items = map.iter_from(&"ba"); + let result = items .take_while(|(key, _)| key.starts_with("ba")) .collect::>();