@@ -39,15 +39,23 @@ export class MyersDiffAlgorithm implements IDiffAlgorithm {
39
39
40
40
loop: while ( true ) {
41
41
d ++ ;
42
- for ( k = - d ; k <= d ; k += 2 ) {
43
- if ( ! timeout . isValid ( ) ) {
44
- return DiffAlgorithmResult . trivialTimedOut ( seq1 , seq2 ) ;
45
- }
46
-
47
- const maxXofDLineTop = k === d ? - 1 : V . get ( k + 1 ) ; // We take a vertical non-diagonal
48
- const maxXofDLineLeft = k === - d ? - 1 : V . get ( k - 1 ) + 1 ; // We take a horizontal non-diagonal (+1 x)
42
+ if ( ! timeout . isValid ( ) ) {
43
+ return DiffAlgorithmResult . trivialTimedOut ( seq1 , seq2 ) ;
44
+ }
45
+ // The paper has `for (k = -d; k <= d; k += 2)`, but we can ignore diagonals that cannot influence the result.
46
+ const lowerBound = - Math . min ( d , seq2 . length + ( d % 2 ) ) ;
47
+ const upperBound = Math . min ( d , seq1 . length + ( d % 2 ) ) ;
48
+ for ( k = lowerBound ; k <= upperBound ; k += 2 ) {
49
+ // We can use the X values of (d-1)-lines to compute X value of the longest d-lines.
50
+ const maxXofDLineTop = k === upperBound ? - 1 : V . get ( k + 1 ) ; // We take a vertical non-diagonal (add a symbol in seq1)
51
+ const maxXofDLineLeft = k === lowerBound ? - 1 : V . get ( k - 1 ) + 1 ; // We take a horizontal non-diagonal (+1 x) (delete a symbol in seq1)
49
52
const x = Math . min ( Math . max ( maxXofDLineTop , maxXofDLineLeft ) , seq1 . length ) ;
50
53
const y = x - k ;
54
+ if ( x > seq1 . length || y > seq2 . length ) {
55
+ // This diagonal is irrelevant for the result.
56
+ // TODO: Don't pay the cost for this in the next iteration.
57
+ continue ;
58
+ }
51
59
const newMaxX = getXAfterSnake ( x , y ) ;
52
60
V . set ( k , newMaxX ) ;
53
61
const lastPath = x === maxXofDLineTop ? paths . get ( k + 1 ) : paths . get ( k - 1 ) ;
0 commit comments