Stop requiring the creation and storage of FileStateValues within ResolvedFile objects.
While this does not eliminate the need for stat operation yet, it gets rid of one usage of the stat result (and is also a self contained change)
RELNOTES: None
PiperOrigin-RevId: 204417559
diff --git a/src/main/java/com/google/devtools/build/lib/actions/FilesetOutputSymlink.java b/src/main/java/com/google/devtools/build/lib/actions/FilesetOutputSymlink.java
index 2611984..caf641f 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/FilesetOutputSymlink.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/FilesetOutputSymlink.java
@@ -13,159 +13,61 @@
// limitations under the License.
package com.google.devtools.build.lib.actions;
+import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.vfs.PathFragment;
-import java.util.Objects;
-import javax.annotation.Nullable;
/** Definition of a symlink in the output tree of a Fileset rule. */
+@AutoValue
public abstract class FilesetOutputSymlink {
- private static final int STRIPPED_METADATA = -1;
- private final PathFragment name;
- private final PathFragment target;
- private final int metadataHash;
-
- FilesetOutputSymlink(PathFragment name, PathFragment target, int metadataHash) {
- this.name = Preconditions.checkNotNull(name);
- this.target = Preconditions.checkNotNull(target);
- this.metadataHash = metadataHash;
- }
+ private static final Integer STRIPPED_METADATA = new Integer(-1);
/** Final name of the symlink relative to the Fileset's output directory. */
- public PathFragment getName() {
- return name;
- }
+ public abstract PathFragment getName();
/**
* Target of the symlink. This may be relative to the target's location if the target itself is a
* relative symlink. We can override it by using FilesetEntry.symlinks = 'dereference'.
*/
- public PathFragment getTargetPath() {
- return target;
- }
+ public abstract PathFragment getTargetPath();
- /** The hashcode of the target's file state. */
- public int getMetadataHash() {
- return metadataHash;
- }
+ /**
+ * Return the best effort metadata about the target. Currently this will be a FileStateValue for
+ * source targets. For generated targets we try to return a FileArtifactValue when possible, or
+ * else this will be a Integer hashcode of the target.
+ */
+ public abstract Object getMetadata();
/** true if the target is a generated artifact */
public abstract boolean isGeneratedTarget();
- /**
- * returns the target artifact if it's generated {@link #isGeneratedTarget() == true}, or null
- * otherwise.
- */
- @Nullable
- public abstract FileArtifactValue getTargetArtifactValue();
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || !obj.getClass().equals(getClass())) {
- return false;
- }
- FilesetOutputSymlink o = (FilesetOutputSymlink) obj;
- return getName().equals(o.getName())
- && getTargetPath().equals(o.getTargetPath())
- && getMetadataHash() == o.getMetadataHash()
- && isGeneratedTarget() == o.isGeneratedTarget()
- && Objects.equals(getTargetArtifactValue(), o.getTargetArtifactValue());
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(
- getName(),
- getTargetPath(),
- getMetadataHash(),
- isGeneratedTarget(),
- getTargetArtifactValue());
- }
-
@Override
public String toString() {
- if (getMetadataHash() == STRIPPED_METADATA) {
+ if (getMetadata() == STRIPPED_METADATA) {
return String.format(
"FilesetOutputSymlink(%s -> %s)",
getName().getPathString(), getTargetPath().getPathString());
} else {
return String.format(
"FilesetOutputSymlink(%s -> %s | metadataHash=%s)",
- getName().getPathString(), getTargetPath().getPathString(), getMetadataHash());
+ getName().getPathString(), getTargetPath().getPathString(), getMetadata());
}
}
@VisibleForTesting
public static FilesetOutputSymlink createForTesting(PathFragment name, PathFragment target) {
- return new SourceOutputSymlink(name, target, STRIPPED_METADATA);
+ return new AutoValue_FilesetOutputSymlink(name, target, STRIPPED_METADATA, false);
}
/**
* @param name relative path under the Fileset's output directory, including FilesetEntry.destdir
* with and FilesetEntry.strip_prefix applied (if applicable)
* @param target relative or absolute value of the link
- * @param metadataHash hashcode of the target's file state
+ * @param metadata metadata corresponding to the target.
+ * @param isGeneratedTarget true of the target is generated.
*/
- public static FilesetOutputSymlink createForSourceTarget(
- PathFragment name, PathFragment target, int metadataHash) {
- return new SourceOutputSymlink(name, target, metadataHash);
- }
-
- /**
- * @param name relative path under the Fileset's output directory, including FilesetEntry.destdir
- * with and FilesetEntry.strip_prefix applied (if applicable)
- * @param target relative or absolute value of the link
- * @param metadataHash hashcode of the target's file state.
- * @param fileArtifactValue the {@link FileArtifactValue} corresponding to the target.
- */
- public static FilesetOutputSymlink createForDerivedTarget(
- PathFragment name,
- PathFragment target,
- int metadataHash,
- FileArtifactValue fileArtifactValue) {
- return new DerivedOutputSymlink(name, target, metadataHash, fileArtifactValue);
- }
-
- private static class DerivedOutputSymlink extends FilesetOutputSymlink {
- private final FileArtifactValue fileArtifactValue;
-
- DerivedOutputSymlink(
- PathFragment name,
- PathFragment target,
- int metadataHash,
- FileArtifactValue fileArtifactValue) {
- super(name, target, metadataHash);
- this.fileArtifactValue = fileArtifactValue;
- }
-
- @Override
- public boolean isGeneratedTarget() {
- return true;
- }
-
- @Override
- public FileArtifactValue getTargetArtifactValue() {
- return fileArtifactValue;
- }
- }
-
- private static class SourceOutputSymlink extends FilesetOutputSymlink {
- SourceOutputSymlink(PathFragment name, PathFragment target, int metadataHash) {
- super(name, target, metadataHash);
- }
-
- @Override
- public boolean isGeneratedTarget() {
- return false;
- }
-
- @Override
- public FileArtifactValue getTargetArtifactValue() {
- return null;
- }
+ public static FilesetOutputSymlink create(
+ PathFragment name, PathFragment target, Object metadata, boolean isGeneratedTarget) {
+ return new AutoValue_FilesetOutputSymlink(name, target, metadata, isGeneratedTarget);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunction.java
index 00a16f9..bc91ed7 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunction.java
@@ -20,7 +20,6 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
-import com.google.devtools.build.lib.actions.FileArtifactValue;
import com.google.devtools.build.lib.actions.FilesetOutputSymlink;
import com.google.devtools.build.lib.actions.FilesetTraversalParams;
import com.google.devtools.build.lib.actions.FilesetTraversalParams.DirectTraversal;
@@ -189,16 +188,12 @@
throw new FilesetEntryFunctionException(e);
}
- // Metadata field must be present. It can only be absent when stripped by tests.
- String metadata = Integer.toHexString(f.getMetadataHash());
-
maybeStoreSymlink(
linkName,
targetName,
- f.getMetadataHash(),
+ f.getMetadata(),
t.getDestPath(),
direct.isGenerated(),
- f.getValueForDerivedArtifacts(),
outputSymlinks);
}
}
@@ -214,10 +209,9 @@
maybeStoreSymlink(
nestedLink.getName(),
nestedLink.getTargetPath(),
- nestedLink.getMetadataHash(),
+ nestedLink.getMetadata(),
destPath,
nestedLink.isGeneratedTarget(),
- nestedLink.getTargetArtifactValue(),
result);
}
@@ -225,23 +219,14 @@
private static void maybeStoreSymlink(
PathFragment linkName,
PathFragment linkTarget,
- int metadataHash,
+ Object metadata,
PathFragment destPath,
boolean isGenerated,
- FileArtifactValue targetArtifactValue,
Map<PathFragment, FilesetOutputSymlink> result) {
linkName = destPath.getRelative(linkName);
if (!result.containsKey(linkName)) {
- if (isGenerated) {
- result.put(
- linkName,
- FilesetOutputSymlink.createForDerivedTarget(
- linkName, linkTarget, metadataHash, targetArtifactValue));
- } else {
- result.put(
- linkName,
- FilesetOutputSymlink.createForSourceTarget(linkName, linkTarget, metadataHash));
- }
+ result.put(
+ linkName, FilesetOutputSymlink.create(linkName, linkTarget, metadata, isGenerated));
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java
index 818d227..070b831 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java
@@ -13,14 +13,12 @@
// limitations under the License.
package com.google.devtools.build.lib.skyframe;
-import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Verify;
import com.google.common.collect.Collections2;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ArtifactSkyKey;
import com.google.devtools.build.lib.actions.FileArtifactValue;
-import com.google.devtools.build.lib.actions.FileStateValue;
import com.google.devtools.build.lib.actions.FileValue;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
@@ -30,7 +28,6 @@
import com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.TraversalRequest;
import com.google.devtools.build.lib.vfs.Dirent;
import com.google.devtools.build.lib.vfs.FileStatus;
-import com.google.devtools.build.lib.vfs.FileStatusWithDigest;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Root;
@@ -200,22 +197,19 @@
private static final class FileInfo {
final FileType type;
- final FileStateValue metadata;
+ final Object metadata;
@Nullable final RootedPath realPath;
@Nullable final PathFragment unresolvedSymlinkTarget;
- @Nullable final FileArtifactValue fileArtifactValue;
FileInfo(
FileType type,
- FileStateValue metadata,
+ Object metadata,
@Nullable RootedPath realPath,
- @Nullable PathFragment unresolvedSymlinkTarget,
- @Nullable FileArtifactValue fileArtifactValue) {
+ @Nullable PathFragment unresolvedSymlinkTarget) {
this.type = Preconditions.checkNotNull(type);
- this.metadata = Preconditions.checkNotNull(metadata);
+ this.metadata = metadata;
this.realPath = realPath;
this.unresolvedSymlinkTarget = unresolvedSymlinkTarget;
- this.fileArtifactValue = fileArtifactValue;
}
@Override
@@ -229,6 +223,9 @@
}
}
+ private static final FileInfo NON_EXISTENT_FILE_INFO =
+ new FileInfo(FileType.NONEXISTENT, new Integer(0), null, null);
+
private static FileInfo lookUpFileInfo(Environment env, TraversalRequest traversal)
throws MissingDepException, IOException, InterruptedException {
if (traversal.isRootGenerated) {
@@ -244,7 +241,7 @@
if (value instanceof FileArtifactValue) {
fsVal = (FileArtifactValue) value;
} else {
- return new FileInfo(FileType.NONEXISTENT, null, null, null, null);
+ return NON_EXISTENT_FILE_INFO;
}
}
@@ -274,14 +271,7 @@
type = followStat.isFile() ? FileType.SYMLINK_TO_FILE : FileType.SYMLINK_TO_DIRECTORY;
}
return new FileInfo(
- type,
- FileStateValue.createWithStatNoFollow(
- traversal.root.asRootedPath(),
- new StatWithDigest(noFollowStat, fsVal != null ? fsVal.getDigest() : null),
- null),
- realPath,
- unresolvedLinkTarget,
- fsVal);
+ type, fsVal != null ? fsVal : noFollowStat.hashCode(), realPath, unresolvedLinkTarget);
} else {
// Stat the file.
FileValue fileValue =
@@ -302,19 +292,14 @@
type = fileValue.isDirectory() ? FileType.DIRECTORY : FileType.FILE;
}
return new FileInfo(
- type,
- fileValue.realFileStateValue(),
- fileValue.realRootedPath(),
- unresolvedLinkTarget,
- null);
+ type, fileValue.realFileStateValue(), fileValue.realRootedPath(), unresolvedLinkTarget);
} else {
// If it doesn't exist, or it's a dangling symlink, we still want to handle that gracefully.
return new FileInfo(
fileValue.isSymlink() ? FileType.DANGLING_SYMLINK : FileType.NONEXISTENT,
fileValue.realFileStateValue(),
null,
- fileValue.isSymlink() ? fileValue.getUnresolvedLinkTarget() : null,
- null);
+ fileValue.isSymlink() ? fileValue.getUnresolvedLinkTarget() : null);
}
}
}
@@ -451,8 +436,7 @@
Preconditions.checkState(info.type.isSymlink() && !info.type.exists(), "{%s} {%s}", linkName,
info.type);
return RecursiveFilesystemTraversalValue.of(
- ResolvedFileFactory.danglingSymlink(
- linkName, info.unresolvedSymlinkTarget, info.metadata, info.fileArtifactValue));
+ ResolvedFileFactory.danglingSymlink(linkName, info.unresolvedSymlinkTarget, info.metadata));
}
/**
@@ -468,14 +452,10 @@
if (info.type.isSymlink()) {
return RecursiveFilesystemTraversalValue.of(
ResolvedFileFactory.symlinkToFile(
- info.realPath,
- path,
- info.unresolvedSymlinkTarget,
- info.metadata,
- info.fileArtifactValue));
+ info.realPath, path, info.unresolvedSymlinkTarget, info.metadata));
} else {
return RecursiveFilesystemTraversalValue.of(
- ResolvedFileFactory.regularFile(path, info.metadata, info.fileArtifactValue));
+ ResolvedFileFactory.regularFile(path, info.metadata));
}
}
@@ -494,8 +474,7 @@
rootInfo.realPath,
traversal.root.asRootedPath(),
rootInfo.unresolvedSymlinkTarget,
- hashDirectorySymlink(children, rootInfo.metadata.hashCode()),
- rootInfo.fileArtifactValue);
+ hashDirectorySymlink(children, rootInfo.metadata));
paths = NestedSetBuilder.<ResolvedFile>stableOrder().addTransitive(children).add(root);
} else {
root = ResolvedFileFactory.directory(rootInfo.realPath);
@@ -503,8 +482,7 @@
return RecursiveFilesystemTraversalValue.of(root, paths.build());
}
- private static int hashDirectorySymlink(
- Iterable<ResolvedFile> children, int symlinkHash) {
+ private static int hashDirectorySymlink(Iterable<ResolvedFile> children, Object metadata) {
// If the root is a directory symlink, the associated FileStateValue does not change when the
// linked directory's contents change, so we can't use the FileStateValue as metadata like we
// do with other ResolvedFile kinds. Instead we compute a metadata hash from the child
@@ -513,9 +491,9 @@
// Compute the hash using the method described in Effective Java, 2nd ed., Item 9.
int result = 0;
for (ResolvedFile c : children) {
- result = 31 * result + c.getMetadataHash();
+ result = 31 * result + c.getMetadata().hashCode();
}
- return 31 * result + symlinkHash;
+ return 31 * result + metadata.hashCode();
}
private static SkyValue getDependentSkyValue(Environment env, SkyKey key)
@@ -551,13 +529,7 @@
throw new MissingDepException();
}
- return Collections2.transform(values.values(),
- new Function<SkyValue, RecursiveFilesystemTraversalValue>() {
- @Override
- public RecursiveFilesystemTraversalValue apply(SkyValue input) {
- return (RecursiveFilesystemTraversalValue) input;
- }
- });
+ return Collections2.transform(values.values(), RecursiveFilesystemTraversalValue.class::cast);
}
/** Type information about the filesystem entry residing at a path. */
@@ -616,60 +588,4 @@
boolean exists() { return false; }
@Override public abstract String toString();
}
-
- private static class StatWithDigest implements FileStatusWithDigest {
- private final FileStatus noFollowStat;
- private final byte[] digest;
-
- public StatWithDigest(FileStatus noFollowStat, byte[] digest) {
- this.noFollowStat = noFollowStat;
- this.digest = digest;
- }
-
- @Nullable
- @Override
- public byte[] getDigest() throws IOException {
- return digest;
- }
-
- @Override
- public boolean isFile() {
- return noFollowStat.isFile();
- }
-
- @Override
- public boolean isDirectory() {
- return noFollowStat.isDirectory();
- }
-
- @Override
- public boolean isSymbolicLink() {
- return noFollowStat.isSymbolicLink();
- }
-
- @Override
- public boolean isSpecialFile() {
- return noFollowStat.isSpecialFile();
- }
-
- @Override
- public long getSize() throws IOException {
- return noFollowStat.getSize();
- }
-
- @Override
- public long getLastModifiedTime() throws IOException {
- return noFollowStat.getLastModifiedTime();
- }
-
- @Override
- public long getLastChangeTime() throws IOException {
- return noFollowStat.getLastChangeTime();
- }
-
- @Override
- public long getNodeId() throws IOException {
- return noFollowStat.getNodeId();
- }
- }
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalValue.java
index 0b91f51..000daa6 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalValue.java
@@ -18,7 +18,6 @@
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.Interner;
-import com.google.devtools.build.lib.actions.FileArtifactValue;
import com.google.devtools.build.lib.actions.FileStateValue;
import com.google.devtools.build.lib.actions.FilesetTraversalParams.DirectTraversalRoot;
import com.google.devtools.build.lib.actions.FilesetTraversalParams.PackageBoundaryMode;
@@ -262,20 +261,17 @@
private static final class RegularFile implements ResolvedFile {
private final RootedPath path;
- @Nullable private final FileStateValue metadata;
- @Nullable private final FileArtifactValue artifactValue;
+ private final Object metadata;
/** C'tor for {@link #stripMetadataForTesting()}. */
private RegularFile(RootedPath path) {
this.path = Preconditions.checkNotNull(path);
- this.metadata = null;
- this.artifactValue = null;
+ this.metadata = EMPTY_METADATA;
}
- RegularFile(RootedPath path, FileStateValue metadata, FileArtifactValue artifactValue) {
+ RegularFile(RootedPath path, Object metadata) {
this.path = Preconditions.checkNotNull(path);
- this.metadata = Preconditions.checkNotNull(metadata);
- this.artifactValue = artifactValue;
+ this.metadata = metadata;
}
@Override
@@ -290,8 +286,8 @@
@Override
@Nullable
- public int getMetadataHash() {
- return metadata == null ? 0 : metadata.hashCode();
+ public Object getMetadata() {
+ return metadata;
}
@Override
@@ -303,7 +299,7 @@
return false;
}
return this.path.equals(((RegularFile) obj).path)
- && Objects.equal(this.metadata, ((RegularFile) obj).metadata);
+ && this.metadata.equals(((RegularFile) obj).metadata);
}
@Override
@@ -327,11 +323,6 @@
}
@Override
- public FileArtifactValue getValueForDerivedArtifacts() {
- return artifactValue;
- }
-
- @Override
public PathFragment getTargetInSymlinkTree(boolean followSymlinks) {
return path.asPath().asFragment();
}
@@ -355,8 +346,8 @@
}
@Override
- public int getMetadataHash() {
- return FileStateValue.DIRECTORY_FILE_STATE_NODE.hashCode();
+ public Object getMetadata() {
+ return FileStateValue.DIRECTORY_FILE_STATE_NODE;
}
@Override
@@ -391,11 +382,6 @@
}
@Override
- public FileArtifactValue getValueForDerivedArtifacts() {
- return null;
- }
-
- @Override
public PathFragment getTargetInSymlinkTree(boolean followSymlinks) {
return path.asPath().asFragment();
}
@@ -403,29 +389,21 @@
private static final class DanglingSymlink implements ResolvedFile {
private final Symlink symlink;
- @Nullable private final FileStateValue metadata;
- @Nullable private final FileArtifactValue artifactValue;
+ private final Object metadata;
private DanglingSymlink(Symlink symlink) {
this.symlink = symlink;
- this.metadata = null;
- this.artifactValue = null;
+ this.metadata = EMPTY_METADATA;
}
private DanglingSymlink(RootedPath linkNamePath, PathFragment linkTargetPath) {
this.symlink = new Symlink(linkNamePath, linkTargetPath);
- this.metadata = null;
- this.artifactValue = null;
+ this.metadata = EMPTY_METADATA;
}
- DanglingSymlink(
- RootedPath linkNamePath,
- PathFragment linkTargetPath,
- FileStateValue metadata,
- @Nullable FileArtifactValue fileArtifactValue) {
+ DanglingSymlink(RootedPath linkNamePath, PathFragment linkTargetPath, Object metadata) {
this.symlink = new Symlink(linkNamePath, linkTargetPath);
- this.metadata = Preconditions.checkNotNull(metadata);
- this.artifactValue = fileArtifactValue;
+ this.metadata = metadata;
}
@Override
@@ -440,9 +418,8 @@
}
@Override
- @Nullable
- public int getMetadataHash() {
- return metadata == null ? 0 : metadata.hashCode();
+ public Object getMetadata() {
+ return metadata;
}
@Override
@@ -453,7 +430,7 @@
if (!(obj instanceof DanglingSymlink)) {
return false;
}
- return Objects.equal(this.metadata, ((DanglingSymlink) obj).metadata)
+ return this.metadata.equals(((DanglingSymlink) obj).metadata)
&& this.symlink.equals(((DanglingSymlink) obj).symlink);
}
@@ -478,11 +455,6 @@
}
@Override
- public FileArtifactValue getValueForDerivedArtifacts() {
- return artifactValue;
- }
-
- @Override
public PathFragment getTargetInSymlinkTree(boolean followSymlinks)
throws DanglingSymlinkException {
if (followSymlinks) {
@@ -496,36 +468,31 @@
private static final class SymlinkToFile implements ResolvedFile {
private final RootedPath path;
- @Nullable private final FileStateValue metadata;
+ private final Object metadata;
private final Symlink symlink;
- @Nullable private final FileArtifactValue fileArtifactValue;
/** C'tor for {@link #stripMetadataForTesting()}. */
private SymlinkToFile(RootedPath targetPath, Symlink symlink) {
this.path = Preconditions.checkNotNull(targetPath);
- this.metadata = null;
+ this.metadata = EMPTY_METADATA;
this.symlink = Preconditions.checkNotNull(symlink);
- this.fileArtifactValue = null;
}
private SymlinkToFile(
RootedPath targetPath, RootedPath linkNamePath, PathFragment linkTargetPath) {
this.path = Preconditions.checkNotNull(targetPath);
- this.metadata = null;
+ this.metadata = EMPTY_METADATA;
this.symlink = new Symlink(linkNamePath, linkTargetPath);
- this.fileArtifactValue = null;
}
SymlinkToFile(
RootedPath targetPath,
RootedPath linkNamePath,
PathFragment linkTargetPath,
- FileStateValue metadata,
- @Nullable FileArtifactValue fileArtifactValue) {
+ Object metadata) {
this.path = Preconditions.checkNotNull(targetPath);
- this.metadata = Preconditions.checkNotNull(metadata);
+ this.metadata = metadata;
this.symlink = new Symlink(linkNamePath, linkTargetPath);
- this.fileArtifactValue = fileArtifactValue;
}
@Override
@@ -539,9 +506,8 @@
}
@Override
- @Nullable
- public int getMetadataHash() {
- return metadata == null ? 0 : metadata.hashCode();
+ public Object getMetadata() {
+ return metadata;
}
@Override
@@ -553,7 +519,7 @@
return false;
}
return this.path.equals(((SymlinkToFile) obj).path)
- && Objects.equal(this.metadata, ((SymlinkToFile) obj).metadata)
+ && this.metadata.equals(((SymlinkToFile) obj).metadata)
&& this.symlink.equals(((SymlinkToFile) obj).symlink);
}
@@ -578,11 +544,6 @@
}
@Override
- public FileArtifactValue getValueForDerivedArtifacts() {
- return fileArtifactValue;
- }
-
- @Override
public PathFragment getTargetInSymlinkTree(boolean followSymlinks) {
return followSymlinks ? path.asPath().asFragment() : symlink.unresolvedLinkTarget;
}
@@ -590,36 +551,28 @@
private static final class SymlinkToDirectory implements ResolvedFile {
private final RootedPath path;
- @Nullable private final int metadataHash;
+ private final Object metadata;
private final Symlink symlink;
- @Nullable private final FileArtifactValue fileArtifactValue;
/** C'tor for {@link #stripMetadataForTesting()}. */
private SymlinkToDirectory(RootedPath targetPath, Symlink symlink) {
this.path = Preconditions.checkNotNull(targetPath);
- this.metadataHash = 0;
+ this.metadata = EMPTY_METADATA;
this.symlink = symlink;
- this.fileArtifactValue = null;
}
private SymlinkToDirectory(
RootedPath targetPath, RootedPath linkNamePath, PathFragment linkValue) {
this.path = Preconditions.checkNotNull(targetPath);
- this.metadataHash = 0;
+ this.metadata = EMPTY_METADATA;
this.symlink = new Symlink(linkNamePath, linkValue);
- this.fileArtifactValue = null;
}
SymlinkToDirectory(
- RootedPath targetPath,
- RootedPath linkNamePath,
- PathFragment linkValue,
- int metadataHash,
- @Nullable FileArtifactValue fileArtifactValue) {
+ RootedPath targetPath, RootedPath linkNamePath, PathFragment linkValue, Object metadata) {
this.path = Preconditions.checkNotNull(targetPath);
- this.metadataHash = metadataHash;
+ this.metadata = metadata;
this.symlink = new Symlink(linkNamePath, linkValue);
- this.fileArtifactValue = fileArtifactValue;
}
@Override
@@ -633,9 +586,8 @@
}
@Override
- @Nullable
- public int getMetadataHash() {
- return metadataHash;
+ public Object getMetadata() {
+ return metadata;
}
@Override
@@ -647,13 +599,13 @@
return false;
}
return this.path.equals(((SymlinkToDirectory) obj).path)
- && Objects.equal(this.metadataHash, ((SymlinkToDirectory) obj).metadataHash)
+ && this.metadata.equals(((SymlinkToDirectory) obj).metadata)
&& this.symlink.equals(((SymlinkToDirectory) obj).symlink);
}
@Override
public int hashCode() {
- return Objects.hashCode(path, metadataHash, symlink);
+ return Objects.hashCode(path, metadata, symlink);
}
@Override
@@ -672,11 +624,6 @@
}
@Override
- public FileArtifactValue getValueForDerivedArtifacts() {
- return fileArtifactValue;
- }
-
- @Override
public PathFragment getTargetInSymlinkTree(boolean followSymlinks) {
return followSymlinks ? path.asPath().asFragment() : symlink.unresolvedLinkTarget;
}
@@ -685,9 +632,8 @@
static final class ResolvedFileFactory {
private ResolvedFileFactory() {}
- public static ResolvedFile regularFile(
- RootedPath path, FileStateValue metadata, FileArtifactValue fileArtifactValue) {
- return new RegularFile(path, metadata, fileArtifactValue);
+ public static ResolvedFile regularFile(RootedPath path, Object metadata) {
+ return new RegularFile(path, metadata);
}
public static ResolvedFile directory(RootedPath path) {
@@ -698,28 +644,18 @@
RootedPath targetPath,
RootedPath linkNamePath,
PathFragment linkTargetPath,
- FileStateValue metadata,
- FileArtifactValue fileArtifactValue) {
- return new SymlinkToFile(
- targetPath, linkNamePath, linkTargetPath, metadata, fileArtifactValue);
+ Object metadata) {
+ return new SymlinkToFile(targetPath, linkNamePath, linkTargetPath, metadata);
}
public static ResolvedFile symlinkToDirectory(
- RootedPath targetPath,
- RootedPath linkNamePath,
- PathFragment linkValue,
- int metadataHash,
- FileArtifactValue fileArtifactValue) {
- return new SymlinkToDirectory(
- targetPath, linkNamePath, linkValue, metadataHash, fileArtifactValue);
+ RootedPath targetPath, RootedPath linkNamePath, PathFragment linkValue, Object metadata) {
+ return new SymlinkToDirectory(targetPath, linkNamePath, linkValue, metadata);
}
public static ResolvedFile danglingSymlink(
- RootedPath linkNamePath,
- PathFragment linkValue,
- FileStateValue metadata,
- FileArtifactValue fileArtifactValue) {
- return new DanglingSymlink(linkNamePath, linkValue, metadata, fileArtifactValue);
+ RootedPath linkNamePath, PathFragment linkValue, Object metadata) {
+ return new DanglingSymlink(linkNamePath, linkValue, metadata);
}
}
@@ -747,6 +683,8 @@
}
}
+ private static final Integer EMPTY_METADATA = new Integer(0);
+
/**
* Path and type information about a single file or symlink.
*
@@ -766,15 +704,11 @@
RootedPath getPath();
/**
- * Hash code of associated metadata.
- *
- * <p>This is usually some hash of the {@link FileStateValue} of the underlying filesystem
- * entity.
- *
- * <p>If tests stripped the metadata or the {@link ResolvedFile} was created by the
- * {@link ResolvedFileFactoryForTesting}, this method returns 0.
+ * Return the best effort metadata about the target. Currently this will be a FileStateValue for
+ * source targets. For generated targets we try to return a FileArtifactValue when possible, or
+ * else this will be a Integer hashcode of the target.
*/
- int getMetadataHash();
+ Object getMetadata();
/**
* Returns the path of the Fileset-output symlink relative to the output directory.
@@ -792,15 +726,12 @@
*/
PathFragment getTargetInSymlinkTree(boolean followSymlinks) throws DanglingSymlinkException;
- @Nullable
- FileArtifactValue getValueForDerivedArtifacts();
-
/**
- * Returns a copy of this object with the metadata stripped away.
+ * Returns a copy of this object with the metadataHash stripped away.
*
- * <p>This method should only be used by tests that wish to assert that this
- * {@link ResolvedFile} refers to the expected absolute path and has the expected type, without
- * asserting its actual contents (which the metadata is a function of).
+ * <p>This method should only be used by tests that wish to assert that this {@link
+ * ResolvedFile} refers to the expected absolute path and has the expected type, without
+ * asserting its actual contents (which the metadataHash is a function of).
*/
@VisibleForTesting
ResolvedFile stripMetadataForTesting();