From 082fb5f2fcb057e25c0982b68643b6c413fafa4b Mon Sep 17 00:00:00 2001 From: Markus Zimmermann Date: Sat, 29 Oct 2016 21:55:33 +0200 Subject: [PATCH 1/4] Test case to confirm that a timeout of 0 does not alter the patch outcome Closes #28 --- diffmatchpatch/dmp_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/diffmatchpatch/dmp_test.go b/diffmatchpatch/dmp_test.go index 7d64b6e..5630beb 100644 --- a/diffmatchpatch/dmp_test.go +++ b/diffmatchpatch/dmp_test.go @@ -1259,6 +1259,14 @@ func Test_patch_make(t *testing.T) { patches = dmp.PatchMake("2016-09-01T03:07:14.807830741Z", "2016-09-01T03:07:15.154800781Z") assert.Equal(t, "@@ -15,16 +15,16 @@\n 07:1\n+5.15\n 4\n-.\n 80\n+0\n 78\n-3074\n 1Z\n", dmp.PatchToText(patches), "patch_make: Corner case of #31 fixed by #32") + + text1 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ut risus et enim consectetur convallis a non ipsum. Sed nec nibh cursus, interdum libero vel." + text2 = "Lorem a ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ut risus et enim consectetur convallis a non ipsum. Sed nec nibh cursus, interdum liberovel." + dmp2 := New() + dmp2.DiffTimeout = 0 + diffs = dmp2.DiffMain(text1, text2, true) + patches = dmp2.PatchMake(text1, diffs) + assert.Equal(t, "@@ -1,14 +1,16 @@\n Lorem \n+a \n ipsum do\n@@ -148,13 +148,12 @@\n m libero\n- \n vel.\n", dmp2.PatchToText(patches), "patch_make: Corner case of #28 wrong patch with timeout of 0") } func Test_PatchSplitMax(t *testing.T) { From f2030ee2ca1aac352276bfc5ef859f264ddfc06b Mon Sep 17 00:00:00 2001 From: Markus Zimmermann Date: Sat, 29 Oct 2016 22:00:39 +0200 Subject: [PATCH 2/4] Refactor, remove diffMain DiffMain has no purpose anymore since it uses diffMainRunes as well, so we can just remove diffMain. --- diffmatchpatch/dmp.go | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/diffmatchpatch/dmp.go b/diffmatchpatch/dmp.go index 9c41a49..2f6daf6 100644 --- a/diffmatchpatch/dmp.go +++ b/diffmatchpatch/dmp.go @@ -250,17 +250,7 @@ func New() *DiffMatchPatch { // DiffMain finds the differences between two texts. func (dmp *DiffMatchPatch) DiffMain(text1, text2 string, checklines bool) []Diff { - var deadline time.Time - if dmp.DiffTimeout <= 0 { - deadline = time.Now().Add(24 * 365 * time.Hour) - } else { - deadline = time.Now().Add(dmp.DiffTimeout) - } - return dmp.diffMain(text1, text2, checklines, deadline) -} - -func (dmp *DiffMatchPatch) diffMain(text1, text2 string, checklines bool, deadline time.Time) []Diff { - return dmp.diffMainRunes([]rune(text1), []rune(text2), checklines, deadline) + return dmp.DiffMainRunes([]rune(text1), []rune(text2), checklines) } // DiffMainRunes finds the differences between two rune sequences. @@ -406,7 +396,7 @@ func (dmp *DiffMatchPatch) diffLineMode(text1, text2 []rune, deadline time.Time) countDelete+countInsert) pointer = pointer - countDelete - countInsert - a := dmp.diffMain(textDelete, textInsert, false, deadline) + a := dmp.diffMainRunes([]rune(textDelete), []rune(textInsert), false, deadline) for j := len(a) - 1; j >= 0; j-- { diffs = splice(diffs, pointer, 0, a[j]) } From 8bdce7a9b9fc6c63d33cfe9e71501bd4b653ab60 Mon Sep 17 00:00:00 2001 From: Markus Zimmermann Date: Sat, 29 Oct 2016 22:10:51 +0200 Subject: [PATCH 3/4] Introduce a note that diffLineMode is faster using strings than rune slices. --- diffmatchpatch/dmp.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/diffmatchpatch/dmp.go b/diffmatchpatch/dmp.go index 2f6daf6..c8ff9d2 100644 --- a/diffmatchpatch/dmp.go +++ b/diffmatchpatch/dmp.go @@ -377,6 +377,8 @@ func (dmp *DiffMatchPatch) diffLineMode(text1, text2 []rune, deadline time.Time) pointer := 0 countDelete := 0 countInsert := 0 + + // NOTE: Rune slices are slower than using strings in this case. textDelete := "" textInsert := "" From dc653857757538de2928ea9011940d0b3e5f3993 Mon Sep 17 00:00:00 2001 From: Markus Zimmermann Date: Sat, 29 Oct 2016 22:29:32 +0200 Subject: [PATCH 4/4] Fix, timeout of 0 was not a timeout of "infinity". --- diffmatchpatch/dmp.go | 6 ++---- diffmatchpatch/dmp_test.go | 11 +++++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/diffmatchpatch/dmp.go b/diffmatchpatch/dmp.go index c8ff9d2..af1a34c 100644 --- a/diffmatchpatch/dmp.go +++ b/diffmatchpatch/dmp.go @@ -256,9 +256,7 @@ func (dmp *DiffMatchPatch) DiffMain(text1, text2 string, checklines bool) []Diff // DiffMainRunes finds the differences between two rune sequences. func (dmp *DiffMatchPatch) DiffMainRunes(text1, text2 []rune, checklines bool) []Diff { var deadline time.Time - if dmp.DiffTimeout <= 0 { - deadline = time.Now().Add(24 * 365 * time.Hour) - } else { + if dmp.DiffTimeout > 0 { deadline = time.Now().Add(dmp.DiffTimeout) } return dmp.diffMainRunes(text1, text2, checklines, deadline) @@ -456,7 +454,7 @@ func (dmp *DiffMatchPatch) diffBisect(runes1, runes2 []rune, deadline time.Time) k2end := 0 for d := 0; d < maxD; d++ { // Bail out if deadline is reached. - if time.Now().After(deadline) { + if !deadline.IsZero() && time.Now().After(deadline) { break } diff --git a/diffmatchpatch/dmp_test.go b/diffmatchpatch/dmp_test.go index 5630beb..bbfeae9 100644 --- a/diffmatchpatch/dmp_test.go +++ b/diffmatchpatch/dmp_test.go @@ -907,18 +907,21 @@ func Test_diffBisect(t *testing.T) { // Since the resulting diff hasn't been normalized, it would be ok if // the insertion and deletion pairs are swapped. // If the order changes, tweak this test as required. - diffs := []Diff{ + correctDiffs := []Diff{ Diff{DiffDelete, "c"}, Diff{DiffInsert, "m"}, Diff{DiffEqual, "a"}, Diff{DiffDelete, "t"}, Diff{DiffInsert, "p"}} - assertDiffEqual(t, diffs, dmp.DiffBisect(a, b, time.Date(9999, time.December, 31, 23, 59, 59, 59, time.UTC))) + assertDiffEqual(t, correctDiffs, dmp.DiffBisect(a, b, time.Date(9999, time.December, 31, 23, 59, 59, 59, time.UTC))) // Timeout. - diffs = []Diff{Diff{DiffDelete, "cat"}, Diff{DiffInsert, "map"}} - assertDiffEqual(t, diffs, dmp.DiffBisect(a, b, time.Date(0001, time.January, 01, 00, 00, 00, 00, time.UTC))) + diffs := []Diff{Diff{DiffDelete, "cat"}, Diff{DiffInsert, "map"}} + assertDiffEqual(t, diffs, dmp.DiffBisect(a, b, time.Now().Add(time.Nanosecond))) + + // Negative deadlines count as having infinite time. + assertDiffEqual(t, correctDiffs, dmp.DiffBisect(a, b, time.Date(0001, time.January, 01, 00, 00, 00, 00, time.UTC))) } func Test_diffMain(t *testing.T) {