mirror of https://github.com/encounter/objdiff.git
Remove LevEditType::Keep variant (#27)
This commit is contained in:
parent
319b1c35c0
commit
019493f944
|
@ -133,7 +133,6 @@ pub fn diff_code(
|
||||||
right_diff.push(ObjInsDiff::default());
|
right_diff.push(ObjInsDiff::default());
|
||||||
cur_left = left_iter.next();
|
cur_left = left_iter.next();
|
||||||
}
|
}
|
||||||
LevEditType::Keep => unreachable!(),
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -511,13 +510,12 @@ fn diff_data(left: &mut ObjSection, right: &mut ObjSection) {
|
||||||
let mut right_diff = Vec::<ObjDataDiff>::new();
|
let mut right_diff = Vec::<ObjDataDiff>::new();
|
||||||
let mut left_cur = 0usize;
|
let mut left_cur = 0usize;
|
||||||
let mut right_cur = 0usize;
|
let mut right_cur = 0usize;
|
||||||
let mut cur_op = LevEditType::Keep;
|
let mut cur_op = LevEditType::Replace;
|
||||||
let mut cur_left_data = Vec::<u8>::new();
|
let mut cur_left_data = Vec::<u8>::new();
|
||||||
let mut cur_right_data = Vec::<u8>::new();
|
let mut cur_right_data = Vec::<u8>::new();
|
||||||
for op in edit_ops {
|
for op in edit_ops {
|
||||||
if cur_op != op.op_type || left_cur < op.first_start || right_cur < op.second_start {
|
if cur_op != op.op_type || left_cur < op.first_start || right_cur < op.second_start {
|
||||||
match cur_op {
|
match cur_op {
|
||||||
LevEditType::Keep => {}
|
|
||||||
LevEditType::Replace => {
|
LevEditType::Replace => {
|
||||||
let left_data = take(&mut cur_left_data);
|
let left_data = take(&mut cur_left_data);
|
||||||
let right_data = take(&mut cur_right_data);
|
let right_data = take(&mut cur_right_data);
|
||||||
|
@ -603,7 +601,6 @@ fn diff_data(left: &mut ObjSection, right: &mut ObjSection) {
|
||||||
cur_left_data.push(left.data[left_cur]);
|
cur_left_data.push(left.data[left_cur]);
|
||||||
left_cur += 1;
|
left_cur += 1;
|
||||||
}
|
}
|
||||||
LevEditType::Keep => unreachable!(),
|
|
||||||
}
|
}
|
||||||
cur_op = op.op_type;
|
cur_op = op.op_type;
|
||||||
}
|
}
|
||||||
|
@ -627,7 +624,6 @@ fn diff_data(left: &mut ObjSection, right: &mut ObjSection) {
|
||||||
|
|
||||||
// TODO: merge with above
|
// TODO: merge with above
|
||||||
match cur_op {
|
match cur_op {
|
||||||
LevEditType::Keep => {}
|
|
||||||
LevEditType::Replace => {
|
LevEditType::Replace => {
|
||||||
let left_data = take(&mut cur_left_data);
|
let left_data = take(&mut cur_left_data);
|
||||||
let right_data = take(&mut cur_right_data);
|
let right_data = take(&mut cur_right_data);
|
||||||
|
|
110
src/editops.rs
110
src/editops.rs
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
pub enum LevEditType {
|
pub enum LevEditType {
|
||||||
Keep,
|
|
||||||
Replace,
|
Replace,
|
||||||
Insert,
|
Insert,
|
||||||
Delete,
|
Delete,
|
||||||
|
@ -77,19 +76,10 @@ where T: PartialEq {
|
||||||
cache_matrix[current + 1 + p] = x;
|
cache_matrix[current + 1 + p] = x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
editops_from_cost_matrix(
|
editops_from_cost_matrix::<T>(matrix_columns, matrix_rows, prefix_len, cache_matrix)
|
||||||
first_string,
|
|
||||||
second_string,
|
|
||||||
matrix_columns,
|
|
||||||
matrix_rows,
|
|
||||||
prefix_len,
|
|
||||||
cache_matrix,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn editops_from_cost_matrix<T>(
|
fn editops_from_cost_matrix<T>(
|
||||||
string1: &[T],
|
|
||||||
string2: &[T],
|
|
||||||
len1: usize,
|
len1: usize,
|
||||||
len2: usize,
|
len2: usize,
|
||||||
prefix_len: usize,
|
prefix_len: usize,
|
||||||
|
@ -98,77 +88,57 @@ fn editops_from_cost_matrix<T>(
|
||||||
where
|
where
|
||||||
T: PartialEq,
|
T: PartialEq,
|
||||||
{
|
{
|
||||||
|
let mut ops = Vec::with_capacity(cache_matrix[len1 * len2 - 1]);
|
||||||
let mut dir = 0;
|
let mut dir = 0;
|
||||||
|
|
||||||
let mut ops: Vec<LevEditOp> = vec![];
|
|
||||||
ops.reserve(cache_matrix[len1 * len2 - 1]);
|
|
||||||
|
|
||||||
let mut i = len1 - 1;
|
let mut i = len1 - 1;
|
||||||
let mut j = len2 - 1;
|
let mut j = len2 - 1;
|
||||||
let mut p = len1 * len2 - 1;
|
let mut p = len1 * len2 - 1;
|
||||||
|
|
||||||
// let string1_chars: Vec<char> = string1.chars().collect();
|
|
||||||
// let string2_chars: Vec<char> = string2.chars().collect();
|
|
||||||
|
|
||||||
//TODO this is still pretty ugly
|
//TODO this is still pretty ugly
|
||||||
while i > 0 || j > 0 {
|
while i > 0 || j > 0 {
|
||||||
let current_value = cache_matrix[p];
|
let current_value = cache_matrix[p];
|
||||||
|
|
||||||
let op_type;
|
// More than one operation can be possible at a time. We use `dir` to
|
||||||
|
// decide when ambiguous.
|
||||||
|
let is_insert = j > 0 && current_value == cache_matrix[p - 1] + 1;
|
||||||
|
let is_delete = i > 0 && current_value == cache_matrix[p - len2] + 1;
|
||||||
|
let is_replace = i > 0 && j > 0 && current_value == cache_matrix[p - len2 - 1] + 1;
|
||||||
|
|
||||||
if dir == -1 && j > 0 && current_value == cache_matrix[p - 1] + 1 {
|
let (op_type, new_dir) = match (dir, is_insert, is_delete, is_replace) {
|
||||||
op_type = LevEditType::Insert;
|
(_, false, false, false) => (None, 0),
|
||||||
} else if dir == 1 && i > 0 && current_value == cache_matrix[p - len2] + 1 {
|
(-1, true, _, _) => (Some(LevEditType::Insert), -1),
|
||||||
op_type = LevEditType::Delete;
|
(1, _, true, _) => (Some(LevEditType::Delete), 1),
|
||||||
} else if i > 0
|
(_, _, _, true) => (Some(LevEditType::Replace), 0),
|
||||||
&& j > 0
|
(0, true, _, _) => (Some(LevEditType::Insert), -1),
|
||||||
&& current_value == cache_matrix[p - len2 - 1]
|
(0, _, true, _) => (Some(LevEditType::Delete), 1),
|
||||||
&& string1[i - 1] == string2[j - 1]
|
_ => panic!("something went terribly wrong"),
|
||||||
{
|
|
||||||
op_type = LevEditType::Keep;
|
|
||||||
} else if i > 0 && j > 0 && current_value == cache_matrix[p - len2 - 1] + 1 {
|
|
||||||
op_type = LevEditType::Replace;
|
|
||||||
}
|
|
||||||
/* we can't turn directly from -1 to 1, in this case it would be better
|
|
||||||
* to go diagonally, but check it (dir == 0) */
|
|
||||||
else if dir == 0 && j > 0 && current_value == cache_matrix[p - 1] + 1 {
|
|
||||||
op_type = LevEditType::Insert;
|
|
||||||
} else if dir == 0 && i > 0 && current_value == cache_matrix[p - len2] + 1 {
|
|
||||||
op_type = LevEditType::Delete;
|
|
||||||
} else {
|
|
||||||
panic!("something went terribly wrong");
|
|
||||||
}
|
|
||||||
|
|
||||||
match op_type {
|
|
||||||
LevEditType::Insert => {
|
|
||||||
j -= 1;
|
|
||||||
p -= 1;
|
|
||||||
dir = -1;
|
|
||||||
}
|
|
||||||
LevEditType::Delete => {
|
|
||||||
i -= 1;
|
|
||||||
p -= len2;
|
|
||||||
dir = 1;
|
|
||||||
}
|
|
||||||
LevEditType::Replace => {
|
|
||||||
i -= 1;
|
|
||||||
j -= 1;
|
|
||||||
p -= len2 + 1;
|
|
||||||
dir = 0;
|
|
||||||
}
|
|
||||||
LevEditType::Keep => {
|
|
||||||
i -= 1;
|
|
||||||
j -= 1;
|
|
||||||
p -= len2 + 1;
|
|
||||||
dir = 0;
|
|
||||||
/* LevEditKeep does not has to be stored */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let edit_op =
|
match new_dir {
|
||||||
LevEditOp { op_type, first_start: i + prefix_len, second_start: j + prefix_len };
|
-1 => {
|
||||||
ops.insert(0, edit_op);
|
j -= 1;
|
||||||
|
p -= 1;
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
i -= 1;
|
||||||
|
p -= len2;
|
||||||
|
}
|
||||||
|
0 => {
|
||||||
|
i -= 1;
|
||||||
|
j -= 1;
|
||||||
|
p -= len2 + 1;
|
||||||
|
}
|
||||||
|
_ => panic!("something went terribly wrong"),
|
||||||
|
};
|
||||||
|
dir = new_dir;
|
||||||
|
|
||||||
|
if let Some(op_type) = op_type {
|
||||||
|
ops.insert(0, LevEditOp {
|
||||||
|
op_type,
|
||||||
|
first_start: i + prefix_len,
|
||||||
|
second_start: j + prefix_len,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ops
|
ops
|
||||||
|
|
Loading…
Reference in New Issue