diff options
author | tomlu <tomlu@google.com> | 2018-02-08 15:32:00 -0800 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-02-08 15:34:11 -0800 |
commit | a729b9b4c3d7844a7d44934bf3365f92633c0a60 (patch) | |
tree | 6329f4baf5b0b83ea6e3bd577b78b8d49afea9f1 /src/main/java/com/google/devtools/build/lib/actions/Artifact.java | |
parent | 0ab46f0dd95f735056add4dd8a90a76944b81d00 (diff) |
Replace path implementation.
Path and PathFragment have been replaced with String-based implementations. They are pretty similar, but each method is dissimilar enough that I did not feel sharing code was appropriate.
A summary of changes:
PATH
====
* Subsumes LocalPath (deleted, its tests repurposed)
* Use a simple string to back Path
* Path instances are no longer interned; Reference equality will no longer work
* Always normalized (same as before)
* Some operations will now be slower, like instance compares (which were previously just a reference check)
* Multiple identical paths will now consume more memory since they are not interned
PATH FRAGMENT
=============
* Use a simple string to back PathFragment
* No more segment arrays with interned strings
* Always normalized
* Remove isNormalized
* Replace some isNormalizied uses with containsUpLevelReferences() to check if path fragments try to escape their scope
* To check if user input is normalized, supply static methods on PathFragment to validate the string before constructing a PathFragment
* Because PathFragments are always normalized, we have to replace checks for literal "." from PathFragment#getPathString to PathFragment#getSafePathString. The latter returns "." for the empty string.
* The previous implementation supported efficient segment semantics (segment count, iterating over segments). This is now expensive since we do longer have a segment array.
ARTIFACT
========
* Remove Path instance. It is instead dynamically constructed on request. This is necessary to avoid this CL becoming a memory regression.
RELNOTES: None
PiperOrigin-RevId: 185062932
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/actions/Artifact.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/actions/Artifact.java | 64 |
1 files changed, 23 insertions, 41 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 395f5dfde8..964b05d5a6 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 @@ -176,7 +176,6 @@ public class Artifact public static final Predicate<Artifact> MIDDLEMAN_FILTER = input -> !input.isMiddlemanArtifact(); private final int hashCode; - private final Path path; private final ArtifactRoot root; private final PathFragment execPath; private final PathFragment rootRelativePath; @@ -203,35 +202,26 @@ public class Artifact */ @VisibleForTesting @AutoCodec.Instantiator - public Artifact(Path path, ArtifactRoot root, PathFragment execPath, ArtifactOwner owner) { - if (root == null || !root.getRoot().contains(path)) { - throw new IllegalArgumentException(root + ": illegal root for " + path - + " (execPath: " + execPath + ")"); - } - if (execPath == null - || execPath.isAbsolute() != root.getRoot().isAbsolute() - || !path.asFragment().endsWith(execPath)) { - throw new IllegalArgumentException(execPath + ": illegal execPath for " + path - + " (root: " + root + ")"); + public Artifact(ArtifactRoot root, PathFragment execPath, ArtifactOwner owner) { + Preconditions.checkNotNull(root); + if (execPath == null || execPath.isAbsolute() != root.getRoot().isAbsolute()) { + throw new IllegalArgumentException( + execPath + ": illegal execPath for " + execPath + " (root: " + root + ")"); } if (execPath.isEmpty()) { throw new IllegalArgumentException( "it is illegal to create an artifact with an empty execPath"); } - this.hashCode = path.hashCode(); - this.path = path; + this.hashCode = execPath.hashCode(); this.root = root; this.execPath = execPath; - // These two lines establish the invariant that - // execPath == rootRelativePath <=> execPath.equals(rootRelativePath) - // This is important for isSourceArtifact. - PathFragment rootRel = root.getRoot().relativize(path); - if (!execPath.endsWith(rootRel)) { - throw new IllegalArgumentException(execPath + ": illegal execPath doesn't end with " - + rootRel + " at " + path + " with root " + root); + PathFragment rootExecPath = root.getExecPath(); + if (rootExecPath.isEmpty()) { + this.rootRelativePath = execPath; + } else { + this.rootRelativePath = execPath.relativeTo(root.getExecPath()); } - this.rootRelativePath = rootRel.equals(execPath) ? execPath : rootRel; - this.owner = Preconditions.checkNotNull(owner, path); + this.owner = Preconditions.checkNotNull(owner); } /** @@ -251,8 +241,8 @@ public class Artifact * <pre> */ @VisibleForTesting - public Artifact(Path path, ArtifactRoot root, PathFragment execPath) { - this(path, root, execPath, ArtifactOwner.NullArtifactOwner.INSTANCE); + public Artifact(ArtifactRoot root, PathFragment execPath) { + this(root, execPath, ArtifactOwner.NullArtifactOwner.INSTANCE); } /** @@ -262,7 +252,6 @@ public class Artifact @VisibleForTesting // Only exists for testing. public Artifact(Path path, ArtifactRoot root) { this( - path, root, root.getExecPath().getRelative(root.getRoot().relativize(path)), ArtifactOwner.NullArtifactOwner.INSTANCE); @@ -272,14 +261,13 @@ public class Artifact @VisibleForTesting // Only exists for testing. public Artifact(PathFragment rootRelativePath, ArtifactRoot root) { this( - root.getRoot().getRelative(rootRelativePath), root, root.getExecPath().getRelative(rootRelativePath), ArtifactOwner.NullArtifactOwner.INSTANCE); } public final Path getPath() { - return path; + return root.getRoot().getRelative(rootRelativePath); } public boolean hasParent() { @@ -412,9 +400,8 @@ public class Artifact structField = true, doc = "Returns true if this is a source file, i.e. it is not generated." ) - @SuppressWarnings("ReferenceEquality") // == is an optimization public final boolean isSourceArtifact() { - return execPath == rootRelativePath; + return root.isSourceRoot(); } /** @@ -479,12 +466,8 @@ public class Artifact @VisibleForSerialization public SpecialArtifact( - Path path, - ArtifactRoot root, - PathFragment execPath, - ArtifactOwner owner, - SpecialArtifactType type) { - super(path, root, execPath, owner); + ArtifactRoot root, PathFragment execPath, ArtifactOwner owner, SpecialArtifactType type) { + super(root, execPath, owner); this.type = type; } @@ -559,17 +542,16 @@ public class Artifact TreeFileArtifact( SpecialArtifact parentTreeArtifact, PathFragment parentRelativePath, ArtifactOwner owner) { super( - parentTreeArtifact.getPath().getRelative(parentRelativePath), parentTreeArtifact.getRoot(), parentTreeArtifact.getExecPath().getRelative(parentRelativePath), owner); - Preconditions.checkState( + Preconditions.checkArgument( parentTreeArtifact.isTreeArtifact(), "The parent of TreeFileArtifact (parent-relative path: %s) is not a TreeArtifact: %s", parentRelativePath, parentTreeArtifact); - Preconditions.checkState( - parentRelativePath.isNormalized() && !parentRelativePath.isAbsolute(), + Preconditions.checkArgument( + !parentRelativePath.containsUplevelReferences() && !parentRelativePath.isAbsolute(), "%s is not a proper normalized relative path", parentRelativePath); this.parentTreeArtifact = parentTreeArtifact; @@ -668,7 +650,7 @@ public class Artifact // We don't bother to check root in the equivalence relation, because we // assume that no root is an ancestor of another one. Artifact that = (Artifact) other; - return Objects.equals(this.path, that.path); + return Objects.equals(this.execPath, that.execPath) && Objects.equals(this.root, that.root); } @Override @@ -702,7 +684,7 @@ public class Artifact return "[" + root + "]" + rootRelativePath; } else { // Derived Artifact: path and root are under execRoot - PathFragment execRoot = trimTail(path.asFragment(), execPath); + PathFragment execRoot = trimTail(getPath().asFragment(), execPath); return "[[" + execRoot + "]" |