blob: bff685097d5cbbd6c70c1b6b4b1c7a667c0d3fcb [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,
Googlerc4e22552016-09-27 15:44:40 +000047 EvaluationProgressReceiver progressReceiver,
Janak Ramakrishnancc7712f2016-07-08 17:38:27 +000048 InvalidationState state,
49 boolean traverseGraph,
50 DirtyKeyTracker dirtyKeyTracker)
51 throws InterruptedException {
Mark Schaller226ce6812015-09-01 22:44:58 +000052 DeletingNodeVisitor visitor =
53 createDeletingVisitorIfNeeded(
Googlerc4e22552016-09-27 15:44:40 +000054 graph, diff, progressReceiver, state, traverseGraph, dirtyKeyTracker);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010055 if (visitor != null) {
56 visitor.run();
57 }
58 }
59
Mark Schallere3c88de2015-08-05 22:02:59 +000060 @Nullable
Mark Schaller226ce6812015-09-01 22:44:58 +000061 static DeletingNodeVisitor createDeletingVisitorIfNeeded(
Janak Ramakrishnancc7712f2016-07-08 17:38:27 +000062 InMemoryGraph graph,
Mark Schaller226ce6812015-09-01 22:44:58 +000063 Iterable<SkyKey> diff,
Googlerc4e22552016-09-27 15:44:40 +000064 EvaluationProgressReceiver progressReceiver,
Mark Schaller226ce6812015-09-01 22:44:58 +000065 InvalidationState state,
66 boolean traverseGraph,
67 DirtyKeyTracker dirtyKeyTracker) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010068 state.update(diff);
Mark Schallere3c88de2015-08-05 22:02:59 +000069 return state.isEmpty() ? null
Googlerc4e22552016-09-27 15:44:40 +000070 : new DeletingNodeVisitor(graph, progressReceiver, state, traverseGraph,
Mark Schallere3c88de2015-08-05 22:02:59 +000071 dirtyKeyTracker);
72 }
73
74 @Nullable
Mark Schaller226ce6812015-09-01 22:44:58 +000075 static DirtyingNodeVisitor createInvalidatingVisitorIfNeeded(
Nathan Harmata33faf912016-08-10 19:15:15 +000076 QueryableGraph graph,
Mark Schaller226ce6812015-09-01 22:44:58 +000077 Iterable<SkyKey> diff,
Googlerc4e22552016-09-27 15:44:40 +000078 EvaluationProgressReceiver progressReceiver,
Mark Schaller226ce6812015-09-01 22:44:58 +000079 InvalidationState state,
80 DirtyKeyTracker dirtyKeyTracker,
Mark Schallereff2b452015-10-13 20:06:19 +000081 Function<ExecutorParams, ? extends ExecutorService> executorFactory) {
Mark Schallere3c88de2015-08-05 22:02:59 +000082 state.update(diff);
83 return state.isEmpty() ? null
Googlerc4e22552016-09-27 15:44:40 +000084 : new DirtyingNodeVisitor(graph, progressReceiver, state, dirtyKeyTracker,
Mark Schallere3c88de2015-08-05 22:02:59 +000085 executorFactory);
86 }
87
Mark Schaller454bc6d2015-11-03 19:12:48 +000088 @Nullable
89 private static DirtyingNodeVisitor createInvalidatingVisitorIfNeeded(
Nathan Harmata33faf912016-08-10 19:15:15 +000090 QueryableGraph graph,
Mark Schaller454bc6d2015-11-03 19:12:48 +000091 Iterable<SkyKey> diff,
Googlerc4e22552016-09-27 15:44:40 +000092 EvaluationProgressReceiver progressReceiver,
Mark Schaller454bc6d2015-11-03 19:12:48 +000093 InvalidationState state,
94 DirtyKeyTracker dirtyKeyTracker,
Mark Schallerc6ed6132015-11-24 15:45:40 +000095 ForkJoinPool forkJoinPool,
Nathan Harmata3724d922016-05-26 19:56:24 +000096 boolean supportInterruptions,
97 ErrorHandler errorHandler) {
Mark Schaller454bc6d2015-11-03 19:12:48 +000098 state.update(diff);
99 return state.isEmpty()
100 ? null
101 : new DirtyingNodeVisitor(
Mark Schallerc6ed6132015-11-24 15:45:40 +0000102 graph,
Googlerc4e22552016-09-27 15:44:40 +0000103 progressReceiver,
Mark Schallerc6ed6132015-11-24 15:45:40 +0000104 state,
105 dirtyKeyTracker,
106 forkJoinPool,
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000107 supportInterruptions);
Mark Schaller454bc6d2015-11-03 19:12:48 +0000108 }
109
Mark Schallere3c88de2015-08-05 22:02:59 +0000110 /**
Mark Schaller454bc6d2015-11-03 19:12:48 +0000111 * Invalidates given values and their upward transitive closure in the graph if necessary, using
112 * an executor constructed with the provided factory.
Mark Schallere3c88de2015-08-05 22:02:59 +0000113 */
Mark Schaller226ce6812015-09-01 22:44:58 +0000114 public static void invalidate(
Nathan Harmata33faf912016-08-10 19:15:15 +0000115 QueryableGraph graph,
Mark Schaller226ce6812015-09-01 22:44:58 +0000116 Iterable<SkyKey> diff,
Googlerc4e22552016-09-27 15:44:40 +0000117 EvaluationProgressReceiver progressReceiver,
Mark Schaller226ce6812015-09-01 22:44:58 +0000118 InvalidationState state,
Mark Schallere3c88de2015-08-05 22:02:59 +0000119 DirtyKeyTracker dirtyKeyTracker,
Mark Schallereff2b452015-10-13 20:06:19 +0000120 Function<ExecutorParams, ? extends ExecutorService> executorFactory)
Mark Schaller226ce6812015-09-01 22:44:58 +0000121 throws InterruptedException {
Mark Schaller226ce6812015-09-01 22:44:58 +0000122 DirtyingNodeVisitor visitor =
123 createInvalidatingVisitorIfNeeded(
Googlerc4e22552016-09-27 15:44:40 +0000124 graph, diff, progressReceiver, state, dirtyKeyTracker, executorFactory);
Mark Schallere3c88de2015-08-05 22:02:59 +0000125 if (visitor != null) {
126 visitor.run();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100127 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100128 }
129
130 /**
Mark Schaller454bc6d2015-11-03 19:12:48 +0000131 * Invalidates given values and their upward transitive closure in the graph if necessary, using
132 * the provided {@link ForkJoinPool}.
133 */
134 public static void invalidate(
Nathan Harmata33faf912016-08-10 19:15:15 +0000135 QueryableGraph graph,
Mark Schaller454bc6d2015-11-03 19:12:48 +0000136 Iterable<SkyKey> diff,
Googlerc4e22552016-09-27 15:44:40 +0000137 EvaluationProgressReceiver progressReceiver,
Mark Schaller454bc6d2015-11-03 19:12:48 +0000138 InvalidationState state,
139 DirtyKeyTracker dirtyKeyTracker,
Mark Schallerc6ed6132015-11-24 15:45:40 +0000140 ForkJoinPool forkJoinPool,
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000141 boolean supportInterruptions)
Mark Schaller454bc6d2015-11-03 19:12:48 +0000142 throws InterruptedException {
143 DirtyingNodeVisitor visitor =
144 createInvalidatingVisitorIfNeeded(
Mark Schallerc6ed6132015-11-24 15:45:40 +0000145 graph,
146 diff,
Googlerc4e22552016-09-27 15:44:40 +0000147 progressReceiver,
Mark Schallerc6ed6132015-11-24 15:45:40 +0000148 state,
149 dirtyKeyTracker,
150 forkJoinPool,
Nathan Harmata3724d922016-05-26 19:56:24 +0000151 supportInterruptions,
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000152 ErrorHandler.NullHandler.INSTANCE);
Mark Schaller454bc6d2015-11-03 19:12:48 +0000153 if (visitor != null) {
154 visitor.run();
155 }
156 }
157
Janak Ramakrishnancc7712f2016-07-08 17:38:27 +0000158 /** Invalidates given values and their upward transitive closure in the graph. */
Mark Schaller454bc6d2015-11-03 19:12:48 +0000159 public static void invalidate(
Nathan Harmata33faf912016-08-10 19:15:15 +0000160 QueryableGraph graph,
Mark Schaller454bc6d2015-11-03 19:12:48 +0000161 Iterable<SkyKey> diff,
Googlerc4e22552016-09-27 15:44:40 +0000162 EvaluationProgressReceiver progressReceiver,
Mark Schaller454bc6d2015-11-03 19:12:48 +0000163 InvalidationState state,
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100164 DirtyKeyTracker dirtyKeyTracker)
Mark Schallere3c88de2015-08-05 22:02:59 +0000165 throws InterruptedException {
Googlerc4e22552016-09-27 15:44:40 +0000166 invalidate(graph, diff, progressReceiver, state, dirtyKeyTracker,
Mark Schallere3c88de2015-08-05 22:02:59 +0000167 AbstractQueueVisitor.EXECUTOR_FACTORY);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100168 }
Mark Schallere3c88de2015-08-05 22:02:59 +0000169
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100170}