Building, but failing test WIP

This commit is contained in:
Keith Simmons 2022-04-27 17:25:38 -07:00
parent 065734e1de
commit 04fc1d5982
14 changed files with 492 additions and 419 deletions

View file

@ -91,26 +91,34 @@ impl HistoryEntry {
self.transaction.id
}
fn push_edit(&mut self, edit: &EditOperation) {
self.transaction.edit_ids.push(edit.timestamp.local());
self.transaction.end.observe(edit.timestamp.local());
fn push_edit(&mut self, edit_operation: &EditOperation) {
self.transaction
.edit_ids
.push(edit_operation.timestamp.local());
self.transaction
.end
.observe(edit_operation.timestamp.local());
let mut other_ranges = edit.ranges.iter().peekable();
let mut edits = edit_operation
.ranges
.iter()
.zip(edit_operation.new_text.iter())
.peekable();
let mut new_ranges = Vec::new();
let insertion_len = edit.new_text.as_ref().map_or(0, |t| t.len());
let mut delta = 0;
for mut self_range in self.transaction.ranges.iter().cloned() {
self_range.start += delta;
self_range.end += delta;
while let Some(other_range) = other_ranges.peek() {
while let Some((other_range, new_text)) = edits.peek() {
let insertion_len = new_text.as_ref().map_or(0, |t| t.len());
let mut other_range = (*other_range).clone();
other_range.start += delta;
other_range.end += delta;
if other_range.start <= self_range.end {
other_ranges.next().unwrap();
edits.next().unwrap();
delta += insertion_len;
if other_range.end < self_range.start {
@ -129,7 +137,8 @@ impl HistoryEntry {
new_ranges.push(self_range);
}
for other_range in other_ranges {
for (other_range, new_text) in edits {
let insertion_len = new_text.as_ref().map_or(0, |t| t.len());
new_ranges.push(other_range.start + delta..other_range.end + delta + insertion_len);
delta += insertion_len;
}
@ -515,7 +524,7 @@ pub struct EditOperation {
pub timestamp: InsertionTimestamp,
pub version: clock::Global,
pub ranges: Vec<Range<FullOffset>>,
pub new_text: Option<String>,
pub new_text: Vec<Option<Arc<str>>>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
@ -606,20 +615,30 @@ impl Buffer {
self.history.group_interval
}
pub fn edit<R, I, S, T>(&mut self, ranges: R, new_text: T) -> Operation
pub fn edit<S, T>(&mut self, range: Range<S>, new_text: T) -> Operation
where
S: ToOffset,
T: Into<Arc<str>>,
{
self.edit_batched([(range, new_text)])
}
pub fn edit_batched<R, I, S, T>(&mut self, edits: R) -> Operation
where
R: IntoIterator<IntoIter = I>,
I: ExactSizeIterator<Item = Range<S>>,
I: ExactSizeIterator<Item = (Range<S>, T)>,
S: ToOffset,
T: Into<String>,
T: Into<Arc<str>>,
{
let new_text = new_text.into();
let new_text_len = new_text.len();
let new_text = if new_text_len > 0 {
Some(new_text)
} else {
None
};
let edits = edits.into_iter().map(|(range, new_text)| {
let possibly_empty_arc_str = new_text.into();
let non_empty_text = if possibly_empty_arc_str.len() > 0 {
Some(possibly_empty_arc_str)
} else {
None
};
(range, non_empty_text)
});
self.start_transaction();
let timestamp = InsertionTimestamp {
@ -627,8 +646,7 @@ impl Buffer {
local: self.local_clock.tick().value,
lamport: self.lamport_clock.tick().value,
};
let operation =
Operation::Edit(self.apply_local_edit(ranges.into_iter(), new_text, timestamp));
let operation = Operation::Edit(self.apply_local_edit(edits, timestamp));
self.history.push(operation.clone());
self.history.push_undo(operation.local_timestamp());
@ -637,35 +655,35 @@ impl Buffer {
operation
}
fn apply_local_edit<S: ToOffset>(
fn apply_local_edit<S: ToOffset, T: Into<Arc<str>>>(
&mut self,
ranges: impl ExactSizeIterator<Item = Range<S>>,
new_text: Option<String>,
edits: impl ExactSizeIterator<Item = (Range<S>, Option<T>)>,
timestamp: InsertionTimestamp,
) -> EditOperation {
let mut edits = Patch::default();
let mut edits_patch = Patch::default();
let mut edit_op = EditOperation {
timestamp,
version: self.version(),
ranges: Vec::with_capacity(ranges.len()),
new_text: None,
ranges: Vec::with_capacity(edits.len()),
new_text: Vec::with_capacity(edits.len()),
};
let mut new_insertions = Vec::new();
let mut insertion_offset = 0;
let mut ranges = ranges
.map(|range| range.start.to_offset(&*self)..range.end.to_offset(&*self))
let mut ranges = edits
.map(|(range, new_text)| (range.to_offset(&*self), new_text))
.peekable();
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 new_fragments =
old_fragments.slice(&ranges.peek().unwrap().start, Bias::Right, &None);
old_fragments.slice(&ranges.peek().unwrap().0.start, Bias::Right, &None);
new_ropes.push_tree(new_fragments.summary().text);
let mut fragment_start = old_fragments.start().visible;
for range in ranges {
for (range, new_text) in ranges {
let new_text = new_text.map(|t| t.into());
let fragment_end = old_fragments.end(&None).visible;
// If the current fragment ends before this range, then jump ahead to the first fragment
@ -708,7 +726,7 @@ impl Buffer {
// Insert the new text before any existing fragments within the range.
if let Some(new_text) = new_text.as_deref() {
let new_start = new_fragments.summary().text.visible;
edits.push(Edit {
edits_patch.push(Edit {
old: fragment_start..fragment_start,
new: new_start..new_start + new_text.len(),
});
@ -750,7 +768,7 @@ impl Buffer {
if intersection.len > 0 {
if fragment.visible && !intersection.visible {
let new_start = new_fragments.summary().text.visible;
edits.push(Edit {
edits_patch.push(Edit {
old: fragment_start..intersection_end,
new: new_start..new_start,
});
@ -767,6 +785,7 @@ impl Buffer {
let full_range_end = FullOffset(range.end + old_fragments.start().deleted);
edit_op.ranges.push(full_range_start..full_range_end);
edit_op.new_text.push(new_text);
}
// If the current fragment has been partially consumed, then consume the rest of it
@ -794,8 +813,7 @@ impl Buffer {
self.snapshot.insertions.edit(new_insertions, &());
self.snapshot.visible_text = visible_text;
self.snapshot.deleted_text = deleted_text;
self.subscriptions.publish_mut(&edits);
edit_op.new_text = new_text;
self.subscriptions.publish_mut(&edits_patch);
edit_op
}
@ -822,7 +840,7 @@ impl Buffer {
self.apply_remote_edit(
&edit.version,
&edit.ranges,
edit.new_text.as_deref(),
&edit.new_text,
edit.timestamp,
);
self.snapshot.version.observe(edit.timestamp.local());
@ -852,14 +870,15 @@ impl Buffer {
&mut self,
version: &clock::Global,
ranges: &[Range<FullOffset>],
new_text: Option<&str>,
new_text: &[Option<Arc<str>>],
timestamp: InsertionTimestamp,
) {
if ranges.is_empty() {
return;
}
let mut edits = Patch::default();
let edits = ranges.into_iter().zip(new_text.into_iter());
let mut edits_patch = Patch::default();
let cx = Some(version.clone());
let mut new_insertions = Vec::new();
let mut insertion_offset = 0;
@ -874,7 +893,7 @@ impl Buffer {
new_ropes.push_tree(new_fragments.summary().text);
let mut fragment_start = old_fragments.start().0.full_offset();
for range in ranges {
for (range, new_text) in edits {
let fragment_end = old_fragments.end(&cx).0.full_offset();
// If the current fragment ends before this range, then jump ahead to the first fragment
@ -950,7 +969,7 @@ impl Buffer {
old_start += fragment_start.0 - old_fragments.start().0.full_offset().0;
}
let new_start = new_fragments.summary().text.visible;
edits.push(Edit {
edits_patch.push(Edit {
old: old_start..old_start,
new: new_start..new_start + new_text.len(),
});
@ -995,7 +1014,7 @@ impl Buffer {
let old_start = old_fragments.start().1
+ (fragment_start.0 - old_fragments.start().0.full_offset().0);
let new_start = new_fragments.summary().text.visible;
edits.push(Edit {
edits_patch.push(Edit {
old: old_start..old_start + intersection.len,
new: new_start..new_start,
});
@ -1036,7 +1055,7 @@ impl Buffer {
self.snapshot.visible_text = visible_text;
self.snapshot.deleted_text = deleted_text;
self.snapshot.insertions.edit(new_insertions, &());
self.subscriptions.publish_mut(&edits);
self.subscriptions.publish_mut(&edits_patch);
}
fn apply_undo(&mut self, undo: &UndoOperation) -> Result<()> {
@ -1416,31 +1435,32 @@ impl Buffer {
pub fn randomly_edit<T>(
&mut self,
rng: &mut T,
old_range_count: usize,
) -> (Vec<Range<usize>>, String, Operation)
edit_count: usize,
) -> (Vec<(Range<usize>, Arc<str>)>, Operation)
where
T: rand::Rng,
{
let mut old_ranges: Vec<Range<usize>> = Vec::new();
for _ in 0..old_range_count {
let last_end = old_ranges.last().map_or(0, |last_range| last_range.end + 1);
if last_end > self.len() {
let mut edits: Vec<(Range<usize>, Arc<str>)> = Vec::new();
let mut last_end = None;
for _ in 0..edit_count {
if last_end.map_or(false, |last_end| last_end >= self.len()) {
break;
}
old_ranges.push(self.random_byte_range(last_end, rng));
let new_start = last_end.map_or(0, |last_end| last_end + 1);
let range = self.random_byte_range(new_start, rng);
last_end = Some(range.end);
let new_text_len = rng.gen_range(0..10);
let new_text: String = crate::random_char_iter::RandomCharIter::new(&mut *rng)
.take(new_text_len)
.collect();
edits.push((range, new_text.into()));
}
let new_text_len = rng.gen_range(0..10);
let new_text: String = crate::random_char_iter::RandomCharIter::new(&mut *rng)
.take(new_text_len)
.collect();
log::info!(
"mutating buffer {} at {:?}: {:?}",
self.replica_id,
old_ranges,
new_text
);
let op = self.edit(old_ranges.iter().cloned(), new_text.as_str());
(old_ranges, new_text, op)
log::info!("mutating buffer {} with {:?}", self.replica_id, edits);
let op = self.edit_batched(edits.iter().cloned());
(edits, op)
}
pub fn randomly_undo_redo(&mut self, rng: &mut impl rand::Rng) -> Vec<Operation> {