Skip to content

Commit 019493f

Browse files
authored
Remove LevEditType::Keep variant (#27)
1 parent 319b1c3 commit 019493f

File tree

2 files changed

+32
-66
lines changed

2 files changed

+32
-66
lines changed

src/diff.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ pub fn diff_code(
133133
right_diff.push(ObjInsDiff::default());
134134
cur_left = left_iter.next();
135135
}
136-
LevEditType::Keep => unreachable!(),
137136
}
138137
} else {
139138
break;
@@ -511,13 +510,12 @@ fn diff_data(left: &mut ObjSection, right: &mut ObjSection) {
511510
let mut right_diff = Vec::<ObjDataDiff>::new();
512511
let mut left_cur = 0usize;
513512
let mut right_cur = 0usize;
514-
let mut cur_op = LevEditType::Keep;
513+
let mut cur_op = LevEditType::Replace;
515514
let mut cur_left_data = Vec::<u8>::new();
516515
let mut cur_right_data = Vec::<u8>::new();
517516
for op in edit_ops {
518517
if cur_op != op.op_type || left_cur < op.first_start || right_cur < op.second_start {
519518
match cur_op {
520-
LevEditType::Keep => {}
521519
LevEditType::Replace => {
522520
let left_data = take(&mut cur_left_data);
523521
let right_data = take(&mut cur_right_data);
@@ -603,7 +601,6 @@ fn diff_data(left: &mut ObjSection, right: &mut ObjSection) {
603601
cur_left_data.push(left.data[left_cur]);
604602
left_cur += 1;
605603
}
606-
LevEditType::Keep => unreachable!(),
607604
}
608605
cur_op = op.op_type;
609606
}
@@ -627,7 +624,6 @@ fn diff_data(left: &mut ObjSection, right: &mut ObjSection) {
627624

628625
// TODO: merge with above
629626
match cur_op {
630-
LevEditType::Keep => {}
631627
LevEditType::Replace => {
632628
let left_data = take(&mut cur_left_data);
633629
let right_data = take(&mut cur_right_data);

src/editops.rs

Lines changed: 31 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727

2828
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
2929
pub enum LevEditType {
30-
Keep,
3130
Replace,
3231
Insert,
3332
Delete,
@@ -77,19 +76,10 @@ where T: PartialEq {
7776
cache_matrix[current + 1 + p] = x;
7877
}
7978
}
80-
editops_from_cost_matrix(
81-
first_string,
82-
second_string,
83-
matrix_columns,
84-
matrix_rows,
85-
prefix_len,
86-
cache_matrix,
87-
)
79+
editops_from_cost_matrix::<T>(matrix_columns, matrix_rows, prefix_len, cache_matrix)
8880
}
8981

9082
fn editops_from_cost_matrix<T>(
91-
string1: &[T],
92-
string2: &[T],
9383
len1: usize,
9484
len2: usize,
9585
prefix_len: usize,
@@ -98,77 +88,57 @@ fn editops_from_cost_matrix<T>(
9888
where
9989
T: PartialEq,
10090
{
91+
let mut ops = Vec::with_capacity(cache_matrix[len1 * len2 - 1]);
10192
let mut dir = 0;
102-
103-
let mut ops: Vec<LevEditOp> = vec![];
104-
ops.reserve(cache_matrix[len1 * len2 - 1]);
105-
10693
let mut i = len1 - 1;
10794
let mut j = len2 - 1;
10895
let mut p = len1 * len2 - 1;
10996

110-
// let string1_chars: Vec<char> = string1.chars().collect();
111-
// let string2_chars: Vec<char> = string2.chars().collect();
112-
11397
//TODO this is still pretty ugly
11498
while i > 0 || j > 0 {
11599
let current_value = cache_matrix[p];
116100

117-
let op_type;
118-
119-
if dir == -1 && j > 0 && current_value == cache_matrix[p - 1] + 1 {
120-
op_type = LevEditType::Insert;
121-
} else if dir == 1 && i > 0 && current_value == cache_matrix[p - len2] + 1 {
122-
op_type = LevEditType::Delete;
123-
} else if i > 0
124-
&& j > 0
125-
&& current_value == cache_matrix[p - len2 - 1]
126-
&& string1[i - 1] == string2[j - 1]
127-
{
128-
op_type = LevEditType::Keep;
129-
} else if i > 0 && j > 0 && current_value == cache_matrix[p - len2 - 1] + 1 {
130-
op_type = LevEditType::Replace;
131-
}
132-
/* we can't turn directly from -1 to 1, in this case it would be better
133-
* to go diagonally, but check it (dir == 0) */
134-
else if dir == 0 && j > 0 && current_value == cache_matrix[p - 1] + 1 {
135-
op_type = LevEditType::Insert;
136-
} else if dir == 0 && i > 0 && current_value == cache_matrix[p - len2] + 1 {
137-
op_type = LevEditType::Delete;
138-
} else {
139-
panic!("something went terribly wrong");
140-
}
101+
// More than one operation can be possible at a time. We use `dir` to
102+
// decide when ambiguous.
103+
let is_insert = j > 0 && current_value == cache_matrix[p - 1] + 1;
104+
let is_delete = i > 0 && current_value == cache_matrix[p - len2] + 1;
105+
let is_replace = i > 0 && j > 0 && current_value == cache_matrix[p - len2 - 1] + 1;
106+
107+
let (op_type, new_dir) = match (dir, is_insert, is_delete, is_replace) {
108+
(_, false, false, false) => (None, 0),
109+
(-1, true, _, _) => (Some(LevEditType::Insert), -1),
110+
(1, _, true, _) => (Some(LevEditType::Delete), 1),
111+
(_, _, _, true) => (Some(LevEditType::Replace), 0),
112+
(0, true, _, _) => (Some(LevEditType::Insert), -1),
113+
(0, _, true, _) => (Some(LevEditType::Delete), 1),
114+
_ => panic!("something went terribly wrong"),
115+
};
141116

142-
match op_type {
143-
LevEditType::Insert => {
117+
match new_dir {
118+
-1 => {
144119
j -= 1;
145120
p -= 1;
146-
dir = -1;
147121
}
148-
LevEditType::Delete => {
122+
1 => {
149123
i -= 1;
150124
p -= len2;
151-
dir = 1;
152125
}
153-
LevEditType::Replace => {
126+
0 => {
154127
i -= 1;
155128
j -= 1;
156129
p -= len2 + 1;
157-
dir = 0;
158-
}
159-
LevEditType::Keep => {
160-
i -= 1;
161-
j -= 1;
162-
p -= len2 + 1;
163-
dir = 0;
164-
/* LevEditKeep does not has to be stored */
165-
continue;
166130
}
131+
_ => panic!("something went terribly wrong"),
167132
};
168-
169-
let edit_op =
170-
LevEditOp { op_type, first_start: i + prefix_len, second_start: j + prefix_len };
171-
ops.insert(0, edit_op);
133+
dir = new_dir;
134+
135+
if let Some(op_type) = op_type {
136+
ops.insert(0, LevEditOp {
137+
op_type,
138+
first_start: i + prefix_len,
139+
second_start: j + prefix_len,
140+
});
141+
}
172142
}
173143

174144
ops

0 commit comments

Comments
 (0)