diff options
author | 2015-04-24 15:48:53 +0000 | |
---|---|---|
committer | 2015-04-27 18:48:14 +0000 | |
commit | 906f255982742a373890437f086c08feab980349 (patch) | |
tree | fe0acb92e405baf5bdde519fd3559f33c37a394f /src/main | |
parent | ce4717a9e720e75b70fb000b040547d7dc3b0216 (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.java | 20 |
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) { |