Remove LevEditType::Keep variant (#27)

This commit is contained in:
Nick Condron 2023-01-22 13:20:50 -05:00 committed by GitHub
parent 319b1c35c0
commit 019493f944
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 75 deletions

View File

@ -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);

View File

@ -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