mirror of
https://github.com/loro-dev/loro.git
synced 2025-01-22 21:07:43 +00:00
Fix partial inclusion bug in Tracker (#214)
* fix: partial inclusion bug in Tracker * fix: rm redundant logs
This commit is contained in:
parent
33d06d5cd8
commit
699c2c73a5
3 changed files with 43 additions and 15 deletions
|
@ -72,8 +72,7 @@ impl Tracker {
|
|||
pub(crate) fn insert(&mut self, mut op_id: ID, mut pos: usize, mut content: RichtextChunk) {
|
||||
let last_id = op_id.inc(content.len() as Counter - 1);
|
||||
let applied_counter_end = self.applied_vv.get(&last_id.peer).copied().unwrap_or(0);
|
||||
if applied_counter_end > last_id.counter {
|
||||
// the op is included in the applied vv
|
||||
if applied_counter_end > op_id.counter {
|
||||
if !self.current_vv.includes_id(last_id) {
|
||||
// PERF: may be slow
|
||||
let mut updates = Default::default();
|
||||
|
@ -87,9 +86,13 @@ impl Tracker {
|
|||
);
|
||||
self.batch_update(updates, false);
|
||||
}
|
||||
return;
|
||||
} else if applied_counter_end > op_id.counter {
|
||||
// need to slice the content
|
||||
|
||||
if applied_counter_end > last_id.counter {
|
||||
// the op is included in the applied vv
|
||||
return;
|
||||
}
|
||||
|
||||
// the op is partially included, need to slice the content
|
||||
let start = (applied_counter_end - op_id.counter) as usize;
|
||||
op_id.counter = applied_counter_end;
|
||||
pos += start;
|
||||
|
@ -137,8 +140,7 @@ impl Tracker {
|
|||
pub(crate) fn delete(&mut self, mut op_id: ID, mut pos: usize, mut len: usize, reverse: bool) {
|
||||
let last_id = op_id.inc(len as Counter - 1);
|
||||
let applied_counter_end = self.applied_vv.get(&last_id.peer).copied().unwrap_or(0);
|
||||
if applied_counter_end > last_id.counter {
|
||||
// the op is included in the applied_vv
|
||||
if applied_counter_end > op_id.counter {
|
||||
if !self.current_vv.includes_id(last_id) {
|
||||
// PERF: may be slow
|
||||
let mut updates = Default::default();
|
||||
|
@ -148,9 +150,12 @@ impl Tracker {
|
|||
);
|
||||
self.batch_update(updates, false);
|
||||
}
|
||||
return;
|
||||
} else if applied_counter_end > op_id.counter {
|
||||
// need to slice the op
|
||||
|
||||
if applied_counter_end > last_id.counter {
|
||||
return;
|
||||
}
|
||||
|
||||
// the op is partially included, need to slice the op
|
||||
let start = (applied_counter_end - op_id.counter) as usize;
|
||||
op_id.counter = applied_counter_end;
|
||||
len -= start;
|
||||
|
@ -176,7 +181,6 @@ impl Tracker {
|
|||
|
||||
let mut cur_id = op_id;
|
||||
for id_span in ans {
|
||||
debug_log::debug_dbg!(&cur_id, id_span, reverse);
|
||||
let len = id_span.atom_len();
|
||||
self.id_to_cursor
|
||||
.push(cur_id, id_to_cursor::Cursor::Delete(id_span));
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
pub(super) mod tree;
|
||||
use debug_log::debug_dbg;
|
||||
use itertools::Itertools;
|
||||
pub(crate) use tree::TreeDeletedSetTrait;
|
||||
pub(super) use tree::TreeDiffCache;
|
||||
|
@ -76,7 +75,6 @@ impl DiffCalculator {
|
|||
after: &crate::VersionVector,
|
||||
after_frontiers: Option<&Frontiers>,
|
||||
) -> Vec<InternalContainerDiff> {
|
||||
debug_dbg!(&before, &after, &oplog);
|
||||
if self.has_all {
|
||||
let include_before = self.last_vv.includes_vv(before);
|
||||
let include_after = self.last_vv.includes_vv(after);
|
||||
|
@ -724,7 +722,6 @@ impl DiffCalculatorTrait for RichtextDiffCalculator {
|
|||
|
||||
// FIXME: handle new containers when inserting richtext style like comments
|
||||
|
||||
// debug_log::debug_dbg!(&delta, from, to);
|
||||
// debug_log::debug_dbg!(&self.tracker);
|
||||
InternalDiff::RichtextRaw(delta)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::sync::{atomic::AtomicBool, Arc, Mutex};
|
||||
|
||||
use loro_common::{ContainerID, ContainerType, LoroValue, ID};
|
||||
use loro_common::{ContainerID, ContainerType, LoroResult, LoroValue, ID};
|
||||
use loro_internal::{
|
||||
container::richtext::TextStyleInfoFlag,
|
||||
handler::{Handler, ValueOrContainer},
|
||||
|
@ -9,6 +9,33 @@ use loro_internal::{
|
|||
};
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn issue_211() -> LoroResult<()> {
|
||||
let doc1 = LoroDoc::new_auto_commit();
|
||||
let doc2 = LoroDoc::new_auto_commit();
|
||||
doc1.get_text("text").insert(0, "T")?;
|
||||
doc2.merge(&doc1)?;
|
||||
let v0 = doc1.oplog_frontiers();
|
||||
doc1.get_text("text").insert(1, "A")?;
|
||||
doc2.get_text("text").insert(1, "B")?;
|
||||
doc1.checkout(&v0)?;
|
||||
doc2.checkout(&v0)?;
|
||||
doc1.checkout_to_latest();
|
||||
doc2.checkout_to_latest();
|
||||
// let v1_of_doc1 = doc1.oplog_frontiers();
|
||||
let v1_of_doc2 = doc2.oplog_frontiers();
|
||||
doc2.get_text("text").insert(2, "B")?;
|
||||
doc2.checkout(&v1_of_doc2)?;
|
||||
doc2.checkout(&v0)?;
|
||||
assert_eq!(
|
||||
doc2.get_deep_value().to_json_value(),
|
||||
json!({
|
||||
"text": "T"
|
||||
})
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mark_with_the_same_key_value_should_be_skipped() {
|
||||
let a = LoroDoc::new_auto_commit();
|
||||
|
|
Loading…
Reference in a new issue