blob: 3577230e3a2f0c305ba74cf2200113be723c3cd3 [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package com.google.devtools.build.skyframe;
15
Mark Schallere3c88de2015-08-05 22:02:59 +000016import com.google.common.base.Function;
17import com.google.devtools.build.lib.concurrent.AbstractQueueVisitor;
Nathan Harmata3724d922016-05-26 19:56:24 +000018import com.google.devtools.build.lib.concurrent.ErrorHandler;
Mark Schallereff2b452015-10-13 20:06:19 +000019import com.google.devtools.build.lib.concurrent.ExecutorParams;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010020import com.google.devtools.build.skyframe.InvalidatingNodeVisitor.DeletingNodeVisitor;
21import com.google.devtools.build.skyframe.InvalidatingNodeVisitor.DirtyingNodeVisitor;
22import com.google.devtools.build.skyframe.InvalidatingNodeVisitor.InvalidationState;
Mark Schallereff2b452015-10-13 20:06:19 +000023import java.util.concurrent.ExecutorService;
Mark Schaller454bc6d2015-11-03 19:12:48 +000024import java.util.concurrent.ForkJoinPool;
Mark Schallere3c88de2015-08-05 22:02:59 +000025import javax.annotation.Nullable;
26
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010027/**
28 * Utility class for performing eager invalidation on Skyframe graphs.
29 *
30 * <p>This is intended only for use in alternative {@code MemoizingEvaluator} implementations.
31 */
32public final class EagerInvalidator {
33
34 private EagerInvalidator() {}
35
36 /**
37 * Deletes given values. The {@code traverseGraph} parameter controls whether this method deletes
38 * (transitive) dependents of these nodes and relevant graph edges, or just the nodes themselves.
39 * Deleting just the nodes is inconsistent unless the graph will not be used for incremental
40 * builds in the future, but unfortunately there is a case where we delete nodes intra-build. As
41 * long as the full upward transitive closure of the nodes is specified for deletion, the graph
42 * remains consistent.
43 */
Janak Ramakrishnancc7712f2016-07-08 17:38:27 +000044 public static void delete(
45 InMemoryGraph graph,
46 Iterable<SkyKey> diff,
Chloe Calvarin860b8d22016-10-05 22:52:55 +000047 DirtyTrackingProgressReceiver progressReceiver,
Janak Ramakrishnancc7712f2016-07-08 17:38:27 +000048 InvalidationState state,
Chloe Calvarin860b8d22016-10-05 22:52:55 +000049 boolean traverseGraph)
Janak Ramakrishnancc7712f2016-07-08 17:38:27 +000050 throws InterruptedException {
Mark Schaller226ce6812015-09-01 22:44:58 +000051 DeletingNodeVisitor visitor =
52 createDeletingVisitorIfNeeded(
Chloe Calvarin860b8d22016-10-05 22:52:55 +000053 graph, diff, progressReceiver, state, traverseGraph);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010054 if (visitor != null) {
55 visitor.run();
56 }
57 }
58
Mark Schallere3c88de2015-08-05 22:02:59 +000059 @Nullable
Mark Schaller226ce6812015-09-01 22:44:58 +000060 static DeletingNodeVisitor createDeletingVisitorIfNeeded(
Janak Ramakrishnancc7712f2016-07-08 17:38:27 +000061 InMemoryGraph graph,
Mark Schaller226ce6812015-09-01 22:44:58 +000062 Iterable<SkyKey> diff,
Chloe Calvarin860b8d22016-10-05 22:52:55 +000063 DirtyTrackingProgressReceiver progressReceiver,
Mark Schaller226ce6812015-09-01 22:44:58 +000064 InvalidationState state,
Chloe Calvarin860b8d22016-10-05 22:52:55 +000065 boolean traverseGraph) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010066 state.update(diff);
Mark Schallere3c88de2015-08-05 22:02:59 +000067 return state.isEmpty() ? null
Chloe Calvarin860b8d22016-10-05 22:52:55 +000068 : new DeletingNodeVisitor(graph, progressReceiver, state, traverseGraph);
Mark Schallere3c88de2015-08-05 22:02:59 +000069 }
70
71 @Nullable
Mark Schaller226ce6812015-09-01 22:44:58 +000072 static DirtyingNodeVisitor createInvalidatingVisitorIfNeeded(
Nathan Harmata33faf912016-08-10 19:15:15 +000073 QueryableGraph graph,
Mark Schaller226ce6812015-09-01 22:44:58 +000074 Iterable<SkyKey> diff,
Chloe Calvarin860b8d22016-10-05 22:52:55 +000075 DirtyTrackingProgressReceiver progressReceiver,
Mark Schaller226ce6812015-09-01 22:44:58 +000076 InvalidationState state,
Mark Schallereff2b452015-10-13 20:06:19 +000077 Function<ExecutorParams, ? extends ExecutorService> executorFactory) {
Mark Schallere3c88de2015-08-05 22:02:59 +000078 state.update(diff);
79 return state.isEmpty() ? null
Chloe Calvarin860b8d22016-10-05 22:52:55 +000080 : new DirtyingNodeVisitor(graph, progressReceiver, state, executorFactory);
Mark Schallere3c88de2015-08-05 22:02:59 +000081 }
82
Mark Schaller454bc6d2015-11-03 19:12:48 +000083 @Nullable
84 private static DirtyingNodeVisitor createInvalidatingVisitorIfNeeded(
Nathan Harmata33faf912016-08-10 19:15:15 +000085 QueryableGraph graph,
Mark Schaller454bc6d2015-11-03 19:12:48 +000086 Iterable<SkyKey> diff,
Chloe Calvarin860b8d22016-10-05 22:52:55 +000087 DirtyTrackingProgressReceiver progressReceiver,
Mark Schaller454bc6d2015-11-03 19:12:48 +000088 InvalidationState state,
Mark Schallerc6ed6132015-11-24 15:45:40 +000089 ForkJoinPool forkJoinPool,
Nathan Harmata3724d922016-05-26 19:56:24 +000090 boolean supportInterruptions,
91 ErrorHandler errorHandler) {
Mark Schaller454bc6d2015-11-03 19:12:48 +000092 state.update(diff);
93 return state.isEmpty()
94 ? null
95 : new DirtyingNodeVisitor(
Mark Schallerc6ed6132015-11-24 15:45:40 +000096 graph,
Googlerc4e22552016-09-27 15:44:40 +000097 progressReceiver,
Mark Schallerc6ed6132015-11-24 15:45:40 +000098 state,
Mark Schallerc6ed6132015-11-24 15:45:40 +000099 forkJoinPool,
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000100 supportInterruptions);
Mark Schaller454bc6d2015-11-03 19:12:48 +0000101 }
Mark Schallere3c88de2015-08-05 22:02:59 +0000102 /**
Mark Schaller454bc6d2015-11-03 19:12:48 +0000103 * Invalidates given values and their upward transitive closure in the graph if necessary, using
104 * an executor constructed with the provided factory.
Mark Schallere3c88de2015-08-05 22:02:59 +0000105 */
Mark Schaller226ce6812015-09-01 22:44:58 +0000106 public static void invalidate(
Nathan Harmata33faf912016-08-10 19:15:15 +0000107 QueryableGraph graph,
Mark Schaller226ce6812015-09-01 22:44:58 +0000108 Iterable<SkyKey> diff,
Chloe Calvarin860b8d22016-10-05 22:52:55 +0000109 DirtyTrackingProgressReceiver progressReceiver,
Mark Schaller226ce6812015-09-01 22:44:58 +0000110 InvalidationState state,
Mark Schallereff2b452015-10-13 20:06:19 +0000111 Function<ExecutorParams, ? extends ExecutorService> executorFactory)
Mark Schaller226ce6812015-09-01 22:44:58 +0000112 throws InterruptedException {
Mark Schaller226ce6812015-09-01 22:44:58 +0000113 DirtyingNodeVisitor visitor =
114 createInvalidatingVisitorIfNeeded(
Chloe Calvarin860b8d22016-10-05 22:52:55 +0000115 graph, diff, progressReceiver, state, executorFactory);
Mark Schallere3c88de2015-08-05 22:02:59 +0000116 if (visitor != null) {
117 visitor.run();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100118 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100119 }
120
121 /**
Mark Schaller454bc6d2015-11-03 19:12:48 +0000122 * Invalidates given values and their upward transitive closure in the graph if necessary, using
123 * the provided {@link ForkJoinPool}.
124 */
125 public static void invalidate(
Nathan Harmata33faf912016-08-10 19:15:15 +0000126 QueryableGraph graph,
Mark Schaller454bc6d2015-11-03 19:12:48 +0000127 Iterable<SkyKey> diff,
Chloe Calvarin860b8d22016-10-05 22:52:55 +0000128 DirtyTrackingProgressReceiver progressReceiver,
Mark Schaller454bc6d2015-11-03 19:12:48 +0000129 InvalidationState state,
Mark Schallerc6ed6132015-11-24 15:45:40 +0000130 ForkJoinPool forkJoinPool,
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000131 boolean supportInterruptions)
Mark Schaller454bc6d2015-11-03 19:12:48 +0000132 throws InterruptedException {
133 DirtyingNodeVisitor visitor =
134 createInvalidatingVisitorIfNeeded(
Mark Schallerc6ed6132015-11-24 15:45:40 +0000135 graph,
136 diff,
Googlerc4e22552016-09-27 15:44:40 +0000137 progressReceiver,
Mark Schallerc6ed6132015-11-24 15:45:40 +0000138 state,
Mark Schallerc6ed6132015-11-24 15:45:40 +0000139 forkJoinPool,
Nathan Harmata3724d922016-05-26 19:56:24 +0000140 supportInterruptions,
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000141 ErrorHandler.NullHandler.INSTANCE);
Mark Schaller454bc6d2015-11-03 19:12:48 +0000142 if (visitor != null) {
143 visitor.run();
144 }
145 }
146
Janak Ramakrishnancc7712f2016-07-08 17:38:27 +0000147 /** Invalidates given values and their upward transitive closure in the graph. */
Mark Schaller454bc6d2015-11-03 19:12:48 +0000148 public static void invalidate(
Nathan Harmata33faf912016-08-10 19:15:15 +0000149 QueryableGraph graph,
Mark Schaller454bc6d2015-11-03 19:12:48 +0000150 Iterable<SkyKey> diff,
Chloe Calvarin860b8d22016-10-05 22:52:55 +0000151 DirtyTrackingProgressReceiver progressReceiver,
152 InvalidationState state)
Mark Schallere3c88de2015-08-05 22:02:59 +0000153 throws InterruptedException {
Chloe Calvarin860b8d22016-10-05 22:52:55 +0000154 invalidate(graph, diff, progressReceiver, state, AbstractQueueVisitor.EXECUTOR_FACTORY);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100155 }
Mark Schallere3c88de2015-08-05 22:02:59 +0000156
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100157}