From: "Shawn O. Pearce" <spearce@spearce.org>
To: Robin Rosenberg <robin.rosenberg@dewire.com>
Cc: Marek Zawirski <marek.zawirski@gmail.com>,
Daniel Cheng <j16sdiz+freenet@gmail.com>,
git@vger.kernel.org
Subject: [JGIT PATCH 2/5] Implement CRC32 computation during PackWriter
Date: Wed, 25 Mar 2009 18:21:52 -0700 [thread overview]
Message-ID: <1238030515-31768-2-git-send-email-spearce@spearce.org> (raw)
In-Reply-To: <1238030515-31768-1-git-send-email-spearce@spearce.org>
To correctly create a v2 index file for a pack we must compute the
CRC32 code for each object entry as they are written out, otherwise
the CRC32 table will be full of 0's, and fail verification if the
resulting pack were to be reused.
Reported-by: Daniel Cheng (aka SDiZ) <j16sdiz+freenet@gmail.com>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
.../tst/org/spearce/jgit/lib/PackWriterTest.java | 17 +++---
.../PackOutputStream.java} | 65 +++++++++++++-------
.../src/org/spearce/jgit/lib/PackWriter.java | 16 ++---
3 files changed, 57 insertions(+), 41 deletions(-)
rename org.spearce.jgit/src/org/spearce/jgit/{util/CountingOutputStream.java => lib/PackOutputStream.java} (61%)
diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/PackWriterTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/PackWriterTest.java
index f7139fc..46616e3 100644
--- a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/PackWriterTest.java
+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/PackWriterTest.java
@@ -56,7 +56,6 @@
import org.spearce.jgit.revwalk.RevObject;
import org.spearce.jgit.revwalk.RevWalk;
import org.spearce.jgit.transport.IndexPack;
-import org.spearce.jgit.util.CountingOutputStream;
import org.spearce.jgit.util.JGitTestUtil;
public class PackWriterTest extends RepositoryTestCase {
@@ -71,7 +70,7 @@
private ByteArrayOutputStream os;
- private CountingOutputStream cos;
+ private PackOutputStream cos;
private File packBase;
@@ -84,7 +83,7 @@
public void setUp() throws Exception {
super.setUp();
os = new ByteArrayOutputStream();
- cos = new CountingOutputStream(os);
+ cos = new PackOutputStream(os);
packBase = new File(trash, "tmp_pack");
packFile = new File(trash, "tmp_pack.pack");
indexFile = new File(trash, "tmp_pack.idx");
@@ -308,11 +307,11 @@ public void testWritePack4ThinPack() throws IOException {
*/
public void testWritePack2SizeDeltasVsNoDeltas() throws Exception {
testWritePack2();
- final long sizePack2NoDeltas = cos.getCount();
+ final long sizePack2NoDeltas = cos.length();
tearDown();
setUp();
testWritePack2DeltasReuseRefs();
- final long sizePack2DeltasRefs = cos.getCount();
+ final long sizePack2DeltasRefs = cos.length();
assertTrue(sizePack2NoDeltas > sizePack2DeltasRefs);
}
@@ -327,11 +326,11 @@ public void testWritePack2SizeDeltasVsNoDeltas() throws Exception {
*/
public void testWritePack2SizeOffsetsVsRefs() throws Exception {
testWritePack2DeltasReuseRefs();
- final long sizePack2DeltasRefs = cos.getCount();
+ final long sizePack2DeltasRefs = cos.length();
tearDown();
setUp();
testWritePack2DeltasReuseOffsets();
- final long sizePack2DeltasOffsets = cos.getCount();
+ final long sizePack2DeltasOffsets = cos.length();
assertTrue(sizePack2DeltasRefs > sizePack2DeltasOffsets);
}
@@ -345,11 +344,11 @@ public void testWritePack2SizeOffsetsVsRefs() throws Exception {
*/
public void testWritePack4SizeThinVsNoThin() throws Exception {
testWritePack4();
- final long sizePack4 = cos.getCount();
+ final long sizePack4 = cos.length();
tearDown();
setUp();
testWritePack4ThinPack();
- final long sizePack4Thin = cos.getCount();
+ final long sizePack4Thin = cos.length();
assertTrue(sizePack4 > sizePack4Thin);
}
diff --git a/org.spearce.jgit/src/org/spearce/jgit/util/CountingOutputStream.java b/org.spearce.jgit/src/org/spearce/jgit/lib/PackOutputStream.java
similarity index 61%
rename from org.spearce.jgit/src/org/spearce/jgit/util/CountingOutputStream.java
rename to org.spearce.jgit/src/org/spearce/jgit/lib/PackOutputStream.java
index 5f333f5..403b892 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/util/CountingOutputStream.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/PackOutputStream.java
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2009, Google Inc.
* Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
*
* All rights reserved.
@@ -35,46 +36,66 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-package org.spearce.jgit.util;
+package org.spearce.jgit.lib;
-import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.security.MessageDigest;
+import java.util.zip.CRC32;
+
+/** Custom output stream to support {@link PackWriter}. */
+final class PackOutputStream extends OutputStream {
+ private final OutputStream out;
+
+ private final CRC32 crc = new CRC32();
+
+ private final MessageDigest md = Constants.newMessageDigest();
-/**
- * Counting output stream decoration. Counts bytes written to stream.
- */
-public class CountingOutputStream extends FilterOutputStream {
private long count;
- /**
- * Create counting stream being decorated to provided real output stream.
- *
- * @param out
- * output stream where data should be written
- */
- public CountingOutputStream(OutputStream out) {
- super(out);
+ PackOutputStream(final OutputStream out) {
+ this.out = out;
}
@Override
- public void write(int b) throws IOException {
+ public void write(final int b) throws IOException {
out.write(b);
+ crc.update(b);
+ md.update((byte) b);
count++;
}
@Override
- public void write(byte[] b, int off, int len) throws IOException {
+ public void write(final byte[] b, final int off, final int len)
+ throws IOException {
out.write(b, off, len);
+ crc.update(b, off, len);
+ md.update(b, off, len);
count += len;
}
- /**
- * Return number of already written bytes.
- *
- * @return number of written bytes since stream start.
- */
- public long getCount() {
+ @Override
+ public void flush() throws IOException {
+ out.flush();
+ }
+
+ /** @return total number of bytes written since stream start. */
+ long length() {
return count;
}
+
+ /** @return obtain the current CRC32 register. */
+ int getCRC32() {
+ return (int) crc.getValue();
+ }
+
+ /** Reinitialize the CRC32 register for a new region. */
+ void resetCRC32() {
+ crc.reset();
+ }
+
+ /** @return obtain the current SHA-1 digest. */
+ byte[] getDigest() {
+ return md.digest();
+ }
}
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/PackWriter.java b/org.spearce.jgit/src/org/spearce/jgit/lib/PackWriter.java
index 601ce71..cfec35c 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/PackWriter.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/PackWriter.java
@@ -40,7 +40,6 @@
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
-import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collection;
@@ -57,7 +56,6 @@
import org.spearce.jgit.revwalk.RevObject;
import org.spearce.jgit.revwalk.RevSort;
import org.spearce.jgit.transport.PackedObjectInfo;
-import org.spearce.jgit.util.CountingOutputStream;
import org.spearce.jgit.util.NB;
/**
@@ -166,9 +164,7 @@
private final Repository db;
- private DigestOutputStream out;
-
- private CountingOutputStream countingOut;
+ private PackOutputStream out;
private final Deflater deflater;
@@ -563,8 +559,7 @@ public void writePack(OutputStream packStream) throws IOException {
if (!(packStream instanceof BufferedOutputStream))
packStream = new BufferedOutputStream(packStream);
- countingOut = new CountingOutputStream(packStream);
- out = new DigestOutputStream(countingOut, Constants.newMessageDigest());
+ out = new PackOutputStream(packStream);
writeMonitor.beginTask(WRITING_OBJECTS_PROGRESS, getObjectsNumber());
writeHeader();
@@ -687,11 +682,13 @@ private void writeObject(final ObjectToPack otp) throws IOException {
assert !otp.isWritten();
- otp.setOffset(countingOut.getCount());
+ out.resetCRC32();
+ otp.setOffset(out.length());
if (otp.isDeltaRepresentation())
writeDeltaObject(otp);
else
writeWholeObject(otp);
+ otp.setCRC(out.getCRC32());
writeMonitor.update(1);
}
@@ -753,8 +750,7 @@ private void writeObjectHeader(final int objectType, long dataLength)
}
private void writeChecksum() throws IOException {
- out.on(false);
- packcsum = out.getMessageDigest().digest();
+ packcsum = out.getDigest();
out.write(packcsum);
}
--
1.6.2.1.471.g682837
next prev parent reply other threads:[~2009-03-26 1:23 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-26 1:21 [JGIT PATCH 1/5] Remove dead/unused reset method from CountingOutputStream Shawn O. Pearce
2009-03-26 1:21 ` Shawn O. Pearce [this message]
2009-03-26 1:21 ` [JGIT PATCH 3/5] Test case for pack index CRC32 when written by PackWriter Shawn O. Pearce
2009-03-26 1:21 ` [JGIT PATCH 4/5] Write the pack header in one shot Shawn O. Pearce
2009-03-26 1:21 ` [JGIT PATCH 5/5] Use Deflater directly in PackWriter Shawn O. Pearce
2009-03-26 15:35 ` [JGIT PATCH 3/5] Test case for pack index CRC32 when written by PackWriter Daniel Cheng
2009-03-26 15:35 ` Daniel Cheng
2009-03-27 8:11 ` patch series starting with [JGIT PATCH 1/5] Remove dead/unused reset method from CountingOutputStream Robin Rosenberg
2009-03-27 14:51 ` Shawn O. Pearce
2009-03-27 14:55 ` Shawn O. Pearce
2009-03-27 23:53 ` Robin Rosenberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1238030515-31768-2-git-send-email-spearce@spearce.org \
--to=spearce@spearce.org \
--cc=git@vger.kernel.org \
--cc=j16sdiz+freenet@gmail.com \
--cc=marek.zawirski@gmail.com \
--cc=robin.rosenberg@dewire.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).