aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
authorGravatar shahan <shahan@google.com>2018-02-23 15:41:52 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2018-02-23 15:43:54 -0800
commitbbbf3dce2b95f054c8f2e85746b6b50b47740f61 (patch)
tree04d99f077d117a513d97651526c77cccada47b53 /src/main/java/com/google
parent62476a2738456c14bf92b6bcc81ade2c93ca7e87 (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')
-rw-r--r--src/main/java/com/google/devtools/build/lib/pkgcache/FilteringPolicies.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/pkgcache/FilteringPolicy.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesValue.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupValue.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java28
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValueCodec.java67
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsValue.java22
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfTargetsUnderDirectoryValue.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/RecursivePkgValue.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecRegistry.java22
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecs.java25
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/ObjectCodecTester.java26
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/SerializationTester.java21
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,