@@ -18,6 +18,12 @@ func Strings(a, b string) []Change {
1818 return Diff (len (a ), len (b ), & strings {a , b })
1919}
2020
21+ // GranularStrings returns the differences of two strings larger
22+ // than the specified granularity.
23+ func GranularStrings (a , b string , granularity int ) []Change {
24+ return GranularDiff (len (a ), len (b ), & strings {a , b }, granularity )
25+ }
26+
2127type strings struct { a , b string }
2228
2329func (d * strings ) Equal (i , j int ) bool { return d .a [i ] == d .b [j ] }
@@ -49,6 +55,30 @@ type runes struct{ a, b []rune }
4955
5056func (d * runes ) Equal (i , j int ) bool { return d .a [i ] == d .b [j ] }
5157
58+ // GranularDiff returns differences in data with all neighboring change
59+ // sequences smaller than the specified granularity merged.
60+ // data.Equal is called repeatedly with 0<=i<n and 0<=j<m
61+ func GranularDiff (n , m int , data Data , granularity int ) []Change {
62+ diffs := Diff (n , m , data )
63+ if diffs == nil {
64+ return nil
65+ }
66+ gap := 0
67+ for i := 1 ; i < len (diffs ); i ++ {
68+ change := diffs [i ]
69+ pchange := diffs [i - gap - 1 ]
70+ // same as change.B-(pchange.B+pchange.Ins); consistency is key
71+ if change .A - (pchange .A + pchange .Del ) <= granularity {
72+ // merge changes: start at same spot, Del from first to end of second, Ins from first to end of second.
73+ change = Change {A : pchange .A , B : pchange .B ,
74+ Del : change .A - pchange .A + change .Del , Ins : change .B - pchange .B + change .Ins }
75+ gap ++
76+ }
77+ diffs [i - gap ] = change
78+ }
79+ return diffs [:len (diffs )- gap : len (diffs )- gap ]
80+ }
81+
5282// Diff returns the differences of data.
5383// data.Equal is called repeatedly with 0<=i<n and 0<=j<m
5484func Diff (n , m int , data Data ) []Change {
0 commit comments