diff options
author | 2018-07-26 10:34:15 -0700 | |
---|---|---|
committer | 2018-07-26 10:35:21 -0700 | |
commit | db01c6f926bcb4774d901797c59f51dd54c05624 (patch) | |
tree | e6787b60cc8aeefc22943a34f4fb151b1b6fca8d /src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationValue.java | |
parent | e24a591d4288b33dfbf790e89e0def610fe6a7d9 (diff) |
PiperOrigin-RevId: 206181674
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationValue.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationValue.java | 86 |
1 files changed, 79 insertions, 7 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationValue.java index 90479a9a54..1e9bc52d30 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationValue.java @@ -21,14 +21,23 @@ import com.google.devtools.build.lib.analysis.config.BuildOptions; import com.google.devtools.build.lib.analysis.config.FragmentClassSet; import com.google.devtools.build.lib.concurrent.BlazeInterners; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; +import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext; +import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; +import com.google.devtools.build.lib.skyframe.serialization.SerializationContext; +import com.google.devtools.build.lib.skyframe.serialization.SerializationException; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; -import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization; import com.google.devtools.build.skyframe.SkyFunctionName; import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; +import com.google.protobuf.ByteString; +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import java.io.IOException; import java.io.Serializable; import java.util.Objects; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import java.util.logging.Logger; /** A Skyframe value representing a {@link BuildConfiguration}. */ @@ -59,7 +68,7 @@ public class BuildConfigurationValue implements SkyValue { public static Key key( Set<Class<? extends BuildConfiguration.Fragment>> fragments, BuildOptions.OptionsDiffForReconstruction optionsDiff) { - return Key.create( + return key( FragmentClassSet.of( ImmutableSortedSet.copyOf(BuildConfiguration.lexicalFragmentSorter, fragments)), optionsDiff); @@ -75,18 +84,15 @@ public class BuildConfigurationValue implements SkyValue { } /** {@link SkyKey} for {@link BuildConfigurationValue}. */ - @AutoCodec public static final class Key implements SkyKey, Serializable { private static final Interner<Key> keyInterner = BlazeInterners.newWeakInterner(); private final FragmentClassSet fragments; - final BuildOptions.OptionsDiffForReconstruction optionsDiff; + private final BuildOptions.OptionsDiffForReconstruction optionsDiff; // If hashCode really is -1, we'll recompute it from scratch each time. Oh well. private volatile int hashCode = -1; - @AutoCodec.Instantiator - @VisibleForSerialization - static Key create( + private static Key create( FragmentClassSet fragments, BuildOptions.OptionsDiffForReconstruction optionsDiff) { return keyInterner.intern(new Key(fragments, optionsDiff)); } @@ -135,5 +141,71 @@ public class BuildConfigurationValue implements SkyValue { public String toString() { return "BuildConfigurationValue.Key[" + optionsDiff.getChecksum() + "]"; } + + private static class Codec implements ObjectCodec<Key> { + @Override + public Class<Key> getEncodedClass() { + return Key.class; + } + + @Override + public void serialize(SerializationContext context, Key obj, CodedOutputStream codedOut) + throws SerializationException, IOException { + @SuppressWarnings("unchecked") + ConcurrentMap<BuildConfigurationValue.Key, ByteString> cache = + context.getDependency(KeyCodecCache.class).map; + ByteString bytes = cache.get(obj); + if (bytes == null) { + context = context.getNewNonMemoizingContext(); + ByteString.Output byteStringOut = ByteString.newOutput(); + CodedOutputStream bytesOut = CodedOutputStream.newInstance(byteStringOut); + context.serialize(obj.optionsDiff, bytesOut); + bytesOut.flush(); + byteStringOut.flush(); + int optionsDiffSerializedSize = byteStringOut.size(); + context.serialize(obj.fragments, bytesOut); + bytesOut.flush(); + byteStringOut.flush(); + bytes = byteStringOut.toByteString(); + cache.put(obj, bytes); + logger.info( + "Serialized " + + obj.optionsDiff + + " and " + + obj.fragments + + " to " + + bytes.size() + + " bytes (optionsDiff took " + + optionsDiffSerializedSize + + " bytes)"); + } + codedOut.writeBytesNoTag(bytes); + } + + @Override + public Key deserialize(DeserializationContext context, CodedInputStream codedIn) + throws SerializationException, IOException { + codedIn = codedIn.readBytes().newCodedInput(); + context = context.getNewNonMemoizingContext(); + BuildOptions.OptionsDiffForReconstruction optionsDiff = context.deserialize(codedIn); + FragmentClassSet fragmentClassSet = context.deserialize(codedIn); + return key(fragmentClassSet, optionsDiff); + } + } + } + + /** + * Injected cache for {@code Codec}, so that we don't have to repeatedly serialize the same + * object. We still incur the over-the-wire cost of the bytes, but we don't use CPU to repeatedly + * compute it. + * + * <p>We provide the cache as an injected dependency so that different serializers' caches are + * isolated. + */ + public static class KeyCodecCache { + private final ConcurrentMap<BuildConfigurationValue.Key, ByteString> map = + new ConcurrentHashMap<>(); + + public KeyCodecCache() {} } } |