1 11 package org.eclipse.compare.rangedifferencer; 12 13 import java.util.ArrayList ; 14 import java.util.List ; 15 16 import org.eclipse.compare.internal.CompareMessages; 17 import org.eclipse.compare.internal.CompareUIPlugin; 18 import org.eclipse.core.runtime.*; 19 20 41 public final class RangeDifferencer { 42 43 private static final RangeDifference[] EMPTY_RESULT= new RangeDifference[0]; 44 45 48 private RangeDifferencer() { 49 } 51 52 61 public static RangeDifference[] findDifferences(IRangeComparator left, IRangeComparator right) { 62 return findDifferences((IProgressMonitor)null, left, right); 63 } 64 65 76 public static RangeDifference[] findDifferences(IProgressMonitor pm, IRangeComparator left, IRangeComparator right) { 77 if (isUseOldDifferencer()) { 78 return OldDifferencer.findDifferences(pm, left, right); 79 } 80 return RangeComparatorLCS.findDifferences(pm, left, right); 81 } 82 83 private static boolean isUseOldDifferencer() { 84 return CompareUIPlugin.getDefault().isUseOldDifferencer(); 85 } 86 87 99 public static RangeDifference[] findDifferences(IRangeComparator ancestor, IRangeComparator left, IRangeComparator right) { 100 return findDifferences(null, ancestor, left, right); 101 } 102 103 117 public static RangeDifference[] findDifferences(IProgressMonitor pm, IRangeComparator ancestor, IRangeComparator left, IRangeComparator right) { 118 try { 119 if (ancestor == null) 120 return findDifferences(pm, left, right); 121 SubMonitor monitor = SubMonitor.convert(pm, CompareMessages.RangeComparatorLCS_0, 100); 122 RangeDifference[] leftAncestorScript= null; 123 RangeDifference[] rightAncestorScript= findDifferences(monitor.newChild(50), ancestor, right); 124 if (rightAncestorScript != null) { 125 monitor.setWorkRemaining(100); 126 leftAncestorScript= findDifferences(monitor.newChild(50), ancestor, left); 127 } 128 if (rightAncestorScript == null || leftAncestorScript == null) 129 return null; 130 131 DifferencesIterator myIter= new DifferencesIterator(rightAncestorScript); 132 DifferencesIterator yourIter= new DifferencesIterator(leftAncestorScript); 133 134 List diff3= new ArrayList (); 135 diff3.add(new RangeDifference(RangeDifference.ERROR)); 137 int changeRangeStart= 0; 138 int changeRangeEnd= 0; 139 monitor.setWorkRemaining(rightAncestorScript.length + leftAncestorScript.length); 143 while (myIter.fDifference != null || yourIter.fDifference != null) { 144 145 DifferencesIterator startThread; 146 myIter.removeAll(); 147 yourIter.removeAll(); 148 if (myIter.fDifference == null) 152 startThread= yourIter; 153 else if (yourIter.fDifference == null) 154 startThread= myIter; 155 else { if (myIter.fDifference.fLeftStart <= yourIter.fDifference.fLeftStart) startThread= myIter; 158 else 159 startThread= yourIter; 160 } 161 changeRangeStart= startThread.fDifference.fLeftStart; 162 changeRangeEnd= startThread.fDifference.leftEnd(); 163 164 startThread.next(); 165 monitor.worked(1); 166 DifferencesIterator other= startThread.other(myIter, yourIter); 171 while (other.fDifference != null && other.fDifference.fLeftStart <= changeRangeEnd) { 172 int newMax= other.fDifference.leftEnd(); 173 other.next(); 174 monitor.worked(1); 175 if (newMax >= changeRangeEnd) { 176 changeRangeEnd= newMax; 177 other= other.other(myIter, yourIter); 178 } 179 } 180 diff3.add(createRangeDifference3(myIter, yourIter, diff3, right, left, changeRangeStart, changeRangeEnd)); 181 } 182 183 diff3.remove(0); 185 return (RangeDifference[]) diff3.toArray(EMPTY_RESULT); 186 } finally { 187 if (pm != null) 188 pm.done(); 189 } 190 } 191 192 201 public static RangeDifference[] findRanges(IRangeComparator left, IRangeComparator right) { 202 return findRanges((IProgressMonitor)null, left, right); 203 } 204 205 216 public static RangeDifference[] findRanges(IProgressMonitor pm, IRangeComparator left, IRangeComparator right) { 217 RangeDifference[] in= findDifferences(pm, left, right); 218 List out= new ArrayList (); 219 220 RangeDifference rd; 221 222 int mstart= 0; 223 int ystart= 0; 224 225 for (int i= 0; i < in.length; i++) { 226 RangeDifference es= in[i]; 227 228 rd= new RangeDifference(RangeDifference.NOCHANGE, mstart, es.rightStart() - mstart, ystart, es.leftStart() - ystart); 229 if (rd.maxLength() != 0) 230 out.add(rd); 231 232 out.add(es); 233 234 mstart= es.rightEnd(); 235 ystart= es.leftEnd(); 236 } 237 rd= new RangeDifference(RangeDifference.NOCHANGE, mstart, right.getRangeCount() - mstart, ystart, left.getRangeCount() - ystart); 238 if (rd.maxLength() > 0) 239 out.add(rd); 240 241 return (RangeDifference[]) out.toArray(EMPTY_RESULT); 242 } 243 244 256 public static RangeDifference[] findRanges(IRangeComparator ancestor, IRangeComparator left, IRangeComparator right) { 257 return findRanges(null, ancestor, left, right); 258 } 259 260 274 public static RangeDifference[] findRanges(IProgressMonitor pm, IRangeComparator ancestor, IRangeComparator left, IRangeComparator right) { 275 276 if (ancestor == null) 277 return findRanges(pm, left, right); 278 279 RangeDifference[] in= findDifferences(pm, ancestor, left, right); 280 List out= new ArrayList (); 281 282 RangeDifference rd; 283 284 int mstart= 0; 285 int ystart= 0; 286 int astart= 0; 287 288 for (int i= 0; i < in.length; i++) { 289 RangeDifference es= in[i]; 290 291 rd= new RangeDifference(RangeDifference.NOCHANGE, mstart, es.rightStart() - mstart, ystart, es.leftStart() - ystart, astart, es.ancestorStart() - astart); 292 if (rd.maxLength() > 0) 293 out.add(rd); 294 295 out.add(es); 296 297 mstart= es.rightEnd(); 298 ystart= es.leftEnd(); 299 astart= es.ancestorEnd(); 300 } 301 rd= new RangeDifference(RangeDifference.NOCHANGE, mstart, right.getRangeCount() - mstart, ystart, left.getRangeCount() - ystart, astart, ancestor.getRangeCount() - astart); 302 if (rd.maxLength() > 0) 303 out.add(rd); 304 305 return (RangeDifference[]) out.toArray(EMPTY_RESULT); 306 } 307 308 310 314 private static RangeDifference createRangeDifference3(DifferencesIterator myIter, DifferencesIterator yourIter, List diff3, 315 IRangeComparator right, IRangeComparator left, int changeRangeStart, int changeRangeEnd) { 316 317 int rightStart, rightEnd; 318 int leftStart, leftEnd; 319 int kind= RangeDifference.ERROR; 320 RangeDifference last= (RangeDifference) diff3.get(diff3.size() - 1); 321 322 Assert.isTrue((myIter.getCount() != 0 || yourIter.getCount() != 0)); if (myIter.getCount() == 0) { rightStart= changeRangeStart - last.ancestorEnd() + last.rightEnd(); 328 rightEnd= changeRangeEnd - last.ancestorEnd() + last.rightEnd(); 329 kind= RangeDifference.LEFT; 330 } else { 331 RangeDifference f= (RangeDifference) myIter.fRange.get(0); 332 RangeDifference l= (RangeDifference) myIter.fRange.get(myIter.fRange.size() - 1); 333 rightStart= changeRangeStart - f.fLeftStart + f.fRightStart; 334 rightEnd= changeRangeEnd - l.leftEnd() + l.rightEnd(); 335 } 336 337 if (yourIter.getCount() == 0) { leftStart= changeRangeStart - last.ancestorEnd() + last.leftEnd(); 339 leftEnd= changeRangeEnd - last.ancestorEnd() + last.leftEnd(); 340 kind= RangeDifference.RIGHT; 341 } else { 342 RangeDifference f= (RangeDifference) yourIter.fRange.get(0); 343 RangeDifference l= (RangeDifference) yourIter.fRange.get(yourIter.fRange.size() - 1); 344 leftStart= changeRangeStart - f.fLeftStart + f.fRightStart; 345 leftEnd= changeRangeEnd - l.leftEnd() + l.rightEnd(); 346 } 347 348 if (kind == RangeDifference.ERROR) { if (rangeSpansEqual(right, rightStart, rightEnd - rightStart, left, leftStart, leftEnd - leftStart)) 350 kind= RangeDifference.ANCESTOR; 351 else 352 kind= RangeDifference.CONFLICT; 353 } 354 return new RangeDifference(kind, rightStart, rightEnd - rightStart, leftStart, leftEnd - leftStart, changeRangeStart, changeRangeEnd - changeRangeStart); 355 } 356 357 360 private static boolean rangeSpansEqual(IRangeComparator right, int rightStart, int rightLen, IRangeComparator left, int leftStart, int leftLen) { 361 if (rightLen == leftLen) { 362 int i= 0; 363 for (i= 0; i < rightLen; i++) { 364 if (!rangesEqual(right, rightStart + i, left, leftStart + i)) 365 break; 366 } 367 if (i == rightLen) 368 return true; 369 } 370 return false; 371 } 372 373 376 private static boolean rangesEqual(IRangeComparator a, int ai, IRangeComparator b, int bi) { 377 return a.rangesEqual(ai, b, bi); 378 } 379 } 380 381 | Popular Tags |