From 43a88b17b2f5e0405beff3d55ef5cdb7e6f09d10 Mon Sep 17 00:00:00 2001 From: Dima Kudosh Date: Thu, 18 Feb 2016 13:59:47 +0300 Subject: [PATCH] Add function to get grouping opcodes for sequence matcher struct --- src/sequencematcher.rs | 64 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/src/sequencematcher.rs b/src/sequencematcher.rs index 127455b..f924f47 100644 --- a/src/sequencematcher.rs +++ b/src/sequencematcher.rs @@ -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> { + 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())