Don't iterate over children when building events if events won't be stored anyway. Also batch retrievals of children when building events. -- MOS_MIGRATED_REVID=105174435
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 156e93e..fc54c1f 100644 --- a/src/main/java/com/google/devtools/build/skyframe/ParallelEvaluator.java +++ b/src/main/java/com/google/devtools/build/skyframe/ParallelEvaluator.java
@@ -94,6 +94,16 @@ * evaluation implementations outside of this package. */ public final class ParallelEvaluator implements Evaluator { + + /** Filters out events which should not be stored. */ + public interface EventFilter extends Predicate<Event> { + /** + * Returns true if any events should be stored. Otherwise, optimizations may be made to avoid + * doing unnecessary work. + */ + boolean storeEvents(); + } + private final ProcessableGraph graph; private final Version graphVersion; @@ -136,7 +146,7 @@ @Nullable private final EvaluationProgressReceiver progressReceiver; private final DirtyKeyTracker dirtyKeyTracker; private final Receiver<Collection<SkyKey>> inflightKeysReceiver; - private final Predicate<Event> storedEventFilter; + private final EventFilter storedEventFilter; private static final Interner<SkyKey> KEY_CANONICALIZER = Interners.newWeakInterner(); @@ -146,7 +156,7 @@ ImmutableMap<? extends SkyFunctionName, ? extends SkyFunction> skyFunctions, final EventHandler reporter, EmittedEventState emittedEventState, - Predicate<Event> storedEventFilter, + EventFilter storedEventFilter, boolean keepGoing, int threadCount, @Nullable EvaluationProgressReceiver progressReceiver, @@ -215,17 +225,19 @@ /** The set of errors encountered while fetching children. */ private final Collection<ErrorInfo> childErrorInfos = new LinkedHashSet<>(); - private final StoredEventHandler eventHandler = new StoredEventHandler() { - @Override - public void handle(Event e) { - checkActive(); - if (storedEventFilter.apply(e)) { - super.handle(e); - } else { - reporter.handle(e); - } - } - }; + private final StoredEventHandler eventHandler = + new StoredEventHandler() { + @Override + @SuppressWarnings("UnsynchronizedOverridesSynchronized") // only delegates to thread-safe. + public void handle(Event e) { + checkActive(); + if (storedEventFilter.apply(e)) { + super.handle(e); + } else { + reporter.handle(e); + } + } + }; private SkyFunctionEnvironment(SkyKey skyKey, Set<SkyKey> directDeps, ValueVisitor visitor) { this(skyKey, directDeps, null, visitor); @@ -268,12 +280,21 @@ if (!events.isEmpty()) { eventBuilder.add(new TaggedEvents(getTagFromKey(), events)); } - for (SkyKey dep : graph.get(skyKey).getTemporaryDirectDeps()) { - ValueWithMetadata value = getValueMaybeFromError(dep, bubbleErrorInfo); - if (value != null) { + if (storedEventFilter.storeEvents()) { + // Only do the work of processing children if we're going to store events. + Set<SkyKey> depKeys = graph.get(skyKey).getTemporaryDirectDeps(); + Map<SkyKey, ValueWithMetadata> deps = getValuesMaybeFromError(depKeys, bubbleErrorInfo); + if (!missingChildren && depKeys.size() != deps.size()) { + throw new IllegalStateException( + "Missing keys for " + + skyKey + + ": " + + Sets.difference(depKeys, deps.keySet()) + + ", " + + graph.get(skyKey)); + } + for (ValueWithMetadata value : deps.values()) { eventBuilder.addTransitive(value.getTransitiveEvents()); - } else { - Preconditions.checkState(missingChildren, "", dep, skyKey); } } return eventBuilder.build();