This commit is contained in:
Max Brunsfeld
2021-06-01 18:22:08 -07:00
parent 74b07fed18
commit 5f28fdb8f7
+175 -408
View File
@@ -28,7 +28,7 @@ use std::{
cell::RefCell,
cmp,
hash::BuildHasher,
iter::{self, Iterator},
iter::Iterator,
mem,
ops::{Deref, DerefMut, Range},
str,
@@ -109,7 +109,6 @@ pub struct Buffer {
fragments: SumTree<Fragment>,
visible_text: Rope,
deleted_text: Rope,
insertion_splits: HashMap<time::Local, SumTree<InsertionSplit>>,
pub version: time::Global,
saved_version: time::Global,
saved_mtime: SystemTime,
@@ -338,9 +337,7 @@ pub struct Insertion {
#[derive(Eq, PartialEq, Clone, Debug)]
struct Fragment {
id: FragmentId,
insertion: Arc<Insertion>,
range_in_insertion: Range<usize>,
insertion_id: time::Local,
len: usize,
deletions: HashSet<time::Local>,
max_undos: time::Global,
@@ -350,7 +347,6 @@ struct Fragment {
#[derive(Eq, PartialEq, Clone, Debug)]
pub struct FragmentSummary {
text: FragmentTextSummary,
max_fragment_id: FragmentId,
max_version: time::Global,
min_insertion_version: time::Global,
max_insertion_version: time::Global,
@@ -369,17 +365,6 @@ impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FragmentTextSummary {
}
}
#[derive(Eq, PartialEq, Clone, Debug)]
struct InsertionSplit {
extent: usize,
fragment_id: FragmentId,
}
#[derive(Eq, PartialEq, Clone, Debug)]
struct InsertionSplitSummary {
extent: usize,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Operation {
Edit {
@@ -474,52 +459,20 @@ impl Buffer {
saved_mtime = UNIX_EPOCH;
}
let mut visible_text = Rope::new();
let mut insertion_splits = HashMap::default();
let mut fragments = SumTree::new();
let base_text = Rope::from(history.base_text.as_ref());
let base_insertion = Arc::new(Insertion {
id: time::Local::default(),
parent_id: time::Local::default(),
offset_in_parent: 0,
lamport_timestamp: time::Lamport::default(),
});
let visible_text = Rope::from(history.base_text.as_ref());
let mut local_clock = time::Local::new(replica_id);
insertion_splits.insert(
base_insertion.id,
SumTree::from_item(
InsertionSplit {
fragment_id: FragmentId::min_value().clone(),
extent: 0,
},
&(),
),
);
fragments.push(
Fragment::new(
FragmentId::min_value().clone(),
base_insertion.clone(),
0..0,
),
&None,
);
if base_text.len() > 0 {
let base_fragment_id =
FragmentId::between(&FragmentId::min_value(), &FragmentId::max_value());
let range_in_insertion = 0..base_text.len();
visible_text = base_text.clone();
insertion_splits.get_mut(&base_insertion.id).unwrap().push(
InsertionSplit {
fragment_id: base_fragment_id.clone(),
extent: range_in_insertion.end,
},
&(),
);
if visible_text.len() > 0 {
fragments.push(
Fragment::new(base_fragment_id, base_insertion, range_in_insertion.clone()),
Fragment {
insertion_id: local_clock.tick(),
len: visible_text.len(),
deletions: Default::default(),
max_undos: Default::default(),
visible: true,
},
&None,
);
}
@@ -528,7 +481,6 @@ impl Buffer {
visible_text,
deleted_text: Rope::new(),
fragments,
insertion_splits,
version: time::Global::new(),
saved_version: time::Global::new(),
last_edit: time::Local::default(),
@@ -544,7 +496,7 @@ impl Buffer {
deferred_ops: OperationQueue::new(),
deferred_replicas: HashSet::default(),
replica_id,
local_clock: time::Local::new(replica_id),
local_clock,
lamport_clock: time::Lamport::new(replica_id),
};
result.reparse(cx);
@@ -1205,7 +1157,7 @@ impl Buffer {
if let Some(fragment) = fragment {
// Was this fragment visible in the edit's base version? If not, push it into
// the new fragments, skip it, and continue the loop.
if !version.observed(fragment.insertion.id) {
if !version.observed(fragment.insertion_id) {
new_ropes.push_fragment(fragment, fragment.visible);
new_fragments.push(fragment.clone(), &None);
old_fragments.next(&old_fragments_cx);
@@ -1222,10 +1174,7 @@ impl Buffer {
deletions: fragment.deletions.clone(),
max_undos: fragment.max_undos.clone(),
visible: fragment.visible,
// DELETE
id: Default::default(),
insertion: fragment.insertion.clone(),
range_in_insertion: Default::default(),
insertion_id: fragment.insertion_id,
};
new_ropes.push_fragment(&suffix, fragment.visible);
new_fragments.push(suffix, &None);
@@ -1249,11 +1198,7 @@ impl Buffer {
deletions: fragment.deletions.clone(),
max_undos: fragment.max_undos.clone(),
visible: fragment.visible,
// TODO: Delete these
id: Default::default(),
insertion: fragment.insertion.clone(),
range_in_insertion: Default::default(),
insertion_id: fragment.insertion_id,
};
fragment_start_offset += prefix.len;
new_ropes.push_fragment(&prefix, fragment.visible);
@@ -1273,11 +1218,7 @@ impl Buffer {
deletions,
max_undos: fragment.max_undos.clone(),
visible: false,
// TODO: Delete these
id: Default::default(),
insertion: fragment.insertion.clone(),
range_in_insertion: Default::default(),
insertion_id: fragment.insertion_id,
};
fragment_start_offset += deleted.len;
new_ropes.push_fragment(&deleted, fragment.visible);
@@ -1293,11 +1234,7 @@ impl Buffer {
deletions: Default::default(),
max_undos: Default::default(), // TODO: Is this right?
visible: true,
// TODO: Delete these
id: Default::default(),
insertion: fragment.insertion.clone(),
range_in_insertion: Default::default(),
insertion_id: local_timestamp,
},
&None,
);
@@ -1326,16 +1263,13 @@ impl Buffer {
deletions: fragment.deletions.clone(),
max_undos: fragment.max_undos.clone(),
visible: fragment.visible,
// DELETE
id: Default::default(),
insertion: fragment.insertion.clone(),
range_in_insertion: Default::default(),
insertion_id: fragment.insertion_id,
};
new_ropes.push_fragment(&suffix, fragment.visible);
new_fragments.push(suffix, &None);
}
let suffix_fragments = old_fragments.suffix(&None);
let suffix_fragments = old_fragments.suffix(&old_fragments_cx);
new_ropes.push_tree(suffix_fragments.summary().text);
new_fragments.push_tree(suffix_fragments, &None);
}
@@ -1420,95 +1354,129 @@ impl Buffer {
}
fn apply_undo(&mut self, undo: UndoOperation) -> Result<()> {
let mut old_fragments = self.fragments.cursor::<VersionedOffset, VersionedOffset>();
let mut new_fragments = SumTree::new();
let mut new_ropes =
RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
self.undo_map.insert(undo);
let edit = &self.history.ops[&undo.edit_id];
let version = Some(edit.version.clone());
for range in &edit.ranges {
let preceding_fragments = old_fragments.slice(
&VersionedOffset::Offset(range.start),
SeekBias::Right,
&version,
);
new_ropes.push_tree(preceding_fragments.summary().text);
new_fragments.push_tree(preceding_fragments, &None);
while old_fragments.end(&version).offset() < range.end {
if let Some(fragment) = old_fragments.item() {
let mut fragment = fragment.clone();
let fragment_was_visible = fragment.visible;
if edit.version.observed(fragment.insertion_id) {
fragment.visible = fragment.is_visible(&self.undo_map);
fragment.max_undos.observe(undo.id);
}
new_ropes.push_fragment(&fragment, fragment_was_visible);
new_fragments.push(fragment, &None);
// Skip over any fragments that were not present when the edit occurred.
let newer_fragments = old_fragments.slice(
&old_fragments.end(&version),
SeekBias::Right,
&version,
);
new_ropes.push_tree(newer_fragments.summary().text);
new_fragments.push_tree(newer_fragments, &None);
} else {
break;
}
}
}
let suffix = old_fragments.suffix(&version);
new_ropes.push_tree(suffix.summary().text);
new_fragments.push_tree(suffix, &None);
drop(old_fragments);
let (visible_text, deleted_text) = new_ropes.finish();
self.fragments = new_fragments;
self.visible_text = visible_text;
self.deleted_text = deleted_text;
// if edit.start_id == edit.end_id && edit.start_offset == edit.end_offset {
// let splits = &self.insertion_splits[&undo.edit_id];
// let mut insertion_splits = splits.cursor::<(), ()>().map(|s| &s.fragment_id).peekable();
// let first_split_id = insertion_splits.next().unwrap();
// new_fragments =
// fragments_cursor.slice(&FragmentIdRef::new(first_split_id), SeekBias::Left, &None);
// new_ropes.push_tree(new_fragments.summary().text);
// loop {
// let mut fragment = fragments_cursor.item().unwrap().clone();
// let was_visible = fragment.visible;
// fragment.visible = fragment.is_visible(&self.undo_map);
// fragment.max_undos.observe(undo.id);
// new_ropes.push_fragment(&fragment, was_visible);
// new_fragments.push(fragment.clone(), &None);
// fragments_cursor.next(&None);
// if let Some(split_id) = insertion_splits.next() {
// let slice = fragments_cursor.slice(
// &FragmentIdRef::new(split_id),
// SeekBias::Left,
// &None,
// );
// new_ropes.push_tree(slice.summary().text);
// new_fragments.push_tree(slice, &None);
// } else {
// break;
// }
// }
// } else {
// new_fragments = fragments_cursor.slice(
// &FragmentIdRef::new(&edit.),
// SeekBias::Left,
// &None,
// );
// new_ropes.push_tree(new_fragments.summary().text);
// while let Some(fragment) = fragments_cursor.item() {
// if fragment.id > end_fragment_id {
// break;
// } else {
// let mut fragment = fragment.clone();
// let fragment_was_visible = fragment.visible;
// if edit.version_in_range.observed(fragment.insertion.id)
// || fragment.insertion.id == undo.edit_id
// {
// fragment.visible = fragment.is_visible(&self.undo_map);
// fragment.max_undos.observe(undo.id);
// }
// new_ropes.push_fragment(&fragment, fragment_was_visible);
// new_fragments.push(fragment, &None);
// fragments_cursor.next(&None);
// }
// }
// }
// new_fragments.push_tree(fragments_cursor.suffix(&None), &None);
// let (visible_text, deleted_text) = new_ropes.finish();
// drop(fragments_cursor);
// self.fragments = new_fragments;
// self.visible_text = visible_text;
// self.deleted_text = deleted_text;
Ok(())
}
// {
// let mut new_fragments;
// let mut old_visible_text = Rope::new();
// let mut old_deleted_text = Rope::new();
// mem::swap(&mut old_visible_text, &mut self.visible_text);
// mem::swap(&mut old_deleted_text, &mut self.deleted_text);
// let mut new_ropes =
// RopeBuilder::new(old_visible_text.cursor(0), old_deleted_text.cursor(0));
// self.undo_map.insert(undo);
// let edit = &self.history.ops[&undo.edit_id];
// let start_fragment_id = self.resolve_fragment_id(edit.start_id, edit.start_offset)?;
// let end_fragment_id = self.resolve_fragment_id(edit.end_id, edit.end_offset)?;
// let mut fragments_cursor = self.fragments.cursor::<FragmentIdRef, ()>();
// if edit.start_id == edit.end_id && edit.start_offset == edit.end_offset {
// let splits = &self.insertion_splits[&undo.edit_id];
// let mut insertion_splits = splits.cursor::<(), ()>().map(|s| &s.fragment_id).peekable();
// let first_split_id = insertion_splits.next().unwrap();
// new_fragments =
// fragments_cursor.slice(&FragmentIdRef::new(first_split_id), SeekBias::Left, &None);
// new_ropes.push_tree(new_fragments.summary().text);
// loop {
// let mut fragment = fragments_cursor.item().unwrap().clone();
// let was_visible = fragment.visible;
// fragment.visible = fragment.is_visible(&self.undo_map);
// fragment.max_undos.observe(undo.id);
// new_ropes.push_fragment(&fragment, was_visible);
// new_fragments.push(fragment.clone(), &None);
// fragments_cursor.next(&None);
// if let Some(split_id) = insertion_splits.next() {
// let slice = fragments_cursor.slice(
// &FragmentIdRef::new(split_id),
// SeekBias::Left,
// &None,
// );
// new_ropes.push_tree(slice.summary().text);
// new_fragments.push_tree(slice, &None);
// } else {
// break;
// }
// }
// } else {
// new_fragments = fragments_cursor.slice(
// &FragmentIdRef::new(&start_fragment_id),
// SeekBias::Left,
// &None,
// );
// new_ropes.push_tree(new_fragments.summary().text);
// while let Some(fragment) = fragments_cursor.item() {
// if fragment.id > end_fragment_id {
// break;
// } else {
// let mut fragment = fragment.clone();
// let fragment_was_visible = fragment.visible;
// if edit.version_in_range.observed(fragment.insertion.id)
// || fragment.insertion.id == undo.edit_id
// {
// fragment.visible = fragment.is_visible(&self.undo_map);
// fragment.max_undos.observe(undo.id);
// }
// new_ropes.push_fragment(&fragment, fragment_was_visible);
// new_fragments.push(fragment, &None);
// fragments_cursor.next(&None);
// }
// }
// }
// new_fragments.push_tree(fragments_cursor.suffix(&None), &None);
// let (visible_text, deleted_text) = new_ropes.finish();
// drop(fragments_cursor);
// self.fragments = new_fragments;
// self.visible_text = visible_text;
// self.deleted_text = deleted_text;
// Ok(())
// }
fn flush_deferred_ops(&mut self) -> Result<()> {
self.deferred_replicas.clear();
let mut deferred_ops = Vec::new();
@@ -1588,14 +1556,6 @@ impl Buffer {
let mut fragment_end = fragment_start + fragment.visible_len();
let fragment_was_visible = fragment.visible;
let old_split_tree = self
.insertion_splits
.remove(&fragment.insertion.id)
.unwrap();
let mut splits_cursor = old_split_tree.cursor::<usize, ()>();
let mut new_split_tree =
splits_cursor.slice(&fragment.range_in_insertion.start, SeekBias::Right, &());
// 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
// inserted text.
@@ -1603,33 +1563,23 @@ impl Buffer {
let range = cur_range.clone().unwrap();
if range.start > fragment_start {
let mut prefix = fragment.clone();
prefix.range_in_insertion.end =
prefix.range_in_insertion.start + (range.start - fragment_start);
prefix.id =
FragmentId::between(&new_fragments.last().unwrap().id, &fragment.id);
fragment.range_in_insertion.start = prefix.range_in_insertion.end;
prefix.len = range.start - fragment_start;
fragment.len -= prefix.len;
new_ropes.push_fragment(&prefix, prefix.visible);
new_fragments.push(prefix.clone(), &None);
new_split_tree.push(
InsertionSplit {
extent: prefix.range_in_insertion.end - prefix.range_in_insertion.start,
fragment_id: prefix.id,
},
&(),
);
fragment_start = range.start;
}
if range.start == fragment_start {
if let Some(new_text) = new_text.clone() {
let new_fragment = self.build_fragment_to_insert(
&new_fragments.last().unwrap(),
Some(&fragment),
&new_text,
edit_id,
lamport_timestamp,
);
let new_fragment = Fragment {
len: new_text.len(),
insertion_id: edit_id,
deletions: Default::default(),
max_undos: Default::default(),
visible: true,
};
new_ropes.push_str(&new_text);
new_fragments.push(new_fragment, &None);
@@ -1639,25 +1589,14 @@ impl Buffer {
if range.end < fragment_end {
if range.end > fragment_start {
let mut prefix = fragment.clone();
prefix.range_in_insertion.end =
prefix.range_in_insertion.start + (range.end - fragment_start);
prefix.id =
FragmentId::between(&new_fragments.last().unwrap().id, &fragment.id);
prefix.len = range.end - fragment_start;
if prefix.visible {
prefix.deletions.insert(edit_id);
prefix.visible = false;
}
fragment.range_in_insertion.start = prefix.range_in_insertion.end;
fragment.len -= prefix.len;
new_ropes.push_fragment(&prefix, fragment_was_visible);
new_fragments.push(prefix.clone(), &None);
new_split_tree.push(
InsertionSplit {
extent: prefix.range_in_insertion.end
- prefix.range_in_insertion.start,
fragment_id: prefix.id,
},
&(),
);
fragment_start = range.end;
}
} else {
@@ -1676,20 +1615,6 @@ impl Buffer {
break;
}
}
new_split_tree.push(
InsertionSplit {
extent: fragment.range_in_insertion.end - fragment.range_in_insertion.start,
fragment_id: fragment.id.clone(),
},
&(),
);
splits_cursor.next(&());
new_split_tree.push_tree(
splits_cursor.slice(&old_split_tree.extent::<usize>(&()), SeekBias::Right, &()),
&(),
);
self.insertion_splits
.insert(fragment.insertion.id, new_split_tree);
new_ropes.push_fragment(&fragment, fragment_was_visible);
new_fragments.push(fragment, &None);
@@ -1740,16 +1665,15 @@ impl Buffer {
// multiple because ranges must be disjoint.
if cur_range.is_some() {
debug_assert_eq!(old_ranges.next(), None);
let last_fragment = new_fragments.last().unwrap();
if let Some(new_text) = new_text {
let new_fragment = self.build_fragment_to_insert(
&last_fragment,
None,
&new_text,
edit_id,
lamport_timestamp,
);
let new_fragment = Fragment {
len: new_text.len(),
insertion_id: edit_id,
deletions: Default::default(),
max_undos: Default::default(),
visible: true,
};
new_ropes.push_str(&new_text);
new_fragments.push(new_fragment, &None);
@@ -1764,44 +1688,6 @@ impl Buffer {
self.deleted_text = deleted_text;
}
fn build_fragment_to_insert(
&mut self,
prev_fragment: &Fragment,
next_fragment: Option<&Fragment>,
text: &str,
insertion_id: time::Local,
lamport_timestamp: time::Lamport,
) -> Fragment {
let new_fragment_id = FragmentId::between(
&prev_fragment.id,
next_fragment
.map(|f| &f.id)
.unwrap_or(&FragmentId::max_value()),
);
let range_in_insertion = 0..text.len();
let mut split_tree = SumTree::new();
split_tree.push(
InsertionSplit {
extent: range_in_insertion.len(),
fragment_id: new_fragment_id.clone(),
},
&(),
);
self.insertion_splits.insert(insertion_id, split_tree);
Fragment::new(
new_fragment_id,
Arc::new(Insertion {
id: insertion_id,
parent_id: prev_fragment.insertion.id,
offset_in_parent: prev_fragment.range_in_insertion.end,
lamport_timestamp,
}),
range_in_insertion,
)
}
pub fn anchor_before<T: ToOffset>(&self, position: T) -> Anchor {
self.anchor_at(position, AnchorBias::Left)
}
@@ -1905,7 +1791,6 @@ impl Clone for Buffer {
fragments: self.fragments.clone(),
visible_text: self.visible_text.clone(),
deleted_text: self.deleted_text.clone(),
insertion_splits: self.insertion_splits.clone(),
version: self.version.clone(),
saved_version: self.saved_version.clone(),
saved_mtime: self.saved_mtime,
@@ -2015,7 +1900,7 @@ impl<'a> RopeBuilder<'a> {
}
fn push_fragment(&mut self, fragment: &Fragment, was_visible: bool) {
self.push(fragment.len(), was_visible, fragment.visible)
self.push(fragment.len, was_visible, fragment.visible)
}
fn push(&mut self, len: usize, was_visible: bool, is_visible: bool) {
@@ -2071,38 +1956,38 @@ impl<'a, F: Fn(&FragmentSummary) -> bool> Iterator for Edits<'a, F> {
if !fragment.was_visible(&self.since, &self.undos) && fragment.visible {
if let Some(ref mut change) = change {
if change.new_range.end == new_offset {
change.new_range.end += fragment.len();
self.delta += fragment.len() as isize;
change.new_range.end += fragment.len;
self.delta += fragment.len as isize;
} else {
break;
}
} else {
change = Some(Edit {
old_range: old_offset..old_offset,
new_range: new_offset..new_offset + fragment.len(),
new_range: new_offset..new_offset + fragment.len,
old_lines: Point::zero(),
});
self.delta += fragment.len() as isize;
self.delta += fragment.len as isize;
}
} else if fragment.was_visible(&self.since, &self.undos) && !fragment.visible {
let deleted_start = self.cursor.start().deleted;
let old_lines = self.deleted_text.to_point(deleted_start + fragment.len())
let old_lines = self.deleted_text.to_point(deleted_start + fragment.len)
- self.deleted_text.to_point(deleted_start);
if let Some(ref mut change) = change {
if change.new_range.end == new_offset {
change.old_range.end += fragment.len();
change.old_range.end += fragment.len;
change.old_lines += &old_lines;
self.delta -= fragment.len() as isize;
self.delta -= fragment.len as isize;
} else {
break;
}
} else {
change = Some(Edit {
old_range: old_offset..old_offset + fragment.len(),
old_range: old_offset..old_offset + fragment.len,
new_range: new_offset..new_offset,
old_lines,
});
self.delta -= fragment.len() as isize;
self.delta -= fragment.len as isize;
}
}
@@ -2233,85 +2118,22 @@ impl<'a> Iterator for HighlightedChunks<'a> {
}
}
#[derive(Ord, PartialOrd, Eq, PartialEq, Clone, Debug)]
struct FragmentId(Arc<[u16]>);
lazy_static! {
static ref FRAGMENT_ID_EMPTY: FragmentId = FragmentId(Arc::from([]));
static ref FRAGMENT_ID_MIN_VALUE: FragmentId = FragmentId(Arc::from([0 as u16]));
static ref FRAGMENT_ID_MAX_VALUE: FragmentId = FragmentId(Arc::from([u16::max_value()]));
}
impl Default for FragmentId {
fn default() -> Self {
FRAGMENT_ID_EMPTY.clone()
}
}
impl FragmentId {
fn min_value() -> &'static Self {
&FRAGMENT_ID_MIN_VALUE
}
fn max_value() -> &'static Self {
&FRAGMENT_ID_MAX_VALUE
}
fn between(left: &Self, right: &Self) -> Self {
Self::between_with_max(left, right, u16::max_value())
}
fn between_with_max(left: &Self, right: &Self, max_value: u16) -> Self {
let mut new_entries = Vec::new();
let left_entries = left.0.iter().cloned().chain(iter::repeat(0));
let right_entries = right.0.iter().cloned().chain(iter::repeat(max_value));
for (l, r) in left_entries.zip(right_entries) {
let interval = r - l;
if interval > 1 {
new_entries.push(l + cmp::max(1, cmp::min(8, interval / 2)));
break;
} else {
new_entries.push(l);
}
}
FragmentId(Arc::from(new_entries))
}
}
impl Fragment {
fn new(id: FragmentId, insertion: Arc<Insertion>, range_in_insertion: Range<usize>) -> Self {
Self {
id,
insertion,
len: range_in_insertion.len(),
range_in_insertion,
deletions: Default::default(),
max_undos: Default::default(),
visible: true,
}
}
fn is_visible(&self, undos: &UndoMap) -> bool {
!undos.is_undone(self.insertion.id) && self.deletions.iter().all(|d| undos.is_undone(*d))
!undos.is_undone(self.insertion_id) && self.deletions.iter().all(|d| undos.is_undone(*d))
}
fn was_visible(&self, version: &time::Global, undos: &UndoMap) -> bool {
(version.observed(self.insertion.id) && !undos.was_undone(self.insertion.id, version))
(version.observed(self.insertion_id) && !undos.was_undone(self.insertion_id, version))
&& self
.deletions
.iter()
.all(|d| !version.observed(*d) || undos.was_undone(*d, version))
}
fn len(&self) -> usize {
self.range_in_insertion.len()
}
fn visible_len(&self) -> usize {
if self.visible {
self.range_in_insertion.len()
self.len
} else {
0
}
@@ -2323,22 +2145,21 @@ impl sum_tree::Item for Fragment {
fn summary(&self) -> Self::Summary {
let mut max_version = time::Global::new();
max_version.observe(self.insertion.id);
max_version.observe(self.insertion_id);
for deletion in &self.deletions {
max_version.observe(*deletion);
}
max_version.join(&self.max_undos);
let mut min_insertion_version = time::Global::new();
min_insertion_version.observe(self.insertion.id);
min_insertion_version.observe(self.insertion_id);
let max_insertion_version = min_insertion_version.clone();
if self.visible {
FragmentSummary {
text: FragmentTextSummary {
visible: self.len(),
visible: self.len,
deleted: 0,
},
max_fragment_id: self.id.clone(),
max_version,
min_insertion_version,
max_insertion_version,
@@ -2347,9 +2168,8 @@ impl sum_tree::Item for Fragment {
FragmentSummary {
text: FragmentTextSummary {
visible: 0,
deleted: self.len(),
deleted: self.len,
},
max_fragment_id: self.id.clone(),
max_version,
min_insertion_version,
max_insertion_version,
@@ -2364,8 +2184,6 @@ impl sum_tree::Summary for FragmentSummary {
fn add_summary(&mut self, other: &Self, _: &Self::Context) {
self.text.visible += &other.text.visible;
self.text.deleted += &other.text.deleted;
debug_assert!(self.max_fragment_id <= other.max_fragment_id);
self.max_fragment_id = other.max_fragment_id.clone();
self.max_version.join(&other.max_version);
self.min_insertion_version
.meet(&other.min_insertion_version);
@@ -2378,7 +2196,6 @@ impl Default for FragmentSummary {
fn default() -> Self {
FragmentSummary {
text: FragmentTextSummary::default(),
max_fragment_id: FragmentId::min_value().clone(),
max_version: time::Global::new(),
min_insertion_version: time::Global::new(),
max_insertion_version: time::Global::new(),
@@ -2392,36 +2209,6 @@ impl<'a> sum_tree::Dimension<'a, FragmentSummary> for usize {
}
}
impl sum_tree::Item for InsertionSplit {
type Summary = InsertionSplitSummary;
fn summary(&self) -> Self::Summary {
InsertionSplitSummary {
extent: self.extent,
}
}
}
impl sum_tree::Summary for InsertionSplitSummary {
type Context = ();
fn add_summary(&mut self, other: &Self, _: &()) {
self.extent += other.extent;
}
}
impl Default for InsertionSplitSummary {
fn default() -> Self {
InsertionSplitSummary { extent: 0 }
}
}
impl<'a> sum_tree::Dimension<'a, InsertionSplitSummary> for usize {
fn add_summary(&mut self, summary: &InsertionSplitSummary, _: &()) {
*self += summary.extent;
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
enum VersionedOffset {
Offset(usize),
@@ -2847,26 +2634,6 @@ mod tests {
});
}
#[test]
fn test_fragment_ids() {
for seed in 0..10 {
let rng = &mut StdRng::seed_from_u64(seed);
let mut ids = vec![FragmentId(Arc::from([0])), FragmentId(Arc::from([4]))];
for _i in 0..100 {
let index = rng.gen_range(1..ids.len());
let left = ids[index - 1].clone();
let right = ids[index].clone();
ids.insert(index, FragmentId::between_with_max(&left, &right, 4));
let mut sorted_ids = ids.clone();
sorted_ids.sort();
assert_eq!(ids, sorted_ids);
}
}
}
#[gpui::test]
fn test_anchors(cx: &mut gpui::MutableAppContext) {
cx.add_model(|cx| {