Remove break_up_raw_operations
This commit is contained in:
parent
b230d34b88
commit
2b78f0c76f
6 changed files with 61 additions and 52 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
//! Taken from <https://github.com/mitsuhiko/similar/blob/7e15c44de11a1cd61e1149189929e189ef977fd8/src/algorithms/myers.rs>
|
//! Taken from <https://github.com/mitsuhiko/similar/blob/7e15c44de11a1cd61e1149189929e189ef977fd8/src/algorithms/myers.rs>
|
||||||
|
//!
|
||||||
//! Myers' diff algorithm.
|
//! Myers' diff algorithm.
|
||||||
//!
|
//!
|
||||||
//! * time: `O((N+M)D)`
|
//! * time: `O((N+M)D)`
|
||||||
|
|
@ -34,8 +35,7 @@ use crate::{
|
||||||
/// Diff `old`, between indices `old_range` and `new` between indices
|
/// Diff `old`, between indices `old_range` and `new` between indices
|
||||||
/// `new_range`.
|
/// `new_range`.
|
||||||
///
|
///
|
||||||
/// This diff is done with an optional deadline that defines the maximal
|
/// The returned RawOperations all have a token count of 1.
|
||||||
/// execution time permitted before it bails and falls back to an approximation.
|
|
||||||
pub fn diff<T>(old: &[Token<T>], new: &[Token<T>]) -> Vec<RawOperation<T>>
|
pub fn diff<T>(old: &[Token<T>], new: &[Token<T>]) -> Vec<RawOperation<T>>
|
||||||
where
|
where
|
||||||
T: PartialEq + Clone + std::fmt::Debug,
|
T: PartialEq + Clone + std::fmt::Debug,
|
||||||
|
|
@ -44,6 +44,7 @@ where
|
||||||
let mut vb = V::new(max_d);
|
let mut vb = V::new(max_d);
|
||||||
let mut vf = V::new(max_d);
|
let mut vf = V::new(max_d);
|
||||||
let mut result: Vec<RawOperation<T>> = vec![];
|
let mut result: Vec<RawOperation<T>> = vec![];
|
||||||
|
|
||||||
conquer(
|
conquer(
|
||||||
old,
|
old,
|
||||||
0..old.len(),
|
0..old.len(),
|
||||||
|
|
@ -53,6 +54,12 @@ where
|
||||||
&mut vb,
|
&mut vb,
|
||||||
&mut result,
|
&mut result,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
debug_assert!(
|
||||||
|
result.iter().all(|op| op.tokens().len() == 1),
|
||||||
|
"All operations should be of length 1"
|
||||||
|
);
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,9 +241,11 @@ fn conquer<T>(
|
||||||
// Check for common prefix
|
// Check for common prefix
|
||||||
let common_prefix_len = common_prefix_len(old, old_range.clone(), new, new_range.clone());
|
let common_prefix_len = common_prefix_len(old, old_range.clone(), new, new_range.clone());
|
||||||
if common_prefix_len > 0 {
|
if common_prefix_len > 0 {
|
||||||
result.push(RawOperation::Equal(
|
result.extend(
|
||||||
old[old_range.start..old_range.start + common_prefix_len].to_vec(),
|
old[old_range.start..old_range.start + common_prefix_len]
|
||||||
));
|
.iter()
|
||||||
|
.map(|token| RawOperation::Equal(vec![token.clone()])),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
old_range.start += common_prefix_len;
|
old_range.start += common_prefix_len;
|
||||||
new_range.start += common_prefix_len;
|
new_range.start += common_prefix_len;
|
||||||
|
|
@ -251,15 +260,19 @@ fn conquer<T>(
|
||||||
new_range.end -= common_suffix_len;
|
new_range.end -= common_suffix_len;
|
||||||
|
|
||||||
if old_range.is_empty() && new_range.is_empty() {
|
if old_range.is_empty() && new_range.is_empty() {
|
||||||
// Do nothing
|
// do nothing
|
||||||
} else if new_range.is_empty() {
|
} else if new_range.is_empty() {
|
||||||
result.push(RawOperation::Delete(
|
result.extend(
|
||||||
old[old_range.start..old_range.start + old_range.len()].to_vec(),
|
old[old_range.start..old_range.start + old_range.len()]
|
||||||
));
|
.iter()
|
||||||
|
.map(|token| RawOperation::Delete(vec![token.clone()])),
|
||||||
|
)
|
||||||
} else if old_range.is_empty() {
|
} else if old_range.is_empty() {
|
||||||
result.push(RawOperation::Insert(
|
result.extend(
|
||||||
new[new_range.start..new_range.start + new_range.len()].to_vec(),
|
new[new_range.start..new_range.start + new_range.len()]
|
||||||
));
|
.iter()
|
||||||
|
.map(|token| RawOperation::Insert(vec![token.clone()])),
|
||||||
|
)
|
||||||
} else if let Some((x_start, y_start)) =
|
} else if let Some((x_start, y_start)) =
|
||||||
find_middle_snake(old, old_range.clone(), new, new_range.clone(), vf, vb)
|
find_middle_snake(old, old_range.clone(), new, new_range.clone(), vf, vb)
|
||||||
{
|
{
|
||||||
|
|
@ -268,18 +281,24 @@ fn conquer<T>(
|
||||||
conquer(old, old_a, new, new_a, vf, vb, result);
|
conquer(old, old_a, new, new_a, vf, vb, result);
|
||||||
conquer(old, old_b, new, new_b, vf, vb, result);
|
conquer(old, old_b, new, new_b, vf, vb, result);
|
||||||
} else {
|
} else {
|
||||||
result.push(RawOperation::Delete(
|
result.extend(
|
||||||
old[old_range.start..old_range.end].to_vec(),
|
old[old_range.start..old_range.end]
|
||||||
));
|
.iter()
|
||||||
result.push(RawOperation::Insert(
|
.map(|token| RawOperation::Delete(vec![token.clone()])),
|
||||||
new[new_range.start..new_range.end].to_vec(),
|
);
|
||||||
));
|
result.extend(
|
||||||
|
new[new_range.start..new_range.end]
|
||||||
|
.iter()
|
||||||
|
.map(|token| RawOperation::Insert(vec![token.clone()])),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if common_suffix_len > 0 {
|
if common_suffix_len > 0 {
|
||||||
result.push(RawOperation::Equal(
|
result.extend(
|
||||||
old[common_suffix.0..common_suffix.0 + common_suffix_len].to_vec(),
|
old[common_suffix.0..common_suffix.0 + common_suffix_len]
|
||||||
));
|
.iter()
|
||||||
|
.map(|token| RawOperation::Equal(vec![token.clone()])),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,10 @@ snapshot_kind: text
|
||||||
is_left_joinable: true,
|
is_left_joinable: true,
|
||||||
is_right_joinable: true,
|
is_right_joinable: true,
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Delete(
|
||||||
|
[
|
||||||
Token {
|
Token {
|
||||||
normalised: "b",
|
normalised: "b",
|
||||||
original: "b",
|
original: "b",
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,20 @@ snapshot_kind: text
|
||||||
is_left_joinable: true,
|
is_left_joinable: true,
|
||||||
is_right_joinable: true,
|
is_right_joinable: true,
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Equal(
|
||||||
|
[
|
||||||
Token {
|
Token {
|
||||||
normalised: "b",
|
normalised: "b",
|
||||||
original: "b",
|
original: "b",
|
||||||
is_left_joinable: true,
|
is_left_joinable: true,
|
||||||
is_right_joinable: true,
|
is_right_joinable: true,
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Equal(
|
||||||
|
[
|
||||||
Token {
|
Token {
|
||||||
normalised: "c",
|
normalised: "c",
|
||||||
original: "c",
|
original: "c",
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,10 @@ snapshot_kind: text
|
||||||
is_left_joinable: true,
|
is_left_joinable: true,
|
||||||
is_right_joinable: true,
|
is_right_joinable: true,
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Insert(
|
||||||
|
[
|
||||||
Token {
|
Token {
|
||||||
normalised: "b",
|
normalised: "b",
|
||||||
original: "b",
|
original: "b",
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,10 @@ snapshot_kind: text
|
||||||
is_left_joinable: true,
|
is_left_joinable: true,
|
||||||
is_right_joinable: true,
|
is_right_joinable: true,
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Delete(
|
||||||
|
[
|
||||||
Token {
|
Token {
|
||||||
normalised: "c",
|
normalised: "c",
|
||||||
original: "c",
|
original: "c",
|
||||||
|
|
|
||||||
|
|
@ -63,41 +63,11 @@ where
|
||||||
|
|
||||||
Self::new(
|
Self::new(
|
||||||
original,
|
original,
|
||||||
Self::cook_operations(Self::elongate_operations(Self::break_up_raw_operations(
|
Self::cook_operations(Self::elongate_operations(diff)).collect(),
|
||||||
diff,
|
|
||||||
)))
|
|
||||||
.collect(),
|
|
||||||
updated.cursors,
|
updated.cursors,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn break_up_raw_operations<I>(raw_operations: I) -> impl Iterator<Item = RawOperation<T>>
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = RawOperation<T>>,
|
|
||||||
{
|
|
||||||
raw_operations.into_iter().flat_map(|raw_operation| {
|
|
||||||
let mut result: Vec<RawOperation<T>> = Vec::new();
|
|
||||||
match raw_operation {
|
|
||||||
RawOperation::Insert(tokens) => {
|
|
||||||
for token in tokens {
|
|
||||||
result.push(RawOperation::Insert(vec![token]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RawOperation::Delete(tokens) => {
|
|
||||||
for token in tokens {
|
|
||||||
result.push(RawOperation::Delete(vec![token]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RawOperation::Equal(tokens) => {
|
|
||||||
for token in tokens {
|
|
||||||
result.push(RawOperation::Equal(vec![token]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.into_iter()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn elongate_operations<I>(raw_operations: I) -> Vec<RawOperation<T>>
|
fn elongate_operations<I>(raw_operations: I) -> Vec<RawOperation<T>>
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = RawOperation<T>>,
|
I: IntoIterator<Item = RawOperation<T>>,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue