From b3b088e32f2e7061a0eb7824d0fd003638508203 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 11 May 2008 14:09:59 -0400 Subject: [PATCH] Define static ASCII encoded type strings for ObjectId computation We frequently need to compute the ObjectId of something, and to do that we must embed the type name as an ASCII string into the header as part of the digest calculation. This means we are often building these ASCII encoded strings, but there's only 4 possible values in Git so it doesn't make sense to keep redoing the String->byte[] on every ObjectId computation. Instead we store them as static byte[] and pray nobody will be foolish enough to edit our constant data. Signed-off-by: Shawn O. Pearce --- .../tst/org/spearce/jgit/lib/ReadTreeTest.java | 2 +- .../src/org/spearce/jgit/lib/Constants.java | 32 +++++++++++ .../src/org/spearce/jgit/lib/ObjectLoader.java | 2 +- .../src/org/spearce/jgit/lib/ObjectWriter.java | 14 ++--- .../src/org/spearce/jgit/transport/IndexPack.java | 66 +++------------------- .../spearce/jgit/treewalk/WorkingTreeIterator.java | 5 +- 6 files changed, 52 insertions(+), 69 deletions(-) diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/ReadTreeTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/ReadTreeTest.java index d33a6b44..eee3d4a0 100644 --- a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/ReadTreeTest.java +++ b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/ReadTreeTest.java @@ -98,7 +98,7 @@ public class ReadTreeTest extends RepositoryTestCase { InputStream is = new ByteArrayInputStream(data.getBytes()); ObjectWriter objectWriter = new ObjectWriter(db); try { - return objectWriter.writeObject(Constants.TYPE_BLOB, data + return objectWriter.writeObject(Constants.OBJ_BLOB, data .getBytes().length, is, true); } catch (IOException e) { fail(e.toString()); diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java index 228ea976..0c83cf2c 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java @@ -65,6 +65,14 @@ public final class Constants { */ public static final String TYPE_TAG = "tag"; + private static final byte[] ENCODED_TYPE_COMMIT = encodeASCII(TYPE_COMMIT); + + private static final byte[] ENCODED_TYPE_BLOB = encodeASCII(TYPE_BLOB); + + private static final byte[] ENCODED_TYPE_TREE = encodeASCII(TYPE_TREE); + + private static final byte[] ENCODED_TYPE_TAG = encodeASCII(TYPE_TAG); + /** An unknown or invalid object type code. */ public static final int OBJ_BAD = -1; @@ -213,6 +221,30 @@ public final class Constants { } /** + * Convert an OBJ_* type constant to an ASCII encoded string constant. + *

+ * The ASCII encoded string is often the canonical representation of + * the type within a loose object header, or within a tag header. + * + * @param typeCode the type code, from a pack representation. + * @return the canonical ASCII encoded name of this type. + */ + public static byte[] encodedTypeString(final int typeCode) { + switch (typeCode) { + case OBJ_COMMIT: + return ENCODED_TYPE_COMMIT; + case OBJ_TREE: + return ENCODED_TYPE_TREE; + case OBJ_BLOB: + return ENCODED_TYPE_BLOB; + case OBJ_TAG: + return ENCODED_TYPE_TAG; + default: + throw new IllegalArgumentException("Bad object type: " + typeCode); + } + } + + /** * Convert an integer into its decimal representation. * * @param s diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectLoader.java b/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectLoader.java index f02e3fcd..8f425835 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectLoader.java +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectLoader.java @@ -33,7 +33,7 @@ public abstract class ObjectLoader { public ObjectId getId() throws IOException { if (objectId == null) { final MessageDigest md = Constants.newMessageDigest(); - md.update(Constants.encodeASCII(Constants.typeString(getType()))); + md.update(Constants.encodedTypeString(getType())); md.update((byte) ' '); md.update(Constants.encodeASCII(getSize())); md.update((byte) 0); diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectWriter.java b/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectWriter.java index a5904646..bf940eae 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectWriter.java +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectWriter.java @@ -103,7 +103,7 @@ public class ObjectWriter { */ public ObjectId writeBlob(final long len, final InputStream is) throws IOException { - return writeObject(Constants.TYPE_BLOB, len, is, true); + return writeObject(Constants.OBJ_BLOB, len, is, true); } /** @@ -142,7 +142,7 @@ public class ObjectWriter { private ObjectId writeTree(final long len, final InputStream is) throws IOException { - return writeObject(Constants.TYPE_TREE, len, is, true); + return writeObject(Constants.OBJ_TREE, len, is, true); } /** @@ -245,12 +245,12 @@ public class ObjectWriter { private ObjectId writeCommit(final long len, final InputStream is) throws IOException { - return writeObject(Constants.TYPE_COMMIT, len, is, true); + return writeObject(Constants.OBJ_COMMIT, len, is, true); } private ObjectId writeTag(final long len, final InputStream is) throws IOException { - return writeObject(Constants.TYPE_TAG, len, is, true); + return writeObject(Constants.OBJ_TAG, len, is, true); } /** @@ -264,11 +264,11 @@ public class ObjectWriter { */ public ObjectId computeBlobSha1(final long len, final InputStream is) throws IOException { - return writeObject(Constants.TYPE_BLOB, len, is, false); + return writeObject(Constants.OBJ_BLOB, len, is, false); } @SuppressWarnings("null") - ObjectId writeObject(final String type, long len, final InputStream is, + ObjectId writeObject(final int type, long len, final InputStream is, boolean store) throws IOException { final File t; final DeflaterOutputStream deflateStream; @@ -294,7 +294,7 @@ public class ObjectWriter { byte[] header; int n; - header = Constants.encodeASCII(type); + header = Constants.encodedTypeString(type); md.update(header); if (deflateStream != null) deflateStream.write(header); diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/IndexPack.java b/org.spearce.jgit/src/org/spearce/jgit/transport/IndexPack.java index b6e5956f..d9150f87 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/transport/IndexPack.java +++ b/org.spearce.jgit/src/org/spearce/jgit/transport/IndexPack.java @@ -55,21 +55,6 @@ public class IndexPack { private static final int BUFFER_SIZE = 2048; - private static final byte[] COMMIT; - - private static final byte[] TREE; - - private static final byte[] TAG; - - private static final byte[] BLOB; - - static { - COMMIT = Constants.encodeASCII(Constants.TYPE_COMMIT); - TREE = Constants.encodeASCII(Constants.TYPE_TREE); - TAG = Constants.encodeASCII(Constants.TYPE_TAG); - BLOB = Constants.encodeASCII(Constants.TYPE_BLOB); - } - /** * Create an index pack instance to load a new pack into a repository. *

@@ -274,10 +259,10 @@ public class IndexPack { private void resolveDeltas(final ObjectEntry oe) throws IOException { if (baseById.containsKey(oe) || baseByPos.containsKey(new Long(oe.pos))) - resolveDeltas(oe.pos, null, null, oe); + resolveDeltas(oe.pos, Constants.OBJ_BAD, null, oe); } - private void resolveDeltas(final long pos, byte[] type, byte[] data, + private void resolveDeltas(final long pos, int type, byte[] data, ObjectEntry oe) throws IOException { position(pos); int c = readFromFile(); @@ -292,19 +277,10 @@ public class IndexPack { switch (typeCode) { case Constants.OBJ_COMMIT: - type = COMMIT; - data = inflateFromFile((int) sz); - break; case Constants.OBJ_TREE: - type = TREE; - data = inflateFromFile((int) sz); - break; case Constants.OBJ_BLOB: - type = BLOB; - data = inflateFromFile((int) sz); - break; case Constants.OBJ_TAG: - type = TAG; + type = typeCode; data = inflateFromFile((int) sz); break; case Constants.OBJ_OFS_DELTA: { @@ -325,7 +301,7 @@ public class IndexPack { } if (oe == null) { - objectDigest.update(type); + objectDigest.update(Constants.encodedTypeString(type)); objectDigest.update((byte) ' '); objectDigest.update(Constants.encodeASCII(data.length)); objectDigest.update((byte) 0); @@ -338,7 +314,7 @@ public class IndexPack { resolveChildDeltas(pos, type, data, oe); } - private void resolveChildDeltas(final long pos, byte[] type, byte[] data, + private void resolveChildDeltas(final long pos, int type, byte[] data, ObjectEntry oe) throws IOException { final ArrayList a = baseById.remove(oe); final ArrayList b = baseByPos.remove(new Long(pos)); @@ -374,33 +350,15 @@ public class IndexPack { final ObjectLoader ldr = repo.openObject(baseId); final byte[] data = ldr.getBytes(); final int typeCode = ldr.getType(); - final byte[] type; final ObjectEntry oe; - switch (typeCode) { - case Constants.OBJ_COMMIT: - type = COMMIT; - break; - case Constants.OBJ_TREE: - type = TREE; - break; - case Constants.OBJ_BLOB: - type = BLOB; - break; - case Constants.OBJ_TAG: - type = TAG; - break; - default: - throw new IOException("Unknown object type " + typeCode + "."); - } - oe = new ObjectEntry(end, baseId); entries[entryCount++] = oe; packOut.seek(end); writeWhole(def, typeCode, data); end = packOut.getFilePointer(); - resolveChildDeltas(oe.pos, type, data, oe); + resolveChildDeltas(oe.pos, typeCode, data, oe); if (progress.isCancelled()) throw new IOException("Download cancelled during indexing"); } @@ -542,16 +500,10 @@ public class IndexPack { switch (typeCode) { case Constants.OBJ_COMMIT: - whole(COMMIT, pos, sz); - break; case Constants.OBJ_TREE: - whole(TREE, pos, sz); - break; case Constants.OBJ_BLOB: - whole(BLOB, pos, sz); - break; case Constants.OBJ_TAG: - whole(TAG, pos, sz); + whole(typeCode, pos, sz); break; case Constants.OBJ_OFS_DELTA: { c = readFromInput() & 0xff; @@ -594,9 +546,9 @@ public class IndexPack { } } - private void whole(final byte[] type, final long pos, final long sz) + private void whole(final int type, final long pos, final long sz) throws IOException { - objectDigest.update(type); + objectDigest.update(Constants.encodedTypeString(type)); objectDigest.update((byte) ' '); objectDigest.update(Constants.encodeASCII(sz)); objectDigest.update((byte) 0); diff --git a/org.spearce.jgit/src/org/spearce/jgit/treewalk/WorkingTreeIterator.java b/org.spearce.jgit/src/org/spearce/jgit/treewalk/WorkingTreeIterator.java index 334f9679..de730f29 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/treewalk/WorkingTreeIterator.java +++ b/org.spearce.jgit/src/org/spearce/jgit/treewalk/WorkingTreeIterator.java @@ -131,9 +131,8 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { private static final byte[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; - private static final String TYPE_BLOB = Constants.TYPE_BLOB; - - private static final byte[] hblob = Constants.encodeASCII(TYPE_BLOB); + private static final byte[] hblob = Constants + .encodedTypeString(Constants.OBJ_BLOB); private byte[] idBufferBlob(final Entry e) { try { -- 2.11.4.GIT