50
50
namespace NGit.Diff
53
/// Diff algorithm, based on "An O(ND) Difference Algorithm and its
54
/// Variations", by Eugene Myers.
53
/// Diff algorithm, based on "An O(ND) Difference Algorithm and its Variations",
57
/// Diff algorithm, based on "An O(ND) Difference Algorithm and its
58
/// Variations", by Eugene Myers.
57
/// Diff algorithm, based on "An O(ND) Difference Algorithm and its Variations",
59
60
/// The basic idea is to put the line numbers of text A as columns ("x") and the
60
/// lines of text B as rows ("y"). Now you try to find the shortest "edit path"
61
/// from the upper left corner to the lower right corner, where you can
62
/// always go horizontally or vertically, but diagonally from (x,y) to
63
/// (x+1,y+1) only if line x in text A is identical to line y in text B.
64
/// Myers' fundamental concept is the "furthest reaching D-path on diagonal k":
65
/// a D-path is an edit path starting at the upper left corner and containing
66
/// exactly D non-diagonal elements ("differences"). The furthest reaching
67
/// D-path on diagonal k is the one that contains the most (diagonal) elements
68
/// which ends on diagonal k (where k = y - x).
61
/// lines of text B as rows ("y"). Now you try to find the shortest "edit path"
62
/// from the upper left corner to the lower right corner, where you can always go
63
/// horizontally or vertically, but diagonally from (x,y) to (x+1,y+1) only if
64
/// line x in text A is identical to line y in text B.
66
/// Myers' fundamental concept is the "furthest reaching D-path on diagonal k": a
67
/// D-path is an edit path starting at the upper left corner and containing
68
/// exactly D non-diagonal elements ("differences"). The furthest reaching D-path
69
/// on diagonal k is the one that contains the most (diagonal) elements which
70
/// ends on diagonal k (where k = y - x).
70
74
/// H E L L O W O R L D
75
/// Since every D-path has exactly D horizontal or vertical elements, it can
76
/// only end on the diagonals -D, -D+2, ..., D-2, D.
77
/// Since every furthest reaching D-path contains at least one furthest
78
/// reaching (D-1)-path (except for D=0), we can construct them recursively.
81
/// Since every D-path has exactly D horizontal or vertical elements, it can only
82
/// end on the diagonals -D, -D+2, ..., D-2, D.
84
/// Since every furthest reaching D-path contains at least one furthest reaching
85
/// (D-1)-path (except for D=0), we can construct them recursively.
79
87
/// Since we are really interested in the shortest edit path, we can start
80
88
/// looking for a 0-path, then a 1-path, and so on, until we find a path that
81
89
/// ends in the lower right corner.
82
91
/// To save space, we do not need to store all paths (which has quadratic space
83
/// requirements), but generate the D-paths simultaneously from both sides.
84
/// When the ends meet, we will have found "the middle" of the path. From the
85
/// end points of that diagonal part, we can generate the rest recursively.
92
/// requirements), but generate the D-paths simultaneously from both sides. When
93
/// the ends meet, we will have found "the middle" of the path. From the end
94
/// points of that diagonal part, we can generate the rest recursively.
86
96
/// This only requires linear space.
87
/// The overall (runtime) complexity is
98
/// The overall (runtime) complexity is:
88
100
/// O(N * D^2 + 2 * N/2 * (D/2)^2 + 4 * N/4 * (D/4)^2 + ...)
89
101
/// = O(N * D^2 * 5 / 4) = O(N * D^2),
90
/// (With each step, we have to find the middle parts of twice as many regions
91
/// as before, but the regions (as well as the D) are halved.)
92
/// So the overall runtime complexity stays the same with linear space,
93
/// albeit with a larger constant factor.
104
/// (With each step, we have to find the middle parts of twice as many regions as
105
/// before, but the regions (as well as the D) are halved.)
107
/// So the overall runtime complexity stays the same with linear space, albeit
108
/// with a larger constant factor.
96
111
public class MyersDiff<S> where S:Sequence
98
private sealed class _LowLevelDiffAlgorithm_110 : LowLevelDiffAlgorithm
113
private sealed class _LowLevelDiffAlgorithm_114 : LowLevelDiffAlgorithm
100
public _LowLevelDiffAlgorithm_110()
115
public _LowLevelDiffAlgorithm_114()