comparison src/org/tmatesoft/hg/repo/HgBundle.java @ 532:688c1ab113bb

Introduce explicit reference to base patch in bundle's group element, use it when cloning to fix defect when few revisions list null,null parents
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 23 Jan 2013 19:14:15 +0100
parents 2f9ed6bcefa2
children 243202f1bda5
comparison
equal deleted inserted replaced
531:95c2f43008bd 532:688c1ab113bb
1 /* 1 /*
2 * Copyright (c) 2011-2012 TMate Software Ltd 2 * Copyright (c) 2011-2013 TMate Software Ltd
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License. 6 * the Free Software Foundation; version 2 of the License.
7 * 7 *
407 } 407 }
408 408
409 private static void readGroup(DataAccess da, Inspector inspector) throws IOException { 409 private static void readGroup(DataAccess da, Inspector inspector) throws IOException {
410 int len = da.readInt(); 410 int len = da.readInt();
411 boolean good2go = true; 411 boolean good2go = true;
412 Nodeid prevNodeid = Nodeid.NULL;
412 while (len > 4 && !da.isEmpty() && good2go) { 413 while (len > 4 && !da.isEmpty() && good2go) {
413 byte[] nb = new byte[80]; 414 byte[] nb = new byte[80];
414 da.readBytes(nb, 0, 80); 415 da.readBytes(nb, 0, 80);
415 int dataLength = len - 84 /* length field + 4 nodeids */; 416 int dataLength = len - 84 /* length field + 4 nodeids */;
416 byte[] data = new byte[dataLength]; 417 byte[] data = new byte[dataLength];
417 da.readBytes(data, 0, dataLength); 418 da.readBytes(data, 0, dataLength);
418 DataAccess slice = new ByteArrayDataAccess(data); // XXX in fact, may pass a slicing DataAccess. 419 DataAccess slice = new ByteArrayDataAccess(data); // XXX in fact, may pass a slicing DataAccess.
419 // Just need to make sure that we seek to proper location afterwards (where next GroupElement starts), 420 // Just need to make sure that we seek to proper location afterwards (where next GroupElement starts),
420 // regardless whether that slice has read it or not. 421 // regardless whether that slice has read it or not.
421 GroupElement ge = new GroupElement(nb, slice); 422 GroupElement ge = new GroupElement(nb, prevNodeid, slice);
422 good2go = inspector.element(ge); 423 good2go = inspector.element(ge);
423 slice.done(); // BADA doesn't implement done(), but it could (e.g. free array) 424 slice.done(); // BADA doesn't implement done(), but it could (e.g. free array)
424 /// and we'd better tell it we are not going to use it any more. However, it's important to ensure Inspector 425 /// and we'd better tell it we are not going to use it any more. However, it's important to ensure Inspector
425 // implementations out there do not retain GroupElement.rawData() 426 // implementations out there do not retain GroupElement.rawData()
427 prevNodeid = ge.node();
426 len = da.isEmpty() ? 0 : da.readInt(); 428 len = da.isEmpty() ? 0 : da.readInt();
427 } 429 }
428 // need to skip up to group end if inspector told he don't want to continue with the group, 430 // need to skip up to group end if inspector told he don't want to continue with the group,
429 // because outer code may try to read next group immediately as we return back. 431 // because outer code may try to read next group immediately as we return back.
430 while (len > 4 && !da.isEmpty()) { 432 while (len > 4 && !da.isEmpty()) {
444 @Experimental(reason="Cumbersome API, rawData and apply with byte[] perhaps need replacement with ByteChannel/ByteBuffer, and better Exceptions. Perhaps, shall split into interface and impl") 446 @Experimental(reason="Cumbersome API, rawData and apply with byte[] perhaps need replacement with ByteChannel/ByteBuffer, and better Exceptions. Perhaps, shall split into interface and impl")
445 public static class GroupElement { 447 public static class GroupElement {
446 private final byte[] header; // byte[80] takes 120 bytes, 4 Nodeids - 192 448 private final byte[] header; // byte[80] takes 120 bytes, 4 Nodeids - 192
447 private final DataAccess dataAccess; 449 private final DataAccess dataAccess;
448 private Patch patches; 450 private Patch patches;
449 451 private final Nodeid deltaBase;
450 GroupElement(byte[] fourNodeids, DataAccess rawDataAccess) { 452
453 GroupElement(byte[] fourNodeids, Nodeid deltaBaseRev, DataAccess rawDataAccess) {
451 assert fourNodeids != null && fourNodeids.length == 80; 454 assert fourNodeids != null && fourNodeids.length == 80;
452 header = fourNodeids; 455 header = fourNodeids;
456 deltaBase = deltaBaseRev;
453 dataAccess = rawDataAccess; 457 dataAccess = rawDataAccess;
454 } 458 }
455 459
456 /** 460 /**
457 * <b>node</b> field of the group element 461 * <b>node</b> field of the group element
481 * <b>cs</b> <i>(changeset link)</i> field of the group element 485 * <b>cs</b> <i>(changeset link)</i> field of the group element
482 * @return changeset revision, never <code>null</code> 486 * @return changeset revision, never <code>null</code>
483 */ 487 */
484 public Nodeid cset() { 488 public Nodeid cset() {
485 return Nodeid.fromBinary(header, 60); 489 return Nodeid.fromBinary(header, 60);
490 }
491
492 /**
493 * Revision this element keeps patches against. For the patches of the very first revision returns {@link Nodeid#NULL}.
494 * @return revision of delta base, never <code>null</code>
495 */
496 public Nodeid patchBase() {
497 return deltaBase;
486 } 498 }
487 499
488 public byte[] rawDataByteArray() throws IOException { // XXX IOException or HgInvalidFileException? 500 public byte[] rawDataByteArray() throws IOException { // XXX IOException or HgInvalidFileException?
489 return rawData().byteArray(); 501 return rawData().byteArray();
490 } 502 }