Replace Default trait bound with a zero function on Summary/Dimension (#17975)

This lets us provide a context when constructing the zero value. We need
it so we can require anchors to be associated with a buffer id, which
we're doing as part of simplifying the multibuffer API.

Release Notes:

- N/A

Co-authored-by: Nathan <nathan@zed.dev>
This commit is contained in:
Antonio Scandurra 2024-09-17 19:43:59 -06:00 committed by GitHub
parent 4d074fc737
commit 2e72fd210a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 706 additions and 349 deletions

View file

@ -100,7 +100,7 @@ impl Anchor {
false
} else {
let fragment_id = buffer.fragment_id_for_anchor(self);
let mut fragment_cursor = buffer.fragments.cursor::<(Option<&Locator>, usize)>();
let mut fragment_cursor = buffer.fragments.cursor::<(Option<&Locator>, usize)>(&None);
fragment_cursor.seek(&Some(fragment_id), Bias::Left, &None);
fragment_cursor
.item()

View file

@ -85,6 +85,10 @@ impl sum_tree::KeyedItem for Locator {
impl sum_tree::Summary for Locator {
type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &Self, _: &()) {
self.assign(summary);
}

View file

@ -34,7 +34,7 @@ impl<T: Operation> Default for OperationQueue<T> {
impl<T: Operation> OperationQueue<T> {
pub fn new() -> Self {
OperationQueue(SumTree::new())
OperationQueue(SumTree::default())
}
pub fn len(&self) -> usize {
@ -58,7 +58,7 @@ impl<T: Operation> OperationQueue<T> {
pub fn drain(&mut self) -> Self {
let clone = self.clone();
self.0 = SumTree::new();
self.0 = SumTree::default();
clone
}
@ -70,6 +70,10 @@ impl<T: Operation> OperationQueue<T> {
impl Summary for OperationSummary {
type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, other: &Self, _: &()) {
assert!(self.key < other.key);
self.key = other.key;
@ -90,6 +94,10 @@ impl<'a> Add<&'a Self> for OperationSummary {
}
impl<'a> Dimension<'a, OperationSummary> for OperationKey {
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &OperationSummary, _: &()) {
assert!(*self <= summary.key);
*self = summary.key;

View file

@ -492,6 +492,10 @@ struct FragmentTextSummary {
}
impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FragmentTextSummary {
fn zero(_: &Option<clock::Global>) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option<clock::Global>) {
self.visible += summary.text.visible;
self.deleted += summary.text.deleted;
@ -654,8 +658,8 @@ impl Buffer {
normalized: Rope,
) -> Buffer {
let history = History::new(normalized);
let mut fragments = SumTree::new();
let mut insertions = SumTree::new();
let mut fragments = SumTree::new(&None);
let mut insertions = SumTree::default();
let mut lamport_clock = clock::Lamport::new(replica_id);
let mut version = clock::Global::new();
@ -772,7 +776,7 @@ impl Buffer {
let mut new_ropes =
RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
let mut old_fragments = self.fragments.cursor::<FragmentTextSummary>();
let mut old_fragments = self.fragments.cursor::<FragmentTextSummary>(&None);
let mut new_fragments =
old_fragments.slice(&edits.peek().unwrap().0.start, Bias::Right, &None);
new_ropes.append(new_fragments.summary().text);
@ -992,7 +996,7 @@ impl Buffer {
let mut insertion_offset = 0;
let mut new_ropes =
RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
let mut old_fragments = self.fragments.cursor::<(VersionedFullOffset, usize)>();
let mut old_fragments = self.fragments.cursor::<(VersionedFullOffset, usize)>(&cx);
let mut new_fragments = old_fragments.slice(
&VersionedFullOffset::Offset(ranges[0].start),
Bias::Left,
@ -1185,7 +1189,7 @@ impl Buffer {
// Get all of the fragments corresponding to these insertion slices.
let mut fragment_ids = Vec::new();
let mut insertions_cursor = self.insertions.cursor::<InsertionFragmentKey>();
let mut insertions_cursor = self.insertions.cursor::<InsertionFragmentKey>(&());
for insertion_slice in &insertion_slices {
if insertion_slice.insertion_id != insertions_cursor.start().timestamp
|| insertion_slice.range.start > insertions_cursor.start().split_offset
@ -1217,8 +1221,8 @@ impl Buffer {
self.snapshot.undo_map.insert(undo);
let mut edits = Patch::default();
let mut old_fragments = self.fragments.cursor::<(Option<&Locator>, usize)>();
let mut new_fragments = SumTree::new();
let mut old_fragments = self.fragments.cursor::<(Option<&Locator>, usize)>(&None);
let mut new_fragments = SumTree::new(&None);
let mut new_ropes =
RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
@ -1455,7 +1459,7 @@ impl Buffer {
D: TextDimension,
{
// get fragment ranges
let mut cursor = self.fragments.cursor::<(Option<&Locator>, usize)>();
let mut cursor = self.fragments.cursor::<(Option<&Locator>, usize)>(&None);
let offset_ranges = self
.fragment_ids_for_edits(transaction.edit_ids.iter())
.into_iter()
@ -1485,7 +1489,7 @@ impl Buffer {
});
// convert to the desired text dimension.
let mut position = D::default();
let mut position = D::zero(&());
let mut rope_cursor = self.visible_text.cursor(0);
disjoint_ranges.map(move |range| {
position.add_assign(&rope_cursor.summary(range.start));
@ -1665,8 +1669,8 @@ impl Buffer {
);
}
let mut cursor = self.snapshot.fragments.cursor::<Option<&Locator>>();
for insertion_fragment in self.snapshot.insertions.cursor::<()>() {
let mut cursor = self.snapshot.fragments.cursor::<Option<&Locator>>(&None);
for insertion_fragment in self.snapshot.insertions.cursor::<()>(&()) {
cursor.seek(&Some(&insertion_fragment.fragment_id), Bias::Left, &None);
let fragment = cursor.item().unwrap();
assert_eq!(insertion_fragment.fragment_id, fragment.id);
@ -1783,7 +1787,7 @@ impl BufferSnapshot {
let mut cursor = self
.fragments
.filter::<_, FragmentTextSummary>(move |summary| {
.filter::<_, FragmentTextSummary>(&None, move |summary| {
!version.observed_all(&summary.max_version)
});
cursor.next(&None);
@ -2110,14 +2114,14 @@ impl BufferSnapshot {
A: 'a + IntoIterator<Item = (&'a Anchor, T)>,
{
let anchors = anchors.into_iter();
let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>();
let mut fragment_cursor = self.fragments.cursor::<(Option<&Locator>, usize)>();
let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(&());
let mut fragment_cursor = self.fragments.cursor::<(Option<&Locator>, usize)>(&None);
let mut text_cursor = self.visible_text.cursor(0);
let mut position = D::default();
let mut position = D::zero(&());
anchors.map(move |(anchor, payload)| {
if *anchor == Anchor::MIN {
return (D::default(), payload);
return (D::zero(&()), payload);
} else if *anchor == Anchor::MAX {
return (D::from_text_summary(&self.visible_text.summary()), payload);
}
@ -2159,7 +2163,7 @@ impl BufferSnapshot {
D: TextDimension,
{
if *anchor == Anchor::MIN {
D::default()
D::zero(&())
} else if *anchor == Anchor::MAX {
D::from_text_summary(&self.visible_text.summary())
} else {
@ -2167,7 +2171,7 @@ impl BufferSnapshot {
timestamp: anchor.timestamp,
split_offset: anchor.offset,
};
let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>();
let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(&());
insertion_cursor.seek(&anchor_key, anchor.bias, &());
if let Some(insertion) = insertion_cursor.item() {
let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key);
@ -2192,7 +2196,7 @@ impl BufferSnapshot {
);
};
let mut fragment_cursor = self.fragments.cursor::<(Option<&Locator>, usize)>();
let mut fragment_cursor = self.fragments.cursor::<(Option<&Locator>, usize)>(&None);
fragment_cursor.seek(&Some(&insertion.fragment_id), Bias::Left, &None);
let fragment = fragment_cursor.item().unwrap();
let mut fragment_offset = fragment_cursor.start().1;
@ -2213,7 +2217,7 @@ impl BufferSnapshot {
timestamp: anchor.timestamp,
split_offset: anchor.offset,
};
let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>();
let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(&());
insertion_cursor.seek(&anchor_key, anchor.bias, &());
if let Some(insertion) = insertion_cursor.item() {
let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key);
@ -2263,7 +2267,7 @@ impl BufferSnapshot {
} else if bias == Bias::Right && offset == self.len() {
Anchor::MAX
} else {
let mut fragment_cursor = self.fragments.cursor::<usize>();
let mut fragment_cursor = self.fragments.cursor::<usize>(&None);
fragment_cursor.seek(&offset, bias, &None);
let fragment = fragment_cursor.item().unwrap();
let overshoot = offset - *fragment_cursor.start();
@ -2341,15 +2345,15 @@ impl BufferSnapshot {
let fragments_cursor = if *since == self.version {
None
} else {
let mut cursor = self
.fragments
.filter(move |summary| !since.observed_all(&summary.max_version));
let mut cursor = self.fragments.filter(&None, move |summary| {
!since.observed_all(&summary.max_version)
});
cursor.next(&None);
Some(cursor)
};
let mut cursor = self
.fragments
.cursor::<(Option<&Locator>, FragmentTextSummary)>();
.cursor::<(Option<&Locator>, FragmentTextSummary)>(&None);
let start_fragment_id = self.fragment_id_for_anchor(&range.start);
cursor.seek(&Some(start_fragment_id), Bias::Left, &None);
@ -2371,8 +2375,8 @@ impl BufferSnapshot {
fragments_cursor,
undos: &self.undo_map,
since,
old_end: Default::default(),
new_end: Default::default(),
old_end: D::zero(&()),
new_end: D::zero(&()),
range: (start_fragment_id, range.start.offset)..(end_fragment_id, range.end.offset),
buffer_id: self.remote_id,
}
@ -2382,9 +2386,9 @@ impl BufferSnapshot {
if *since != self.version {
let start_fragment_id = self.fragment_id_for_anchor(&range.start);
let end_fragment_id = self.fragment_id_for_anchor(&range.end);
let mut cursor = self
.fragments
.filter::<_, usize>(move |summary| !since.observed_all(&summary.max_version));
let mut cursor = self.fragments.filter::<_, usize>(&None, move |summary| {
!since.observed_all(&summary.max_version)
});
cursor.next(&None);
while let Some(fragment) = cursor.item() {
if fragment.id > *end_fragment_id {
@ -2405,9 +2409,9 @@ impl BufferSnapshot {
pub fn has_edits_since(&self, since: &clock::Global) -> bool {
if *since != self.version {
let mut cursor = self
.fragments
.filter::<_, usize>(move |summary| !since.observed_all(&summary.max_version));
let mut cursor = self.fragments.filter::<_, usize>(&None, move |summary| {
!since.observed_all(&summary.max_version)
});
cursor.next(&None);
while let Some(fragment) = cursor.item() {
let was_visible = fragment.was_visible(since, &self.undo_map);
@ -2644,6 +2648,10 @@ impl sum_tree::Item for Fragment {
impl sum_tree::Summary for FragmentSummary {
type Context = Option<clock::Global>;
fn zero(_cx: &Self::Context) -> Self {
Default::default()
}
fn add_summary(&mut self, other: &Self, _: &Self::Context) {
self.max_id.assign(&other.max_id);
self.text.visible += &other.text.visible;
@ -2704,6 +2712,10 @@ impl InsertionFragment {
impl sum_tree::Summary for InsertionFragmentKey {
type Context = ();
fn zero(_cx: &()) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &Self, _: &()) {
*self = *summary;
}
@ -2736,18 +2748,30 @@ impl ops::Sub for FullOffset {
}
impl<'a> sum_tree::Dimension<'a, FragmentSummary> for usize {
fn zero(_: &Option<clock::Global>) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &FragmentSummary, _: &Option<clock::Global>) {
*self += summary.text.visible;
}
}
impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FullOffset {
fn zero(_: &Option<clock::Global>) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &FragmentSummary, _: &Option<clock::Global>) {
self.0 += summary.text.visible + summary.text.deleted;
}
}
impl<'a> sum_tree::Dimension<'a, FragmentSummary> for Option<&'a Locator> {
fn zero(_: &Option<clock::Global>) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option<clock::Global>) {
*self = Some(&summary.max_id);
}
@ -2786,6 +2810,10 @@ impl Default for VersionedFullOffset {
}
impl<'a> sum_tree::Dimension<'a, FragmentSummary> for VersionedFullOffset {
fn zero(_cx: &Option<clock::Global>) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &'a FragmentSummary, cx: &Option<clock::Global>) {
if let Self::Offset(offset) = self {
let version = cx.as_ref().unwrap();

View file

@ -33,6 +33,10 @@ struct UndoMapKey {
impl sum_tree::Summary for UndoMapKey {
type Context = ();
fn zero(_cx: &Self::Context) -> Self {
Default::default()
}
fn add_summary(&mut self, summary: &Self, _: &Self::Context) {
*self = cmp::max(*self, *summary);
}
@ -62,9 +66,8 @@ impl UndoMap {
pub fn is_undone(&self, edit_id: clock::Lamport) -> bool {
self.undo_count(edit_id) % 2 == 1
}
pub fn was_undone(&self, edit_id: clock::Lamport, version: &clock::Global) -> bool {
let mut cursor = self.0.cursor::<UndoMapKey>();
let mut cursor = self.0.cursor::<UndoMapKey>(&());
cursor.seek(
&UndoMapKey {
edit_id,
@ -89,7 +92,7 @@ impl UndoMap {
}
pub fn undo_count(&self, edit_id: clock::Lamport) -> u32 {
let mut cursor = self.0.cursor::<UndoMapKey>();
let mut cursor = self.0.cursor::<UndoMapKey>(&());
cursor.seek(
&UndoMapKey {
edit_id,