zed/crates/sum_tree/src/cursor.rs

710 lines
21 KiB
Rust
Raw Normal View History

2021-03-10 04:00:51 +00:00
use super::*;
use arrayvec::ArrayVec;
use std::{cmp::Ordering, mem, sync::Arc};
2021-03-10 04:00:51 +00:00
#[derive(Clone)]
struct StackEntry<'a, T: Item, D> {
2021-03-10 04:00:51 +00:00
tree: &'a SumTree<T>,
index: usize,
position: D,
}
2021-03-10 04:00:51 +00:00
#[derive(Clone)]
pub struct Cursor<'a, T: Item, D> {
2021-03-10 04:00:51 +00:00
tree: &'a SumTree<T>,
stack: ArrayVec<StackEntry<'a, T, D>, 16>,
position: D,
2021-03-10 04:00:51 +00:00
did_seek: bool,
at_end: bool,
}
pub struct Iter<'a, T: Item> {
tree: &'a SumTree<T>,
stack: ArrayVec<StackEntry<'a, T, ()>, 16>,
}
impl<'a, T, D> Cursor<'a, T, D>
2021-03-10 04:00:51 +00:00
where
T: Item,
D: Dimension<'a, T::Summary>,
2021-03-10 04:00:51 +00:00
{
pub fn new(tree: &'a SumTree<T>) -> Self {
Self {
tree,
stack: ArrayVec::new(),
position: D::default(),
2021-03-10 04:00:51 +00:00
did_seek: false,
at_end: tree.is_empty(),
2021-03-10 04:00:51 +00:00
}
}
fn reset(&mut self) {
self.did_seek = false;
self.at_end = self.tree.is_empty();
2021-03-10 04:00:51 +00:00
self.stack.truncate(0);
self.position = D::default();
}
pub fn start(&self) -> &D {
&self.position
2021-03-10 04:00:51 +00:00
}
pub fn end(&self, cx: &<T::Summary as Summary>::Context) -> D {
2021-03-10 04:00:51 +00:00
if let Some(item_summary) = self.item_summary() {
let mut end = self.start().clone();
end.add_summary(item_summary, cx);
2021-03-10 04:00:51 +00:00
end
} else {
self.start().clone()
2021-03-10 04:00:51 +00:00
}
}
pub fn item(&self) -> Option<&'a T> {
self.assert_did_seek();
2021-03-10 04:00:51 +00:00
if let Some(entry) = self.stack.last() {
match *entry.tree.0 {
Node::Leaf { ref items, .. } => {
if entry.index == items.len() {
None
} else {
Some(&items[entry.index])
}
}
_ => unreachable!(),
}
} else {
None
}
}
pub fn item_summary(&self) -> Option<&'a T::Summary> {
self.assert_did_seek();
2021-03-10 04:00:51 +00:00
if let Some(entry) = self.stack.last() {
match *entry.tree.0 {
Node::Leaf {
ref item_summaries, ..
} => {
if entry.index == item_summaries.len() {
None
} else {
Some(&item_summaries[entry.index])
}
}
_ => unreachable!(),
}
} else {
None
}
}
pub fn prev_item(&self) -> Option<&'a T> {
self.assert_did_seek();
2021-03-10 04:00:51 +00:00
if let Some(entry) = self.stack.last() {
if entry.index == 0 {
if let Some(prev_leaf) = self.prev_leaf() {
Some(prev_leaf.0.items().last().unwrap())
} else {
None
}
} else {
match *entry.tree.0 {
Node::Leaf { ref items, .. } => Some(&items[entry.index - 1]),
_ => unreachable!(),
}
}
} else if self.at_end {
self.tree.last()
} else {
None
}
}
fn prev_leaf(&self) -> Option<&'a SumTree<T>> {
for entry in self.stack.iter().rev().skip(1) {
if entry.index != 0 {
match *entry.tree.0 {
Node::Internal {
ref child_trees, ..
} => return Some(child_trees[entry.index - 1].rightmost_leaf()),
Node::Leaf { .. } => unreachable!(),
};
}
}
None
}
pub fn prev(&mut self, cx: &<T::Summary as Summary>::Context) {
self.prev_internal(|_| true, cx)
}
2021-03-10 04:00:51 +00:00
fn prev_internal<F>(&mut self, mut filter_node: F, cx: &<T::Summary as Summary>::Context)
where
F: FnMut(&T::Summary) -> bool,
{
if !self.did_seek {
self.did_seek = true;
self.at_end = true;
}
2021-03-10 04:00:51 +00:00
if self.at_end {
self.position = D::default();
self.at_end = self.tree.is_empty();
if !self.tree.is_empty() {
self.stack.push(StackEntry {
tree: self.tree,
index: self.tree.0.child_summaries().len(),
position: D::from_summary(self.tree.summary(), cx),
});
}
}
2021-03-10 04:00:51 +00:00
let mut descending = false;
while !self.stack.is_empty() {
if let Some(StackEntry { position, .. }) = self.stack.iter().rev().nth(1) {
self.position = position.clone();
} else {
self.position = D::default();
}
2021-03-10 04:00:51 +00:00
let mut entry = self.stack.last_mut().unwrap();
if !descending {
if entry.index == 0 {
self.stack.pop();
continue;
} else {
entry.index -= 1;
}
}
2021-03-10 04:00:51 +00:00
for summary in &entry.tree.0.child_summaries()[..entry.index] {
self.position.add_summary(summary, cx);
}
entry.position = self.position.clone();
descending = filter_node(&entry.tree.0.child_summaries()[entry.index]);
match entry.tree.0.as_ref() {
Node::Internal { child_trees, .. } => {
if descending {
let tree = &child_trees[entry.index];
self.stack.push(StackEntry {
position: D::default(),
tree,
index: tree.0.child_summaries().len() - 1,
})
}
}
Node::Leaf { .. } => {
if descending {
break;
}
2021-03-10 04:00:51 +00:00
}
}
}
}
pub fn next(&mut self, cx: &<T::Summary as Summary>::Context) {
self.next_internal(|_| true, cx)
2021-03-10 04:00:51 +00:00
}
fn next_internal<F>(&mut self, mut filter_node: F, cx: &<T::Summary as Summary>::Context)
2021-03-10 04:00:51 +00:00
where
F: FnMut(&T::Summary) -> bool,
2021-03-10 04:00:51 +00:00
{
let mut descend = false;
2021-03-10 04:00:51 +00:00
if self.stack.is_empty() {
if !self.at_end {
self.stack.push(StackEntry {
tree: self.tree,
index: 0,
position: D::default(),
});
descend = true;
}
self.did_seek = true;
}
while !self.stack.is_empty() {
let new_subtree = {
let entry = self.stack.last_mut().unwrap();
match entry.tree.0.as_ref() {
Node::Internal {
child_trees,
child_summaries,
..
} => {
if !descend {
entry.index += 1;
entry.position = self.position.clone();
}
2021-03-10 04:00:51 +00:00
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, cx);
self.position.add_summary(next_summary, cx);
}
2021-03-10 04:00:51 +00:00
}
child_trees.get(entry.index)
}
Node::Leaf { item_summaries, .. } => {
if !descend {
2021-03-10 04:00:51 +00:00
let item_summary = &item_summaries[entry.index];
entry.index += 1;
entry.position.add_summary(item_summary, cx);
self.position.add_summary(item_summary, cx);
}
loop {
2021-03-10 04:00:51 +00:00
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, cx);
self.position.add_summary(next_item_summary, cx);
2021-03-10 04:00:51 +00:00
}
} else {
break None;
}
}
2021-03-10 04:00:51 +00:00
}
}
};
if let Some(subtree) = new_subtree {
descend = true;
self.stack.push(StackEntry {
tree: subtree,
index: 0,
position: self.position.clone(),
});
} else {
descend = false;
self.stack.pop();
2021-03-10 04:00:51 +00:00
}
}
self.at_end = self.stack.is_empty();
debug_assert!(self.stack.is_empty() || self.stack.last().unwrap().tree.0.is_leaf());
2021-03-10 04:00:51 +00:00
}
fn assert_did_seek(&self) {
assert!(
self.did_seek,
"Must call `seek`, `next` or `prev` before calling this method"
);
}
2021-03-10 04:00:51 +00:00
}
impl<'a, T, D> Cursor<'a, T, D>
2021-03-10 04:00:51 +00:00
where
T: Item,
D: Dimension<'a, T::Summary>,
2021-03-10 04:00:51 +00:00
{
pub fn seek<Target>(
&mut self,
pos: &Target,
bias: Bias,
cx: &<T::Summary as Summary>::Context,
) -> bool
where
Target: SeekTarget<'a, T::Summary, D>,
{
2021-03-10 04:00:51 +00:00
self.reset();
self.seek_internal(pos, bias, &mut (), cx)
2021-03-10 04:00:51 +00:00
}
pub fn seek_forward<Target>(
&mut self,
pos: &Target,
2021-06-04 11:39:57 +00:00
bias: Bias,
cx: &<T::Summary as Summary>::Context,
) -> bool
where
Target: SeekTarget<'a, T::Summary, D>,
{
self.seek_internal(pos, bias, &mut (), cx)
2021-03-10 04:00:51 +00:00
}
pub fn slice<Target>(
&mut self,
end: &Target,
2021-06-04 11:39:57 +00:00
bias: Bias,
cx: &<T::Summary as Summary>::Context,
) -> SumTree<T>
where
Target: SeekTarget<'a, T::Summary, D>,
{
let mut slice = SliceSeekAggregate {
tree: SumTree::new(),
leaf_items: ArrayVec::new(),
leaf_item_summaries: ArrayVec::new(),
leaf_summary: T::Summary::default(),
};
self.seek_internal(end, bias, &mut slice, cx);
slice.tree
2021-03-10 04:00:51 +00:00
}
pub fn suffix(&mut self, cx: &<T::Summary as Summary>::Context) -> SumTree<T> {
self.slice(&End::new(), Bias::Right, cx)
2021-03-10 04:00:51 +00:00
}
pub fn summary<Target, Output>(
&mut self,
end: &Target,
bias: Bias,
cx: &<T::Summary as Summary>::Context,
) -> Output
2021-03-10 04:00:51 +00:00
where
Target: SeekTarget<'a, T::Summary, D>,
Output: Dimension<'a, T::Summary>,
2021-03-10 04:00:51 +00:00
{
let mut summary = SummarySeekAggregate(Output::default());
self.seek_internal(end, bias, &mut summary, cx);
summary.0
2021-03-10 04:00:51 +00:00
}
fn seek_internal(
2021-03-10 04:00:51 +00:00
&mut self,
target: &dyn SeekTarget<'a, T::Summary, D>,
2021-06-04 11:39:57 +00:00
bias: Bias,
aggregate: &mut dyn SeekAggregate<'a, T>,
cx: &<T::Summary as Summary>::Context,
) -> bool {
debug_assert!(
target.cmp(&self.position, cx) >= Ordering::Equal,
"cannot seek backward from {:?} to {:?}",
self.position,
target
);
2021-03-10 04:00:51 +00:00
if !self.did_seek {
self.did_seek = true;
self.stack.push(StackEntry {
tree: self.tree,
index: 0,
position: Default::default(),
});
}
2021-03-10 04:00:51 +00:00
let mut ascending = false;
'outer: while let Some(entry) = self.stack.last_mut() {
match *entry.tree.0 {
Node::Internal {
ref child_summaries,
ref child_trees,
..
} => {
if ascending {
entry.index += 1;
2021-03-10 04:00:51 +00:00
}
for (child_tree, child_summary) in child_trees[entry.index..]
.iter()
.zip(&child_summaries[entry.index..])
{
let mut child_end = self.position.clone();
child_end.add_summary(child_summary, cx);
2021-03-10 04:00:51 +00:00
let comparison = target.cmp(&child_end, cx);
if comparison == Ordering::Greater
2021-06-04 11:39:57 +00:00
|| (comparison == Ordering::Equal && bias == Bias::Right)
2021-03-10 04:00:51 +00:00
{
self.position = child_end;
aggregate.push_tree(child_tree, child_summary, cx);
entry.index += 1;
entry.position = self.position.clone();
} else {
self.stack.push(StackEntry {
tree: child_tree,
index: 0,
position: self.position.clone(),
});
ascending = false;
continue 'outer;
2021-03-10 04:00:51 +00:00
}
}
}
Node::Leaf {
ref items,
ref item_summaries,
..
} => {
aggregate.begin_leaf();
for (item, item_summary) in items[entry.index..]
.iter()
.zip(&item_summaries[entry.index..])
{
let mut child_end = self.position.clone();
child_end.add_summary(item_summary, cx);
let comparison = target.cmp(&child_end, cx);
if comparison == Ordering::Greater
2021-06-04 11:39:57 +00:00
|| (comparison == Ordering::Equal && bias == Bias::Right)
2021-03-10 04:00:51 +00:00
{
self.position = child_end;
aggregate.push_item(item, item_summary, cx);
entry.index += 1;
} else {
aggregate.end_leaf(cx);
break 'outer;
2021-03-10 04:00:51 +00:00
}
}
aggregate.end_leaf(cx);
2021-03-10 04:00:51 +00:00
}
}
self.stack.pop();
ascending = true;
2021-03-10 04:00:51 +00:00
}
self.at_end = self.stack.is_empty();
debug_assert!(self.stack.is_empty() || self.stack.last().unwrap().tree.0.is_leaf());
let mut end = self.position.clone();
2021-06-04 11:39:57 +00:00
if bias == Bias::Left {
2021-03-10 04:00:51 +00:00
if let Some(summary) = self.item_summary() {
end.add_summary(summary, cx);
2021-03-10 04:00:51 +00:00
}
}
target.cmp(&end, cx) == Ordering::Equal
2021-03-10 04:00:51 +00:00
}
}
impl<'a, T: Item> Iter<'a, T> {
pub(crate) fn new(tree: &'a SumTree<T>) -> Self {
Self {
tree,
stack: Default::default(),
}
}
}
impl<'a, T: Item> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
let mut descend = false;
if self.stack.is_empty() {
self.stack.push(StackEntry {
tree: self.tree,
index: 0,
position: (),
});
descend = true;
}
while !self.stack.is_empty() {
let new_subtree = {
let entry = self.stack.last_mut().unwrap();
match entry.tree.0.as_ref() {
Node::Internal { child_trees, .. } => {
if !descend {
entry.index += 1;
}
child_trees.get(entry.index)
}
Node::Leaf { items, .. } => {
if !descend {
entry.index += 1;
}
if let Some(next_item) = items.get(entry.index) {
return Some(next_item);
} else {
None
}
}
}
};
if let Some(subtree) = new_subtree {
descend = true;
self.stack.push(StackEntry {
tree: subtree,
index: 0,
position: (),
});
} else {
descend = false;
self.stack.pop();
}
}
None
}
}
impl<'a, T, S, D> Iterator for Cursor<'a, T, D>
2021-03-10 04:00:51 +00:00
where
T: Item<Summary = S>,
S: Summary<Context = ()>,
D: Dimension<'a, T::Summary>,
2021-03-10 04:00:51 +00:00
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
if !self.did_seek {
self.next(&());
2021-03-10 04:00:51 +00:00
}
if let Some(item) = self.item() {
self.next(&());
2021-03-10 04:00:51 +00:00
Some(item)
} else {
None
}
}
}
pub struct FilterCursor<'a, F, T: Item, D> {
cursor: Cursor<'a, T, D>,
2021-03-10 04:00:51 +00:00
filter_node: F,
}
impl<'a, F, T, D> FilterCursor<'a, F, T, D>
2021-03-10 04:00:51 +00:00
where
F: FnMut(&T::Summary) -> bool,
2021-03-10 04:00:51 +00:00
T: Item,
D: Dimension<'a, T::Summary>,
2021-03-10 04:00:51 +00:00
{
pub fn new(tree: &'a SumTree<T>, filter_node: F) -> Self {
let cursor = tree.cursor::<D>();
2021-03-10 04:00:51 +00:00
Self {
cursor,
filter_node,
}
}
pub fn start(&self) -> &D {
self.cursor.start()
2021-03-10 04:00:51 +00:00
}
pub fn end(&self, cx: &<T::Summary as Summary>::Context) -> D {
self.cursor.end(cx)
}
2021-03-10 04:00:51 +00:00
pub fn item(&self) -> Option<&'a T> {
self.cursor.item()
}
pub fn next(&mut self, cx: &<T::Summary as Summary>::Context) {
self.cursor.next_internal(&mut self.filter_node, cx);
2021-03-10 04:00:51 +00:00
}
pub fn prev(&mut self, cx: &<T::Summary as Summary>::Context) {
self.cursor.prev_internal(&mut self.filter_node, cx);
}
2021-03-10 04:00:51 +00:00
}
impl<'a, F, T, S, U> Iterator for FilterCursor<'a, F, T, U>
2021-03-10 04:00:51 +00:00
where
F: FnMut(&T::Summary) -> bool,
T: Item<Summary = S>,
S: Summary<Context = ()>, //Context for the summary must be unit type, as .next() doesn't take arguments
2021-03-10 04:00:51 +00:00
U: Dimension<'a, T::Summary>,
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
if !self.cursor.did_seek {
self.next(&());
}
2021-03-10 04:00:51 +00:00
if let Some(item) = self.item() {
self.cursor.next_internal(&mut self.filter_node, &());
2021-03-10 04:00:51 +00:00
Some(item)
} else {
None
}
}
}
trait SeekAggregate<'a, T: Item> {
fn begin_leaf(&mut self);
fn end_leaf(&mut self, cx: &<T::Summary as Summary>::Context);
fn push_item(
&mut self,
item: &'a T,
summary: &'a T::Summary,
cx: &<T::Summary as Summary>::Context,
);
fn push_tree(
&mut self,
tree: &'a SumTree<T>,
summary: &'a T::Summary,
cx: &<T::Summary as Summary>::Context,
);
}
struct SliceSeekAggregate<T: Item> {
tree: SumTree<T>,
leaf_items: ArrayVec<T, { 2 * TREE_BASE }>,
leaf_item_summaries: ArrayVec<T::Summary, { 2 * TREE_BASE }>,
leaf_summary: T::Summary,
}
struct SummarySeekAggregate<D>(D);
impl<'a, T: Item> SeekAggregate<'a, T> for () {
fn begin_leaf(&mut self) {}
fn end_leaf(&mut self, _: &<T::Summary as Summary>::Context) {}
fn push_item(&mut self, _: &T, _: &T::Summary, _: &<T::Summary as Summary>::Context) {}
fn push_tree(&mut self, _: &SumTree<T>, _: &T::Summary, _: &<T::Summary as Summary>::Context) {}
}
impl<'a, T: Item> SeekAggregate<'a, T> for SliceSeekAggregate<T> {
fn begin_leaf(&mut self) {}
fn end_leaf(&mut self, cx: &<T::Summary as Summary>::Context) {
self.tree.push_tree(
SumTree(Arc::new(Node::Leaf {
summary: mem::take(&mut self.leaf_summary),
items: mem::take(&mut self.leaf_items),
item_summaries: mem::take(&mut self.leaf_item_summaries),
})),
cx,
);
}
fn push_item(&mut self, item: &T, summary: &T::Summary, cx: &<T::Summary as Summary>::Context) {
self.leaf_items.push(item.clone());
self.leaf_item_summaries.push(summary.clone());
Summary::add_summary(&mut self.leaf_summary, summary, cx);
}
fn push_tree(
&mut self,
tree: &SumTree<T>,
_: &T::Summary,
cx: &<T::Summary as Summary>::Context,
) {
self.tree.push_tree(tree.clone(), cx);
}
}
impl<'a, T: Item, D> SeekAggregate<'a, T> for SummarySeekAggregate<D>
where
D: Dimension<'a, T::Summary>,
{
fn begin_leaf(&mut self) {}
fn end_leaf(&mut self, _: &<T::Summary as Summary>::Context) {}
fn push_item(&mut self, _: &T, summary: &'a T::Summary, cx: &<T::Summary as Summary>::Context) {
self.0.add_summary(summary, cx);
}
fn push_tree(
&mut self,
_: &SumTree<T>,
summary: &'a T::Summary,
cx: &<T::Summary as Summary>::Context,
) {
self.0.add_summary(summary, cx);
}
2021-03-10 04:00:51 +00:00
}