diff options
author | 2018-02-23 15:41:52 -0800 | |
---|---|---|
committer | 2018-02-23 15:43:54 -0800 | |
commit | bbbf3dce2b95f054c8f2e85746b6b50b47740f61 (patch) | |
tree | 04d99f077d117a513d97651526c77cccada47b53 /src/main/java/com/google | |
parent | 62476a2738456c14bf92b6bcc81ade2c93ca7e87 (diff) |
Integrates CodecScanner into SkyValueEncoder.
* Deletes a number of CODEC references, now superceded by registry functionality.
* Minimal SkyKeySerializer modifications for correctness, as certain codec changes require
codecs to be in available in the registry.
PiperOrigin-RevId: 186834520
Diffstat (limited to 'src/main/java/com/google')
14 files changed, 152 insertions, 129 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/pkgcache/FilteringPolicies.java b/src/main/java/com/google/devtools/build/lib/pkgcache/FilteringPolicies.java index 404051e0b7..e91439642b 100644 --- a/src/main/java/com/google/devtools/build/lib/pkgcache/FilteringPolicies.java +++ b/src/main/java/com/google/devtools/build/lib/pkgcache/FilteringPolicies.java @@ -37,10 +37,8 @@ public final class FilteringPolicies { private FilteringPolicies() { } - /** - * Base class for singleton filtering policies. - */ - private abstract static class AbstractFilteringPolicy implements FilteringPolicy { + /** Base class for singleton filtering policies. */ + private abstract static class AbstractFilteringPolicy extends FilteringPolicy { private final int hashCode = getClass().getSimpleName().hashCode(); @Override @@ -90,7 +88,7 @@ public final class FilteringPolicies { } /** FilteringPolicy for combining FilteringPolicies. */ - public static class AndFilteringPolicy implements FilteringPolicy { + public static class AndFilteringPolicy extends FilteringPolicy { private final FilteringPolicy firstPolicy; private final FilteringPolicy secondPolicy; diff --git a/src/main/java/com/google/devtools/build/lib/pkgcache/FilteringPolicy.java b/src/main/java/com/google/devtools/build/lib/pkgcache/FilteringPolicy.java index 9e98190382..3790fbc581 100644 --- a/src/main/java/com/google/devtools/build/lib/pkgcache/FilteringPolicy.java +++ b/src/main/java/com/google/devtools/build/lib/pkgcache/FilteringPolicy.java @@ -15,21 +15,20 @@ package com.google.devtools.build.lib.pkgcache; import com.google.devtools.build.lib.concurrent.ThreadSafety; import com.google.devtools.build.lib.packages.Target; - import java.io.Serializable; /** * A filtering policy defines how target patterns are matched. For instance, we may wish to select * only tests or no tests. */ -public interface FilteringPolicy extends Serializable { +public abstract class FilteringPolicy implements Serializable { /** * Returns true if this target should be retained. * * @param explicit true iff the label was specified explicitly, as opposed to being discovered by - * a wildcard. + * a wildcard. */ @ThreadSafety.ThreadSafe - boolean shouldRetain(Target target, boolean explicit); + public abstract boolean shouldRetain(Target target, boolean explicit); } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesValue.java index 0bdd5c512e..73d13b8b95 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesValue.java @@ -15,22 +15,22 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.skyframe.LegacySkyKey; import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; -/** - * An immutable set of package name prefixes that should be blacklisted. - */ +/** An immutable set of package name prefixes that should be blacklisted. */ +@AutoCodec public class BlacklistedPackagePrefixesValue implements SkyValue { private final ImmutableSet<PathFragment> patterns; private static final SkyKey BLACKLIST_KEY = LegacySkyKey.create(SkyFunctions.BLACKLISTED_PACKAGE_PREFIXES, ""); - public BlacklistedPackagePrefixesValue(ImmutableSet<PathFragment> exclusions) { - this.patterns = Preconditions.checkNotNull(exclusions); + public BlacklistedPackagePrefixesValue(ImmutableSet<PathFragment> patterns) { + this.patterns = Preconditions.checkNotNull(patterns); } public static SkyKey key() { diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupValue.java index 491275ceef..4454dbe339 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupValue.java @@ -15,6 +15,7 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.base.Preconditions; import com.google.devtools.build.lib.cmdline.PackageIdentifier; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.skyframe.LegacySkyKey; import com.google.devtools.build.skyframe.SkyKey; @@ -27,7 +28,7 @@ import com.google.devtools.build.skyframe.SkyValue; */ public abstract class ContainingPackageLookupValue implements SkyValue { - public static final NoContainingPackage NONE = new NoContainingPackage(); + public static final NoContainingPackage NONE = NoContainingPackage.INSTANCE; /** Returns whether there is a containing package. */ public abstract boolean hasContainingPackage(); @@ -49,7 +50,9 @@ public abstract class ContainingPackageLookupValue implements SkyValue { } /** Value indicating there is no containing package. */ + @AutoCodec(strategy = AutoCodec.Strategy.SINGLETON) public static class NoContainingPackage extends ContainingPackageLookupValue { + public static final NoContainingPackage INSTANCE = new NoContainingPackage(); private NoContainingPackage() {} @@ -70,12 +73,15 @@ public abstract class ContainingPackageLookupValue implements SkyValue { } /** A successful lookup value. */ + @AutoCodec public static class ContainingPackage extends ContainingPackageLookupValue { private final PackageIdentifier containingPackage; private final Root containingPackageRoot; - private ContainingPackage(PackageIdentifier pkgId, Root containingPackageRoot) { - this.containingPackage = pkgId; + @AutoCodec.Instantiator + @AutoCodec.VisibleForSerialization + ContainingPackage(PackageIdentifier containingPackage, Root containingPackageRoot) { + this.containingPackage = containingPackage; this.containingPackageRoot = containingPackageRoot; } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java index 408bc2753f..0c78c40146 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java @@ -17,6 +17,7 @@ import com.google.common.base.Objects; import com.google.common.base.Preconditions; import com.google.devtools.build.lib.cmdline.PackageIdentifier; import com.google.devtools.build.lib.packages.BuildFileName; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; @@ -38,11 +39,11 @@ import com.google.devtools.build.skyframe.SkyValue; public abstract class PackageLookupValue implements SkyValue { public static final NoBuildFilePackageLookupValue NO_BUILD_FILE_VALUE = - new NoBuildFilePackageLookupValue(); + NoBuildFilePackageLookupValue.INSTANCE; public static final DeletedPackageLookupValue DELETED_PACKAGE_VALUE = - new DeletedPackageLookupValue(); + DeletedPackageLookupValue.INSTANCE; public static final NoRepositoryPackageLookupValue NO_SUCH_REPOSITORY_VALUE = - new NoRepositoryPackageLookupValue(); + NoRepositoryPackageLookupValue.INSTANCE; enum ErrorReason { /** There is no BUILD file. */ @@ -118,12 +119,15 @@ public abstract class PackageLookupValue implements SkyValue { } /** Successful lookup value. */ + @AutoCodec public static class SuccessfulPackageLookupValue extends PackageLookupValue { private final Root root; private final BuildFileName buildFileName; - private SuccessfulPackageLookupValue(Root root, BuildFileName buildFileName) { + @AutoCodec.Instantiator + @AutoCodec.VisibleForSerialization + SuccessfulPackageLookupValue(Root root, BuildFileName buildFileName) { this.root = root; this.buildFileName = buildFileName; } @@ -187,7 +191,9 @@ public abstract class PackageLookupValue implements SkyValue { } /** Marker value for no build file found. */ + @AutoCodec(strategy = AutoCodec.Strategy.SINGLETON) public static class NoBuildFilePackageLookupValue extends UnsuccessfulPackageLookupValue { + static final NoBuildFilePackageLookupValue INSTANCE = new NoBuildFilePackageLookupValue(); private NoBuildFilePackageLookupValue() { } @@ -204,11 +210,14 @@ public abstract class PackageLookupValue implements SkyValue { } /** Value indicating the package name was in error. */ + @AutoCodec public static class InvalidNamePackageLookupValue extends UnsuccessfulPackageLookupValue { private final String errorMsg; - private InvalidNamePackageLookupValue(String errorMsg) { + @AutoCodec.Instantiator + @AutoCodec.VisibleForSerialization + InvalidNamePackageLookupValue(String errorMsg) { this.errorMsg = errorMsg; } @@ -243,13 +252,16 @@ public abstract class PackageLookupValue implements SkyValue { } /** Value indicating the package name was in error. */ + @AutoCodec public static class IncorrectRepositoryReferencePackageLookupValue extends UnsuccessfulPackageLookupValue { private final PackageIdentifier invalidPackageIdentifier; private final PackageIdentifier correctedPackageIdentifier; - private IncorrectRepositoryReferencePackageLookupValue( + @AutoCodec.Instantiator + @AutoCodec.VisibleForSerialization + IncorrectRepositoryReferencePackageLookupValue( PackageIdentifier invalidPackageIdentifier, PackageIdentifier correctedPackageIdentifier) { this.invalidPackageIdentifier = invalidPackageIdentifier; this.correctedPackageIdentifier = correctedPackageIdentifier; @@ -305,7 +317,9 @@ public abstract class PackageLookupValue implements SkyValue { } /** Marker value for a deleted package. */ + @AutoCodec(strategy = AutoCodec.Strategy.SINGLETON) public static class DeletedPackageLookupValue extends UnsuccessfulPackageLookupValue { + static final DeletedPackageLookupValue INSTANCE = new DeletedPackageLookupValue(); private DeletedPackageLookupValue() { } @@ -325,7 +339,9 @@ public abstract class PackageLookupValue implements SkyValue { * Marker value for repository we could not find. This can happen when looking for a label that * specifies a non-existent repository. */ + @AutoCodec(strategy = AutoCodec.Strategy.SINGLETON) public static class NoRepositoryPackageLookupValue extends UnsuccessfulPackageLookupValue { + static final NoRepositoryPackageLookupValue INSTANCE = new NoRepositoryPackageLookupValue(); private NoRepositoryPackageLookupValue() {} diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java index 8f5277a98a..2f8338989d 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java @@ -25,6 +25,7 @@ import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory.BuildIn import com.google.devtools.build.lib.packages.RuleVisibility; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; import com.google.devtools.build.lib.skyframe.SkyframeActionExecutor.ConflictException; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.syntax.SkylarkSemantics; import com.google.devtools.build.skyframe.Injectable; import com.google.devtools.build.skyframe.LegacySkyKey; @@ -40,6 +41,7 @@ import javax.annotation.Nullable; * "precomputed" from skyframe's perspective and so the graph needs to be prepopulated with them * (e.g. via injection). */ +@AutoCodec public final class PrecomputedValue implements SkyValue { /** * An externally-injected precomputed value. Exists so that modules can inject precomputed values @@ -103,6 +105,7 @@ public final class PrecomputedValue implements SkyValue { private final Object value; + @AutoCodec.Instantiator public PrecomputedValue(Object value) { this.value = Preconditions.checkNotNull(value); } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValueCodec.java b/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValueCodec.java deleted file mode 100644 index 1fc108d778..0000000000 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValueCodec.java +++ /dev/null @@ -1,67 +0,0 @@ -// 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.skyframe; - -import com.google.common.base.Preconditions; -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.ObjectCodecs; -import com.google.devtools.build.lib.skyframe.serialization.SerializationContext; -import com.google.devtools.build.lib.skyframe.serialization.SerializationException; -import com.google.protobuf.CodedInputStream; -import com.google.protobuf.CodedOutputStream; -import java.io.IOException; -import java.util.function.Supplier; - -/** - * {@link ObjectCodec} for {@link PrecomputedValue} objects. Because {@link PrecomputedValue} - * objects can theoretically contain any kind of value object as their value, an {@link - * ObjectCodecs} instance must be accessible to this codec during serialization/deserialization, so - * that it can handle the arbitrary objects it's given. - */ -public class PrecomputedValueCodec implements ObjectCodec<PrecomputedValue> { - private final Supplier<ObjectCodecs> objectCodecsSupplier; - - public PrecomputedValueCodec(Supplier<ObjectCodecs> objectCodecsSupplier) { - this.objectCodecsSupplier = objectCodecsSupplier; - } - - @Override - public Class<PrecomputedValue> getEncodedClass() { - return PrecomputedValue.class; - } - - @Override - public void serialize( - SerializationContext context, PrecomputedValue obj, CodedOutputStream codedOut) - throws SerializationException, IOException { - ObjectCodecs objectCodecs = objectCodecsSupplier.get(); - Object val = obj.get(); - Preconditions.checkState(!(val instanceof PrecomputedValue), "recursive precomputed: %s", obj); - // TODO(janakr): this assumes the classifier is the class of the object. This should be enforced - // by the ObjectCodecs instance. - String classifier = val.getClass().getName(); - codedOut.writeStringNoTag(classifier); - objectCodecs.serialize(classifier, val, codedOut); - } - - @Override - public PrecomputedValue deserialize(DeserializationContext context, CodedInputStream codedIn) - throws SerializationException, IOException { - ObjectCodecs objectCodecs = objectCodecsSupplier.get(); - Object val = objectCodecs.deserialize(codedIn.readBytes(), codedIn); - return new PrecomputedValue(val); - } -} diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsValue.java index ad0ed0c60c..6c915658f4 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsValue.java @@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; import com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.skyframe.LegacySkyKey; import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; @@ -26,20 +27,19 @@ import java.io.Serializable; import java.util.Objects; /** - * The value returned by {@link PrepareDepsOfPatternsFunction}. Although that function is - * invoked primarily for its side effect (i.e. ensuring the graph contains targets matching the - * pattern sequence and their transitive dependencies), this value contains the - * {@link TargetPatternKey} arguments of the {@link PrepareDepsOfPatternFunction}s evaluated in - * service of it. + * The value returned by {@link PrepareDepsOfPatternsFunction}. Although that function is invoked + * primarily for its side effect (i.e. ensuring the graph contains targets matching the pattern + * sequence and their transitive dependencies), this value contains the {@link TargetPatternKey} + * arguments of the {@link PrepareDepsOfPatternFunction}s evaluated in service of it. * * <p>Because the returned value may remain the same when the side-effects of this function - * evaluation change, this value and the {@link PrepareDepsOfPatternsFunction} which computes it - * are incompatible with change pruning. It should only be requested by consumers who do not - * require reevaluation when {@link PrepareDepsOfPatternsFunction} is reevaluated. Safe consumers - * include, e.g., top-level consumers, and other functions which invoke {@link - * PrepareDepsOfPatternsFunction} solely for its side-effects and which do not behave differently - * depending on those side-effects. + * evaluation change, this value and the {@link PrepareDepsOfPatternsFunction} which computes it are + * incompatible with change pruning. It should only be requested by consumers who do not require + * reevaluation when {@link PrepareDepsOfPatternsFunction} is reevaluated. Safe consumers include, + * e.g., top-level consumers, and other functions which invoke {@link PrepareDepsOfPatternsFunction} + * solely for its side-effects and which do not behave differently depending on those side-effects. */ +@AutoCodec @Immutable @ThreadSafe public final class PrepareDepsOfPatternsValue implements SkyValue { diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfTargetsUnderDirectoryValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfTargetsUnderDirectoryValue.java index 54db4d57cd..4c948a73d0 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfTargetsUnderDirectoryValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfTargetsUnderDirectoryValue.java @@ -21,6 +21,8 @@ import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; import com.google.devtools.build.lib.pkgcache.FilteringPolicies; import com.google.devtools.build.lib.pkgcache.FilteringPolicy; import com.google.devtools.build.lib.skyframe.RecursivePkgValue.RecursivePkgKey; +import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.LegacySkyKey; @@ -70,12 +72,17 @@ public final class PrepareDepsOfTargetsUnderDirectoryValue implements SkyValue { /** * The argument value for {@link SkyKey}s of {@link PrepareDepsOfTargetsUnderDirectoryFunction}. */ + @AutoCodec public static final class PrepareDepsOfTargetsUnderDirectoryKey implements Serializable { + public static final ObjectCodec<PrepareDepsOfTargetsUnderDirectoryKey> CODEC = + new PrepareDepsOfTargetsUnderDirectoryValue_PrepareDepsOfTargetsUnderDirectoryKey_AutoCodec(); + private final RecursivePkgKey recursivePkgKey; private final FilteringPolicy filteringPolicy; - public PrepareDepsOfTargetsUnderDirectoryKey(RecursivePkgKey recursivePkgKey, - FilteringPolicy filteringPolicy) { + @AutoCodec.Instantiator + public PrepareDepsOfTargetsUnderDirectoryKey( + RecursivePkgKey recursivePkgKey, FilteringPolicy filteringPolicy) { this.recursivePkgKey = Preconditions.checkNotNull(recursivePkgKey); this.filteringPolicy = Preconditions.checkNotNull(filteringPolicy); } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RecursivePkgValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/RecursivePkgValue.java index 74f94bf117..59b1201831 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/RecursivePkgValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/RecursivePkgValue.java @@ -21,6 +21,8 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; +import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.LegacySkyKey; @@ -69,19 +71,26 @@ public class RecursivePkgValue implements SkyValue { /** * A RecursivePkgKey is a tuple of a {@link RootedPath}, {@code rootedPath}, defining the * directory to recurse beneath in search of packages, and an {@link ImmutableSet} of {@link - * PathFragment}s, {@code excludedPaths}, relative to {@code rootedPath.getRoot}, defining the - * set of subdirectories strictly beneath {@code rootedPath} to skip. + * PathFragment}s, {@code excludedPaths}, relative to {@code rootedPath.getRoot}, defining the set + * of subdirectories strictly beneath {@code rootedPath} to skip. * - * <p>Throws {@link IllegalArgumentException} if {@code excludedPaths} contains any paths that - * are equal to {@code rootedPath} or that are not beneath {@code rootedPath}. + * <p>Throws {@link IllegalArgumentException} if {@code excludedPaths} contains any paths that are + * equal to {@code rootedPath} or that are not beneath {@code rootedPath}. */ + @AutoCodec @ThreadSafe public static final class RecursivePkgKey implements Serializable { + public static final ObjectCodec<RecursivePkgKey> CODEC = + new RecursivePkgValue_RecursivePkgKey_AutoCodec(); + private final RepositoryName repositoryName; private final RootedPath rootedPath; private final ImmutableSet<PathFragment> excludedPaths; - public RecursivePkgKey(RepositoryName repositoryName, RootedPath rootedPath, + @AutoCodec.Instantiator + public RecursivePkgKey( + RepositoryName repositoryName, + RootedPath rootedPath, ImmutableSet<PathFragment> excludedPaths) { PathFragment.checkAllPathsAreUnder(excludedPaths, rootedPath.getRootRelativePath()); Preconditions.checkState(!repositoryName.isDefault()); diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecRegistry.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecRegistry.java index e404ab0145..b1ff058f78 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecRegistry.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecRegistry.java @@ -123,6 +123,20 @@ public class ObjectCodecRegistry { } } + /** + * Creates a builder using the current contents of this registry. + * + * <p>This is much more efficient than scanning multiple times. + */ + Builder getBuilder() { + Builder builder = newBuilder(); + builder.setAllowDefaultCodec(defaultCodecDescriptor != null); + for (Map.Entry<String, CodecDescriptor> entry : stringMappedCodecs.entrySet()) { + builder.add(entry.getKey(), entry.getValue().getCodec()); + } + return builder; + } + /** Describes encoding logic. */ static interface CodecDescriptor { void serialize(SerializationContext context, Object obj, CodedOutputStream codedOut) @@ -143,11 +157,7 @@ public class ObjectCodecRegistry { */ int getTag(); - /** - * Returns the underlying codec. - * - * <p>For backwards compatibility. New callers should prefer the methods above. - */ + /** Returns the underlying codec. */ ObjectCodec<?> getCodec(); } @@ -206,8 +216,6 @@ public class ObjectCodecRegistry { private final ImmutableMap.Builder<String, CodecHolder> codecsBuilder = ImmutableMap.builder(); private boolean allowDefaultCodec = true; - private Builder() {} - /** * Add custom serialization strategy ({@code codec}) for {@code classifier}. * diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecs.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecs.java index 99a02ae8ed..4d31a033be 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecs.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecs.java @@ -38,8 +38,20 @@ public class ObjectCodecs { */ ObjectCodecs(ObjectCodecRegistry codecRegistry, ImmutableMap<Class<?>, Object> dependencies) { this.codecRegistry = codecRegistry; - serializationContext = new SerializationContext(dependencies); - deserializationContext = new DeserializationContext(dependencies); + serializationContext = new SerializationContext(codecRegistry, dependencies); + deserializationContext = new DeserializationContext(codecRegistry, dependencies); + } + + public ByteString serialize(Object subject) throws SerializationException { + ByteString.Output resultOut = ByteString.newOutput(); + CodedOutputStream codedOut = CodedOutputStream.newInstance(resultOut); + try { + serializationContext.serialize(subject, codedOut); + codedOut.flush(); + return resultOut.toByteString(); + } catch (IOException e) { + throw new SerializationException("Failed to serialize " + subject, e); + } } /** @@ -78,6 +90,15 @@ public class ObjectCodecs { } } + public Object deserialize(ByteString data) throws SerializationException { + CodedInputStream codedIn = data.newCodedInput(); + try { + return deserializationContext.deserialize(codedIn); + } catch (IOException e) { + throw new SerializationException("Failed to deserialize data", e); + } + } + /** * Deserialize {@code data} using the serialization strategy determined by {@code classifier}. * {@code classifier} should be the utf-8 encoded {@link ByteString} representation of the {@link diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/ObjectCodecTester.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/ObjectCodecTester.java index a0f5873ae6..3d4988aa3e 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/ObjectCodecTester.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/ObjectCodecTester.java @@ -61,6 +61,7 @@ public class ObjectCodecTester<T> { private final DeserializationContext readContext; private final boolean skipBadDataTest; private final VerificationFunction<T> verificationFunction; + private final int repetitions; private ObjectCodecTester( ObjectCodec<T> underTest, @@ -68,7 +69,8 @@ public class ObjectCodecTester<T> { SerializationContext writeContext, DeserializationContext readContext, boolean skipBadDataTest, - VerificationFunction<T> verificationFunction) { + VerificationFunction<T> verificationFunction, + int repetitions) { this.underTest = underTest; Preconditions.checkState(!subjects.isEmpty(), "No subjects provided"); this.subjects = subjects; @@ -76,6 +78,7 @@ public class ObjectCodecTester<T> { this.readContext = readContext; this.skipBadDataTest = skipBadDataTest; this.verificationFunction = verificationFunction; + this.repetitions = repetitions; } private void runTests() throws Exception { @@ -90,11 +93,13 @@ public class ObjectCodecTester<T> { void testSerializeDeserialize() throws Exception { Stopwatch timer = Stopwatch.createStarted(); int totalBytes = 0; - for (T subject : subjects) { - byte[] serialized = toBytes(subject); - totalBytes += serialized.length; - T deserialized = fromBytes(serialized); - verificationFunction.verifyDeserialized(subject, deserialized); + for (int i = 0; i < repetitions; ++i) { + for (T subject : subjects) { + byte[] serialized = toBytes(subject); + totalBytes += serialized.length; + T deserialized = fromBytes(serialized); + verificationFunction.verifyDeserialized(subject, deserialized); + } } logger.log( Level.INFO, @@ -143,6 +148,7 @@ public class ObjectCodecTester<T> { private boolean skipBadDataTest = false; private VerificationFunction<T> verificationFunction = (original, deserialized) -> assertThat(deserialized).isEqualTo(original); + int repetitions = 1; private Builder(ObjectCodec<T> underTest) { this.underTest = underTest; @@ -185,6 +191,11 @@ public class ObjectCodecTester<T> { return this; } + public Builder<T> setRepetitions(int repetitions) { + this.repetitions = repetitions; + return this; + } + /** Captures the state of this builder and run all associated tests. */ public void buildAndRunTests() throws Exception { build().runTests(); @@ -202,7 +213,8 @@ public class ObjectCodecTester<T> { new SerializationContext(dependencies), new DeserializationContext(dependencies), skipBadDataTest, - verificationFunction); + verificationFunction, + repetitions); } } } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/SerializationTester.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/SerializationTester.java index 5d561ad7c9..d89a428603 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/SerializationTester.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/SerializationTester.java @@ -66,6 +66,8 @@ public class SerializationTester { private VerificationFunction verificationFunction = (original, deserialized) -> assertThat(deserialized).isEqualTo(original); + private int repetitions = 1; + public SerializationTester(Object... subjects) { Preconditions.checkArgument(subjects.length > 0); this.subjects = ImmutableList.copyOf(subjects); @@ -89,6 +91,12 @@ public class SerializationTester { return this; } + /** Sets the number of times to repeat serialization and deserialization. */ + public SerializationTester setRepetitions(int repetitions) { + this.repetitions = repetitions; + return this; + } + public void runTests() throws Exception { testSerializeDeserialize(); testStableSerialization(); @@ -96,14 +104,17 @@ public class SerializationTester { } /** Runs serialization/deserialization tests. */ + @SuppressWarnings("unchecked") private void testSerializeDeserialize() throws Exception { Stopwatch timer = Stopwatch.createStarted(); int totalBytes = 0; - for (Object subject : subjects) { - byte[] serialized = toBytes(subject); - totalBytes += serialized.length; - Object deserialized = fromBytes(serialized); - verificationFunction.verifyDeserialized(subject, deserialized); + for (int i = 0; i < repetitions; ++i) { + for (Object subject : subjects) { + byte[] serialized = toBytes(subject); + totalBytes += serialized.length; + Object deserialized = fromBytes(serialized); + verificationFunction.verifyDeserialized(subject, deserialized); + } } logger.log( Level.INFO, |