# HG changeset patch # User Artem Tikhomirov # Date 1294285335 -3600 # Node ID d4fdd1845b3fe02fde5d32da0bf5f842158eb121 # Parent 6f9aca1a97bee6444b90420e26b820a5efd1988a Nodeid with array of exactly 20 bytes diff -r 6f9aca1a97be -r d4fdd1845b3f src/com/tmate/hgkit/ll/HgManifest.java --- a/src/com/tmate/hgkit/ll/HgManifest.java Thu Jan 06 03:30:43 2011 +0100 +++ b/src/com/tmate/hgkit/ll/HgManifest.java Thu Jan 06 04:42:15 2011 +0100 @@ -22,7 +22,7 @@ if (!gtg) { return; } - gtg = gtg && inspector.begin(revisionNumber, new Nodeid(nodeid)); + gtg = gtg && inspector.begin(revisionNumber, new Nodeid(nodeid.clone())); int i; String fname = null; String flags = null; diff -r 6f9aca1a97be -r d4fdd1845b3f src/com/tmate/hgkit/ll/LocalHgRepo.java --- a/src/com/tmate/hgkit/ll/LocalHgRepo.java Thu Jan 06 03:30:43 2011 +0100 +++ b/src/com/tmate/hgkit/ll/LocalHgRepo.java Thu Jan 06 04:42:15 2011 +0100 @@ -63,7 +63,7 @@ if (nidR1 == null) { inspector.added(fname); } else { - if (nidR1.compareTo(nid) == 0 && ((flags == null && flagsR1 == null) || flags.equals(flagsR1))) { + if (nidR1.equals(nid) && ((flags == null && flagsR1 == null) || flags.equals(flagsR1))) { inspector.clean(fname); } else { inspector.modified(fname); diff -r 6f9aca1a97be -r d4fdd1845b3f src/com/tmate/hgkit/ll/Nodeid.java --- a/src/com/tmate/hgkit/ll/Nodeid.java Thu Jan 06 03:30:43 2011 +0100 +++ b/src/com/tmate/hgkit/ll/Nodeid.java Thu Jan 06 04:42:15 2011 +0100 @@ -3,6 +3,8 @@ */ package com.tmate.hgkit.ll; +import java.util.Arrays; + /** @@ -13,40 +15,41 @@ * @author artem * */ -public final class Nodeid implements Comparable { +public final class Nodeid { public static int NULLREV = -1; private final byte[] binaryData; + /** + * @param binaryRepresentation - byte[20], kept by reference. Use {@link #clone()} if original array may get changed. + */ public Nodeid(byte[] binaryRepresentation) { // 5 int fields => 32 bytes // byte[20] => 48 bytes + if (binaryRepresentation == null || binaryRepresentation.length != 20) { + throw new IllegalArgumentException(); + } this.binaryData = binaryRepresentation; } - // instead of hashCode/equals - public int compareTo(Nodeid o) { - return equals(this.binaryData, o.binaryData) ? 0 : -1; + @Override + public int hashCode() { + // TODO consider own impl, especially if byte[] get replaced with 5 ints + return Arrays.hashCode(binaryData); + } + + @Override + public boolean equals(Object o) { + if (o instanceof Nodeid) { + return Arrays.equals(this.binaryData, ((Nodeid) o).binaryData); + } + return false; } public boolean equalsTo(byte[] buf) { - return equals(this.binaryData, buf); + return Arrays.equals(this.binaryData, buf); } - private static boolean equals(byte[] a1, byte[] a2) { - if (a1 == null || a1.length < 20 || a2 == null || a2.length < 20) { - throw new IllegalArgumentException(); - } - // assume significant bits are at the end of the array - final int s1 = a1.length - 20, s2 = a2.length - 20; - for (int i = 0; i < 20; i++) { - if (a1[s1+i] != a2[s2+i]) { - return false; - } - } - return true; - } - @Override public String toString() { return new DigestHelper().toHexString(binaryData, 0, binaryData.length); @@ -54,8 +57,10 @@ // binascii.unhexlify() public static Nodeid fromAscii(byte[] asciiRepresentation, int offset, int length) { - assert length % 2 == 0; // Python's binascii.hexlify convert each byte into 2 digits - byte[] data = new byte[length >>> 1]; // XXX use known size instead? nodeid is always 20 bytes + if (length != 40) { + throw new IllegalArgumentException(); + } + byte[] data = new byte[20]; for (int i = 0, j = offset; i < data.length; i++) { int hiNibble = Character.digit(asciiRepresentation[j++], 16); int lowNibble = Character.digit(asciiRepresentation[j++], 16); diff -r 6f9aca1a97be -r d4fdd1845b3f src/com/tmate/hgkit/ll/Revlog.java --- a/src/com/tmate/hgkit/ll/Revlog.java Thu Jan 06 03:30:43 2011 +0100 +++ b/src/com/tmate/hgkit/ll/Revlog.java Thu Jan 06 04:42:15 2011 +0100 @@ -32,6 +32,7 @@ // instantly - e.g. calculate hash, or comparing two revisions public interface Inspector { // XXX boolean retVal to indicate whether to continue? - void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[/*32*/] nodeid, byte[] data); + // TODO specify nodeid and data length, and reuse policy (i.e. if revlog stream doesn't reuse nodeid[] for each call) + void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[/*20*/] nodeid, byte[] data); } } diff -r 6f9aca1a97be -r d4fdd1845b3f src/com/tmate/hgkit/ll/RevlogStream.java --- a/src/com/tmate/hgkit/ll/RevlogStream.java Thu Jan 06 03:30:43 2011 +0100 +++ b/src/com/tmate/hgkit/ll/RevlogStream.java Thu Jan 06 04:42:15 2011 +0100 @@ -78,13 +78,13 @@ final int indexSize = revisionCount(); DataAccess daIndex = getIndexStream(); try { + byte[] nodeidBuf = new byte[20]; for (int i = 0; i < indexSize; i++) { daIndex.skip(8); int compressedLen = daIndex.readInt(); daIndex.skip(20); - byte[] buf = new byte[20]; - daIndex.readBytes(buf, 0, 20); - if (nodeid.equalsTo(buf)) { + daIndex.readBytes(nodeidBuf, 0, 20); + if (nodeid.equalsTo(nodeidBuf)) { return i; } daIndex.skip(inline ? 12 + compressedLen : 12); @@ -129,6 +129,7 @@ daData = getDataStream(); } try { + byte[] nodeidBuf = new byte[20]; byte[] lastData = null; int i; boolean extraReadsToBaseRev = false; @@ -150,9 +151,8 @@ int linkRevision = daIndex.readInt(); int parent1Revision = daIndex.readInt(); int parent2Revision = daIndex.readInt(); - byte[] buf = new byte[32]; - // XXX Hg keeps 12 last bytes empty, we move them into front here - daIndex.readBytes(buf, 12, 20); + // Hg has 32 bytes here, uses 20 for nodeid, and keeps 12 last bytes empty + daIndex.readBytes(nodeidBuf, 0, 20); daIndex.skip(12); byte[] data = null; if (needData) { @@ -207,7 +207,7 @@ } } if (!extraReadsToBaseRev || i >= start) { - inspector.next(i, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, buf, data); + inspector.next(i, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, nodeidBuf, data); } lastData = data; }