Allows subclasses of InMemoryNodeEntry to determine whether a child has actually changed.
PiperOrigin-RevId: 215598031
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 25b867f..d0f0703 100644
--- a/src/main/java/com/google/devtools/build/skyframe/InMemoryNodeEntry.java
+++ b/src/main/java/com/google/devtools/build/skyframe/InMemoryNodeEntry.java
@@ -311,16 +311,21 @@
isDirty() && getDirtyBuildingState().getDirtyState() == DirtyState.FORCED_REBUILDING;
// If this is a new value, or it has changed since the last build, set the version to the
// current graph version.
- Preconditions.checkState(
- forcedRebuild || !this.lastChangedVersion.equals(version),
- "Changed value but with the same version? %s %s %s",
- this.lastChangedVersion,
- version,
- this);
+ if (!forcedRebuild && this.lastChangedVersion.equals(version)) {
+ logError(
+ new IllegalStateException(
+ "Changed value but with the same version? "
+ + this.lastChangedVersion
+ + " "
+ + version
+ + " "
+ + this));
+ }
+ // If this is a new value, or it has changed since the last build, set the version to the
+ // current graph version.
this.lastChangedVersion = version;
this.value = value;
}
-
return setStateFinishedAndReturnReverseDepsToSignal();
}
@@ -449,7 +454,8 @@
Preconditions.checkState(isEvaluating(), this);
signaledDeps++;
if (isDirty()) {
- dirtyBuildingState.signalDepInternal(!childVersion.atMost(lastEvaluatedVersion), isReady());
+ dirtyBuildingState.signalDepInternal(
+ hasChildChanged(lastEvaluatedVersion, childVersion), isReady());
}
return isReady();
}
@@ -640,6 +646,20 @@
return isReady(getNumTemporaryDirectDeps());
}
+ /** True if the child has changed since the last evaluated version. */
+ protected boolean hasChildChanged(Version lastEvaluatedVersion, Version childVersion) {
+ // childVersion > lastEvaluatedVersion
+ return !childVersion.atMost(lastEvaluatedVersion);
+ }
+
+ protected int getSignaledDeps() {
+ return signaledDeps;
+ }
+
+ protected void logError(RuntimeException error) {
+ throw error;
+ }
+
/** Returns whether all known children of this node have signaled that they are done. */
private boolean isReady(int numDirectDeps) {
Preconditions.checkState(signaledDeps <= numDirectDeps, "%s %s", numDirectDeps, this);