Augment the QueryableGraph#get[BatchWithFieldHints] method to take in parameters conveying the requesting node (if any), the requested node(s), as well as a reason for the skyframe graph lookup. Alternate graph implementations may be interested in this information.
--
MOS_MIGRATED_REVID=128496089
diff --git a/src/main/java/com/google/devtools/build/skyframe/DelegatingWalkableGraph.java b/src/main/java/com/google/devtools/build/skyframe/DelegatingWalkableGraph.java
index 7a584ec..b6c5825 100644
--- a/src/main/java/com/google/devtools/build/skyframe/DelegatingWalkableGraph.java
+++ b/src/main/java/com/google/devtools/build/skyframe/DelegatingWalkableGraph.java
@@ -18,7 +18,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.google.devtools.build.lib.util.Preconditions;
-
+import com.google.devtools.build.skyframe.QueryableGraph.Reason;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
@@ -39,7 +39,8 @@
private NodeEntry getEntry(SkyKey key) {
NodeEntry entry =
Preconditions.checkNotNull(
- graph.getBatchWithFieldHints(ImmutableList.of(key), NodeEntryField.VALUE_ONLY).get(key),
+ graph.getBatchWithFieldHints(
+ null, Reason.OTHER, ImmutableList.of(key), NodeEntryField.VALUE_ONLY).get(key),
key);
Preconditions.checkState(entry.isDone(), "%s %s", key, entry);
return entry;
@@ -48,7 +49,8 @@
@Override
public boolean exists(SkyKey key) {
NodeEntry entry =
- graph.getBatchWithFieldHints(ImmutableList.of(key), NodeEntryField.NO_FIELDS).get(key);
+ graph.getBatchWithFieldHints(
+ null, Reason.OTHER, ImmutableList.of(key), NodeEntryField.NO_FIELDS).get(key);
return entry != null && entry.isDone();
}
@@ -71,7 +73,8 @@
public Map<SkyKey, SkyValue> getSuccessfulValues(Iterable<SkyKey> keys) {
return Maps.filterValues(
Maps.transformValues(
- graph.getBatchWithFieldHints(keys, NodeEntryField.VALUE_ONLY), GET_SKY_VALUE_FUNCTION),
+ graph.getBatchWithFieldHints(null, Reason.OTHER, keys, NodeEntryField.VALUE_ONLY),
+ GET_SKY_VALUE_FUNCTION),
Predicates.notNull());
}
@@ -79,7 +82,7 @@
public Map<SkyKey, Exception> getMissingAndExceptions(Iterable<SkyKey> keys) {
Map<SkyKey, Exception> result = new HashMap<>();
Map<SkyKey, NodeEntry> graphResult =
- graph.getBatchWithFieldHints(keys, NodeEntryField.VALUE_ONLY);
+ graph.getBatchWithFieldHints(null, Reason.OTHER, keys, NodeEntryField.VALUE_ONLY);
for (SkyKey key : keys) {
NodeEntry nodeEntry = graphResult.get(key);
if (nodeEntry == null || !nodeEntry.isDone()) {
@@ -103,8 +106,8 @@
@Override
public Map<SkyKey, Iterable<SkyKey>> getDirectDeps(Iterable<SkyKey> keys) {
- Map<SkyKey, NodeEntry> entries =
- graph.getBatchWithFieldHints(keys, EnumSet.of(NodeEntryField.DIRECT_DEPS));
+ Map<SkyKey, NodeEntry> entries = graph.getBatchWithFieldHints(
+ null, Reason.OTHER, keys, EnumSet.of(NodeEntryField.DIRECT_DEPS));
Map<SkyKey, Iterable<SkyKey>> result = new HashMap<>(entries.size());
for (Entry<SkyKey, NodeEntry> entry : entries.entrySet()) {
Preconditions.checkState(entry.getValue().isDone(), entry);
@@ -115,8 +118,8 @@
@Override
public Map<SkyKey, Iterable<SkyKey>> getReverseDeps(Iterable<SkyKey> keys) {
- Map<SkyKey, NodeEntry> entries =
- graph.getBatchWithFieldHints(keys, EnumSet.of(NodeEntryField.REVERSE_DEPS));
+ Map<SkyKey, NodeEntry> entries = graph.getBatchWithFieldHints(
+ null, Reason.OTHER, keys, EnumSet.of(NodeEntryField.REVERSE_DEPS));
Map<SkyKey, Iterable<SkyKey>> result = new HashMap<>(entries.size());
for (Entry<SkyKey, NodeEntry> entry : entries.entrySet()) {
Preconditions.checkState(entry.getValue().isDone(), entry);
diff --git a/src/main/java/com/google/devtools/build/skyframe/EvaluableGraph.java b/src/main/java/com/google/devtools/build/skyframe/EvaluableGraph.java
index a9c067d..0db7dad 100644
--- a/src/main/java/com/google/devtools/build/skyframe/EvaluableGraph.java
+++ b/src/main/java/com/google/devtools/build/skyframe/EvaluableGraph.java
@@ -14,8 +14,8 @@
package com.google.devtools.build.skyframe;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
-
import java.util.Map;
+import javax.annotation.Nullable;
/**
* Interface between a single version of the graph and the evaluator. Supports mutation of that
@@ -27,6 +27,11 @@
* Like {@link QueryableGraph#getBatchWithFieldHints}, except it creates a new node for each key
* not already present in the graph. Thus, the returned map will have an entry for each key in
* {@code keys}.
+ *
+ * @param requestor if non-{@code null}, the node on behalf of which the given {@code keys} are
+ * being requested.
+ * @param reason the reason the nodes are being requested.
*/
- Map<SkyKey, NodeEntry> createIfAbsentBatch(Iterable<SkyKey> keys);
+ Map<SkyKey, NodeEntry> createIfAbsentBatch(
+ @Nullable SkyKey requestor, Reason reason, Iterable<SkyKey> keys);
}
diff --git a/src/main/java/com/google/devtools/build/skyframe/InMemoryGraph.java b/src/main/java/com/google/devtools/build/skyframe/InMemoryGraph.java
index 6f25093..9eee52e 100644
--- a/src/main/java/com/google/devtools/build/skyframe/InMemoryGraph.java
+++ b/src/main/java/com/google/devtools/build/skyframe/InMemoryGraph.java
@@ -18,7 +18,7 @@
/** {@link ProcessableGraph} that exposes the contents of the entire graph. */
interface InMemoryGraph extends ProcessableGraph, InvalidatableGraph {
@Override
- Map<SkyKey, NodeEntry> getBatch(Iterable<SkyKey> keys);
+ Map<SkyKey, NodeEntry> getBatchForInvalidation(Iterable<SkyKey> keys);
/**
* Returns a read-only live view of the nodes in the graph. All node are included. Dirty values
diff --git a/src/main/java/com/google/devtools/build/skyframe/InMemoryGraphImpl.java b/src/main/java/com/google/devtools/build/skyframe/InMemoryGraphImpl.java
index ef6e24b..e068c3f 100644
--- a/src/main/java/com/google/devtools/build/skyframe/InMemoryGraphImpl.java
+++ b/src/main/java/com/google/devtools/build/skyframe/InMemoryGraphImpl.java
@@ -19,11 +19,11 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;
-
import java.util.Collections;
import java.util.EnumSet;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
+import javax.annotation.Nullable;
/**
* An in-memory graph implementation. All operations are thread-safe with ConcurrentMap semantics.
@@ -51,15 +51,15 @@
}
@Override
- public NodeEntry get(SkyKey skyKey) {
+ public NodeEntry get(@Nullable SkyKey requestor, Reason reason, SkyKey skyKey) {
return nodeMap.get(skyKey);
}
@Override
- public Map<SkyKey, NodeEntry> getBatch(Iterable<SkyKey> keys) {
+ public Map<SkyKey, NodeEntry> getBatchForInvalidation(Iterable<SkyKey> keys) {
ImmutableMap.Builder<SkyKey, NodeEntry> builder = ImmutableMap.builder();
for (SkyKey key : keys) {
- NodeEntry entry = get(key);
+ NodeEntry entry = get(null, Reason.OTHER, key);
if (entry != null) {
builder.put(key, entry);
}
@@ -69,8 +69,8 @@
@Override
public Map<SkyKey, NodeEntry> getBatchWithFieldHints(
- Iterable<SkyKey> keys, EnumSet<NodeEntryField> fields) {
- return getBatch(keys);
+ SkyKey requestor, Reason reason, Iterable<SkyKey> keys, EnumSet<NodeEntryField> fields) {
+ return getBatchForInvalidation(keys);
}
protected NodeEntry createIfAbsent(SkyKey key) {
@@ -80,7 +80,8 @@
}
@Override
- public Map<SkyKey, NodeEntry> createIfAbsentBatch(Iterable<SkyKey> keys) {
+ public Map<SkyKey, NodeEntry> createIfAbsentBatch(
+ @Nullable SkyKey requestor, Reason reason, Iterable<SkyKey> keys) {
ImmutableMap.Builder<SkyKey, NodeEntry> builder = ImmutableMap.builder();
for (SkyKey key : keys) {
builder.put(key, createIfAbsent(key));
diff --git a/src/main/java/com/google/devtools/build/skyframe/InMemoryMemoizingEvaluator.java b/src/main/java/com/google/devtools/build/skyframe/InMemoryMemoizingEvaluator.java
index 5d853b7..38604ed 100644
--- a/src/main/java/com/google/devtools/build/skyframe/InMemoryMemoizingEvaluator.java
+++ b/src/main/java/com/google/devtools/build/skyframe/InMemoryMemoizingEvaluator.java
@@ -29,7 +29,7 @@
import com.google.devtools.build.skyframe.InvalidatingNodeVisitor.InvalidationState;
import com.google.devtools.build.skyframe.ParallelEvaluator.EventFilter;
import com.google.devtools.build.skyframe.ParallelEvaluator.Receiver;
-
+import com.google.devtools.build.skyframe.QueryableGraph.Reason;
import java.io.PrintStream;
import java.util.Collection;
import java.util.HashMap;
@@ -129,7 +129,7 @@
Sets.filter(dirtyKeyTracker.getDirtyKeys(), new Predicate<SkyKey>() {
@Override
public boolean apply(SkyKey skyKey) {
- NodeEntry entry = graph.get(skyKey);
+ NodeEntry entry = graph.get(null, Reason.OTHER, skyKey);
Preconditions.checkNotNull(entry, skyKey);
Preconditions.checkState(entry.isDirty(), skyKey);
return entry.getVersion().atMost(threshold);
@@ -207,7 +207,7 @@
Entry<SkyKey, SkyValue> entry = it.next();
SkyKey key = entry.getKey();
SkyValue newValue = entry.getValue();
- NodeEntry prevEntry = graph.get(key);
+ NodeEntry prevEntry = graph.get(null, Reason.OTHER, key);
if (prevEntry != null && prevEntry.isDone()) {
Iterable<SkyKey> directDeps = prevEntry.getDirectDeps();
Preconditions.checkState(Iterables.isEmpty(directDeps),
@@ -280,7 +280,7 @@
@Nullable
@Override
public NodeEntry getExistingEntryForTesting(SkyKey key) {
- return graph.get(key);
+ return graph.get(null, Reason.OTHER, key);
}
@Override
diff --git a/src/main/java/com/google/devtools/build/skyframe/InvalidatableGraph.java b/src/main/java/com/google/devtools/build/skyframe/InvalidatableGraph.java
index 2437407..8abdae6 100644
--- a/src/main/java/com/google/devtools/build/skyframe/InvalidatableGraph.java
+++ b/src/main/java/com/google/devtools/build/skyframe/InvalidatableGraph.java
@@ -30,5 +30,5 @@
* {@code keys}, {@code m.get(k).equals(e)} iff {@code get(k) == e} and {@code e != null}, and
* {@code !m.containsKey(k)} iff {@code get(k) == null}.
*/
- Map<SkyKey, ? extends ThinNodeEntry> getBatch(Iterable<SkyKey> keys);
+ Map<SkyKey, ? extends ThinNodeEntry> getBatchForInvalidation(Iterable<SkyKey> keys);
}
diff --git a/src/main/java/com/google/devtools/build/skyframe/InvalidatingNodeVisitor.java b/src/main/java/com/google/devtools/build/skyframe/InvalidatingNodeVisitor.java
index 1fe90d1..c8dd68a 100644
--- a/src/main/java/com/google/devtools/build/skyframe/InvalidatingNodeVisitor.java
+++ b/src/main/java/com/google/devtools/build/skyframe/InvalidatingNodeVisitor.java
@@ -269,7 +269,7 @@
for (SkyKey key : unvisitedKeys) {
pendingVisitations.add(Pair.of(key, InvalidationType.DELETED));
}
- final Map<SkyKey, NodeEntry> entries = graph.getBatch(unvisitedKeys);
+ final Map<SkyKey, NodeEntry> entries = graph.getBatchForInvalidation(unvisitedKeys);
for (final SkyKey key : unvisitedKeys) {
executor.execute(
new Runnable() {
@@ -305,7 +305,7 @@
entry.isDone()
? entry.getDirectDeps()
: entry.getAllDirectDepsForIncompleteNode();
- Map<SkyKey, NodeEntry> depMap = graph.getBatch(directDeps);
+ Map<SkyKey, NodeEntry> depMap = graph.getBatchForInvalidation(directDeps);
for (Map.Entry<SkyKey, NodeEntry> directDepEntry : depMap.entrySet()) {
NodeEntry dep = directDepEntry.getValue();
if (dep != null) {
@@ -432,7 +432,7 @@
pendingVisitations.add(Pair.of(key, invalidationType));
}
}
- final Map<SkyKey, ? extends ThinNodeEntry> entries = graph.getBatch(keysToGet);
+ final Map<SkyKey, ? extends ThinNodeEntry> entries = graph.getBatchForInvalidation(keysToGet);
if (enqueueingKeyForExistenceCheck != null && entries.size() != keysToGet.size()) {
Set<SkyKey> missingKeys = Sets.difference(ImmutableSet.copyOf(keysToGet), entries.keySet());
throw new IllegalStateException(
diff --git a/src/main/java/com/google/devtools/build/skyframe/ParallelEvaluator.java b/src/main/java/com/google/devtools/build/skyframe/ParallelEvaluator.java
index 8cd502d..61c93cb 100644
--- a/src/main/java/com/google/devtools/build/skyframe/ParallelEvaluator.java
+++ b/src/main/java/com/google/devtools/build/skyframe/ParallelEvaluator.java
@@ -49,6 +49,7 @@
import com.google.devtools.build.skyframe.MemoizingEvaluator.EmittedEventState;
import com.google.devtools.build.skyframe.NodeEntry.DependencyState;
import com.google.devtools.build.skyframe.NodeEntry.DirtyState;
+import com.google.devtools.build.skyframe.QueryableGraph.Reason;
import com.google.devtools.build.skyframe.SkyFunctionException.ReifiedSkyFunctionException;
import java.util.ArrayDeque;
@@ -222,8 +223,11 @@
this.errorHandler = errorHandler;
}
- private Map<SkyKey, NodeEntry> getBatchValues(Iterable<SkyKey> keys) {
- return graph.getBatchWithFieldHints(keys, NodeEntryField.VALUE_ONLY);
+ private Map<SkyKey, NodeEntry> getBatchValues(
+ SkyKey parent,
+ Reason reason,
+ Iterable<SkyKey> keys) {
+ return graph.getBatchWithFieldHints(parent, reason, keys, NodeEntryField.VALUE_ONLY);
}
/** Receives the events from the NestedSet and delegates to the reporter. */
@@ -312,8 +316,8 @@
ValueVisitor visitor) {
this.skyKey = skyKey;
this.oldDeps = oldDeps;
- this.directDeps = Collections.unmodifiableMap(
- batchPrefetch(directDeps, oldDeps, /*assertDone=*/bubbleErrorInfo == null, skyKey));
+ this.directDeps = Collections.unmodifiableMap(batchPrefetch(
+ skyKey, directDeps, oldDeps, /*assertDone=*/bubbleErrorInfo == null, skyKey));
this.bubbleErrorInfo = bubbleErrorInfo;
this.visitor = visitor;
Preconditions.checkState(
@@ -323,7 +327,7 @@
}
private Map<SkyKey, NodeEntry> batchPrefetch(
- GroupedList<SkyKey> depKeys, Set<SkyKey> oldDeps, boolean assertDone,
+ SkyKey requestor, GroupedList<SkyKey> depKeys, Set<SkyKey> oldDeps, boolean assertDone,
SkyKey keyForDebugging) {
Iterable<SkyKey> depKeysAsIterable = Iterables.concat(depKeys);
Iterable<SkyKey> keysToPrefetch = depKeysAsIterable;
@@ -332,7 +336,7 @@
keysToPrefetchBuilder.addAll(depKeysAsIterable).addAll(oldDeps);
keysToPrefetch = keysToPrefetchBuilder.build();
}
- Map<SkyKey, NodeEntry> batchMap = getBatchValues(keysToPrefetch);
+ Map<SkyKey, NodeEntry> batchMap = getBatchValues(requestor, Reason.PREFETCH, keysToPrefetch);
if (PREFETCH_OLD_DEPS) {
batchMap = ImmutableMap.copyOf(
Maps.filterKeys(batchMap, Predicates.in(ImmutableSet.copyOf(depKeysAsIterable))));
@@ -357,7 +361,7 @@
Preconditions.checkState(building, skyKey);
}
- private NestedSet<TaggedEvents> buildEvents(boolean missingChildren) {
+ private NestedSet<TaggedEvents> buildEvents(NodeEntry entry, boolean missingChildren) {
// Aggregate the nested set of events from the direct deps, also adding the events from
// building this value.
NestedSetBuilder<TaggedEvents> eventBuilder = NestedSetBuilder.stableOrder();
@@ -367,10 +371,10 @@
}
if (storedEventFilter.storeEvents()) {
// Only do the work of processing children if we're going to store events.
- GroupedList<SkyKey> depKeys = graph.get(skyKey).getTemporaryDirectDeps();
+ GroupedList<SkyKey> depKeys = entry.getTemporaryDirectDeps();
Map<SkyKey, SkyValue> deps =
getValuesMaybeFromError(
- Iterables.concat(depKeys), bubbleErrorInfo, depKeys.numElements());
+ null, Iterables.concat(depKeys), bubbleErrorInfo, depKeys.numElements());
if (!missingChildren && depKeys.numElements() != deps.size()) {
throw new IllegalStateException(
"Missing keys for "
@@ -378,7 +382,7 @@
+ ": "
+ Sets.difference(depKeys.toSet(), deps.keySet())
+ ", "
- + graph.get(skyKey));
+ + entry);
}
for (SkyValue value : deps.values()) {
if (value == NULL_MARKER) {
@@ -425,13 +429,14 @@
* dependencies of this node <i>must</i> already have been registered, since this method may
* register a dependence on the error transience node, which should always be the last dep.
*/
- private void setError(ErrorInfo errorInfo, boolean isDirectlyTransient) {
+ private void setError(NodeEntry state, ErrorInfo errorInfo, boolean isDirectlyTransient) {
Preconditions.checkState(value == null, "%s %s %s", skyKey, value, errorInfo);
Preconditions.checkState(this.errorInfo == null,
"%s %s %s", skyKey, this.errorInfo, errorInfo);
if (isDirectlyTransient) {
- NodeEntry errorTransienceNode = graph.get(ErrorTransienceValue.KEY);
+ NodeEntry errorTransienceNode =
+ graph.get(skyKey, Reason.RDEP_ADDITION, ErrorTransienceValue.KEY);
DependencyState triState;
if (oldDeps.contains(ErrorTransienceValue.KEY)) {
triState = errorTransienceNode.checkIfDoneForDirtyReverseDep(skyKey);
@@ -440,8 +445,6 @@
}
Preconditions.checkState(triState == DependencyState.DONE,
"%s %s %s", skyKey, triState, errorInfo);
-
- final NodeEntry state = graph.get(skyKey);
state.addTemporaryDirectDeps(
GroupedListHelper.create(ImmutableList.of(ErrorTransienceValue.KEY)));
state.signalDep();
@@ -451,6 +454,7 @@
}
private Map<SkyKey, SkyValue> getValuesMaybeFromError(
+ @Nullable SkyKey requestor,
Iterable<SkyKey> keys,
@Nullable Map<SkyKey, ValueWithMetadata> bubbleErrorInfo,
int keySize) {
@@ -467,7 +471,8 @@
missingKeys.add(key);
}
}
- Map<SkyKey, NodeEntry> missingEntries = getBatchValues(missingKeys);
+ Map<SkyKey, NodeEntry> missingEntries =
+ getBatchValues(requestor, Reason.DEP_REQUESTED, missingKeys);
for (SkyKey key : missingKeys) {
builder.put(key, maybeGetValueFromError(key, missingEntries.get(key), bubbleErrorInfo));
}
@@ -483,7 +488,7 @@
"Error transience key cannot be in requested deps of %s",
skyKey);
Map<SkyKey, SkyValue> values =
- getValuesMaybeFromError(depKeys, bubbleErrorInfo, depKeys.size());
+ getValuesMaybeFromError(skyKey, depKeys, bubbleErrorInfo, depKeys.size());
for (Map.Entry<SkyKey, SkyValue> depEntry : values.entrySet()) {
SkyKey depKey = depEntry.getKey();
SkyValue depValue = depEntry.getValue();
@@ -495,9 +500,9 @@
+ " was already in deps of "
+ skyKey
+ "( dep: "
- + graph.get(depKey)
+ + graph.get(skyKey, Reason.OTHER, depKey)
+ ", parent: "
- + graph.get(skyKey));
+ + graph.get(null, Reason.OTHER, skyKey));
}
valuesMissing = true;
addDep(depKey);
@@ -636,8 +641,7 @@
* <p>The node entry is informed if the node's value and error are definitive via the flag
* {@code completeValue}.
*/
- void commit(boolean enqueueParents) {
- NodeEntry primaryEntry = Preconditions.checkNotNull(graph.get(skyKey), skyKey);
+ void commit(NodeEntry primaryEntry, boolean enqueueParents) {
// Construct the definitive error info, if there is one.
finalizeErrorInfo();
@@ -648,7 +652,7 @@
// (2) value == null && enqueueParents happens for values that are found to have errors
// during a --keep_going build.
- NestedSet<TaggedEvents> events = buildEvents(/*missingChildren=*/false);
+ NestedSet<TaggedEvents> events = buildEvents(primaryEntry, /*missingChildren=*/false);
Version valueVersion;
SkyValue valueWithMetadata;
if (value == null) {
@@ -663,11 +667,12 @@
// Remove the rdep on this entry for each of its old deps that is no longer a direct dep.
Set<SkyKey> depsToRemove =
Sets.difference(oldDeps, primaryEntry.getTemporaryDirectDeps().toSet());
- for (NodeEntry oldDepEntry :
- graph
- .getBatchWithFieldHints(
- depsToRemove, EnumSet.of(NodeEntryField.INDIVIDUAL_REVERSE_DEPS))
- .values()) {
+ Collection<NodeEntry> oldDepEntries = graph.getBatchWithFieldHints(
+ skyKey,
+ Reason.RDEP_REMOVAL,
+ depsToRemove,
+ EnumSet.of(NodeEntryField.INDIVIDUAL_REVERSE_DEPS)).values();
+ for (NodeEntry oldDepEntry : oldDepEntries) {
oldDepEntry.removeReverseDep(skyKey);
}
}
@@ -694,7 +699,11 @@
progressReceiver.evaluated(skyKey, new SkyValueSupplier(primaryEntry),
valueVersion.equals(graphVersion) ? EvaluationState.BUILT : EvaluationState.CLEAN);
}
- signalValuesAndEnqueueIfReady(enqueueParents ? visitor : null, reverseDeps, valueVersion);
+ signalValuesAndEnqueueIfReady(
+ enqueueParents ? visitor : null,
+ skyKey,
+ reverseDeps,
+ valueVersion);
visitor.notifyDone(skyKey);
replayingNestedSetEventVisitor.visit(events);
@@ -878,7 +887,8 @@
private boolean invalidatedByErrorTransience(Collection<SkyKey> depGroup, NodeEntry entry) {
return depGroup.size() == 1
&& depGroup.contains(ErrorTransienceValue.KEY)
- && !graph.get(ErrorTransienceValue.KEY).getVersion().atMost(entry.getVersion());
+ && !graph.get(
+ null, Reason.OTHER, ErrorTransienceValue.KEY).getVersion().atMost(entry.getVersion());
}
private DirtyOutcome maybeHandleDirtyNode(NodeEntry state) {
@@ -912,7 +922,8 @@
// usual, but we can't, because then the ErrorTransienceValue would remain as a dep,
// which would be incorrect if, for instance, the value re-evaluated to a non-error.
state.forceRebuild();
- graph.get(ErrorTransienceValue.KEY).removeReverseDep(skyKey);
+ graph.get(
+ skyKey, Reason.RDEP_REMOVAL, ErrorTransienceValue.KEY).removeReverseDep(skyKey);
return DirtyOutcome.NEEDS_EVALUATION;
}
if (!keepGoing) {
@@ -925,6 +936,8 @@
// a child error.
Map<SkyKey, NodeEntry> entriesToCheck =
graph.getBatchWithFieldHints(
+ skyKey,
+ Reason.EVALUATION,
directDepsToCheck,
EnumSet.of(NodeEntryField.VALUE, NodeEntryField.INDIVIDUAL_REVERSE_DEPS));
for (Map.Entry<SkyKey, NodeEntry> entry : entriesToCheck.entrySet()) {
@@ -960,8 +973,8 @@
// TODO(bazel-team): If this signals the current node, consider falling through to the
// VERIFIED_CLEAN case below directly, without scheduling a new Evaluate().
- for (Map.Entry<SkyKey, NodeEntry> e
- : graph.createIfAbsentBatch(directDepsToCheck).entrySet()) {
+ for (Map.Entry<SkyKey, NodeEntry> e : graph.createIfAbsentBatch(
+ skyKey, Reason.ENQUEUING_CHILD, directDepsToCheck).entrySet()) {
SkyKey directDep = e.getKey();
NodeEntry directDepEntry = e.getValue();
enqueueChild(skyKey, state, directDep, directDepEntry, /*depAlreadyExists=*/ true);
@@ -982,7 +995,7 @@
}
throw SchedulerException.ofError(state.getErrorInfo(), skyKey);
}
- signalValuesAndEnqueueIfReady(visitor, reverseDeps, state.getVersion());
+ signalValuesAndEnqueueIfReady(visitor, skyKey, reverseDeps, state.getVersion());
return DirtyOutcome.ALREADY_PROCESSED;
case NEEDS_REBUILDING:
maybeMarkRebuilding(state);
@@ -996,7 +1009,9 @@
@Override
public void run() {
- NodeEntry state = Preconditions.checkNotNull(graph.get(skyKey), skyKey);
+ NodeEntry state = Preconditions.checkNotNull(
+ graph.get(null, Reason.EVALUATION, skyKey),
+ skyKey);
Preconditions.checkState(state.isReady(), "%s %s", skyKey, state);
if (maybeHandleDirtyNode(state) == DirtyOutcome.ALREADY_PROCESSED) {
return;
@@ -1036,7 +1051,8 @@
}
}
- Map<SkyKey, NodeEntry> newlyRequestedDeps = getBatchValues(env.newlyRequestedDeps);
+ Map<SkyKey, NodeEntry> newlyRequestedDeps =
+ getBatchValues(skyKey, Reason.RDEP_ADDITION, env.newlyRequestedDeps);
boolean isTransitivelyTransient = reifiedBuilderException.isTransient();
for (NodeEntry depEntry
: Iterables.concat(env.directDeps.values(), newlyRequestedDeps.values())) {
@@ -1051,8 +1067,11 @@
ErrorInfo errorInfo = ErrorInfo.fromException(reifiedBuilderException,
isTransitivelyTransient);
registerNewlyDiscoveredDepsForDoneEntry(skyKey, state, newlyRequestedDeps, oldDeps, env);
- env.setError(errorInfo, /*isDirectlyTransient=*/ reifiedBuilderException.isTransient());
- env.commit(/*enqueueParents=*/keepGoing);
+ env.setError(
+ state,
+ errorInfo,
+ /*isDirectlyTransient=*/ reifiedBuilderException.isTransient());
+ env.commit(state, /*enqueueParents=*/keepGoing);
if (!shouldFailFast) {
return;
}
@@ -1093,10 +1112,13 @@
skyKey,
state,
graph.getBatchWithFieldHints(
- env.newlyRequestedDeps, EnumSet.of(NodeEntryField.INDIVIDUAL_REVERSE_DEPS)),
+ skyKey,
+ Reason.RDEP_ADDITION,
+ env.newlyRequestedDeps,
+ EnumSet.of(NodeEntryField.INDIVIDUAL_REVERSE_DEPS)),
oldDeps,
env);
- env.commit(/*enqueueParents=*/true);
+ env.commit(state, /*enqueueParents=*/true);
return;
}
@@ -1107,8 +1129,12 @@
// error bubbling can occur. Note that this edge will subsequently be removed during graph
// cleaning (since the current node will never be committed to the graph).
SkyKey childErrorKey = env.getDepErrorKey();
- NodeEntry childErrorEntry = Preconditions.checkNotNull(graph.get(childErrorKey),
- "skyKey: %s, state: %s childErrorKey: %s", skyKey, state, childErrorKey);
+ NodeEntry childErrorEntry = Preconditions.checkNotNull(
+ graph.get(skyKey, Reason.OTHER, childErrorKey),
+ "skyKey: %s, state: %s childErrorKey: %s",
+ skyKey,
+ state,
+ childErrorKey);
Preconditions.checkState(
!state.getTemporaryDirectDeps().expensiveContains(childErrorKey),
"Done error was already known: %s %s %s %s",
@@ -1162,11 +1188,12 @@
// If the child error was catastrophic, committing this parent to the graph is not
// necessary, but since we don't do error bubbling in catastrophes, it doesn't violate any
// invariants either.
- env.commit(/*enqueueParents=*/ true);
+ env.commit(state, /*enqueueParents=*/ true);
return;
}
- for (Map.Entry<SkyKey, NodeEntry> e : graph.createIfAbsentBatch(newDirectDeps).entrySet()) {
+ for (Map.Entry<SkyKey, NodeEntry> e
+ : graph.createIfAbsentBatch(skyKey, Reason.ENQUEUING_CHILD, newDirectDeps).entrySet()) {
SkyKey newDirectDep = e.getKey();
NodeEntry newDirectDepEntry = e.getValue();
enqueueChild(
@@ -1209,11 +1236,12 @@
* cycles).
*/
private void signalValuesAndEnqueueIfReady(
- @Nullable ValueVisitor visitor, Iterable<SkyKey> keys, Version version) {
+ @Nullable ValueVisitor visitor, SkyKey skyKey, Iterable<SkyKey> keys, Version version) {
// No fields of the entry are needed here, since we're just enqueuing for evaluation, but more
// importantly, these hints are not respected for not-done nodes. If they are, we may need to
// alter this hint.
- Map<SkyKey, NodeEntry> batch = graph.getBatchWithFieldHints(keys, NodeEntryField.NO_FIELDS);
+ Map<SkyKey, NodeEntry> batch =
+ graph.getBatchWithFieldHints(skyKey, Reason.SIGNAL_DEP, keys, NodeEntryField.NO_FIELDS);
if (visitor != null) {
for (SkyKey key : keys) {
NodeEntry entry = Preconditions.checkNotNull(batch.get(key), key);
@@ -1236,8 +1264,8 @@
* If child is not done, removes {@param inProgressParent} from {@param child}'s reverse deps.
* Returns whether child should be removed from inProgressParent's entry's direct deps.
*/
- private boolean removeIncompleteChild(SkyKey inProgressParent, SkyKey child) {
- NodeEntry childEntry = graph.get(child);
+ private boolean removeIncompleteChildForCycle(SkyKey inProgressParent, SkyKey child) {
+ NodeEntry childEntry = graph.get(inProgressParent, Reason.CYCLE_CHECKING, child);
if (!isDoneForBuild(childEntry)) {
childEntry.removeInProgressReverseDep(inProgressParent);
return true;
@@ -1311,7 +1339,7 @@
// directly without launching the heavy machinery, spawning threads, etc.
// Inform progressReceiver that these nodes are done to be consistent with the main code path.
boolean allAreDone = true;
- Map<SkyKey, NodeEntry> batch = getBatchValues(skyKeySet);
+ Map<SkyKey, NodeEntry> batch = getBatchValues(null, Reason.EVALUATION, skyKeySet);
for (SkyKey key : skyKeySet) {
if (!isDoneForBuild(batch.get(key))) {
allAreDone = false;
@@ -1330,7 +1358,7 @@
if (!keepGoing) {
Set<SkyKey> cachedErrorKeys = new HashSet<>();
for (SkyKey skyKey : skyKeySet) {
- NodeEntry entry = graph.get(skyKey);
+ NodeEntry entry = graph.get(null, Reason.EVALUATION, skyKey);
if (entry == null) {
continue;
}
@@ -1375,7 +1403,8 @@
// in the graph, by the time that it is needed. Creating it on demand in a parallel context sets
// up a race condition, because there is no way to atomically create a node and set its value.
NodeEntry errorTransienceEntry = Iterables.getOnlyElement(
- graph.createIfAbsentBatch(ImmutableList.of(ErrorTransienceValue.KEY)).values());
+ graph.createIfAbsentBatch(
+ null, Reason.EVALUATION, ImmutableList.of(ErrorTransienceValue.KEY)).values());
if (!errorTransienceEntry.isDone()) {
injectValues(
ImmutableMap.of(ErrorTransienceValue.KEY, (SkyValue) ErrorTransienceValue.INSTANCE),
@@ -1383,7 +1412,8 @@
graph,
dirtyKeyTracker);
}
- for (Map.Entry<SkyKey, NodeEntry> e : graph.createIfAbsentBatch(skyKeys).entrySet()) {
+ for (Map.Entry<SkyKey, NodeEntry> e
+ : graph.createIfAbsentBatch(null, Reason.EVALUATION, skyKeys).entrySet()) {
SkyKey skyKey = e.getKey();
NodeEntry entry = e.getValue();
// This must be equivalent to the code in enqueueChild above, in order to be thread-safe.
@@ -1447,7 +1477,7 @@
ImmutableMap.of(
errorKey,
ValueWithMetadata.wrapWithMetadata(
- graph.get(errorKey).getValueMaybeWithMetadata()));
+ graph.get(null, Reason.ERROR_BUBBLING, errorKey).getValueMaybeWithMetadata()));
}
}
Preconditions.checkState(visitor.getCrashes().isEmpty(), visitor.getCrashes());
@@ -1494,7 +1524,9 @@
Map<SkyKey, ValueWithMetadata> bubbleErrorInfo = new HashMap<>();
boolean externalInterrupt = false;
while (true) {
- NodeEntry errorEntry = Preconditions.checkNotNull(graph.get(errorKey), errorKey);
+ NodeEntry errorEntry = Preconditions.checkNotNull(
+ graph.get(null, Reason.ERROR_BUBBLING, errorKey),
+ errorKey);
Iterable<SkyKey> reverseDeps = errorEntry.isDone()
? errorEntry.getReverseDeps()
: errorEntry.getInProgressReverseDeps();
@@ -1511,8 +1543,11 @@
// We are in a cycle. Don't try to bubble anything up -- cycle detection will kick in.
return null;
}
- NodeEntry bubbleParentEntry = Preconditions.checkNotNull(graph.get(bubbleParent),
- "parent %s of %s not in graph", bubbleParent, errorKey);
+ NodeEntry bubbleParentEntry = Preconditions.checkNotNull(
+ graph.get(errorKey, Reason.ERROR_BUBBLING, bubbleParent),
+ "parent %s of %s not in graph",
+ bubbleParent,
+ errorKey);
// Might be the parent that requested the error.
if (bubbleParentEntry.isDone()) {
// This parent is cached from a previous evaluate call. We shouldn't bubble up to it
@@ -1604,7 +1639,7 @@
/*isTransitivelyTransient=*/ false);
bubbleErrorInfo.put(errorKey,
ValueWithMetadata.error(ErrorInfo.fromChildErrors(errorKey, ImmutableSet.of(error)),
- env.buildEvents(/*missingChildren=*/true)));
+ env.buildEvents(parentEntry, /*missingChildren=*/true)));
continue;
}
} finally {
@@ -1614,7 +1649,7 @@
// Builder didn't throw an exception, so just propagate this one up.
bubbleErrorInfo.put(errorKey,
ValueWithMetadata.error(ErrorInfo.fromChildErrors(errorKey, ImmutableSet.of(error)),
- env.buildEvents(/*missingChildren=*/true)));
+ env.buildEvents(parentEntry, /*missingChildren=*/true)));
}
// Reset the interrupt bit if there was an interrupt from outside this evaluator interrupt.
@@ -1649,7 +1684,10 @@
EvaluationResult.Builder<T> result = EvaluationResult.builder();
List<SkyKey> cycleRoots = new ArrayList<>();
for (SkyKey skyKey : skyKeys) {
- SkyValue unwrappedValue = maybeGetValueFromError(skyKey, graph.get(skyKey), bubbleErrorInfo);
+ SkyValue unwrappedValue = maybeGetValueFromError(
+ skyKey,
+ graph.get(null, Reason.EVALUATION, skyKey),
+ bubbleErrorInfo);
ValueWithMetadata valueWithMetadata =
unwrappedValue == NULL_MARKER ? null : ValueWithMetadata.wrapWithMetadata(unwrappedValue);
// Cycle checking: if there is a cycle, evaluation cannot progress, therefore,
@@ -1782,7 +1820,7 @@
// A marker node means we are done with all children of a node. Since all nodes have
// errors, we must have found errors in the children when that happens.
key = graphPath.remove(graphPath.size() - 1);
- entry = Preconditions.checkNotNull(graph.get(key), key);
+ entry = Preconditions.checkNotNull(graph.get(null, Reason.CYCLE_CHECKING, key), key);
pathSet.remove(key);
// Skip this node if it was first/last node of a cycle, and so has already been processed.
if (entry.isDone()) {
@@ -1807,7 +1845,7 @@
maybeMarkRebuilding(entry);
GroupedList<SkyKey> directDeps = entry.getTemporaryDirectDeps();
// Find out which children have errors. Similar logic to that in Evaluate#run().
- List<ErrorInfo> errorDeps = getChildrenErrorsForCycle(Iterables.concat(directDeps));
+ List<ErrorInfo> errorDeps = getChildrenErrorsForCycle(key, Iterables.concat(directDeps));
Preconditions.checkState(!errorDeps.isEmpty(),
"Value %s was not successfully evaluated, but had no child errors. ValueEntry: %s", key,
entry);
@@ -1817,10 +1855,11 @@
directDeps,
Sets.difference(entry.getAllRemainingDirtyDirectDeps(), removedDeps),
visitor);
- env.setError(ErrorInfo.fromChildErrors(key, errorDeps), /*isDirectlyTransient=*/false);
- env.commit(/*enqueueParents=*/false);
+ env.setError(
+ entry, ErrorInfo.fromChildErrors(key, errorDeps), /*isDirectlyTransient=*/false);
+ env.commit(entry, /*enqueueParents=*/false);
} else {
- entry = graph.get(key);
+ entry = graph.get(null, Reason.CYCLE_CHECKING, key);
}
Preconditions.checkNotNull(entry, key);
@@ -1870,14 +1909,14 @@
// Construct error info for this node. Get errors from children, which are all done
// except possibly for the cycleChild.
List<ErrorInfo> allErrors =
- getChildrenErrors(
+ getChildrenErrorsForCycleChecking(
Iterables.concat(entry.getTemporaryDirectDeps()),
/*unfinishedChild=*/ cycleChild);
CycleInfo cycleInfo = new CycleInfo(cycle);
// Add in this cycle.
allErrors.add(ErrorInfo.fromCycle(cycleInfo));
- env.setError(ErrorInfo.fromChildErrors(key, allErrors), /*isTransient=*/false);
- env.commit(/*enqueueParents=*/false);
+ env.setError(entry, ErrorInfo.fromChildErrors(key, allErrors), /*isTransient=*/false);
+ env.commit(entry, /*enqueueParents=*/false);
continue;
} else {
// We need to return right away in the noKeepGoing case, so construct the cycle (with the
@@ -1898,8 +1937,8 @@
// out.
// TODO(janakr): If graph implementations start using these hints for not-done nodes, we may
// have to change this.
- Map<SkyKey, NodeEntry> childrenNodes =
- graph.getBatchWithFieldHints(children, NodeEntryField.NO_FIELDS);
+ Map<SkyKey, NodeEntry> childrenNodes = graph.getBatchWithFieldHints(
+ key, Reason.CYCLE_CHECKING, children, NodeEntryField.NO_FIELDS);
Preconditions.checkState(childrenNodes.size() == Iterables.size(children), childrenNodes);
children = Maps.filterValues(childrenNodes, new Predicate<NodeEntry>() {
@Override
@@ -1917,7 +1956,7 @@
toVisit.push(nextValue);
}
}
- return keepGoing ? getAndCheckDone(root).getErrorInfo() : null;
+ return keepGoing ? getAndCheckDoneForCycle(root).getErrorInfo() : null;
}
/**
@@ -1934,10 +1973,10 @@
* @param children child nodes to query for errors.
* @return List of ErrorInfos from all children that had errors.
*/
- private List<ErrorInfo> getChildrenErrorsForCycle(Iterable<SkyKey> children) {
+ private List<ErrorInfo> getChildrenErrorsForCycle(SkyKey parent, Iterable<SkyKey> children) {
List<ErrorInfo> allErrors = new ArrayList<>();
boolean foundCycle = false;
- for (NodeEntry childNode : getAndCheckDoneBatch(children).values()) {
+ for (NodeEntry childNode : getAndCheckDoneBatchForCycle(parent, children).values()) {
ErrorInfo errorInfo = childNode.getErrorInfo();
if (errorInfo != null) {
foundCycle |= !Iterables.isEmpty(errorInfo.getCycleInfo());
@@ -1955,9 +1994,12 @@
* @param unfinishedChild child which is allowed to not be done.
* @return List of ErrorInfos from all children that had errors.
*/
- private List<ErrorInfo> getChildrenErrors(Iterable<SkyKey> children, SkyKey unfinishedChild) {
+ private List<ErrorInfo> getChildrenErrorsForCycleChecking(
+ Iterable<SkyKey> children, SkyKey unfinishedChild) {
List<ErrorInfo> allErrors = new ArrayList<>();
- for (Entry<SkyKey, NodeEntry> childMapEntry : getBatchValues(children).entrySet()) {
+ Set<Entry<SkyKey, NodeEntry>> childEntries =
+ getBatchValues(null, Reason.CYCLE_CHECKING, children).entrySet();
+ for (Entry<SkyKey, NodeEntry> childMapEntry : childEntries) {
SkyKey childKey = childMapEntry.getKey();
NodeEntry childNodeEntry = childMapEntry.getValue();
ErrorInfo errorInfo = getErrorMaybe(childKey, childNodeEntry,
@@ -2041,7 +2083,7 @@
SkyKey key, NodeEntry entry, Iterable<SkyKey> children) {
Set<SkyKey> unfinishedDeps = new HashSet<>();
for (SkyKey child : children) {
- if (removeIncompleteChild(key, child)) {
+ if (removeIncompleteChildForCycle(key, child)) {
unfinishedDeps.add(child);
}
}
@@ -2049,18 +2091,19 @@
return unfinishedDeps;
}
- private NodeEntry getAndCheckDone(SkyKey key) {
- return checkDone(key, graph.get(key));
- }
-
private static NodeEntry checkDone(SkyKey key, NodeEntry entry) {
Preconditions.checkNotNull(entry, key);
Preconditions.checkState(entry.isDone(), "%s %s", key, entry);
return entry;
}
- private Map<SkyKey, NodeEntry> getAndCheckDoneBatch(Iterable<SkyKey> keys) {
- Map<SkyKey, NodeEntry> nodes = getBatchValues(keys);
+ private NodeEntry getAndCheckDoneForCycle(SkyKey key) {
+ return checkDone(key, graph.get(null, Reason.CYCLE_CHECKING, key));
+ }
+
+ private Map<SkyKey, NodeEntry> getAndCheckDoneBatchForCycle(
+ SkyKey parent, Iterable<SkyKey> keys) {
+ Map<SkyKey, NodeEntry> nodes = getBatchValues(parent, Reason.CYCLE_CHECKING, keys);
for (Map.Entry<SkyKey, NodeEntry> nodeEntryMapEntry : nodes.entrySet()) {
checkDone(nodeEntryMapEntry.getKey(), nodeEntryMapEntry.getValue());
}
@@ -2096,7 +2139,8 @@
Version version,
EvaluableGraph graph,
DirtyKeyTracker dirtyKeyTracker) {
- Map<SkyKey, NodeEntry> prevNodeEntries = graph.createIfAbsentBatch(injectionMap.keySet());
+ Map<SkyKey, NodeEntry> prevNodeEntries =
+ graph.createIfAbsentBatch(null, Reason.OTHER, injectionMap.keySet());
for (Map.Entry<SkyKey, SkyValue> injectionEntry : injectionMap.entrySet()) {
SkyKey key = injectionEntry.getKey();
SkyValue value = injectionEntry.getValue();
diff --git a/src/main/java/com/google/devtools/build/skyframe/QueryableGraph.java b/src/main/java/com/google/devtools/build/skyframe/QueryableGraph.java
index 2703802..75ce05c 100644
--- a/src/main/java/com/google/devtools/build/skyframe/QueryableGraph.java
+++ b/src/main/java/com/google/devtools/build/skyframe/QueryableGraph.java
@@ -23,9 +23,15 @@
/** A graph that exposes its entries and structure, for use by classes that must traverse it. */
@ThreadSafe
public interface QueryableGraph {
- /** Returns the node with the given name, or {@code null} if the node does not exist. */
+ /**
+ * Returns the node with the given {@code key}, or {@code null} if the node does not exist.
+ *
+ * @param requestor if non-{@code null}, the node on behalf of which {@code key} is being
+ * requested.
+ * @param reason the reason the node is being requested.
+ */
@Nullable
- NodeEntry get(SkyKey key);
+ NodeEntry get(@Nullable SkyKey requestor, Reason reason, SkyKey key);
/**
* Fetches all the given nodes. Returns a map {@code m} such that, for all {@code k} in {@code
@@ -34,7 +40,65 @@
* QueryableGraph implementation that allows it to possibly construct certain fields of the
* returned node entries more lazily. Hints may only be applied to nodes in a certain state, like
* done nodes.
+ *
+ * @param requestor if non-{@code null}, the node on behalf of which the given {@code keys} are
+ * being requested.
+ * @param reason the reason the nodes are being requested.
*/
Map<SkyKey, NodeEntry> getBatchWithFieldHints(
- Iterable<SkyKey> keys, EnumSet<NodeEntryField> fields);
+ @Nullable SkyKey requestor,
+ Reason reason,
+ Iterable<SkyKey> keys,
+ EnumSet<NodeEntryField> fields);
+
+ /**
+ * The reason that a node is being looked up in the Skyframe graph.
+ *
+ * <p>Alternate graph implementations may wish to make use of this information.
+ */
+ enum Reason {
+ /**
+ * The node is being looked up as part of the prefetch step before evaluation of a SkyFunction.
+ */
+ PREFETCH,
+
+ /**
+ * The node is being fetched because it is about to be evaluated or it has already been
+ * evaluated, but *not* because it was just requested during evaluation of a SkyFunction (see
+ * DEP_REQUESTED).
+ */
+ EVALUATION,
+
+ /** The node is being looked up because it was requested during evaluation of a SkyFunction. */
+ DEP_REQUESTED,
+
+ /** The node is being looked up during the invalidation phase of Skyframe evaluation. */
+ INVALIDATION,
+
+ /** The node is being looked up during the cycle checking phase of Skyframe evaluation. */
+ CYCLE_CHECKING,
+
+ /** The node is being looked up so that an rdep can be added to it. */
+ RDEP_ADDITION,
+
+ /** The node is being looked up so that an rdep can be removed from it. */
+ RDEP_REMOVAL,
+
+ /** The node is being looked up so it can be enqueued for evaluation or change pruning. */
+ ENQUEUING_CHILD,
+
+ /**
+ * The node is being looked up so that it can be signaled that a dependency is now complete.
+ */
+ SIGNAL_DEP,
+
+ /**
+ * The node is being looking up as part of the error bubbling phase of fail-fast Skyframe
+ * evaluation.
+ */
+ ERROR_BUBBLING,
+
+ /** Some other reason than one of the above. */
+ OTHER,
+ }
}
diff --git a/src/main/java/com/google/devtools/build/skyframe/QueryableGraphBackedSkyFunctionEnvironment.java b/src/main/java/com/google/devtools/build/skyframe/QueryableGraphBackedSkyFunctionEnvironment.java
index ed38be3..6aaadcd 100644
--- a/src/main/java/com/google/devtools/build/skyframe/QueryableGraphBackedSkyFunctionEnvironment.java
+++ b/src/main/java/com/google/devtools/build/skyframe/QueryableGraphBackedSkyFunctionEnvironment.java
@@ -19,7 +19,7 @@
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.util.Preconditions;
-
+import com.google.devtools.build.skyframe.QueryableGraph.Reason;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -70,8 +70,8 @@
@Override
protected Map<SkyKey, ValueOrUntypedException> getValueOrUntypedExceptions(Set<SkyKey> depKeys) {
- Map<SkyKey, NodeEntry> resultMap =
- queryableGraph.getBatchWithFieldHints(depKeys, NodeEntryField.VALUE_ONLY);
+ Map<SkyKey, NodeEntry> resultMap = queryableGraph.getBatchWithFieldHints(
+ null, Reason.DEP_REQUESTED, depKeys, NodeEntryField.VALUE_ONLY);
Map<SkyKey, NodeEntry> resultWithMissingKeys = new HashMap<>(resultMap);
for (SkyKey missingDep : Sets.difference(depKeys, resultMap.keySet())) {
resultWithMissingKeys.put(missingDep, null);