Permit use of ForkJoinQuiescingExecutor for invalidation Changes InvalidatingNodeVisitor's use of AbstractQueueVisitor from inheritance to composition. This allows it to vary its executor implementation. A ForkJoinPool-specialized implementation option is provided. -- MOS_MIGRATED_REVID=106960011
diff --git a/src/main/java/com/google/devtools/build/skyframe/EagerInvalidator.java b/src/main/java/com/google/devtools/build/skyframe/EagerInvalidator.java index ce76bc6..cb2a8cc 100644 --- a/src/main/java/com/google/devtools/build/skyframe/EagerInvalidator.java +++ b/src/main/java/com/google/devtools/build/skyframe/EagerInvalidator.java
@@ -21,6 +21,7 @@ import com.google.devtools.build.skyframe.InvalidatingNodeVisitor.InvalidationState; import java.util.concurrent.ExecutorService; +import java.util.concurrent.ForkJoinPool; import javax.annotation.Nullable; @@ -80,9 +81,24 @@ executorFactory); } + @Nullable + private static DirtyingNodeVisitor createInvalidatingVisitorIfNeeded( + ThinNodeQueryableGraph graph, + Iterable<SkyKey> diff, + EvaluationProgressReceiver invalidationReceiver, + InvalidationState state, + DirtyKeyTracker dirtyKeyTracker, + ForkJoinPool forkJoinPool) { + state.update(diff); + return state.isEmpty() + ? null + : new DirtyingNodeVisitor( + graph, invalidationReceiver, state, dirtyKeyTracker, forkJoinPool); + } + /** - * Invalidates given values and their upward transitive closure in the graph, using an executor - * constructed with the provided factory, if necessary. + * Invalidates given values and their upward transitive closure in the graph if necessary, using + * an executor constructed with the provided factory. */ public static void invalidate( ThinNodeQueryableGraph graph, @@ -92,10 +108,6 @@ DirtyKeyTracker dirtyKeyTracker, Function<ExecutorParams, ? extends ExecutorService> executorFactory) throws InterruptedException { - // If we are invalidating, we must be in an incremental build by definition, so we must - // maintain a consistent graph state by traversing the graph and invalidating transitive - // dependencies. If edges aren't present, it would be impossible to check the dependencies of - // a dirty node in any case. DirtyingNodeVisitor visitor = createInvalidatingVisitorIfNeeded( graph, diff, invalidationReceiver, state, dirtyKeyTracker, executorFactory); @@ -105,10 +117,33 @@ } /** + * Invalidates given values and their upward transitive closure in the graph if necessary, using + * the provided {@link ForkJoinPool}. + */ + public static void invalidate( + ThinNodeQueryableGraph graph, + Iterable<SkyKey> diff, + EvaluationProgressReceiver invalidationReceiver, + InvalidationState state, + DirtyKeyTracker dirtyKeyTracker, + ForkJoinPool forkJoinPool) + throws InterruptedException { + DirtyingNodeVisitor visitor = + createInvalidatingVisitorIfNeeded( + graph, diff, invalidationReceiver, state, dirtyKeyTracker, forkJoinPool); + if (visitor != null) { + visitor.run(); + } + } + + /** * Invalidates given values and their upward transitive closure in the graph. */ - public static void invalidate(DirtiableGraph graph, Iterable<SkyKey> diff, - EvaluationProgressReceiver invalidationReceiver, InvalidationState state, + public static void invalidate( + DirtiableGraph graph, + Iterable<SkyKey> diff, + EvaluationProgressReceiver invalidationReceiver, + InvalidationState state, DirtyKeyTracker dirtyKeyTracker) throws InterruptedException { invalidate(graph, diff, invalidationReceiver, state, dirtyKeyTracker,