From 42c2c729597eb7e8a87c62dce435781f47732d2c Mon Sep 17 00:00:00 2001 From: tomlu Date: Wed, 31 Jan 2018 11:18:20 -0800 Subject: Add memory-efficient map for storing nested set -> digest. Instead of using ConcurrentHashMap, we use a dead-simple open addressed hash hable with a giant byte array with 16-byte slots. We then read or write fingerprints straight into and out of the array, obviating the need to generate intermediate garbage. Locking mechanism is a read-write lock. This should be faster than full synchronisation for read-heavy loads. RELNOTES: None PiperOrigin-RevId: 184019301 --- .../google/devtools/build/lib/util/Fingerprint.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/main/java/com/google/devtools/build/lib/util') 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 c2119eeccb..ddb71b4aaf 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 @@ -20,6 +20,7 @@ import com.google.devtools.build.lib.vfs.PathFragment; import com.google.protobuf.CodedOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.security.DigestException; import java.security.DigestOutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -73,6 +74,26 @@ public final class Fingerprint { return md5.digest(); } + /** + * Completes the hash computation by doing final operations and resets the underlying state, + * allowing this instance to be used again. + * + *

Instead of returning a digest, this method writes the digest straight into the supplied byte + * array, at the given offset. + * + * @see java.security.MessageDigest#digest() + */ + public void digestAndReset(byte[] buf, int offset, int len) { + try { + codedOut.flush(); + md5.digest(buf, offset, len); + } catch (IOException e) { + throw new IllegalStateException("failed to flush", e); + } catch (DigestException e) { + throw new IllegalStateException("failed to digest", e); + } + } + /** Same as {@link #digestAndReset()}, except returns the digest in hex string form. */ public String hexDigestAndReset() { return hexDigest(digestAndReset()); -- cgit v1.2.3