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

View File

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

View File

@ -12,6 +12,7 @@ use gpui::{AppContext, ModelHandle};
use parking_lot::{Mutex, MutexGuard}; use parking_lot::{Mutex, MutexGuard};
use std::{ use std::{
cmp::{self, Ordering}, cmp::{self, Ordering},
iter,
ops::Range, ops::Range,
}; };
@ -80,7 +81,13 @@ impl FoldMap {
where where
T: ToOffset, 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>( pub fn fold<T: ToOffset>(
@ -149,7 +156,7 @@ impl FoldMap {
..Default::default() ..Default::default()
}); });
fold_ixs_to_delete.push(*folds_cursor.start()); 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(); let mut folds = SumTree::new();
for fold_ix in fold_ixs_to_delete { for fold_ix in fold_ixs_to_delete {
folds.push_tree(cursor.slice(&fold_ix, SeekBias::Right, buffer), buffer); folds.push_tree(cursor.slice(&fold_ix, SeekBias::Right, buffer), buffer);
cursor.next(); cursor.next(buffer);
} }
folds.push_tree(cursor.suffix(buffer), buffer); folds.push_tree(cursor.suffix(buffer), buffer);
folds folds
@ -186,10 +193,13 @@ impl FoldMap {
let buffer = self.buffer.read(cx); let buffer = self.buffer.read(cx);
let start = buffer.anchor_before(range.start.to_offset(buffer)); let start = buffer.anchor_before(range.start.to_offset(buffer));
let end = buffer.anchor_after(range.end.to_offset(buffer)); let end = buffer.anchor_after(range.end.to_offset(buffer));
self.folds.filter::<_, usize>(move |summary| { self.folds.filter::<_, usize>(
start.cmp(&summary.max_end, buffer).unwrap() == Ordering::Less move |summary| {
&& end.cmp(&summary.min_start, buffer).unwrap() == Ordering::Greater 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 pub fn intersects_fold<T>(&self, offset: T, cx: &AppContext) -> bool
@ -212,8 +222,8 @@ impl FoldMap {
if transform.display_text.is_some() { if transform.display_text.is_some() {
return true; return true;
} }
if cursor.end().row() == display_row { if cursor.end(&()).row() == display_row {
cursor.next() cursor.next(&())
} else { } else {
break; break;
} }
@ -244,7 +254,7 @@ impl FoldMap {
let overshoot = point - cursor.start().buffer.lines; let overshoot = point - cursor.start().buffer.lines;
DisplayPoint(cmp::min( DisplayPoint(cmp::min(
cursor.start().display.lines + overshoot, 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(); edit.old_range.start = *cursor.start();
cursor.seek(&edit.old_range.end, SeekBias::Right, &()); cursor.seek(&edit.old_range.end, SeekBias::Right, &());
cursor.next(); cursor.next(&());
let mut delta = edit.delta(); let mut delta = edit.delta();
loop { loop {
@ -293,7 +303,7 @@ impl FoldMap {
if next_edit.old_range.end >= edit.old_range.end { if next_edit.old_range.end >= edit.old_range.end {
edit.old_range.end = next_edit.old_range.end; edit.old_range.end = next_edit.old_range.end;
cursor.seek(&edit.old_range.end, SeekBias::Right, &()); cursor.seek(&edit.old_range.end, SeekBias::Right, &());
cursor.next(); cursor.next(&());
} }
} else { } else {
break; break;
@ -306,9 +316,14 @@ impl FoldMap {
let anchor = buffer.anchor_before(edit.new_range.start); let anchor = buffer.anchor_before(edit.new_range.start);
let mut folds_cursor = self.folds.cursor::<_, ()>(); let mut folds_cursor = self.folds.cursor::<_, ()>();
folds_cursor.seek(&Fold(anchor..Anchor::End), SeekBias::Left, buffer); folds_cursor.seek(&Fold(anchor..Anchor::End), SeekBias::Left, buffer);
let mut folds = folds_cursor let mut folds = iter::from_fn(move || {
.map(|f| f.0.start.to_offset(buffer)..f.0.end.to_offset(buffer)) let item = folds_cursor
.peekable(); .item()
.map(|f| f.0.start.to_offset(buffer)..f.0.end.to_offset(buffer));
folds_cursor.next(buffer);
item
})
.peekable();
while folds while folds
.peek() .peek()
@ -501,7 +516,7 @@ impl FoldMapSnapshot {
if offset.0 == transform_start || matches!(bias, Bias::Left) { if offset.0 == transform_start || matches!(bias, Bias::Left) {
DisplayOffset(transform_start) DisplayOffset(transform_start)
} else { } else {
DisplayOffset(cursor.end().display.bytes) DisplayOffset(cursor.end(&()).display.bytes)
} }
} else { } else {
let overshoot = offset.0 - transform_start; let overshoot = offset.0 - transform_start;
@ -526,7 +541,7 @@ impl FoldMapSnapshot {
if point.0 == transform_start || matches!(bias, Bias::Left) { if point.0 == transform_start || matches!(bias, Bias::Left) {
DisplayPoint(transform_start) DisplayPoint(transform_start)
} else { } else {
DisplayPoint(cursor.end().display.lines) DisplayPoint(cursor.end(&()).display.lines)
} }
} else { } else {
let overshoot = point.0 - transform_start; 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 { 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, &()); 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 { 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.start = summary.start.clone();
self.0.end = summary.end.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 { 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; *self += summary.count;
} }
} }
@ -676,8 +691,8 @@ impl<'a> Iterator for BufferRows<'a> {
type Item = u32; type Item = u32;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
while self.display_point > self.cursor.end().display.lines { while self.display_point > self.cursor.end(&()).display.lines {
self.cursor.next(); self.cursor.next(&());
if self.cursor.item().is_none() { if self.cursor.item().is_none() {
// TODO: Return a bool from next? // TODO: Return a bool from next?
break; break;
@ -717,10 +732,10 @@ impl<'a> Iterator for Chunks<'a> {
self.buffer_offset += transform.summary.buffer.bytes; self.buffer_offset += transform.summary.buffer.bytes;
self.buffer_chunks.seek(self.buffer_offset); 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.item().is_some()
{ {
self.transform_cursor.next(); self.transform_cursor.next(&());
} }
return Some(display_text); return Some(display_text);
@ -732,10 +747,10 @@ impl<'a> Iterator for Chunks<'a> {
chunk = &chunk[offset_in_chunk..]; chunk = &chunk[offset_in_chunk..];
// Truncate the chunk so that it ends at the next fold. // 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 { if chunk.len() >= region_end {
chunk = &chunk[0..region_end]; chunk = &chunk[0..region_end];
self.transform_cursor.next(); self.transform_cursor.next(&());
} else { } else {
self.buffer_chunks.next(); self.buffer_chunks.next();
} }
@ -772,10 +787,10 @@ impl<'a> Iterator for HighlightedChunks<'a> {
self.buffer_offset += transform.summary.buffer.bytes; self.buffer_offset += transform.summary.buffer.bytes;
self.buffer_chunks.seek(self.buffer_offset); 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.item().is_some()
{ {
self.transform_cursor.next(); self.transform_cursor.next(&());
} }
return Some((display_text, StyleId::default())); return Some((display_text, StyleId::default()));
@ -796,10 +811,10 @@ impl<'a> Iterator for HighlightedChunks<'a> {
chunk = &chunk[offset_in_chunk..]; chunk = &chunk[offset_in_chunk..];
// Truncate the chunk so that it ends at the next fold. // 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 { if chunk.len() >= region_end {
chunk = &chunk[0..region_end]; chunk = &chunk[0..region_end];
self.transform_cursor.next(); self.transform_cursor.next(&());
} else { } else {
self.buffer_chunk.take(); self.buffer_chunk.take();
} }
@ -813,7 +828,7 @@ impl<'a> Iterator for HighlightedChunks<'a> {
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for DisplayPoint { 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; self.0 += &summary.display.lines;
} }
} }
@ -822,19 +837,19 @@ impl<'a> sum_tree::Dimension<'a, TransformSummary> for DisplayPoint {
pub struct DisplayOffset(usize); pub struct DisplayOffset(usize);
impl<'a> sum_tree::Dimension<'a, TransformSummary> for DisplayOffset { 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; self.0 += &summary.display.bytes;
} }
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for Point { 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; *self += &summary.buffer.lines;
} }
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for usize { 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; *self += &summary.buffer.bytes;
} }
} }
@ -1027,29 +1042,6 @@ mod tests {
for _ in 0..operations { for _ in 0..operations {
log::info!("text: {:?}", buffer.read(cx).text()); 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) { match rng.gen_range(0..=100) {
0..=34 => { 0..=34 => {
let buffer = buffer.read(cx); let buffer = buffer.read(cx);
@ -1195,7 +1187,7 @@ mod tests {
let start = buffer.clip_offset(rng.gen_range(0..=end), Left); let start = buffer.clip_offset(rng.gen_range(0..=end), Left);
let expected_folds = map let expected_folds = map
.folds .folds
.items() .items(buffer)
.into_iter() .into_iter()
.filter(|fold| { .filter(|fold| {
let start = buffer.anchor_before(start); let start = buffer.anchor_before(start);
@ -1250,7 +1242,7 @@ mod tests {
fn merged_fold_ranges(&self, cx: &AppContext) -> Vec<Range<usize>> { fn merged_fold_ranges(&self, cx: &AppContext) -> Vec<Range<usize>> {
let buffer = self.buffer.read(cx); 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. // Ensure sorting doesn't change how folds get merged and displayed.
folds.sort_by(|a, b| a.0.cmp(&b.0, buffer).unwrap()); folds.sort_by(|a, b| a.0.cmp(&b.0, buffer).unwrap());
let mut fold_ranges = folds 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 { 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); assert!(*self <= summary.key);
*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 { 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 () { 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> { pub trait SeekDimension<'a, T: Summary>: Dimension<'a, T> {
@ -71,9 +71,15 @@ impl<T: Item> SumTree<T> {
} }
#[allow(unused)] #[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::<(), ()>(); 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> pub fn cursor<'a, S, U>(&'a self) -> Cursor<T, S, U>
@ -84,12 +90,16 @@ impl<T: Item> SumTree<T> {
Cursor::new(self) 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 where
F: Fn(&T::Summary) -> bool, F: Fn(&T::Summary) -> bool,
U: Dimension<'a, T::Summary>, U: Dimension<'a, T::Summary>,
{ {
FilterCursor::new(self, filter_node) FilterCursor::new(self, filter_node, cx)
} }
#[allow(dead_code)] #[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(); let mut extent = D::default();
match self.0.as_ref() { match self.0.as_ref() {
Node::Internal { summary, .. } | Node::Leaf { summary, .. } => { Node::Internal { summary, .. } | Node::Leaf { summary, .. } => {
extent.add_summary(summary); extent.add_summary(summary, cx);
} }
} }
extent extent
@ -434,7 +447,7 @@ impl<T: KeyedItem> SumTree<T> {
if let Some(old_item) = old_item { if let Some(old_item) = old_item {
if old_item.key() == new_key { if old_item.key() == new_key {
removed.push(old_item.clone()); removed.push(old_item.clone());
cursor.next(); cursor.next(cx);
} }
} }
@ -580,7 +593,10 @@ mod tests {
tree2.extend(50..100, &()); tree2.extend(50..100, &());
tree1.push_tree(tree2, &()); 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] #[test]
@ -596,16 +612,16 @@ mod tests {
tree.extend(rng.sample_iter(distributions::Standard).take(count), &()); tree.extend(rng.sample_iter(distributions::Standard).take(count), &());
for _ in 0..5 { 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 splice_start = rng.gen_range(0..splice_end + 1);
let count = rng.gen_range(0..3); let count = rng.gen_range(0..3);
let tree_end = tree.extent::<Count>(); let tree_end = tree.extent::<Count>(&());
let new_items = rng let new_items = rng
.sample_iter(distributions::Standard) .sample_iter(distributions::Standard)
.take(count) .take(count)
.collect::<Vec<u8>>(); .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()); reference_items.splice(splice_start..splice_end, new_items.clone());
tree = { tree = {
@ -617,11 +633,12 @@ mod tests {
new_tree 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 let mut reference_filter = tree
.items() .items(&())
.into_iter() .into_iter()
.enumerate() .enumerate()
.filter(|(_, item)| (item & 1) == 0); .filter(|(_, item)| (item & 1) == 0);
@ -629,11 +646,11 @@ mod tests {
let (reference_index, reference_item) = reference_filter.next().unwrap(); let (reference_index, reference_item) = reference_filter.next().unwrap();
assert_eq!(actual_item, &reference_item); assert_eq!(actual_item, &reference_item);
assert_eq!(filter_cursor.start().0, reference_index); assert_eq!(filter_cursor.start().0, reference_index);
filter_cursor.next(); filter_cursor.next(&());
} }
assert!(reference_filter.next().is_none()); 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 before_start = false;
let mut cursor = tree.cursor::<Count, Count>(); let mut cursor = tree.cursor::<Count, Count>();
cursor.seek(&Count(pos), SeekBias::Right, &()); cursor.seek(&Count(pos), SeekBias::Right, &());
@ -654,13 +671,13 @@ mod tests {
} }
if i < 5 { if i < 5 {
cursor.next(); cursor.next(&());
if pos < reference_items.len() { if pos < reference_items.len() {
pos += 1; pos += 1;
before_start = false; before_start = false;
} }
} else { } else {
cursor.prev(); cursor.prev(&());
if pos == 0 { if pos == 0 {
before_start = true; before_start = true;
} }
@ -670,7 +687,7 @@ mod tests {
} }
for _ in 0..10 { 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 = rng.gen_range(0..end + 1);
let start_bias = if rng.gen() { let start_bias = if rng.gen() {
SeekBias::Left SeekBias::Left
@ -701,7 +718,7 @@ mod tests {
let tree = SumTree::<u8>::new(); let tree = SumTree::<u8>::new();
let mut cursor = tree.cursor::<Count, Sum>(); let mut cursor = tree.cursor::<Count, Sum>();
assert_eq!( assert_eq!(
cursor.slice(&Count(0), SeekBias::Right, &()).items(), cursor.slice(&Count(0), SeekBias::Right, &()).items(&()),
Vec::<u8>::new() Vec::<u8>::new()
); );
assert_eq!(cursor.item(), None); assert_eq!(cursor.item(), None);
@ -713,25 +730,28 @@ mod tests {
tree.extend(vec![1], &()); tree.extend(vec![1], &());
let mut cursor = tree.cursor::<Count, Sum>(); let mut cursor = tree.cursor::<Count, Sum>();
assert_eq!( assert_eq!(
cursor.slice(&Count(0), SeekBias::Right, &()).items(), cursor.slice(&Count(0), SeekBias::Right, &()).items(&()),
Vec::<u8>::new() Vec::<u8>::new()
); );
assert_eq!(cursor.item(), Some(&1)); assert_eq!(cursor.item(), Some(&1));
assert_eq!(cursor.prev_item(), None); assert_eq!(cursor.prev_item(), None);
assert_eq!(cursor.start(), &Sum(0)); assert_eq!(cursor.start(), &Sum(0));
cursor.next(); cursor.next(&());
assert_eq!(cursor.item(), None); assert_eq!(cursor.item(), None);
assert_eq!(cursor.prev_item(), Some(&1)); assert_eq!(cursor.prev_item(), Some(&1));
assert_eq!(cursor.start(), &Sum(1)); assert_eq!(cursor.start(), &Sum(1));
cursor.prev(); cursor.prev(&());
assert_eq!(cursor.item(), Some(&1)); assert_eq!(cursor.item(), Some(&1));
assert_eq!(cursor.prev_item(), None); assert_eq!(cursor.prev_item(), None);
assert_eq!(cursor.start(), &Sum(0)); assert_eq!(cursor.start(), &Sum(0));
let mut cursor = tree.cursor::<Count, Sum>(); 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.item(), None);
assert_eq!(cursor.prev_item(), Some(&1)); assert_eq!(cursor.prev_item(), Some(&1));
assert_eq!(cursor.start(), &Sum(1)); assert_eq!(cursor.start(), &Sum(1));
@ -739,8 +759,8 @@ mod tests {
cursor.seek(&Count(0), SeekBias::Right, &()); cursor.seek(&Count(0), SeekBias::Right, &());
assert_eq!( assert_eq!(
cursor cursor
.slice(&tree.extent::<Count>(), SeekBias::Right, &()) .slice(&tree.extent::<Count>(&()), SeekBias::Right, &())
.items(), .items(&()),
[1] [1]
); );
assert_eq!(cursor.item(), None); assert_eq!(cursor.item(), None);
@ -753,70 +773,70 @@ mod tests {
let mut cursor = tree.cursor::<Count, Sum>(); let mut cursor = tree.cursor::<Count, Sum>();
assert_eq!( assert_eq!(
cursor.slice(&Count(2), SeekBias::Right, &()).items(), cursor.slice(&Count(2), SeekBias::Right, &()).items(&()),
[1, 2] [1, 2]
); );
assert_eq!(cursor.item(), Some(&3)); assert_eq!(cursor.item(), Some(&3));
assert_eq!(cursor.prev_item(), Some(&2)); assert_eq!(cursor.prev_item(), Some(&2));
assert_eq!(cursor.start(), &Sum(3)); assert_eq!(cursor.start(), &Sum(3));
cursor.next(); cursor.next(&());
assert_eq!(cursor.item(), Some(&4)); assert_eq!(cursor.item(), Some(&4));
assert_eq!(cursor.prev_item(), Some(&3)); assert_eq!(cursor.prev_item(), Some(&3));
assert_eq!(cursor.start(), &Sum(6)); assert_eq!(cursor.start(), &Sum(6));
cursor.next(); cursor.next(&());
assert_eq!(cursor.item(), Some(&5)); assert_eq!(cursor.item(), Some(&5));
assert_eq!(cursor.prev_item(), Some(&4)); assert_eq!(cursor.prev_item(), Some(&4));
assert_eq!(cursor.start(), &Sum(10)); assert_eq!(cursor.start(), &Sum(10));
cursor.next(); cursor.next(&());
assert_eq!(cursor.item(), Some(&6)); assert_eq!(cursor.item(), Some(&6));
assert_eq!(cursor.prev_item(), Some(&5)); assert_eq!(cursor.prev_item(), Some(&5));
assert_eq!(cursor.start(), &Sum(15)); assert_eq!(cursor.start(), &Sum(15));
cursor.next(); cursor.next(&());
cursor.next(); cursor.next(&());
assert_eq!(cursor.item(), None); assert_eq!(cursor.item(), None);
assert_eq!(cursor.prev_item(), Some(&6)); assert_eq!(cursor.prev_item(), Some(&6));
assert_eq!(cursor.start(), &Sum(21)); assert_eq!(cursor.start(), &Sum(21));
cursor.prev(); cursor.prev(&());
assert_eq!(cursor.item(), Some(&6)); assert_eq!(cursor.item(), Some(&6));
assert_eq!(cursor.prev_item(), Some(&5)); assert_eq!(cursor.prev_item(), Some(&5));
assert_eq!(cursor.start(), &Sum(15)); assert_eq!(cursor.start(), &Sum(15));
cursor.prev(); cursor.prev(&());
assert_eq!(cursor.item(), Some(&5)); assert_eq!(cursor.item(), Some(&5));
assert_eq!(cursor.prev_item(), Some(&4)); assert_eq!(cursor.prev_item(), Some(&4));
assert_eq!(cursor.start(), &Sum(10)); assert_eq!(cursor.start(), &Sum(10));
cursor.prev(); cursor.prev(&());
assert_eq!(cursor.item(), Some(&4)); assert_eq!(cursor.item(), Some(&4));
assert_eq!(cursor.prev_item(), Some(&3)); assert_eq!(cursor.prev_item(), Some(&3));
assert_eq!(cursor.start(), &Sum(6)); assert_eq!(cursor.start(), &Sum(6));
cursor.prev(); cursor.prev(&());
assert_eq!(cursor.item(), Some(&3)); assert_eq!(cursor.item(), Some(&3));
assert_eq!(cursor.prev_item(), Some(&2)); assert_eq!(cursor.prev_item(), Some(&2));
assert_eq!(cursor.start(), &Sum(3)); assert_eq!(cursor.start(), &Sum(3));
cursor.prev(); cursor.prev(&());
assert_eq!(cursor.item(), Some(&2)); assert_eq!(cursor.item(), Some(&2));
assert_eq!(cursor.prev_item(), Some(&1)); assert_eq!(cursor.prev_item(), Some(&1));
assert_eq!(cursor.start(), &Sum(1)); assert_eq!(cursor.start(), &Sum(1));
cursor.prev(); cursor.prev(&());
assert_eq!(cursor.item(), Some(&1)); assert_eq!(cursor.item(), Some(&1));
assert_eq!(cursor.prev_item(), None); assert_eq!(cursor.prev_item(), None);
assert_eq!(cursor.start(), &Sum(0)); assert_eq!(cursor.start(), &Sum(0));
cursor.prev(); cursor.prev(&());
assert_eq!(cursor.item(), None); assert_eq!(cursor.item(), None);
assert_eq!(cursor.prev_item(), None); assert_eq!(cursor.prev_item(), None);
assert_eq!(cursor.start(), &Sum(0)); assert_eq!(cursor.start(), &Sum(0));
cursor.next(); cursor.next(&());
assert_eq!(cursor.item(), Some(&1)); assert_eq!(cursor.item(), Some(&1));
assert_eq!(cursor.prev_item(), None); assert_eq!(cursor.prev_item(), None);
assert_eq!(cursor.start(), &Sum(0)); assert_eq!(cursor.start(), &Sum(0));
@ -824,9 +844,9 @@ mod tests {
let mut cursor = tree.cursor::<Count, Sum>(); let mut cursor = tree.cursor::<Count, Sum>();
assert_eq!( assert_eq!(
cursor cursor
.slice(&tree.extent::<Count>(), SeekBias::Right, &()) .slice(&tree.extent::<Count>(&()), SeekBias::Right, &())
.items(), .items(&()),
tree.items() tree.items(&())
); );
assert_eq!(cursor.item(), None); assert_eq!(cursor.item(), None);
assert_eq!(cursor.prev_item(), Some(&6)); assert_eq!(cursor.prev_item(), Some(&6));
@ -835,8 +855,8 @@ mod tests {
cursor.seek(&Count(3), SeekBias::Right, &()); cursor.seek(&Count(3), SeekBias::Right, &());
assert_eq!( assert_eq!(
cursor cursor
.slice(&tree.extent::<Count>(), SeekBias::Right, &()) .slice(&tree.extent::<Count>(&()), SeekBias::Right, &())
.items(), .items(&()),
[4, 5, 6] [4, 5, 6]
); );
assert_eq!(cursor.item(), None); assert_eq!(cursor.item(), None);
@ -852,15 +872,15 @@ mod tests {
// Slicing without resetting starts from where the cursor is parked at. // Slicing without resetting starts from where the cursor is parked at.
cursor.seek(&Count(1), SeekBias::Right, &()); cursor.seek(&Count(1), SeekBias::Right, &());
assert_eq!( assert_eq!(
cursor.slice(&Count(3), SeekBias::Right, &()).items(), cursor.slice(&Count(3), SeekBias::Right, &()).items(&()),
vec![2, 3] vec![2, 3]
); );
assert_eq!( assert_eq!(
cursor.slice(&Count(6), SeekBias::Left, &()).items(), cursor.slice(&Count(6), SeekBias::Left, &()).items(&()),
vec![4, 5] vec![4, 5]
); );
assert_eq!( assert_eq!(
cursor.slice(&Count(6), SeekBias::Right, &()).items(), cursor.slice(&Count(6), SeekBias::Right, &()).items(&()),
vec![6] vec![6]
); );
} }
@ -870,7 +890,7 @@ mod tests {
let mut tree = SumTree::<u8>::new(); let mut tree = SumTree::<u8>::new();
let removed = tree.edit(vec![Edit::Insert(1), Edit::Insert(2), Edit::Insert(0)], &()); 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!(removed, Vec::<u8>::new());
assert_eq!(tree.get(&0, &()), Some(&0)); assert_eq!(tree.get(&0, &()), Some(&0));
assert_eq!(tree.get(&1, &()), Some(&1)); assert_eq!(tree.get(&1, &()), Some(&1));
@ -878,7 +898,7 @@ mod tests {
assert_eq!(tree.get(&4, &()), None); assert_eq!(tree.get(&4, &()), None);
let removed = tree.edit(vec![Edit::Insert(2), Edit::Insert(4), Edit::Remove(0)], &()); 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!(removed, vec![0, 2]);
assert_eq!(tree.get(&0, &()), None); assert_eq!(tree.get(&0, &()), None);
assert_eq!(tree.get(&1, &()), Some(&1)); assert_eq!(tree.get(&1, &()), Some(&1));
@ -933,19 +953,19 @@ mod tests {
} }
impl<'a> Dimension<'a, IntegersSummary> for u8 { impl<'a> Dimension<'a, IntegersSummary> for u8 {
fn add_summary(&mut self, summary: &IntegersSummary) { fn add_summary(&mut self, summary: &IntegersSummary, _: &()) {
*self = summary.max; *self = summary.max;
} }
} }
impl<'a> Dimension<'a, IntegersSummary> for Count { 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; self.0 += summary.count.0;
} }
} }
impl<'a> Dimension<'a, IntegersSummary> for Sum { 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; self.0 += summary.sum.0;
} }
} }

View File

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

View File

@ -603,7 +603,7 @@ impl Default for PathKey {
} }
impl<'a> sum_tree::Dimension<'a, EntrySummary> 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(); 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> { 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()); *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); pub struct FileCount(usize);
impl<'a> sum_tree::Dimension<'a, EntrySummary> for FileCount { 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; self.0 += summary.file_count;
} }
} }
@ -661,7 +661,7 @@ impl<'a> sum_tree::Dimension<'a, EntrySummary> for FileCount {
pub struct VisibleFileCount(usize); pub struct VisibleFileCount(usize);
impl<'a> sum_tree::Dimension<'a, EntrySummary> for VisibleFileCount { 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; self.0 += summary.visible_file_count;
} }
} }