diff options
author | Lauris BH <lauris@nix.lv> | 2020-03-17 18:19:58 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-17 12:19:58 -0400 |
commit | 43c09134a972dc421aa06fb303697671c828cf67 (patch) | |
tree | 6bf8da5bc0a23ce516cd5598ec982b6715fb6716 /vendor/github.com/sergi/go-diff | |
parent | 2f928316dbc2bb71137e857d97039d4f51f7d405 (diff) | |
download | gitea-43c09134a972dc421aa06fb303697671c828cf67.tar.gz gitea-43c09134a972dc421aa06fb303697671c828cf67.zip |
Migrate to go-git/go-git v5.0.0 (#10735)
Diffstat (limited to 'vendor/github.com/sergi/go-diff')
-rw-r--r-- | vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go | 141 | ||||
-rw-r--r-- | vendor/github.com/sergi/go-diff/diffmatchpatch/operation_string.go | 17 |
2 files changed, 88 insertions, 70 deletions
diff --git a/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go index 82ad7bc8f1..cb25b43757 100644 --- a/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go +++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go @@ -25,6 +25,8 @@ import ( // Operation defines the operation of a diff item. type Operation int8 +//go:generate stringer -type=Operation -trimprefix=Diff + const ( // DiffDelete item represents a delete diff. DiffDelete Operation = -1 @@ -40,8 +42,41 @@ type Diff struct { Text string } +// splice removes amount elements from slice at index index, replacing them with elements. func splice(slice []Diff, index int, amount int, elements ...Diff) []Diff { - return append(slice[:index], append(elements, slice[index+amount:]...)...) + if len(elements) == amount { + // Easy case: overwrite the relevant items. + copy(slice[index:], elements) + return slice + } + if len(elements) < amount { + // Fewer new items than old. + // Copy in the new items. + copy(slice[index:], elements) + // Shift the remaining items left. + copy(slice[index+len(elements):], slice[index+amount:]) + // Calculate the new end of the slice. + end := len(slice) - amount + len(elements) + // Zero stranded elements at end so that they can be garbage collected. + tail := slice[end:] + for i := range tail { + tail[i] = Diff{} + } + return slice[:end] + } + // More new items than old. + // Make room in slice for new elements. + // There's probably an even more efficient way to do this, + // but this is simple and clear. + need := len(slice) - amount + len(elements) + for len(slice) < need { + slice = append(slice, Diff{}) + } + // Shift slice elements right to make room for new elements. + copy(slice[index+len(elements):], slice[index+amount:]) + // Copy in new elements. + copy(slice[index:], elements) + return slice } // DiffMain finds the differences between two texts. @@ -145,7 +180,10 @@ func (dmp *DiffMatchPatch) diffCompute(text1, text2 []rune, checklines bool, dea diffsA := dmp.diffMainRunes(text1A, text2A, checklines, deadline) diffsB := dmp.diffMainRunes(text1B, text2B, checklines, deadline) // Merge the results. - return append(diffsA, append([]Diff{Diff{DiffEqual, string(midCommon)}}, diffsB...)...) + diffs := diffsA + diffs = append(diffs, Diff{DiffEqual, string(midCommon)}) + diffs = append(diffs, diffsB...) + return diffs } else if checklines && len(text1) > 100 && len(text2) > 100 { return dmp.diffLineMode(text1, text2, deadline) } @@ -247,7 +285,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 !deadline.IsZero() && time.Now().After(deadline) { + if !deadline.IsZero() && d%16 == 0 && time.Now().After(deadline) { break } @@ -434,48 +472,29 @@ func (dmp *DiffMatchPatch) DiffCommonSuffix(text1, text2 string) int { // commonPrefixLength returns the length of the common prefix of two rune slices. func commonPrefixLength(text1, text2 []rune) int { - short, long := text1, text2 - if len(short) > len(long) { - short, long = long, short - } - for i, r := range short { - if r != long[i] { - return i + // Linear search. See comment in commonSuffixLength. + n := 0 + for ; n < len(text1) && n < len(text2); n++ { + if text1[n] != text2[n] { + return n } } - return len(short) + return n } // commonSuffixLength returns the length of the common suffix of two rune slices. func commonSuffixLength(text1, text2 []rune) int { - n := min(len(text1), len(text2)) - for i := 0; i < n; i++ { - if text1[len(text1)-i-1] != text2[len(text2)-i-1] { - return i + // Use linear search rather than the binary search discussed at https://neil.fraser.name/news/2007/10/09/. + // See discussion at https://github.com/sergi/go-diff/issues/54. + i1 := len(text1) + i2 := len(text2) + for n := 0; ; n++ { + i1-- + i2-- + if i1 < 0 || i2 < 0 || text1[i1] != text2[i2] { + return n } } - return n - - // TODO research and benchmark this, why is it not activated? https://github.com/sergi/go-diff/issues/54 - // Binary search. - // Performance analysis: http://neil.fraser.name/news/2007/10/09/ - /* - pointermin := 0 - pointermax := math.Min(len(text1), len(text2)) - pointermid := pointermax - pointerend := 0 - for pointermin < pointermid { - if text1[len(text1)-pointermid:len(text1)-pointerend] == - text2[len(text2)-pointermid:len(text2)-pointerend] { - pointermin = pointermid - pointerend = pointermin - } else { - pointermax = pointermid - } - pointermid = math.Floor((pointermax-pointermin)/2 + pointermin) - } - return pointermid - */ } // DiffCommonOverlap determines if the suffix of one string is the prefix of another. @@ -628,11 +647,7 @@ func (dmp *DiffMatchPatch) diffHalfMatchI(l, s []rune, i int) [][]rune { func (dmp *DiffMatchPatch) DiffCleanupSemantic(diffs []Diff) []Diff { changes := false // Stack of indices where equalities are found. - type equality struct { - data int - next *equality - } - var equalities *equality + equalities := make([]int, 0, len(diffs)) var lastequality string // Always equal to diffs[equalities[equalitiesLength - 1]][1] @@ -645,11 +660,7 @@ func (dmp *DiffMatchPatch) DiffCleanupSemantic(diffs []Diff) []Diff { for pointer < len(diffs) { if diffs[pointer].Type == DiffEqual { // Equality found. - - equalities = &equality{ - data: pointer, - next: equalities, - } + equalities = append(equalities, pointer) lengthInsertions1 = lengthInsertions2 lengthDeletions1 = lengthDeletions2 lengthInsertions2 = 0 @@ -670,23 +681,20 @@ func (dmp *DiffMatchPatch) DiffCleanupSemantic(diffs []Diff) []Diff { (len(lastequality) <= difference1) && (len(lastequality) <= difference2) { // Duplicate record. - insPoint := equalities.data - diffs = append( - diffs[:insPoint], - append([]Diff{Diff{DiffDelete, lastequality}}, diffs[insPoint:]...)...) + insPoint := equalities[len(equalities)-1] + diffs = splice(diffs, insPoint, 0, Diff{DiffDelete, lastequality}) // Change second copy to insert. diffs[insPoint+1].Type = DiffInsert // Throw away the equality we just deleted. - equalities = equalities.next + equalities = equalities[:len(equalities)-1] - if equalities != nil { - equalities = equalities.next + if len(equalities) > 0 { + equalities = equalities[:len(equalities)-1] } - if equalities != nil { - pointer = equalities.data - } else { - pointer = -1 + pointer = -1 + if len(equalities) > 0 { + pointer = equalities[len(equalities)-1] } lengthInsertions1 = 0 // Reset the counters. @@ -724,10 +732,7 @@ func (dmp *DiffMatchPatch) DiffCleanupSemantic(diffs []Diff) []Diff { float64(overlapLength1) >= float64(len(insertion))/2 { // Overlap found. Insert an equality and trim the surrounding edits. - diffs = append( - diffs[:pointer], - append([]Diff{Diff{DiffEqual, insertion[:overlapLength1]}}, diffs[pointer:]...)...) - + diffs = splice(diffs, pointer, 0, Diff{DiffEqual, insertion[:overlapLength1]}) diffs[pointer-1].Text = deletion[0 : len(deletion)-overlapLength1] diffs[pointer+1].Text = insertion[overlapLength1:] @@ -738,10 +743,7 @@ func (dmp *DiffMatchPatch) DiffCleanupSemantic(diffs []Diff) []Diff { float64(overlapLength2) >= float64(len(insertion))/2 { // Reverse overlap found. Insert an equality and swap and trim the surrounding edits. overlap := Diff{DiffEqual, deletion[:overlapLength2]} - diffs = append( - diffs[:pointer], - append([]Diff{overlap}, diffs[pointer:]...)...) - + diffs = splice(diffs, pointer, 0, overlap) diffs[pointer-1].Type = DiffInsert diffs[pointer-1].Text = insertion[0 : len(insertion)-overlapLength2] diffs[pointer+1].Type = DiffDelete @@ -954,8 +956,7 @@ func (dmp *DiffMatchPatch) DiffCleanupEfficiency(diffs []Diff) []Diff { insPoint := equalities.data // Duplicate record. - diffs = append(diffs[:insPoint], - append([]Diff{Diff{DiffDelete, lastequality}}, diffs[insPoint:]...)...) + diffs = splice(diffs, insPoint, 0, Diff{DiffDelete, lastequality}) // Change second copy to insert. diffs[insPoint+1].Type = DiffInsert @@ -1235,9 +1236,9 @@ func (dmp *DiffMatchPatch) DiffLevenshtein(diffs []Diff) int { for _, aDiff := range diffs { switch aDiff.Type { case DiffInsert: - insertions += len(aDiff.Text) + insertions += utf8.RuneCountInString(aDiff.Text) case DiffDelete: - deletions += len(aDiff.Text) + deletions += utf8.RuneCountInString(aDiff.Text) case DiffEqual: // A deletion and an insertion is one substitution. levenshtein += max(insertions, deletions) diff --git a/vendor/github.com/sergi/go-diff/diffmatchpatch/operation_string.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/operation_string.go new file mode 100644 index 0000000000..533ec0da7b --- /dev/null +++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/operation_string.go @@ -0,0 +1,17 @@ +// Code generated by "stringer -type=Operation -trimprefix=Diff"; DO NOT EDIT. + +package diffmatchpatch + +import "fmt" + +const _Operation_name = "DeleteEqualInsert" + +var _Operation_index = [...]uint8{0, 6, 11, 17} + +func (i Operation) String() string { + i -= -1 + if i < 0 || i >= Operation(len(_Operation_index)-1) { + return fmt.Sprintf("Operation(%d)", i+-1) + } + return _Operation_name[_Operation_index[i]:_Operation_index[i+1]] +} |