Skip to content

Commit e5b5459

Browse files
fix(diff): correct overlap detection and bounds in linear space Myers (#46)
* fix(diff): correct overlap detection and bounds in linear space Myers This commit resolves two critical pathfinding bugs in the linear space Myers algorithm (`findMiddleSnake`) that caused it to produce suboptimal diffs or silently fail to explore valid search spaces. 1. Fix forward search overlap detection: During the forward search overlap check (when `delta` is odd), the algorithm incorrectly checked the reverse vector `vr` at `offset + (delta - k)`. However, the reverse search already maps its furthest-reaching `x` bounds to the same forward diagonal `k`. Checking the wrong index caused the algorithm to miss the true optimal middle snake, leading to longer, suboptimal edit scripts. This is fixed by correctly checking `reverseIdx := offset + k`. 2. Fix vector sizing and offset for negative delta: When sequence A is shorter than sequence B (`delta < 0`), the forward-diagonal `k` in the reverse search can reach down to `-maxDiff + delta`. Because `offset` was previously only adjusted for positive `delta`, calculating `offset + k` would result in negative indices. This caused the reverse search to silently trigger bounds checks and skip exploring half of its required search grid. The `vectorSize` and `offset` are now correctly adjusted when `delta < 0` to accommodate the full bounds. * chore: add comments Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent e4c9d81 commit e5b5459

1 file changed

Lines changed: 5 additions & 3 deletions

File tree

diff/myers/myers.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -339,11 +339,13 @@ func findMiddleSnake(a, b []string, aStart, aEnd, bStart, bEnd int) snake { //re
339339
// vr: Reverse search (from bottom-right)
340340
// Size needs to accommodate k ranging from -maxDiff to +maxDiff.
341341
vectorSize := 2*maxDiff + 1
342+
offset := maxDiff
342343
if delta > 0 {
343344
vectorSize += delta // Ensure space for reverse search diagonals
345+
} else if delta < 0 {
346+
vectorSize -= delta // delta is negative, so this increases the size
347+
offset -= delta // delta is negative, so this increases the offset
344348
}
345-
// offset: Used to map diagonal k (which can be negative) to non-negative array indices.
346-
offset := maxDiff
347349

348350
vf := make([]int, vectorSize)
349351
vr := make([]int, vectorSize) // Stores relative x-coordinates within the n x m grid
@@ -448,7 +450,7 @@ func findMiddleSnake(a, b []string, aStart, aEnd, bStart, bEnd int) snake { //re
448450
// Overlap Check
449451
// Overlap check
450452
if delta%2 != 0 && k >= delta-(d-1) && k <= delta+(d-1) {
451-
reverseIdx := offset + (delta - k)
453+
reverseIdx := offset + k
452454
if reverseIdx >= 0 && reverseIdx < vectorSize {
453455
reverseX := vr[reverseIdx]
454456
if reverseX >= 0 && x >= reverseX {

0 commit comments

Comments
 (0)