Supply a context when adding summary to Dimension

This commit is contained in:
Antonio Scandurra 2021-06-01 12:50:10 +02:00
parent e8a9eee84f
commit 311e1b0f5e
7 changed files with 234 additions and 211 deletions

View File

@ -360,7 +360,7 @@ struct FragmentTextSummary {
}
impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FragmentTextSummary {
fn add_summary(&mut self, summary: &'a FragmentSummary) {
fn add_summary(&mut self, summary: &'a FragmentSummary, _: &()) {
self.visible += summary.text.visible;
self.deleted += summary.text.deleted;
}
@ -825,7 +825,7 @@ impl Buffer {
}
pub fn len(&self) -> usize {
self.fragments.extent::<usize>()
self.fragments.extent::<usize>(&())
}
pub fn line_len(&self, row: u32) -> u32 {
@ -871,9 +871,10 @@ impl Buffer {
pub fn edits_since<'a>(&'a self, since: time::Global) -> impl 'a + Iterator<Item = Edit> {
let since_2 = since.clone();
let cursor = self
.fragments
.filter(move |summary| summary.max_version.changed_since(&since_2));
let cursor = self.fragments.filter(
move |summary| summary.max_version.changed_since(&since_2),
&(),
);
Edits {
deleted_text: &self.deleted_text,
@ -1201,7 +1202,7 @@ impl Buffer {
let fragment = fragments_cursor.item().unwrap().clone();
new_ropes.push_fragment(&fragment, fragment.visible);
new_fragments.push(fragment, &());
fragments_cursor.next();
fragments_cursor.next(&());
}
while let Some(fragment) = fragments_cursor.item() {
@ -1291,7 +1292,7 @@ impl Buffer {
new_fragments.push(fragment, &());
}
fragments_cursor.next();
fragments_cursor.next(&());
}
if let Some(new_text) = new_text {
@ -1420,7 +1421,7 @@ impl Buffer {
new_ropes.push_fragment(&fragment, was_visible);
new_fragments.push(fragment.clone(), &());
fragments_cursor.next();
fragments_cursor.next(&());
if let Some(split_id) = insertion_splits.next() {
let slice =
fragments_cursor.slice(&FragmentIdRef::new(split_id), SeekBias::Left, &());
@ -1453,7 +1454,7 @@ impl Buffer {
new_ropes.push_fragment(&fragment, fragment_was_visible);
new_fragments.push(fragment, &());
fragments_cursor.next();
fragments_cursor.next(&());
}
}
}
@ -1704,9 +1705,9 @@ impl Buffer {
},
&(),
);
splits_cursor.next();
splits_cursor.next(&());
new_split_tree.push_tree(
splits_cursor.slice(&old_split_tree.extent::<usize>(), SeekBias::Right, &()),
splits_cursor.slice(&old_split_tree.extent::<usize>(&()), SeekBias::Right, &()),
&(),
);
self.insertion_splits
@ -1716,7 +1717,7 @@ impl Buffer {
new_fragments.push(fragment, &());
// Scan forward until we find a fragment that is not fully contained by the current splice.
fragments_cursor.next();
fragments_cursor.next(&());
if let Some(range) = cur_range.clone() {
while let Some(fragment) = fragments_cursor.item() {
let fragment_summary = fragments_cursor.item_summary().unwrap();
@ -1733,7 +1734,7 @@ impl Buffer {
new_ropes.push_fragment(&new_fragment, fragment_was_visible);
new_fragments.push(new_fragment, &());
fragments_cursor.next();
fragments_cursor.next(&());
if range.end == fragment_end {
end_id = Some(fragment.insertion.id);
@ -1912,9 +1913,9 @@ impl Buffer {
);
}
cursor.next();
cursor.next(&());
new_split_tree.push_tree(
cursor.slice(&old_split_tree.extent::<usize>(), SeekBias::Right, &()),
cursor.slice(&old_split_tree.extent::<usize>(&()), SeekBias::Right, &()),
&(),
);
@ -2261,7 +2262,7 @@ impl<'a, F: Fn(&FragmentSummary) -> bool> Iterator for Edits<'a, F> {
}
}
self.cursor.next();
self.cursor.next(&());
}
change
@ -2445,7 +2446,7 @@ impl<'a> FragmentIdRef<'a> {
}
impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FragmentIdRef<'a> {
fn add_summary(&mut self, summary: &'a FragmentSummary) {
fn add_summary(&mut self, summary: &'a FragmentSummary, _: &()) {
self.0 = Some(&summary.max_fragment_id)
}
}
@ -2543,7 +2544,7 @@ impl Default for FragmentSummary {
}
impl<'a> sum_tree::Dimension<'a, FragmentSummary> for usize {
fn add_summary(&mut self, summary: &FragmentSummary) {
fn add_summary(&mut self, summary: &FragmentSummary, _: &()) {
*self += summary.text.visible;
}
}
@ -2573,7 +2574,7 @@ impl Default for InsertionSplitSummary {
}
impl<'a> sum_tree::Dimension<'a, InsertionSplitSummary> for usize {
fn add_summary(&mut self, summary: &InsertionSplitSummary) {
fn add_summary(&mut self, summary: &InsertionSplitSummary, _: &()) {
*self += summary.extent;
}
}

View File

@ -25,13 +25,13 @@ impl Rope {
pub fn append(&mut self, rope: Rope) {
let mut chunks = rope.chunks.cursor::<(), ()>();
chunks.next();
chunks.next(&());
if let Some(chunk) = chunks.item() {
if self.chunks.last().map_or(false, |c| c.0.len() < CHUNK_BASE)
|| chunk.0.len() < CHUNK_BASE
{
self.push(&chunk.0);
chunks.next();
chunks.next(&());
}
}
@ -99,11 +99,11 @@ impl Rope {
}
pub fn len(&self) -> usize {
self.chunks.extent()
self.chunks.extent(&())
}
pub fn max_point(&self) -> Point {
self.chunks.extent()
self.chunks.extent(&())
}
pub fn cursor(&self, offset: usize) -> Cursor {
@ -218,12 +218,12 @@ impl<'a> Cursor<'a> {
let mut slice = Rope::new();
if let Some(start_chunk) = self.chunks.item() {
let start_ix = self.offset - self.chunks.start();
let end_ix = cmp::min(end_offset, self.chunks.end()) - self.chunks.start();
let end_ix = cmp::min(end_offset, self.chunks.end(&())) - self.chunks.start();
slice.push(&start_chunk.0[start_ix..end_ix]);
}
if end_offset > self.chunks.end() {
self.chunks.next();
if end_offset > self.chunks.end(&()) {
self.chunks.next(&());
slice.append(Rope {
chunks: self.chunks.slice(&end_offset, SeekBias::Right, &()),
});
@ -243,12 +243,12 @@ impl<'a> Cursor<'a> {
let mut summary = TextSummary::default();
if let Some(start_chunk) = self.chunks.item() {
let start_ix = self.offset - self.chunks.start();
let end_ix = cmp::min(end_offset, self.chunks.end()) - self.chunks.start();
let end_ix = cmp::min(end_offset, self.chunks.end(&())) - self.chunks.start();
summary = TextSummary::from(&start_chunk.0[start_ix..end_ix]);
}
if end_offset > self.chunks.end() {
self.chunks.next();
if end_offset > self.chunks.end(&()) {
self.chunks.next(&());
summary += &self.chunks.summary(&end_offset, SeekBias::Right, &());
if let Some(end_chunk) = self.chunks.item() {
let end_ix = end_offset - self.chunks.start();
@ -260,7 +260,7 @@ impl<'a> Cursor<'a> {
}
pub fn suffix(mut self) -> Rope {
self.slice(self.rope.chunks.extent())
self.slice(self.rope.chunks.extent(&()))
}
pub fn offset(&self) -> usize {
@ -285,7 +285,7 @@ impl<'a> Chunks<'a> {
}
pub fn seek(&mut self, offset: usize) {
if offset >= self.chunks.end() {
if offset >= self.chunks.end(&()) {
self.chunks.seek_forward(&offset, SeekBias::Right, &());
} else {
self.chunks.seek(&offset, SeekBias::Right, &());
@ -312,7 +312,7 @@ impl<'a> Iterator for Chunks<'a> {
fn next(&mut self) -> Option<Self::Item> {
let result = self.peek();
if result.is_some() {
self.chunks.next();
self.chunks.next(&());
}
result
}
@ -478,19 +478,19 @@ impl std::ops::AddAssign<Self> for TextSummary {
}
impl<'a> sum_tree::Dimension<'a, TextSummary> for TextSummary {
fn add_summary(&mut self, summary: &'a TextSummary) {
fn add_summary(&mut self, summary: &'a TextSummary, _: &()) {
*self += summary;
}
}
impl<'a> sum_tree::Dimension<'a, TextSummary> for usize {
fn add_summary(&mut self, summary: &'a TextSummary) {
fn add_summary(&mut self, summary: &'a TextSummary, _: &()) {
*self += summary.bytes;
}
}
impl<'a> sum_tree::Dimension<'a, TextSummary> for Point {
fn add_summary(&mut self, summary: &'a TextSummary) {
fn add_summary(&mut self, summary: &'a TextSummary, _: &()) {
*self += &summary.lines;
}
}

View File

@ -12,6 +12,7 @@ use gpui::{AppContext, ModelHandle};
use parking_lot::{Mutex, MutexGuard};
use std::{
cmp::{self, Ordering},
iter,
ops::Range,
};
@ -80,7 +81,13 @@ impl FoldMap {
where
T: ToOffset,
{
self.intersecting_folds(range, cx).map(|f| &f.0)
let buffer = self.buffer.read(cx);
let mut folds = self.intersecting_folds(range, cx);
iter::from_fn(move || {
let item = folds.item().map(|f| &f.0);
folds.next(buffer);
item
})
}
pub fn fold<T: ToOffset>(
@ -149,7 +156,7 @@ impl FoldMap {
..Default::default()
});
fold_ixs_to_delete.push(*folds_cursor.start());
folds_cursor.next();
folds_cursor.next(buffer);
}
}
@ -167,7 +174,7 @@ impl FoldMap {
let mut folds = SumTree::new();
for fold_ix in fold_ixs_to_delete {
folds.push_tree(cursor.slice(&fold_ix, SeekBias::Right, buffer), buffer);
cursor.next();
cursor.next(buffer);
}
folds.push_tree(cursor.suffix(buffer), buffer);
folds
@ -186,10 +193,13 @@ impl FoldMap {
let buffer = self.buffer.read(cx);
let start = buffer.anchor_before(range.start.to_offset(buffer));
let end = buffer.anchor_after(range.end.to_offset(buffer));
self.folds.filter::<_, usize>(move |summary| {
self.folds.filter::<_, usize>(
move |summary| {
start.cmp(&summary.max_end, buffer).unwrap() == Ordering::Less
&& end.cmp(&summary.min_start, buffer).unwrap() == Ordering::Greater
})
},
buffer,
)
}
pub fn intersects_fold<T>(&self, offset: T, cx: &AppContext) -> bool
@ -212,8 +222,8 @@ impl FoldMap {
if transform.display_text.is_some() {
return true;
}
if cursor.end().row() == display_row {
cursor.next()
if cursor.end(&()).row() == display_row {
cursor.next(&())
} else {
break;
}
@ -244,7 +254,7 @@ impl FoldMap {
let overshoot = point - cursor.start().buffer.lines;
DisplayPoint(cmp::min(
cursor.start().display.lines + overshoot,
cursor.end().display.lines,
cursor.end(&()).display.lines,
))
}
@ -276,7 +286,7 @@ impl FoldMap {
edit.old_range.start = *cursor.start();
cursor.seek(&edit.old_range.end, SeekBias::Right, &());
cursor.next();
cursor.next(&());
let mut delta = edit.delta();
loop {
@ -293,7 +303,7 @@ impl FoldMap {
if next_edit.old_range.end >= edit.old_range.end {
edit.old_range.end = next_edit.old_range.end;
cursor.seek(&edit.old_range.end, SeekBias::Right, &());
cursor.next();
cursor.next(&());
}
} else {
break;
@ -306,8 +316,13 @@ impl FoldMap {
let anchor = buffer.anchor_before(edit.new_range.start);
let mut folds_cursor = self.folds.cursor::<_, ()>();
folds_cursor.seek(&Fold(anchor..Anchor::End), SeekBias::Left, buffer);
let mut folds = folds_cursor
.map(|f| f.0.start.to_offset(buffer)..f.0.end.to_offset(buffer))
let mut folds = iter::from_fn(move || {
let item = folds_cursor
.item()
.map(|f| f.0.start.to_offset(buffer)..f.0.end.to_offset(buffer));
folds_cursor.next(buffer);
item
})
.peekable();
while folds
@ -501,7 +516,7 @@ impl FoldMapSnapshot {
if offset.0 == transform_start || matches!(bias, Bias::Left) {
DisplayOffset(transform_start)
} else {
DisplayOffset(cursor.end().display.bytes)
DisplayOffset(cursor.end(&()).display.bytes)
}
} else {
let overshoot = offset.0 - transform_start;
@ -526,7 +541,7 @@ impl FoldMapSnapshot {
if point.0 == transform_start || matches!(bias, Bias::Left) {
DisplayPoint(transform_start)
} else {
DisplayPoint(cursor.end().display.lines)
DisplayPoint(cursor.end(&()).display.lines)
}
} else {
let overshoot = point.0 - transform_start;
@ -574,7 +589,7 @@ impl sum_tree::Summary for TransformSummary {
}
impl<'a> sum_tree::Dimension<'a, TransformSummary> for TransformSummary {
fn add_summary(&mut self, summary: &'a TransformSummary) {
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
sum_tree::Summary::add_summary(self, summary, &());
}
}
@ -649,7 +664,7 @@ impl sum_tree::Summary for FoldSummary {
}
impl<'a> sum_tree::Dimension<'a, FoldSummary> for Fold {
fn add_summary(&mut self, summary: &'a FoldSummary) {
fn add_summary(&mut self, summary: &'a FoldSummary, _: &Buffer) {
self.0.start = summary.start.clone();
self.0.end = summary.end.clone();
}
@ -662,7 +677,7 @@ impl<'a> sum_tree::SeekDimension<'a, FoldSummary> for Fold {
}
impl<'a> sum_tree::Dimension<'a, FoldSummary> for usize {
fn add_summary(&mut self, summary: &'a FoldSummary) {
fn add_summary(&mut self, summary: &'a FoldSummary, _: &Buffer) {
*self += summary.count;
}
}
@ -676,8 +691,8 @@ impl<'a> Iterator for BufferRows<'a> {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
while self.display_point > self.cursor.end().display.lines {
self.cursor.next();
while self.display_point > self.cursor.end(&()).display.lines {
self.cursor.next(&());
if self.cursor.item().is_none() {
// TODO: Return a bool from next?
break;
@ -717,10 +732,10 @@ impl<'a> Iterator for Chunks<'a> {
self.buffer_offset += transform.summary.buffer.bytes;
self.buffer_chunks.seek(self.buffer_offset);
while self.buffer_offset >= self.transform_cursor.end().buffer.bytes
while self.buffer_offset >= self.transform_cursor.end(&()).buffer.bytes
&& self.transform_cursor.item().is_some()
{
self.transform_cursor.next();
self.transform_cursor.next(&());
}
return Some(display_text);
@ -732,10 +747,10 @@ impl<'a> Iterator for Chunks<'a> {
chunk = &chunk[offset_in_chunk..];
// Truncate the chunk so that it ends at the next fold.
let region_end = self.transform_cursor.end().buffer.bytes - self.buffer_offset;
let region_end = self.transform_cursor.end(&()).buffer.bytes - self.buffer_offset;
if chunk.len() >= region_end {
chunk = &chunk[0..region_end];
self.transform_cursor.next();
self.transform_cursor.next(&());
} else {
self.buffer_chunks.next();
}
@ -772,10 +787,10 @@ impl<'a> Iterator for HighlightedChunks<'a> {
self.buffer_offset += transform.summary.buffer.bytes;
self.buffer_chunks.seek(self.buffer_offset);
while self.buffer_offset >= self.transform_cursor.end().buffer.bytes
while self.buffer_offset >= self.transform_cursor.end(&()).buffer.bytes
&& self.transform_cursor.item().is_some()
{
self.transform_cursor.next();
self.transform_cursor.next(&());
}
return Some((display_text, StyleId::default()));
@ -796,10 +811,10 @@ impl<'a> Iterator for HighlightedChunks<'a> {
chunk = &chunk[offset_in_chunk..];
// Truncate the chunk so that it ends at the next fold.
let region_end = self.transform_cursor.end().buffer.bytes - self.buffer_offset;
let region_end = self.transform_cursor.end(&()).buffer.bytes - self.buffer_offset;
if chunk.len() >= region_end {
chunk = &chunk[0..region_end];
self.transform_cursor.next();
self.transform_cursor.next(&());
} else {
self.buffer_chunk.take();
}
@ -813,7 +828,7 @@ impl<'a> Iterator for HighlightedChunks<'a> {
}
impl<'a> sum_tree::Dimension<'a, TransformSummary> for DisplayPoint {
fn add_summary(&mut self, summary: &'a TransformSummary) {
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
self.0 += &summary.display.lines;
}
}
@ -822,19 +837,19 @@ impl<'a> sum_tree::Dimension<'a, TransformSummary> for DisplayPoint {
pub struct DisplayOffset(usize);
impl<'a> sum_tree::Dimension<'a, TransformSummary> for DisplayOffset {
fn add_summary(&mut self, summary: &'a TransformSummary) {
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
self.0 += &summary.display.bytes;
}
}
impl<'a> sum_tree::Dimension<'a, TransformSummary> for Point {
fn add_summary(&mut self, summary: &'a TransformSummary) {
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
*self += &summary.buffer.lines;
}
}
impl<'a> sum_tree::Dimension<'a, TransformSummary> for usize {
fn add_summary(&mut self, summary: &'a TransformSummary) {
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
*self += &summary.buffer.bytes;
}
}
@ -1027,29 +1042,6 @@ mod tests {
for _ in 0..operations {
log::info!("text: {:?}", buffer.read(cx).text());
{
let buffer = buffer.read(cx);
let mut cursor = map.folds.cursor::<(), ()>();
cursor.next(buffer);
let mut prev_fold: Option<&Fold> = None;
while let Some(fold) = cursor.item() {
if let Some(prev_fold) = prev_fold {
let prev_fold = prev_fold.0.start.to_offset(buffer)
..prev_fold.0.end.to_offset(buffer);
let fold = fold.0.start.to_offset(buffer)..fold.0.end.to_offset(buffer);
assert!(
fold.start > prev_fold.start
|| (fold.start == prev_fold.start && fold.end <= prev_fold.end),
"prev fold {:?}\ncurr fold {:?}",
prev_fold,
fold
);
}
prev_fold = Some(fold);
cursor.next(buffer);
}
}
match rng.gen_range(0..=100) {
0..=34 => {
let buffer = buffer.read(cx);
@ -1195,7 +1187,7 @@ mod tests {
let start = buffer.clip_offset(rng.gen_range(0..=end), Left);
let expected_folds = map
.folds
.items()
.items(buffer)
.into_iter()
.filter(|fold| {
let start = buffer.anchor_before(start);
@ -1250,7 +1242,7 @@ mod tests {
fn merged_fold_ranges(&self, cx: &AppContext) -> Vec<Range<usize>> {
let buffer = self.buffer.read(cx);
let mut folds = self.folds.items();
let mut folds = self.folds.items(buffer);
// Ensure sorting doesn't change how folds get merged and displayed.
folds.sort_by(|a, b| a.0.cmp(&b.0, buffer).unwrap());
let mut fold_ranges = folds

View File

@ -89,7 +89,7 @@ impl<'a> Add<&'a Self> for OperationSummary {
}
impl<'a> Dimension<'a, OperationSummary> for OperationKey {
fn add_summary(&mut self, summary: &OperationSummary) {
fn add_summary(&mut self, summary: &OperationSummary, _: &()) {
assert!(*self <= summary.key);
*self = summary.key;
}

View File

@ -29,11 +29,11 @@ pub trait Summary: Default + Clone + fmt::Debug {
}
pub trait Dimension<'a, S: Summary>: Clone + fmt::Debug + Default {
fn add_summary(&mut self, _summary: &'a S);
fn add_summary(&mut self, _summary: &'a S, _: &S::Context);
}
impl<'a, T: Summary> Dimension<'a, T> for () {
fn add_summary(&mut self, _: &'a T) {}
fn add_summary(&mut self, _: &'a T, _: &T::Context) {}
}
pub trait SeekDimension<'a, T: Summary>: Dimension<'a, T> {
@ -71,9 +71,15 @@ impl<T: Item> SumTree<T> {
}
#[allow(unused)]
pub fn items(&self) -> Vec<T> {
pub fn items(&self, cx: &<T::Summary as Summary>::Context) -> Vec<T> {
let mut items = Vec::new();
let mut cursor = self.cursor::<(), ()>();
cursor.cloned().collect()
cursor.next(cx);
while let Some(item) = cursor.item() {
items.push(item.clone());
cursor.next(cx);
}
items
}
pub fn cursor<'a, S, U>(&'a self) -> Cursor<T, S, U>
@ -84,12 +90,16 @@ impl<T: Item> SumTree<T> {
Cursor::new(self)
}
pub fn filter<'a, F, U>(&'a self, filter_node: F) -> FilterCursor<F, T, U>
pub fn filter<'a, F, U>(
&'a self,
filter_node: F,
cx: &<T::Summary as Summary>::Context,
) -> FilterCursor<F, T, U>
where
F: Fn(&T::Summary) -> bool,
U: Dimension<'a, T::Summary>,
{
FilterCursor::new(self, filter_node)
FilterCursor::new(self, filter_node, cx)
}
#[allow(dead_code)]
@ -141,11 +151,14 @@ impl<T: Item> SumTree<T> {
}
}
pub fn extent<'a, D: Dimension<'a, T::Summary>>(&'a self) -> D {
pub fn extent<'a, D: Dimension<'a, T::Summary>>(
&'a self,
cx: &<T::Summary as Summary>::Context,
) -> D {
let mut extent = D::default();
match self.0.as_ref() {
Node::Internal { summary, .. } | Node::Leaf { summary, .. } => {
extent.add_summary(summary);
extent.add_summary(summary, cx);
}
}
extent
@ -434,7 +447,7 @@ impl<T: KeyedItem> SumTree<T> {
if let Some(old_item) = old_item {
if old_item.key() == new_key {
removed.push(old_item.clone());
cursor.next();
cursor.next(cx);
}
}
@ -580,7 +593,10 @@ mod tests {
tree2.extend(50..100, &());
tree1.push_tree(tree2, &());
assert_eq!(tree1.items(), (0..20).chain(50..100).collect::<Vec<u8>>());
assert_eq!(
tree1.items(&()),
(0..20).chain(50..100).collect::<Vec<u8>>()
);
}
#[test]
@ -596,16 +612,16 @@ mod tests {
tree.extend(rng.sample_iter(distributions::Standard).take(count), &());
for _ in 0..5 {
let splice_end = rng.gen_range(0..tree.extent::<Count>().0 + 1);
let splice_end = rng.gen_range(0..tree.extent::<Count>(&()).0 + 1);
let splice_start = rng.gen_range(0..splice_end + 1);
let count = rng.gen_range(0..3);
let tree_end = tree.extent::<Count>();
let tree_end = tree.extent::<Count>(&());
let new_items = rng
.sample_iter(distributions::Standard)
.take(count)
.collect::<Vec<u8>>();
let mut reference_items = tree.items();
let mut reference_items = tree.items(&());
reference_items.splice(splice_start..splice_end, new_items.clone());
tree = {
@ -617,11 +633,12 @@ mod tests {
new_tree
};
assert_eq!(tree.items(), reference_items);
assert_eq!(tree.items(&()), reference_items);
let mut filter_cursor = tree.filter::<_, Count>(|summary| summary.contains_even);
let mut filter_cursor =
tree.filter::<_, Count>(|summary| summary.contains_even, &());
let mut reference_filter = tree
.items()
.items(&())
.into_iter()
.enumerate()
.filter(|(_, item)| (item & 1) == 0);
@ -629,11 +646,11 @@ mod tests {
let (reference_index, reference_item) = reference_filter.next().unwrap();
assert_eq!(actual_item, &reference_item);
assert_eq!(filter_cursor.start().0, reference_index);
filter_cursor.next();
filter_cursor.next(&());
}
assert!(reference_filter.next().is_none());
let mut pos = rng.gen_range(0..tree.extent::<Count>().0 + 1);
let mut pos = rng.gen_range(0..tree.extent::<Count>(&()).0 + 1);
let mut before_start = false;
let mut cursor = tree.cursor::<Count, Count>();
cursor.seek(&Count(pos), SeekBias::Right, &());
@ -654,13 +671,13 @@ mod tests {
}
if i < 5 {
cursor.next();
cursor.next(&());
if pos < reference_items.len() {
pos += 1;
before_start = false;
}
} else {
cursor.prev();
cursor.prev(&());
if pos == 0 {
before_start = true;
}
@ -670,7 +687,7 @@ mod tests {
}
for _ in 0..10 {
let end = rng.gen_range(0..tree.extent::<Count>().0 + 1);
let end = rng.gen_range(0..tree.extent::<Count>(&()).0 + 1);
let start = rng.gen_range(0..end + 1);
let start_bias = if rng.gen() {
SeekBias::Left
@ -701,7 +718,7 @@ mod tests {
let tree = SumTree::<u8>::new();
let mut cursor = tree.cursor::<Count, Sum>();
assert_eq!(
cursor.slice(&Count(0), SeekBias::Right, &()).items(),
cursor.slice(&Count(0), SeekBias::Right, &()).items(&()),
Vec::<u8>::new()
);
assert_eq!(cursor.item(), None);
@ -713,25 +730,28 @@ mod tests {
tree.extend(vec![1], &());
let mut cursor = tree.cursor::<Count, Sum>();
assert_eq!(
cursor.slice(&Count(0), SeekBias::Right, &()).items(),
cursor.slice(&Count(0), SeekBias::Right, &()).items(&()),
Vec::<u8>::new()
);
assert_eq!(cursor.item(), Some(&1));
assert_eq!(cursor.prev_item(), None);
assert_eq!(cursor.start(), &Sum(0));
cursor.next();
cursor.next(&());
assert_eq!(cursor.item(), None);
assert_eq!(cursor.prev_item(), Some(&1));
assert_eq!(cursor.start(), &Sum(1));
cursor.prev();
cursor.prev(&());
assert_eq!(cursor.item(), Some(&1));
assert_eq!(cursor.prev_item(), None);
assert_eq!(cursor.start(), &Sum(0));
let mut cursor = tree.cursor::<Count, Sum>();
assert_eq!(cursor.slice(&Count(1), SeekBias::Right, &()).items(), [1]);
assert_eq!(
cursor.slice(&Count(1), SeekBias::Right, &()).items(&()),
[1]
);
assert_eq!(cursor.item(), None);
assert_eq!(cursor.prev_item(), Some(&1));
assert_eq!(cursor.start(), &Sum(1));
@ -739,8 +759,8 @@ mod tests {
cursor.seek(&Count(0), SeekBias::Right, &());
assert_eq!(
cursor
.slice(&tree.extent::<Count>(), SeekBias::Right, &())
.items(),
.slice(&tree.extent::<Count>(&()), SeekBias::Right, &())
.items(&()),
[1]
);
assert_eq!(cursor.item(), None);
@ -753,70 +773,70 @@ mod tests {
let mut cursor = tree.cursor::<Count, Sum>();
assert_eq!(
cursor.slice(&Count(2), SeekBias::Right, &()).items(),
cursor.slice(&Count(2), SeekBias::Right, &()).items(&()),
[1, 2]
);
assert_eq!(cursor.item(), Some(&3));
assert_eq!(cursor.prev_item(), Some(&2));
assert_eq!(cursor.start(), &Sum(3));
cursor.next();
cursor.next(&());
assert_eq!(cursor.item(), Some(&4));
assert_eq!(cursor.prev_item(), Some(&3));
assert_eq!(cursor.start(), &Sum(6));
cursor.next();
cursor.next(&());
assert_eq!(cursor.item(), Some(&5));
assert_eq!(cursor.prev_item(), Some(&4));
assert_eq!(cursor.start(), &Sum(10));
cursor.next();
cursor.next(&());
assert_eq!(cursor.item(), Some(&6));
assert_eq!(cursor.prev_item(), Some(&5));
assert_eq!(cursor.start(), &Sum(15));
cursor.next();
cursor.next();
cursor.next(&());
cursor.next(&());
assert_eq!(cursor.item(), None);
assert_eq!(cursor.prev_item(), Some(&6));
assert_eq!(cursor.start(), &Sum(21));
cursor.prev();
cursor.prev(&());
assert_eq!(cursor.item(), Some(&6));
assert_eq!(cursor.prev_item(), Some(&5));
assert_eq!(cursor.start(), &Sum(15));
cursor.prev();
cursor.prev(&());
assert_eq!(cursor.item(), Some(&5));
assert_eq!(cursor.prev_item(), Some(&4));
assert_eq!(cursor.start(), &Sum(10));
cursor.prev();
cursor.prev(&());
assert_eq!(cursor.item(), Some(&4));
assert_eq!(cursor.prev_item(), Some(&3));
assert_eq!(cursor.start(), &Sum(6));
cursor.prev();
cursor.prev(&());
assert_eq!(cursor.item(), Some(&3));
assert_eq!(cursor.prev_item(), Some(&2));
assert_eq!(cursor.start(), &Sum(3));
cursor.prev();
cursor.prev(&());
assert_eq!(cursor.item(), Some(&2));
assert_eq!(cursor.prev_item(), Some(&1));
assert_eq!(cursor.start(), &Sum(1));
cursor.prev();
cursor.prev(&());
assert_eq!(cursor.item(), Some(&1));
assert_eq!(cursor.prev_item(), None);
assert_eq!(cursor.start(), &Sum(0));
cursor.prev();
cursor.prev(&());
assert_eq!(cursor.item(), None);
assert_eq!(cursor.prev_item(), None);
assert_eq!(cursor.start(), &Sum(0));
cursor.next();
cursor.next(&());
assert_eq!(cursor.item(), Some(&1));
assert_eq!(cursor.prev_item(), None);
assert_eq!(cursor.start(), &Sum(0));
@ -824,9 +844,9 @@ mod tests {
let mut cursor = tree.cursor::<Count, Sum>();
assert_eq!(
cursor
.slice(&tree.extent::<Count>(), SeekBias::Right, &())
.items(),
tree.items()
.slice(&tree.extent::<Count>(&()), SeekBias::Right, &())
.items(&()),
tree.items(&())
);
assert_eq!(cursor.item(), None);
assert_eq!(cursor.prev_item(), Some(&6));
@ -835,8 +855,8 @@ mod tests {
cursor.seek(&Count(3), SeekBias::Right, &());
assert_eq!(
cursor
.slice(&tree.extent::<Count>(), SeekBias::Right, &())
.items(),
.slice(&tree.extent::<Count>(&()), SeekBias::Right, &())
.items(&()),
[4, 5, 6]
);
assert_eq!(cursor.item(), None);
@ -852,15 +872,15 @@ mod tests {
// Slicing without resetting starts from where the cursor is parked at.
cursor.seek(&Count(1), SeekBias::Right, &());
assert_eq!(
cursor.slice(&Count(3), SeekBias::Right, &()).items(),
cursor.slice(&Count(3), SeekBias::Right, &()).items(&()),
vec![2, 3]
);
assert_eq!(
cursor.slice(&Count(6), SeekBias::Left, &()).items(),
cursor.slice(&Count(6), SeekBias::Left, &()).items(&()),
vec![4, 5]
);
assert_eq!(
cursor.slice(&Count(6), SeekBias::Right, &()).items(),
cursor.slice(&Count(6), SeekBias::Right, &()).items(&()),
vec![6]
);
}
@ -870,7 +890,7 @@ mod tests {
let mut tree = SumTree::<u8>::new();
let removed = tree.edit(vec![Edit::Insert(1), Edit::Insert(2), Edit::Insert(0)], &());
assert_eq!(tree.items(), vec![0, 1, 2]);
assert_eq!(tree.items(&()), vec![0, 1, 2]);
assert_eq!(removed, Vec::<u8>::new());
assert_eq!(tree.get(&0, &()), Some(&0));
assert_eq!(tree.get(&1, &()), Some(&1));
@ -878,7 +898,7 @@ mod tests {
assert_eq!(tree.get(&4, &()), None);
let removed = tree.edit(vec![Edit::Insert(2), Edit::Insert(4), Edit::Remove(0)], &());
assert_eq!(tree.items(), vec![1, 2, 4]);
assert_eq!(tree.items(&()), vec![1, 2, 4]);
assert_eq!(removed, vec![0, 2]);
assert_eq!(tree.get(&0, &()), None);
assert_eq!(tree.get(&1, &()), Some(&1));
@ -933,19 +953,19 @@ mod tests {
}
impl<'a> Dimension<'a, IntegersSummary> for u8 {
fn add_summary(&mut self, summary: &IntegersSummary) {
fn add_summary(&mut self, summary: &IntegersSummary, _: &()) {
*self = summary.max;
}
}
impl<'a> Dimension<'a, IntegersSummary> for Count {
fn add_summary(&mut self, summary: &IntegersSummary) {
fn add_summary(&mut self, summary: &IntegersSummary, _: &()) {
self.0 += summary.count.0;
}
}
impl<'a> Dimension<'a, IntegersSummary> for Sum {
fn add_summary(&mut self, summary: &IntegersSummary) {
fn add_summary(&mut self, summary: &IntegersSummary, _: &()) {
self.0 += summary.sum.0;
}
}

View File

@ -49,10 +49,10 @@ where
&self.sum_dimension
}
pub fn end(&self) -> U {
pub fn end(&self, cx: &<T::Summary as Summary>::Context) -> U {
if let Some(item_summary) = self.item_summary() {
let mut end = self.start().clone();
end.add_summary(item_summary);
end.add_summary(item_summary, cx);
end
} else {
self.start().clone()
@ -134,13 +134,13 @@ where
}
#[allow(unused)]
pub fn prev(&mut self) {
pub fn prev(&mut self, cx: &<T::Summary as Summary>::Context) {
assert!(self.did_seek, "Must seek before calling this method");
if self.at_end {
self.seek_dimension = S::default();
self.sum_dimension = U::default();
self.descend_to_last_item(self.tree);
self.descend_to_last_item(self.tree, cx);
self.at_end = false;
} else {
while let Some(entry) = self.stack.pop() {
@ -167,8 +167,8 @@ where
..
} => {
for summary in &child_summaries[0..new_index] {
self.seek_dimension.add_summary(summary);
self.sum_dimension.add_summary(summary);
self.seek_dimension.add_summary(summary, cx);
self.sum_dimension.add_summary(summary, cx);
}
self.stack.push(StackEntry {
tree: entry.tree,
@ -176,12 +176,12 @@ where
seek_dimension: self.seek_dimension.clone(),
sum_dimension: self.sum_dimension.clone(),
});
self.descend_to_last_item(&child_trees[new_index]);
self.descend_to_last_item(&child_trees[new_index], cx);
}
Node::Leaf { item_summaries, .. } => {
for item_summary in &item_summaries[0..new_index] {
self.seek_dimension.add_summary(item_summary);
self.sum_dimension.add_summary(item_summary);
self.seek_dimension.add_summary(item_summary, cx);
self.sum_dimension.add_summary(item_summary, cx);
}
self.stack.push(StackEntry {
tree: entry.tree,
@ -198,11 +198,11 @@ where
}
}
pub fn next(&mut self) {
self.next_internal(|_| true)
pub fn next(&mut self, cx: &<T::Summary as Summary>::Context) {
self.next_internal(|_| true, cx)
}
fn next_internal<F>(&mut self, filter_node: F)
fn next_internal<F>(&mut self, filter_node: F, cx: &<T::Summary as Summary>::Context)
where
F: Fn(&T::Summary) -> bool,
{
@ -230,8 +230,8 @@ where
} => {
if !descend {
let summary = &child_summaries[entry.index];
entry.seek_dimension.add_summary(summary);
entry.sum_dimension.add_summary(summary);
entry.seek_dimension.add_summary(summary, cx);
entry.sum_dimension.add_summary(summary, cx);
entry.index += 1;
}
@ -240,8 +240,8 @@ where
if filter_node(next_summary) {
break;
} else {
self.seek_dimension.add_summary(next_summary);
self.sum_dimension.add_summary(next_summary);
self.seek_dimension.add_summary(next_summary, cx);
self.sum_dimension.add_summary(next_summary, cx);
}
entry.index += 1;
}
@ -251,10 +251,10 @@ where
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);
self.seek_dimension.add_summary(item_summary, cx);
entry.seek_dimension.add_summary(item_summary, cx);
self.sum_dimension.add_summary(item_summary, cx);
entry.sum_dimension.add_summary(item_summary, cx);
entry.index += 1;
}
@ -263,10 +263,10 @@ where
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);
self.seek_dimension.add_summary(next_item_summary, cx);
entry.seek_dimension.add_summary(next_item_summary, cx);
self.sum_dimension.add_summary(next_item_summary, cx);
entry.sum_dimension.add_summary(next_item_summary, cx);
entry.index += 1;
}
} else {
@ -295,7 +295,11 @@ where
debug_assert!(self.stack.is_empty() || self.stack.last().unwrap().tree.0.is_leaf());
}
fn descend_to_last_item(&mut self, mut subtree: &'a SumTree<T>) {
fn descend_to_last_item(
&mut self,
mut subtree: &'a SumTree<T>,
cx: &<T::Summary as Summary>::Context,
) {
self.did_seek = true;
loop {
match subtree.0.as_ref() {
@ -305,8 +309,8 @@ where
..
} => {
for summary in &child_summaries[0..child_summaries.len() - 1] {
self.seek_dimension.add_summary(summary);
self.sum_dimension.add_summary(summary);
self.seek_dimension.add_summary(summary, cx);
self.sum_dimension.add_summary(summary, cx);
}
self.stack.push(StackEntry {
@ -320,8 +324,8 @@ where
Node::Leaf { item_summaries, .. } => {
let last_index = item_summaries.len().saturating_sub(1);
for item_summary in &item_summaries[0..last_index] {
self.seek_dimension.add_summary(item_summary);
self.sum_dimension.add_summary(item_summary);
self.seek_dimension.add_summary(item_summary, cx);
self.sum_dimension.add_summary(item_summary, cx);
}
self.stack.push(StackEntry {
tree: subtree,
@ -372,7 +376,7 @@ where
}
pub fn suffix(&mut self, cx: &<T::Summary as Summary>::Context) -> SumTree<T> {
let extent = self.tree.extent::<S>();
let extent = self.tree.extent::<S>(cx);
let mut slice = SeekAggregate::Slice(SumTree::new());
self.seek_internal::<()>(&extent, SeekBias::Right, &mut slice, cx);
if let SeekAggregate::Slice(slice) = slice {
@ -428,21 +432,21 @@ where
.zip(&child_summaries[entry.index..])
{
let mut child_end = self.seek_dimension.clone();
child_end.add_summary(&child_summary);
child_end.add_summary(&child_summary, cx);
let comparison = target.cmp(&child_end, cx);
if comparison == Ordering::Greater
|| (comparison == Ordering::Equal && bias == SeekBias::Right)
{
self.seek_dimension = child_end;
self.sum_dimension.add_summary(child_summary);
self.sum_dimension.add_summary(child_summary, cx);
match aggregate {
SeekAggregate::None => {}
SeekAggregate::Slice(slice) => {
slice.push_tree(child_tree.clone(), cx);
}
SeekAggregate::Summary(summary) => {
summary.add_summary(child_summary);
summary.add_summary(child_summary, cx);
}
}
entry.index += 1;
@ -470,14 +474,14 @@ where
.zip(&item_summaries[entry.index..])
{
let mut child_end = self.seek_dimension.clone();
child_end.add_summary(item_summary);
child_end.add_summary(item_summary, cx);
let comparison = target.cmp(&child_end, cx);
if comparison == Ordering::Greater
|| (comparison == Ordering::Equal && bias == SeekBias::Right)
{
self.seek_dimension = child_end;
self.sum_dimension.add_summary(item_summary);
self.sum_dimension.add_summary(item_summary, cx);
match aggregate {
SeekAggregate::None => {}
SeekAggregate::Slice(_) => {
@ -489,7 +493,7 @@ where
.add_summary(item_summary, cx);
}
SeekAggregate::Summary(summary) => {
summary.add_summary(item_summary);
summary.add_summary(item_summary, cx);
}
}
entry.index += 1;
@ -544,21 +548,21 @@ where
child_trees.iter().zip(child_summaries).enumerate()
{
let mut child_end = self.seek_dimension.clone();
child_end.add_summary(child_summary);
child_end.add_summary(child_summary, cx);
let comparison = target.cmp(&child_end, cx);
if comparison == Ordering::Greater
|| (comparison == Ordering::Equal && bias == SeekBias::Right)
{
self.seek_dimension = child_end;
self.sum_dimension.add_summary(child_summary);
self.sum_dimension.add_summary(child_summary, cx);
match aggregate {
SeekAggregate::None => {}
SeekAggregate::Slice(slice) => {
slice.push_tree(child_trees[index].clone(), cx);
}
SeekAggregate::Summary(summary) => {
summary.add_summary(child_summary);
summary.add_summary(child_summary, cx);
}
}
} else {
@ -590,14 +594,14 @@ where
items.iter().zip(item_summaries).enumerate()
{
let mut child_end = self.seek_dimension.clone();
child_end.add_summary(item_summary);
child_end.add_summary(item_summary, cx);
let comparison = target.cmp(&child_end, cx);
if comparison == Ordering::Greater
|| (comparison == Ordering::Equal && bias == SeekBias::Right)
{
self.seek_dimension = child_end;
self.sum_dimension.add_summary(item_summary);
self.sum_dimension.add_summary(item_summary, cx);
match aggregate {
SeekAggregate::None => {}
SeekAggregate::Slice(_) => {
@ -609,7 +613,7 @@ where
slice_item_summaries.push(item_summary.clone());
}
SeekAggregate::Summary(summary) => {
summary.add_summary(item_summary);
summary.add_summary(item_summary, cx);
}
}
} else {
@ -651,7 +655,7 @@ where
if bias == SeekBias::Left {
let mut end = self.seek_dimension.clone();
if let Some(summary) = self.item_summary() {
end.add_summary(summary);
end.add_summary(summary, cx);
}
target.cmp(&end, cx) == Ordering::Equal
} else {
@ -660,21 +664,22 @@ where
}
}
impl<'a, T, S, U> Iterator for Cursor<'a, T, S, U>
impl<'a, T, S, Seek, Sum> Iterator for Cursor<'a, T, Seek, Sum>
where
T: Item,
S: Dimension<'a, T::Summary>,
U: Dimension<'a, T::Summary>,
T: Item<Summary = S>,
S: Summary<Context = ()>,
Seek: Dimension<'a, T::Summary>,
Sum: Dimension<'a, T::Summary>,
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
if !self.did_seek {
self.next();
self.next(&());
}
if let Some(item) = self.item() {
self.next();
self.next(&());
Some(item)
} else {
None
@ -693,9 +698,13 @@ where
T: Item,
U: Dimension<'a, T::Summary>,
{
pub fn new(tree: &'a SumTree<T>, filter_node: F) -> Self {
pub fn new(
tree: &'a SumTree<T>,
filter_node: F,
cx: &<T::Summary as Summary>::Context,
) -> Self {
let mut cursor = tree.cursor::<(), U>();
cursor.next_internal(&filter_node);
cursor.next_internal(&filter_node, cx);
Self {
cursor,
filter_node,
@ -710,22 +719,23 @@ where
self.cursor.item()
}
pub fn next(&mut self) {
self.cursor.next_internal(&self.filter_node);
pub fn next(&mut self, cx: &<T::Summary as Summary>::Context) {
self.cursor.next_internal(&self.filter_node, cx);
}
}
impl<'a, F, T, U> Iterator for FilterCursor<'a, F, T, U>
impl<'a, F, T, S, U> Iterator for FilterCursor<'a, F, T, U>
where
F: Fn(&T::Summary) -> bool,
T: Item,
T: Item<Summary = S>,
S: Summary<Context = ()>,
U: Dimension<'a, T::Summary>,
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
if let Some(item) = self.item() {
self.cursor.next_internal(&self.filter_node);
self.cursor.next_internal(&self.filter_node, &());
Some(item)
} else {
None

View File

@ -603,7 +603,7 @@ impl Default for PathKey {
}
impl<'a> sum_tree::Dimension<'a, EntrySummary> for PathKey {
fn add_summary(&mut self, summary: &'a EntrySummary) {
fn add_summary(&mut self, summary: &'a EntrySummary, _: &()) {
self.0 = summary.max_path.clone();
}
}
@ -643,7 +643,7 @@ impl<'a> Default for PathSearch<'a> {
}
impl<'a: 'b, 'b> sum_tree::Dimension<'a, EntrySummary> for PathSearch<'b> {
fn add_summary(&mut self, summary: &'a EntrySummary) {
fn add_summary(&mut self, summary: &'a EntrySummary, _: &()) {
*self = Self::Exact(summary.max_path.as_ref());
}
}
@ -652,7 +652,7 @@ impl<'a: 'b, 'b> sum_tree::Dimension<'a, EntrySummary> for PathSearch<'b> {
pub struct FileCount(usize);
impl<'a> sum_tree::Dimension<'a, EntrySummary> for FileCount {
fn add_summary(&mut self, summary: &'a EntrySummary) {
fn add_summary(&mut self, summary: &'a EntrySummary, _: &()) {
self.0 += summary.file_count;
}
}
@ -661,7 +661,7 @@ impl<'a> sum_tree::Dimension<'a, EntrySummary> for FileCount {
pub struct VisibleFileCount(usize);
impl<'a> sum_tree::Dimension<'a, EntrySummary> for VisibleFileCount {
fn add_summary(&mut self, summary: &'a EntrySummary) {
fn add_summary(&mut self, summary: &'a EntrySummary, _: &()) {
self.0 += summary.visible_file_count;
}
}