diff --git a/crates/loro-internal/src/version.rs b/crates/loro-internal/src/version.rs index 13385e5e..4788e154 100644 --- a/crates/loro-internal/src/version.rs +++ b/crates/loro-internal/src/version.rs @@ -901,226 +901,6 @@ pub fn are_frontiers_eq(a: &[ID], b: &[ID]) -> bool { a == b } -#[derive(Debug, Default)] -pub struct PatchedVersionVector { - pub base: Arc, - pub patch: VersionVector, -} - -impl Clone for PatchedVersionVector { - fn clone(&self) -> Self { - Self { - base: Arc::clone(&self.base), - patch: self.patch.clone(), - } - } -} - -impl From for VersionVector { - fn from(mut v: PatchedVersionVector) -> Self { - for (client_id, counter) in v.base.iter() { - if v.patch.contains_key(client_id) { - continue; - } - - v.patch.set_last(ID::new(*client_id, *counter)); - } - - v.patch - } -} - -impl PatchedVersionVector { - #[inline] - pub fn new(base: Arc) -> Self { - Self { - base, - patch: Default::default(), - } - } - - #[inline] - pub fn is_empty(&self) -> bool { - self.patch.is_empty() && self.base.is_empty() - } - - pub fn from_version(base: &Arc, version: &VersionVector) -> Self { - let mut patch = VersionVector::new(); - for (client_id, counter) in version.iter() { - if let Some(base_counter) = base.get(client_id) { - if *base_counter != *counter { - patch.set_end(ID::new(*client_id, *counter)); - } - } else { - patch.set_end(ID::new(*client_id, *counter)); - } - } - - if cfg!(debug_assertions) { - for (client_id, counter) in base.iter() { - if let Some(patch_counter) = version.get(client_id) { - assert!(*patch_counter >= *counter); - } else { - unreachable!("base should be a subset of version"); - } - } - } - - Self { - base: Arc::clone(base), - patch, - } - } - - #[inline] - pub fn extend_to_include_last_id(&mut self, id: ID) { - self.patch.extend_to_include_last_id(id); - self.omit_if_needless(id.peer); - } - - #[inline] - pub fn set_end(&mut self, id: ID) { - self.patch.set_end(id); - self.omit_if_needless(id.peer); - } - - #[inline] - pub fn set_last(&mut self, id: ID) { - self.patch.set_last(id); - self.omit_if_needless(id.peer); - } - - #[inline] - pub fn extend_to_include(&mut self, span: IdSpan) { - self.patch.extend_to_include(span); - self.omit_if_needless(span.peer); - } - - #[inline] - pub fn shrink_to_exclude(&mut self, span: IdSpan) { - self.patch.shrink_to_exclude(span); - self.omit_if_needless(span.peer); - } - - #[inline] - pub fn forward(&mut self, spans: &IdSpanVector) { - for span in spans.iter() { - let span = IdSpan { - peer: *span.0, - counter: *span.1, - }; - - if let Some(counter) = self.patch.get_mut(&span.peer) { - if *counter < span.counter.norm_end() { - *counter = span.counter.norm_end(); - self.omit_if_needless(span.peer); - } - } else { - let target = span.counter.norm_end(); - if self.base.get(&span.peer) == Some(&target) { - continue; - } - - self.patch.insert(span.peer, target); - } - } - } - - #[inline] - pub fn retreat(&mut self, spans: &IdSpanVector) { - for span in spans.iter() { - let span = IdSpan { - peer: *span.0, - counter: *span.1, - }; - - if let Some(counter) = self.patch.get_mut(&span.peer) { - if *counter > span.counter.min() { - *counter = span.counter.min(); - self.omit_if_needless(span.peer); - } - } - } - } - - #[inline(always)] - fn omit_if_needless(&mut self, client_id: PeerID) { - if let Some(patch_value) = self.patch.get(&client_id) { - if *patch_value == *self.base.get(&client_id).unwrap_or(&0) { - self.patch.remove(&client_id); - } - } - } - - #[inline] - pub fn get(&self, client_id: &PeerID) -> Option<&Counter> { - self.patch - .get(client_id) - .or_else(|| self.base.get(client_id)) - } - - #[inline] - pub fn insert(&mut self, client_id: PeerID, counter: Counter) { - self.patch.insert(client_id, counter); - self.omit_if_needless(client_id); - } - - #[inline] - pub fn includes_id(&self, id: ID) -> bool { - self.patch.includes_id(id) || self.base.includes_id(id) - } - - pub fn iter(&self) -> impl Iterator { - self.patch.iter().chain( - self.base - .iter() - .filter(|(client_id, _)| !self.patch.contains_key(client_id)), - ) - } - - pub fn sub_iter<'a>(&'a self, rhs: &'a Self) -> impl Iterator + 'a { - if !Arc::ptr_eq(&self.base, &rhs.base) { - unimplemented!(); - } - - self.patch.sub_iter(&rhs.patch) - } - - pub fn diff_iter<'a>( - &'a self, - rhs: &'a Self, - ) -> ( - impl Iterator + 'a, - impl Iterator + 'a, - ) { - if !Arc::ptr_eq(&self.base, &rhs.base) { - unimplemented!(); - } - - self.patch.diff_iter(&rhs.patch) - } -} - -impl PartialEq for PatchedVersionVector { - fn eq(&self, other: &Self) -> bool { - if Arc::ptr_eq(&self.base, &other.base) { - self.patch.eq(&other.patch) - } else { - self.base == other.base && self.patch == other.patch - } - } -} - -impl PartialOrd for PatchedVersionVector { - fn partial_cmp(&self, other: &Self) -> Option { - if Arc::ptr_eq(&self.base, &other.base) || self.base == other.base { - self.patch.partial_cmp(&other.patch) - } else { - None - } - } -} - #[cfg(test)] mod tests { #![allow(clippy::neg_cmp_op_on_partial_ord)]