Переглянути джерело

Define DiffAlgorithm as an abstract function

This makes it easier to parametrize DiffFormatter with a different
implementation, as we later plan to add PatienceDiff to JGit.

Change-Id: Id35ef478d5fa20fe10a1ba297f9436fd7adde9ce
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
tags/v0.10.1
Shawn O. Pearce 13 роки тому
джерело
коміт
307ba53eb6

+ 2
- 2
org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/IpLogGenerator.java Переглянути файл

@@ -384,9 +384,9 @@ public class IpLogGenerator {
else
oldImage = new byte[0];

EditList edits = new MyersDiff<RawText>(
EditList edits = MyersDiff.INSTANCE.diff(
RawTextComparator.DEFAULT, new RawText(oldImage),
new RawText(openBlob(1))).getEdits();
new RawText(openBlob(1)));
for (Edit e : edits)
addedLines += e.getEndB() - e.getBeginB();
}

+ 3
- 3
org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/MyersDiffPerformanceTest.java Переглянути файл

@@ -164,14 +164,14 @@ public class MyersDiffPerformanceTest extends TestCase {
CharArray ac = new CharArray(a);
CharArray bc = new CharArray(b);
CharCmp cmp = new CharCmp();
MyersDiff<CharArray> myersDiff = null;
int D = 0;
int cpuTimeChanges = 0;
long lastReadout = 0;
long interimTime = 0;
int repetitions = 0;
stopwatch.start();
while (cpuTimeChanges < minCPUTimerTicks && interimTime < longTaskBoundary) {
myersDiff = new MyersDiff<CharArray>(cmp, ac, bc);
D = MyersDiff.INSTANCE.diff(cmp, ac, bc).size();
repetitions++;
interimTime = stopwatch.readout();
if (interimTime != lastReadout) {
@@ -181,7 +181,7 @@ public class MyersDiffPerformanceTest extends TestCase {
}
ret.runningTime = stopwatch.stop() / repetitions;
ret.N = ac.size() + bc.size();
ret.D = myersDiff.getEdits().size();
ret.D = D;

return ret;
}

+ 2
- 2
org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/MyersDiffTest.java Переглянути файл

@@ -63,9 +63,9 @@ public class MyersDiffTest extends TestCase {
}

public void assertDiff(String a, String b, String edits) {
MyersDiff diff = new MyersDiff<CharArray>(new CharCmp(),
EditList editList = MyersDiff.INSTANCE.diff(new CharCmp(),
toCharArray(a), toCharArray(b));
assertEquals(edits, toString(diff.getEdits()));
assertEquals(edits, toString(editList));
}

private static String toString(EditList list) {

+ 79
- 0
org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java Переглянути файл

@@ -0,0 +1,79 @@
/*
* Copyright (C) 2010, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.eclipse.jgit.diff;

/**
* Compares two {@link Sequence}s to create an {@link EditList} of changes.
*
* An algorithm's {@code diff} method must be callable from concurrent threads
* without data collisions. This permits some algorithms to use a singleton
* pattern, with concurrent invocations using the same singleton. Other
* algorithms may support parameterization, in which case the caller can create
* a unique instance per thread.
*/
public interface DiffAlgorithm {
/**
* Compare two sequences and identify a list of edits between them.
*
* @param <S>
* type of sequence being compared.
* @param <C>
* type of comparator to evaluate the sequence elements.
* @param cmp
* the comparator supplying the element equivalence function.
* @param a
* the first (also known as old or pre-image) sequence. Edits
* returned by this algorithm will reference indexes using the
* 'A' side: {@link Edit#getBeginA()}, {@link Edit#getEndA()}.
* @param b
* the second (also known as new or post-image) sequence. Edits
* returned by this algorithm will reference indexes using the
* 'B' side: {@link Edit#getBeginB()}, {@link Edit#getEndB()}.
* @return a modifiable edit list comparing the two sequences. If empty, the
* sequences are identical according to {@code cmp}'s rules. The
* result list is never null.
*/
public <S extends Sequence, C extends SequenceComparator<? super S>> EditList diff(
C cmp, S a, S b);
}

+ 14
- 1
org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java Переглянути файл

@@ -118,6 +118,8 @@ public class DiffFormatter {

private int abbreviationLength = 7;

private DiffAlgorithm diffAlgorithm = MyersDiff.INSTANCE;

private RawTextComparator comparator = RawTextComparator.DEFAULT;

private int binaryFileThreshold = DEFAULT_BINARY_FILE_THRESHOLD;
@@ -206,6 +208,17 @@ public class DiffFormatter {
abbreviationLength = count;
}

/**
* Set the algorithm that constructs difference output.
*
* @param alg
* the algorithm to produce text file differences.
* @see MyersDiff#INSTANCE
*/
public void setDiffAlgorithm(DiffAlgorithm alg) {
diffAlgorithm = alg;
}

/**
* Set the line equivalence function for text file differences.
*
@@ -893,7 +906,7 @@ public class DiffFormatter {
}

private EditList diff(RawText a, RawText b) {
return new MyersDiff<RawText>(comparator, a, b).getEdits();
return diffAlgorithm.diff(comparator, a, b);
}

private void assertHaveRepository() {

+ 10
- 9
org.eclipse.jgit/src/org/eclipse/jgit/diff/MyersDiff.java Переглянути файл

@@ -106,13 +106,21 @@ import org.eclipse.jgit.util.LongList;
* type of sequence.
*/
public class MyersDiff<S extends Sequence> {
/** Singleton instance of MyersDiff. */
public static final DiffAlgorithm INSTANCE = new DiffAlgorithm() {
public <S extends Sequence, C extends SequenceComparator<? super S>> EditList diff(
C cmp, S a, S b) {
return new MyersDiff<S>(cmp, a, b).getEdits();
}
};

/**
* The list of edits found during the last call to {@link #calculateEdits()}
*/
protected EditList edits;

/** Comparison function for sequences. */
protected SequenceComparator<S> cmp;
protected SequenceComparator<? super S> cmp;

/**
* The first text to be compared. Referred to as "Text A" in the comments
@@ -124,14 +132,7 @@ public class MyersDiff<S extends Sequence> {
*/
protected S b;

/**
* The only constructor
*
* @param cmp comparison method for this execution.
* @param a the text A which should be compared
* @param b the text B which should be compared
*/
public MyersDiff(SequenceComparator<S> cmp, S a, S b) {
private MyersDiff(SequenceComparator<? super S> cmp, S a, S b) {
this.cmp = cmp;
this.a = a;
this.b = b;

+ 2
- 2
org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java Переглянути файл

@@ -90,9 +90,9 @@ public final class MergeAlgorithm {
sequences.add(ours);
sequences.add(theirs);
MergeResult result = new MergeResult<S>(sequences);
EditList oursEdits = new MyersDiff<S>(cmp, base, ours).getEdits();
EditList oursEdits = MyersDiff.INSTANCE.diff(cmp, base, ours);
Iterator<Edit> baseToOurs = oursEdits.iterator();
EditList theirsEdits = new MyersDiff<S>(cmp, base, theirs).getEdits();
EditList theirsEdits = MyersDiff.INSTANCE.diff(cmp, base, theirs);
Iterator<Edit> baseToTheirs = theirsEdits.iterator();
int current = 0; // points to the next line (first line is 0) of base
// which was not handled yet

Завантаження…
Відмінити
Зберегти