fix: resolve LORO-766

This commit is contained in:
Zixuan Chen 2024-07-24 15:44:48 +08:00
parent 3d516a3e18
commit 618c38c7b9
No known key found for this signature in database
2 changed files with 25 additions and 6 deletions

View file

@ -177,7 +177,7 @@ impl std::fmt::Debug for OpLog {
}
}
pub(crate) struct EnsureChangeDepsAreAtTheEnd;
pub(crate) struct EnsureDagNodeDepsAreAtTheEnd;
impl OpLog {
#[inline]
@ -240,7 +240,7 @@ impl OpLog {
}
/// This is the **only** place to update the `OpLog.changes`
pub(crate) fn insert_new_change(&mut self, change: Change, _: EnsureChangeDepsAreAtTheEnd) {
pub(crate) fn insert_new_change(&mut self, change: Change, _: EnsureDagNodeDepsAreAtTheEnd) {
self.op_groups.insert_by_change(&change);
self.change_store.insert_change(change.clone());
self.register_container_and_parent_link(&change);
@ -291,7 +291,7 @@ impl OpLog {
pub(crate) fn update_dag_on_new_change(
&mut self,
change: &Change,
) -> EnsureChangeDepsAreAtTheEnd {
) -> EnsureDagNodeDepsAreAtTheEnd {
let len = change.content_len();
if change.deps_on_self() {
// don't need to push new element to dag because it only depends on itself
@ -344,11 +344,19 @@ impl OpLog {
let target = self.dag.get_mut(*dep).unwrap();
if target.ctr_last() == dep.counter {
target.has_succ = true;
} else {
// We need to split the target node into two part
// so that we can ensure the new change depends on the
// last id of a dag node.
let new_node =
target.slice(dep.counter as usize - target.cnt as usize, target.len);
target.len -= new_node.len;
self.dag.map.insert(new_node.id_start(), new_node);
}
}
}
EnsureChangeDepsAreAtTheEnd
EnsureDagNodeDepsAreAtTheEnd
}
/// Trim the known part of change

View file

@ -7,6 +7,7 @@ use crate::id::{Counter, ID};
use crate::span::{HasId, HasLamport};
use crate::version::{Frontiers, ImVersionVector, VersionVector};
use loro_common::{HasCounter, HasCounterSpan, HasIdSpan};
use once_cell::sync::OnceCell;
use rle::{HasIndex, HasLength, Mergable, Sliceable};
use super::{AppDag, AppDagNode};
@ -28,8 +29,18 @@ impl Sliceable for AppDagNode {
peer: self.peer,
cnt: self.cnt + from as Counter,
lamport: self.lamport + from as Lamport,
deps: Default::default(),
vv: Default::default(),
deps: if from > 0 {
Frontiers::from_id(self.id_start().inc(from as Counter - 1))
} else {
self.deps.clone()
},
vv: if let Some(vv) = self.vv.get() {
let mut new = vv.clone();
new.insert(self.peer, self.cnt + from as Counter);
OnceCell::with_value(new)
} else {
OnceCell::new()
},
has_succ: if to == self.len { self.has_succ } else { true },
len: to - from,
}