@@ -401,7 +401,7 @@ impl<T: Item> SumTree<T> {
}
let mut pos = D::zero(cx);
- return match Self::find_recurse::<_, _, true>(cx, target, bias, &mut pos, self) {
+ return match Self::find_iterate::<_, _, true>(cx, target, bias, &mut pos, self) {
Some((item, end)) => (pos, end, Some(item)),
None => (pos.clone(), pos, None),
};
@@ -427,68 +427,69 @@ impl<T: Item> SumTree<T> {
}
let mut pos = D::zero(cx);
- return match Self::find_recurse::<_, _, false>(cx, target, bias, &mut pos, self) {
+ return match Self::find_iterate::<_, _, false>(cx, target, bias, &mut pos, self) {
Some((item, end)) => (pos, end, Some(item)),
None => (pos.clone(), pos, None),
};
}
- fn find_recurse<'tree, 'a, D, Target, const EXACT: bool>(
+ fn find_iterate<'tree, 'a, D, Target, const EXACT: bool>(
cx: <T::Summary as Summary>::Context<'a>,
target: &Target,
bias: Bias,
position: &mut D,
- this: &'tree SumTree<T>,
+ mut this: &'tree SumTree<T>,
) -> Option<(&'tree T, D)>
where
D: Dimension<'tree, T::Summary>,
Target: SeekTarget<'tree, T::Summary, D>,
{
- match &*this.0 {
- Node::Internal {
- child_summaries,
- child_trees,
- ..
- } => {
- for (child_tree, child_summary) in child_trees.iter().zip(child_summaries) {
- let child_end = position.clone().with_added_summary(child_summary, cx);
-
- let comparison = target.cmp(&child_end, cx);
- let target_in_child = comparison == Ordering::Less
- || (comparison == Ordering::Equal && bias == Bias::Left);
- if target_in_child {
- return Self::find_recurse::<D, Target, EXACT>(
- cx, target, bias, position, child_tree,
- );
+ 'iterate: loop {
+ match &*this.0 {
+ Node::Internal {
+ child_summaries,
+ child_trees,
+ ..
+ } => {
+ for (child_tree, child_summary) in child_trees.iter().zip(child_summaries) {
+ let child_end = position.clone().with_added_summary(child_summary, cx);
+
+ let comparison = target.cmp(&child_end, cx);
+ let target_in_child = comparison == Ordering::Less
+ || (comparison == Ordering::Equal && bias == Bias::Left);
+ if target_in_child {
+ this = child_tree;
+ continue 'iterate;
+ }
+ *position = child_end;
}
- *position = child_end;
}
- }
- Node::Leaf {
- items,
- item_summaries,
- ..
- } => {
- for (item, item_summary) in items.iter().zip(item_summaries) {
- let mut child_end = position.clone();
- child_end.add_summary(item_summary, cx);
+ Node::Leaf {
+ items,
+ item_summaries,
+ ..
+ } => {
+ for (item, item_summary) in items.iter().zip(item_summaries) {
+ let mut child_end = position.clone();
+ child_end.add_summary(item_summary, cx);
+
+ let comparison = target.cmp(&child_end, cx);
+ let entry_found = if EXACT {
+ comparison == Ordering::Equal
+ } else {
+ comparison == Ordering::Less
+ || (comparison == Ordering::Equal && bias == Bias::Left)
+ };
+ if entry_found {
+ return Some((item, child_end));
+ }
- let comparison = target.cmp(&child_end, cx);
- let entry_found = if EXACT {
- comparison == Ordering::Equal
- } else {
- comparison == Ordering::Less
- || (comparison == Ordering::Equal && bias == Bias::Left)
- };
- if entry_found {
- return Some((item, child_end));
+ *position = child_end;
}
-
- *position = child_end;
}
}
+ return None;
}
- None
}
/// A more efficient version of `Cursor::new()` + `Cursor::seek()` + `Cursor::item()`
@@ -511,75 +512,72 @@ impl<T: Item> SumTree<T> {
}
let mut pos = D::zero(cx);
- return match Self::find_recurse_with_prev::<_, _, false>(
- cx, target, bias, &mut pos, self, None,
- ) {
+ return match Self::find_with_prev_iterate::<_, _, false>(cx, target, bias, &mut pos, self) {
Some((prev, item, end)) => (pos, end, Some((prev, item))),
None => (pos.clone(), pos, None),
};
}
- fn find_recurse_with_prev<'tree, 'a, D, Target, const EXACT: bool>(
+ fn find_with_prev_iterate<'tree, 'a, D, Target, const EXACT: bool>(
cx: <T::Summary as Summary>::Context<'a>,
target: &Target,
bias: Bias,
position: &mut D,
- this: &'tree SumTree<T>,
- prev: Option<&'tree T>,
+ mut this: &'tree SumTree<T>,
) -> Option<(Option<&'tree T>, &'tree T, D)>
where
D: Dimension<'tree, T::Summary>,
Target: SeekTarget<'tree, T::Summary, D>,
{
- match &*this.0 {
- Node::Internal {
- child_summaries,
- child_trees,
- ..
- } => {
- let mut prev = prev;
- for (child_tree, child_summary) in child_trees.iter().zip(child_summaries) {
- let child_end = position.clone().with_added_summary(child_summary, cx);
-
- let comparison = target.cmp(&child_end, cx);
- let target_in_child = comparison == Ordering::Less
- || (comparison == Ordering::Equal && bias == Bias::Left);
- if target_in_child {
- return Self::find_recurse_with_prev::<D, Target, EXACT>(
- cx, target, bias, position, child_tree, prev,
- );
+ let mut prev = None;
+ 'iterate: loop {
+ match &*this.0 {
+ Node::Internal {
+ child_summaries,
+ child_trees,
+ ..
+ } => {
+ for (child_tree, child_summary) in child_trees.iter().zip(child_summaries) {
+ let child_end = position.clone().with_added_summary(child_summary, cx);
+
+ let comparison = target.cmp(&child_end, cx);
+ let target_in_child = comparison == Ordering::Less
+ || (comparison == Ordering::Equal && bias == Bias::Left);
+ if target_in_child {
+ this = child_tree;
+ continue 'iterate;
+ }
+ prev = child_tree.last();
+ *position = child_end;
}
- prev = child_tree.last();
- *position = child_end;
}
- }
- Node::Leaf {
- items,
- item_summaries,
- ..
- } => {
- let mut prev = prev;
- for (item, item_summary) in items.iter().zip(item_summaries) {
- let mut child_end = position.clone();
- child_end.add_summary(item_summary, cx);
-
- let comparison = target.cmp(&child_end, cx);
- let entry_found = if EXACT {
- comparison == Ordering::Equal
- } else {
- comparison == Ordering::Less
- || (comparison == Ordering::Equal && bias == Bias::Left)
- };
- if entry_found {
- return Some((prev, item, child_end));
- }
+ Node::Leaf {
+ items,
+ item_summaries,
+ ..
+ } => {
+ for (item, item_summary) in items.iter().zip(item_summaries) {
+ let mut child_end = position.clone();
+ child_end.add_summary(item_summary, cx);
+
+ let comparison = target.cmp(&child_end, cx);
+ let entry_found = if EXACT {
+ comparison == Ordering::Equal
+ } else {
+ comparison == Ordering::Less
+ || (comparison == Ordering::Equal && bias == Bias::Left)
+ };
+ if entry_found {
+ return Some((prev, item, child_end));
+ }
- prev = Some(item);
- *position = child_end;
+ prev = Some(item);
+ *position = child_end;
+ }
}
}
+ return None;
}
- None
}
pub fn cursor<'a, 'b, D>(