diff options
author | tomlu <tomlu@google.com> | 2017-11-29 14:01:21 -0800 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2017-11-29 14:03:30 -0800 |
commit | 3d1a194ff9e76f25f1a7242ff2d021523ba8e4a0 (patch) | |
tree | 9fec583a59b8ee6ee0f4fac513d5471956dfe1d3 /src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetFingerprintCache.java | |
parent | 8f8b8859fc7d85feee97481443fb11c0b7ae03ce (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.java | 78 |
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); +} |