mirror of
https://github.com/loro-dev/loro.git
synced 2025-01-22 12:57:20 +00:00
fix: movable list undo del impl
This commit is contained in:
parent
ba7c1b7b94
commit
f4823191e7
2 changed files with 156 additions and 22 deletions
|
@ -12782,6 +12782,132 @@ fn movable_list_undo_impl() {
|
|||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn movable_list_undo_impl_1() {
|
||||
test_multi_sites(
|
||||
5,
|
||||
vec![FuzzTarget::All],
|
||||
&mut [
|
||||
Handle {
|
||||
site: 29,
|
||||
target: 29,
|
||||
container: 6,
|
||||
action: Generic(GenericAction {
|
||||
value: Container(Text),
|
||||
bool: false,
|
||||
key: 4292569563,
|
||||
pos: 15492342490870120406,
|
||||
length: 18446519864200508159,
|
||||
prop: 10161246657334578573,
|
||||
}),
|
||||
},
|
||||
Handle {
|
||||
site: 167,
|
||||
target: 129,
|
||||
container: 4,
|
||||
action: Generic(GenericAction {
|
||||
value: Container(Map),
|
||||
bool: true,
|
||||
key: 123736320,
|
||||
pos: 12898264252198542080,
|
||||
length: 15789862182697904091,
|
||||
prop: 18446618237837639456,
|
||||
}),
|
||||
},
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
Handle {
|
||||
site: 0,
|
||||
target: 24,
|
||||
container: 24,
|
||||
action: Generic(GenericAction {
|
||||
value: I32(-65536),
|
||||
bool: true,
|
||||
key: 4009754624,
|
||||
pos: 17221764975752642560,
|
||||
length: 7421932185895899375,
|
||||
prop: 18446744073709551474,
|
||||
}),
|
||||
},
|
||||
Handle {
|
||||
site: 128,
|
||||
target: 81,
|
||||
container: 43,
|
||||
action: Generic(GenericAction {
|
||||
value: Container(Text),
|
||||
bool: true,
|
||||
key: 757935366,
|
||||
pos: 7627690425558565057,
|
||||
length: 15810408764199600091,
|
||||
prop: 3752949689037608703,
|
||||
}),
|
||||
},
|
||||
SyncAllUndo {
|
||||
site: 108,
|
||||
op_len: 2365849344,
|
||||
},
|
||||
Handle {
|
||||
site: 167,
|
||||
target: 129,
|
||||
container: 4,
|
||||
action: Generic(GenericAction {
|
||||
value: Container(Map),
|
||||
bool: true,
|
||||
key: 123736320,
|
||||
pos: 12838591557135883008,
|
||||
length: 15789862182697904091,
|
||||
prop: 18446618237837639456,
|
||||
}),
|
||||
},
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
Handle {
|
||||
site: 0,
|
||||
target: 24,
|
||||
container: 24,
|
||||
action: Generic(GenericAction {
|
||||
value: I32(-65536),
|
||||
bool: true,
|
||||
key: 4009754624,
|
||||
pos: 17221764975752642560,
|
||||
length: 7421932185895899375,
|
||||
prop: 18446744073709551474,
|
||||
}),
|
||||
},
|
||||
Handle {
|
||||
site: 128,
|
||||
target: 79,
|
||||
container: 43,
|
||||
action: Generic(GenericAction {
|
||||
value: Container(Text),
|
||||
bool: false,
|
||||
key: 4612,
|
||||
pos: 6293508899878207488,
|
||||
length: 185600485263537,
|
||||
prop: 8169935443840729235,
|
||||
}),
|
||||
},
|
||||
Checkout {
|
||||
site: 147,
|
||||
to: 2067994371,
|
||||
},
|
||||
SyncAllUndo {
|
||||
site: 0,
|
||||
op_len: 3318087425,
|
||||
},
|
||||
Sync { from: 197, to: 35 },
|
||||
SyncAllUndo {
|
||||
site: 151,
|
||||
op_len: 2543294359,
|
||||
},
|
||||
Undo {
|
||||
site: 1,
|
||||
op_len: 4250350213,
|
||||
},
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn minify() {
|
||||
minify_error(
|
||||
|
|
|
@ -78,11 +78,15 @@ impl MovableListHandler {
|
|||
let mut index_shift = 0;
|
||||
let mut deleted_indices = Vec::new();
|
||||
let mut next_deleted = BinaryHeap::new();
|
||||
// - positive values are retain
|
||||
// - negative values are deletions
|
||||
let mut delta_change: Vec<isize> = Vec::new();
|
||||
|
||||
for delta_item in delta.iter() {
|
||||
match delta_item {
|
||||
loro_delta::DeltaItem::Retain { len, .. } => {
|
||||
index += len;
|
||||
delta_change.push(*len as isize);
|
||||
}
|
||||
loro_delta::DeltaItem::Replace {
|
||||
value,
|
||||
|
@ -90,13 +94,16 @@ impl MovableListHandler {
|
|||
attr,
|
||||
} => {
|
||||
// Handle deletions in the current replace operation.
|
||||
let old_index = index;
|
||||
self.handle_deletions_in_replace(
|
||||
*delete,
|
||||
&mut index,
|
||||
index_shift,
|
||||
&mut next_deleted,
|
||||
);
|
||||
delta_change.push(-((index - old_index) as isize));
|
||||
|
||||
let old_index = index;
|
||||
// Process the insertions and moves.
|
||||
let mut context = ReplacementContext {
|
||||
index: &mut index,
|
||||
|
@ -109,12 +116,13 @@ impl MovableListHandler {
|
|||
|
||||
self.process_replacements(value, attr, &mut context)
|
||||
.unwrap();
|
||||
delta_change.push((index - old_index) as isize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply any remaining deletions.
|
||||
self.apply_remaining_deletions(&delta, &mut deleted_indices)
|
||||
self.apply_remaining_deletions(delta_change, &mut deleted_indices)
|
||||
.unwrap();
|
||||
|
||||
Ok(())
|
||||
|
@ -162,7 +170,8 @@ impl MovableListHandler {
|
|||
to_delete
|
||||
}
|
||||
|
||||
/// Handles deletions within a replace operation.
|
||||
/// Handles deletions' effect on the index within a replace operation.
|
||||
/// It will not perform the deletions.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
|
@ -268,25 +277,27 @@ impl MovableListHandler {
|
|||
/// * `deleted_indices` - A list of indices that have been deleted.
|
||||
fn apply_remaining_deletions(
|
||||
&self,
|
||||
delta: &loro_delta::DeltaRope<
|
||||
loro_delta::array_vec::ArrayVec<ValueOrHandler, 8>,
|
||||
crate::event::ListDeltaMeta,
|
||||
>,
|
||||
delta: Vec<isize>,
|
||||
deleted_indices: &mut Vec<usize>,
|
||||
) -> LoroResult<()> {
|
||||
// Sort deleted indices from largest to smallest.
|
||||
deleted_indices.sort_by_key(|&x| std::cmp::Reverse(x));
|
||||
|
||||
let mut index = 0;
|
||||
let mut index: usize = 0;
|
||||
for delta_item in delta.iter() {
|
||||
match delta_item {
|
||||
loro_delta::DeltaItem::Retain { len, .. } => {
|
||||
index += len;
|
||||
match *delta_item {
|
||||
x if x > 0 => {
|
||||
index += x as usize;
|
||||
}
|
||||
loro_delta::DeltaItem::Replace { delete, value, .. } => {
|
||||
if *delete > 0 {
|
||||
let mut remaining_deletes = *delete;
|
||||
neg_delete => {
|
||||
let delete = neg_delete.unsigned_abs();
|
||||
let mut remaining_deletes = delete;
|
||||
while let Some(&last) = deleted_indices.last() {
|
||||
if last < index {
|
||||
deleted_indices.pop();
|
||||
continue;
|
||||
}
|
||||
|
||||
if last < index + remaining_deletes {
|
||||
deleted_indices.pop();
|
||||
remaining_deletes -= 1;
|
||||
|
@ -297,9 +308,6 @@ impl MovableListHandler {
|
|||
|
||||
self.delete(index, remaining_deletes)?;
|
||||
}
|
||||
|
||||
index += value.len();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue