Rephrase Fingerprint in terms of guava HashFunction. This minimizes API divergence and allows us to make use of performance enhancements in guava, such as https://github.com/google/guava/issues/1197. -- MOS_MIGRATED_REVID=127108107
diff --git a/src/main/java/com/google/devtools/build/lib/actions/cache/Digest.java b/src/main/java/com/google/devtools/build/lib/actions/cache/Digest.java index c5653ac..0698919 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/cache/Digest.java +++ b/src/main/java/com/google/devtools/build/lib/actions/cache/Digest.java
@@ -13,6 +13,7 @@ // limitations under the License. package com.google.devtools.build.lib.actions.cache; +import com.google.common.hash.HashCode; import com.google.devtools.build.lib.util.Fingerprint; import com.google.devtools.build.lib.util.VarInt; @@ -107,7 +108,7 @@ @Override public String toString() { - return Fingerprint.hexDigest(digest); + return HashCode.fromBytes(digest).toString(); } private static byte[] getDigest(Fingerprint fp, String execPath, Metadata md) {
diff --git a/src/main/java/com/google/devtools/build/lib/util/Fingerprint.java b/src/main/java/com/google/devtools/build/lib/util/Fingerprint.java index a461041..75737c3 100644 --- a/src/main/java/com/google/devtools/build/lib/util/Fingerprint.java +++ b/src/main/java/com/google/devtools/build/lib/util/Fingerprint.java
@@ -17,11 +17,12 @@ import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.collect.Iterables; +import com.google.common.hash.HashFunction; +import com.google.common.hash.Hasher; +import com.google.common.hash.Hashing; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.util.Map; import java.util.UUID; @@ -34,18 +35,14 @@ */ public final class Fingerprint { - private final MessageDigest md; + private Hasher hasher; + private static final HashFunction MD5_HASH_FUNCTION = Hashing.md5(); /** - * Creates and initializes a new MD5 object; if this fails, Java must be - * installed incorrectly. + * Creates and initializes a new Hasher. */ public Fingerprint() { - try { - md = MessageDigest.getInstance("md5"); - } catch (NoSuchAlgorithmException e) { - throw new IllegalStateException("MD5 not available", e); - } + reset(); } /** @@ -57,7 +54,9 @@ * @see java.security.MessageDigest#digest() */ public byte[] digestAndReset() { - return md.digest(); + byte[] bytes = hasher.hash().asBytes(); + reset(); + return bytes; } /** @@ -68,23 +67,9 @@ * @return the MD5 digest as a 32-character string of hexadecimal digits */ public String hexDigestAndReset() { - return hexDigest(digestAndReset()); - } - - /** - * Returns a string representation of an MD5 digest. - * - * @param digest the MD5 digest, perhaps from a previous call to digest - * @return the digest as a 32-character string of hexadecimal digits - */ - public static String hexDigest(byte[] digest) { - StringBuilder b = new StringBuilder(32); - for (int i = 0; i < digest.length; i++) { - int n = digest[i]; - b.append("0123456789abcdef".charAt((n >> 4) & 0xF)); - b.append("0123456789abcdef".charAt(n & 0xF)); - } - return b.toString(); + String hexDigest = hasher.hash().toString(); + reset(); + return hexDigest; } /** @@ -94,7 +79,7 @@ * @see java.security.MessageDigest#update(byte[]) */ public Fingerprint addBytes(byte[] input) { - md.update(input); + hasher.putBytes(input); return this; } @@ -107,7 +92,7 @@ * @see java.security.MessageDigest#update(byte[], int, int) */ public Fingerprint addBytes(byte[] input, int offset, int len) { - md.update(input, offset, len); + hasher.putBytes(input, offset, len); return this; } @@ -133,13 +118,7 @@ * @param input the integer with which to update the digest */ public Fingerprint addInt(int input) { - md.update(new byte[] { - (byte) input, - (byte) (input >> 8), - (byte) (input >> 16), - (byte) (input >> 24), - }); - + hasher.putInt(input); return this; } @@ -149,17 +128,7 @@ * @param input the long with which to update the digest */ public Fingerprint addLong(long input) { - md.update(new byte[]{ - (byte) input, - (byte) (input >> 8), - (byte) (input >> 16), - (byte) (input >> 24), - (byte) (input >> 32), - (byte) (input >> 40), - (byte) (input >> 48), - (byte) (input >> 56), - }); - + hasher.putLong(input); return this; } @@ -199,7 +168,8 @@ public Fingerprint addString(String input) { byte[] bytes = input.getBytes(UTF_8); addInt(bytes.length); - md.update(bytes); + // Note that Hasher#putString() would not include the length of {@code input}. + hasher.putBytes(bytes); return this; } @@ -231,7 +201,7 @@ for (int i = 0; i < input.length(); i++) { bytes[i] = (byte) input.charAt(i); } - md.update(bytes); + hasher.putBytes(bytes); return this; } @@ -321,7 +291,7 @@ * Reset the Fingerprint for additional use as though previous digesting had not been done. */ public void reset() { - md.reset(); + hasher = MD5_HASH_FUNCTION.newHasher(); } // -------- Convenience methods ---------------------------- @@ -333,8 +303,6 @@ * @param input the String from which to compute the digest */ public static String md5Digest(String input) { - Fingerprint f = new Fingerprint(); - f.addBytes(input.getBytes(UTF_8)); - return f.hexDigestAndReset(); + return MD5_HASH_FUNCTION.hashString(input, UTF_8).toString(); } }