Refactor `getValues` in `skyframe` directory to only provide the necessary methods for Skyframe evaluation. It will help create less garbage.
PiperOrigin-RevId: 438056310
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
index 861b277..7c0f2cb 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
@@ -2513,6 +2513,7 @@
":package_value",
":test_expansion_value",
":tests_for_target_pattern_value",
+ "//src/main/java/com/google/devtools/build/lib/bugreport",
"//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/main/java/com/google/devtools/build/lib/packages",
"//src/main/java/com/google/devtools/build/skyframe",
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PathCasingLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PathCasingLookupFunction.java
index 46395bf..89424a9 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PathCasingLookupFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PathCasingLookupFunction.java
@@ -24,9 +24,8 @@
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyKey;
-import com.google.devtools.build.skyframe.SkyValue;
+import com.google.devtools.build.skyframe.SkyframeIterableResult;
import java.io.IOException;
-import java.util.Map;
/** SkyFunction for {@link PathCasingLookupValue}s. */
public final class PathCasingLookupFunction implements SkyFunction {
@@ -51,17 +50,25 @@
SkyKey parentCasingKey = PathCasingLookupValue.key(parent);
SkyKey parentFileKey = FileValue.key(parent);
SkyKey childFileKey = FileValue.key(arg.getPath());
- Map<SkyKey, SkyValue> values =
- env.getValues(ImmutableList.of(parentCasingKey, parentFileKey, childFileKey));
+ SkyframeIterableResult values =
+ env.getOrderedValuesAndExceptions(
+ ImmutableList.of(parentCasingKey, parentFileKey, childFileKey));
if (env.valuesMissing()) {
return null;
}
- if (!((PathCasingLookupValue) values.get(parentCasingKey)).isCorrect()) {
+ PathCasingLookupValue pathCasingLookupValue = (PathCasingLookupValue) values.next();
+ if (pathCasingLookupValue == null) {
+ return null;
+ }
+ if (!pathCasingLookupValue.isCorrect()) {
// Parent's casing is bad, so this path's casing is also bad.
return PathCasingLookupValue.BAD;
}
- FileValue parentFile = (FileValue) values.get(parentFileKey);
+ FileValue parentFile = (FileValue) values.next();
+ if (parentFile == null) {
+ return null;
+ }
if (!parentFile.exists()) {
// Parent's casing is good, because it's missing.
// That means this path is also missing, so by definition its casing is good.
@@ -76,7 +83,10 @@
+ ": its parent exists but is not a directory"));
}
- FileValue childFile = (FileValue) values.get(childFileKey);
+ FileValue childFile = (FileValue) values.next();
+ if (childFile == null) {
+ return null;
+ }
if (!childFile.exists()) {
// Parent's casing is good, but this file is missing.
// That means this path is missing, so by definition its casing is good.
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareAnalysisPhaseFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareAnalysisPhaseFunction.java
index d0d0a07..f1ae109 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareAnalysisPhaseFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareAnalysisPhaseFunction.java
@@ -43,7 +43,8 @@
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyKey;
-import com.google.devtools.build.skyframe.SkyValue;
+import com.google.devtools.build.skyframe.SkyframeIterableResult;
+import com.google.devtools.build.skyframe.SkyframeLookupResult;
import com.google.devtools.common.options.OptionsParsingException;
import java.util.ArrayList;
import java.util.Collection;
@@ -110,7 +111,7 @@
ImmutableList<BuildConfigurationKey> targetConfigurationKeys =
targetConfigurationKeysBuilder.build();
- Map<SkyKey, SkyValue> configs = env.getValues(targetConfigurationKeys);
+ SkyframeLookupResult configs = env.getValuesAndExceptions(targetConfigurationKeys);
// We only report invalid options for the target configurations, and abort if there's an error.
ErrorSensingEventHandler<Void> nosyEventHandler =
@@ -277,7 +278,7 @@
}
}
- Map<SkyKey, SkyValue> configsResult = env.getValues(configSkyKeys);
+ SkyframeIterableResult configsResult = env.getOrderedValuesAndExceptions(configSkyKeys);
if (env.valuesMissing()) {
return null;
}
@@ -292,20 +293,14 @@
if (buildSettingPackages == null) {
return null;
}
- Collection<BuildOptions> toOptions =
- ConfigurationResolver.applyTransitionWithSkyframe(
- fromOptions, transition, env, env.getListener())
- .values();
- for (BuildOptions toOption : toOptions) {
- SkyKey configKey =
- BuildConfigurationKey.withPlatformMapping(platformMappingValue, toOption);
- BuildConfigurationValue configValue =
- (BuildConfigurationValue) configsResult.get(configKey);
+ while (configsResult.hasNext()) {
+ BuildConfigurationValue configValue = (BuildConfigurationValue) configsResult.next();
// configValue will be null here if there was an exception thrown during configuration
// creation. This will be reported elsewhere.
- if (configValue != null) {
- builder.put(key, configValue);
+ if (configValue == null) {
+ return null;
}
+ builder.put(key, configValue);
}
}
return builder;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java
index 10527f6..55c693f 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java
@@ -339,8 +339,8 @@
for (Root root : roots) {
RootedPath rootedPath = RootedPath.toRootedPath(root, directoryPathFragment);
- env.getValues(getDeps(repository, repositoryIgnoredSubdirectories, policy, rootedPath));
- if (env.valuesMissing()) {
+ if (GraphTraversingHelper.declareDependenciesAndCheckIfValuesMissing(
+ env, getDeps(repository, repositoryIgnoredSubdirectories, policy, rootedPath))) {
throw new MissingDepException();
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java
index b723829..df82357 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java
@@ -18,9 +18,7 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.base.Verify;
-import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Maps;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
import com.google.devtools.build.lib.actions.FileArtifactValue;
@@ -60,10 +58,10 @@
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
+import com.google.devtools.build.skyframe.SkyframeIterableResult;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -230,7 +228,7 @@
}
// We are free to traverse this directory.
- Collection<RecursiveFilesystemTraversalValue> subdirTraversals =
+ ImmutableList<RecursiveFilesystemTraversalValue> subdirTraversals =
traverseChildren(env, traversal);
if (subdirTraversals == null) {
return null;
@@ -595,7 +593,7 @@
private static RecursiveFilesystemTraversalValue resultForDirectory(
TraversalRequest traversal,
FileInfo rootInfo,
- Collection<RecursiveFilesystemTraversalValue> subdirTraversals) {
+ ImmutableList<RecursiveFilesystemTraversalValue> subdirTraversals) {
// Collect transitive closure of files in subdirectories.
NestedSetBuilder<ResolvedFile> paths = NestedSetBuilder.stableOrder();
for (RecursiveFilesystemTraversalValue child : subdirTraversals) {
@@ -635,7 +633,7 @@
/** Requests Skyframe to compute the dependent values and returns them. */
@Nullable
- private Collection<RecursiveFilesystemTraversalValue> traverseChildren(
+ private ImmutableList<RecursiveFilesystemTraversalValue> traverseChildren(
Environment env, TraversalRequest traversal)
throws InterruptedException, RecursiveFilesystemTraversalFunctionException, IOException {
// Use the traversal's path, even if it's a symlink. The contents of the directory, as listed
@@ -677,21 +675,33 @@
if (keys == null) {
return null;
}
- Map<SkyKey, SkyValue> values = Maps.newHashMapWithExpectedSize(keys.size());
+ ImmutableList.Builder<RecursiveFilesystemTraversalValue> values =
+ ImmutableList.builderWithExpectedSize(keys.size());
if (traversal.isRootGenerated) {
// Don't create Skyframe nodes for a recursive traversal over the output tree.
// Instead, inline the recursion in the top-level request.
for (TraversalRequest traversalRequest : keys) {
- values.put(traversalRequest, compute(traversalRequest, env));
+ SkyValue computeValue = compute(traversalRequest, env);
+ if (computeValue == null) {
+ continue;
+ }
+ values.add((RecursiveFilesystemTraversalValue) computeValue);
}
} else {
- values = env.getValues(keys);
+ SkyframeIterableResult result = env.getOrderedValuesAndExceptions(keys);
+ while (result.hasNext()) {
+ var iterateValue = (RecursiveFilesystemTraversalValue) result.next();
+ if (iterateValue == null) {
+ break;
+ }
+ values.add(iterateValue);
+ }
}
if (env.valuesMissing()) {
return null;
}
- return Collections2.transform(values.values(), RecursiveFilesystemTraversalValue.class::cast);
+ return values.build();
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternPhaseFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternPhaseFunction.java
index 92de221..e17ae51 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternPhaseFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternPhaseFunction.java
@@ -55,7 +55,6 @@
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunction.Environment;
import com.google.devtools.build.skyframe.SkyKey;
-import com.google.devtools.build.skyframe.SkyValue;
import com.google.devtools.build.skyframe.SkyframeIterableResult;
import com.google.devtools.build.skyframe.SkyframeLookupResult;
import java.util.ArrayList;
@@ -130,7 +129,7 @@
}
}
}
- Map<SkyKey, SkyValue> expandedTests = env.getValues(testExpansionKeys.values());
+ SkyframeLookupResult expandedTests = env.getValuesAndExceptions(testExpansionKeys.values());
if (env.valuesMissing()) {
return null;
}
@@ -200,13 +199,16 @@
ResolvedTargets.Builder<Label> expandedLabelsBuilder = ResolvedTargets.builder();
ImmutableMap.Builder<Label, ImmutableSet<Label>> testSuiteExpansions =
- ImmutableMap.builderWithExpectedSize(expandedTests.size());
+ ImmutableMap.builderWithExpectedSize(testExpansionKeys.size());
for (Target target : targets.getTargets()) {
Label label = target.getLabel();
if (TargetUtils.isTestSuiteRule(target) && options.isExpandTestSuites()) {
SkyKey expansionKey = Preconditions.checkNotNull(testExpansionKeys.get(label));
- ResolvedTargets<Label> testExpansion =
- ((TestsForTargetPatternValue) expandedTests.get(expansionKey)).getLabels();
+ var value = (TestsForTargetPatternValue) expandedTests.get(expansionKey);
+ if (value == null) {
+ return null;
+ }
+ ResolvedTargets<Label> testExpansion = value.getLabels();
expandedLabelsBuilder.merge(testExpansion);
testSuiteExpansions.put(label, testExpansion.getTargets());
} else {
@@ -443,7 +445,7 @@
}
expandedSuiteKeys.add(TestsForTargetPatternValue.key(value.getTargets().getTargets()));
}
- Map<SkyKey, SkyValue> expandedSuites = env.getValues(expandedSuiteKeys);
+ SkyframeIterableResult expandedSuites = env.getOrderedValuesAndExceptions(expandedSuiteKeys);
if (env.valuesMissing()) {
return null;
}
@@ -466,8 +468,13 @@
}
TestsForTargetPatternValue expandedSuitesValue =
- (TestsForTargetPatternValue)
- expandedSuites.get(TestsForTargetPatternValue.key(value.getTargets().getTargets()));
+ (TestsForTargetPatternValue) expandedSuites.next();
+ if (expandedSuitesValue == null) {
+ BugReport.sendBugReport(
+ new IllegalStateException(
+ "expandedSuitesValue " + pattern + " was missing, this should never happen"));
+ return null;
+ }
if (pattern.isNegative()) {
ResolvedTargets<Target> negativeTargets =
TestsForTargetPatternFunction.labelsToTargets(
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 b98e2e4..f2357ef 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
@@ -20,6 +20,7 @@
import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
import com.google.devtools.build.lib.analysis.test.TestProvider;
import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.skyframe.GraphTraversingHelper;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
@@ -55,11 +56,11 @@
}
}
} else {
- env.getValues(
+ if (GraphTraversingHelper.declareDependenciesAndCheckIfValuesMissingMaybeWithExceptions(
+ env,
Iterables.transform(
TestProvider.getTestStatusArtifacts(ct),
- Artifact.DerivedArtifact::getGeneratingActionKey));
- if (env.valuesMissing()) {
+ Artifact.DerivedArtifact::getGeneratingActionKey))) {
return null;
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TestsForTargetPatternFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/TestsForTargetPatternFunction.java
index ec13a52..33ee1ba 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TestsForTargetPatternFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TestsForTargetPatternFunction.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.skyframe;
import com.google.common.collect.ImmutableSet;
+import com.google.devtools.build.lib.bugreport.BugReport;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.cmdline.ResolvedTargets;
@@ -25,6 +26,7 @@
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
+import com.google.devtools.build.skyframe.SkyframeIterableResult;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
@@ -48,7 +50,7 @@
testsInSuitesKeys.add(TestExpansionValue.key(target, true));
}
}
- Map<SkyKey, SkyValue> testsInSuites = env.getValues(testsInSuitesKeys);
+ SkyframeIterableResult testsInSuites = env.getOrderedValuesAndExceptions(testsInSuitesKeys);
if (env.valuesMissing()) {
return null;
}
@@ -59,19 +61,16 @@
if (TargetUtils.isTestRule(target)) {
result.add(target.getLabel());
} else if (TargetUtils.isTestSuiteRule(target)) {
- TestExpansionValue value =
- (TestExpansionValue) testsInSuites.get(TestExpansionValue.key(target, true));
- if (value != null) {
- result.addAll(value.getLabels().getTargets());
- hasError |= value.getLabels().hasError();
+ TestExpansionValue value = (TestExpansionValue) testsInSuites.next();
+ if (value == null) {
+ return null;
}
+ result.addAll(value.getLabels().getTargets());
+ hasError |= value.getLabels().hasError();
} else {
result.add(target.getLabel());
}
}
- if (env.valuesMissing()) {
- return null;
- }
// We use ResolvedTargets in order to associate an error flag; the result should never contain
// any filtered targets.
return new TestsForTargetPatternValue(new ResolvedTargets<>(result, hasError));
@@ -83,8 +82,8 @@
for (Label label : labels) {
pkgIdentifiers.add(label.getPackageIdentifier());
}
- // Don't bother to check for exceptions - the incoming list should only contain valid targets.
- Map<SkyKey, SkyValue> packages = env.getValues(PackageValue.keys(pkgIdentifiers));
+ List<SkyKey> packagesKeys = PackageValue.keys(pkgIdentifiers);
+ SkyframeIterableResult packages = env.getOrderedValuesAndExceptions(packagesKeys);
if (env.valuesMissing()) {
return null;
}
@@ -92,10 +91,16 @@
ResolvedTargets.Builder<Target> builder = ResolvedTargets.builder();
builder.mergeError(hasError);
Map<PackageIdentifier, Package> packageMap = new HashMap<>();
- for (Map.Entry<SkyKey, SkyValue> entry : packages.entrySet()) {
- packageMap.put(
- (PackageIdentifier) entry.getKey().argument(),
- ((PackageValue) entry.getValue()).getPackage());
+ for (SkyKey packagesKey : packagesKeys) {
+ // Don't bother to check for exceptions - the incoming list should only contain valid targets.
+ PackageValue packagesValue = (PackageValue) packages.next();
+ if (packagesValue == null) {
+ BugReport.sendBugReport(
+ new IllegalStateException(
+ "PackageValue " + packagesKey + " was missing, this should never happen"));
+ return null;
+ }
+ packageMap.put((PackageIdentifier) packagesKey.argument(), packagesValue.getPackage());
}
for (Label label : labels) {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TopLevelActionLookupConflictFindingFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/TopLevelActionLookupConflictFindingFunction.java
index e567650..a4066fc 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TopLevelActionLookupConflictFindingFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TopLevelActionLookupConflictFindingFunction.java
@@ -13,6 +13,8 @@
// limitations under the License.
package com.google.devtools.build.lib.skyframe;
+import static com.google.common.collect.ImmutableList.toImmutableList;
+
import com.google.auto.value.AutoValue;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.ActionLookupKey;
@@ -22,12 +24,12 @@
import com.google.devtools.build.lib.analysis.TopLevelArtifactHelper;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.util.Pair;
+import com.google.devtools.build.skyframe.GraphTraversingHelper;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
-import java.util.stream.Collectors;
import javax.annotation.Nullable;
/**
@@ -46,12 +48,13 @@
if (env.valuesMissing()) {
return null;
}
-
- env.getValues(
- ActionLookupConflictFindingFunction.convertArtifacts(
- valueAndArtifactsToBuild.second.getAllArtifacts())
- .collect(Collectors.toList()));
- return env.valuesMissing() ? null : ActionLookupConflictFindingValue.INSTANCE;
+ return GraphTraversingHelper.declareDependenciesAndCheckIfValuesMissingMaybeWithExceptions(
+ env,
+ ActionLookupConflictFindingFunction.convertArtifacts(
+ valueAndArtifactsToBuild.second.getAllArtifacts())
+ .collect(toImmutableList()))
+ ? null
+ : ActionLookupConflictFindingValue.INSTANCE;
}
@Nullable
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ToplevelStarlarkAspectFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ToplevelStarlarkAspectFunction.java
index 12a608f..1b356d4 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ToplevelStarlarkAspectFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ToplevelStarlarkAspectFunction.java
@@ -25,6 +25,7 @@
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
+import com.google.devtools.build.skyframe.SkyframeIterableResult;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -63,12 +64,20 @@
topLevelAspectsDetails.getAspectsDetails(),
topLevelAspectsKey.getBaseConfiguredTargetKey());
- Map<SkyKey, SkyValue> result = env.getValues(aspectsKeys);
+ SkyframeIterableResult result = env.getOrderedValuesAndExceptions(aspectsKeys);
if (env.valuesMissing()) {
return null; // some aspects keys are not evaluated
}
-
- return new TopLevelAspectsValue(result.values());
+ ImmutableList.Builder<SkyValue> values =
+ ImmutableList.builderWithExpectedSize(aspectsKeys.size());
+ while (result.hasNext()) {
+ SkyValue value = result.next();
+ if (value == null) {
+ return null;
+ }
+ values.add(value);
+ }
+ return new TopLevelAspectsValue(values.build());
}
private static Collection<AspectKey> getTopLevelAspectsKeys(
diff --git a/src/main/java/com/google/devtools/build/skyframe/GraphTraversingHelper.java b/src/main/java/com/google/devtools/build/skyframe/GraphTraversingHelper.java
index 6e4d9cd..604140f 100644
--- a/src/main/java/com/google/devtools/build/skyframe/GraphTraversingHelper.java
+++ b/src/main/java/com/google/devtools/build/skyframe/GraphTraversingHelper.java
@@ -102,5 +102,29 @@
return false;
}
+ /**
+ * Returns false iff for each key in {@code skyKeys}, the corresponding node is done with values
+ * in the Skyframe graph, and every node evaluated successfully without an exception.
+ *
+ * <p>Prefer {@link #declareDependenciesAndCheckIfValuesMissing} when possible. This method is for
+ * {@link SkyFunction} callers that don't handle child exceptions themselves, and just want to
+ * propagate child exceptions upwards via Skyframe.
+ */
+ public static <E extends Exception>
+ boolean declareDependenciesAndCheckIfValuesMissingMaybeWithExceptions(
+ SkyFunction.Environment env, Iterable<? extends SkyKey> skyKeys)
+ throws InterruptedException {
+ SkyframeIterableResult result = env.getOrderedValuesAndExceptions(skyKeys);
+ if (env.valuesMissing()) {
+ return true;
+ }
+ while (result.hasNext()) {
+ if (result.next() == null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private GraphTraversingHelper() {}
}