comparison src/org/tmatesoft/hg/repo/Revlog.java @ 471:7bcfbc255f48

Merge changes from smartgit3 branch into 1.1 stream
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 11 Jul 2012 20:40:47 +0200
parents 909306e412e2 2e402c12ebc6
children b3c16d1aede0
comparison
equal deleted inserted replaced
470:31bd09da0dcf 471:7bcfbc255f48
26 import java.util.List; 26 import java.util.List;
27 27
28 import org.tmatesoft.hg.core.Nodeid; 28 import org.tmatesoft.hg.core.Nodeid;
29 import org.tmatesoft.hg.internal.DataAccess; 29 import org.tmatesoft.hg.internal.DataAccess;
30 import org.tmatesoft.hg.internal.Experimental; 30 import org.tmatesoft.hg.internal.Experimental;
31 import org.tmatesoft.hg.internal.IntMap;
31 import org.tmatesoft.hg.internal.Preview; 32 import org.tmatesoft.hg.internal.Preview;
32 import org.tmatesoft.hg.internal.RevlogStream; 33 import org.tmatesoft.hg.internal.RevlogStream;
33 import org.tmatesoft.hg.util.Adaptable; 34 import org.tmatesoft.hg.util.Adaptable;
34 import org.tmatesoft.hg.util.ByteChannel; 35 import org.tmatesoft.hg.util.ByteChannel;
35 import org.tmatesoft.hg.util.CancelSupport; 36 import org.tmatesoft.hg.util.CancelSupport;
285 * @param end 286 * @param end
286 * @param inspector 287 * @param inspector
287 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> 288 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
288 */ 289 */
289 @Experimental 290 @Experimental
290 public void indexWalk(int start, int end, final Revlog.Inspector inspector) throws HgRuntimeException { 291 public final void indexWalk(int start, int end, final Revlog.Inspector inspector) throws HgRuntimeException {
291 int lastRev = getLastRevision(); 292 int lastRev = getLastRevision();
292 if (start == TIP) { 293 final int _start = start == TIP ? lastRev : start;
293 start = lastRev;
294 }
295 if (end == TIP) { 294 if (end == TIP) {
296 end = lastRev; 295 end = lastRev;
297 } 296 }
298 final RevisionInspector revisionInsp = Adaptable.Factory.getAdapter(inspector, RevisionInspector.class, null); 297 final RevisionInspector revisionInsp = Adaptable.Factory.getAdapter(inspector, RevisionInspector.class, null);
299 final ParentInspector parentInsp = Adaptable.Factory.getAdapter(inspector, ParentInspector.class, null); 298 final ParentInspector parentInsp = Adaptable.Factory.getAdapter(inspector, ParentInspector.class, null);
300 final Nodeid[] allRevisions = parentInsp == null ? null : new Nodeid[end - start + 1]; 299 final Nodeid[] allRevisions = parentInsp == null ? null : new Nodeid[end - _start + 1];
301 300 // next are to build set of parent indexes that are not part of the range iteration
302 content.iterate(start, end, false, new RevlogStream.Inspector() { 301 // i.e. those parents we need to read separately. See Issue 31 for details.
302 final int[] firstParentIndexes = parentInsp == null || _start == 0 ? null : new int[allRevisions.length];
303 final int[] secondParentIndexes = parentInsp == null || _start == 0 ? null : new int[allRevisions.length];
304 final IntMap<Nodeid> missingParents = parentInsp == null || _start == 0 ? null : new IntMap<Nodeid>(16);
305
306 content.iterate(_start, end, false, new RevlogStream.Inspector() {
307 private int i = 0;
303 308
304 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) { 309 public void next(int revisionIndex, int actualLen, int baseRevIndex, int linkRevIndex, int parent1RevIndex, int parent2RevIndex, byte[] nodeid, DataAccess data) {
305 Nodeid nid = Nodeid.fromBinary(nodeid, 0); 310 Nodeid nid = Nodeid.fromBinary(nodeid, 0);
306 if (revisionInsp != null) { 311 if (revisionInsp != null) {
307 revisionInsp.next(revisionNumber, nid, linkRevision); 312 revisionInsp.next(revisionIndex, nid, linkRevIndex);
308 } 313 }
309 if (parentInsp != null) { 314 if (parentInsp != null) {
310 Nodeid p1 = parent1Revision == -1 ? Nodeid.NULL : allRevisions[parent1Revision]; 315 allRevisions[i] = nid;
311 Nodeid p2 = parent2Revision == -1 ? Nodeid.NULL : allRevisions[parent2Revision]; 316 if (_start > 0) {
312 allRevisions[revisionNumber] = nid; 317 firstParentIndexes[i] = parent1RevIndex;
313 parentInsp.next(revisionNumber, nid, parent1Revision, parent2Revision, p1, p2); 318 secondParentIndexes[i] = parent2RevIndex;
319 if (parent1RevIndex < _start && parent1RevIndex >= 0) {
320 missingParents.put(parent1RevIndex, null);
321 }
322 if (parent2RevIndex < _start && parent2RevIndex >= 0) {
323 missingParents.put(parent2RevIndex, null);
324 }
325 } else {
326 Nodeid p1 = parent1RevIndex == -1 ? Nodeid.NULL : allRevisions[parent1RevIndex];
327 Nodeid p2 = parent2RevIndex == -1 ? Nodeid.NULL : allRevisions[parent2RevIndex];
328 parentInsp.next(revisionIndex, allRevisions[i], parent1RevIndex, parent2RevIndex, p1, p2);
329 }
330 i++;
314 } 331 }
315 } 332 }
316 }); 333 });
334 if (parentInsp != null && _start > 0) {
335 assert missingParents.size() > 0; // in fact, more relaxed than assert. rather 'assume'
336 // TODO int[] IntMap#keys() or even sort of iterator that can modify values
337 for (int k = missingParents.firstKey(), l = missingParents.lastKey(); k <= l; k++) {
338 if (missingParents.containsKey(k)) {
339 Nodeid nid = getRepo().getChangelog().getRevision(k);
340 missingParents.put(k, nid);
341 }
342 }
343
344 for (int i = 0, revNum = _start; i < allRevisions.length; i++, revNum++) {
345 int riP1 = firstParentIndexes[i];
346 int riP2 = secondParentIndexes[i];
347 Nodeid p1, p2;
348 p1 = p2 = Nodeid.NULL;
349 if (riP1 >= _start) {
350 // p1 of revNum's revision is out of iterated range
351 // (don't check for riP1<end as I assume parents come prior to children in the changelog)
352 p1 = allRevisions[riP1 - start];
353 } else if (riP1 != -1) {
354 assert riP1 >=0 && riP1 < _start;
355 p1 = missingParents.get(riP1);
356 }
357 // same for Pp2
358 if (riP2 >= _start) {
359 p2 = allRevisions[riP2 - start];
360 } else if (riP2 != -1) {
361 assert riP2 >= 0 && riP2 < _start;
362 p2 = missingParents.get(riP2);
363 }
364 parentInsp.next(revNum, allRevisions[i], riP1, riP2, p1, p2);
365 }
366 }
317 } 367 }
318 368
319 /** 369 /**
320 * MARKER 370 * MARKER
321 */ 371 */