Change Artifact.equals() to early-out if hashcodes differ. java.util.HashMap.get() has an optimization where it compares the hashcode to a cached value before calling equals() on the candidate key. CompactHashSet/Map keep a table of cached hashcodes. But RegularImmutableMap only has a comment saying it assumes the objects in the collection will optimize equals() with == and hashcode as appropriate! Simplify use of Objects.equal(); none of the fields are nullable. Take getClass() out of hashcode computation. I think two different Artifact subclasses for the same path is unusual in normal operation, and I may try to exploit the pass-through hashcode in ActionInputMap. RELNOTES: None. PiperOrigin-RevId: 210117899
diff --git a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java index fb4f1ed..db97a74 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java +++ b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
@@ -56,7 +56,6 @@ import java.util.Comparator; import java.util.List; import java.util.Map; -import java.util.Objects; import javax.annotation.Nullable; /** @@ -291,7 +290,7 @@ // The ArtifactOwner is not part of this computation because it is very rare that two Artifacts // have the same execPath and different owners, so a collision is fine there. If this is // changed, OwnerlessArtifactWrapper must also be changed. - this.hashCode = execPath.hashCode() + this.getClass().hashCode() * 13; + this.hashCode = execPath.hashCode(); this.root = root; this.execPath = execPath; this.rootRelativePath = rootRelativePath; @@ -711,6 +710,9 @@ @SuppressWarnings("EqualsGetClass") // Distinct classes of Artifact are never equal. @Override public boolean equals(Object other) { + if (this == other) { + return true; + } if (!(other instanceof Artifact)) { return false; } @@ -718,11 +720,11 @@ return false; } Artifact that = (Artifact) other; - return equalsWithoutOwner(that) && owner.equals(that.getArtifactOwner()); + return equalsWithoutOwner(that) && owner.equals(that.owner); } public boolean equalsWithoutOwner(Artifact other) { - return Objects.equals(this.execPath, other.execPath) && Objects.equals(this.root, other.root); + return hashCode == other.hashCode && execPath.equals(other.execPath) && root.equals(other.root); } @Override