changeset 24:d4fdd1845b3f

Nodeid with array of exactly 20 bytes
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Thu, 06 Jan 2011 04:42:15 +0100
parents 6f9aca1a97be
children da8ccbfae64d
files src/com/tmate/hgkit/ll/HgManifest.java src/com/tmate/hgkit/ll/LocalHgRepo.java src/com/tmate/hgkit/ll/Nodeid.java src/com/tmate/hgkit/ll/Revlog.java src/com/tmate/hgkit/ll/RevlogStream.java
diffstat 5 files changed, 37 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- 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;
--- 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);
--- 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<Nodeid> {
+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);
--- 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);
 	}
 }
--- 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;
 			}