mirror of
https://github.com/loro-dev/loro.git
synced 2025-01-22 21:07:43 +00:00
fix: resolve LORO-766
This commit is contained in:
parent
3d516a3e18
commit
618c38c7b9
2 changed files with 25 additions and 6 deletions
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue