Simplify protocol messages related to selection sets

This prepares the way to switch to using AnchorRangeMaps to store and transmit selection sets.
This commit is contained in:
Nathan Sobo 2021-10-22 12:35:29 -06:00
parent 087ff28d0d
commit 401bdf0ba1
2 changed files with 79 additions and 55 deletions

View File

@ -408,7 +408,11 @@ pub enum Operation {
}, },
UpdateSelections { UpdateSelections {
set_id: SelectionSetId, set_id: SelectionSetId,
selections: Option<Arc<[Selection]>>, selections: Arc<[Selection]>,
lamport_timestamp: clock::Lamport,
},
RemoveSelections {
set_id: SelectionSetId,
lamport_timestamp: clock::Lamport, lamport_timestamp: clock::Lamport,
}, },
SetActiveSelections { SetActiveSelections {
@ -484,7 +488,7 @@ impl Buffer {
.map(|set| { .map(|set| {
let set_id = clock::Lamport { let set_id = clock::Lamport {
replica_id: set.replica_id as ReplicaId, replica_id: set.replica_id as ReplicaId,
value: set.local_timestamp, value: set.lamport_timestamp,
}; };
let selections: Vec<Selection> = set let selections: Vec<Selection> = set
.selections .selections
@ -510,9 +514,9 @@ impl Buffer {
selections: self selections: self
.selections .selections
.iter() .iter()
.map(|(set_id, set)| proto::SelectionSetSnapshot { .map(|(set_id, set)| proto::SelectionSet {
replica_id: set_id.replica_id as u32, replica_id: set_id.replica_id as u32,
local_timestamp: set_id.value, lamport_timestamp: set_id.value,
selections: set.selections.iter().map(Into::into).collect(), selections: set.selections.iter().map(Into::into).collect(),
is_active: set.active, is_active: set.active,
}) })
@ -849,23 +853,26 @@ impl Buffer {
selections, selections,
lamport_timestamp, lamport_timestamp,
} => { } => {
if let Some(selections) = selections { if let Some(set) = self.selections.get_mut(&set_id) {
if let Some(set) = self.selections.get_mut(&set_id) { set.selections = selections;
set.selections = selections;
} else {
self.selections.insert(
set_id,
SelectionSet {
selections,
active: false,
},
);
}
} else { } else {
self.selections.remove(&set_id); self.selections.insert(
set_id,
SelectionSet {
selections,
active: false,
},
);
} }
self.lamport_clock.observe(lamport_timestamp); self.lamport_clock.observe(lamport_timestamp);
} }
Operation::RemoveSelections {
set_id,
lamport_timestamp,
} => {
self.selections.remove(&set_id);
self.lamport_clock.observe(lamport_timestamp);
}
Operation::SetActiveSelections { Operation::SetActiveSelections {
set_id, set_id,
lamport_timestamp, lamport_timestamp,
@ -1127,16 +1134,13 @@ impl Buffer {
Operation::Edit(edit) => self.version >= edit.version, Operation::Edit(edit) => self.version >= edit.version,
Operation::Undo { undo, .. } => self.version >= undo.version, Operation::Undo { undo, .. } => self.version >= undo.version,
Operation::UpdateSelections { selections, .. } => { Operation::UpdateSelections { selections, .. } => {
if let Some(selections) = selections { selections.iter().all(|selection| {
selections.iter().all(|selection| { let contains_start = self.version >= selection.start.version;
let contains_start = self.version >= selection.start.version; let contains_end = self.version >= selection.end.version;
let contains_end = self.version >= selection.end.version; contains_start && contains_end
contains_start && contains_end })
})
} else {
true
}
} }
Operation::RemoveSelections { .. } => true,
Operation::SetActiveSelections { set_id, .. } => { Operation::SetActiveSelections { set_id, .. } => {
set_id.map_or(true, |set_id| self.selections.contains_key(&set_id)) set_id.map_or(true, |set_id| self.selections.contains_key(&set_id))
} }
@ -1279,7 +1283,7 @@ impl Buffer {
set.selections = selections.clone(); set.selections = selections.clone();
Ok(Operation::UpdateSelections { Ok(Operation::UpdateSelections {
set_id, set_id,
selections: Some(selections), selections,
lamport_timestamp: self.lamport_clock.tick(), lamport_timestamp: self.lamport_clock.tick(),
}) })
} }
@ -1296,7 +1300,7 @@ impl Buffer {
); );
Operation::UpdateSelections { Operation::UpdateSelections {
set_id: lamport_timestamp, set_id: lamport_timestamp,
selections: Some(selections), selections,
lamport_timestamp, lamport_timestamp,
} }
} }
@ -1329,9 +1333,8 @@ impl Buffer {
self.selections self.selections
.remove(&set_id) .remove(&set_id)
.ok_or_else(|| anyhow!("invalid selection set id {:?}", set_id))?; .ok_or_else(|| anyhow!("invalid selection set id {:?}", set_id))?;
Ok(Operation::UpdateSelections { Ok(Operation::RemoveSelections {
set_id, set_id,
selections: None,
lamport_timestamp: self.lamport_clock.tick(), lamport_timestamp: self.lamport_clock.tick(),
}) })
} }
@ -2130,6 +2133,9 @@ impl Operation {
Operation::UpdateSelections { Operation::UpdateSelections {
lamport_timestamp, .. lamport_timestamp, ..
} => *lamport_timestamp, } => *lamport_timestamp,
Operation::RemoveSelections {
lamport_timestamp, ..
} => *lamport_timestamp,
Operation::SetActiveSelections { Operation::SetActiveSelections {
lamport_timestamp, .. lamport_timestamp, ..
} => *lamport_timestamp, } => *lamport_timestamp,
@ -2186,9 +2192,17 @@ impl<'a> Into<proto::Operation> for &'a Operation {
replica_id: set_id.replica_id as u32, replica_id: set_id.replica_id as u32,
local_timestamp: set_id.value, local_timestamp: set_id.value,
lamport_timestamp: lamport_timestamp.value, lamport_timestamp: lamport_timestamp.value,
set: selections.as_ref().map(|selections| proto::SelectionSet { selections: selections.iter().map(Into::into).collect(),
selections: selections.iter().map(Into::into).collect(), },
}), ),
Operation::RemoveSelections {
set_id,
lamport_timestamp,
} => proto::operation::Variant::RemoveSelections(
proto::operation::RemoveSelections {
replica_id: set_id.replica_id as u32,
local_timestamp: set_id.value,
lamport_timestamp: lamport_timestamp.value,
}, },
), ),
Operation::SetActiveSelections { Operation::SetActiveSelections {
@ -2284,16 +2298,11 @@ impl TryFrom<proto::Operation> for Operation {
}, },
}, },
proto::operation::Variant::UpdateSelections(message) => { proto::operation::Variant::UpdateSelections(message) => {
let selections: Option<Vec<Selection>> = if let Some(set) = message.set { let selections: Vec<Selection> = message
Some( .selections
set.selections .into_iter()
.into_iter() .map(TryFrom::try_from)
.map(TryFrom::try_from) .collect::<Result<_, _>>()?;
.collect::<Result<_, _>>()?,
)
} else {
None
};
Operation::UpdateSelections { Operation::UpdateSelections {
set_id: clock::Lamport { set_id: clock::Lamport {
replica_id: message.replica_id as ReplicaId, replica_id: message.replica_id as ReplicaId,
@ -2303,7 +2312,19 @@ impl TryFrom<proto::Operation> for Operation {
replica_id: message.replica_id as ReplicaId, replica_id: message.replica_id as ReplicaId,
value: message.lamport_timestamp, value: message.lamport_timestamp,
}, },
selections: selections.map(Arc::from), selections: Arc::from(selections),
}
}
proto::operation::Variant::RemoveSelections(message) => {
Operation::RemoveSelections {
set_id: clock::Lamport {
replica_id: message.replica_id as ReplicaId,
value: message.local_timestamp,
},
lamport_timestamp: clock::Lamport {
replica_id: message.replica_id as ReplicaId,
value: message.lamport_timestamp,
},
} }
} }
proto::operation::Variant::SetActiveSelections(message) => { proto::operation::Variant::SetActiveSelections(message) => {

View File

@ -227,18 +227,14 @@ message Buffer {
uint64 id = 1; uint64 id = 1;
string content = 2; string content = 2;
repeated Operation.Edit history = 3; repeated Operation.Edit history = 3;
repeated SelectionSetSnapshot selections = 4; repeated SelectionSet selections = 4;
}
message SelectionSetSnapshot {
uint32 replica_id = 1;
uint32 local_timestamp = 2;
repeated Selection selections = 3;
bool is_active = 4;
} }
message SelectionSet { message SelectionSet {
repeated Selection selections = 1; uint32 replica_id = 1;
uint32 lamport_timestamp = 2;
repeated Selection selections = 3;
bool is_active = 4;
} }
message Selection { message Selection {
@ -263,7 +259,8 @@ message Operation {
Edit edit = 1; Edit edit = 1;
Undo undo = 2; Undo undo = 2;
UpdateSelections update_selections = 3; UpdateSelections update_selections = 3;
SetActiveSelections set_active_selections = 4; RemoveSelections remove_selections = 4;
SetActiveSelections set_active_selections = 5;
} }
message Edit { message Edit {
@ -294,7 +291,13 @@ message Operation {
uint32 replica_id = 1; uint32 replica_id = 1;
uint32 local_timestamp = 2; uint32 local_timestamp = 2;
uint32 lamport_timestamp = 3; uint32 lamport_timestamp = 3;
SelectionSet set = 4; repeated Selection selections = 4;
}
message RemoveSelections {
uint32 replica_id = 1;
uint32 local_timestamp = 2;
uint32 lamport_timestamp = 3;
} }
message SetActiveSelections { message SetActiveSelections {