1 11 package org.eclipse.compare.rangedifferencer; 12 13 import java.util.ArrayList ; 14 15 import org.eclipse.core.runtime.Assert; 16 import org.eclipse.core.runtime.IProgressMonitor; 17 18 23 class OldDifferencer { 24 25 private static final RangeDifference[] EMPTY_RESULT= new RangeDifference[0]; 26 27 private static class LinkedRangeDifference extends RangeDifference { 28 29 static final int INSERT= 0; 30 static final int DELETE= 1; 31 32 LinkedRangeDifference fNext; 33 34 37 LinkedRangeDifference() { 38 super(ERROR); 39 fNext= null; 40 } 41 42 45 LinkedRangeDifference(LinkedRangeDifference next, int operation) { 46 super(operation); 47 fNext= next; 48 } 49 50 53 LinkedRangeDifference getNext() { 54 return fNext; 55 } 56 57 boolean isDelete() { 58 return kind() == DELETE; 59 } 60 61 boolean isInsert() { 62 return kind() == INSERT; 63 } 64 65 68 void setNext(LinkedRangeDifference next) { 69 fNext= next; 70 } 71 } 72 73 public static RangeDifference[] findDifferences(IProgressMonitor pm, IRangeComparator left, IRangeComparator right) { 74 75 Assert.isTrue(right.getClass().equals(left.getClass())); 77 78 int rightSize= right.getRangeCount(); 79 int leftSize= left.getRangeCount(); 80 int diagLen= 2 * Math.max(rightSize, leftSize); int maxDiagonal= diagLen; 86 int lastDiagonal[]= new int[diagLen + 1]; int origin= diagLen / 2; 90 LinkedRangeDifference script[]= new LinkedRangeDifference[diagLen + 1]; 92 int row, col; 93 94 for (row= 0; row < rightSize && row < leftSize && rangesEqual(right, row, left, row) == true;) 96 row++; 97 98 lastDiagonal[origin]= row; 99 script[origin]= null; 100 int lower= (row == rightSize) ? origin + 1 : origin - 1; 101 int upper= (row == leftSize) ? origin - 1 : origin + 1; 102 103 if (lower > upper) 104 return EMPTY_RESULT; 105 106 108 for (int d= 1; d <= maxDiagonal; ++d) { 111 if (pm != null) 112 pm.worked(1); 113 114 if (right.skipRangeComparison(d, maxDiagonal, left)) 115 return EMPTY_RESULT; 117 for (int k= lower; k <= upper; k += 2) { LinkedRangeDifference edit; 120 121 if (pm != null && pm.isCanceled()) 122 return EMPTY_RESULT; 123 124 if (k == origin - d || k != origin + d && lastDiagonal[k + 1] >= lastDiagonal[k - 1]) { 125 row= lastDiagonal[k + 1] + 1; 129 edit= new LinkedRangeDifference(script[k + 1], LinkedRangeDifference.DELETE); 130 } else { 131 row= lastDiagonal[k - 1]; 135 edit= new LinkedRangeDifference(script[k - 1], LinkedRangeDifference.INSERT); 136 } 137 col= row + k - origin; 138 edit.fRightStart= row; 139 edit.fLeftStart= col; 140 Assert.isTrue(k >= 0 && k <= maxDiagonal); 141 script[k]= edit; 142 143 while (row < rightSize && col < leftSize && rangesEqual(right, row, left, col) == true) { 145 ++row; 146 ++col; 147 } 148 149 Assert.isTrue(k >= 0 && k <= maxDiagonal); lastDiagonal[k]= row; 151 152 if (row == rightSize && col == leftSize) { 153 return createDifferencesRanges(script[k]); 155 } 156 if (row == rightSize) 157 lower= k + 2; 158 if (col == leftSize) 159 upper= k - 2; 160 } 161 --lower; 162 ++upper; 163 } 164 Assert.isTrue(false); 166 return null; 167 } 168 169 172 private static boolean rangesEqual(IRangeComparator a, int ai, IRangeComparator b, int bi) { 173 return a.rangesEqual(ai, b, bi); 174 } 175 176 182 private static RangeDifference[] createDifferencesRanges(LinkedRangeDifference start) { 183 184 LinkedRangeDifference ep= reverseDifferences(start); 185 ArrayList result= new ArrayList (); 186 RangeDifference es= null; 187 188 while (ep != null) { 189 es= new RangeDifference(RangeDifference.CHANGE); 190 191 if (ep.isInsert()) { 192 es.fRightStart= ep.fRightStart + 1; 193 es.fLeftStart= ep.fLeftStart; 194 RangeDifference b= ep; 195 do { 196 ep= ep.getNext(); 197 es.fLeftLength++; 198 } while (ep != null && ep.isInsert() && ep.fRightStart == b.fRightStart); 199 } else { 200 es.fRightStart= ep.fRightStart; 201 es.fLeftStart= ep.fLeftStart; 202 203 RangeDifference a= ep; 204 do { 208 a= ep; 209 ep= ep.getNext(); 210 es.fRightLength++; 211 } while (ep != null && ep.isDelete() && ep.fRightStart == a.fRightStart + 1); 212 213 boolean change= (ep != null && ep.isInsert() && ep.fRightStart == a.fRightStart); 214 215 if (change) { 216 RangeDifference b= ep; 217 do { 221 ep= ep.getNext(); 222 es.fLeftLength++; 223 } while (ep != null && ep.isInsert() && ep.fRightStart == b.fRightStart); 224 } else { 225 es.fLeftLength= 0; 226 } 227 es.fLeftStart++; 229 } 230 es.fRightStart--; 234 es.fLeftStart--; 235 result.add(es); 236 } 237 return (RangeDifference[]) result.toArray(EMPTY_RESULT); 238 } 239 240 243 private static LinkedRangeDifference reverseDifferences(LinkedRangeDifference start) { 244 LinkedRangeDifference ep, behind, ahead; 245 246 ahead= start; 247 ep= null; 248 while (ahead != null) { 249 behind= ep; 250 ep= ahead; 251 ahead= ahead.getNext(); 252 ep.setNext(behind); 253 } 254 return ep; 255 } 256 } 257 | Popular Tags |