Skip to content

Commit 0749d74

Browse files
committed
add GranularDiff{,Strings} functions
1 parent bf079ce commit 0749d74

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

diff.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
2127
type strings struct{ a, b string }
2228

2329
func (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

5056
func (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
5484
func Diff(n, m int, data Data) []Change {

0 commit comments

Comments
 (0)