Mercurial > jhg
comparison src/org/tmatesoft/hg/internal/PatchGenerator.java @ 542:a71a05ec11bc
Towards annotate/blame support: general outline of the functionality
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Thu, 14 Feb 2013 16:36:13 +0100 |
| parents | 946b13196252 |
| children | 1e95f48d9886 |
comparison
equal
deleted
inserted
replaced
| 541:946b13196252 | 542:a71a05ec11bc |
|---|---|
| 156 | 156 |
| 157 public void end() { | 157 public void end() { |
| 158 } | 158 } |
| 159 } | 159 } |
| 160 | 160 |
| 161 static class DeltaDumpInspector implements MatchInspector { | 161 static class DeltaInspector implements MatchInspector { |
| 162 protected int changeStartS1, changeStartS2; | 162 protected int changeStartS1, changeStartS2; |
| 163 protected ChunkSequence seq1, seq2; | 163 protected ChunkSequence seq1, seq2; |
| 164 | 164 |
| 165 | 165 |
| 166 public void begin(ChunkSequence s1, ChunkSequence s2) { | 166 public void begin(ChunkSequence s1, ChunkSequence s2) { |
| 168 seq2 = s2; | 168 seq2 = s2; |
| 169 changeStartS1 = changeStartS2 = 0; | 169 changeStartS1 = changeStartS2 = 0; |
| 170 } | 170 } |
| 171 | 171 |
| 172 public void match(int startSeq1, int startSeq2, int matchLength) { | 172 public void match(int startSeq1, int startSeq2, int matchLength) { |
| 173 reportDeltaElement(startSeq1, startSeq2); | 173 reportDeltaElement(startSeq1, startSeq2, matchLength); |
| 174 changeStartS1 = startSeq1 + matchLength; | 174 changeStartS1 = startSeq1 + matchLength; |
| 175 changeStartS2 = startSeq2 + matchLength; | 175 changeStartS2 = startSeq2 + matchLength; |
| 176 } | 176 } |
| 177 | 177 |
| 178 public void end() { | 178 public void end() { |
| 179 if (changeStartS1 < seq1.chunkCount() || changeStartS2 < seq2.chunkCount()) { | 179 if (changeStartS1 < seq1.chunkCount() || changeStartS2 < seq2.chunkCount()) { |
| 180 reportDeltaElement(seq1.chunkCount(), seq2.chunkCount()); | 180 reportDeltaElement(seq1.chunkCount(), seq2.chunkCount(), 0); |
| 181 } | 181 } |
| 182 } | 182 } |
| 183 | 183 |
| 184 protected void reportDeltaElement(int matchStartSeq1, int matchStartSeq2) { | 184 protected void reportDeltaElement(int matchStartSeq1, int matchStartSeq2, int matchLength) { |
| 185 if (changeStartS1 < matchStartSeq1) { | 185 if (changeStartS1 < matchStartSeq1) { |
| 186 if (changeStartS2 < matchStartSeq2) { | 186 if (changeStartS2 < matchStartSeq2) { |
| 187 System.out.printf("changed [%d..%d) with [%d..%d)\n", changeStartS1, matchStartSeq1, changeStartS2, matchStartSeq2); | 187 changed(changeStartS1, matchStartSeq1, changeStartS2, matchStartSeq2); |
| 188 } else { | 188 } else { |
| 189 assert changeStartS2 == matchStartSeq2; | 189 assert changeStartS2 == matchStartSeq2; |
| 190 System.out.printf("deleted [%d..%d)\n", changeStartS1, matchStartSeq1); | 190 deleted(changeStartS1, matchStartSeq1); |
| 191 } | 191 } |
| 192 } else { | 192 } else { |
| 193 assert changeStartS1 == matchStartSeq1; | 193 assert changeStartS1 == matchStartSeq1; |
| 194 if(changeStartS2 < matchStartSeq2) { | 194 if(changeStartS2 < matchStartSeq2) { |
| 195 System.out.printf("added [%d..%d)\n", changeStartS2, matchStartSeq2); | 195 added(matchStartSeq1, changeStartS2, matchStartSeq2); |
| 196 } else { | 196 } else { |
| 197 assert changeStartS2 == matchStartSeq2; | 197 assert changeStartS2 == matchStartSeq2; |
| 198 System.out.printf("adjustent equal blocks %d, %d and %d,%d\n", changeStartS1, matchStartSeq1, changeStartS2, matchStartSeq2); | 198 System.out.printf("adjustent equal blocks %d, %d and %d,%d\n", changeStartS1, matchStartSeq1, changeStartS2, matchStartSeq2); |
| 199 } | 199 } |
| 200 } | 200 } |
| 201 } | 201 if (matchLength > 0) { |
| 202 } | 202 unchanged(matchStartSeq1, matchStartSeq2, matchLength); |
| 203 | 203 } |
| 204 static class PatchFillInspector extends DeltaDumpInspector { | 204 } |
| 205 | |
| 206 /** | |
| 207 * [s1From..s1To) replaced with [s2From..s2To) | |
| 208 */ | |
| 209 protected void changed(int s1From, int s1To, int s2From, int s2To) { | |
| 210 // NO-OP | |
| 211 } | |
| 212 | |
| 213 protected void deleted(int s1From, int s1To) { | |
| 214 // NO-OP | |
| 215 } | |
| 216 | |
| 217 protected void added(int s1InsertPoint, int s2From, int s2To) { | |
| 218 // NO-OP | |
| 219 } | |
| 220 | |
| 221 protected void unchanged(int s1From, int s2From, int length) { | |
| 222 // NO-OP | |
| 223 } | |
| 224 } | |
| 225 | |
| 226 static class DeltaDumpInspector extends DeltaInspector { | |
| 227 | |
| 228 @Override | |
| 229 protected void changed(int s1From, int s1To, int s2From, int s2To) { | |
| 230 System.out.printf("changed [%d..%d) with [%d..%d)\n", s1From, s1To, s2From, s2To); | |
| 231 } | |
| 232 | |
| 233 @Override | |
| 234 protected void deleted(int s1From, int s1To) { | |
| 235 System.out.printf("deleted [%d..%d)\n", s1From, s1To); | |
| 236 } | |
| 237 | |
| 238 @Override | |
| 239 protected void added(int s1InsertPoint, int s2From, int s2To) { | |
| 240 System.out.printf("added [%d..%d) at %d\n", s2From, s2To, s1InsertPoint); | |
| 241 } | |
| 242 | |
| 243 } | |
| 244 | |
| 245 static class PatchFillInspector extends DeltaInspector { | |
| 205 private final Patch deltaCollector; | 246 private final Patch deltaCollector; |
| 206 | 247 |
| 207 PatchFillInspector(Patch p) { | 248 PatchFillInspector(Patch p) { |
| 208 assert p != null; | 249 assert p != null; |
| 209 deltaCollector = p; | 250 deltaCollector = p; |
| 210 } | 251 } |
| 211 | 252 |
| 212 @Override | 253 @Override |
| 213 protected void reportDeltaElement(int matchStartSeq1, int matchStartSeq2) { | 254 protected void changed(int s1From, int s1To, int s2From, int s2To) { |
| 214 if (changeStartS1 < matchStartSeq1) { | 255 int from = seq1.chunk(s1From).getOffset(); |
| 215 int from = seq1.chunk(changeStartS1).getOffset(); | 256 int to = seq1.chunk(s1To).getOffset(); |
| 216 int to = seq1.chunk(matchStartSeq1).getOffset(); | 257 byte[] data = seq2.data(s2From, s2To); |
| 217 byte[] data = seq2.data(changeStartS2, matchStartSeq2); | 258 deltaCollector.add(from, to, data); |
| 218 deltaCollector.add(from, to, data); | 259 } |
| 219 } else { | 260 |
| 220 assert changeStartS1 == matchStartSeq1; | 261 @Override |
| 221 int insPoint = seq1.chunk(changeStartS1).getOffset(); | 262 protected void deleted(int s1From, int s1To) { |
| 222 byte[] data = seq2.data(changeStartS2, matchStartSeq2); | 263 int from = seq1.chunk(s1From).getOffset(); |
| 223 deltaCollector.add(insPoint, insPoint, data); | 264 int to = seq1.chunk(s1To).getOffset(); |
| 224 } | 265 deltaCollector.add(from, to, new byte[0]); |
| 266 } | |
| 267 | |
| 268 @Override | |
| 269 protected void added(int s1InsertPoint, int s2From, int s2To) { | |
| 270 int insPoint = seq1.chunk(s1InsertPoint).getOffset(); | |
| 271 byte[] data = seq2.data(s2From, s2To); | |
| 272 deltaCollector.add(insPoint, insPoint, data); | |
| 225 } | 273 } |
| 226 } | 274 } |
| 227 | 275 |
| 228 | 276 |
| 229 | 277 |
| 255 init(prev, content); | 303 init(prev, content); |
| 256 findMatchingBlocks(new PatchFillInspector(rv)); | 304 findMatchingBlocks(new PatchFillInspector(rv)); |
| 257 return rv; | 305 return rv; |
| 258 } | 306 } |
| 259 | 307 |
| 260 private static class ChunkSequence { | 308 /* |
| 309 * TODO shall be parameterized (template?) and refacctored to facilitate matching non lines only | |
| 310 * (sequence diff algorithm above doesn't care about sequence nature) | |
| 311 */ | |
| 312 static final class ChunkSequence { | |
| 261 | 313 |
| 262 private final byte[] input; | 314 private final byte[] input; |
| 263 private ArrayList<ByteChain> lines; | 315 private ArrayList<ByteChain> lines; |
| 264 | 316 |
| 265 public ChunkSequence(byte[] data) { | 317 public ChunkSequence(byte[] data) { |
