diff options
author | mjhalupka <mjhalupka@google.com> | 2018-06-27 08:17:36 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-06-27 08:19:04 -0700 |
commit | db9afe745e855e03aea69a00457bab7aa4a80b5d (patch) | |
tree | c063d47b5759f5c9a6c99c6ba6cadb8e4017af67 /src/main/java/com/google/devtools/build/lib/actions | |
parent | 4d868fe0a7abc2fdca602ce388e50295eb5aa2e3 (diff) |
Add an interner for non source artifacts that are deserialized.
PiperOrigin-RevId: 202311773
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/actions')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/actions/Artifact.java | 49 |
1 files changed, 48 insertions, 1 deletions
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 a974646d55..a27756e259 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 @@ -22,6 +22,8 @@ import com.google.common.base.Functions; import com.google.common.base.Joiner; import com.google.common.base.Preconditions; import com.google.common.base.Predicate; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Streams; @@ -53,6 +55,7 @@ import java.util.Collection; import java.util.Comparator; import java.util.List; import java.util.Objects; +import java.util.concurrent.ExecutionException; import javax.annotation.Nullable; /** @@ -152,6 +155,9 @@ public class Artifact /** A Predicate that evaluates to true if the Artifact is not a middleman artifact. */ public static final Predicate<Artifact> MIDDLEMAN_FILTER = input -> !input.isMiddlemanArtifact(); + private static final Cache<InternedArtifact, Artifact> ARTIFACT_INTERNER = + CacheBuilder.newBuilder().weakValues().build(); + private final int hashCode; private final ArtifactRoot root; private final PathFragment execPath; @@ -177,11 +183,24 @@ public class Artifact + ")"); } PathFragment rootExecPath = root.getExecPath(); - return new Artifact( + Artifact artifact = new Artifact( root, rootExecPath.isEmpty() ? rootRelativePath : rootExecPath.getRelative(rootRelativePath), rootRelativePath, owner); + if (artifact.isSourceArtifact()) { + return artifact; + } else { + return intern(artifact); + } + } + + private static Artifact intern(Artifact artifact) { + try { + return ARTIFACT_INTERNER.get(new InternedArtifact(artifact), () -> artifact); + } catch (ExecutionException e) { + throw new IllegalStateException(e); + } } /** @@ -583,6 +602,34 @@ public class Artifact } /** + * Wraps an artifact for interning because we need to check the artifact owner when doing equals. + */ + private static final class InternedArtifact { + private final Artifact wrappedArtifact; + + InternedArtifact(Artifact artifact) { + this.wrappedArtifact = artifact; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof InternedArtifact)) { + return false; + } + if (!getClass().equals(other.getClass())) { + return false; + } + InternedArtifact that = (InternedArtifact) other; + return Artifact.equalWithOwner(wrappedArtifact, that.wrappedArtifact); + } + + @Override + public final int hashCode() { + return wrappedArtifact.hashCode(); + } + } + + /** * Returns the relative path to this artifact relative to its root. (Useful * when deriving output filenames from input files, etc.) */ |