aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Janak Ramakrishnan <janakr@google.com>2016-05-13 21:14:56 +0000
committerGravatar Kristina Chodorow <kchodorow@google.com>2016-05-16 15:16:42 +0000
commit3b5d5d22f27fa8d9297fdf39b5b18d1bb6ea8e57 (patch)
treee0503976694a62a8365403abc888f33c76fb8e3a
parenta56c1f4a1b47131b6d366a658f1f1e5abe0cdf3d (diff)
Stop converting temporary direct deps to a set. In almost all cases, this conversion is unnecessary and wasteful. In the remaining cases, the set conversion can be explicit.
-- MOS_MIGRATED_REVID=122294939
-rw-r--r--src/main/java/com/google/devtools/build/lib/util/GroupedList.java17
-rw-r--r--src/main/java/com/google/devtools/build/skyframe/BuildingState.java4
-rw-r--r--src/main/java/com/google/devtools/build/skyframe/DelegatingNodeEntry.java3
-rw-r--r--src/main/java/com/google/devtools/build/skyframe/InMemoryNodeEntry.java7
-rw-r--r--src/main/java/com/google/devtools/build/skyframe/InvalidatingNodeVisitor.java4
-rw-r--r--src/main/java/com/google/devtools/build/skyframe/NodeEntry.java7
-rw-r--r--src/main/java/com/google/devtools/build/skyframe/ParallelEvaluator.java83
-rw-r--r--src/test/java/com/google/devtools/build/skyframe/DeterministicGraph.java7
-rw-r--r--src/test/java/com/google/devtools/build/skyframe/InMemoryNodeEntryTest.java14
-rw-r--r--src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java8
-rw-r--r--src/test/java/com/google/devtools/build/skyframe/NodeEntrySubject.java20
11 files changed, 108 insertions, 66 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/util/GroupedList.java b/src/main/java/com/google/devtools/build/lib/util/GroupedList.java
index 393b05dc5a..7f0db7839c 100644
--- a/src/main/java/com/google/devtools/build/lib/util/GroupedList.java
+++ b/src/main/java/com/google/devtools/build/lib/util/GroupedList.java
@@ -122,6 +122,23 @@ public class GroupedList<T> implements Iterable<Collection<T>> {
return elements.isEmpty();
}
+ /**
+ * Returns true if this list contains {@code needle}. Takes time proportional to list size. Call
+ * {@link #toSet} instead and use the result if doing multiple contains checks.
+ */
+ public boolean expensiveContains(T needle) {
+ for (Object obj : elements) {
+ if (obj instanceof List) {
+ if (((List) obj).contains(needle)) {
+ return true;
+ }
+ } else if (obj.equals(needle)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private static final Object EMPTY_LIST = new Object();
public Object compress() {
diff --git a/src/main/java/com/google/devtools/build/skyframe/BuildingState.java b/src/main/java/com/google/devtools/build/skyframe/BuildingState.java
index 9b4a9720a3..95a7ca8ae5 100644
--- a/src/main/java/com/google/devtools/build/skyframe/BuildingState.java
+++ b/src/main/java/com/google/devtools/build/skyframe/BuildingState.java
@@ -388,8 +388,8 @@ public class BuildingState {
*
* @see NodeEntry#getTemporaryDirectDeps()
*/
- Set<SkyKey> getDirectDepsForBuild() {
- return directDeps.toSet();
+ GroupedList<SkyKey> getDirectDepsForBuild() {
+ return directDeps;
}
/**
diff --git a/src/main/java/com/google/devtools/build/skyframe/DelegatingNodeEntry.java b/src/main/java/com/google/devtools/build/skyframe/DelegatingNodeEntry.java
index 52b2ffba2a..4215f0e495 100644
--- a/src/main/java/com/google/devtools/build/skyframe/DelegatingNodeEntry.java
+++ b/src/main/java/com/google/devtools/build/skyframe/DelegatingNodeEntry.java
@@ -13,6 +13,7 @@
// limitations under the License.
package com.google.devtools.build.skyframe;
+import com.google.devtools.build.lib.util.GroupedList;
import com.google.devtools.build.lib.util.GroupedList.GroupedListHelper;
import java.util.Collection;
@@ -120,7 +121,7 @@ public abstract class DelegatingNodeEntry implements NodeEntry {
}
@Override
- public Set<SkyKey> getTemporaryDirectDeps() {
+ public GroupedList<SkyKey> getTemporaryDirectDeps() {
return getDelegate().getTemporaryDirectDeps();
}
diff --git a/src/main/java/com/google/devtools/build/skyframe/InMemoryNodeEntry.java b/src/main/java/com/google/devtools/build/skyframe/InMemoryNodeEntry.java
index 7b885b8ebd..56bcd05024 100644
--- a/src/main/java/com/google/devtools/build/skyframe/InMemoryNodeEntry.java
+++ b/src/main/java/com/google/devtools/build/skyframe/InMemoryNodeEntry.java
@@ -415,10 +415,11 @@ public class InMemoryNodeEntry implements NodeEntry {
public synchronized Iterable<SkyKey> getAllDirectDepsForIncompleteNode() {
Preconditions.checkState(!isDone(), this);
if (!isDirty()) {
- return getTemporaryDirectDeps();
+ return Iterables.concat(getTemporaryDirectDeps());
} else {
return Iterables.concat(
- getTemporaryDirectDeps(), buildingState.getAllRemainingDirtyDirectDeps());
+ Iterables.concat(getTemporaryDirectDeps()),
+ buildingState.getAllRemainingDirtyDirectDeps());
}
}
@@ -428,7 +429,7 @@ public class InMemoryNodeEntry implements NodeEntry {
}
@Override
- public synchronized Set<SkyKey> getTemporaryDirectDeps() {
+ public synchronized GroupedList<SkyKey> getTemporaryDirectDeps() {
Preconditions.checkState(!isDone(), "temporary shouldn't be done: %s", this);
return buildingState.getDirectDepsForBuild();
}
diff --git a/src/main/java/com/google/devtools/build/skyframe/InvalidatingNodeVisitor.java b/src/main/java/com/google/devtools/build/skyframe/InvalidatingNodeVisitor.java
index 06ff375fae..cdda90ea9f 100644
--- a/src/main/java/com/google/devtools/build/skyframe/InvalidatingNodeVisitor.java
+++ b/src/main/java/com/google/devtools/build/skyframe/InvalidatingNodeVisitor.java
@@ -297,7 +297,9 @@ public abstract class InvalidatingNodeVisitor<TGraph extends ThinNodeQueryableGr
// child -- because of our compact storage of rdeps, checking which list
// contains this parent could be expensive.
Set<SkyKey> signalingDeps =
- entry.isDone() ? ImmutableSet.<SkyKey>of() : entry.getTemporaryDirectDeps();
+ entry.isDone()
+ ? ImmutableSet.<SkyKey>of()
+ : entry.getTemporaryDirectDeps().toSet();
Iterable<SkyKey> directDeps =
entry.isDone()
? entry.getDirectDeps()
diff --git a/src/main/java/com/google/devtools/build/skyframe/NodeEntry.java b/src/main/java/com/google/devtools/build/skyframe/NodeEntry.java
index d9f5c87676..924771a232 100644
--- a/src/main/java/com/google/devtools/build/skyframe/NodeEntry.java
+++ b/src/main/java/com/google/devtools/build/skyframe/NodeEntry.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.skyframe;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
+import com.google.devtools.build.lib.util.GroupedList;
import com.google.devtools.build.lib.util.GroupedList.GroupedListHelper;
import java.util.Collection;
@@ -284,11 +285,11 @@ public interface NodeEntry extends ThinNodeEntry {
Collection<SkyKey> markRebuildingAndGetAllRemainingDirtyDirectDeps();
/**
- * Returns the set of direct dependencies. This may only be called while the node is being
- * evaluated, that is, before {@link #setValue} and after {@link #markDirty}.
+ * Returns the {@link GroupedList} of direct dependencies. This may only be called while the node
+ * is being evaluated, that is, before {@link #setValue} and after {@link #markDirty}.
*/
@ThreadSafe
- Set<SkyKey> getTemporaryDirectDeps();
+ GroupedList<SkyKey> getTemporaryDirectDeps();
@ThreadSafe
boolean noDepsLastBuild();
diff --git a/src/main/java/com/google/devtools/build/skyframe/ParallelEvaluator.java b/src/main/java/com/google/devtools/build/skyframe/ParallelEvaluator.java
index 51c393a8b6..74ba24c999 100644
--- a/src/main/java/com/google/devtools/build/skyframe/ParallelEvaluator.java
+++ b/src/main/java/com/google/devtools/build/skyframe/ParallelEvaluator.java
@@ -39,6 +39,7 @@ import com.google.devtools.build.lib.events.StoredEventHandler;
import com.google.devtools.build.lib.profiler.Profiler;
import com.google.devtools.build.lib.profiler.ProfilerTask;
import com.google.devtools.build.lib.util.BlazeClock;
+import com.google.devtools.build.lib.util.GroupedList;
import com.google.devtools.build.lib.util.GroupedList.GroupedListHelper;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.skyframe.EvaluationProgressReceiver.EvaluationState;
@@ -268,25 +269,36 @@ public final class ParallelEvaluator implements Evaluator {
}
};
- private SkyFunctionEnvironment(SkyKey skyKey, Set<SkyKey> directDeps, ValueVisitor visitor) {
+ private SkyFunctionEnvironment(
+ SkyKey skyKey, GroupedList<SkyKey> directDeps, ValueVisitor visitor) {
this(skyKey, directDeps, null, visitor);
}
- private SkyFunctionEnvironment(SkyKey skyKey, Set<SkyKey> directDeps,
- @Nullable Map<SkyKey, ValueWithMetadata> bubbleErrorInfo, ValueVisitor visitor) {
+ private SkyFunctionEnvironment(
+ SkyKey skyKey,
+ GroupedList<SkyKey> directDeps,
+ @Nullable Map<SkyKey, ValueWithMetadata> bubbleErrorInfo,
+ ValueVisitor visitor) {
this.skyKey = skyKey;
this.directDeps = Collections.unmodifiableMap(
batchPrefetch(directDeps, /*assertDone=*/bubbleErrorInfo == null, skyKey));
this.bubbleErrorInfo = bubbleErrorInfo;
this.visitor = visitor;
+ Preconditions.checkState(
+ !this.directDeps.containsKey(ErrorTransienceValue.KEY),
+ "%s cannot have a dep on ErrorTransienceValue during building",
+ skyKey);
}
private Map<SkyKey, NodeEntry> batchPrefetch(
- Set<SkyKey> keys, boolean assertDone, SkyKey keyForDebugging) {
- Map<SkyKey, NodeEntry> batchMap = graph.getBatch(keys);
- if (batchMap.size() != keys.size()) {
- throw new IllegalStateException("Missing keys for " + keyForDebugging + ": "
- + Sets.difference(keys, batchMap.keySet()));
+ GroupedList<SkyKey> keys, boolean assertDone, SkyKey keyForDebugging) {
+ Map<SkyKey, NodeEntry> batchMap = graph.getBatch(Iterables.concat(keys));
+ if (batchMap.size() != keys.numElements()) {
+ throw new IllegalStateException(
+ "Missing keys for "
+ + keyForDebugging
+ + ": "
+ + Sets.difference(keys.toSet(), batchMap.keySet()));
}
if (assertDone) {
for (Map.Entry<SkyKey, NodeEntry> entry : batchMap.entrySet()) {
@@ -311,14 +323,16 @@ public final class ParallelEvaluator implements Evaluator {
}
if (storedEventFilter.storeEvents()) {
// Only do the work of processing children if we're going to store events.
- Set<SkyKey> depKeys = graph.get(skyKey).getTemporaryDirectDeps();
- Map<SkyKey, SkyValue> deps = getValuesMaybeFromError(depKeys, bubbleErrorInfo);
- if (!missingChildren && depKeys.size() != deps.size()) {
+ GroupedList<SkyKey> depKeys = graph.get(skyKey).getTemporaryDirectDeps();
+ Map<SkyKey, SkyValue> deps =
+ getValuesMaybeFromError(
+ Iterables.concat(depKeys), bubbleErrorInfo, depKeys.numElements());
+ if (!missingChildren && depKeys.numElements() != deps.size()) {
throw new IllegalStateException(
"Missing keys for "
+ skyKey
+ ": "
- + Sets.difference(depKeys, deps.keySet())
+ + Sets.difference(depKeys.toSet(), deps.keySet())
+ ", "
+ graph.get(skyKey));
}
@@ -388,9 +402,11 @@ public final class ParallelEvaluator implements Evaluator {
}
private Map<SkyKey, SkyValue> getValuesMaybeFromError(
- Set<SkyKey> keys, @Nullable Map<SkyKey, ValueWithMetadata> bubbleErrorInfo) {
+ Iterable<SkyKey> keys,
+ @Nullable Map<SkyKey, ValueWithMetadata> bubbleErrorInfo,
+ int keySize) {
ImmutableMap.Builder<SkyKey, SkyValue> builder = ImmutableMap.builder();
- ArrayList<SkyKey> missingKeys = new ArrayList<>(keys.size());
+ ArrayList<SkyKey> missingKeys = new ArrayList<>(keySize);
for (SkyKey key : keys) {
NodeEntry entry = directDeps.get(key);
if (entry != null) {
@@ -417,7 +433,8 @@ public final class ParallelEvaluator implements Evaluator {
!depKeys.contains(ErrorTransienceValue.KEY),
"Error transience key cannot be in requested deps of %s",
skyKey);
- Map<SkyKey, SkyValue> values = getValuesMaybeFromError(depKeys, bubbleErrorInfo);
+ Map<SkyKey, SkyValue> values =
+ getValuesMaybeFromError(depKeys, bubbleErrorInfo, depKeys.size());
for (Map.Entry<SkyKey, SkyValue> depEntry : values.entrySet()) {
SkyKey depKey = depEntry.getKey();
SkyValue depValue = depEntry.getValue();
@@ -933,16 +950,9 @@ public final class ParallelEvaluator implements Evaluator {
return;
}
- // TODO(bazel-team): Once deps are requested in a deterministic order within a group, or the
- // framework is resilient to rearranging group order, change this so that
- // SkyFunctionEnvironment "follows along" as the node builder runs, iterating through the
- // direct deps that were requested on a previous run. This would allow us to avoid the
- // conversion of the direct deps into a set.
- Set<SkyKey> directDeps = state.getTemporaryDirectDeps();
- Preconditions.checkState(!directDeps.contains(ErrorTransienceValue.KEY),
- "%s cannot have a dep on ErrorTransienceValue during building: %s", skyKey, state);
// Get the corresponding SkyFunction and call it on this value.
- SkyFunctionEnvironment env = new SkyFunctionEnvironment(skyKey, directDeps, visitor);
+ SkyFunctionEnvironment env =
+ new SkyFunctionEnvironment(skyKey, state.getTemporaryDirectDeps(), visitor);
SkyFunctionName functionName = skyKey.functionName();
SkyFunction factory = skyFunctions.get(functionName);
Preconditions.checkState(factory != null,
@@ -1038,8 +1048,8 @@ public final class ParallelEvaluator implements Evaluator {
NodeEntry childErrorEntry = Preconditions.checkNotNull(graph.get(childErrorKey),
"skyKey: %s, state: %s childErrorKey: %s", skyKey, state, childErrorKey);
Preconditions.checkState(
- !state.getTemporaryDirectDeps().contains(childErrorKey),
- "Done error was already know: %s %s %s %s",
+ !state.getTemporaryDirectDeps().expensiveContains(childErrorKey),
+ "Done error was already known: %s %s %s %s",
skyKey,
state,
childErrorKey,
@@ -1448,7 +1458,7 @@ public final class ParallelEvaluator implements Evaluator {
continue;
}
if (visitor.isInflight(bubbleParent)
- && bubbleParentEntry.getTemporaryDirectDeps().contains(errorKey)) {
+ && bubbleParentEntry.getTemporaryDirectDeps().expensiveContains(errorKey)) {
// Only bubble up to parent if it's part of this build. If this node was dirtied and
// re-evaluated, but in a build without this parent, we may try to bubble up to that
// parent. Don't -- it's not part of the build.
@@ -1488,7 +1498,7 @@ public final class ParallelEvaluator implements Evaluator {
}
}
SkyFunctionEnvironment env =
- new SkyFunctionEnvironment(parent, ImmutableSet.<SkyKey>of(), bubbleErrorInfo, visitor);
+ new SkyFunctionEnvironment(parent, new GroupedList<SkyKey>(), bubbleErrorInfo, visitor);
externalInterrupt = externalInterrupt || Thread.currentThread().isInterrupted();
try {
// This build is only to check if the parent node can give us a better error. We don't
@@ -1701,12 +1711,13 @@ public final class ParallelEvaluator implements Evaluator {
// error.
Preconditions.checkState(entry.isReady(), "%s not ready. ValueEntry: %s", key, entry);
} else if (!entry.isReady()) {
- removeIncompleteChildrenForCycle(key, entry, entry.getTemporaryDirectDeps());
+ removeIncompleteChildrenForCycle(
+ key, entry, Iterables.concat(entry.getTemporaryDirectDeps()));
}
maybeMarkRebuildingAndRemoveRemainingDirtyDirectDeps(key, entry);
- Set<SkyKey> directDeps = entry.getTemporaryDirectDeps();
+ GroupedList<SkyKey> directDeps = entry.getTemporaryDirectDeps();
// Find out which children have errors. Similar logic to that in Evaluate#run().
- List<ErrorInfo> errorDeps = getChildrenErrorsForCycle(directDeps);
+ List<ErrorInfo> errorDeps = getChildrenErrorsForCycle(Iterables.concat(directDeps));
Preconditions.checkState(!errorDeps.isEmpty(),
"Value %s was not successfully evaluated, but had no child errors. ValueEntry: %s", key,
entry);
@@ -1758,7 +1769,9 @@ public final class ParallelEvaluator implements Evaluator {
// Construct error info for this node. Get errors from children, which are all done
// except possibly for the cycleChild.
List<ErrorInfo> allErrors =
- getChildrenErrors(entry.getTemporaryDirectDeps(), /*unfinishedChild=*/cycleChild);
+ getChildrenErrors(
+ Iterables.concat(entry.getTemporaryDirectDeps()), /*unfinishedChild=*/
+ cycleChild);
CycleInfo cycleInfo = new CycleInfo(cycle);
// Add in this cycle.
allErrors.add(ErrorInfo.fromCycle(cycleInfo));
@@ -1775,7 +1788,7 @@ public final class ParallelEvaluator implements Evaluator {
}
// This node is not yet known to be in a cycle. So process its children.
- Iterable<SkyKey> children = entry.getTemporaryDirectDeps();
+ Iterable<SkyKey> children = Iterables.concat(entry.getTemporaryDirectDeps());
if (Iterables.isEmpty(children)) {
continue;
}
@@ -1864,7 +1877,9 @@ public final class ParallelEvaluator implements Evaluator {
*/
private void removeDescendantsOfCycleValue(SkyKey key, NodeEntry entry,
@Nullable SkyKey cycleChild, Iterable<SkyKey> toVisit, int cycleLength) {
- Set<SkyKey> unvisitedDeps = new HashSet<>(entry.getTemporaryDirectDeps());
+ GroupedList<SkyKey> directDeps = entry.getTemporaryDirectDeps();
+ Set<SkyKey> unvisitedDeps = Sets.newHashSetWithExpectedSize(directDeps.numElements());
+ Iterables.addAll(unvisitedDeps, Iterables.concat(directDeps));
unvisitedDeps.remove(cycleChild);
// Remove any children from this node that are not part of the cycle we just found. They are
// irrelevant to the node as it stands, and if they are deleted from the graph because they are
diff --git a/src/test/java/com/google/devtools/build/skyframe/DeterministicGraph.java b/src/test/java/com/google/devtools/build/skyframe/DeterministicGraph.java
index 81149777c6..85df5c59d5 100644
--- a/src/test/java/com/google/devtools/build/skyframe/DeterministicGraph.java
+++ b/src/test/java/com/google/devtools/build/skyframe/DeterministicGraph.java
@@ -121,12 +121,5 @@ public class DeterministicGraph<TGraph extends ThinNodeQueryableGraph>
result.addAll(super.getInProgressReverseDeps());
return result;
}
-
- @Override
- public synchronized Set<SkyKey> getTemporaryDirectDeps() {
- TreeSet<SkyKey> result = new TreeSet<>(ALPHABETICAL_SKYKEY_COMPARATOR);
- result.addAll(super.getTemporaryDirectDeps());
- return result;
- }
}
}
diff --git a/src/test/java/com/google/devtools/build/skyframe/InMemoryNodeEntryTest.java b/src/test/java/com/google/devtools/build/skyframe/InMemoryNodeEntryTest.java
index 4170c54922..92bed7b9b4 100644
--- a/src/test/java/com/google/devtools/build/skyframe/InMemoryNodeEntryTest.java
+++ b/src/test/java/com/google/devtools/build/skyframe/InMemoryNodeEntryTest.java
@@ -77,7 +77,7 @@ public class InMemoryNodeEntryTest {
assertFalse(entry.isReady());
assertTrue(entry.signalDep());
assertTrue(entry.isReady());
- assertThat(entry.getTemporaryDirectDeps()).containsExactly(dep1);
+ assertThatNodeEntry(entry).hasTemporaryDirectDepsThat().containsExactly(dep1);
SkyKey dep2 = key("dep2");
SkyKey dep3 = key("dep3");
addTemporaryDirectDep(entry, dep2);
@@ -197,7 +197,7 @@ public class InMemoryNodeEntryTest {
assertThat(entry.getNextDirtyDirectDeps()).containsExactly(dep);
addTemporaryDirectDep(entry, dep);
entry.signalDep();
- assertThat(entry.getTemporaryDirectDeps()).containsExactly(dep);
+ assertThatNodeEntry(entry).hasTemporaryDirectDepsThat().containsExactly(dep);
assertTrue(entry.isReady());
assertThat(entry.markRebuildingAndGetAllRemainingDirtyDirectDeps()).isEmpty();
assertThat(setValue(entry, new SkyValue() {}, /*errorInfo=*/null,
@@ -414,7 +414,7 @@ public class InMemoryNodeEntryTest {
addTemporaryDirectDep(entry, dep);
entry.signalDep(IntVersion.of(1L));
assertEquals(NodeEntry.DirtyState.NEEDS_REBUILDING, entry.getDirtyState());
- assertThat(entry.getTemporaryDirectDeps()).containsExactly(dep);
+ assertThatNodeEntry(entry).hasTemporaryDirectDepsThat().containsExactly(dep);
assertThat(entry.markRebuildingAndGetAllRemainingDirtyDirectDeps()).isEmpty();
setValue(entry, new IntegerValue(5), /*errorInfo=*/null, /*graphVersion=*/1L);
assertTrue(entry.isDone());
@@ -443,7 +443,7 @@ public class InMemoryNodeEntryTest {
addTemporaryDirectDep(entry, dep);
entry.signalDep(IntVersion.of(1L));
assertEquals(NodeEntry.DirtyState.NEEDS_REBUILDING, entry.getDirtyState());
- assertThat(entry.getTemporaryDirectDeps()).containsExactly(dep);
+ assertThatNodeEntry(entry).hasTemporaryDirectDepsThat().containsExactly(dep);
ReifiedSkyFunctionException exception = new ReifiedSkyFunctionException(
new GenericFunctionException(new SomeErrorException("oops"), Transience.PERSISTENT),
key("cause"));
@@ -480,7 +480,7 @@ public class InMemoryNodeEntryTest {
addTemporaryDirectDep(entry, dep);
entry.signalDep(IntVersion.of(1L));
assertEquals(NodeEntry.DirtyState.NEEDS_REBUILDING, entry.getDirtyState());
- assertThat(entry.getTemporaryDirectDeps()).containsExactly(dep);
+ assertThatNodeEntry(entry).hasTemporaryDirectDepsThat().containsExactly(dep);
assertThat(entry.markRebuildingAndGetAllRemainingDirtyDirectDeps())
.containsExactly(dep1InGroup, dep2InGroup);
addTemporaryDirectDeps(entry, dep2InGroup, dep1InGroup);
@@ -511,7 +511,7 @@ public class InMemoryNodeEntryTest {
addTemporaryDirectDep(entry, dep);
entry.signalDep(IntVersion.of(1L));
assertEquals(NodeEntry.DirtyState.NEEDS_REBUILDING, entry.getDirtyState());
- assertThat(entry.getTemporaryDirectDeps()).containsExactly(dep);
+ assertThatNodeEntry(entry).hasTemporaryDirectDepsThat().containsExactly(dep);
assertThat(entry.markRebuildingAndGetAllRemainingDirtyDirectDeps()).isEmpty();
setValue(entry, /*value=*/null, errorInfo, /*graphVersion=*/1L);
assertTrue(entry.isDone());
@@ -588,7 +588,7 @@ public class InMemoryNodeEntryTest {
addTemporaryDirectDep(entry, dep);
assertTrue(entry.signalDep(IntVersion.of(1L)));
assertEquals(NodeEntry.DirtyState.NEEDS_REBUILDING, entry.getDirtyState());
- assertThat(entry.getTemporaryDirectDeps()).containsExactly(dep);
+ assertThatNodeEntry(entry).hasTemporaryDirectDepsThat().containsExactly(dep);
assertThat(entry.markRebuildingAndGetAllRemainingDirtyDirectDeps()).isEmpty();
addTemporaryDirectDep(entry, key("dep2"));
assertTrue(entry.signalDep(IntVersion.of(1L)));
diff --git a/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java b/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java
index 8ca696e9e7..c18f07666d 100644
--- a/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java
+++ b/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java
@@ -1047,9 +1047,8 @@ public class MemoizingEvaluatorTest {
@Test
public void cycleAndSelfEdgeWithDirtyValueInSameGroup() throws Exception {
- makeGraphDeterministic();
- final SkyKey cycleKey1 = GraphTester.toSkyKey("zcycleKey1");
- final SkyKey cycleKey2 = GraphTester.toSkyKey("acycleKey2");
+ final SkyKey cycleKey1 = GraphTester.toSkyKey("cycleKey1");
+ final SkyKey cycleKey2 = GraphTester.toSkyKey("cycleKey2");
tester.getOrCreate(cycleKey2).addDependency(cycleKey2).setComputedValue(CONCATENATE);
tester
.getOrCreate(cycleKey1)
@@ -1059,8 +1058,9 @@ public class MemoizingEvaluatorTest {
@Override
public SkyValue compute(SkyKey skyKey, Environment env)
throws SkyFunctionException, InterruptedException {
+ // The order here is important -- 2 before 1.
Map<SkyKey, SkyValue> result =
- env.getValues(ImmutableList.of(cycleKey1, cycleKey2));
+ env.getValues(ImmutableList.of(cycleKey2, cycleKey1));
Preconditions.checkState(env.valuesMissing(), result);
return null;
}
diff --git a/src/test/java/com/google/devtools/build/skyframe/NodeEntrySubject.java b/src/test/java/com/google/devtools/build/skyframe/NodeEntrySubject.java
index 537d738c94..50ed287a19 100644
--- a/src/test/java/com/google/devtools/build/skyframe/NodeEntrySubject.java
+++ b/src/test/java/com/google/devtools/build/skyframe/NodeEntrySubject.java
@@ -13,21 +13,33 @@
// limitations under the License.
package com.google.devtools.build.skyframe;
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.Iterables;
import com.google.common.truth.DefaultSubject;
import com.google.common.truth.FailureStrategy;
+import com.google.common.truth.IterableSubject;
import com.google.common.truth.Subject;
-import com.google.common.truth.Truth;
/**
* {@link Subject} for {@link NodeEntry}. Please add to this class if you need more
* functionality!
*/
-public class NodeEntrySubject extends Subject<NodeEntrySubject, NodeEntry> {
- public NodeEntrySubject(FailureStrategy failureStrategy, NodeEntry nodeEntry) {
+class NodeEntrySubject extends Subject<NodeEntrySubject, NodeEntry> {
+ NodeEntrySubject(FailureStrategy failureStrategy, NodeEntry nodeEntry) {
super(failureStrategy, nodeEntry);
}
DefaultSubject hasVersionThat() {
- return Truth.assertThat(getSubject().getVersion()).named("Version for " + getDisplaySubject());
+ return assertThat(getSubject().getVersion()).named(detail("Version"));
+ }
+
+ IterableSubject hasTemporaryDirectDepsThat() {
+ return assertThat(Iterables.concat(getSubject().getTemporaryDirectDeps()))
+ .named(detail("TemporaryDirectDeps"));
+ }
+
+ private String detail(String descriptor) {
+ return descriptor + " for" + getDisplaySubject();
}
}