tikhomirov@680: /* tikhomirov@680: * Copyright (c) 2013 TMate Software Ltd tikhomirov@680: * tikhomirov@680: * This program is free software; you can redistribute it and/or modify tikhomirov@680: * it under the terms of the GNU General Public License as published by tikhomirov@680: * the Free Software Foundation; version 2 of the License. tikhomirov@680: * tikhomirov@680: * This program is distributed in the hope that it will be useful, tikhomirov@680: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@680: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@680: * GNU General Public License for more details. tikhomirov@680: * tikhomirov@680: * For information on how to redistribute this software under tikhomirov@680: * the terms of a license other than GNU General Public License tikhomirov@680: * contact TMate Software at support@hg4j.com tikhomirov@680: */ tikhomirov@680: package org.tmatesoft.hg.internal.diff; tikhomirov@680: tikhomirov@680: import java.util.ArrayList; tikhomirov@680: tikhomirov@680: import org.tmatesoft.hg.internal.DiffHelper; tikhomirov@680: import org.tmatesoft.hg.internal.IntSliceSeq; tikhomirov@680: import org.tmatesoft.hg.internal.IntTuple; tikhomirov@680: import org.tmatesoft.hg.internal.DiffHelper.ChunkSequence; tikhomirov@680: tikhomirov@680: /** tikhomirov@680: * Sequence of pairs of ranges (s1Start,s1End) - (s2Start, s2End) tikhomirov@680: * @author Artem Tikhomirov tikhomirov@680: * @author TMate Software Ltd. tikhomirov@680: */ tikhomirov@680: public class DiffRangeMap extends DiffHelper.DeltaInspector> { tikhomirov@680: private final IntSliceSeq ranges; tikhomirov@680: tikhomirov@680: public DiffRangeMap() { tikhomirov@680: ranges = new IntSliceSeq(5); tikhomirov@680: } tikhomirov@680: tikhomirov@680: /** tikhomirov@680: * handy method to fill this map from supplied DiffHelper tikhomirov@680: *
tikhomirov@680: 	 *   DiffHelper pg = ...
tikhomirov@680: 	 *   pg.findMatchingBlocks(p1ToBase); // doesn't compile
tikhomirov@680: 	 *   DiffHelper dh = pg;
tikhomirov@680: 	 *   dh.findMatchingBlocks(p1ToBase); // compiles ok!
tikhomirov@680: 	 * 
tikhomirov@680: */ tikhomirov@680: public DiffRangeMap fill(DiffHelper dh) { tikhomirov@680: dh.findMatchingBlocks(this); tikhomirov@680: return this; tikhomirov@680: } tikhomirov@680: tikhomirov@680: @Override tikhomirov@680: protected void added(int s1InsertPoint, int s2From, int s2To) { tikhomirov@680: ranges.add(s1InsertPoint, s1InsertPoint, s2From, s2To, (int)'+'); tikhomirov@680: } tikhomirov@680: @Override tikhomirov@680: protected void changed(int s1From, int s1To, int s2From, int s2To) { tikhomirov@680: ranges.add(s1From, s1To, s2From, s2To, (int)'*'); tikhomirov@680: } tikhomirov@680: @Override tikhomirov@680: protected void deleted(int s2DeletePoint, int s1From, int s1To) { tikhomirov@680: ranges.add(s1From, s1To, s2DeletePoint, s2DeletePoint, (int)'-'); tikhomirov@680: } tikhomirov@680: @Override tikhomirov@680: protected void unchanged(int s1From, int s2From, int length) { tikhomirov@680: ranges.add(s1From, s1From + length, s2From, s2From + length, (int)'='); tikhomirov@680: } tikhomirov@680: tikhomirov@680: public Iterable findInSource(int sourceStart, int sourceEnd) { tikhomirov@680: ArrayList rv = new ArrayList(4); tikhomirov@680: for (IntTuple t : ranges) { tikhomirov@680: int srcRangeStart = t.at(0); tikhomirov@680: int srcRangeEnd = t.at(1); tikhomirov@680: if (srcRangeEnd <= sourceStart) { // srcRangeEnd exclusive tikhomirov@680: continue; tikhomirov@680: } tikhomirov@680: if (srcRangeStart >= sourceEnd) { tikhomirov@680: break; tikhomirov@680: } tikhomirov@680: rv.add(new RangePair(srcRangeStart, srcRangeEnd, t.at(2), t.at(3))); tikhomirov@680: } tikhomirov@680: return rv; tikhomirov@680: } tikhomirov@680: tikhomirov@680: public Iterable insertions() { tikhomirov@680: return rangesOfKind('+'); tikhomirov@680: } tikhomirov@680: tikhomirov@680: public Iterable same() { tikhomirov@680: return rangesOfKind('='); tikhomirov@680: } tikhomirov@680: tikhomirov@680: private Iterable rangesOfKind(int kind) { tikhomirov@680: ArrayList rv = new ArrayList(4); tikhomirov@680: for (IntTuple t : ranges) { tikhomirov@680: if (t.at(4) == kind) { tikhomirov@680: rv.add(new RangePair(t.at(0), t.at(1), t.at(2), t.at(3))); tikhomirov@680: } tikhomirov@680: } tikhomirov@680: return rv; tikhomirov@680: } tikhomirov@680: tikhomirov@680: public static final class RangePair { tikhomirov@680: private final int s1Start; tikhomirov@680: private final int s1End; tikhomirov@680: private final int s2Start; tikhomirov@680: private final int s2End; tikhomirov@680: tikhomirov@680: public RangePair(int s1Start, int s1End, int s2Start, int s2End) { tikhomirov@680: this.s1Start = s1Start; tikhomirov@680: this.s1End = s1End; tikhomirov@680: this.s2Start = s2Start; tikhomirov@680: this.s2End = s2End; tikhomirov@680: } tikhomirov@680: public int start1() { tikhomirov@680: return s1Start; tikhomirov@680: } tikhomirov@680: public int end1() { tikhomirov@680: return s1End; tikhomirov@680: } tikhomirov@680: public int length1() { tikhomirov@680: return s1End - s1Start; tikhomirov@680: } tikhomirov@680: public int start2() { tikhomirov@680: return s2Start; tikhomirov@680: } tikhomirov@680: public int end2() { tikhomirov@680: return s2End; tikhomirov@680: } tikhomirov@680: public int length2() { tikhomirov@680: return s2End - s2Start; tikhomirov@680: } tikhomirov@680: @Override tikhomirov@680: public String toString() { tikhomirov@680: return String.format("[%d..%d)->[%d..%d)", s1Start, s1End, s2Start, s2End); tikhomirov@680: } tikhomirov@680: } tikhomirov@680: }