下面列出了java.util.LinkedList#addLast ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Puts a specific parfor statistic for future analysis into the repository.
*
* @param id ?
* @param type parfor statistic type
* @param s ?
*/
public static void putPFStat( long id, Stat type, double s)
{
if( _disabled )
return; // do nothing
//check if parfor exists
if( !_pfstats.containsKey(id) )
_pfstats.put(id, new HashMap<Stat,LinkedList<Double>>());
HashMap<Stat,LinkedList<Double>> allstats = _pfstats.get(id);
//check if stat type exists
if( !allstats.containsKey(type) )
allstats.put(type, new LinkedList<Double>());
LinkedList<Double> stats = allstats.get(type);
//add new stat
stats.addLast(s);
}
public ShardIterator replicaActiveInitializingShardIt() {
// If the primaries are unassigned, return an empty list (there aren't
// any replicas to query anyway)
if (noPrimariesActive()) {
return new PlainShardIterator(shardId, NO_SHARDS);
}
LinkedList<ShardRouting> ordered = new LinkedList<>();
for (ShardRouting replica : shuffler.shuffle(replicas)) {
if (replica.active()) {
ordered.addFirst(replica);
} else if (replica.initializing()) {
ordered.addLast(replica);
}
}
return new PlainShardIterator(shardId, ordered);
}
public static void addQ(LinkedList<Float> Q, List<Float> P) {
Iterator<Float> it = P.iterator();
float p = 0;
LinkedList<Float> temp = new LinkedList<Float>();
for (float q : Q) {
if (it.hasNext()) {
p = it.next();
}
temp.addLast(p + q);
}
Q.clear();
Q.addAll(temp);
}
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> res = new LinkedList<>();
if (root == null) {
return res;
}
LinkedList<TreeNode> queue = new LinkedList<>();
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> curLevel = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode node = queue.removeFirst();
curLevel.add(node.val);
if (node.left != null) {
queue.addLast(node.left);
}
if (node.right != null) {
queue.addLast(node.right);
}
}
res.add(0, curLevel);
}
return res;
}
public static void multiplyQ(LinkedList<Float> Q, List<Float> P) {
Iterator<Float> it = P.iterator();
float p = 0;
LinkedList<Float> temp = new LinkedList<Float>();
for (float q : Q) {
if (it.hasNext()) {
p = it.next();
}
temp.addLast(q * p);
}
Q.clear();
Q.addAll(temp);
}
public void testShiftFTF10() throws RPLException {
AbstractExpression condition = and(geq(var("x"), lit(4)), leq(var("x"), lit(6)));
LinkedList<State> output = new LinkedList<State>();
closed = false;
JShifter m = new JShifter(new Executor() {
@Override
public void close() throws RPLException {
closed = true;
}
@Override
public void push(State s) throws RPLException {
output.addLast(s);
}
}, condition, 10);
m.push(s1, 0);
assertEquals(list(), output);
m.push(s2, 1);
assertEquals(list(), output);
m.push(s3, 2);
assertEquals(list(), output);
m.push(s4, 3);
assertEquals(list(s4, 0), output);
m.push(s5, 4);
assertEquals(list(s4, 0, s5, 1), output);
m.push(s6, 5);
assertEquals(list(s4, 0, s5, 1, s6, 2), output);
m.push(s7, 6);
assertEquals(list(s4, 0, s5, 1, s6, 2), output);
m.push(s8, 7);
assertEquals(list(s4, 0, s5, 1, s6, 2), output);
m.push(s9, 8);
assertEquals(list(s4, 0, s5, 1, s6, 2), output);
m.close();
assertEquals(list(s4, 0, s5, 1, s6, 2, s1, 10, s2, 11, s3, 12, s7, 16, s8, 17, s9, 18), output);
assertTrue(closed);
}
public void testShiftTF1() throws RPLException {
AbstractExpression condition = lt(var("x"), lit(4));
LinkedList<State> output = new LinkedList<State>();
closed = false;
LShifter m = new LShifter(new Executor() {
@Override
public void close() throws RPLException {
closed = true;
}
@Override
public void push(State s) throws RPLException {
output.addLast(s);
}
}, condition, 1);
m.push(s1, 0);
assertEquals(list(s1, 0), output);
m.push(s2, 1);
assertEquals(list(s1, 0, s2, 1), output);
m.push(s3, 2);
assertEquals(list(s1, 0, s2, 1, s3, 2), output);
m.push(s4, 3);
assertEquals(list(s1, 0, s2, 1, s3, 2), output);
m.push(s5, 4);
assertEquals(list(s1, 0, s2, 1, s3, 2, s4, 4), output);
m.push(s6, 5);
assertEquals(list(s1, 0, s2, 1, s3, 2, s4, 4, s5, 5), output);
m.close();
assertEquals(list(s1, 0, s2, 1, s3, 2, s4, 4, s5, 5, s6, 6), output);
assertTrue(closed);
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String s1 = req.getParameter(FIELD_NAME);
LinkedList ll = new LinkedList();
ll.addLast(s1);
String s2 = (String) ll.getLast();
PrintWriter writer = resp.getWriter();
writer.println(s2); /* BAD */
}
private void doVisit(FileVisitor visitor, File file, LinkedList<String> relativePath, int segmentIndex, AtomicBoolean stopFlag) {
if (stopFlag.get()) {
return;
}
String segment = patternSegments.get(segmentIndex);
if (segment.contains("**")) {
PatternSet patternSet = new PatternSet();
patternSet.include(includePattern);
patternSet.exclude(excludeSpec);
DirectoryFileTree fileTree = new DirectoryFileTree(baseDir, patternSet);
fileTree.visitFrom(visitor, file, new RelativePath(file.isFile(), relativePath.toArray(new String[relativePath.size()])));
} else if (segment.contains("*") || segment.contains("?")) {
PatternStep step = PatternStepFactory.getStep(segment, false);
File[] children = file.listFiles();
if (children == null) {
if (!file.canRead()) {
throw new GradleException(String.format("Could not list contents of directory '%s' as it is not readable.", file));
}
// else, might be a link which points to nothing, or has been removed while we're visiting, or ...
throw new GradleException(String.format("Could not list contents of '%s'.", file));
}
for (File child : children) {
if (stopFlag.get()) { break; }
if (step.matches(child.getName())) {
relativePath.addLast(child.getName());
doVisitDirOrFile(visitor, child, relativePath, segmentIndex + 1, stopFlag);
relativePath.removeLast();
}
}
} else {
relativePath.addLast(segment);
doVisitDirOrFile(visitor, new File(file, segment), relativePath, segmentIndex + 1, stopFlag);
relativePath.removeLast();
}
}
static String makeVersion ( String version )
{
if ( version == null )
{
return null;
}
// remove trailing -SNAPSHOT
version = version.replaceAll ( "-SNAPSHOT$", "" );
final LinkedList<String> toks = new LinkedList<String> ( Arrays.asList ( version.split ( "\\.", 4 ) ) );
while ( toks.size () > 3 )
{
toks.removeLast ();
}
while ( toks.size () < 3 )
{
toks.addLast ( "0" );
}
final StringBuilder sb = new StringBuilder ();
while ( !toks.isEmpty () )
{
if ( sb.length () > 0 )
{
sb.append ( '.' );
}
sb.append ( toks.pollFirst () );
}
return sb.toString ();
}
@Override
public List<TextRange> select(final PsiElement e, final CharSequence editorText, final int cursorOffset, final Editor editor) {
final VirtualFile file = e.getContainingFile().getVirtualFile();
final FileType fileType = file == null? null : file.getFileType();
if (fileType == null) return super.select(e, editorText, cursorOffset, editor);
final int textLength = editorText.length();
final TextRange totalRange = e.getTextRange();
final HighlighterIterator iterator = ((EditorEx)editor).getHighlighter().createIterator(totalRange.getStartOffset());
final BraceMatcher braceMatcher = BraceMatchingUtil.getBraceMatcher(fileType, iterator);
final ArrayList<TextRange> result = new ArrayList<TextRange>();
final LinkedList<Trinity<Integer, Integer, IElementType>> stack = new LinkedList<Trinity<Integer, Integer, IElementType>>();
while (!iterator.atEnd() && iterator.getStart() < totalRange.getEndOffset()) {
final Trinity<Integer, Integer, IElementType> last;
if (braceMatcher.isLBraceToken(iterator, editorText, fileType)) {
stack.addLast(Trinity.create(iterator.getStart(), iterator.getEnd(), iterator.getTokenType()));
}
else if (braceMatcher.isRBraceToken(iterator, editorText, fileType)
&& !stack.isEmpty() && braceMatcher.isPairBraces((last = stack.getLast()).third, iterator.getTokenType())) {
stack.removeLast();
result.addAll(expandToWholeLine(editorText, new TextRange(last.first, iterator.getEnd())));
int bodyStart = last.second;
int bodyEnd = iterator.getStart();
while (bodyStart < textLength && Character.isWhitespace(editorText.charAt(bodyStart))) bodyStart ++;
while (bodyEnd > 0 && Character.isWhitespace(editorText.charAt(bodyEnd - 1))) bodyEnd --;
result.addAll(expandToWholeLine(editorText, new TextRange(bodyStart, bodyEnd)));
}
iterator.advance();
}
result.add(e.getTextRange());
return result;
}
@Override
public List<List<Writable>> mapSequence(List<List<Writable>> sequence) {
int colIdx = inputSchema.getIndexOfColumn(columnName);
ColumnType columnType = inputSchema.getType(colIdx);
List<List<Writable>> out = new ArrayList<>(sequence.size());
LinkedList<Writable> window = new LinkedList<>();
for (int i = 0; i < sequence.size(); i++) {
Writable current = sequence.get(i).get(colIdx);
window.addLast(current);
if (window.size() > lookback) {
window.removeFirst();
}
Writable reduced;
if (window.size() < lookback && edgeCaseHandling == EdgeCaseHandling.SpecifiedValue) {
reduced = edgeCaseValue;
} else {
IAggregableReduceOp<Writable, List<Writable>> reductionOp = AggregableReductionUtils
.reduceColumn(Collections.singletonList(op), columnType, false, null);
for (Writable w : window) {
reductionOp.accept(w);
}
reduced = reductionOp.get().get(0);
}
ArrayList<Writable> outThisStep = new ArrayList<>(sequence.get(i).size() + 1);
outThisStep.addAll(sequence.get(i));
outThisStep.add(reduced);
out.add(outThisStep);
}
return out;
}
private static void deleteOldSegmentAndCreateNewSegment(LogSegmentMetadata oldMetadata,
String newSegmentsPath,
List<ACL> acls,
LinkedList<Op> createOps,
LinkedList<Op> deleteOps) {
createOps.addLast(Op.create(
newSegmentsPath + "/" + oldMetadata.getZNodeName(),
oldMetadata.getFinalisedData().getBytes(UTF_8),
acls,
CreateMode.PERSISTENT));
deleteOps.addFirst(Op.delete(
oldMetadata.getZkPath(),
-1));
}
/**
* Add a runtime event to the runtime event queue. The queue has a fixed
* size {@link RuntimeEvent#RUNTIME_EVENT_QUEUE_SIZE} and the oldest
* entry will be thrown out of the queue is about to overflow
* @param self self reference
* @param event event to add
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static void addRuntimeEvent(final Object self, final Object event) {
final LinkedList<RuntimeEvent<?>> q = getEventQueue(self);
final int cap = (Integer)getEventQueueCapacity(self);
while (q.size() >= cap) {
q.removeFirst();
}
q.addLast(getEvent(event));
}
private double Proposal_multistepOnNode() {
int rootNodeNum = treeModel.getRoot().getNumber();
//unlike the old version, self-move isn't allowed.
int originalNode1 = findAnOnNodeRandomly(); //find an on-node
//System.out.print("Try " + originalNode1);
int[] numStepsFromI_selected =determineTreeNeighborhood(originalNode1, 100000);
//1. Select an unoccupied site within some steps away from it.
LinkedList<Integer> possibilities1 = new LinkedList<Integer>();
for(int i=0; i < numNodes; i++){
// System.out.println("#steps from I_selected " + numStepsFromI_selected[i]);
//make sure no self select
boolean isIn1 = numStepsFromI_selected[i] <= maxNodeLevel && numStepsFromI_selected[i] !=0 && i != rootNodeNum;
if(isIn1){
possibilities1.addLast(new Integer(i));
}
}//end for
int numPossibilities1 = possibilities1.size();
int whichMove = (int) (Math.floor(Math.random()*numPossibilities1)); //choose from possibilities
int site_add1 = possibilities1.get(whichMove).intValue();
curNode = site_add1;
// System.out.println(" and select " + site_add1);
// System.out.println("selected node = " + site_add1 + " that's " + numStepsFromI_selected[site_add1] + " steps from " + originalNode1);
indicators.setParameterValue(originalNode1, 0); // the existing indicator is now set to be off
indicators.setParameterValue(site_add1, 1); //set the new selected index to the new node.
//backward calculation
int[] numStepsBackward =determineTreeNeighborhood(site_add1, 100000);
//1. Select an unoccupied site within some steps away from it.
LinkedList<Integer> possibilities2 = new LinkedList<Integer>();
for(int i=0; i < numNodes; i++){
// System.out.println("#steps from I_selected " + numStepsFromI_selected[i]);
//make sure no self select
boolean isIn2 = numStepsBackward[i] <= maxNodeLevel && numStepsBackward[i] !=0 && i != rootNodeNum;
if(isIn2){
possibilities2.addLast(new Integer(i));
}
}//end for
int numPossibilities2 = possibilities2.size();
// System.out.println("numPossibilities1=" + numPossibilities1 + " numPossibilities2 = " + numPossibilities2);
double logHastingRatio = Math.log( (1/ (double)numPossibilities2) / (1/ (double)numPossibilities1) );
//System.out.println("logHastingRatio = " + logHastingRatio);
return logHastingRatio;
}
private double Proposal_HotMultistepOnNodeFlipMu() {
int rootNum = treeModel.getRoot().getNumber();
//unlike the old version, self-move isn't allowed.
int originalNode1 = findAnOnNodeRandomly(); //find an on-node
//System.out.print("Try " + originalNode1);
int[] numStepsFromI_selected =determineTreeNeighborhood(originalNode1, 100000);
//1. Select an unoccupied site within some steps away from it.
LinkedList<Integer> possibilities1 = new LinkedList<Integer>();
for(int i=0; i < numNodes; i++){
// System.out.println("#steps from I_selected " + numStepsFromI_selected[i]);
//make sure no self select
boolean isIn1 = numStepsFromI_selected[i] <= maxNodeLevel && numStepsFromI_selected[i] !=0 && i != rootNum;
if(isIn1 && hotNodes[i] ==1){
possibilities1.addLast(new Integer(i));
}
}//end for
int numPossibilities1 = possibilities1.size();
//if there is a single legal configuration to switch to
if(numPossibilities1 > 0){
int whichMove = (int) (Math.floor(Math.random()*numPossibilities1)); //choose from possibilities
int site_add1 = possibilities1.get(whichMove).intValue();
// System.out.println(" and select " + site_add1);
// System.out.println("selected node = " + site_add1 + " that's " + numStepsFromI_selected[site_add1] + " steps from " + originalNode1);
indicators.setParameterValue(originalNode1, 0); // the existing indicator is now set to be off
indicators.setParameterValue(site_add1, 1); //set the new selected index to the new node.
//Flip mu - so the neighbor that replaces the original node now also inherits the existing node's mu
//Parameter originalNodeMu = mu.getParameter(originalNode1+1); //offset of 1
Parameter originalNodeMu = mu.getParameter(originalNode1);
double[] tmp = originalNodeMu.getParameterValues();
//Parameter newMu = mu.getParameter(site_add1+1); //offset of 1
Parameter newMu = mu.getParameter(site_add1);
double[] tmpNew = newMu.getParameterValues();
originalNodeMu.setParameterValue(0, tmpNew[0]);
originalNodeMu.setParameterValue(1, tmpNew[1]);
newMu.setParameterValue(0, tmp[0]);
newMu.setParameterValue(1, tmp[1]);
//backward calculation
int[] numStepsBackward =determineTreeNeighborhood(site_add1, 100000);
//1. Select an unoccupied site within some steps away from it.
LinkedList<Integer> possibilities2 = new LinkedList<Integer>();
for(int i=0; i < numNodes; i++){
// System.out.println("#steps from I_selected " + numStepsFromI_selected[i]);
//make sure no self select
boolean isIn2 = numStepsBackward[i] <= maxNodeLevel && numStepsBackward[i] !=0 && i != rootNum;
if(isIn2 && hotNodes[i] ==1){
possibilities2.addLast(new Integer(i));
}
}//end for
int numPossibilities2 = possibilities2.size();
// System.out.println("numPossibilities1=" + numPossibilities1 + " numPossibilities2 = " + numPossibilities2);
double logHastingRatio = Math.log( (1/ (double)numPossibilities2) / (1/ (double)numPossibilities1) );
//System.out.println("logHastingRatio = " + logHastingRatio);
return logHastingRatio;
}
else{
return Double.NEGATIVE_INFINITY;
}
}
@Override
public List<Task> createTasks()
{
LinkedList<Task> tasks = new LinkedList<>();
long lFrom = _fromVal.getLongValue();
long lTo = _toVal.getLongValue();
long lIncr = _incrVal.getLongValue();
int P = _numThreads; // number of parallel workers
long N = _numIter; // total number of iterations
long R = N; // remaining number of iterations
long K = -1; // next _numThreads task sizes
TaskType type = null; // type of iterations: range tasks (similar to run-length encoding) make only sense if taskSize>3
for( long i = lFrom; i<=lTo; )
{
K = determineNextBatchSize(R, P);
R -= (K * P);
type = (ParForProgramBlock.USE_RANGE_TASKS_IF_USEFUL && K>3 ) ?
TaskType.RANGE : TaskType.SET;
//for each logical processor
for( int j=0; j<P; j++ )
{
if( i > lTo ) //no more iterations
break;
//create new task and add to list of tasks
Task lTask = new Task(_iterVarName, type);
tasks.addLast(lTask);
// add iterations to task
if( type == TaskType.SET ) {
//value based tasks
for( long k=0; k<K && i<=lTo; k++, i+=lIncr )
lTask.addIteration(new IntObject(i));
}
else {
//determine end of task
long to = Math.min( i+(K-1)*lIncr, lTo );
//range based tasks
lTask.addIteration(new IntObject(i)); //from
lTask.addIteration(new IntObject(to)); //to
lTask.addIteration(new IntObject(lIncr)); //increment
i = to + lIncr;
}
}
}
return tasks;
}
protected Route buildroute(RouteId id) {
NodePortTuple npt;
long srcId = id.getSrc();
long dstId = id.getDst();
LinkedList<NodePortTuple> switchPorts =
new LinkedList<NodePortTuple>();
if (destinationRootedTrees == null) return null;
if (destinationRootedTrees.get(dstId) == null) return null;
Map<Long, Link> nexthoplinks =
destinationRootedTrees.get(dstId).getLinks();
if (!switches.contains(srcId) || !switches.contains(dstId)) {
// This is a switch that is not connected to any other switch
// hence there was no update for links (and hence it is not
// in the network)
log.debug("buildroute: Standalone switch: {}", srcId);
// The only possible non-null path for this case is
// if srcId equals dstId --- and that too is an 'empty' path []
} else if ((nexthoplinks!=null) && (nexthoplinks.get(srcId)!=null)) {
while (srcId != dstId) {
Link l = nexthoplinks.get(srcId);
npt = new NodePortTuple(l.getSrc(), l.getSrcPort());
switchPorts.addLast(npt);
npt = new NodePortTuple(l.getDst(), l.getDstPort());
switchPorts.addLast(npt);
srcId = nexthoplinks.get(srcId).getDst();
}
}
// else, no path exists, and path equals null
Route result = null;
if (switchPorts != null && !switchPorts.isEmpty())
result = new Route(id, switchPorts);
if (log.isTraceEnabled()) {
log.trace("buildroute: {}", result);
}
return result;
}
/**
* This method checks all blocks of each level and creates an ensemble that minimizes
* the epsilon of this ensemble. This is done by choosing disjoint blocks with maximal size,
* i.e. if the block of <code>maxLevel</code> is active, we found the most accurate summary.
* If this block is in the state <b>UNDER-CONSTRUCTION</b> right now, it will take the <b>
* ACTIVE</b> block at level <code>maxLevel - 1</code> and fills the missing partitions by
* choosing appropriate blocks at lower levels.
*
* @return {@link LinkedList} of {@link Quantiles} that contains the summary of the stream that
* have the smallest epsilon compared to all other possible summaries.
*/
private LinkedList<Quantiles> getStreamSummary() {
LinkedList<Quantiles> summary = new LinkedList<Quantiles>();
// if the highest level contains an ACTIVE element, this element will cover the whole window
if (!this.quantiles.get(maxLevel).isEmpty()) {
summary.add(this.quantiles.get(maxLevel).getNewestElement());
return summary;
}
// if there is no ACTIVE element in the highest level we add the only active element of the next
// lower level into the summary. There is at most one element active, because if there would be
// two elements, the block in the highest level must be ACTIVE, too.
Quantiles bigBlock = this.quantiles.get(maxLevel - 1).getNewestElement();
// interval [ 0 ; leftBorder ] not covered yet
int leftBorder = this.quantiles.get(maxLevel - 1).getLifeTime(0);
// interval [ rightBorder ; windowSize ] not covered yet
int rightBorder = this.quantiles.get(maxLevel - 1).getLifeTime(0) + this.quantiles.get(maxLevel - 1).getSize(0);
// there are at most two intervals uncovered. i.e. at the beginning and at the end of the window.
int maxUncovered = this.quantiles.get(0).getSize(0);
// next level
int level = this.maxLevel - 2;
// covering the left uncovered interval
while (level >= 0 && leftBorder > maxUncovered) {
for (int i = this.quantiles.get(level).getAll().size() - 1; i > -1; i--){
if (leftBorder > this.quantiles.get(level).getLifeTime(i)){
leftBorder = this.quantiles.get(level).getLifeTime(i);
summary.addFirst(this.quantiles.get(level).get(i));
}
}
level--;
}
summary.add(bigBlock);
// next level
level = this.maxLevel - 2;
// covering the right uncovered interval
while (level >=0 && rightBorder < this.windowSize - maxUncovered) {
for (int i = 0; i < this.quantiles.get(level).getAll().size(); i++){
if (rightBorder < this.quantiles.get(level).getLifeTime(i) + this.quantiles.get(level).getSize(i)){
rightBorder = this.quantiles.get(level).getLifeTime(i) + this.quantiles.get(level).getSize(i);
summary.addLast(this.quantiles.get(level).get(i));
}
}
level--;
}
return summary;
}
/**
* Find the differences between two texts. Simplifies the problem by
* stripping any common prefix or suffix off the texts before diffing.
* @param text1 Old string to be diffed.
* @param text2 New string to be diffed.
* @param checklines Speedup flag. If false, then don't run a
* line-level diff first to identify the changed areas.
* If true, then run a faster slightly less optimal diff.
* @param deadline Time when the diff should be complete by. Used
* internally for recursive calls. Users should set DiffTimeout instead.
* @return Linked List of Diff objects.
*/
private LinkedList<Diff> diff_main(String text1, String text2,
boolean checklines, long deadline) {
// Check for null inputs.
if (text1 == null || text2 == null) {
throw new IllegalArgumentException("Null inputs. (diff_main)");
}
// Check for equality (speedup).
LinkedList<Diff> diffs;
if (text1.equals(text2)) {
diffs = new LinkedList<Diff>();
if (text1.length() != 0) {
diffs.add(new Diff(Operation.EQUAL, text1));
}
return diffs;
}
// Trim off common prefix (speedup).
int commonlength = diff_commonPrefix(text1, text2);
String commonprefix = text1.substring(0, commonlength);
text1 = text1.substring(commonlength);
text2 = text2.substring(commonlength);
// Trim off common suffix (speedup).
commonlength = diff_commonSuffix(text1, text2);
String commonsuffix = text1.substring(text1.length() - commonlength);
text1 = text1.substring(0, text1.length() - commonlength);
text2 = text2.substring(0, text2.length() - commonlength);
// Compute the diff on the middle block.
diffs = diff_compute(text1, text2, checklines, deadline);
// Restore the prefix and suffix.
if (commonprefix.length() != 0) {
diffs.addFirst(new Diff(Operation.EQUAL, commonprefix));
}
if (commonsuffix.length() != 0) {
diffs.addLast(new Diff(Operation.EQUAL, commonsuffix));
}
diff_cleanupMerge(diffs);
return diffs;
}