aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/actions
diff options
context:
space:
mode:
authorGravatar mjhalupka <mjhalupka@google.com>2018-06-27 08:17:36 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-06-27 08:19:04 -0700
commitdb9afe745e855e03aea69a00457bab7aa4a80b5d (patch)
treec063d47b5759f5c9a6c99c6ba6cadb8e4017af67 /src/main/java/com/google/devtools/build/lib/actions
parent4d868fe0a7abc2fdca602ce388e50295eb5aa2e3 (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.java49
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.)
*/