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};
|
use utils::{slice_str, calculate_ratio};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
@@ -207,6 +207,68 @@ impl<'a> SequenceMatcher<'a>{
|
|||||||
return self.opcodes.as_ref().unwrap().clone()
|
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{
|
pub fn ratio(&mut self) -> f32{
|
||||||
let matches = self.get_matching_blocks().iter().fold(0, |res, &m| res + m.size);
|
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())
|
calculate_ratio(matches, self.first_sequence.len() + self.second_sequence.len())
|
||||||
|
|||||||
Reference in New Issue
Block a user