WIP - Serialize buffer in terms of its state, not its base text + ops

The main reason for this is that we need to include information about
a buffer's UndoMap into its protobuf representation. But it's a bit
complex to correctly incorporate this information into the current
protobuf representation.

If we want to continue reusing `Buffer::apply_remote_edit` for
incorporating the historical operations, we need to either make
that method capable of incorporating already-undone edits, or
serialize the UndoMap into undo *operations*, so that we can apply
these undo operations after the fact when deserializing. But this is
not trivial, because an UndoOperation requires information about
the full offset ranges that were undone.
This commit is contained in:
Max Brunsfeld 2022-01-04 18:06:16 -08:00
parent d7ecbdcc1d
commit 984e366c32
6 changed files with 222 additions and 44 deletions

View file

@ -32,7 +32,7 @@ pub fn serialize_operation(operation: &Operation) -> proto::Operation {
counts: undo
.counts
.iter()
.map(|(edit_id, count)| proto::operation::UndoCount {
.map(|(edit_id, count)| proto::UndoCount {
replica_id: edit_id.replica_id as u32,
local_timestamp: edit_id.value,
count: *count,
@ -91,6 +91,50 @@ pub fn serialize_edit_operation(operation: &EditOperation) -> proto::operation::
}
}
pub fn serialize_undo_map_entry(
(edit_id, counts): (&clock::Local, &[(clock::Local, u32)]),
) -> proto::UndoMapEntry {
proto::UndoMapEntry {
replica_id: edit_id.replica_id as u32,
local_timestamp: edit_id.value,
counts: counts
.iter()
.map(|(undo_id, count)| proto::UndoCount {
replica_id: undo_id.replica_id as u32,
local_timestamp: undo_id.value,
count: *count,
})
.collect(),
}
}
pub fn serialize_buffer_fragment(fragment: &text::Fragment) -> proto::BufferFragment {
proto::BufferFragment {
replica_id: fragment.insertion_timestamp.replica_id as u32,
local_timestamp: fragment.insertion_timestamp.local,
lamport_timestamp: fragment.insertion_timestamp.lamport,
insertion_offset: fragment.insertion_offset as u32,
len: fragment.len as u32,
visible: fragment.visible,
deletions: fragment
.deletions
.iter()
.map(|clock| proto::VectorClockEntry {
replica_id: clock.replica_id as u32,
timestamp: clock.value,
})
.collect(),
max_undos: fragment
.max_undos
.iter()
.map(|clock| proto::VectorClockEntry {
replica_id: clock.replica_id as u32,
timestamp: clock.value,
})
.collect(),
}
}
pub fn serialize_selections(selections: &Arc<[Selection<Anchor>]>) -> Vec<proto::Selection> {
selections
.iter()
@ -252,6 +296,38 @@ pub fn deserialize_edit_operation(edit: proto::operation::Edit) -> EditOperation
}
}
pub fn deserialize_undo_map_entry(
entry: proto::UndoMapEntry,
) -> (clock::Local, Vec<(clock::Local, u32)>) {
(
clock::Local {
replica_id: entry.replica_id as u16,
value: entry.local_timestamp,
},
entry
.counts
.into_iter()
.map(|undo_count| {
(
clock::Local {
replica_id: undo_count.replica_id as u16,
value: undo_count.local_timestamp,
},
undo_count.count,
)
})
.collect(),
)
}
pub fn deserialize_buffer_fragment(
message: proto::BufferFragment,
ix: usize,
count: usize,
) -> Fragment {
todo!()
}
pub fn deserialize_selections(selections: Vec<proto::Selection>) -> Arc<[Selection<Anchor>]> {
Arc::from(
selections