From 6dcd9d19e842f2c95b67b047cfb2491dbdb41ba9 Mon Sep 17 00:00:00 2001 From: Zixuan Chen Date: Fri, 21 Oct 2022 22:28:39 +0800 Subject: [PATCH] fix: change deps bug --- crates/loro-core/src/change.rs | 4 +- .../src/container/text/text_container.rs | 2 +- crates/loro-core/src/fuzz.rs | 26 +++++------ crates/loro-core/src/log_store.rs | 46 +++++++++++++------ crates/loro-core/src/macros.rs | 2 +- 5 files changed, 49 insertions(+), 31 deletions(-) diff --git a/crates/loro-core/src/change.rs b/crates/loro-core/src/change.rs index e2e06e4b..25788b22 100644 --- a/crates/loro-core/src/change.rs +++ b/crates/loro-core/src/change.rs @@ -106,9 +106,7 @@ impl Mergable for Change { return false; } - if other.deps.is_empty() - || (other.deps.len() == 1 && self.id.is_connected_id(&other.deps[0], self.len())) - { + if other.deps.is_empty() || !(other.deps.len() == 1 && self.last_id() == other.deps[0]) { return false; } diff --git a/crates/loro-core/src/container/text/text_container.rs b/crates/loro-core/src/container/text/text_container.rs index 9a4e6643..981f2619 100644 --- a/crates/loro-core/src/container/text/text_container.rs +++ b/crates/loro-core/src/container/text/text_container.rs @@ -167,7 +167,7 @@ impl Container for TextContainer { "Stage1 retreat:{} forward:{}\n{}", format!("{:?}", &iter.retreat).red(), format!("{:?}", &iter.forward).red(), - // format!("{:#?}", &change).blue(), + format!("{:#?}", &change).blue(), ); for op in change.ops.iter() { if op.container == self.id { diff --git a/crates/loro-core/src/fuzz.rs b/crates/loro-core/src/fuzz.rs index 797f43d8..79261765 100644 --- a/crates/loro-core/src/fuzz.rs +++ b/crates/loro-core/src/fuzz.rs @@ -291,7 +291,7 @@ pub fn test_multi_sites(site_num: u8, mut actions: Vec) { for action in actions.iter_mut() { sites.preprocess(action); applied.push(action.clone()); - println!("{}", (&applied).table()); + debug_log!("{}", (&applied).table()); sites.apply_action(action); } @@ -308,24 +308,24 @@ mod test { use super::*; #[test] - fn test_two_1() { + fn test_two_change_deps_issue() { test_multi_sites( 2, vec![ Ins { - content: "1".into(), - pos: 0, - site: 0, - }, - Sync { from: 0, to: 1 }, - Del { - pos: 0, - len: 1, - site: 1, + content: "12345".into(), + pos: 281479272970938, + site: 21, }, Ins { - content: "2".into(), - pos: 1, + content: "67890".into(), + pos: 17870294359908942010, + site: 248, + }, + Sync { from: 1, to: 0 }, + Ins { + content: "abc".into(), + pos: 186, site: 0, }, ], diff --git a/crates/loro-core/src/log_store.rs b/crates/loro-core/src/log_store.rs index 27d4a16a..da6f9584 100644 --- a/crates/loro-core/src/log_store.rs +++ b/crates/loro-core/src/log_store.rs @@ -106,7 +106,7 @@ impl LogStore { { check_import_change_valid(&change); // TODO: cache pending changes - assert!(change.deps.iter().all(|x| self_vv.includes_id(*x))); + assert!(change.deps.iter().all(|x| self.vv().includes_id(*x))); self.apply_remote_change(change) } } @@ -182,28 +182,51 @@ impl LogStore { &self.frontier } + fn update_frontier(&mut self, clear: &[ID], new: &[ID]) { + self.frontier.retain(|x| { + !clear + .iter() + .any(|y| x.client_id == y.client_id && x.counter <= y.counter) + && !new + .iter() + .any(|y| x.client_id == y.client_id && x.counter <= y.counter) + }); + for next in new.iter() { + if self + .frontier + .iter() + .any(|x| x.client_id == next.client_id && x.counter >= next.counter) + { + continue; + } + + self.frontier.push(*next); + } + } + /// this method would not get the container and apply op pub fn append_local_ops(&mut self, ops: Vec) { + if ops.is_empty() { + return; + } + let lamport = self.next_lamport(); let timestamp = (self.cfg.get_time)(); let id = ID { client_id: self.this_client_id, counter: self.get_next_counter(self.this_client_id), }; + let last_id = ops.last().unwrap().id_last(); let change = Change { id, + deps: std::mem::replace(&mut self.frontier, smallvec::smallvec![last_id]), ops: ops.into(), - deps: std::mem::take(&mut self.frontier), lamport, timestamp, freezed: false, break_points: Default::default(), }; - self.frontier.push(ID::new( - self.this_client_id, - id.counter + change.len() as Counter - 1, - )); self.latest_lamport = lamport + change.len() as u32 - 1; self.latest_timestamp = timestamp; self.vv.set_end(change.id_end()); @@ -211,6 +234,8 @@ impl LogStore { .entry(self.this_client_id) .or_insert_with(RleVec::new) .push(change); + + debug_log!("CHANGES---------------- site {}", self.this_client_id); } pub fn apply_remote_change(&mut self, mut change: Change) { @@ -239,14 +264,9 @@ impl LogStore { container.apply(change.id_span(), self); } + drop(container_manager); self.vv.set_end(change.id_end()); - self.frontier = self - .frontier - .iter() - .filter(|x| !change.deps.contains(x)) - .copied() - .collect(); - self.frontier.push(change.last_id()); + self.update_frontier(&change.deps, &[change.last_id()]); if change.last_lamport() > self.latest_lamport { self.latest_lamport = change.last_lamport(); diff --git a/crates/loro-core/src/macros.rs b/crates/loro-core/src/macros.rs index f427779b..d2faba86 100644 --- a/crates/loro-core/src/macros.rs +++ b/crates/loro-core/src/macros.rs @@ -30,7 +30,7 @@ macro_rules! debug_log { }; ($($arg:tt)*) => {{ if cfg!(test) { - // use colored::Colorize; + use colored::Colorize; // print!("{}:{}\t", file!().purple(), line!().to_string().purple()); // println!($($arg)*); }