aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Pearce <spearce@spearce.org>2017-02-26 11:44:51 -0800
committerJonathan Nieder <jrn@google.com>2017-02-26 15:26:53 -0800
commit1bf7d3f290ef7dbf9b4f12d15308a4d93042ac83 (patch)
treedcd13a57b6323daf99673f41174cceac36d7b357
parent0f25f64d4882f7853c9d3dc84ec382d8a78ae646 (diff)
downloadjgit-1bf7d3f290ef7dbf9b4f12d15308a4d93042ac83.tar.gz
jgit-1bf7d3f290ef7dbf9b4f12d15308a4d93042ac83.zip
SHA1: support reset() and reuse instances
Allow SHA1 instances to be reused to compute another hash value, and resume caching them in ObjectInserter and PackParser. This shaves a small amount of running time off parsing git.git's pack file: before after ------ ------ 25.25s 25.55s 25.48s 25.06s 25.26s 24.94s Almost noise (small difference), but recycling the instances reduces some stress on the memory allocator finding two 80 word message block arrays needed for hashing and collision detection. Change-Id: I4af88a720e81460293bc5c5d1d3db1a831e7e228
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/util/sha1/SHA1Test.java15
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java4
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java5
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java32
6 files changed, 49 insertions, 11 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/sha1/SHA1Test.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/sha1/SHA1Test.java
index c53080455c..8642db79e3 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/sha1/SHA1Test.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/sha1/SHA1Test.java
@@ -72,8 +72,13 @@ public class SHA1Test {
s.update(new byte[] {});
ObjectId s1 = ObjectId.fromRaw(s.digest());
+ s.reset();
+ s.update(new byte[] {});
+ ObjectId s2 = s.toObjectId();
+
assertEquals(m1, s1);
assertEquals(exp, s1);
+ assertEquals(exp, s2);
}
@Test
@@ -89,8 +94,13 @@ public class SHA1Test {
s.update(TEST1.getBytes(StandardCharsets.UTF_8));
ObjectId s1 = ObjectId.fromRaw(s.digest());
+ s.reset();
+ s.update(TEST1.getBytes(StandardCharsets.UTF_8));
+ ObjectId s2 = s.toObjectId();
+
assertEquals(m1, s1);
assertEquals(exp, s1);
+ assertEquals(exp, s2);
}
@Test
@@ -106,7 +116,12 @@ public class SHA1Test {
s.update(TEST2.getBytes(StandardCharsets.UTF_8));
ObjectId s1 = ObjectId.fromRaw(s.digest());
+ s.reset();
+ s.update(TEST2.getBytes(StandardCharsets.UTF_8));
+ ObjectId s2 = s.toObjectId();
+
assertEquals(m1, s1);
assertEquals(exp, s1);
+ assertEquals(exp, s2);
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
index d3ac626504..fd72756e39 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
@@ -169,7 +169,7 @@ public class DfsInserter extends ObjectInserter {
}
long offset = beginObject(type, len);
- SHA1 md = SHA1.newInstance();
+ SHA1 md = digest();
md.update(Constants.encodedTypeString(type));
md.update((byte) ' ');
md.update(Constants.encodeASCII(len));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java
index c37c4daa45..aa435bf67c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java
@@ -140,7 +140,7 @@ class ObjectDirectoryInserter extends ObjectInserter {
return insert(type, buf, 0, actLen, createDuplicate);
} else {
- SHA1 md = SHA1.newInstance();
+ SHA1 md = digest();
File tmp = toTemp(md, type, len, is);
ObjectId id = md.toObjectId();
return insertOneObject(tmp, id, createDuplicate);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java
index b39603adac..ad0b3332cf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java
@@ -177,6 +177,8 @@ public abstract class ObjectInserter implements AutoCloseable {
}
}
+ private final SHA1 hasher = SHA1.newInstance();
+
/** Temporary working buffer for streaming data through. */
private byte[] tempBuffer;
@@ -217,7 +219,7 @@ public abstract class ObjectInserter implements AutoCloseable {
/** @return digest to help compute an ObjectId */
protected SHA1 digest() {
- return SHA1.newInstance();
+ return hasher.reset();
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
index 7d48f2a256..c82b3891b5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
@@ -117,6 +117,7 @@ public abstract class PackParser {
private byte[] hdrBuf;
+ private final SHA1 objectHasher = SHA1.newInstance();
private final MutableObjectId tempObjectId;
private InputStream in;
@@ -665,7 +666,7 @@ public abstract class PackParser {
JGitText.get().corruptionDetectedReReadingAt,
Long.valueOf(visit.delta.position)));
- SHA1 objectDigest = SHA1.newInstance();
+ SHA1 objectDigest = objectHasher.reset();
objectDigest.update(Constants.encodedTypeString(type));
objectDigest.update((byte) ' ');
objectDigest.update(Constants.encodeASCII(visit.data.length));
@@ -1023,7 +1024,7 @@ public abstract class PackParser {
private void whole(final long pos, final int type, final long sz)
throws IOException {
- SHA1 objectDigest = SHA1.newInstance();
+ SHA1 objectDigest = objectHasher.reset();
objectDigest.update(Constants.encodedTypeString(type));
objectDigest.update((byte) ' ');
objectDigest.update(Constants.encodeASCII(sz));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java
index 0a1dc1046e..293b4ac56d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java
@@ -63,12 +63,11 @@ public class SHA1 {
return new SHA1();
}
- // Magic initialization constants defined by FIPS180.
- private int h0 = 0x67452301;
- private int h1 = 0xEFCDAB89;
- private int h2 = 0x98BADCFE;
- private int h3 = 0x10325476;
- private int h4 = 0xC3D2E1F0;
+ private int h0;
+ private int h1;
+ private int h2;
+ private int h3;
+ private int h4;
private final int[] w = new int[80];
/** Buffer to accumulate partial blocks to 64 byte alignment. */
@@ -78,6 +77,27 @@ public class SHA1 {
private long length;
private SHA1() {
+ init();
+ }
+
+ /**
+ * Reset this instance to compute another hash.
+ *
+ * @return {@code this}.
+ */
+ public SHA1 reset() {
+ init();
+ length = 0;
+ return this;
+ }
+
+ private void init() {
+ // Magic initialization constants defined by FIPS180.
+ h0 = 0x67452301;
+ h1 = 0xEFCDAB89;
+ h2 = 0x98BADCFE;
+ h3 = 0x10325476;
+ h4 = 0xC3D2E1F0;
}
/**