Make summaries a running sum
This commit is contained in:
parent
57ea58c83e
commit
b43153a99f
3 changed files with 35 additions and 27 deletions
|
@ -205,13 +205,13 @@ where
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn prev(&mut self) {
|
pub fn prev(&mut self) {
|
||||||
self.search_backward(|_| true)
|
self.search_backward(|_| Ordering::Greater)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn search_backward<F>(&mut self, mut filter_node: F)
|
pub fn search_backward<F>(&mut self, mut filter_node: F)
|
||||||
where
|
where
|
||||||
F: FnMut(&T::Summary) -> bool,
|
F: FnMut(&T::Summary) -> Ordering,
|
||||||
{
|
{
|
||||||
if !self.did_seek {
|
if !self.did_seek {
|
||||||
self.did_seek = true;
|
self.did_seek = true;
|
||||||
|
@ -253,13 +253,14 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for summary in &entry.tree.0.child_summaries()[..entry.index] {
|
if entry.index != 0 {
|
||||||
self.position.add_summary(summary, self.cx);
|
self.position
|
||||||
|
.add_summary(&entry.tree.0.child_summaries()[entry.index - 1], self.cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.position = self.position.clone();
|
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() {
|
match entry.tree.0.as_ref() {
|
||||||
Node::Internal { child_trees, .. } => {
|
Node::Internal { child_trees, .. } => {
|
||||||
if descending {
|
if descending {
|
||||||
|
@ -282,13 +283,13 @@ where
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn next(&mut self) {
|
pub fn next(&mut self) {
|
||||||
self.search_forward(|_| true)
|
self.search_forward(|_| Ordering::Less)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn search_forward<F>(&mut self, mut filter_node: F)
|
pub fn search_forward<F>(&mut self, mut filter_node: F)
|
||||||
where
|
where
|
||||||
F: FnMut(&T::Summary) -> bool,
|
F: FnMut(&T::Summary) -> Ordering,
|
||||||
{
|
{
|
||||||
let mut descend = false;
|
let mut descend = false;
|
||||||
|
|
||||||
|
@ -318,14 +319,17 @@ where
|
||||||
entry.position = self.position.clone();
|
entry.position = self.position.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
while entry.index < child_summaries.len() {
|
if entry.index < child_summaries.len() {
|
||||||
let next_summary = &child_summaries[entry.index];
|
let index = child_summaries[entry.index..]
|
||||||
if filter_node(next_summary) {
|
.partition_point(|item| filter_node(item).is_lt());
|
||||||
break;
|
entry.index += index;
|
||||||
} else {
|
let position = Some(entry.index)
|
||||||
entry.index += 1;
|
.filter(|index| *index < child_summaries.len())
|
||||||
entry.position.add_summary(next_summary, self.cx);
|
.unwrap_or(child_summaries.len());
|
||||||
self.position.add_summary(next_summary, self.cx);
|
|
||||||
|
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 {
|
loop {
|
||||||
if let Some(next_item_summary) = item_summaries.get(entry.index) {
|
if entry.index < item_summaries.len() {
|
||||||
if filter_node(next_item_summary) {
|
let index = item_summaries[entry.index..]
|
||||||
return;
|
.partition_point(|item| filter_node(item).is_lt());
|
||||||
} else {
|
entry.index += index;
|
||||||
entry.index += 1;
|
let position = Some(entry.index)
|
||||||
entry.position.add_summary(next_item_summary, self.cx);
|
.filter(|index| *index < item_summaries.len())
|
||||||
self.position.add_summary(next_item_summary, self.cx);
|
.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 {
|
} else {
|
||||||
break None;
|
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>
|
impl<'a, F, T: Item, D> FilterCursor<'a, F, T, D>
|
||||||
where
|
where
|
||||||
F: FnMut(&T::Summary) -> bool,
|
F: FnMut(&T::Summary) -> Ordering,
|
||||||
T: Item,
|
T: Item,
|
||||||
D: Dimension<'a, T::Summary>,
|
D: Dimension<'a, T::Summary>,
|
||||||
{
|
{
|
||||||
|
@ -681,7 +689,7 @@ where
|
||||||
|
|
||||||
impl<'a, F, T: Item, U> Iterator for FilterCursor<'a, F, T, U>
|
impl<'a, F, T: Item, U> Iterator for FilterCursor<'a, F, T, U>
|
||||||
where
|
where
|
||||||
F: FnMut(&T::Summary) -> bool,
|
F: FnMut(&T::Summary) -> Ordering,
|
||||||
U: Dimension<'a, T::Summary>,
|
U: Dimension<'a, T::Summary>,
|
||||||
{
|
{
|
||||||
type Item = &'a T;
|
type Item = &'a T;
|
||||||
|
|
|
@ -375,7 +375,7 @@ impl<T: Item> SumTree<T> {
|
||||||
filter_node: F,
|
filter_node: F,
|
||||||
) -> FilterCursor<'a, F, T, U>
|
) -> FilterCursor<'a, F, T, U>
|
||||||
where
|
where
|
||||||
F: FnMut(&T::Summary) -> bool,
|
F: FnMut(&T::Summary) -> Ordering,
|
||||||
U: Dimension<'a, T::Summary>,
|
U: Dimension<'a, T::Summary>,
|
||||||
{
|
{
|
||||||
FilterCursor::new(self, cx, filter_node)
|
FilterCursor::new(self, cx, filter_node)
|
||||||
|
@ -1026,7 +1026,7 @@ mod tests {
|
||||||
log::info!("tree items: {:?}", tree.items(&()));
|
log::info!("tree items: {:?}", tree.items(&()));
|
||||||
|
|
||||||
let mut filter_cursor =
|
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
|
let expected_filtered_items = tree
|
||||||
.items(&())
|
.items(&())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -412,7 +412,7 @@ mod tests {
|
||||||
.take_while(|(key, _)| key.starts_with("ba"))
|
.take_while(|(key, _)| key.starts_with("ba"))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
assert_eq!(result.len(), 2);
|
assert_eq!(result.len(), 2, "{result:?}");
|
||||||
assert!(result.iter().any(|(k, _)| k == &&"baa"));
|
assert!(result.iter().any(|(k, _)| k == &&"baa"));
|
||||||
assert!(result.iter().any(|(k, _)| k == &&"baaab"));
|
assert!(result.iter().any(|(k, _)| k == &&"baaab"));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue