diff src/com/tmate/hgkit/ll/RevlogStream.java @ 22:603806cd2dc6

Status of local working dir against non-tip base revision
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Thu, 06 Jan 2011 03:30:20 +0100
parents 382cfe9463db
children d4fdd1845b3f
line wrap: on
line diff
--- a/src/com/tmate/hgkit/ll/RevlogStream.java	Wed Jan 05 04:10:28 2011 +0100
+++ b/src/com/tmate/hgkit/ll/RevlogStream.java	Thu Jan 06 03:30:20 2011 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Artem Tikhomirov 
+ * Copyright (c) 2010, 2011 Artem Tikhomirov 
  */
 package com.tmate.hgkit.ll;
 
@@ -51,6 +51,53 @@
 		initOutline();
 		return index.size();
 	}
+	
+	public int dataLength(int revision) {
+		// XXX in fact, use of iterate() instead of this implementation may be quite reasonable.
+		//
+		final int indexSize = revisionCount();
+		DataAccess daIndex = getIndexStream(); // XXX may supply a hint that I'll need really few bytes of data (although at some offset)
+		if (revision == TIP) {
+			revision = indexSize - 1;
+		}
+		try {
+			int recordOffset = inline ? (int) index.get(revision).offset : revision * REVLOGV1_RECORD_SIZE;
+			daIndex.seek(recordOffset + 12); // 6+2+4
+			int actualLen = daIndex.readInt();
+			return actualLen; 
+		} catch (IOException ex) {
+			ex.printStackTrace(); // log error. FIXME better handling
+			throw new IllegalStateException(ex);
+		} finally {
+			daIndex.done();
+		}
+	}
+	
+	public int findLocalRevisionNumber(Nodeid nodeid) {
+		// XXX this one may be implemented with iterate() once there's mechanism to stop iterations
+		final int indexSize = revisionCount();
+		DataAccess daIndex = getIndexStream();
+		try {
+			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)) {
+					return i;
+				}
+				daIndex.skip(inline ? 12 + compressedLen : 12);
+			}
+		} catch (IOException ex) {
+			ex.printStackTrace(); // log error. FIXME better handling
+			throw new IllegalStateException(ex);
+		} finally {
+			daIndex.done();
+		}
+		throw new IllegalArgumentException(String.format("%s doesn't represent a revision of %s", nodeid.toString(), indexFile.getName() /*XXX HgDataFile.getPath might be more suitable here*/));
+	}
+
 
 	private final int REVLOGV1_RECORD_SIZE = 64;
 
@@ -92,7 +139,7 @@
 				i = start;
 			}
 			
-			daIndex.seek(inline ? (int) index.get(i).offset : start * REVLOGV1_RECORD_SIZE);
+			daIndex.seek(inline ? (int) index.get(i).offset : i * REVLOGV1_RECORD_SIZE);
 			for (; i <= end; i++ ) {
 				long l = daIndex.readLong();
 				long offset = l >>> 16;
@@ -205,6 +252,7 @@
 				}
 				if (da.isEmpty()) {
 					// fine, done then
+					res.trimToSize();
 					index = res;
 					break;
 				} else {