Mercurial > hg4j
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 } |
