changeset 43:1b26247d7367

Calculate result length of the patch operarion, when unknown
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 14 Jan 2011 04:41:05 +0100
parents 92c3d0920d58
children b79cf0118dd3
files design.txt src/com/tmate/hgkit/ll/HgBundle.java src/com/tmate/hgkit/ll/RevlogStream.java
diffstat 3 files changed, 15 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/design.txt	Fri Jan 14 04:29:03 2011 +0100
+++ b/design.txt	Fri Jan 14 04:41:05 2011 +0100
@@ -27,7 +27,7 @@
 +buildfile + run samples
 *input stream impl + lifecycle. Step forward with FileChannel and ByteBuffer, although questionable accomplishment (looks bit complicated, cumbersome)
 + dirstate.mtime
-+calculate sha1 digest for file to see I can deal with nodeid
++calculate sha1 digest for file to see I can deal with nodeid. +Do this correctly (smaller nodeid - first)
 *.hgignored processing
 +Nodeid to keep 20 bytes always, Revlog.Inspector to get nodeid array of meaningful data exact size (nor heading 00 bytes, nor 12 extra bytes from the spec)
 +DataAccess - implement memory mapped files, 
--- a/src/com/tmate/hgkit/ll/HgBundle.java	Fri Jan 14 04:29:03 2011 +0100
+++ b/src/com/tmate/hgkit/ll/HgBundle.java	Fri Jan 14 04:41:05 2011 +0100
@@ -45,8 +45,7 @@
 			// (the previous, or parent patch of a given patch p is the patch that has a node equal to p's p1 field)
 			byte[] baseRevContent = hgRepo.getChangelog().content(base);
 			for (GroupElement ge : changelogGroup) {
-				int resultLen = 10000; // XXX calculate based on baseRevContent.length and ge.patches
-				byte[] csetContent = RevlogStream.apply(baseRevContent, resultLen, ge.patches);
+				byte[] csetContent = RevlogStream.apply(baseRevContent, -1, ge.patches);
 				// wiki suggests sha1_digest(min(p1,p2) ++ max(p1,p2) ++ final_text),
 				dh = dh.sha1(ge.firstParent(), ge.secondParent(), csetContent); // XXX ge may give me access to byte[] content of nodeid directly, perhaps, I don't need DH to be friend of Nodeid?
 				if (!ge.node().equalsTo(dh.asBinary())) {
--- a/src/com/tmate/hgkit/ll/RevlogStream.java	Fri Jan 14 04:29:03 2011 +0100
+++ b/src/com/tmate/hgkit/ll/RevlogStream.java	Fri Jan 14 04:41:05 2011 +0100
@@ -286,19 +286,25 @@
 	// FIXME need to implement patch merge (fold, combine, gather and discard from aforementioned mpatch.[c|py]), also see Revlog and Mercurial PDF
 	// FIXME why 2 arrays (rv and tempBuf)???. Think over in-place merging (perhaps some sparse byte chunk list?) - to minimize mem use.
 	/*package-local for HgBundle; until moved to better place*/static byte[] apply(byte[] baseRevisionContent, int outcomeLen, List<PatchRecord> patch) {
-		byte[] tempBuf = new byte[outcomeLen]; // XXX
 		int last = 0, destIndex = 0;
+		if (outcomeLen == -1) {
+			outcomeLen = baseRevisionContent.length;
+			for (PatchRecord pr : patch) {
+				outcomeLen += pr.start - last + pr.len;
+				last = pr.end;
+			}
+			outcomeLen -= last;
+			last = 0;
+		}
+		byte[] rv = new byte[outcomeLen];
 		for (PatchRecord pr : patch) {
-			System.arraycopy(baseRevisionContent, last, tempBuf, destIndex, pr.start-last);
+			System.arraycopy(baseRevisionContent, last, rv, destIndex, pr.start-last);
 			destIndex += pr.start - last;
-			System.arraycopy(pr.data, 0, tempBuf, destIndex, pr.data.length);
+			System.arraycopy(pr.data, 0, rv, destIndex, pr.data.length);
 			destIndex += pr.data.length;
 			last = pr.end;
 		}
-		System.arraycopy(baseRevisionContent, last, tempBuf, destIndex, baseRevisionContent.length - last);
-		destIndex += baseRevisionContent.length - last; // total length
-		byte[] rv = new byte[destIndex];
-		System.arraycopy(tempBuf, 0, rv, 0, destIndex);
+		System.arraycopy(baseRevisionContent, last, rv, destIndex, baseRevisionContent.length - last);
 		return rv;
 	}