43
44
loop: while (true) {
46
>
if (!timeout.isValid()) {
47
return DiffAlgorithmResult.trivialTimedOut(seqX, seqY);
48
}
49
>
// The paper has `for (k = -d; k <= d; k += 2)`, but we can ignore diagonals that cannot influence the result.
myersDiffAlgorithm.ts
50
>
const lowerBound = -Math.min(d, seqY.length + (d % 2));
51
>
const upperBound = Math.min(d, seqX.length + (d % 2));
52
>
for (k = lowerBound; k <= upperBound; k += 2) {
53
>
let step = 0;
54
>
// We can use the X values of (d-1)-lines to compute X value of the longest d-lines.
55
>
const maxXofDLineTop = k === upperBound ? -1 : V.get(k + 1); // We take a vertical non-diagonal (add a symbol in seqX)
56
>
const maxXofDLineLeft = k === lowerBound ? -1 : V.get(k - 1) + 1; // We take a horizontal non-diagonal (+1 x) (delete a symbol in seqX)
57
>
step++;
58
>
const x = Math.min(Math.max(maxXofDLineTop, maxXofDLineLeft), seqX.length);
59
>
const y = x - k;
60
>
step++;
61
>
if (x > seqX.length || y > seqY.length) {
62
// This diagonal is irrelevant for the result.
63
// TODO: Don't pay the cost for this in the next iteration.
64
continue;
65
}
67
>
V.set(k, newMaxX);
68
>
const lastPath = x === maxXofDLineTop ? paths.get(k + 1) : paths.get(k - 1);
69
>
paths.set(k, newMaxX !== x ? new SnakePath(lastPath, x, y, newMaxX - x) : lastPath);
70
>
71
>
if (V.get(k) === seqX.length && V.get(k) - k === seqY.length) {
72
>
break loop;
73
>
}
74
>
}
75
>
}
76
>
77
>
let path = paths.get(k);
78
>
const result: SequenceDiff[] = [];
79
>
let lastAligningPosS1: number = seqX.length;
80
>
let lastAligningPosS2: number = seqY.length;
81
>
82
>
while (true) {
83
>
const endX = path ? path.x + path.length : 0;
84
>
const endY = path ? path.y + path.length : 0;
85
>
86
>
if (endX !== lastAligningPosS1 || endY !== lastAligningPosS2) {
87
>
result.push(new SequenceDiff(
88
>
new OffsetRange(endX, lastAligningPosS1),
89
>
new OffsetRange(endY, lastAligningPosS2),
90
>
));
91
>
}
92
>
if (!path) {
93
>
break;
94
>
}
95
>
lastAligningPosS1 = path.x;
96
>
lastAligningPosS2 = path.y;
97
>
98
>
path = path.prev;
99
>
}
100
>
101
>
result.reverse();
102
>
return new DiffAlgorithmResult(result, false);
103
}
104
}