ListDiff
ListDiff copied to clipboard
Bug: In an edge case, GenDiff will misidentify a Remove/Add as an Update
The edge case occurs while diffing a data source against a reversed version of itself.
Example: A list of 100 items with indices 0..99.
if (i > 0 && j > 0 && match(x[i - 1], y[j - 1])) {
GenDiff(c, x, y, i - 1, j - 1, match);
Actions.Add(new ListDiffAction<S, D>(ListDiffActionType.Update, x[i - 1], y[j - 1]));
}
This check will return true while comparing original[99] with new[0].
My fix is just adding a check to see whether the indices match as well:
if (i > 0 && j > 0 && sourceIdx == destIdx && match(x[i - 1], y[j - 1]))
GenDiff(c, x, y, i - 1, j - 1, match);
Actions.Add(new ListDiffAction<S, D>(ListDiffActionType.Update, x[i - 1], y[j - 1]));
}
Fascinating, what a find. I'm going to have to add a test case to fully wrap my head around it. Your solution seems fine but I just merged an optimization that's going to make the arithmetic tricky. Either way, just complaining, great find, thanks.