Add function to get grouping opcodes for sequence matcher struct

This commit is contained in:
Dima Kudosh
2016-02-18 13:59:47 +03:00
parent 02d2d1762d
commit 43a88b17b2
+63 -1
View File
@@ -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())