Top Description Inners Fields Constructors Methods
org.eclipse.jgit.diff

public Class MyersDiff<S extends Sequence>

extends Object
Class Inheritance
Annotations
@SuppressWarnings:hiding
Type Parameters
<S>
type of sequence.
Static Imports
java.nio.charset.StandardCharsets.UTF_8

Diff algorithm, based on "An O(ND) Difference Algorithm and its Variations", by Eugene Myers.

The basic idea is to put the line numbers of text A as columns ("x") and the lines of text B as rows ("y"). Now you try to find the shortest "edit path" from the upper left corner to the lower right corner, where you can always go horizontally or vertically, but diagonally from (x,y) to (x+1,y+1) only if line x in text A is identical to line y in text B.

Myers' fundamental concept is the "furthest reaching D-path on diagonal k": a D-path is an edit path starting at the upper left corner and containing exactly D non-diagonal elements ("differences"). The furthest reaching D-path on diagonal k is the one that contains the most (diagonal) elements which ends on diagonal k (where k = y - x).

Example:

   H E L L O   W O R L D
   ____
 L     \___
 O         \___
 W             \________

Since every D-path has exactly D horizontal or vertical elements, it can only end on the diagonals -D, -D+2, ..., D-2, D.

Since every furthest reaching D-path contains at least one furthest reaching (D-1)-path (except for D=0), we can construct them recursively.

Since we are really interested in the shortest edit path, we can start looking for a 0-path, then a 1-path, and so on, until we find a path that ends in the lower right corner.

To save space, we do not need to store all paths (which has quadratic space requirements), but generate the D-paths simultaneously from both sides. When the ends meet, we will have found "the middle" of the path. From the end points of that diagonal part, we can generate the rest recursively.

This only requires linear space.

The overall (runtime) complexity is:

    O(N * D^2 + 2 * N/2 * (D/2)^2 + 4 * N/4 * (D/4)^2 + ...)
    = O(N * D^2 * 5 / 4) = O(N * D^2),

(With each step, we have to find the middle parts of twice as many regions as before, but the regions (as well as the D) are halved.)

So the overall runtime complexity stays the same with linear space, albeit with a larger constant factor.

Nested and Inner Type Summary

Modifier and TypeClass and Description
pack-priv class
MyersDiff.MiddleEdit

A class to help bisecting the sequences a and b to find minimal edit paths.

Field Summary

Modifier and TypeField and Description
protected HashedSequence<S>
a

The first text to be compared.

protected HashedSequence<S>
b

The second text to be compared.

protected HashedSequenceComparator<S>
cmp

Comparison function for sequences.

protected EditList
edits

The list of edits found during the last call to calculateEdits(Edit)

public static final DiffAlgorithm
INSTANCE

Singleton instance of MyersDiff.

pack-priv MyersDiff<S>.MiddleEdit

Constructor Summary

AccessConstructor and Description
private

Method Summary

Modifier and TypeMethod and Description
private void
calculateEdits(Edit
portion of the sequences to examine.
r
)

Entrypoint into the algorithm this class is all about.

protected void
calculateEdits(int
start of the part of A which should be compared (0<=beginA<sizeof(A))
beginA
,
int
end of the part of A which should be compared (beginA<=endA<sizeof(A))
endA
,
int
start of the part of B which should be compared (0<=beginB<sizeof(B))
beginB
,
int
end of the part of B which should be compared (beginB<=endB<sizeof(B))
endB
)

Calculates the differences between a given part of A against another given part of B

private static PrintWriter
err()

public static void
main(String[]
two filenames specifying the contents to be diffed
args
)

Main method

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

aback to summary
protected HashedSequence<S> a

The first text to be compared. Referred to as "Text A" in the comments

bback to summary
protected HashedSequence<S> b

The second text to be compared. Referred to as "Text B" in the comments

cmpback to summary
protected HashedSequenceComparator<S> cmp

Comparison function for sequences.

editsback to summary
protected EditList edits

The list of edits found during the last call to calculateEdits(Edit)

INSTANCEback to summary
public static final DiffAlgorithm INSTANCE

Singleton instance of MyersDiff.

middleback to summary
pack-priv MyersDiff<S>.MiddleEdit middle

Constructor Detail

MyersDiffback to summary
private MyersDiff(EditList edits, HashedSequenceComparator<S> cmp, HashedSequence<S> a, HashedSequence<S> b, Edit region)

Method Detail

calculateEditsback to summary
private void calculateEdits(Edit r)

Entrypoint into the algorithm this class is all about. This method triggers that the differences between A and B are calculated in form of a list of edits.

Parameters
r:Edit

portion of the sequences to examine.

calculateEditsback to summary
protected void calculateEdits(int beginA, int endA, int beginB, int endB)

Calculates the differences between a given part of A against another given part of B

Parameters
beginA:int

start of the part of A which should be compared (0<=beginA<sizeof(A))

endA:int

end of the part of A which should be compared (beginA<=endA<sizeof(A))

beginB:int

start of the part of B which should be compared (0<=beginB<sizeof(B))

endB:int

end of the part of B which should be compared (beginB<=endB<sizeof(B))

errback to summary
private static PrintWriter err()
mainback to summary
public static void main(String[] args)

Main method

Parameters
args:String[]

two filenames specifying the contents to be diffed

org.eclipse.jgit.diff back to summary

pack-priv Class MyersDiff.MiddleEdit

extends Object
Class Inheritance

A class to help bisecting the sequences a and b to find minimal edit paths. As the arrays are reused for space efficiency, you will need one instance per thread. The entry function is the calculate() method.

Nested and Inner Type Summary

Modifier and TypeClass and Description
pack-priv class
pack-priv abstract class
pack-priv class

Field Summary

Modifier and TypeField and Description
pack-priv MyersDiff<S>.MiddleEdit.EditPaths
protected int
protected int
protected Edit
protected int
protected int
pack-priv MyersDiff<S>.MiddleEdit.EditPaths

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
pack-priv Edit
calculate(int beginA, int endA, int beginB, int endB)

pack-priv void
initialize(int beginA, int endA, int beginB, int endB)

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

backwardback to summary
pack-priv MyersDiff<S>.MiddleEdit.EditPaths backward
beginAback to summary
protected int beginA
beginBback to summary
protected int beginB
editback to summary
protected Edit edit
endAback to summary
protected int endA
endBback to summary
protected int endB
forwardback to summary
pack-priv MyersDiff<S>.MiddleEdit.EditPaths forward

Constructor Detail

MiddleEditback to summary
pack-priv MiddleEdit()

Method Detail

calculateback to summary
pack-priv Edit calculate(int beginA, int endA, int beginB, int endB)
initializeback to summary
pack-priv void initialize(int beginA, int endA, int beginB, int endB)
org.eclipse.jgit.diff back to summary

pack-priv Class MyersDiff.MiddleEdit.BackwardEditPaths

extends MyersDiff<S extends Sequence>.MiddleEdit.EditPaths
Class Inheritance

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
pack-priv final void
pack-priv final int
pack-priv final int
pack-priv final boolean
pack-priv final boolean
meets(int d, int k, int x, long snake)

Implements abstract org.eclipse.jgit.diff.MyersDiff.MiddleEdit.EditPaths.meets.

pack-priv final int
Inherited from org.eclipse.jgit.diff.MyersDiff.MiddleEdit.EditPaths:
calculategetIndexgetSnakegetXinitializemakeEditnewSnakesnake2xsnake2y

Constructor Detail

BackwardEditPathsback to summary
pack-priv BackwardEditPaths()

Method Detail

adjustMinMaxKback to summary
pack-priv final void adjustMinMaxK(int k, int x)

Implements abstract org.eclipse.jgit.diff.MyersDiff.MiddleEdit.EditPaths.adjustMinMaxK.

Annotations
@Override
getLeftback to summary
pack-priv final int getLeft(int x)

Implements abstract org.eclipse.jgit.diff.MyersDiff.MiddleEdit.EditPaths.getLeft.

Annotations
@Override
getRightback to summary
pack-priv final int getRight(int x)

Implements abstract org.eclipse.jgit.diff.MyersDiff.MiddleEdit.EditPaths.getRight.

Annotations
@Override
isBetterback to summary
pack-priv final boolean isBetter(int left, int right)

Implements abstract org.eclipse.jgit.diff.MyersDiff.MiddleEdit.EditPaths.isBetter.

Annotations
@Override
meetsback to summary
pack-priv final boolean meets(int d, int k, int x, long snake)

Implements abstract org.eclipse.jgit.diff.MyersDiff.MiddleEdit.EditPaths.meets.

Annotations
@Override
snakeback to summary
pack-priv final int snake(int k, int x)

Implements abstract org.eclipse.jgit.diff.MyersDiff.MiddleEdit.EditPaths.snake.

Annotations
@Override
org.eclipse.jgit.diff back to summary

pack-priv abstract Class MyersDiff.MiddleEdit.EditPaths

extends Object
Class Inheritance
Known Direct Subclasses
org.eclipse.jgit.diff.MyersDiff.MiddleEdit.ForwardEditPaths, org.eclipse.jgit.diff.MyersDiff.MiddleEdit.BackwardEditPaths

Field Summary

Modifier and TypeField and Description
pack-priv int
pack-priv int
pack-priv int
pack-priv int
pack-priv int
pack-priv int
pack-priv int
private LongList
private IntList
x

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
pack-priv abstract void
adjustMinMaxK(int k, int x)

pack-priv boolean
calculate(int d)

private int
pack-priv final int
getIndex(int d, int k)

pack-priv abstract int
getLeft(int x)

pack-priv abstract int
getRight(int x)

pack-priv final long
getSnake(int d, int k)

pack-priv final int
getX(int d, int k)

pack-priv void
initialize(int k, int x, int minK, int maxK)

pack-priv abstract boolean
isBetter(int left, int right)

pack-priv final boolean
makeEdit(long snake1, long snake2)

pack-priv abstract boolean
meets(int d, int k, int x, long snake)

pack-priv final long
newSnake(int k, int x)

pack-priv abstract int
snake(int k, int x)

pack-priv final int
snake2x(long snake)

pack-priv final int
snake2y(long snake)

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

beginKback to summary
pack-priv int beginK
endKback to summary
pack-priv int endK
maxKback to summary
pack-priv int maxK
middleKback to summary
pack-priv int middleK
minKback to summary
pack-priv int minK
prevBeginKback to summary
pack-priv int prevBeginK
prevEndKback to summary
pack-priv int prevEndK
snakeback to summary
private LongList snake
xback to summary
private IntList x

Constructor Detail

EditPathsback to summary
pack-priv EditPaths()

Method Detail

adjustMinMaxKback to summary
pack-priv abstract void adjustMinMaxK(int k, int x)
calculateback to summary
pack-priv boolean calculate(int d)
forceKIntoRangeback to summary
private int forceKIntoRange(int k)
getIndexback to summary
pack-priv final int getIndex(int d, int k)
getLeftback to summary
pack-priv abstract int getLeft(int x)
getRightback to summary
pack-priv abstract int getRight(int x)
getSnakeback to summary
pack-priv final long getSnake(int d, int k)
getXback to summary
pack-priv final int getX(int d, int k)
initializeback to summary
pack-priv void initialize(int k, int x, int minK, int maxK)
isBetterback to summary
pack-priv abstract boolean isBetter(int left, int right)
makeEditback to summary
pack-priv final boolean makeEdit(long snake1, long snake2)
meetsback to summary
pack-priv abstract boolean meets(int d, int k, int x, long snake)
newSnakeback to summary
pack-priv final long newSnake(int k, int x)
snakeback to summary
pack-priv abstract int snake(int k, int x)
snake2xback to summary
pack-priv final int snake2x(long snake)
snake2yback to summary
pack-priv final int snake2y(long snake)
org.eclipse.jgit.diff back to summary

pack-priv Class MyersDiff.MiddleEdit.ForwardEditPaths

extends MyersDiff<S extends Sequence>.MiddleEdit.EditPaths
Class Inheritance

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
pack-priv final void
pack-priv final int
pack-priv final int
pack-priv final boolean
pack-priv final boolean
meets(int d, int k, int x, long snake)

Implements abstract org.eclipse.jgit.diff.MyersDiff.MiddleEdit.EditPaths.meets.

pack-priv final int
Inherited from org.eclipse.jgit.diff.MyersDiff.MiddleEdit.EditPaths:
calculategetIndexgetSnakegetXinitializemakeEditnewSnakesnake2xsnake2y

Constructor Detail

ForwardEditPathsback to summary
pack-priv ForwardEditPaths()

Method Detail

adjustMinMaxKback to summary
pack-priv final void adjustMinMaxK(int k, int x)

Implements abstract org.eclipse.jgit.diff.MyersDiff.MiddleEdit.EditPaths.adjustMinMaxK.

Annotations
@Override
getLeftback to summary
pack-priv final int getLeft(int x)

Implements abstract org.eclipse.jgit.diff.MyersDiff.MiddleEdit.EditPaths.getLeft.

Annotations
@Override
getRightback to summary
pack-priv final int getRight(int x)

Implements abstract org.eclipse.jgit.diff.MyersDiff.MiddleEdit.EditPaths.getRight.

Annotations
@Override
isBetterback to summary
pack-priv final boolean isBetter(int left, int right)

Implements abstract org.eclipse.jgit.diff.MyersDiff.MiddleEdit.EditPaths.isBetter.

Annotations
@Override
meetsback to summary
pack-priv final boolean meets(int d, int k, int x, long snake)

Implements abstract org.eclipse.jgit.diff.MyersDiff.MiddleEdit.EditPaths.meets.

Annotations
@Override
snakeback to summary
pack-priv final int snake(int k, int x)

Implements abstract org.eclipse.jgit.diff.MyersDiff.MiddleEdit.EditPaths.snake.

Annotations
@Override