Always provide a context to sum tree's methods

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Antonio Scandurra 2021-05-06 19:29:38 +02:00
parent 65e92ac2f2
commit e8179f7e3e
7 changed files with 378 additions and 347 deletions

View File

@ -373,39 +373,48 @@ impl Buffer {
insertion_splits.insert( insertion_splits.insert(
base_insertion.id, base_insertion.id,
SumTree::from_item(InsertionSplit { SumTree::from_item(
fragment_id: FragmentId::min_value().clone(), InsertionSplit {
extent: 0, fragment_id: FragmentId::min_value().clone(),
}), extent: 0,
},
&(),
),
);
fragments.push(
Fragment {
id: FragmentId::min_value().clone(),
insertion: base_insertion.clone(),
text: base_insertion.text.slice(0..0),
deletions: Default::default(),
max_undos: Default::default(),
visible: true,
},
&(),
); );
fragments.push(Fragment {
id: FragmentId::min_value().clone(),
insertion: base_insertion.clone(),
text: base_insertion.text.slice(0..0),
deletions: Default::default(),
max_undos: Default::default(),
visible: true,
});
if base_insertion.text.len() > 0 { if base_insertion.text.len() > 0 {
let base_fragment_id = let base_fragment_id =
FragmentId::between(&FragmentId::min_value(), &FragmentId::max_value()); FragmentId::between(&FragmentId::min_value(), &FragmentId::max_value());
insertion_splits insertion_splits.get_mut(&base_insertion.id).unwrap().push(
.get_mut(&base_insertion.id) InsertionSplit {
.unwrap()
.push(InsertionSplit {
fragment_id: base_fragment_id.clone(), fragment_id: base_fragment_id.clone(),
extent: base_insertion.text.len(), extent: base_insertion.text.len(),
}); },
fragments.push(Fragment { &(),
id: base_fragment_id, );
text: base_insertion.text.clone(), fragments.push(
insertion: base_insertion, Fragment {
deletions: Default::default(), id: base_fragment_id,
max_undos: Default::default(), text: base_insertion.text.clone(),
visible: true, insertion: base_insertion,
}); deletions: Default::default(),
max_undos: Default::default(),
visible: true,
},
&(),
);
} }
Self { Self {
@ -470,7 +479,7 @@ impl Buffer {
let mut summary = TextSummary::default(); let mut summary = TextSummary::default();
let mut cursor = self.fragments.cursor::<usize, usize>(); let mut cursor = self.fragments.cursor::<usize, usize>();
cursor.seek(&range.start, SeekBias::Right); cursor.seek(&range.start, SeekBias::Right, &());
if let Some(fragment) = cursor.item() { if let Some(fragment) = cursor.item() {
let summary_start = cmp::max(*cursor.start(), range.start) - cursor.start(); let summary_start = cmp::max(*cursor.start(), range.start) - cursor.start();
@ -480,7 +489,7 @@ impl Buffer {
} }
if range.end > *cursor.start() { if range.end > *cursor.start() {
summary += cursor.summary::<TextSummary>(&range.end, SeekBias::Right); summary += cursor.summary::<TextSummary>(&range.end, SeekBias::Right, &());
if let Some(fragment) = cursor.item() { if let Some(fragment) = cursor.item() {
let summary_start = cmp::max(*cursor.start(), range.start) - cursor.start(); let summary_start = cmp::max(*cursor.start(), range.start) - cursor.start();
@ -515,7 +524,7 @@ impl Buffer {
let mut summary = TextSummary::default(); let mut summary = TextSummary::default();
let mut cursor = self.fragments.cursor::<usize, usize>(); let mut cursor = self.fragments.cursor::<usize, usize>();
cursor.seek(&range.start, SeekBias::Right); cursor.seek(&range.start, SeekBias::Right, &());
if let Some(fragment) = cursor.item() { if let Some(fragment) = cursor.item() {
let summary_start = cmp::max(*cursor.start(), range.start) - cursor.start(); let summary_start = cmp::max(*cursor.start(), range.start) - cursor.start();
@ -525,7 +534,7 @@ impl Buffer {
} }
if range.end > *cursor.start() { if range.end > *cursor.start() {
summary += cursor.summary::<TextSummary>(&range.end, SeekBias::Right); summary += cursor.summary::<TextSummary>(&range.end, SeekBias::Right, &());
if let Some(fragment) = cursor.item() { if let Some(fragment) = cursor.item() {
let summary_start = cmp::max(*cursor.start(), range.start) - cursor.start(); let summary_start = cmp::max(*cursor.start(), range.start) - cursor.start();
@ -933,10 +942,10 @@ impl Buffer {
let mut cursor = old_fragments.cursor::<FragmentIdRef, ()>(); let mut cursor = old_fragments.cursor::<FragmentIdRef, ()>();
let mut new_fragments = let mut new_fragments =
cursor.slice(&FragmentIdRef::new(&start_fragment_id), SeekBias::Left); cursor.slice(&FragmentIdRef::new(&start_fragment_id), SeekBias::Left, &());
if start_offset == cursor.item().unwrap().end_offset() { if start_offset == cursor.item().unwrap().end_offset() {
new_fragments.push(cursor.item().unwrap().clone()); new_fragments.push(cursor.item().unwrap().clone(), &());
cursor.next(); cursor.next();
} }
@ -975,30 +984,33 @@ impl Buffer {
None None
}; };
if let Some(fragment) = before_range { if let Some(fragment) = before_range {
new_fragments.push(fragment); new_fragments.push(fragment, &());
} }
if let Some(fragment) = insertion { if let Some(fragment) = insertion {
new_fragments.push(fragment); new_fragments.push(fragment, &());
} }
if let Some(mut fragment) = within_range { if let Some(mut fragment) = within_range {
if fragment.was_visible(&version_in_range, &self.undo_map) { if fragment.was_visible(&version_in_range, &self.undo_map) {
fragment.deletions.insert(local_timestamp); fragment.deletions.insert(local_timestamp);
fragment.visible = false; fragment.visible = false;
} }
new_fragments.push(fragment); new_fragments.push(fragment, &());
} }
if let Some(fragment) = after_range { if let Some(fragment) = after_range {
new_fragments.push(fragment); new_fragments.push(fragment, &());
} }
} else { } else {
if new_text.is_some() && lamport_timestamp > fragment.insertion.lamport_timestamp { if new_text.is_some() && lamport_timestamp > fragment.insertion.lamport_timestamp {
new_fragments.push(self.build_fragment_to_insert( new_fragments.push(
cursor.prev_item().as_ref().unwrap(), self.build_fragment_to_insert(
Some(&fragment), cursor.prev_item().as_ref().unwrap(),
new_text.take().unwrap(), Some(&fragment),
local_timestamp, new_text.take().unwrap(),
lamport_timestamp, local_timestamp,
)); lamport_timestamp,
),
&(),
);
} }
if fragment.id < end_fragment_id if fragment.id < end_fragment_id
@ -1007,23 +1019,26 @@ impl Buffer {
fragment.deletions.insert(local_timestamp); fragment.deletions.insert(local_timestamp);
fragment.visible = false; fragment.visible = false;
} }
new_fragments.push(fragment); new_fragments.push(fragment, &());
} }
cursor.next(); cursor.next();
} }
if let Some(new_text) = new_text { if let Some(new_text) = new_text {
new_fragments.push(self.build_fragment_to_insert( new_fragments.push(
cursor.prev_item().as_ref().unwrap(), self.build_fragment_to_insert(
None, cursor.prev_item().as_ref().unwrap(),
new_text, None,
local_timestamp, new_text,
lamport_timestamp, local_timestamp,
)); lamport_timestamp,
),
&(),
);
} }
new_fragments.push_tree(cursor.slice(&last_id_ref, SeekBias::Right)); new_fragments.push_tree(cursor.slice(&last_id_ref, SeekBias::Right, &()), &());
self.fragments = new_fragments; self.fragments = new_fragments;
self.local_clock.observe(local_timestamp); self.local_clock.observe(local_timestamp);
self.lamport_clock.observe(lamport_timestamp); self.lamport_clock.observe(lamport_timestamp);
@ -1111,23 +1126,26 @@ impl Buffer {
let mut insertion_splits = splits.cursor::<(), ()>().map(|s| &s.fragment_id).peekable(); let mut insertion_splits = splits.cursor::<(), ()>().map(|s| &s.fragment_id).peekable();
let first_split_id = insertion_splits.next().unwrap(); let first_split_id = insertion_splits.next().unwrap();
new_fragments = cursor.slice(&FragmentIdRef::new(first_split_id), SeekBias::Left); new_fragments = cursor.slice(&FragmentIdRef::new(first_split_id), SeekBias::Left, &());
loop { loop {
let mut fragment = cursor.item().unwrap().clone(); let mut fragment = cursor.item().unwrap().clone();
fragment.visible = fragment.is_visible(&self.undo_map); fragment.visible = fragment.is_visible(&self.undo_map);
fragment.max_undos.observe(undo.id); fragment.max_undos.observe(undo.id);
new_fragments.push(fragment); new_fragments.push(fragment, &());
cursor.next(); cursor.next();
if let Some(split_id) = insertion_splits.next() { if let Some(split_id) = insertion_splits.next() {
new_fragments new_fragments.push_tree(
.push_tree(cursor.slice(&FragmentIdRef::new(split_id), SeekBias::Left)); cursor.slice(&FragmentIdRef::new(split_id), SeekBias::Left, &()),
&(),
);
} else { } else {
break; break;
} }
} }
} else { } else {
new_fragments = cursor.slice(&FragmentIdRef::new(&start_fragment_id), SeekBias::Left); new_fragments =
cursor.slice(&FragmentIdRef::new(&start_fragment_id), SeekBias::Left, &());
while let Some(fragment) = cursor.item() { while let Some(fragment) = cursor.item() {
if fragment.id > end_fragment_id { if fragment.id > end_fragment_id {
break; break;
@ -1139,13 +1157,13 @@ impl Buffer {
fragment.visible = fragment.is_visible(&self.undo_map); fragment.visible = fragment.is_visible(&self.undo_map);
fragment.max_undos.observe(undo.id); fragment.max_undos.observe(undo.id);
} }
new_fragments.push(fragment); new_fragments.push(fragment, &());
cursor.next(); cursor.next();
} }
} }
} }
new_fragments.push_tree(cursor.suffix()); new_fragments.push_tree(cursor.suffix(&()), &());
drop(cursor); drop(cursor);
self.fragments = new_fragments; self.fragments = new_fragments;
@ -1209,7 +1227,7 @@ impl Buffer {
.get(&edit_id) .get(&edit_id)
.ok_or_else(|| anyhow!("invalid operation"))?; .ok_or_else(|| anyhow!("invalid operation"))?;
let mut cursor = split_tree.cursor::<usize, ()>(); let mut cursor = split_tree.cursor::<usize, ()>();
cursor.seek(&offset, SeekBias::Left); cursor.seek(&offset, SeekBias::Left, &());
Ok(cursor Ok(cursor
.item() .item()
.ok_or_else(|| anyhow!("invalid operation"))? .ok_or_else(|| anyhow!("invalid operation"))?
@ -1231,7 +1249,10 @@ impl Buffer {
let old_fragments = self.fragments.clone(); let old_fragments = self.fragments.clone();
let mut cursor = old_fragments.cursor::<usize, usize>(); let mut cursor = old_fragments.cursor::<usize, usize>();
let mut new_fragments = SumTree::new(); let mut new_fragments = SumTree::new();
new_fragments.push_tree(cursor.slice(&cur_range.as_ref().unwrap().start, SeekBias::Right)); new_fragments.push_tree(
cursor.slice(&cur_range.as_ref().unwrap().start, SeekBias::Right, &()),
&(),
);
let mut start_id = None; let mut start_id = None;
let mut start_offset = None; let mut start_offset = None;
@ -1253,7 +1274,8 @@ impl Buffer {
.remove(&fragment.insertion.id) .remove(&fragment.insertion.id)
.unwrap(); .unwrap();
let mut splits_cursor = old_split_tree.cursor::<usize, ()>(); let mut splits_cursor = old_split_tree.cursor::<usize, ()>();
let mut new_split_tree = splits_cursor.slice(&fragment.start_offset(), SeekBias::Right); let mut new_split_tree =
splits_cursor.slice(&fragment.start_offset(), SeekBias::Right, &());
// Find all splices that start or end within the current fragment. Then, split the // Find all splices that start or end within the current fragment. Then, split the
// fragment and reassemble it in both trees accounting for the deleted and the newly // fragment and reassemble it in both trees accounting for the deleted and the newly
@ -1266,11 +1288,14 @@ impl Buffer {
prefix.id = prefix.id =
FragmentId::between(&new_fragments.last().unwrap().id, &fragment.id); FragmentId::between(&new_fragments.last().unwrap().id, &fragment.id);
fragment.set_start_offset(prefix.end_offset()); fragment.set_start_offset(prefix.end_offset());
new_fragments.push(prefix.clone()); new_fragments.push(prefix.clone(), &());
new_split_tree.push(InsertionSplit { new_split_tree.push(
extent: prefix.end_offset() - prefix.start_offset(), InsertionSplit {
fragment_id: prefix.id, extent: prefix.end_offset() - prefix.start_offset(),
}); fragment_id: prefix.id,
},
&(),
);
fragment_start = range.start; fragment_start = range.start;
} }
@ -1294,7 +1319,7 @@ impl Buffer {
local_timestamp, local_timestamp,
lamport_timestamp, lamport_timestamp,
); );
new_fragments.push(new_fragment); new_fragments.push(new_fragment, &());
} }
} }
@ -1310,11 +1335,14 @@ impl Buffer {
prefix.visible = false; prefix.visible = false;
} }
fragment.set_start_offset(prefix.end_offset()); fragment.set_start_offset(prefix.end_offset());
new_fragments.push(prefix.clone()); new_fragments.push(prefix.clone(), &());
new_split_tree.push(InsertionSplit { new_split_tree.push(
extent: prefix.end_offset() - prefix.start_offset(), InsertionSplit {
fragment_id: prefix.id, extent: prefix.end_offset() - prefix.start_offset(),
}); fragment_id: prefix.id,
},
&(),
);
fragment_start = range.end; fragment_start = range.end;
end_id = Some(fragment.insertion.id); end_id = Some(fragment.insertion.id);
end_offset = Some(fragment.start_offset()); end_offset = Some(fragment.start_offset());
@ -1358,16 +1386,21 @@ impl Buffer {
break; break;
} }
} }
new_split_tree.push(InsertionSplit { new_split_tree.push(
extent: fragment.end_offset() - fragment.start_offset(), InsertionSplit {
fragment_id: fragment.id.clone(), extent: fragment.end_offset() - fragment.start_offset(),
}); fragment_id: fragment.id.clone(),
},
&(),
);
splits_cursor.next(); splits_cursor.next();
new_split_tree new_split_tree.push_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
.insert(fragment.insertion.id, new_split_tree); .insert(fragment.insertion.id, new_split_tree);
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.
cursor.next(); cursor.next();
@ -1383,7 +1416,7 @@ impl Buffer {
new_fragment.deletions.insert(local_timestamp); new_fragment.deletions.insert(local_timestamp);
new_fragment.visible = false; new_fragment.visible = false;
} }
new_fragments.push(new_fragment); new_fragments.push(new_fragment, &());
cursor.next(); cursor.next();
if range.end == fragment_end { if range.end == fragment_end {
@ -1425,7 +1458,8 @@ impl Buffer {
// and push all the fragments in between into the new tree. // and push all the fragments in between into the new tree.
if cur_range.as_ref().map_or(false, |r| r.start > fragment_end) { if cur_range.as_ref().map_or(false, |r| r.start > fragment_end) {
new_fragments.push_tree( new_fragments.push_tree(
cursor.slice(&cur_range.as_ref().unwrap().start, SeekBias::Right), cursor.slice(&cur_range.as_ref().unwrap().start, SeekBias::Right, &()),
&(),
); );
} }
} }
@ -1457,11 +1491,13 @@ impl Buffer {
local_timestamp, local_timestamp,
lamport_timestamp, lamport_timestamp,
); );
new_fragments.push(new_fragment); new_fragments.push(new_fragment, &());
} }
} else { } else {
new_fragments new_fragments.push_tree(
.push_tree(cursor.slice(&old_fragments.extent::<usize>(), SeekBias::Right)); cursor.slice(&old_fragments.extent::<usize>(), SeekBias::Right, &()),
&(),
);
} }
self.fragments = new_fragments; self.fragments = new_fragments;
@ -1519,32 +1555,43 @@ impl Buffer {
.remove(&fragment.insertion.id) .remove(&fragment.insertion.id)
.unwrap(); .unwrap();
let mut cursor = old_split_tree.cursor::<usize, ()>(); let mut cursor = old_split_tree.cursor::<usize, ()>();
let mut new_split_tree = cursor.slice(&fragment.start_offset(), SeekBias::Right); let mut new_split_tree = cursor.slice(&fragment.start_offset(), SeekBias::Right, &());
if let Some(ref fragment) = before_range { if let Some(ref fragment) = before_range {
new_split_tree.push(InsertionSplit { new_split_tree.push(
extent: range.start - fragment.start_offset(), InsertionSplit {
fragment_id: fragment.id.clone(), extent: range.start - fragment.start_offset(),
}); fragment_id: fragment.id.clone(),
},
&(),
);
} }
if let Some(ref fragment) = within_range { if let Some(ref fragment) = within_range {
new_split_tree.push(InsertionSplit { new_split_tree.push(
extent: range.end - range.start, InsertionSplit {
fragment_id: fragment.id.clone(), extent: range.end - range.start,
}); fragment_id: fragment.id.clone(),
},
&(),
);
} }
if let Some(ref fragment) = after_range { if let Some(ref fragment) = after_range {
new_split_tree.push(InsertionSplit { new_split_tree.push(
extent: fragment.end_offset() - range.end, InsertionSplit {
fragment_id: fragment.id.clone(), extent: fragment.end_offset() - range.end,
}); fragment_id: fragment.id.clone(),
},
&(),
);
} }
cursor.next(); cursor.next();
new_split_tree new_split_tree.push_tree(
.push_tree(cursor.slice(&old_split_tree.extent::<usize>(), SeekBias::Right)); cursor.slice(&old_split_tree.extent::<usize>(), SeekBias::Right, &()),
&(),
);
self.insertion_splits self.insertion_splits
.insert(fragment.insertion.id, new_split_tree); .insert(fragment.insertion.id, new_split_tree);
@ -1569,10 +1616,13 @@ impl Buffer {
); );
let mut split_tree = SumTree::new(); let mut split_tree = SumTree::new();
split_tree.push(InsertionSplit { split_tree.push(
extent: text.len(), InsertionSplit {
fragment_id: new_fragment_id.clone(), extent: text.len(),
}); fragment_id: new_fragment_id.clone(),
},
&(),
);
self.insertion_splits.insert(local_timestamp, split_tree); self.insertion_splits.insert(local_timestamp, split_tree);
Fragment::new( Fragment::new(
@ -1621,7 +1671,7 @@ impl Buffer {
}; };
let mut cursor = self.fragments.cursor::<usize, usize>(); let mut cursor = self.fragments.cursor::<usize, usize>();
cursor.seek(&offset, seek_bias); cursor.seek(&offset, seek_bias, &());
let fragment = cursor.item().unwrap(); let fragment = cursor.item().unwrap();
let offset_in_fragment = offset - cursor.start(); let offset_in_fragment = offset - cursor.start();
let offset_in_insertion = fragment.start_offset() + offset_in_fragment; let offset_in_insertion = fragment.start_offset() + offset_in_fragment;
@ -1653,7 +1703,7 @@ impl Buffer {
.get(&insertion_id) .get(&insertion_id)
.ok_or_else(|| anyhow!("split does not exist for insertion id"))?; .ok_or_else(|| anyhow!("split does not exist for insertion id"))?;
let mut splits_cursor = splits.cursor::<usize, ()>(); let mut splits_cursor = splits.cursor::<usize, ()>();
splits_cursor.seek(offset, seek_bias); splits_cursor.seek(offset, seek_bias, &());
splits_cursor splits_cursor
.item() .item()
.ok_or_else(|| anyhow!("split offset is out of range")) .ok_or_else(|| anyhow!("split offset is out of range"))
@ -1681,13 +1731,13 @@ impl Buffer {
.get(&insertion_id) .get(&insertion_id)
.ok_or_else(|| anyhow!("split does not exist for insertion id"))?; .ok_or_else(|| anyhow!("split does not exist for insertion id"))?;
let mut splits_cursor = splits.cursor::<usize, ()>(); let mut splits_cursor = splits.cursor::<usize, ()>();
splits_cursor.seek(offset, seek_bias); splits_cursor.seek(offset, seek_bias, &());
let split = splits_cursor let split = splits_cursor
.item() .item()
.ok_or_else(|| anyhow!("split offset is out of range"))?; .ok_or_else(|| anyhow!("split offset is out of range"))?;
let mut fragments_cursor = self.fragments.cursor::<FragmentIdRef, TextSummary>(); let mut fragments_cursor = self.fragments.cursor::<FragmentIdRef, TextSummary>();
fragments_cursor.seek(&FragmentIdRef::new(&split.fragment_id), SeekBias::Left); fragments_cursor.seek(&FragmentIdRef::new(&split.fragment_id), SeekBias::Left, &());
let fragment = fragments_cursor let fragment = fragments_cursor
.item() .item()
.ok_or_else(|| anyhow!("fragment id does not exist"))?; .ok_or_else(|| anyhow!("fragment id does not exist"))?;
@ -1707,7 +1757,7 @@ impl Buffer {
#[allow(dead_code)] #[allow(dead_code)]
pub fn point_for_offset(&self, offset: usize) -> Result<Point> { pub fn point_for_offset(&self, offset: usize) -> Result<Point> {
let mut fragments_cursor = self.fragments.cursor::<usize, TextSummary>(); let mut fragments_cursor = self.fragments.cursor::<usize, TextSummary>();
fragments_cursor.seek(&offset, SeekBias::Left); fragments_cursor.seek(&offset, SeekBias::Left, &());
fragments_cursor fragments_cursor
.item() .item()
.ok_or_else(|| anyhow!("offset is out of range")) .ok_or_else(|| anyhow!("offset is out of range"))
@ -1772,7 +1822,7 @@ impl<'a> sum_tree::Dimension<'a, FragmentSummary> for Point {
impl<'a> CharIter<'a> { impl<'a> CharIter<'a> {
fn new(fragments: &'a SumTree<Fragment>, offset: usize) -> Self { fn new(fragments: &'a SumTree<Fragment>, offset: usize) -> Self {
let mut fragments_cursor = fragments.cursor::<usize, usize>(); let mut fragments_cursor = fragments.cursor::<usize, usize>();
fragments_cursor.seek(&offset, SeekBias::Right); fragments_cursor.seek(&offset, SeekBias::Right, &());
let fragment_chars = fragments_cursor.item().map_or("".chars(), |fragment| { let fragment_chars = fragments_cursor.item().map_or("".chars(), |fragment| {
let offset_in_fragment = offset - fragments_cursor.start(); let offset_in_fragment = offset - fragments_cursor.start();
fragment.text[offset_in_fragment..].chars() fragment.text[offset_in_fragment..].chars()
@ -1809,7 +1859,7 @@ impl<'a> Iterator for CharIter<'a> {
impl<'a> FragmentIter<'a> { impl<'a> FragmentIter<'a> {
fn new(fragments: &'a SumTree<Fragment>) -> Self { fn new(fragments: &'a SumTree<Fragment>) -> Self {
let mut cursor = fragments.cursor::<usize, usize>(); let mut cursor = fragments.cursor::<usize, usize>();
cursor.seek(&0, SeekBias::Right); cursor.seek(&0, SeekBias::Right, &());
Self { Self {
cursor, cursor,
started: false, started: false,
@ -2105,7 +2155,7 @@ impl sum_tree::Item for Fragment {
impl sum_tree::Summary for FragmentSummary { impl sum_tree::Summary for FragmentSummary {
type Context = (); type Context = ();
fn add_summary(&mut self, other: &Self, _: Option<&Self::Context>) { fn add_summary(&mut self, other: &Self, _: &()) {
self.text_summary += &other.text_summary; self.text_summary += &other.text_summary;
debug_assert!(self.max_fragment_id <= other.max_fragment_id); debug_assert!(self.max_fragment_id <= other.max_fragment_id);
self.max_fragment_id = other.max_fragment_id.clone(); self.max_fragment_id = other.max_fragment_id.clone();
@ -2171,7 +2221,7 @@ impl sum_tree::Item for InsertionSplit {
impl sum_tree::Summary for InsertionSplitSummary { impl sum_tree::Summary for InsertionSplitSummary {
type Context = (); type Context = ();
fn add_summary(&mut self, other: &Self, _: Option<&Self::Context>) { fn add_summary(&mut self, other: &Self, _: &()) {
self.extent += other.extent; self.extent += other.extent;
} }
} }
@ -2228,7 +2278,7 @@ pub trait ToOffset {
impl ToOffset for Point { impl ToOffset for Point {
fn to_offset(&self, buffer: &Buffer) -> Result<usize> { fn to_offset(&self, buffer: &Buffer) -> Result<usize> {
let mut fragments_cursor = buffer.fragments.cursor::<Point, TextSummary>(); let mut fragments_cursor = buffer.fragments.cursor::<Point, TextSummary>();
fragments_cursor.seek(self, SeekBias::Left); fragments_cursor.seek(self, SeekBias::Left, &());
fragments_cursor fragments_cursor
.item() .item()
.ok_or_else(|| anyhow!("point is out of range")) .ok_or_else(|| anyhow!("point is out of range"))
@ -2272,7 +2322,7 @@ impl ToPoint for Anchor {
impl ToPoint for usize { impl ToPoint for usize {
fn to_point(&self, buffer: &Buffer) -> Result<Point> { fn to_point(&self, buffer: &Buffer) -> Result<Point> {
let mut fragments_cursor = buffer.fragments.cursor::<usize, TextSummary>(); let mut fragments_cursor = buffer.fragments.cursor::<usize, TextSummary>();
fragments_cursor.seek(&self, SeekBias::Left); fragments_cursor.seek(&self, SeekBias::Left, &());
fragments_cursor fragments_cursor
.item() .item()
.ok_or_else(|| anyhow!("offset is out of range")) .ok_or_else(|| anyhow!("offset is out of range"))

View File

@ -61,7 +61,7 @@ pub struct TextSummary {
impl sum_tree::Summary for TextSummary { impl sum_tree::Summary for TextSummary {
type Context = (); type Context = ();
fn add_summary(&mut self, other: &Self, _: Option<&Self::Context>) { fn add_summary(&mut self, other: &Self, _: &()) {
*self += other; *self += other;
} }
} }
@ -165,7 +165,7 @@ impl From<Arc<str>> for Text {
} }
let mut tree = SumTree::new(); let mut tree = SumTree::new();
tree.extend(runs); tree.extend(runs, &());
Text { Text {
text, text,
runs: tree, runs: tree,
@ -239,13 +239,14 @@ impl Text {
pub fn line_len(&self, row: u32) -> u32 { pub fn line_len(&self, row: u32) -> u32 {
let mut cursor = self.runs.cursor::<usize, Point>(); let mut cursor = self.runs.cursor::<usize, Point>();
cursor.seek(&self.range.start, SeekBias::Right); cursor.seek(&self.range.start, SeekBias::Right, &());
let absolute_row = cursor.start().row + row; let absolute_row = cursor.start().row + row;
let mut cursor = self.runs.cursor::<Point, usize>(); let mut cursor = self.runs.cursor::<Point, usize>();
cursor.seek(&Point::new(absolute_row, 0), SeekBias::Right); cursor.seek(&Point::new(absolute_row, 0), SeekBias::Right, &());
let prefix_len = self.range.start.saturating_sub(*cursor.start()); let prefix_len = self.range.start.saturating_sub(*cursor.start());
let line_len = cursor.summary::<usize>(&Point::new(absolute_row + 1, 0), SeekBias::Left); let line_len =
cursor.summary::<usize>(&Point::new(absolute_row + 1, 0), SeekBias::Left, &());
let suffix_len = cursor.start().saturating_sub(self.range.end); let suffix_len = cursor.start().saturating_sub(self.range.end);
line_len line_len
@ -270,14 +271,15 @@ impl Text {
candidates.push(Point::new(0, self.line_len(0))); candidates.push(Point::new(0, self.line_len(0)));
if lines.row > 1 { if lines.row > 1 {
let mut cursor = self.runs.cursor::<usize, Point>(); let mut cursor = self.runs.cursor::<usize, Point>();
cursor.seek(&self.range.start, SeekBias::Right); cursor.seek(&self.range.start, SeekBias::Right, &());
let absolute_start_row = cursor.start().row; let absolute_start_row = cursor.start().row;
let mut cursor = self.runs.cursor::<Point, usize>(); let mut cursor = self.runs.cursor::<Point, usize>();
cursor.seek(&Point::new(absolute_start_row + 1, 0), SeekBias::Right); cursor.seek(&Point::new(absolute_start_row + 1, 0), SeekBias::Right, &());
let summary = cursor.summary::<TextSummary>( let summary = cursor.summary::<TextSummary>(
&Point::new(absolute_start_row + lines.row, 0), &Point::new(absolute_start_row + lines.row, 0),
SeekBias::Left, SeekBias::Left,
&(),
); );
candidates.push(Point::new(1, 0) + &summary.rightmost_point); candidates.push(Point::new(1, 0) + &summary.rightmost_point);
@ -295,7 +297,7 @@ impl Text {
pub fn offset_for_point(&self, point: Point) -> usize { pub fn offset_for_point(&self, point: Point) -> usize {
let mut cursor = self.runs.cursor::<Point, TextSummary>(); let mut cursor = self.runs.cursor::<Point, TextSummary>();
let abs_point = self.abs_point_for_offset(self.range.start) + &point; let abs_point = self.abs_point_for_offset(self.range.start) + &point;
cursor.seek(&abs_point, SeekBias::Right); cursor.seek(&abs_point, SeekBias::Right, &());
let overshoot = abs_point - &cursor.start().lines; let overshoot = abs_point - &cursor.start().lines;
let abs_offset = cursor.start().chars + overshoot.column as usize; let abs_offset = cursor.start().chars + overshoot.column as usize;
abs_offset - self.range.start abs_offset - self.range.start
@ -315,14 +317,14 @@ impl Text {
fn abs_point_for_offset(&self, offset: usize) -> Point { fn abs_point_for_offset(&self, offset: usize) -> Point {
let mut cursor = self.runs.cursor::<usize, TextSummary>(); let mut cursor = self.runs.cursor::<usize, TextSummary>();
cursor.seek(&offset, SeekBias::Right); cursor.seek(&offset, SeekBias::Right, &());
let overshoot = (offset - cursor.start().chars) as u32; let overshoot = (offset - cursor.start().chars) as u32;
cursor.start().lines + &Point::new(0, overshoot) cursor.start().lines + &Point::new(0, overshoot)
} }
fn abs_byte_offset_for_offset(&self, offset: usize) -> usize { fn abs_byte_offset_for_offset(&self, offset: usize) -> usize {
let mut cursor = self.runs.cursor::<usize, TextSummary>(); let mut cursor = self.runs.cursor::<usize, TextSummary>();
cursor.seek(&offset, SeekBias::Right); cursor.seek(&offset, SeekBias::Right, &());
let overshoot = offset - cursor.start().chars; let overshoot = offset - cursor.start().chars;
cursor.start().bytes + overshoot * cursor.item().map_or(0, |run| run.char_size()) as usize cursor.start().bytes + overshoot * cursor.item().map_or(0, |run| run.char_size()) as usize
} }

View File

@ -29,13 +29,16 @@ impl FoldMap {
Self { Self {
buffer: buffer_handle, buffer: buffer_handle,
folds: Default::default(), folds: Default::default(),
transforms: Mutex::new(SumTree::from_item(Transform { transforms: Mutex::new(SumTree::from_item(
summary: TransformSummary { Transform {
buffer: text_summary.clone(), summary: TransformSummary {
display: text_summary, buffer: text_summary.clone(),
display: text_summary,
},
display_text: None,
}, },
display_text: None, &(),
})), )),
last_sync: Mutex::new(buffer.version()), last_sync: Mutex::new(buffer.version()),
} }
} }
@ -106,16 +109,12 @@ impl FoldMap {
self.folds = { self.folds = {
let mut new_tree = SumTree::new(); let mut new_tree = SumTree::new();
let mut cursor = self.folds.cursor::<_, ()>(); let mut cursor = self.folds.cursor::<_, ()>();
new_tree.push_tree_with_ctx( new_tree.push_tree(
cursor.slice_with_ctx( cursor.slice(&FoldRange(fold.0.clone()), SeekBias::Right, buffer),
&FoldRange(fold.0.clone()), buffer,
SeekBias::Right,
Some(buffer),
),
Some(buffer),
); );
new_tree.push_with_ctx(fold, Some(buffer)); new_tree.push(fold, buffer);
new_tree.push_tree_with_ctx(cursor.suffix_with_ctx(Some(buffer)), Some(buffer)); new_tree.push_tree(cursor.suffix(buffer), buffer);
new_tree new_tree
}; };
} }
@ -162,13 +161,10 @@ impl FoldMap {
let mut cursor = self.folds.cursor::<_, ()>(); let mut cursor = self.folds.cursor::<_, ()>();
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_with_ctx( folds.push_tree(cursor.slice(&fold_ix, SeekBias::Right, buffer), buffer);
cursor.slice_with_ctx(&fold_ix, SeekBias::Right, Some(buffer)),
Some(buffer),
);
cursor.next(); cursor.next();
} }
folds.push_tree_with_ctx(cursor.suffix_with_ctx(Some(buffer)), Some(buffer)); folds.push_tree(cursor.suffix(buffer), buffer);
folds folds
}; };
@ -196,7 +192,7 @@ impl FoldMap {
pub fn is_line_folded(&self, display_row: u32, ctx: &AppContext) -> bool { pub fn is_line_folded(&self, display_row: u32, ctx: &AppContext) -> bool {
let transforms = self.sync(ctx); let transforms = self.sync(ctx);
let mut cursor = transforms.cursor::<DisplayPoint, DisplayPoint>(); let mut cursor = transforms.cursor::<DisplayPoint, DisplayPoint>();
cursor.seek(&DisplayPoint::new(display_row, 0), SeekBias::Right); cursor.seek(&DisplayPoint::new(display_row, 0), SeekBias::Right, &());
while let Some(transform) = cursor.item() { while let Some(transform) = cursor.item() {
if transform.display_text.is_some() { if transform.display_text.is_some() {
return true; return true;
@ -213,7 +209,7 @@ impl FoldMap {
pub fn to_buffer_offset(&self, point: DisplayPoint, ctx: &AppContext) -> Result<usize> { pub fn to_buffer_offset(&self, point: DisplayPoint, ctx: &AppContext) -> Result<usize> {
let transforms = self.sync(ctx); let transforms = self.sync(ctx);
let mut cursor = transforms.cursor::<DisplayPoint, TransformSummary>(); let mut cursor = transforms.cursor::<DisplayPoint, TransformSummary>();
cursor.seek(&point, SeekBias::Right); cursor.seek(&point, SeekBias::Right, &());
let overshoot = point.0 - cursor.start().display.lines; let overshoot = point.0 - cursor.start().display.lines;
(cursor.start().buffer.lines + overshoot).to_offset(self.buffer.read(ctx)) (cursor.start().buffer.lines + overshoot).to_offset(self.buffer.read(ctx))
} }
@ -229,7 +225,7 @@ impl FoldMap {
pub fn to_buffer_point(&self, display_point: DisplayPoint, ctx: &AppContext) -> Point { pub fn to_buffer_point(&self, display_point: DisplayPoint, ctx: &AppContext) -> Point {
let transforms = self.sync(ctx); let transforms = self.sync(ctx);
let mut cursor = transforms.cursor::<DisplayPoint, TransformSummary>(); let mut cursor = transforms.cursor::<DisplayPoint, TransformSummary>();
cursor.seek(&display_point, SeekBias::Right); cursor.seek(&display_point, SeekBias::Right, &());
let overshoot = display_point.0 - cursor.start().display.lines; let overshoot = display_point.0 - cursor.start().display.lines;
cursor.start().buffer.lines + overshoot cursor.start().buffer.lines + overshoot
} }
@ -237,7 +233,7 @@ impl FoldMap {
pub fn to_display_point(&self, point: Point, ctx: &AppContext) -> DisplayPoint { pub fn to_display_point(&self, point: Point, ctx: &AppContext) -> DisplayPoint {
let transforms = self.sync(ctx); let transforms = self.sync(ctx);
let mut cursor = transforms.cursor::<Point, TransformSummary>(); let mut cursor = transforms.cursor::<Point, TransformSummary>();
cursor.seek(&point, SeekBias::Right); cursor.seek(&point, SeekBias::Right, &());
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,
@ -262,14 +258,17 @@ impl FoldMap {
let mut new_transforms = SumTree::new(); let mut new_transforms = SumTree::new();
let mut transforms = self.transforms.lock(); let mut transforms = self.transforms.lock();
let mut cursor = transforms.cursor::<usize, usize>(); let mut cursor = transforms.cursor::<usize, usize>();
cursor.seek(&0, SeekBias::Right); cursor.seek(&0, SeekBias::Right, &());
while let Some(mut edit) = edits.next() { while let Some(mut edit) = edits.next() {
new_transforms.push_tree(cursor.slice(&edit.old_range.start, SeekBias::Left)); new_transforms.push_tree(
cursor.slice(&edit.old_range.start, SeekBias::Left, &()),
&(),
);
edit.new_range.start -= edit.old_range.start - cursor.start(); edit.new_range.start -= edit.old_range.start - cursor.start();
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();
@ -286,7 +285,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 {
@ -299,11 +298,7 @@ impl FoldMap {
let anchor = buffer.anchor_before(edit.new_range.start).unwrap(); let anchor = buffer.anchor_before(edit.new_range.start).unwrap();
let mut folds_cursor = self.folds.cursor::<_, ()>(); let mut folds_cursor = self.folds.cursor::<_, ()>();
folds_cursor.seek_with_ctx( folds_cursor.seek(&FoldRange(anchor..Anchor::End), SeekBias::Left, buffer);
&FoldRange(anchor..Anchor::End),
SeekBias::Left,
Some(buffer),
);
let mut folds = folds_cursor let mut folds = folds_cursor
.map(|f| f.0.start.to_offset(buffer).unwrap()..f.0.end.to_offset(buffer).unwrap()) .map(|f| f.0.start.to_offset(buffer).unwrap()..f.0.end.to_offset(buffer).unwrap())
.peekable(); .peekable();
@ -329,29 +324,35 @@ impl FoldMap {
if fold.start > sum.buffer.chars { if fold.start > sum.buffer.chars {
let text_summary = buffer.text_summary_for_range(sum.buffer.chars..fold.start); let text_summary = buffer.text_summary_for_range(sum.buffer.chars..fold.start);
new_transforms.push(Transform { new_transforms.push(
summary: TransformSummary { Transform {
display: text_summary.clone(), summary: TransformSummary {
buffer: text_summary, display: text_summary.clone(),
buffer: text_summary,
},
display_text: None,
}, },
display_text: None, &(),
}); );
} }
if fold.end > fold.start { if fold.end > fold.start {
new_transforms.push(Transform { new_transforms.push(
summary: TransformSummary { Transform {
display: TextSummary { summary: TransformSummary {
chars: 1, display: TextSummary {
bytes: ''.len_utf8(), chars: 1,
lines: Point::new(0, 1), bytes: ''.len_utf8(),
first_line_len: 1, lines: Point::new(0, 1),
rightmost_point: Point::new(0, 1), first_line_len: 1,
rightmost_point: Point::new(0, 1),
},
buffer: buffer.text_summary_for_range(fold.start..fold.end),
}, },
buffer: buffer.text_summary_for_range(fold.start..fold.end), display_text: Some('…'),
}, },
display_text: Some('…'), &(),
}); );
} }
} }
@ -359,26 +360,32 @@ impl FoldMap {
if sum.buffer.chars < edit.new_range.end { if sum.buffer.chars < edit.new_range.end {
let text_summary = let text_summary =
buffer.text_summary_for_range(sum.buffer.chars..edit.new_range.end); buffer.text_summary_for_range(sum.buffer.chars..edit.new_range.end);
new_transforms.push(Transform { new_transforms.push(
Transform {
summary: TransformSummary {
display: text_summary.clone(),
buffer: text_summary,
},
display_text: None,
},
&(),
);
}
}
new_transforms.push_tree(cursor.suffix(&()), &());
if new_transforms.is_empty() {
let text_summary = buffer.text_summary();
new_transforms.push(
Transform {
summary: TransformSummary { summary: TransformSummary {
display: text_summary.clone(), display: text_summary.clone(),
buffer: text_summary, buffer: text_summary,
}, },
display_text: None, display_text: None,
});
}
}
new_transforms.push_tree(cursor.suffix());
if new_transforms.is_empty() {
let text_summary = buffer.text_summary();
new_transforms.push(Transform {
summary: TransformSummary {
display: text_summary.clone(),
buffer: text_summary,
}, },
display_text: None, &(),
}); );
} }
drop(cursor); drop(cursor);
@ -399,7 +406,7 @@ impl FoldMapSnapshot {
let display_point = Point::new(start_row, 0); let display_point = Point::new(start_row, 0);
let mut cursor = self.transforms.cursor(); let mut cursor = self.transforms.cursor();
cursor.seek(&DisplayPoint(display_point), SeekBias::Left); cursor.seek(&DisplayPoint(display_point), SeekBias::Left, &());
Ok(BufferRows { Ok(BufferRows {
display_point, display_point,
@ -410,7 +417,7 @@ impl FoldMapSnapshot {
pub fn chars_at<'a>(&'a self, point: DisplayPoint, ctx: &'a AppContext) -> Result<Chars<'a>> { pub fn chars_at<'a>(&'a self, point: DisplayPoint, ctx: &'a AppContext) -> Result<Chars<'a>> {
let offset = self.to_display_offset(point, ctx)?; let offset = self.to_display_offset(point, ctx)?;
let mut cursor = self.transforms.cursor(); let mut cursor = self.transforms.cursor();
cursor.seek(&offset, SeekBias::Right); cursor.seek(&offset, SeekBias::Right, &());
Ok(Chars { Ok(Chars {
cursor, cursor,
offset: offset.0, offset: offset.0,
@ -421,7 +428,7 @@ impl FoldMapSnapshot {
fn to_display_offset(&self, point: DisplayPoint, ctx: &AppContext) -> Result<DisplayOffset> { fn to_display_offset(&self, point: DisplayPoint, ctx: &AppContext) -> Result<DisplayOffset> {
let mut cursor = self.transforms.cursor::<DisplayPoint, TransformSummary>(); let mut cursor = self.transforms.cursor::<DisplayPoint, TransformSummary>();
cursor.seek(&point, SeekBias::Right); cursor.seek(&point, SeekBias::Right, &());
let overshoot = point.0 - cursor.start().display.lines; let overshoot = point.0 - cursor.start().display.lines;
let mut offset = cursor.start().display.chars; let mut offset = cursor.start().display.chars;
if !overshoot.is_zero() { if !overshoot.is_zero() {
@ -460,7 +467,7 @@ impl sum_tree::Item for Transform {
impl sum_tree::Summary for TransformSummary { impl sum_tree::Summary for TransformSummary {
type Context = (); type Context = ();
fn add_summary(&mut self, other: &Self, _: Option<&Self::Context>) { fn add_summary(&mut self, other: &Self, _: &()) {
self.buffer += &other.buffer; self.buffer += &other.buffer;
self.display += &other.display; self.display += &other.display;
} }
@ -468,7 +475,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, None); sum_tree::Summary::add_summary(self, summary, &());
} }
} }
@ -513,8 +520,7 @@ impl Default for FoldSummary {
impl sum_tree::Summary for FoldSummary { impl sum_tree::Summary for FoldSummary {
type Context = Buffer; type Context = Buffer;
fn add_summary(&mut self, other: &Self, buffer: Option<&Self::Context>) { fn add_summary(&mut self, other: &Self, buffer: &Buffer) {
let buffer = buffer.unwrap();
if other.min_start.cmp(&self.min_start, buffer).unwrap() == Ordering::Less { if other.min_start.cmp(&self.min_start, buffer).unwrap() == Ordering::Less {
self.min_start = other.min_start.clone(); self.min_start = other.min_start.clone();
} }
@ -553,8 +559,8 @@ impl<'a> sum_tree::Dimension<'a, FoldSummary> for FoldRange {
} }
impl<'a> sum_tree::SeekDimension<'a, FoldSummary> for FoldRange { impl<'a> sum_tree::SeekDimension<'a, FoldSummary> for FoldRange {
fn cmp(&self, other: &Self, buffer: Option<&Buffer>) -> Ordering { fn cmp(&self, other: &Self, buffer: &Buffer) -> Ordering {
self.0.cmp(&other.0, buffer.unwrap()).unwrap() self.0.cmp(&other.0, buffer).unwrap()
} }
} }

View File

@ -32,7 +32,8 @@ impl<T: Operation> OperationQueue<T> {
pub fn insert(&mut self, mut ops: Vec<T>) { pub fn insert(&mut self, mut ops: Vec<T>) {
ops.sort_by_key(|op| op.timestamp()); ops.sort_by_key(|op| op.timestamp());
ops.dedup_by_key(|op| op.timestamp()); ops.dedup_by_key(|op| op.timestamp());
self.0.edit(ops.into_iter().map(Edit::Insert).collect()); self.0
.edit(ops.into_iter().map(Edit::Insert).collect(), &());
} }
pub fn drain(&mut self) -> Self { pub fn drain(&mut self) -> Self {
@ -68,7 +69,7 @@ impl<T: Operation> KeyedItem for T {
impl Summary for OperationSummary { impl Summary for OperationSummary {
type Context = (); type Context = ();
fn add_summary(&mut self, other: &Self, _: Option<&Self::Context>) { fn add_summary(&mut self, other: &Self, _: &()) {
assert!(self.key < other.key); assert!(self.key < other.key);
self.key = other.key; self.key = other.key;
self.len += other.len; self.len += other.len;

View File

@ -208,7 +208,7 @@ where
{ {
let mut descend = false; let mut descend = false;
if !self.did_seek { if self.stack.is_empty() && !self.at_end {
self.stack.push(StackEntry { self.stack.push(StackEntry {
tree: self.tree, tree: self.tree,
index: 0, index: 0,
@ -342,42 +342,30 @@ where
S: SeekDimension<'a, T::Summary>, S: SeekDimension<'a, T::Summary>,
U: Dimension<'a, T::Summary>, U: Dimension<'a, T::Summary>,
{ {
pub fn seek(&mut self, pos: &S, bias: SeekBias) -> bool { pub fn seek(
self.seek_with_ctx(pos, bias, None)
}
pub fn seek_with_ctx(
&mut self, &mut self,
pos: &S, pos: &S,
bias: SeekBias, bias: SeekBias,
ctx: Option<&'a <T::Summary as Summary>::Context>, ctx: &<T::Summary as Summary>::Context,
) -> bool { ) -> bool {
self.reset(); self.reset();
self.seek_internal::<()>(pos, bias, &mut SeekAggregate::None, ctx) self.seek_internal::<()>(pos, bias, &mut SeekAggregate::None, ctx)
} }
pub fn seek_forward(&mut self, pos: &S, bias: SeekBias) -> bool { pub fn seek_forward(
self.seek_forward_with_ctx(pos, bias, None)
}
pub fn seek_forward_with_ctx(
&mut self, &mut self,
pos: &S, pos: &S,
bias: SeekBias, bias: SeekBias,
ctx: Option<&'a <T::Summary as Summary>::Context>, ctx: &<T::Summary as Summary>::Context,
) -> bool { ) -> bool {
self.seek_internal::<()>(pos, bias, &mut SeekAggregate::None, ctx) self.seek_internal::<()>(pos, bias, &mut SeekAggregate::None, ctx)
} }
pub fn slice(&mut self, end: &S, bias: SeekBias) -> SumTree<T> { pub fn slice(
self.slice_with_ctx(end, bias, None)
}
pub fn slice_with_ctx(
&mut self, &mut self,
end: &S, end: &S,
bias: SeekBias, bias: SeekBias,
ctx: Option<&'a <T::Summary as Summary>::Context>, ctx: &<T::Summary as Summary>::Context,
) -> SumTree<T> { ) -> SumTree<T> {
let mut slice = SeekAggregate::Slice(SumTree::new()); let mut slice = SeekAggregate::Slice(SumTree::new());
self.seek_internal::<()>(end, bias, &mut slice, ctx); self.seek_internal::<()>(end, bias, &mut slice, ctx);
@ -388,14 +376,7 @@ where
} }
} }
pub fn suffix(&mut self) -> SumTree<T> { pub fn suffix(&mut self, ctx: &<T::Summary as Summary>::Context) -> SumTree<T> {
self.suffix_with_ctx(None)
}
pub fn suffix_with_ctx(
&mut self,
ctx: Option<&'a <T::Summary as Summary>::Context>,
) -> SumTree<T> {
let extent = self.tree.extent::<S>(); let extent = self.tree.extent::<S>();
let mut slice = SeekAggregate::Slice(SumTree::new()); let mut slice = SeekAggregate::Slice(SumTree::new());
self.seek_internal::<()>(&extent, SeekBias::Right, &mut slice, ctx); self.seek_internal::<()>(&extent, SeekBias::Right, &mut slice, ctx);
@ -406,18 +387,11 @@ where
} }
} }
pub fn summary<D>(&mut self, end: &S, bias: SeekBias) -> D pub fn summary<D>(
where
D: Dimension<'a, T::Summary>,
{
self.summary_with_ctx(end, bias, None)
}
pub fn summary_with_ctx<D>(
&mut self, &mut self,
end: &S, end: &S,
bias: SeekBias, bias: SeekBias,
ctx: Option<&'a <T::Summary as Summary>::Context>, ctx: &<T::Summary as Summary>::Context,
) -> D ) -> D
where where
D: Dimension<'a, T::Summary>, D: Dimension<'a, T::Summary>,
@ -436,7 +410,7 @@ where
target: &S, target: &S,
bias: SeekBias, bias: SeekBias,
aggregate: &mut SeekAggregate<T, D>, aggregate: &mut SeekAggregate<T, D>,
ctx: Option<&'a <T::Summary as Summary>::Context>, ctx: &<T::Summary as Summary>::Context,
) -> bool ) -> bool
where where
D: Dimension<'a, T::Summary>, D: Dimension<'a, T::Summary>,
@ -470,7 +444,7 @@ where
match aggregate { match aggregate {
SeekAggregate::None => {} SeekAggregate::None => {}
SeekAggregate::Slice(slice) => { SeekAggregate::Slice(slice) => {
slice.push_tree_with_ctx(child_tree.clone(), ctx); slice.push_tree(child_tree.clone(), ctx);
} }
SeekAggregate::Summary(summary) => { SeekAggregate::Summary(summary) => {
summary.add_summary(child_summary); summary.add_summary(child_summary);
@ -526,7 +500,7 @@ where
entry.index += 1; entry.index += 1;
} else { } else {
if let SeekAggregate::Slice(slice) = aggregate { if let SeekAggregate::Slice(slice) = aggregate {
slice.push_tree_with_ctx( slice.push_tree(
SumTree(Arc::new(Node::Leaf { SumTree(Arc::new(Node::Leaf {
summary: slice_items_summary.unwrap(), summary: slice_items_summary.unwrap(),
items: slice_items, items: slice_items,
@ -541,7 +515,7 @@ where
if let SeekAggregate::Slice(slice) = aggregate { if let SeekAggregate::Slice(slice) = aggregate {
if !slice_items.is_empty() { if !slice_items.is_empty() {
slice.push_tree_with_ctx( slice.push_tree(
SumTree(Arc::new(Node::Leaf { SumTree(Arc::new(Node::Leaf {
summary: slice_items_summary.unwrap(), summary: slice_items_summary.unwrap(),
items: slice_items, items: slice_items,
@ -586,7 +560,7 @@ where
match aggregate { match aggregate {
SeekAggregate::None => {} SeekAggregate::None => {}
SeekAggregate::Slice(slice) => { SeekAggregate::Slice(slice) => {
slice.push_tree_with_ctx(child_trees[index].clone(), ctx); slice.push_tree(child_trees[index].clone(), ctx);
} }
SeekAggregate::Summary(summary) => { SeekAggregate::Summary(summary) => {
summary.add_summary(child_summary); summary.add_summary(child_summary);
@ -656,7 +630,7 @@ where
if let SeekAggregate::Slice(slice) = aggregate { if let SeekAggregate::Slice(slice) = aggregate {
if !slice_items.is_empty() { if !slice_items.is_empty() {
slice.push_tree_with_ctx( slice.push_tree(
SumTree(Arc::new(Node::Leaf { SumTree(Arc::new(Node::Leaf {
summary: slice_items_summary.unwrap(), summary: slice_items_summary.unwrap(),
items: slice_items, items: slice_items,

View File

@ -25,7 +25,7 @@ pub trait KeyedItem: Item {
pub trait Summary: Default + Clone + fmt::Debug { pub trait Summary: Default + Clone + fmt::Debug {
type Context; type Context;
fn add_summary(&mut self, summary: &Self, ctx: Option<&Self::Context>); fn add_summary(&mut self, summary: &Self, ctx: &Self::Context);
} }
pub trait Dimension<'a, S: Summary>: Clone + fmt::Debug + Default { pub trait Dimension<'a, S: Summary>: Clone + fmt::Debug + Default {
@ -37,11 +37,11 @@ impl<'a, T: Summary> Dimension<'a, T> for () {
} }
pub trait SeekDimension<'a, T: Summary>: Dimension<'a, T> { pub trait SeekDimension<'a, T: Summary>: Dimension<'a, T> {
fn cmp(&self, other: &Self, ctx: Option<&T::Context>) -> Ordering; fn cmp(&self, other: &Self, ctx: &T::Context) -> Ordering;
} }
impl<'a, S: Summary, T: Dimension<'a, S> + Ord> SeekDimension<'a, S> for T { impl<'a, S: Summary, T: Dimension<'a, S> + Ord> SeekDimension<'a, S> for T {
fn cmp(&self, other: &Self, _ctx: Option<&S::Context>) -> Ordering { fn cmp(&self, other: &Self, _ctx: &S::Context) -> Ordering {
Ord::cmp(self, other) Ord::cmp(self, other)
} }
} }
@ -64,9 +64,9 @@ impl<T: Item> SumTree<T> {
})) }))
} }
pub fn from_item(item: T) -> Self { pub fn from_item(item: T, ctx: &<T::Summary as Summary>::Context) -> Self {
let mut tree = Self::new(); let mut tree = Self::new();
tree.push(item); tree.push(item, ctx);
tree tree
} }
@ -125,14 +125,7 @@ impl<T: Item> SumTree<T> {
} }
} }
pub fn extend<I>(&mut self, iter: I) pub fn extend<I>(&mut self, iter: I, ctx: &<T::Summary as Summary>::Context)
where
I: IntoIterator<Item = T>,
{
self.extend_with_ctx(iter, None)
}
pub fn extend_with_ctx<I>(&mut self, iter: I, ctx: Option<&<T::Summary as Summary>::Context>)
where where
I: IntoIterator<Item = T>, I: IntoIterator<Item = T>,
{ {
@ -140,7 +133,7 @@ impl<T: Item> SumTree<T> {
for item in iter { for item in iter {
if leaf.is_some() && leaf.as_ref().unwrap().items().len() == 2 * TREE_BASE { if leaf.is_some() && leaf.as_ref().unwrap().items().len() == 2 * TREE_BASE {
self.push_tree(SumTree(Arc::new(leaf.take().unwrap()))); self.push_tree(SumTree(Arc::new(leaf.take().unwrap())), ctx);
} }
if leaf.is_none() { if leaf.is_none() {
@ -167,17 +160,13 @@ impl<T: Item> SumTree<T> {
} }
if leaf.is_some() { if leaf.is_some() {
self.push_tree(SumTree(Arc::new(leaf.take().unwrap()))); self.push_tree(SumTree(Arc::new(leaf.take().unwrap())), ctx);
} }
} }
pub fn push(&mut self, item: T) { pub fn push(&mut self, item: T, ctx: &<T::Summary as Summary>::Context) {
self.push_with_ctx(item, None);
}
pub fn push_with_ctx(&mut self, item: T, ctx: Option<&<T::Summary as Summary>::Context>) {
let summary = item.summary(); let summary = item.summary();
self.push_tree_with_ctx( self.push_tree(
SumTree::from_child_trees( SumTree::from_child_trees(
vec![SumTree(Arc::new(Node::Leaf { vec![SumTree(Arc::new(Node::Leaf {
summary: summary.clone(), summary: summary.clone(),
@ -190,20 +179,12 @@ impl<T: Item> SumTree<T> {
) )
} }
pub fn push_tree(&mut self, other: Self) { pub fn push_tree(&mut self, other: Self, ctx: &<T::Summary as Summary>::Context) {
self.push_tree_with_ctx(other, None);
}
pub fn push_tree_with_ctx(
&mut self,
other: Self,
ctx: Option<&<T::Summary as Summary>::Context>,
) {
let other_node = other.0.clone(); let other_node = other.0.clone();
if !other_node.is_leaf() || other_node.items().len() > 0 { if !other_node.is_leaf() || other_node.items().len() > 0 {
if self.0.height() < other_node.height() { if self.0.height() < other_node.height() {
for tree in other_node.child_trees() { for tree in other_node.child_trees() {
self.push_tree_with_ctx(tree.clone(), ctx); self.push_tree(tree.clone(), ctx);
} }
} else if let Some(split_tree) = self.push_tree_recursive(other, ctx) { } else if let Some(split_tree) = self.push_tree_recursive(other, ctx) {
*self = Self::from_child_trees(vec![self.clone(), split_tree], ctx); *self = Self::from_child_trees(vec![self.clone(), split_tree], ctx);
@ -214,7 +195,7 @@ impl<T: Item> SumTree<T> {
fn push_tree_recursive( fn push_tree_recursive(
&mut self, &mut self,
other: SumTree<T>, other: SumTree<T>,
ctx: Option<&<T::Summary as Summary>::Context>, ctx: &<T::Summary as Summary>::Context,
) -> Option<SumTree<T>> { ) -> Option<SumTree<T>> {
match Arc::make_mut(&mut self.0) { match Arc::make_mut(&mut self.0) {
Node::Internal { Node::Internal {
@ -333,7 +314,7 @@ impl<T: Item> SumTree<T> {
fn from_child_trees( fn from_child_trees(
child_trees: Vec<SumTree<T>>, child_trees: Vec<SumTree<T>>,
ctx: Option<&<T::Summary as Summary>::Context>, ctx: &<T::Summary as Summary>::Context,
) -> Self { ) -> Self {
let height = child_trees[0].0.height() + 1; let height = child_trees[0].0.height() + 1;
let mut child_summaries = ArrayVec::new(); let mut child_summaries = ArrayVec::new();
@ -370,17 +351,21 @@ impl<T: Item> SumTree<T> {
impl<T: KeyedItem> SumTree<T> { impl<T: KeyedItem> SumTree<T> {
#[allow(unused)] #[allow(unused)]
pub fn insert(&mut self, item: T) { pub fn insert(&mut self, item: T, ctx: &<T::Summary as Summary>::Context) {
*self = { *self = {
let mut cursor = self.cursor::<T::Key, ()>(); let mut cursor = self.cursor::<T::Key, ()>();
let mut new_tree = cursor.slice(&item.key(), SeekBias::Left); let mut new_tree = cursor.slice(&item.key(), SeekBias::Left, ctx);
new_tree.push(item); new_tree.push(item, ctx);
new_tree.push_tree(cursor.suffix()); new_tree.push_tree(cursor.suffix(ctx), ctx);
new_tree new_tree
}; };
} }
pub fn edit(&mut self, mut edits: Vec<Edit<T>>) -> Vec<T> { pub fn edit(
&mut self,
mut edits: Vec<Edit<T>>,
ctx: &<T::Summary as Summary>::Context,
) -> Vec<T> {
if edits.is_empty() { if edits.is_empty() {
return Vec::new(); return Vec::new();
} }
@ -393,7 +378,7 @@ impl<T: KeyedItem> SumTree<T> {
let mut new_tree = SumTree::new(); let mut new_tree = SumTree::new();
let mut buffered_items = Vec::new(); let mut buffered_items = Vec::new();
cursor.seek(&T::Key::default(), SeekBias::Left); cursor.seek(&T::Key::default(), SeekBias::Left, ctx);
for edit in edits { for edit in edits {
let new_key = edit.key(); let new_key = edit.key();
let mut old_item = cursor.item(); let mut old_item = cursor.item();
@ -402,9 +387,9 @@ impl<T: KeyedItem> SumTree<T> {
.as_ref() .as_ref()
.map_or(false, |old_item| old_item.key() < new_key) .map_or(false, |old_item| old_item.key() < new_key)
{ {
new_tree.extend(buffered_items.drain(..)); new_tree.extend(buffered_items.drain(..), ctx);
let slice = cursor.slice(&new_key, SeekBias::Left); let slice = cursor.slice(&new_key, SeekBias::Left, ctx);
new_tree.push_tree(slice); new_tree.push_tree(slice, ctx);
old_item = cursor.item(); old_item = cursor.item();
} }
@ -423,17 +408,17 @@ impl<T: KeyedItem> SumTree<T> {
} }
} }
new_tree.extend(buffered_items); new_tree.extend(buffered_items, ctx);
new_tree.push_tree(cursor.suffix()); new_tree.push_tree(cursor.suffix(ctx), ctx);
new_tree new_tree
}; };
removed removed
} }
pub fn get(&self, key: &T::Key) -> Option<&T> { pub fn get(&self, key: &T::Key, ctx: &<T::Summary as Summary>::Context) -> Option<&T> {
let mut cursor = self.cursor::<T::Key, ()>(); let mut cursor = self.cursor::<T::Key, ()>();
if cursor.seek(key, SeekBias::Left) { if cursor.seek(key, SeekBias::Left, ctx) {
cursor.item() cursor.item()
} else { } else {
None None
@ -530,7 +515,7 @@ impl<T: KeyedItem> Edit<T> {
} }
} }
fn sum<'a, T, I>(iter: I, ctx: Option<&T::Context>) -> T fn sum<'a, T, I>(iter: I, ctx: &T::Context) -> T
where where
T: 'a + Summary, T: 'a + Summary,
I: Iterator<Item = &'a T>, I: Iterator<Item = &'a T>,
@ -551,12 +536,12 @@ mod tests {
#[test] #[test]
fn test_extend_and_push_tree() { fn test_extend_and_push_tree() {
let mut tree1 = SumTree::new(); let mut tree1 = SumTree::new();
tree1.extend(0..20); tree1.extend(0..20, &());
let mut tree2 = SumTree::new(); let mut tree2 = SumTree::new();
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>>());
} }
@ -570,7 +555,7 @@ mod tests {
let mut tree = SumTree::<u8>::new(); let mut tree = SumTree::<u8>::new();
let count = rng.gen_range(0..10); let count = rng.gen_range(0..10);
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);
@ -587,10 +572,10 @@ mod tests {
tree = { tree = {
let mut cursor = tree.cursor::<Count, ()>(); let mut cursor = tree.cursor::<Count, ()>();
let mut new_tree = cursor.slice(&Count(splice_start), SeekBias::Right); let mut new_tree = cursor.slice(&Count(splice_start), SeekBias::Right, &());
new_tree.extend(new_items); new_tree.extend(new_items, &());
cursor.seek(&Count(splice_end), SeekBias::Right); cursor.seek(&Count(splice_end), SeekBias::Right, &());
new_tree.push_tree(cursor.slice(&tree_end, SeekBias::Right)); new_tree.push_tree(cursor.slice(&tree_end, SeekBias::Right, &()), &());
new_tree new_tree
}; };
@ -613,7 +598,7 @@ mod tests {
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, &());
for i in 0..10 { for i in 0..10 {
assert_eq!(cursor.start().0, pos); assert_eq!(cursor.start().0, pos);
@ -661,11 +646,11 @@ mod tests {
}; };
let mut cursor = tree.cursor::<Count, ()>(); let mut cursor = tree.cursor::<Count, ()>();
cursor.seek(&Count(start), start_bias); cursor.seek(&Count(start), start_bias, &());
let slice = cursor.slice(&Count(end), end_bias); let slice = cursor.slice(&Count(end), end_bias, &());
cursor.seek(&Count(start), start_bias); cursor.seek(&Count(start), start_bias, &());
let summary = cursor.summary::<Sum>(&Count(end), end_bias); let summary = cursor.summary::<Sum>(&Count(end), end_bias, &());
assert_eq!(summary, slice.summary().sum); assert_eq!(summary, slice.summary().sum);
} }
@ -678,7 +663,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);
@ -687,10 +672,10 @@ mod tests {
// Single-element tree // Single-element tree
let mut tree = SumTree::<u8>::new(); let mut tree = SumTree::<u8>::new();
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));
@ -708,15 +693,15 @@ mod tests {
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));
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]
); );
@ -726,10 +711,13 @@ mod tests {
// Multiple-element tree // Multiple-element tree
let mut tree = SumTree::new(); let mut tree = SumTree::new();
tree.extend(vec![1, 2, 3, 4, 5, 6]); tree.extend(vec![1, 2, 3, 4, 5, 6], &());
let mut cursor = tree.cursor::<Count, Sum>(); let mut cursor = tree.cursor::<Count, Sum>();
assert_eq!(cursor.slice(&Count(2), SeekBias::Right).items(), [1, 2]); assert_eq!(
cursor.slice(&Count(2), SeekBias::Right, &()).items(),
[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));
@ -798,7 +786,7 @@ 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()
); );
@ -806,10 +794,10 @@ mod tests {
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.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]
); );
@ -818,37 +806,46 @@ mod tests {
assert_eq!(cursor.start(), &Sum(21)); assert_eq!(cursor.start(), &Sum(21));
// Seeking can bias left or right // Seeking can bias left or right
cursor.seek(&Count(1), SeekBias::Left); cursor.seek(&Count(1), SeekBias::Left, &());
assert_eq!(cursor.item(), Some(&1)); assert_eq!(cursor.item(), Some(&1));
cursor.seek(&Count(1), SeekBias::Right); cursor.seek(&Count(1), SeekBias::Right, &());
assert_eq!(cursor.item(), Some(&2)); assert_eq!(cursor.item(), Some(&2));
// 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!(cursor.slice(&Count(3), SeekBias::Right).items(), vec![2, 3]); assert_eq!(
assert_eq!(cursor.slice(&Count(6), SeekBias::Left).items(), vec![4, 5]); cursor.slice(&Count(3), SeekBias::Right, &()).items(),
assert_eq!(cursor.slice(&Count(6), SeekBias::Right).items(), vec![6]); vec![2, 3]
);
assert_eq!(
cursor.slice(&Count(6), SeekBias::Left, &()).items(),
vec![4, 5]
);
assert_eq!(
cursor.slice(&Count(6), SeekBias::Right, &()).items(),
vec![6]
);
} }
#[test] #[test]
fn test_edit() { fn test_edit() {
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));
assert_eq!(tree.get(&2), Some(&2)); assert_eq!(tree.get(&2, &()), Some(&2));
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));
assert_eq!(tree.get(&2), Some(&2)); assert_eq!(tree.get(&2, &()), Some(&2));
assert_eq!(tree.get(&4), Some(&4)); assert_eq!(tree.get(&4, &()), Some(&4));
} }
#[derive(Clone, Default, Debug)] #[derive(Clone, Default, Debug)]
@ -889,7 +886,7 @@ mod tests {
impl Summary for IntegersSummary { impl Summary for IntegersSummary {
type Context = (); type Context = ();
fn add_summary(&mut self, other: &Self, _: Option<&Self::Context>) { fn add_summary(&mut self, other: &Self, _: &()) {
self.count.0 += &other.count.0; self.count.0 += &other.count.0;
self.sum.0 += &other.sum.0; self.sum.0 += &other.sum.0;
self.contains_even |= other.contains_even; self.contains_even |= other.contains_even;

View File

@ -249,9 +249,10 @@ impl Snapshot {
#[cfg(test)] #[cfg(test)]
pub fn paths(&self) -> impl Iterator<Item = &Arc<Path>> { pub fn paths(&self) -> impl Iterator<Item = &Arc<Path>> {
let mut cursor = self.entries.cursor::<(), ()>(); self.entries
cursor.next(); .cursor::<(), ()>()
cursor.map(|entry| entry.path()) .skip(1)
.map(|entry| entry.path())
} }
pub fn visible_files(&self, start: usize) -> FileIter { pub fn visible_files(&self, start: usize) -> FileIter {
@ -274,7 +275,7 @@ impl Snapshot {
fn entry_for_path(&self, path: impl AsRef<Path>) -> Option<&Entry> { fn entry_for_path(&self, path: impl AsRef<Path>) -> Option<&Entry> {
let mut cursor = self.entries.cursor::<_, ()>(); let mut cursor = self.entries.cursor::<_, ()>();
if cursor.seek(&PathSearch::Exact(path.as_ref()), SeekBias::Left) { if cursor.seek(&PathSearch::Exact(path.as_ref()), SeekBias::Left, &()) {
cursor.item() cursor.item()
} else { } else {
None None
@ -296,7 +297,7 @@ impl Snapshot {
self.ignores self.ignores
.insert(ignore_dir_path.into(), (Arc::new(ignore), self.scan_id)); .insert(ignore_dir_path.into(), (Arc::new(ignore), self.scan_id));
} }
self.entries.insert(entry); self.entries.insert(entry, &());
} }
fn populate_dir( fn populate_dir(
@ -309,7 +310,7 @@ impl Snapshot {
let mut parent_entry = self let mut parent_entry = self
.entries .entries
.get(&PathKey(parent_path.clone())) .get(&PathKey(parent_path.clone()), &())
.unwrap() .unwrap()
.clone(); .clone();
if let Some(ignore) = ignore { if let Some(ignore) = ignore {
@ -325,15 +326,15 @@ impl Snapshot {
for entry in entries { for entry in entries {
edits.push(Edit::Insert(entry)); edits.push(Edit::Insert(entry));
} }
self.entries.edit(edits); self.entries.edit(edits, &());
} }
fn remove_path(&mut self, path: &Path) { fn remove_path(&mut self, path: &Path) {
let new_entries = { let new_entries = {
let mut cursor = self.entries.cursor::<_, ()>(); let mut cursor = self.entries.cursor::<_, ()>();
let mut new_entries = cursor.slice(&PathSearch::Exact(path), SeekBias::Left); let mut new_entries = cursor.slice(&PathSearch::Exact(path), SeekBias::Left, &());
cursor.seek_forward(&PathSearch::Successor(path), SeekBias::Left); cursor.seek_forward(&PathSearch::Successor(path), SeekBias::Left, &());
new_entries.push_tree(cursor.suffix()); new_entries.push_tree(cursor.suffix(&()), &());
new_entries new_entries
}; };
self.entries = new_entries; self.entries = new_entries;
@ -538,7 +539,7 @@ impl Default for EntrySummary {
impl sum_tree::Summary for EntrySummary { impl sum_tree::Summary for EntrySummary {
type Context = (); type Context = ();
fn add_summary(&mut self, rhs: &Self, _: Option<&Self::Context>) { fn add_summary(&mut self, rhs: &Self, _: &()) {
self.max_path = rhs.max_path.clone(); self.max_path = rhs.max_path.clone();
self.file_count += rhs.file_count; self.file_count += rhs.file_count;
self.visible_file_count += rhs.visible_file_count; self.visible_file_count += rhs.visible_file_count;
@ -1068,7 +1069,7 @@ impl BackgroundScanner {
edits.push(Edit::Insert(entry)); edits.push(Edit::Insert(entry));
} }
} }
self.snapshot.lock().entries.edit(edits); self.snapshot.lock().entries.edit(edits, &());
} }
fn fs_entry_for_path(&self, path: Arc<Path>, abs_path: &Path) -> Result<Option<Entry>> { fn fs_entry_for_path(&self, path: Arc<Path>, abs_path: &Path) -> Result<Option<Entry>> {
@ -1164,13 +1165,13 @@ pub enum FileIter<'a> {
impl<'a> FileIter<'a> { impl<'a> FileIter<'a> {
fn all(snapshot: &'a Snapshot, start: usize) -> Self { fn all(snapshot: &'a Snapshot, start: usize) -> Self {
let mut cursor = snapshot.entries.cursor(); let mut cursor = snapshot.entries.cursor();
cursor.seek(&FileCount(start), SeekBias::Right); cursor.seek(&FileCount(start), SeekBias::Right, &());
Self::All(cursor) Self::All(cursor)
} }
fn visible(snapshot: &'a Snapshot, start: usize) -> Self { fn visible(snapshot: &'a Snapshot, start: usize) -> Self {
let mut cursor = snapshot.entries.cursor(); let mut cursor = snapshot.entries.cursor();
cursor.seek(&VisibleFileCount(start), SeekBias::Right); cursor.seek(&VisibleFileCount(start), SeekBias::Right, &());
Self::Visible(cursor) Self::Visible(cursor)
} }
@ -1178,11 +1179,11 @@ impl<'a> FileIter<'a> {
match self { match self {
Self::All(cursor) => { Self::All(cursor) => {
let ix = *cursor.start(); let ix = *cursor.start();
cursor.seek_forward(&FileCount(ix.0 + 1), SeekBias::Right); cursor.seek_forward(&FileCount(ix.0 + 1), SeekBias::Right, &());
} }
Self::Visible(cursor) => { Self::Visible(cursor) => {
let ix = *cursor.start(); let ix = *cursor.start();
cursor.seek_forward(&VisibleFileCount(ix.0 + 1), SeekBias::Right); cursor.seek_forward(&VisibleFileCount(ix.0 + 1), SeekBias::Right, &());
} }
} }
} }
@ -1216,7 +1217,7 @@ struct ChildEntriesIter<'a> {
impl<'a> ChildEntriesIter<'a> { impl<'a> ChildEntriesIter<'a> {
fn new(parent_path: &'a Path, snapshot: &'a Snapshot) -> Self { fn new(parent_path: &'a Path, snapshot: &'a Snapshot) -> Self {
let mut cursor = snapshot.entries.cursor(); let mut cursor = snapshot.entries.cursor();
cursor.seek(&PathSearch::Exact(parent_path), SeekBias::Right); cursor.seek(&PathSearch::Exact(parent_path), SeekBias::Right, &());
Self { Self {
parent_path, parent_path,
cursor, cursor,
@ -1231,7 +1232,7 @@ impl<'a> Iterator for ChildEntriesIter<'a> {
if let Some(item) = self.cursor.item() { if let Some(item) = self.cursor.item() {
if item.path().starts_with(self.parent_path) { if item.path().starts_with(self.parent_path) {
self.cursor self.cursor
.seek_forward(&PathSearch::Successor(item.path()), SeekBias::Left); .seek_forward(&PathSearch::Successor(item.path()), SeekBias::Left, &());
Some(item) Some(item)
} else { } else {
None None