// Diff computes the difference between old and new. A granularity of 1 or more // combines changes with no greater than that many bytes between them. func Diff(old, new []byte, granularity int) (patch []byte) { changes := diff.Bytes(old, new) if granularity > 0 { changes = diff.Granular(granularity, changes) } for i, c := range changes { a, b := c.A, c.B for _, prev := range changes[:i] { if prev.A < c.A { a -= prev.Del a += prev.Ins } if prev.B < c.B { b -= prev.Ins b += prev.Del } } patch = writeUvarint(patch, a) patch = writeUvarint(patch, b) patch = writeUvarint(patch, c.Del) patch = append(patch, old[c.A:c.A+c.Del]...) patch = writeUvarint(patch, c.Ins) patch = append(patch, new[c.B:c.B+c.Ins]...) } return }
func BenchmarkDiffBytes(b *testing.B) { d1 := []byte("lorem ipsum dolor sit amet consectetur") d2 := []byte("lorem lovesum daenerys targaryen ami consecteture") for i := 0; i < b.N; i++ { diff.Bytes(d1, d2) } }
// diffops diffs data and returns ops func (doc *otdoc) diffops(data []byte) ot.Ops { change := diff.Bytes(([]byte)(*doc.Doc), data) if len(change) == 0 { return nil } ops := make(ot.Ops, 0, len(change)*2) var ret, del, ins int for _, c := range change { if r := c.A - ret - del; r > 0 { ops = append(ops, ot.Op{N: r}) ret = c.A - del } if c.Del > 0 { ops = append(ops, ot.Op{N: -c.Del}) del += c.Del } if c.Ins > 0 { ops = append(ops, ot.Op{S: string(data[c.B : c.B+c.Ins])}) ins += c.Ins } } if r := len(data) - ret - ins; r > 0 { ops = append(ops, ot.Op{N: r}) } if del > 0 || ins > 0 { return ot.Merge(ops) } return nil }
func byteDiff(a, b []byte) []byte { var buf bytes.Buffer n := 0 for _, c := range diff.Granular(1, diff.Bytes(a, b)) { buf.Write(b[n:c.B]) if c.Ins > 0 { buf.Write(colorize(b[c.B : c.B+c.Ins])) } n = c.B + c.Ins } buf.Write(b[n:]) return buf.Bytes() }