Add FoldMap::folds_in_range to randomized test and fix issues it found

This commit is contained in:
Antonio Scandurra 2021-05-06 18:49:41 +02:00
parent 652fc9e4ec
commit 178705f8f9
3 changed files with 120 additions and 143 deletions

View file

@ -199,9 +199,6 @@ where
}
pub fn next(&mut self) {
if !self.did_seek {
self.descend_to_first_item(self.tree, |_| true)
}
self.next_internal(|_| true)
}
@ -209,67 +206,88 @@ where
where
F: Fn(&T::Summary) -> bool,
{
assert!(self.did_seek, "Must seek before calling this method");
let mut descend = false;
if self.stack.is_empty() {
if !self.at_end {
self.descend_to_first_item(self.tree, filter_node);
}
} else {
while self.stack.len() > 0 {
let new_subtree = {
let entry = self.stack.last_mut().unwrap();
match entry.tree.0.as_ref() {
Node::Internal {
child_trees,
child_summaries,
..
} => {
while entry.index < child_summaries.len() {
entry
.seek_dimension
.add_summary(&child_summaries[entry.index]);
entry
.sum_dimension
.add_summary(&child_summaries[entry.index]);
if !self.did_seek {
self.stack.push(StackEntry {
tree: self.tree,
index: 0,
seek_dimension: S::default(),
sum_dimension: U::default(),
});
descend = true;
self.did_seek = true;
}
entry.index += 1;
if let Some(next_summary) = child_summaries.get(entry.index) {
if filter_node(next_summary) {
break;
} else {
self.seek_dimension.add_summary(next_summary);
self.sum_dimension.add_summary(next_summary);
}
}
}
child_trees.get(entry.index)
while self.stack.len() > 0 {
let new_subtree = {
let entry = self.stack.last_mut().unwrap();
match entry.tree.0.as_ref() {
Node::Internal {
child_trees,
child_summaries,
..
} => {
if !descend {
let summary = &child_summaries[entry.index];
entry.seek_dimension.add_summary(summary);
entry.sum_dimension.add_summary(summary);
entry.index += 1;
}
Node::Leaf { item_summaries, .. } => loop {
while entry.index < child_summaries.len() {
let next_summary = &child_summaries[entry.index];
if filter_node(next_summary) {
break;
} else {
self.seek_dimension.add_summary(next_summary);
self.sum_dimension.add_summary(next_summary);
}
entry.index += 1;
}
child_trees.get(entry.index)
}
Node::Leaf { item_summaries, .. } => {
if !descend {
let item_summary = &item_summaries[entry.index];
self.seek_dimension.add_summary(item_summary);
entry.seek_dimension.add_summary(item_summary);
self.sum_dimension.add_summary(item_summary);
entry.sum_dimension.add_summary(item_summary);
entry.index += 1;
}
loop {
if let Some(next_item_summary) = item_summaries.get(entry.index) {
if filter_node(next_item_summary) {
return;
} else {
self.seek_dimension.add_summary(next_item_summary);
entry.seek_dimension.add_summary(next_item_summary);
self.sum_dimension.add_summary(next_item_summary);
entry.sum_dimension.add_summary(next_item_summary);
entry.index += 1;
}
} else {
break None;
}
},
}
}
};
if let Some(subtree) = new_subtree {
self.descend_to_first_item(subtree, filter_node);
break;
} else {
self.stack.pop();
}
};
if let Some(subtree) = new_subtree {
descend = true;
self.stack.push(StackEntry {
tree: subtree,
index: 0,
seek_dimension: self.seek_dimension.clone(),
sum_dimension: self.sum_dimension.clone(),
});
} else {
descend = false;
self.stack.pop();
}
}
@ -277,67 +295,6 @@ where
debug_assert!(self.stack.is_empty() || self.stack.last().unwrap().tree.0.is_leaf());
}
pub fn descend_to_first_item<F>(&mut self, mut subtree: &'a SumTree<T>, filter_node: F)
where
F: Fn(&T::Summary) -> bool,
{
self.did_seek = true;
loop {
subtree = match *subtree.0 {
Node::Internal {
ref child_trees,
ref child_summaries,
..
} => {
let mut new_index = None;
for (index, summary) in child_summaries.iter().enumerate() {
if filter_node(summary) {
new_index = Some(index);
break;
}
self.seek_dimension.add_summary(summary);
self.sum_dimension.add_summary(summary);
}
if let Some(new_index) = new_index {
self.stack.push(StackEntry {
tree: subtree,
index: new_index,
seek_dimension: self.seek_dimension.clone(),
sum_dimension: self.sum_dimension.clone(),
});
&child_trees[new_index]
} else {
break;
}
}
Node::Leaf {
ref item_summaries, ..
} => {
let mut new_index = None;
for (index, item_summary) in item_summaries.iter().enumerate() {
if filter_node(item_summary) {
new_index = Some(index);
break;
}
self.seek_dimension.add_summary(item_summary);
self.sum_dimension.add_summary(item_summary);
}
if let Some(new_index) = new_index {
self.stack.push(StackEntry {
tree: subtree,
index: new_index,
seek_dimension: self.seek_dimension.clone(),
sum_dimension: self.sum_dimension.clone(),
});
}
break;
}
}
}
}
fn descend_to_last_item(&mut self, mut subtree: &'a SumTree<T>) {
self.did_seek = true;
loop {
@ -744,7 +701,7 @@ where
fn next(&mut self) -> Option<Self::Item> {
if !self.did_seek {
self.descend_to_first_item(self.tree, |_| true);
self.next();
}
if let Some(item) = self.item() {
@ -769,13 +726,7 @@ where
{
pub fn new(tree: &'a SumTree<T>, filter_node: F) -> Self {
let mut cursor = tree.cursor::<(), U>();
if filter_node(&tree.summary()) {
cursor.descend_to_first_item(tree, &filter_node);
} else {
cursor.did_seek = true;
cursor.at_end = true;
}
cursor.next_internal(&filter_node);
Self {
cursor,
filter_node,