Merge change Iacb9082e into cq-diff
* changes: Fixed MyersDiff to be able to handle more than 100k
This commit is contained in:
commit
4c3f90cfaa
|
@ -49,6 +49,7 @@
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jgit.util.IntList;
|
import org.eclipse.jgit.util.IntList;
|
||||||
|
import org.eclipse.jgit.util.LongList;
|
||||||
|
|
||||||
public class MyersDiff {
|
public class MyersDiff {
|
||||||
protected EditList edits;
|
protected EditList edits;
|
||||||
|
@ -202,7 +203,7 @@ Edit calculate(int beginA, int endA, int beginB, int endB) {
|
||||||
|
|
||||||
abstract class EditPaths {
|
abstract class EditPaths {
|
||||||
private IntList x = new IntList();
|
private IntList x = new IntList();
|
||||||
private IntList snake = new IntList();
|
private LongList snake = new LongList();
|
||||||
int beginK, endK, middleK;
|
int beginK, endK, middleK;
|
||||||
int prevBeginK, prevEndK;
|
int prevBeginK, prevEndK;
|
||||||
/* if we hit one end early, no need to look further */
|
/* if we hit one end early, no need to look further */
|
||||||
|
@ -222,7 +223,7 @@ final int getX(int d, int k) {
|
||||||
return x.get(getIndex(d, k));
|
return x.get(getIndex(d, k));
|
||||||
}
|
}
|
||||||
|
|
||||||
final int getSnake(int d, int k) {
|
final long getSnake(int d, int k) {
|
||||||
// TODO: remove
|
// TODO: remove
|
||||||
if (k < beginK || k > endK)
|
if (k < beginK || k > endK)
|
||||||
throw new RuntimeException("k " + k + " not in " + beginK + " - " + endK);
|
throw new RuntimeException("k " + k + " not in " + beginK + " - " + endK);
|
||||||
|
@ -253,22 +254,23 @@ void initialize(int k, int x, int minK, int maxK) {
|
||||||
abstract int getRight(int x);
|
abstract int getRight(int x);
|
||||||
abstract boolean isBetter(int left, int right);
|
abstract boolean isBetter(int left, int right);
|
||||||
abstract void adjustMinMaxK(final int k, final int x);
|
abstract void adjustMinMaxK(final int k, final int x);
|
||||||
abstract boolean meets(int d, int k, int x, int snake);
|
abstract boolean meets(int d, int k, int x, long snake);
|
||||||
|
|
||||||
final int newSnake(int k, int x) {
|
final long newSnake(int k, int x) {
|
||||||
int y = k + x;
|
long y = k + x;
|
||||||
return x + (endA + 1) * y;
|
long ret = ((long) x) << 32;
|
||||||
|
return ret | y;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int snake2x(int snake) {
|
final int snake2x(long snake) {
|
||||||
return snake % (endA + 1);
|
return (int) (snake >>> 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int snake2y(int snake) {
|
final int snake2y(long snake) {
|
||||||
return snake / (endA + 1);
|
return (int) snake;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean makeEdit(int snake1, int snake2) {
|
final boolean makeEdit(long snake1, long snake2) {
|
||||||
int x1 = snake2x(snake1), x2 = snake2x(snake2);
|
int x1 = snake2x(snake1), x2 = snake2x(snake2);
|
||||||
int y1 = snake2y(snake1), y2 = snake2y(snake2);
|
int y1 = snake2y(snake1), y2 = snake2y(snake2);
|
||||||
/*
|
/*
|
||||||
|
@ -301,7 +303,7 @@ boolean calculate(int d) {
|
||||||
// go backwards so that we can avoid temp vars
|
// go backwards so that we can avoid temp vars
|
||||||
for (int k = endK; k >= beginK; k -= 2) {
|
for (int k = endK; k >= beginK; k -= 2) {
|
||||||
int left = -1, right = -1;
|
int left = -1, right = -1;
|
||||||
int leftSnake = -1, rightSnake = -1;
|
long leftSnake = -1L, rightSnake = -1L;
|
||||||
// TODO: refactor into its own function
|
// TODO: refactor into its own function
|
||||||
if (k > prevBeginK) {
|
if (k > prevBeginK) {
|
||||||
int i = getIndex(d - 1, k - 1);
|
int i = getIndex(d - 1, k - 1);
|
||||||
|
@ -325,7 +327,8 @@ boolean calculate(int d) {
|
||||||
return true;
|
return true;
|
||||||
right = getRight(end);
|
right = getRight(end);
|
||||||
}
|
}
|
||||||
int newX, newSnake;
|
int newX;
|
||||||
|
long newSnake;
|
||||||
if (k >= prevEndK ||
|
if (k >= prevEndK ||
|
||||||
(k > prevBeginK &&
|
(k > prevBeginK &&
|
||||||
isBetter(left, right))) {
|
isBetter(left, right))) {
|
||||||
|
@ -376,7 +379,7 @@ final void adjustMinMaxK(final int k, final int x) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean meets(int d, int k, int x, int snake) {
|
final boolean meets(int d, int k, int x, long snake) {
|
||||||
if (k < backward.beginK || k > backward.endK)
|
if (k < backward.beginK || k > backward.endK)
|
||||||
return false;
|
return false;
|
||||||
// TODO: move out of loop
|
// TODO: move out of loop
|
||||||
|
@ -418,7 +421,7 @@ final void adjustMinMaxK(final int k, final int x) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean meets(int d, int k, int x, int snake) {
|
final boolean meets(int d, int k, int x, long snake) {
|
||||||
if (k < forward.beginK || k > forward.endK)
|
if (k < forward.beginK || k > forward.endK)
|
||||||
return false;
|
return false;
|
||||||
// TODO: move out of loop
|
// TODO: move out of loop
|
||||||
|
@ -466,4 +469,4 @@ public static void main(String[] args) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009, Christian Halstrick <christian.halstrick@sap.com>
|
||||||
|
* Copyright (C) 2009, 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.util;
|
||||||
|
|
||||||
|
/** A more efficient List<Long> using a primitive long array. */
|
||||||
|
public class LongList {
|
||||||
|
private long[] entries;
|
||||||
|
|
||||||
|
private int count;
|
||||||
|
|
||||||
|
/** Create an empty list with a default capacity. */
|
||||||
|
public LongList() {
|
||||||
|
this(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an empty list with the specified capacity.
|
||||||
|
*
|
||||||
|
* @param capacity
|
||||||
|
* number of entries the list can initially hold.
|
||||||
|
*/
|
||||||
|
public LongList(final int capacity) {
|
||||||
|
entries = new long[capacity];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return number of entries in this list */
|
||||||
|
public int size() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i
|
||||||
|
* index to read, must be in the range [0, {@link #size()}).
|
||||||
|
* @return the number at the specified index
|
||||||
|
* @throws ArrayIndexOutOfBoundsException
|
||||||
|
* the index outside the valid range
|
||||||
|
*/
|
||||||
|
public long get(final int i) {
|
||||||
|
if (count <= i)
|
||||||
|
throw new ArrayIndexOutOfBoundsException(i);
|
||||||
|
return entries[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Empty this list */
|
||||||
|
public void clear() {
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an entry to the end of the list.
|
||||||
|
*
|
||||||
|
* @param n
|
||||||
|
* the number to add.
|
||||||
|
*/
|
||||||
|
public void add(final long n) {
|
||||||
|
if (count == entries.length)
|
||||||
|
grow();
|
||||||
|
entries[count++] = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign an entry in the list.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* index to set, must be in the range [0, {@link #size()}).
|
||||||
|
* @param n
|
||||||
|
* value to store at the position.
|
||||||
|
*/
|
||||||
|
public void set(final int index, final long n) {
|
||||||
|
if (count < index)
|
||||||
|
throw new ArrayIndexOutOfBoundsException(index);
|
||||||
|
else if (count == index)
|
||||||
|
add(n);
|
||||||
|
else
|
||||||
|
entries[index] = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pad the list with entries.
|
||||||
|
*
|
||||||
|
* @param toIndex
|
||||||
|
* index position to stop filling at. 0 inserts no filler. 1
|
||||||
|
* ensures the list has a size of 1, adding <code>val</code> if
|
||||||
|
* the list is currently empty.
|
||||||
|
* @param val
|
||||||
|
* value to insert into padded positions.
|
||||||
|
*/
|
||||||
|
public void fillTo(int toIndex, final long val) {
|
||||||
|
while (count < toIndex)
|
||||||
|
add(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void grow() {
|
||||||
|
final long[] n = new long[(entries.length + 16) * 3 / 2];
|
||||||
|
System.arraycopy(entries, 0, n, 0, count);
|
||||||
|
entries = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
final StringBuilder r = new StringBuilder();
|
||||||
|
r.append('[');
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (i > 0)
|
||||||
|
r.append(", ");
|
||||||
|
r.append(entries[i]);
|
||||||
|
}
|
||||||
|
r.append(']');
|
||||||
|
return r.toString();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue