Model the TopLevelArtifactContext as an argument to the CompletionFunction rather than a PRECOMPUTED value.
Having a stale TopLevelArtifactContext leads to invalidation of all the top level target nodes, causing time wasted due to a lot of cache hits for a null build.
--
MOS_MIGRATED_REVID=127585059
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
index 0346514..8272143 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
@@ -198,9 +198,13 @@
// Execution phase.
if (needsExecutionPhase(request.getBuildOptions())) {
- env.getSkyframeExecutor().injectTopLevelContext(request.getTopLevelArtifactContext());
- executionTool.executeBuild(request.getId(), analysisResult, result,
- configurations, analysisResult.getPackageRoots());
+ executionTool.executeBuild(
+ request.getId(),
+ analysisResult,
+ result,
+ configurations,
+ analysisResult.getPackageRoots(),
+ request.getTopLevelArtifactContext());
}
String delayedErrorMsg = analysisResult.getError();
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
index 0a8a0cb..2d1e52c 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
@@ -55,6 +55,7 @@
import com.google.devtools.build.lib.analysis.BuildView.AnalysisResult;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.SymlinkTreeActionContext;
+import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
import com.google.devtools.build.lib.analysis.TopLevelArtifactHelper;
import com.google.devtools.build.lib.analysis.WorkspaceStatusAction;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
@@ -336,7 +337,8 @@
void executeBuild(UUID buildId, AnalysisResult analysisResult,
BuildResult buildResult,
BuildConfigurationCollection configurations,
- ImmutableMap<PackageIdentifier, Path> packageRoots)
+ ImmutableMap<PackageIdentifier, Path> packageRoots,
+ TopLevelArtifactContext topLevelArtifactContext)
throws BuildFailedException, InterruptedException, TestExecException, AbruptExitException {
Stopwatch timer = Stopwatch.createStarted();
prepare(packageRoots);
@@ -438,7 +440,8 @@
executor,
builtTargets,
request.getBuildOptions().explanationPath != null,
- env.getBlazeWorkspace().getLastExecutionTimeRange());
+ env.getBlazeWorkspace().getLastExecutionTimeRange(),
+ topLevelArtifactContext);
buildCompleted = true;
} catch (BuildFailedException | TestExecException e) {
buildCompleted = true;
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java b/src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java
index afc68b1..ba0fbe6 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java
@@ -29,6 +29,7 @@
import com.google.devtools.build.lib.actions.ResourceManager;
import com.google.devtools.build.lib.actions.TestExecException;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
import com.google.devtools.build.lib.buildtool.buildevent.ExecutionProgressReceiverAvailableEvent;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.events.Reporter;
@@ -101,7 +102,8 @@
Executor executor,
Set<ConfiguredTarget> builtTargets,
boolean explain,
- @Nullable Range<Long> lastExecutionTimeRange)
+ @Nullable Range<Long> lastExecutionTimeRange,
+ TopLevelArtifactContext topLevelArtifactContext)
throws BuildFailedException, AbruptExitException, TestExecException, InterruptedException {
skyframeExecutor.prepareExecution(modifiedOutputFiles, lastExecutionTimeRange);
skyframeExecutor.setFileCache(fileCache);
@@ -146,7 +148,8 @@
finalizeActionsToOutputService,
numJobs,
actionCacheChecker,
- executionProgressReceiver);
+ executionProgressReceiver,
+ topLevelArtifactContext);
// progressReceiver is finished, so unsynchronized access to builtTargets is now safe.
Optional<ExitCode> exitCode = processResult(reporter, result, keepGoing, skyframeExecutor);
@@ -185,7 +188,8 @@
finalizeActionsToOutputService,
numJobs,
actionCacheChecker,
- null);
+ null,
+ topLevelArtifactContext);
exitCode = processResult(reporter, result, keepGoing, skyframeExecutor);
Preconditions.checkState(
exitCode != null || !result.keyNames().isEmpty(),
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionArtifactCycleReporter.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionArtifactCycleReporter.java
index 91574fc..b71321c 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionArtifactCycleReporter.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionArtifactCycleReporter.java
@@ -18,10 +18,10 @@
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Action;
-import com.google.devtools.build.lib.analysis.LabelAndConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.pkgcache.PackageProvider;
import com.google.devtools.build.lib.skyframe.ArtifactValue.OwnedArtifact;
+import com.google.devtools.build.lib.skyframe.TargetCompletionValue.TargetCompletionKey;
import com.google.devtools.build.skyframe.CycleInfo;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
@@ -50,9 +50,9 @@
return "file: " + ((OwnedArtifact) arg).getArtifact().getRootRelativePathString();
} else if (arg instanceof Action) {
return "action: " + ((Action) arg).getMnemonic();
- } else if (arg instanceof LabelAndConfiguration
+ } else if (arg instanceof TargetCompletionKey
&& skyFunctionName.equals(SkyFunctions.TARGET_COMPLETION)) {
- return "configured target: " + ((LabelAndConfiguration) arg).getLabel();
+ return "configured target: " + ((TargetCompletionKey) arg).labelAndConfiguration().getLabel();
}
throw new IllegalStateException(
"Argument is not Action, TargetCompletion, or OwnedArtifact: " + arg);
@@ -60,7 +60,7 @@
@Override
protected Label getLabel(SkyKey key) {
- Object arg = key.argument();
+ Object arg = key.argument();
if (arg instanceof OwnedArtifact) {
return ((OwnedArtifact) arg).getArtifact().getOwner();
} else if (arg instanceof Action) {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AspectCompletionValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/AspectCompletionValue.java
index 22b0ee0..45c17fa 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/AspectCompletionValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/AspectCompletionValue.java
@@ -13,8 +13,11 @@
// limitations under the License.
package com.google.devtools.build.lib.skyframe;
+import com.google.auto.value.AutoValue;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
+import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
+import com.google.devtools.build.lib.skyframe.AspectValue.AspectKey;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
@@ -34,14 +37,29 @@
return aspectValue;
}
- public static Iterable<SkyKey> keys(Collection<AspectValue> targets) {
+ public static Iterable<SkyKey> keys(
+ Collection<AspectValue> targets, final TopLevelArtifactContext ctx) {
return Iterables.transform(
targets,
new Function<AspectValue, SkyKey>() {
@Override
public SkyKey apply(AspectValue aspectValue) {
- return SkyKey.create(SkyFunctions.ASPECT_COMPLETION, aspectValue.getKey());
+ return SkyKey.create(
+ SkyFunctions.ASPECT_COMPLETION,
+ AspectCompletionKey.create(aspectValue.getKey(), ctx));
}
});
}
+
+ @AutoValue
+ abstract static class AspectCompletionKey {
+ public static AspectCompletionKey create(
+ AspectKey aspectKey, TopLevelArtifactContext topLevelArtifactContext) {
+ return new AutoValue_AspectCompletionValue_AspectCompletionKey(
+ aspectKey, topLevelArtifactContext);
+ }
+
+ public abstract AspectKey aspectKey();
+ public abstract TopLevelArtifactContext topLevelArtifactContext();
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/Builder.java b/src/main/java/com/google/devtools/build/lib/skyframe/Builder.java
index e6f1c3d..d25341a 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/Builder.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/Builder.java
@@ -20,6 +20,7 @@
import com.google.devtools.build.lib.actions.Executor;
import com.google.devtools.build.lib.actions.TestExecException;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible;
import com.google.devtools.build.lib.events.Reporter;
import com.google.devtools.build.lib.util.AbruptExitException;
@@ -64,6 +65,8 @@
* valid even if a future action throws ActionExecutionException
* @param lastExecutionTimeRange If not null, the start/finish time of the last build that
* run the execution phase.
+ * @param topLevelArtifactContext contains the the options which determine the artifacts to build
+ * for the top-level targets.
* @throws BuildFailedException if there were problems establishing the action execution
* environment, if the the metadata of any file during the build could not be obtained,
* if any input files are missing, or if an action fails during execution
@@ -81,6 +84,7 @@
Executor executor,
Set<ConfiguredTarget> builtTargets,
boolean explain,
- @Nullable Range<Long> lastExecutionTimeRange)
+ @Nullable Range<Long> lastExecutionTimeRange,
+ TopLevelArtifactContext topLevelArtifactContext)
throws BuildFailedException, AbruptExitException, InterruptedException, TestExecException;
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java
index f19a572..1f48c84 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java
@@ -28,7 +28,9 @@
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.skyframe.AspectCompletionValue.AspectCompletionKey;
import com.google.devtools.build.lib.skyframe.AspectValue.AspectKey;
+import com.google.devtools.build.lib.skyframe.TargetCompletionValue.TargetCompletionKey;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyKey;
@@ -57,7 +59,21 @@
TValue getValueFromSkyKey(SkyKey skyKey, Environment env);
/**
- * Returns all artefacts that need to be built to complete the {@code value}
+ * Returns the options which determine the artifacts to build for the top-level targets.
+ * <p>
+ * For the Top level targets we made a conscious decision to include the TopLevelArtifactContext
+ * within the SkyKey as an argument to the CompletionFunction rather than a separate SkyKey.
+ * As a result we do have <num top level targets> extra SkyKeys for every unique
+ * TopLevelArtifactContexts used over the lifetime of Blaze. This is a minor tradeoff,
+ * since it significantly improves null build times when we're switching the
+ * TopLevelArtifactContexts frequently (common for IDEs), by reusing existing SkyKeys
+ * from earlier runs, instead of causing an eager invalidation
+ * were the TopLevelArtifactContext modeled as a separate SkyKey.
+ */
+ TopLevelArtifactContext getTopLevelArtifactContext(SkyKey skyKey);
+
+ /**
+ * Returns all artifacts that need to be built to complete the {@code value}
*/
ArtifactsToBuild getAllArtifactsToBuild(TValue value, TopLevelArtifactContext context);
@@ -80,18 +96,30 @@
* Creates a failed completion value.
*/
SkyValue createFailed(TValue value, NestedSet<Label> rootCauses);
+
+ /**
+ * Extracts a tag given the {@link SkyKey}.
+ */
+ String extractTag(SkyKey skyKey);
}
private static class TargetCompletor
implements Completor<ConfiguredTargetValue, TargetCompletionValue> {
@Override
public ConfiguredTargetValue getValueFromSkyKey(SkyKey skyKey, Environment env) {
- LabelAndConfiguration lac = (LabelAndConfiguration) skyKey.argument();
+ TargetCompletionKey tcKey = (TargetCompletionKey) skyKey.argument();
+ LabelAndConfiguration lac = tcKey.labelAndConfiguration();
return (ConfiguredTargetValue)
env.getValue(ConfiguredTargetValue.key(lac.getLabel(), lac.getConfiguration()));
}
@Override
+ public TopLevelArtifactContext getTopLevelArtifactContext(SkyKey skyKey) {
+ TargetCompletionKey tcKey = (TargetCompletionKey) skyKey.argument();
+ return tcKey.topLevelArtifactContext();
+ }
+
+ @Override
public ArtifactsToBuild getAllArtifactsToBuild(
ConfiguredTargetValue value, TopLevelArtifactContext topLevelContext) {
return TopLevelArtifactHelper.getAllArtifactsToBuild(
@@ -126,16 +154,29 @@
public SkyValue createFailed(ConfiguredTargetValue value, NestedSet<Label> rootCauses) {
return TargetCompleteEvent.createFailed(value.getConfiguredTarget(), rootCauses);
}
+
+ @Override
+ public String extractTag(SkyKey skyKey) {
+ return Label.print(
+ ((TargetCompletionKey) skyKey.argument()).labelAndConfiguration().getLabel());
+ }
}
private static class AspectCompletor implements Completor<AspectValue, AspectCompletionValue> {
@Override
public AspectValue getValueFromSkyKey(SkyKey skyKey, Environment env) {
- AspectKey aspectKey = (AspectKey) skyKey.argument();
+ AspectCompletionKey acKey = (AspectCompletionKey) skyKey.argument();
+ AspectKey aspectKey = acKey.aspectKey();
return (AspectValue) env.getValue(AspectValue.key(aspectKey));
}
@Override
+ public TopLevelArtifactContext getTopLevelArtifactContext(SkyKey skyKey) {
+ AspectCompletionKey acKey = (AspectCompletionKey) skyKey.argument();
+ return acKey.topLevelArtifactContext();
+ }
+
+ @Override
public ArtifactsToBuild getAllArtifactsToBuild(
AspectValue value, TopLevelArtifactContext topLevelArtifactContext) {
return TopLevelArtifactHelper.getAllArtifactsToBuild(value, topLevelArtifactContext);
@@ -172,6 +213,11 @@
public SkyValue createFailed(AspectValue value, NestedSet<Label> rootCauses) {
return AspectCompleteEvent.createFailed(value, rootCauses);
}
+
+ @Override
+ public String extractTag(SkyKey skyKey) {
+ return Label.print(((AspectCompletionKey) skyKey.argument()).aspectKey().getLabel());
+ }
}
public static SkyFunction targetCompletionFunction(AtomicReference<EventBus> eventBusRef) {
@@ -195,7 +241,7 @@
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws CompletionFunctionException {
TValue value = completor.getValueFromSkyKey(skyKey, env);
- TopLevelArtifactContext topLevelContext = PrecomputedValue.TOP_LEVEL_CONTEXT.get(env);
+ TopLevelArtifactContext topLevelContext = completor.getTopLevelArtifactContext(skyKey);
if (env.valuesMissing()) {
return null;
}
@@ -250,7 +296,7 @@
@Override
public String extractTag(SkyKey skyKey) {
- return Label.print(((LabelAndConfiguration) skyKey.argument()).getLabel());
+ return completor.extractTag(skyKey);
}
private static final class CompletionFunctionException extends SkyFunctionException {
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 3fe34d4..a5f7a67 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
@@ -20,7 +20,6 @@
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
-import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
import com.google.devtools.build.lib.analysis.WorkspaceStatusAction;
import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory;
import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory.BuildInfoKey;
@@ -92,9 +91,6 @@
static final Precomputed<ImmutableList<ActionAnalysisMetadata>> COVERAGE_REPORT_KEY =
new Precomputed<>(SkyKey.create(SkyFunctions.PRECOMPUTED, "coverage_report_actions"));
- static final Precomputed<TopLevelArtifactContext> TOP_LEVEL_CONTEXT =
- new Precomputed<>(SkyKey.create(SkyFunctions.PRECOMPUTED, "top_level_context"));
-
public static final Precomputed<Map<BuildInfoKey, BuildInfoFactory>> BUILD_INFO_FACTORIES =
new Precomputed<>(SkyKey.create(SkyFunctions.PRECOMPUTED, "build_info_factories"));
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
index 4168ef1..f9426d1 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
@@ -633,13 +633,6 @@
PrecomputedValue.DEFAULTS_PACKAGE_CONTENTS.set(injectable(), defaultsPackageContents);
}
- /**
- * Injects the top-level artifact options.
- */
- public void injectTopLevelContext(TopLevelArtifactContext options) {
- PrecomputedValue.TOP_LEVEL_CONTEXT.set(injectable(), options);
- }
-
public void injectWorkspaceStatusData() {
PrecomputedValue.WORKSPACE_STATUS_KEY.set(injectable(),
workspaceStatusActionFactory.createWorkspaceStatusAction(
@@ -1083,7 +1076,8 @@
boolean finalizeActionsToOutputService,
int numJobs,
ActionCacheChecker actionCacheChecker,
- @Nullable EvaluationProgressReceiver executionProgressReceiver)
+ @Nullable EvaluationProgressReceiver executionProgressReceiver,
+ TopLevelArtifactContext topLevelArtifactContext)
throws InterruptedException {
checkActive();
Preconditions.checkState(actionLogBufferPathGenerator != null);
@@ -1096,9 +1090,11 @@
try {
progressReceiver.executionProgressReceiver = executionProgressReceiver;
Iterable<SkyKey> artifactKeys = ArtifactValue.mandatoryKeys(artifactsToBuild);
- Iterable<SkyKey> targetKeys = TargetCompletionValue.keys(targetsToBuild);
- Iterable<SkyKey> aspectKeys = AspectCompletionValue.keys(aspects);
- Iterable<SkyKey> testKeys = TestCompletionValue.keys(targetsToTest, exclusiveTesting);
+ Iterable<SkyKey> targetKeys =
+ TargetCompletionValue.keys(targetsToBuild, topLevelArtifactContext);
+ Iterable<SkyKey> aspectKeys = AspectCompletionValue.keys(aspects, topLevelArtifactContext);
+ Iterable<SkyKey> testKeys =
+ TestCompletionValue.keys(targetsToTest, topLevelArtifactContext, exclusiveTesting);
return buildDriver.evaluate(
Iterables.concat(artifactKeys, targetKeys, aspectKeys, testKeys),
keepGoing,
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TargetCompletionValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/TargetCompletionValue.java
index fcdcdd1..ef55b9f 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TargetCompletionValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TargetCompletionValue.java
@@ -13,10 +13,12 @@
// limitations under the License.
package com.google.devtools.build.lib.skyframe;
+import com.google.auto.value.AutoValue;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.LabelAndConfiguration;
+import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
@@ -36,18 +38,38 @@
return ct;
}
- public static SkyKey key(LabelAndConfiguration labelAndConfiguration) {
- return SkyKey.create(SkyFunctions.TARGET_COMPLETION, labelAndConfiguration);
+ public static SkyKey key(
+ LabelAndConfiguration labelAndConfiguration,
+ TopLevelArtifactContext topLevelArtifactContext) {
+ return SkyKey.create(
+ SkyFunctions.TARGET_COMPLETION,
+ TargetCompletionKey.create(labelAndConfiguration, topLevelArtifactContext));
}
- public static Iterable<SkyKey> keys(Collection<ConfiguredTarget> targets) {
+ public static Iterable<SkyKey> keys(Collection<ConfiguredTarget> targets,
+ final TopLevelArtifactContext ctx) {
return Iterables.transform(
targets,
new Function<ConfiguredTarget, SkyKey>() {
@Override
public SkyKey apply(ConfiguredTarget ct) {
- return SkyKey.create(SkyFunctions.TARGET_COMPLETION, LabelAndConfiguration.of(ct));
+ return SkyKey.create(
+ SkyFunctions.TARGET_COMPLETION,
+ TargetCompletionKey.create(LabelAndConfiguration.of(ct), ctx));
}
});
}
+
+ @AutoValue
+ abstract static class TargetCompletionKey {
+ public static TargetCompletionKey create(
+ LabelAndConfiguration labelAndConfiguration,
+ TopLevelArtifactContext topLevelArtifactContext) {
+ return new AutoValue_TargetCompletionValue_TargetCompletionKey(
+ labelAndConfiguration, topLevelArtifactContext);
+ }
+
+ public abstract LabelAndConfiguration labelAndConfiguration();
+ public abstract TopLevelArtifactContext topLevelArtifactContext();
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TestCompletionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/TestCompletionFunction.java
index 13a2d95..cdb22dd 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TestCompletionFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TestCompletionFunction.java
@@ -16,6 +16,7 @@
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.LabelAndConfiguration;
+import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.rules.test.TestProvider;
import com.google.devtools.build.skyframe.SkyFunction;
@@ -36,8 +37,9 @@
public SkyValue compute(SkyKey skyKey, Environment env) {
TestCompletionValue.TestCompletionKey key =
(TestCompletionValue.TestCompletionKey) skyKey.argument();
- LabelAndConfiguration lac = key.getLabelAndConfiguration();
- if (env.getValue(TargetCompletionValue.key(lac)) == null) {
+ LabelAndConfiguration lac = key.labelAndConfiguration();
+ TopLevelArtifactContext ctx = key.topLevelArtifactContext();
+ if (env.getValue(TargetCompletionValue.key(lac, ctx)) == null) {
return null;
}
@@ -48,7 +50,7 @@
}
ConfiguredTarget ct = ctValue.getConfiguredTarget();
- if (key.isExclusiveTesting()) {
+ if (key.exclusiveTesting()) {
// Request test artifacts iteratively if testing exclusively.
for (Artifact testArtifact : TestProvider.getTestStatusArtifacts(ct)) {
if (env.getValue(ArtifactValue.key(testArtifact, /*isMandatory=*/true)) == null) {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TestCompletionValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/TestCompletionValue.java
index b5321a8..01f5698 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TestCompletionValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TestCompletionValue.java
@@ -13,10 +13,12 @@
// limitations under the License.
package com.google.devtools.build.lib.skyframe;
+import com.google.auto.value.AutoValue;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.LabelAndConfiguration;
+import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
@@ -31,12 +33,18 @@
private TestCompletionValue() { }
- public static SkyKey key(LabelAndConfiguration lac, boolean exclusive) {
- return SkyKey.create(SkyFunctions.TEST_COMPLETION, new TestCompletionKey(lac, exclusive));
+ public static SkyKey key(
+ LabelAndConfiguration lac,
+ final TopLevelArtifactContext topLevelArtifactContext,
+ final boolean exclusiveTesting) {
+ return SkyKey.create(
+ SkyFunctions.TEST_COMPLETION,
+ TestCompletionKey.create(lac, topLevelArtifactContext, exclusiveTesting));
}
public static Iterable<SkyKey> keys(Collection<ConfiguredTarget> targets,
- final boolean exclusive) {
+ final TopLevelArtifactContext topLevelArtifactContext,
+ final boolean exclusiveTesting) {
return Iterables.transform(
targets,
new Function<ConfiguredTarget, SkyKey>() {
@@ -44,26 +52,25 @@
public SkyKey apply(ConfiguredTarget ct) {
return SkyKey.create(
SkyFunctions.TEST_COMPLETION,
- new TestCompletionKey(LabelAndConfiguration.of(ct), exclusive));
+ TestCompletionKey.create(
+ LabelAndConfiguration.of(ct), topLevelArtifactContext, exclusiveTesting));
}
});
}
-
- static class TestCompletionKey {
- private final LabelAndConfiguration lac;
- private final boolean exclusiveTesting;
- TestCompletionKey(LabelAndConfiguration lac, boolean exclusive) {
- this.lac = lac;
- this.exclusiveTesting = exclusive;
+ @AutoValue
+ abstract static class TestCompletionKey {
+
+ public static TestCompletionKey create(
+ LabelAndConfiguration labelAndConfiguration,
+ TopLevelArtifactContext topLevelArtifactContext,
+ boolean exclusiveTesting) {
+ return new AutoValue_TestCompletionValue_TestCompletionKey(
+ labelAndConfiguration, topLevelArtifactContext, exclusiveTesting);
}
- public LabelAndConfiguration getLabelAndConfiguration() {
- return lac;
- }
-
- public boolean isExclusiveTesting() {
- return exclusiveTesting;
- }
+ public abstract LabelAndConfiguration labelAndConfiguration();
+ public abstract TopLevelArtifactContext topLevelArtifactContext();
+ public abstract boolean exclusiveTesting();
}
}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ActionDataTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ActionDataTest.java
index 763d1fa..342784c 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/ActionDataTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/ActionDataTest.java
@@ -93,13 +93,15 @@
Executor executor = new DummyExecutor(scratch.dir("/"));
amnesiacBuilder()
.buildArtifacts(
- reporter, outputs, null, null, null, null, executor, null, /*explain=*/ false, null);
+ reporter, outputs, null, null, null, null, executor, null, /*explain=*/ false, null,
+ null);
assertSame(executor, action.executor);
executor = new DummyExecutor(scratch.dir("/"));
amnesiacBuilder()
.buildArtifacts(
- reporter, outputs, null, null, null, null, executor, null, /*explain=*/ false, null);
+ reporter, outputs, null, null, null, null, executor, null, /*explain=*/ false, null,
+ null);
assertSame(executor, action.executor);
}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java
index 636dab3..17a273e 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java
@@ -392,6 +392,7 @@
executor,
null,
false,
+ null,
null);
// Sanity check that our invalidation receiver is working correctly. We'll rely on it again.
@@ -419,6 +420,7 @@
executor,
null,
false,
+ null,
null);
if (expectActionIs.dirtied()) {
@@ -789,6 +791,16 @@
});
builder.buildArtifacts(
- reporter, ImmutableSet.of(genFile2), null, null, null, null, executor, null, false, null);
+ reporter,
+ ImmutableSet.of(genFile2),
+ null,
+ null,
+ null,
+ null,
+ executor,
+ null,
+ false,
+ null,
+ null);
}
}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java
index 2c1b7e6..de3984d 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java
@@ -43,6 +43,7 @@
import com.google.devtools.build.lib.actions.util.TestAction;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
import com.google.devtools.build.lib.buildtool.SkyframeBuilder;
import com.google.devtools.build.lib.events.Reporter;
import com.google.devtools.build.lib.events.StoredEventHandler;
@@ -219,7 +220,8 @@
Executor executor,
Set<ConfiguredTarget> builtTargets,
boolean explain,
- Range<Long> lastExecutionTimeRange)
+ Range<Long> lastExecutionTimeRange,
+ TopLevelArtifactContext topLevelArtifactContext)
throws BuildFailedException, AbruptExitException, InterruptedException,
TestExecException {
skyframeActionExecutor.prepareForExecution(
@@ -356,6 +358,7 @@
new DummyExecutor(rootDirectory),
builtArtifacts, /*explain=*/
false,
+ null,
null);
} finally {
tsgm.waitForTimestampGranularity(reporter.getOutErr());