Damien Martin-Guillerez | f88f4d8 | 2015-09-25 13:56:55 +0000 | [diff] [blame] | 1 | // Copyright 2015 The Bazel Authors. All rights reserved. |
Janak Ramakrishnan | e72d522 | 2015-02-26 17:09:18 +0000 | [diff] [blame] | 2 | // |
| 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. |
| 14 | package com.google.devtools.build.skyframe; |
| 15 | |
Eric Fellheimer | 6f8b7ce | 2016-01-29 00:15:44 +0000 | [diff] [blame] | 16 | import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; |
Klaus Aehlig | 777b30d | 2017-02-24 16:30:15 +0000 | [diff] [blame] | 17 | import com.google.devtools.build.lib.events.ExtendedEventHandler; |
Googler | 2dd4c18 | 2016-10-31 14:54:37 +0000 | [diff] [blame] | 18 | import com.google.devtools.build.skyframe.QueryableGraph.Reason; |
Janak Ramakrishnan | e72d522 | 2015-02-26 17:09:18 +0000 | [diff] [blame] | 19 | import java.util.Collection; |
Janak Ramakrishnan | 3685873 | 2015-06-17 16:45:47 +0000 | [diff] [blame] | 20 | import java.util.Map; |
Googler | 5e65c98 | 2017-08-17 05:21:54 +0200 | [diff] [blame] | 21 | import java.util.Set; |
Janak Ramakrishnan | e72d522 | 2015-02-26 17:09:18 +0000 | [diff] [blame] | 22 | import javax.annotation.Nullable; |
| 23 | |
| 24 | /** |
| 25 | * Read-only graph that exposes the dependents, dependencies (reverse dependents), and value and |
| 26 | * exception (if any) of a given node. |
Janak Ramakrishnan | 3c0adb2 | 2016-08-15 21:54:55 +0000 | [diff] [blame] | 27 | * |
| 28 | * <p>Certain graph implementations can throw {@link InterruptedException} when trying to retrieve |
| 29 | * node entries. Such exceptions should not be caught locally -- they should be allowed to propagate |
| 30 | * up. |
Janak Ramakrishnan | e72d522 | 2015-02-26 17:09:18 +0000 | [diff] [blame] | 31 | */ |
Eric Fellheimer | 6f8b7ce | 2016-01-29 00:15:44 +0000 | [diff] [blame] | 32 | @ThreadSafe |
Janak Ramakrishnan | e72d522 | 2015-02-26 17:09:18 +0000 | [diff] [blame] | 33 | public interface WalkableGraph { |
Janak Ramakrishnan | e72d522 | 2015-02-26 17:09:18 +0000 | [diff] [blame] | 34 | /** |
| 35 | * Returns the value of the given key, or {@code null} if it has no value due to an error during |
Janak Ramakrishnan | 112840b | 2016-12-29 21:49:56 +0000 | [diff] [blame] | 36 | * its computation or it is not done in the graph. |
| 37 | * |
| 38 | * <p>A node that is done in the graph must have either a non-null getValue, a non-null {@link |
| 39 | * #getException}, or a true {@link #isCycle}. |
| 40 | * |
| 41 | * <p>These three methods should all be reading the same {@link |
| 42 | * NodeEntry#getValueMaybeWithMetadata} value internally, so once that value is indirectly |
| 43 | * retrieved via one of these methods, the others can read it for free. This is relevant for graph |
| 44 | * implementations that may throw an {@link InterruptedException} on retrieving entries and value. |
Janak Ramakrishnan | e72d522 | 2015-02-26 17:09:18 +0000 | [diff] [blame] | 45 | */ |
| 46 | @Nullable |
Janak Ramakrishnan | 3c0adb2 | 2016-08-15 21:54:55 +0000 | [diff] [blame] | 47 | SkyValue getValue(SkyKey key) throws InterruptedException; |
Janak Ramakrishnan | e72d522 | 2015-02-26 17:09:18 +0000 | [diff] [blame] | 48 | |
| 49 | /** |
Miguel Alcon Pinto | 4582087 | 2015-09-11 19:57:47 +0000 | [diff] [blame] | 50 | * Returns a map giving the values of the given keys for done keys that were successfully |
Janak Ramakrishnan | 3c0adb2 | 2016-08-15 21:54:55 +0000 | [diff] [blame] | 51 | * computed. Or in other words, it filters out non-existent nodes, pending nodes and nodes that |
| 52 | * produced an exception. |
Janak Ramakrishnan | 3685873 | 2015-06-17 16:45:47 +0000 | [diff] [blame] | 53 | */ |
Janak Ramakrishnan | 3c0adb2 | 2016-08-15 21:54:55 +0000 | [diff] [blame] | 54 | Map<SkyKey, SkyValue> getSuccessfulValues(Iterable<SkyKey> keys) throws InterruptedException; |
Janak Ramakrishnan | f6f0fcc | 2015-06-19 20:24:52 +0000 | [diff] [blame] | 55 | |
| 56 | /** |
| 57 | * Returns a map giving exceptions associated to the given keys for done keys. Keys not present in |
| 58 | * the graph or whose nodes are not done will be present in the returned map, with null value. In |
| 59 | * other words, if {@code key} is in {@param keys}, then the returned map will contain an entry |
| 60 | * for {@code key} if and only if the node for {@code key} did <i>not</i> evaluate successfully |
| 61 | * without error. |
| 62 | */ |
Janak Ramakrishnan | 3c0adb2 | 2016-08-15 21:54:55 +0000 | [diff] [blame] | 63 | Map<SkyKey, Exception> getMissingAndExceptions(Iterable<SkyKey> keys) throws InterruptedException; |
Janak Ramakrishnan | 3685873 | 2015-06-17 16:45:47 +0000 | [diff] [blame] | 64 | |
| 65 | /** |
Janak Ramakrishnan | e72d522 | 2015-02-26 17:09:18 +0000 | [diff] [blame] | 66 | * Returns the exception thrown when computing the node with the given key, if any. If the node |
Janak Ramakrishnan | 112840b | 2016-12-29 21:49:56 +0000 | [diff] [blame] | 67 | * was computed successfully, depends on a cycle without any other error, or is not done in the |
| 68 | * graph, returns null. |
Janak Ramakrishnan | e72d522 | 2015-02-26 17:09:18 +0000 | [diff] [blame] | 69 | */ |
Janak Ramakrishnan | 3c0adb2 | 2016-08-15 21:54:55 +0000 | [diff] [blame] | 70 | @Nullable |
| 71 | Exception getException(SkyKey key) throws InterruptedException; |
Janak Ramakrishnan | e72d522 | 2015-02-26 17:09:18 +0000 | [diff] [blame] | 72 | |
| 73 | /** |
Janak Ramakrishnan | 112840b | 2016-12-29 21:49:56 +0000 | [diff] [blame] | 74 | * Returns true if the node with the given {@code key} depends on a cycle. Returns false if the |
| 75 | * node does not depend on a cycle, or is not done in the graph. |
| 76 | */ |
| 77 | boolean isCycle(SkyKey key) throws InterruptedException; |
| 78 | |
| 79 | /** |
Janak Ramakrishnan | cda5b66 | 2015-06-18 23:46:36 +0000 | [diff] [blame] | 80 | * Returns a map giving the direct dependencies of the nodes with the given keys. A node for each |
Janak Ramakrishnan | 112840b | 2016-12-29 21:49:56 +0000 | [diff] [blame] | 81 | * given key must be done in the graph if it exists. |
Janak Ramakrishnan | e72d522 | 2015-02-26 17:09:18 +0000 | [diff] [blame] | 82 | */ |
Janak Ramakrishnan | 3c0adb2 | 2016-08-15 21:54:55 +0000 | [diff] [blame] | 83 | Map<SkyKey, Iterable<SkyKey>> getDirectDeps(Iterable<SkyKey> keys) throws InterruptedException; |
Janak Ramakrishnan | 3685873 | 2015-06-17 16:45:47 +0000 | [diff] [blame] | 84 | |
Janak Ramakrishnan | 3685873 | 2015-06-17 16:45:47 +0000 | [diff] [blame] | 85 | /** |
Janak Ramakrishnan | cda5b66 | 2015-06-18 23:46:36 +0000 | [diff] [blame] | 86 | * Returns a map giving the reverse dependencies of the nodes with the given keys. A node for each |
Janak Ramakrishnan | 112840b | 2016-12-29 21:49:56 +0000 | [diff] [blame] | 87 | * given key must be done in the graph if it exists. |
Janak Ramakrishnan | 3685873 | 2015-06-17 16:45:47 +0000 | [diff] [blame] | 88 | */ |
Janak Ramakrishnan | 3c0adb2 | 2016-08-15 21:54:55 +0000 | [diff] [blame] | 89 | Map<SkyKey, Iterable<SkyKey>> getReverseDeps(Iterable<SkyKey> keys) throws InterruptedException; |
Janak Ramakrishnan | 3685873 | 2015-06-17 16:45:47 +0000 | [diff] [blame] | 90 | |
Googler | 2dd4c18 | 2016-10-31 14:54:37 +0000 | [diff] [blame] | 91 | /** |
| 92 | * Examines all the given keys. Returns an iterable of keys whose corresponding nodes are |
| 93 | * currently available to be fetched. |
| 94 | * |
| 95 | * <p>Note: An unavailable node does not mean it is not in the graph. It only means it's not ready |
| 96 | * to be fetched immediately. |
| 97 | */ |
| 98 | Iterable<SkyKey> getCurrentlyAvailableNodes(Iterable<SkyKey> keys, Reason reason); |
| 99 | |
Janak Ramakrishnan | e72d522 | 2015-02-26 17:09:18 +0000 | [diff] [blame] | 100 | /** Provides a WalkableGraph on demand after preparing it. */ |
| 101 | interface WalkableGraphFactory { |
Janak Ramakrishnan | 18d0a5d | 2016-11-16 19:35:48 +0000 | [diff] [blame] | 102 | EvaluationResult<SkyValue> prepareAndGet( |
Googler | 5e65c98 | 2017-08-17 05:21:54 +0200 | [diff] [blame] | 103 | Set<SkyKey> roots, int numThreads, ExtendedEventHandler eventHandler) |
Klaus Aehlig | 777b30d | 2017-02-24 16:30:15 +0000 | [diff] [blame] | 104 | throws InterruptedException; |
Janak Ramakrishnan | 958ef82 | 2016-01-07 16:21:39 +0000 | [diff] [blame] | 105 | |
| 106 | /** Returns the {@link SkyKey} that defines this universe. */ |
| 107 | SkyKey getUniverseKey(Collection<String> roots, String offset); |
Janak Ramakrishnan | e72d522 | 2015-02-26 17:09:18 +0000 | [diff] [blame] | 108 | } |
| 109 | } |