Make two Skyframe nodes with the same events and values equal.
We do this by implementing equality for TaggedEvents (and all objects
it transitively includes). Before this change, if a Skyframe node
re-evaluated to the same value as in the previous build, but had
(transitive) events, change pruning would not cut off the evaluation
of its parents. This is not a big issue in practice because most nodes
that would re-evaluate to the same value (like FileValues or
GlobValues) never emit events, and others (like ActionExecutionValues)
have secondary caches that mask this effect.
Also do a drive-by fix where we were using the hash code of a nested
set instead of the shallow hash code (didn't have any bad effects in
practice because we never hash these values).
(Minor formatting clean-ups from https://bazel-review.googlesource.com/1610 )
--
Change-Id: I751a8479627f0456993c5ec8834528aeb593d736
Reviewed-on: https://bazel-review.googlesource.com/1610
MOS_MIGRATED_REVID=98115908
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/LineNumberTable.java b/src/main/java/com/google/devtools/build/lib/syntax/LineNumberTable.java
index 3bcf0a0..ac629c7 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/LineNumberTable.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/LineNumberTable.java
@@ -25,8 +25,10 @@
import java.io.Serializable;
import java.nio.CharBuffer;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
+import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -146,6 +148,23 @@
? linestart[line + 1]
: bufferLength);
}
+
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(Arrays.hashCode(linestart), path, bufferLength);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == null || !other.getClass().equals(getClass())) {
+ return false;
+ }
+ Regular that = (Regular) other;
+ return this.bufferLength == that.bufferLength
+ && Arrays.equals(this.linestart, that.linestart)
+ && Objects.equals(this.path, that.path);
+ }
}
/**
@@ -197,7 +216,7 @@
}
this.table = hashOrdering.immutableSortedCopy(unorderedTable);
this.bufferLength = buffer.length;
- this.defaultPath = defaultPath;
+ this.defaultPath = Preconditions.checkNotNull(defaultPath);
}
private SingleHashLine getHashLine(int offset) {
@@ -242,5 +261,21 @@
}
return Pair.of(0, 0);
}
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(table, defaultPath, bufferLength);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == null || !other.getClass().equals(getClass())) {
+ return false;
+ }
+ HashLine that = (HashLine) other;
+ return this.bufferLength == that.bufferLength
+ && this.defaultPath.equals(that.defaultPath)
+ && this.table.equals(that.table);
+ }
}
}