aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main
diff options
context:
space:
mode:
authorGravatar Mark Schaller <mschaller@google.com>2015-04-24 15:48:53 +0000
committerGravatar Han-Wen Nienhuys <hanwen@google.com>2015-04-27 18:48:14 +0000
commit906f255982742a373890437f086c08feab980349 (patch)
treefe0acb92e405baf5bdde519fd3559f33c37a394f /src/main
parentce4717a9e720e75b70fb000b040547d7dc3b0216 (diff)
Make SkyKey cached hash code transient
SkyKey argument hashcodes are not stable, because they're composed of values whose hashcodes may not be stable, such as Java enums. Therefore a SkyKey's own hashcode isn't stable. And this is fine, but if we try to serialize and then deserialize the SkyKey with its cached hashcode, the deserialized SkyKey's cached hashcode won't match a normally constructed SkyKey, despite them being equal. Because a SkyKey will deserialize with a default value of 0 for its cached hashcode, this change also introduces a transient boolean guard to note whether the correct hashcode has been calculated and cached. -- MOS_MIGRATED_REVID=91985674
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/google/devtools/build/skyframe/SkyKey.java20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/main/java/com/google/devtools/build/skyframe/SkyKey.java b/src/main/java/com/google/devtools/build/skyframe/SkyKey.java
index cc1dd1fc88..1ac6d4457c 100644
--- a/src/main/java/com/google/devtools/build/skyframe/SkyKey.java
+++ b/src/main/java/com/google/devtools/build/skyframe/SkyKey.java
@@ -34,14 +34,20 @@ public final class SkyKey implements Serializable {
private final Object argument;
/**
- * Cache the hash code for this object. It might be expensive to compute.
+ * Cache the hash code for this object. It might be expensive to compute. It is transient because
+ * argument's hash code might not be stable across JVM instances.
*/
- private final int hashCode;
+ private transient int hashCode;
+
+ /**
+ * Whether the hash code is cached. Needed for {de,}serialization.
+ */
+ private transient boolean hashCodeCached;
public SkyKey(SkyFunctionName functionName, Object valueName) {
this.functionName = Preconditions.checkNotNull(functionName);
this.argument = Preconditions.checkNotNull(valueName);
- this.hashCode = 31 * functionName.hashCode() + argument.hashCode();
+ cacheHashCode();
}
public SkyFunctionName functionName() {
@@ -59,9 +65,17 @@ public final class SkyKey implements Serializable {
@Override
public int hashCode() {
+ if (!hashCodeCached) {
+ cacheHashCode();
+ }
return hashCode;
}
+ private void cacheHashCode() {
+ hashCode = 31 * functionName.hashCode() + argument.hashCode();
+ hashCodeCached = true;
+ }
+
@Override
public boolean equals(Object obj) {
if (this == obj) {