Add function to get grouping opcodes for sequence matcher struct
This commit is contained in:
+63
-1
@@ -1,4 +1,4 @@
|
||||
use std::cmp::Ordering;
|
||||
use std::cmp::{Ordering, max, min};
|
||||
use utils::{slice_str, calculate_ratio};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@@ -207,6 +207,68 @@ impl<'a> SequenceMatcher<'a>{
|
||||
return self.opcodes.as_ref().unwrap().clone()
|
||||
}
|
||||
|
||||
/*
|
||||
codes = self.get_opcodes()
|
||||
if not codes:
|
||||
codes = [("equal", 0, 1, 0, 1)]
|
||||
# Fixup leading and trailing groups if they show no changes.
|
||||
if codes[0][0] == 'equal':
|
||||
tag, i1, i2, j1, j2 = codes[0]
|
||||
codes[0] = tag, max(i1, i2-n), i2, max(j1, j2-n), j2
|
||||
if codes[-1][0] == 'equal':
|
||||
tag, i1, i2, j1, j2 = codes[-1]
|
||||
codes[-1] = tag, i1, min(i2, i1+n), j1, min(j2, j1+n)
|
||||
|
||||
nn = n + n
|
||||
group = []
|
||||
for tag, i1, i2, j1, j2 in codes:
|
||||
# End the current group and start a new one whenever
|
||||
# there is a large range with no changes.
|
||||
if tag == 'equal' and i2-i1 > nn:
|
||||
group.append((tag, i1, min(i2, i1+n), j1, min(j2, j1+n)))
|
||||
yield group
|
||||
group = []
|
||||
i1, j1 = max(i1, i2-n), max(j1, j2-n)
|
||||
group.append((tag, i1, i2, j1 ,j2))
|
||||
if group and not (len(group)==1 and group[0][0] == 'equal'):
|
||||
yield group
|
||||
*/
|
||||
pub fn get_grouped_opcodes(&mut self, n: usize) -> Vec<Vec<Opcode>> {
|
||||
let mut res = Vec::new();
|
||||
let mut codes = self.get_opcodes();
|
||||
if codes.is_empty() {
|
||||
codes.push(Opcode::new("equal".to_string(), 0, 1, 0, 1));
|
||||
}
|
||||
if codes.first().unwrap().tag == "equal" {
|
||||
let mut opcode = codes.first_mut().unwrap();
|
||||
opcode.first_start = max(opcode.first_start, opcode.first_end - n);
|
||||
opcode.second_start = max(opcode.second_start, opcode.second_end - n);
|
||||
}
|
||||
if codes.last().unwrap().tag == "equal" {
|
||||
let mut opcode = codes.last_mut().unwrap();
|
||||
opcode.first_end = min(opcode.first_start + n, opcode.first_end);
|
||||
opcode.second_end = min(opcode.second_start + n, opcode.second_end);
|
||||
}
|
||||
let nn = n + n;
|
||||
let mut group = Vec::new();
|
||||
for code in &codes {
|
||||
let (mut first_start, mut second_start) = (code.first_start, code.second_start);
|
||||
if code.tag == "equal" && code.first_end-code.first_start > nn {
|
||||
group.push( Opcode::new(code.tag.clone(), code.first_start, min(code.first_end, code.first_start+n),
|
||||
code.second_start, min(code.second_end, code.second_start+n)) );
|
||||
res.push(group.clone());
|
||||
group.clear();
|
||||
first_start = max(first_start, code.first_end-n);
|
||||
second_start = max(second_start, code.second_end - n);
|
||||
}
|
||||
group.push( Opcode::new(code.tag.clone(), first_start, code.first_end, second_start, code.second_end) );
|
||||
}
|
||||
if !group.is_empty() && !(group.len()==1 && group.first().unwrap().tag == "equal") {
|
||||
res.push(group.clone());
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
pub fn ratio(&mut self) -> f32{
|
||||
let matches = self.get_matching_blocks().iter().fold(0, |res, &m| res + m.size);
|
||||
calculate_ratio(matches, self.first_sequence.len() + self.second_sequence.len())
|
||||
|
||||
Reference in New Issue
Block a user