diff --git a/crates/fuzz/src/container/tree.rs b/crates/fuzz/src/container/tree.rs index 9130b6f0..f65def69 100644 --- a/crates/fuzz/src/container/tree.rs +++ b/crates/fuzz/src/container/tree.rs @@ -399,6 +399,7 @@ impl TreeTracker { ) { let node = TreeNode::new(target, *parent, position); if let Some(parent) = parent { + trace!("Parent {:?} target {:?}", parent, target); let parent = self.find_node_by_id_mut(*parent).unwrap(); parent.children.insert(*index, node); } else { diff --git a/crates/fuzz/tests/test.rs b/crates/fuzz/tests/test.rs index a86d9c86..10b1f15a 100644 --- a/crates/fuzz/tests/test.rs +++ b/crates/fuzz/tests/test.rs @@ -11620,6 +11620,112 @@ fn trimmed_fuzz_unknown() { ) } +#[test] +fn tree_event_parent_not_found() { + test_multi_sites( + 5, + vec![FuzzTarget::All], + &mut [ + Handle { + site: 7, + target: 7, + container: 7, + action: Generic(GenericAction { + value: I32(117901063), + bool: true, + key: 117901063, + pos: 506381209866536711, + length: 506381209882330885, + prop: 506381209866536711, + }), + }, + Handle { + site: 7, + target: 7, + container: 7, + action: Generic(GenericAction { + value: I32(-15635199), + bool: false, + key: 4294967057, + pos: 506381209866536849, + length: 506381209866536711, + prop: 506381209866536711, + }), + }, + Handle { + site: 7, + target: 7, + container: 7, + action: Generic(GenericAction { + value: I32(1633771873), + bool: true, + key: 828465505, + pos: 13382931975044184514, + length: 13382931975044184546, + prop: 13382931975044184546, + }), + }, + Sync { from: 97, to: 97 }, + Handle { + site: 248, + target: 97, + container: 97, + action: Generic(GenericAction { + value: I32(1633771873), + bool: true, + key: 1633771873, + pos: 7016996765293437281, + length: 7016996765293437281, + prop: 7016996765293437281, + }), + }, + Handle { + site: 7, + target: 7, + container: 7, + action: Generic(GenericAction { + value: I32(587663111), + bool: true, + key: 117901063, + pos: 506381209866536711, + length: 7, + prop: 506381209866536708, + }), + }, + Handle { + site: 7, + target: 7, + container: 7, + action: Generic(GenericAction { + value: I32(117901063), + bool: true, + key: 1799, + pos: 831200004273078272, + length: 18374686478597949846, + prop: 506381209866597582, + }), + }, + Handle { + site: 7, + target: 7, + container: 35, + action: Generic(GenericAction { + value: I32(117901063), + bool: true, + key: 1633771783, + pos: 7016996765293437281, + length: 281480905449825, + prop: 7016996765293437281, + }), + }, + Undo { + site: 97, + op_len: 1633771873, + }, + ], + ) +} + #[test] fn minify() { minify_error( diff --git a/crates/loro-internal/src/state/tree_state.rs b/crates/loro-internal/src/state/tree_state.rs index bc2a3c0d..0a008c3a 100644 --- a/crates/loro-internal/src/state/tree_state.rs +++ b/crates/loro-internal/src/state/tree_state.rs @@ -1052,6 +1052,14 @@ impl ContainerState for TreeState { TreeInternalDiff::Create { parent, position } => { self.mov(target, *parent, last_move_op, Some(position.clone()), false) .unwrap(); + + if let TreeParentId::Node(p) = parent { + // reuse diff cache, at this time,it's "move in deleted" + if self.is_node_deleted(p).unwrap() { + continue; + } + } + let index = self.get_index_by_tree_id(&target).unwrap(); ans.push(TreeDiffItem { target, @@ -1112,6 +1120,13 @@ impl ContainerState for TreeState { self.mov(target, *parent, last_move_op, Some(position.clone()), false) .unwrap(); + if let TreeParentId::Node(p) = parent { + // reuse diff cache, at this time,it's "move in deleted" + if self.is_node_deleted(p).unwrap() { + continue; + } + } + let index = self.get_index_by_tree_id(&target).unwrap(); match was_alive { true => { diff --git a/crates/loro-internal/src/undo.rs b/crates/loro-internal/src/undo.rs index 03e639f5..a43d804c 100644 --- a/crates/loro-internal/src/undo.rs +++ b/crates/loro-internal/src/undo.rs @@ -789,6 +789,8 @@ pub(crate) fn undo( calc_diff(&this_id_span.id_last().into(), this_deps) }); + // println!("event_a_i: {:?}", event_a_i); + // --------------------------------------- // 2. Calc event B_i // --------------------------------------- @@ -806,6 +808,8 @@ pub(crate) fn undo( stack_diff_batch.as_ref().unwrap() }; + // println!("event_b_i: {:?}", event_b_i); + // event_a_prime can undo the ops in the current span and the previous spans let mut event_a_prime = if let Some(mut last_ci) = last_ci.take() { // ------------------------------------------------------------------------------ @@ -826,6 +830,8 @@ pub(crate) fn undo( // -------------------------------------------------- event_a_prime.transform(event_b_i, true); + // println!("event_a_prime: {:?}", event_a_prime); + let c_i = event_a_prime; last_ci = Some(c_i); });