diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/remote/Digests.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/remote/Digests.java | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/remote/Digests.java b/src/main/java/com/google/devtools/build/lib/remote/Digests.java new file mode 100644 index 0000000000..9121bc2782 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/remote/Digests.java @@ -0,0 +1,104 @@ +// Copyright 2016 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.remote; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import com.google.common.hash.HashCode; +import com.google.common.hash.Hashing; +import com.google.devtools.build.lib.actions.ActionInput; +import com.google.devtools.build.lib.actions.ActionInputFileCache; +import com.google.devtools.build.lib.actions.cache.VirtualActionInput; +import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; +import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.remoteexecution.v1test.Action; +import com.google.devtools.remoteexecution.v1test.Digest; +import com.google.protobuf.Message; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** Helper methods relating to computing Digest messages for remote execution. */ +@ThreadSafe +public final class Digests { + private Digests() {} + + public static Digest computeDigest(byte[] blob) { + return buildDigest(Hashing.sha1().hashBytes(blob).toString(), blob.length); + } + + public static Digest computeDigest(Path file) throws IOException { + return buildDigest(file.getSHA1Digest(), file.getFileSize()); + } + + public static Digest computeDigest(VirtualActionInput input) throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + input.writeTo(buffer); + return computeDigest(buffer.toByteArray()); + } + + /** + * Computes a digest of the given proto message. Currently, we simply rely on message output as + * bytes, but this implementation relies on the stability of the proto encoding, in particular + * between different platforms and languages. TODO(olaola): upgrade to a better implementation! + */ + public static Digest computeDigest(Message message) { + return computeDigest(message.toByteArray()); + } + + public static Digest computeDigestUtf8(String str) { + return computeDigest(str.getBytes(UTF_8)); + } + + /** + * A special type of Digest that is used only as a remote action cache key. This is a + * separate type in order to prevent accidentally using other Digests as action keys. + */ + public static final class ActionKey { + private final Digest digest; + + public Digest getDigest() { + return digest; + } + + private ActionKey(Digest digest) { + this.digest = digest; + } + } + + public static ActionKey computeActionKey(Action action) { + return new ActionKey(computeDigest(action)); + } + + /** + * Assumes that the given Digest is a valid digest of an Action, and creates an ActionKey + * wrapper. This should not be called on the client side! + */ + public static ActionKey unsafeActionKeyFromDigest(Digest digest) { + return new ActionKey(digest); + } + + public static Digest buildDigest(byte[] hash, long size) { + return buildDigest(HashCode.fromBytes(hash).toString(), size); + } + + public static Digest buildDigest(String hexHash, long size) { + return Digest.newBuilder().setHash(hexHash).setSizeBytes(size).build(); + } + + public static Digest getDigestFromInputCache(ActionInput input, ActionInputFileCache cache) + throws IOException { + return buildDigest(cache.getDigest(input), cache.getSizeInBytes(input)); + } +} |