aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetFingerprintCache.java
diff options
context:
space:
mode:
authorGravatar tomlu <tomlu@google.com>2017-11-29 14:01:21 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2017-11-29 14:03:30 -0800
commit3d1a194ff9e76f25f1a7242ff2d021523ba8e4a0 (patch)
tree9fec583a59b8ee6ee0f4fac513d5471956dfe1d3 /src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetFingerprintCache.java
parent8f8b8859fc7d85feee97481443fb11c0b7ae03ce (diff)
Add ActionKeyContext to Action#getKey.
This key context can be used by actions to share partial key computations, for instance when computing MD5s for nested sets. RELNOTES: None PiperOrigin-RevId: 177359607
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetFingerprintCache.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetFingerprintCache.java78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetFingerprintCache.java b/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetFingerprintCache.java
new file mode 100644
index 0000000000..8e56d5548a
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetFingerprintCache.java
@@ -0,0 +1,78 @@
+// Copyright 2017 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.collect.nestedset;
+
+import com.google.devtools.build.lib.util.Fingerprint;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/** Computes fingerprints for nested sets, reusing sub-computations from children. */
+public abstract class NestedSetFingerprintCache<T> {
+ private static final byte[] EMPTY_SET_BYTES = new byte[] {};
+ private Map<Object, byte[]> fingerprints = createMap();
+
+ public void addNestedSetToFingerprint(Fingerprint fingerprint, NestedSet<T> nestedSet) {
+ fingerprint.addInt(nestedSet.getOrder().ordinal());
+ Object children = nestedSet.rawChildren();
+ byte[] bytes = getBytes(children);
+ fingerprint.addBytes(bytes);
+ }
+
+ public void clear() {
+ fingerprints = createMap();
+ }
+
+ private byte[] getBytes(Object children) {
+ byte[] bytes = fingerprints.get(children);
+ if (bytes == null) {
+ if (children instanceof Object[]) {
+ Fingerprint fingerprint = new Fingerprint();
+ for (Object child : (Object[]) children) {
+ if (child instanceof Object[]) {
+ fingerprint.addBytes(getBytes(child));
+ } else {
+ addItemFingerprint(fingerprint, cast(child));
+ }
+ }
+ bytes = fingerprint.digestAndReset();
+
+ // There is no point memoizing anything except the multi-item case,
+ // since the single-item case gets inlined into its parents anyway,
+ // and the empty set is a singleton
+ fingerprints.put(children, bytes);
+ } else if (children != NestedSet.EMPTY_CHILDREN) {
+ // Single item
+ Fingerprint fingerprint = new Fingerprint();
+ addItemFingerprint(fingerprint, cast(children));
+ bytes = fingerprint.digestAndReset();
+ } else {
+ // Empty nested set
+ bytes = EMPTY_SET_BYTES;
+ }
+ }
+ return bytes;
+ }
+
+ @SuppressWarnings("unchecked")
+ private T cast(Object item) {
+ return (T) item;
+ }
+
+ private static Map<Object, byte[]> createMap() {
+ return new ConcurrentHashMap<>();
+ }
+
+ protected abstract void addItemFingerprint(Fingerprint fingerprint, T item);
+}