Add method getCurrentlyAvailableNodes to QueryableGraph and Walkable Graph
It allows all graph implementations to return the list of nodes which are
immediately available to be fetched. NOTE: Not-currently-available here does
not mean the nodes do not exist in the graph. It simply means they are not
ready to be fetched immediately yet.
--
MOS_MIGRATED_REVID=137701432
diff --git a/src/main/java/com/google/devtools/build/skyframe/DelegatingWalkableGraph.java b/src/main/java/com/google/devtools/build/skyframe/DelegatingWalkableGraph.java
index 5c22a05..27475db 100644
--- a/src/main/java/com/google/devtools/build/skyframe/DelegatingWalkableGraph.java
+++ b/src/main/java/com/google/devtools/build/skyframe/DelegatingWalkableGraph.java
@@ -126,4 +126,9 @@
return result;
}
+ @Override
+ public Iterable<SkyKey> getCurrentlyAvailableNodes(Iterable<SkyKey> keys, Reason reason) {
+ return graph.getCurrentlyAvailableNodes(keys, reason);
+ }
+
}
diff --git a/src/main/java/com/google/devtools/build/skyframe/InMemoryGraphImpl.java b/src/main/java/com/google/devtools/build/skyframe/InMemoryGraphImpl.java
index 77b1259..71c3ad3 100644
--- a/src/main/java/com/google/devtools/build/skyframe/InMemoryGraphImpl.java
+++ b/src/main/java/com/google/devtools/build/skyframe/InMemoryGraphImpl.java
@@ -17,6 +17,7 @@
import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;
import java.util.Collections;
@@ -127,4 +128,15 @@
boolean keepsEdges() {
return keepEdges;
}
+
+ @Override
+ public Iterable<SkyKey> getCurrentlyAvailableNodes(Iterable<SkyKey> keys, Reason reason) {
+ ImmutableSet.Builder<SkyKey> builder = ImmutableSet.builder();
+ for (SkyKey key : keys) {
+ if (get(null, reason, key) != null) {
+ builder.add(key);
+ }
+ }
+ return builder.build();
+ }
}
diff --git a/src/main/java/com/google/devtools/build/skyframe/QueryableGraph.java b/src/main/java/com/google/devtools/build/skyframe/QueryableGraph.java
index 0286844..7c4971e 100644
--- a/src/main/java/com/google/devtools/build/skyframe/QueryableGraph.java
+++ b/src/main/java/com/google/devtools/build/skyframe/QueryableGraph.java
@@ -49,6 +49,17 @@
@Nullable SkyKey requestor, Reason reason, Iterable<SkyKey> keys) throws InterruptedException;
/**
+ * Examines all the given keys. Returns an iterable of keys whose corresponding nodes are
+ * currently available to be fetched.
+ *
+ * <p>Note: An unavailable node does not mean it is not in the graph. It only means it's not ready
+ * to be fetched immediately.
+ *
+ * @param reason the reason the nodes are being requested.
+ */
+ Iterable<SkyKey> getCurrentlyAvailableNodes(Iterable<SkyKey> keys, Reason reason);
+
+ /**
* The reason that a node is being looked up in the Skyframe graph.
*
* <p>Alternate graph implementations may wish to make use of this information.
diff --git a/src/main/java/com/google/devtools/build/skyframe/WalkableGraph.java b/src/main/java/com/google/devtools/build/skyframe/WalkableGraph.java
index 9f71f1f..240ea7c 100644
--- a/src/main/java/com/google/devtools/build/skyframe/WalkableGraph.java
+++ b/src/main/java/com/google/devtools/build/skyframe/WalkableGraph.java
@@ -15,6 +15,7 @@
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import com.google.devtools.build.lib.events.EventHandler;
+import com.google.devtools.build.skyframe.QueryableGraph.Reason;
import java.util.Collection;
import java.util.Map;
import javax.annotation.Nullable;
@@ -80,6 +81,15 @@
*/
Map<SkyKey, Iterable<SkyKey>> getReverseDeps(Iterable<SkyKey> keys) throws InterruptedException;
+ /**
+ * Examines all the given keys. Returns an iterable of keys whose corresponding nodes are
+ * currently available to be fetched.
+ *
+ * <p>Note: An unavailable node does not mean it is not in the graph. It only means it's not ready
+ * to be fetched immediately.
+ */
+ Iterable<SkyKey> getCurrentlyAvailableNodes(Iterable<SkyKey> keys, Reason reason);
+
/** Provides a WalkableGraph on demand after preparing it. */
interface WalkableGraphFactory {
EvaluationResult<SkyValue> prepareAndGet(Collection<String> roots, String offset,
diff --git a/src/test/java/com/google/devtools/build/skyframe/GraphConcurrencyTest.java b/src/test/java/com/google/devtools/build/skyframe/GraphTest.java
similarity index 96%
rename from src/test/java/com/google/devtools/build/skyframe/GraphConcurrencyTest.java
rename to src/test/java/com/google/devtools/build/skyframe/GraphTest.java
index 6490835..0510523 100644
--- a/src/test/java/com/google/devtools/build/skyframe/GraphConcurrencyTest.java
+++ b/src/test/java/com/google/devtools/build/skyframe/GraphTest.java
@@ -43,8 +43,8 @@
import org.junit.Before;
import org.junit.Test;
-/** Base class for concurrency sanity tests on {@link EvaluableGraph} implementations. */
-public abstract class GraphConcurrencyTest {
+/** Base class for sanity tests on {@link EvaluableGraph} implementations. */
+public abstract class GraphTest {
private static final SkyFunctionName SKY_FUNCTION_NAME = SkyFunctionName.FOR_TESTING;
protected ProcessableGraph graph;
@@ -154,8 +154,9 @@
@Test
public void testAddRemoveRdeps() throws Exception {
SkyKey key = key("foo");
- final NodeEntry entry = Iterables.getOnlyElement(
- graph.createIfAbsentBatch(null, Reason.OTHER, ImmutableList.of(key)).values());
+ final NodeEntry entry =
+ Iterables.getOnlyElement(
+ graph.createIfAbsentBatch(null, Reason.OTHER, ImmutableList.of(key)).values());
// These numbers are arbitrary.
int numThreads = 50;
int numKeys = numThreads;
@@ -459,6 +460,19 @@
}
}
+ @Test
+ public void testGetCurrentlyAvailableNodes() throws Exception {
+ SkyKey foo = key("foo");
+ SkyKey bar = key("bar");
+ SkyKey foobar = key("foobar");
+ graph.createIfAbsentBatch(null, Reason.OTHER, ImmutableList.of(foo, bar));
+
+ Iterable<SkyKey> currentlyAvailable =
+ graph.getCurrentlyAvailableNodes(ImmutableList.of(foo, bar, foobar), Reason.OTHER);
+
+ assertThat(currentlyAvailable).containsExactly(foo, bar);
+ }
+
private static DependencyState startEvaluation(NodeEntry entry) throws InterruptedException {
return entry.addReverseDepAndCheckIfDone(null);
}
diff --git a/src/test/java/com/google/devtools/build/skyframe/InMemoryGraphConcurrencyTest.java b/src/test/java/com/google/devtools/build/skyframe/InMemoryGraphTest.java
similarity index 90%
rename from src/test/java/com/google/devtools/build/skyframe/InMemoryGraphConcurrencyTest.java
rename to src/test/java/com/google/devtools/build/skyframe/InMemoryGraphTest.java
index 18d6875..0180391 100644
--- a/src/test/java/com/google/devtools/build/skyframe/InMemoryGraphConcurrencyTest.java
+++ b/src/test/java/com/google/devtools/build/skyframe/InMemoryGraphTest.java
@@ -14,13 +14,12 @@
package com.google.devtools.build.skyframe;
import com.google.devtools.build.lib.util.Preconditions;
-
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
-/** Concurrency tests for {@link InMemoryGraphImpl}. */
+/** Tests for {@link InMemoryGraphImpl}. */
@RunWith(JUnit4.class)
-public class InMemoryGraphConcurrencyTest extends GraphConcurrencyTest {
+public class InMemoryGraphTest extends GraphTest {
private ProcessableGraph graph;
@Override
diff --git a/src/test/java/com/google/devtools/build/skyframe/NotifyingHelper.java b/src/test/java/com/google/devtools/build/skyframe/NotifyingHelper.java
index 6cde573..559b3cf 100644
--- a/src/test/java/com/google/devtools/build/skyframe/NotifyingHelper.java
+++ b/src/test/java/com/google/devtools/build/skyframe/NotifyingHelper.java
@@ -100,6 +100,11 @@
throws InterruptedException {
return notifyingHelper.wrapEntry(key, delegate.get(requestor, reason, key));
}
+
+ @Override
+ public Iterable<SkyKey> getCurrentlyAvailableNodes(Iterable<SkyKey> keys, Reason reason) {
+ return delegate.getCurrentlyAvailableNodes(keys, reason);
+ }
}
static class NotifyingProcessableGraph