From 602cc856051b02328ed56e2af808b829dafecd4b Mon Sep 17 00:00:00 2001 From: shahan Date: Wed, 6 Jun 2018 20:09:57 -0700 Subject: Refactoring: makes the code simpler by deleting Metadata and InputArtifactData. (minor) ActionFS now implements MetadataProvider.getInput PiperOrigin-RevId: 199575194 --- src/main/java/com/google/devtools/build/lib/BUILD | 1 + .../build/lib/actions/ActionCacheChecker.java | 64 +-- .../devtools/build/lib/actions/ActionInputMap.java | 19 +- .../build/lib/actions/FileArtifactValue.java | 502 +++++++++++++++++++++ .../build/lib/actions/FileContentsProxy.java | 87 ++++ .../devtools/build/lib/actions/FileStateValue.java | 438 ++++++++++++++++++ .../devtools/build/lib/actions/FileValue.java | 343 ++++++++++++++ .../actions/InconsistentFilesystemException.java | 29 ++ .../build/lib/actions/MetadataProvider.java | 12 +- .../build/lib/actions/cache/ActionCache.java | 9 +- .../build/lib/actions/cache/DigestUtils.java | 9 +- .../devtools/build/lib/actions/cache/Metadata.java | 72 --- .../build/lib/actions/cache/MetadataHandler.java | 15 +- .../lib/actions/cache/VirtualActionInput.java | 5 +- .../lib/bazel/repository/MavenServerFunction.java | 2 +- .../skylark/SkylarkRepositoryContext.java | 2 +- .../android/AndroidNdkRepositoryFunction.java | 2 +- .../rules/android/AndroidRepositoryFunction.java | 4 +- .../android/AndroidSdkRepositoryFunction.java | 4 +- .../google/devtools/build/lib/exec/BinTools.java | 9 +- .../build/lib/exec/SingleBuildFileCache.java | 11 +- .../devtools/build/lib/exec/SpawnLogContext.java | 5 +- .../build/lib/query2/SkyQueryEnvironment.java | 2 +- .../build/lib/remote/RemoteSpawnCache.java | 5 +- .../build/lib/remote/TreeNodeRepository.java | 8 +- .../devtools/build/lib/remote/util/DigestUtil.java | 4 +- .../devtools/build/lib/rules/cpp/FdoSupport.java | 2 +- .../rules/repository/LocalRepositoryFunction.java | 2 +- .../repository/NewLocalRepositoryFunction.java | 4 +- .../rules/repository/NewRepositoryFileHandler.java | 2 +- .../repository/RepositoryDelegatorFunction.java | 2 +- .../lib/rules/repository/RepositoryFunction.java | 4 +- .../build/lib/skyframe/ASTFileLookupFunction.java | 2 + .../lib/skyframe/ActionExecutionFunction.java | 20 +- .../build/lib/skyframe/ActionExecutionValue.java | 3 + .../build/lib/skyframe/ActionFileSystem.java | 20 +- .../build/lib/skyframe/ActionMetadataHandler.java | 20 +- .../lib/skyframe/AggregatingArtifactValue.java | 1 + .../build/lib/skyframe/ArtifactFunction.java | 2 + .../build/lib/skyframe/AspectFunction.java | 1 + .../BlacklistedPackagePrefixesFunction.java | 2 + .../lib/skyframe/DirectoryListingFunction.java | 2 + .../build/lib/skyframe/DirectoryListingValue.java | 1 + .../build/lib/skyframe/DirtinessCheckerUtils.java | 3 +- .../EnvironmentBackedRecursivePackageProvider.java | 1 + .../build/lib/skyframe/FileArtifactValue.java | 500 -------------------- .../build/lib/skyframe/FileContentsProxy.java | 90 ---- .../devtools/build/lib/skyframe/FileFunction.java | 3 + .../build/lib/skyframe/FileStateFunction.java | 1 + .../build/lib/skyframe/FileStateValue.java | 437 ------------------ .../devtools/build/lib/skyframe/FileValue.java | 342 -------------- .../build/lib/skyframe/FilesystemValueChecker.java | 1 + .../devtools/build/lib/skyframe/GlobFunction.java | 2 + .../GraphBackedRecursivePackageProvider.java | 1 + .../skyframe/InconsistentFilesystemException.java | 29 -- .../build/lib/skyframe/InputArtifactData.java | 89 ---- .../skyframe/LocalRepositoryLookupFunction.java | 2 + .../build/lib/skyframe/PackageFunction.java | 2 + .../build/lib/skyframe/PackageLookupFunction.java | 2 + .../build/lib/skyframe/PerActionFileCache.java | 12 +- .../lib/skyframe/ProcessPackageDirectory.java | 2 + .../RecursiveFilesystemTraversalFunction.java | 3 + .../RecursiveFilesystemTraversalValue.java | 1 + .../build/lib/skyframe/RunfilesArtifactValue.java | 1 + .../lib/skyframe/SequencedSkyframeExecutor.java | 10 +- .../devtools/build/lib/skyframe/SkyFunctions.java | 2 - .../build/lib/skyframe/SkyframeActionExecutor.java | 6 +- .../build/lib/skyframe/SkyframeExecutor.java | 10 +- .../skyframe/SkyframeIncrementalBuildMonitor.java | 3 +- .../SkyframePackageLoaderWithValueEnvironment.java | 1 + .../lib/skyframe/SkylarkImportLookupFunction.java | 1 + .../build/lib/skyframe/TargetMarkerFunction.java | 1 + .../build/lib/skyframe/TreeArtifactValue.java | 90 ++-- .../build/lib/skyframe/WorkspaceASTFunction.java | 1 + .../skyframe/packages/AbstractPackageLoader.java | 6 +- .../devtools/build/lib/skyframe/packages/BUILD | 1 + .../devtools/build/lib/worker/WorkerFilesHash.java | 4 +- src/test/java/com/google/devtools/build/lib/BUILD | 1 + .../build/lib/actions/ActionCacheCheckerTest.java | 4 +- .../build/lib/actions/ActionInputMapTest.java | 9 +- .../cache/CompactPersistentActionCacheTest.java | 2 +- .../build/lib/actions/util/ActionsTestUtil.java | 4 +- .../build/lib/exec/SpawnInputExpanderTest.java | 2 +- .../lib/exec/util/FakeActionInputFileCache.java | 8 +- .../build/lib/remote/FakeActionInputFileCache.java | 7 +- .../lib/repository/ExternalPackageUtilTest.java | 6 +- .../rules/repository/RepositoryDelegatorTest.java | 6 +- .../rules/repository/RepositoryFunctionTest.java | 10 +- .../ActionTemplateExpansionFunctionTest.java | 1 + .../build/lib/skyframe/ArtifactFunctionTest.java | 4 +- .../lib/skyframe/ArtifactFunctionTestCase.java | 6 +- .../ContainingPackageLookupFunctionTest.java | 10 +- .../build/lib/skyframe/FileArtifactValueTest.java | 3 +- .../build/lib/skyframe/FileContentsProxyTest.java | 1 + .../build/lib/skyframe/FileFunctionTest.java | 9 +- .../build/lib/skyframe/FileStateValueTest.java | 2 + .../devtools/build/lib/skyframe/FileValueTest.java | 2 + .../lib/skyframe/FilesetEntryFunctionTest.java | 10 +- .../lib/skyframe/FilesystemValueCheckerTest.java | 11 +- .../build/lib/skyframe/GlobFunctionTest.java | 7 +- .../LocalRepositoryLookupFunctionTest.java | 6 +- .../build/lib/skyframe/PackageFunctionTest.java | 4 +- .../lib/skyframe/PackageLookupFunctionTest.java | 10 +- .../RecursiveFilesystemTraversalFunctionTest.java | 10 +- .../lib/skyframe/SkyframeAwareActionTest.java | 1 + .../lib/skyframe/TimestampBuilderTestCase.java | 6 +- .../lib/skyframe/TreeArtifactMetadataTest.java | 9 +- .../lib/skyframe/WorkspaceASTFunctionTest.java | 3 +- .../lib/skyframe/WorkspaceFileFunctionTest.java | 8 +- 109 files changed, 1780 insertions(+), 1815 deletions(-) create mode 100644 src/main/java/com/google/devtools/build/lib/actions/FileArtifactValue.java create mode 100644 src/main/java/com/google/devtools/build/lib/actions/FileContentsProxy.java create mode 100644 src/main/java/com/google/devtools/build/lib/actions/FileStateValue.java create mode 100644 src/main/java/com/google/devtools/build/lib/actions/FileValue.java create mode 100644 src/main/java/com/google/devtools/build/lib/actions/InconsistentFilesystemException.java delete mode 100644 src/main/java/com/google/devtools/build/lib/actions/cache/Metadata.java delete mode 100644 src/main/java/com/google/devtools/build/lib/skyframe/FileArtifactValue.java delete mode 100644 src/main/java/com/google/devtools/build/lib/skyframe/FileContentsProxy.java delete mode 100644 src/main/java/com/google/devtools/build/lib/skyframe/FileStateValue.java delete mode 100644 src/main/java/com/google/devtools/build/lib/skyframe/FileValue.java delete mode 100644 src/main/java/com/google/devtools/build/lib/skyframe/InconsistentFilesystemException.java delete mode 100644 src/main/java/com/google/devtools/build/lib/skyframe/InputArtifactData.java diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD index 27f1e62f8a..fbfcff804b 100644 --- a/src/main/java/com/google/devtools/build/lib/BUILD +++ b/src/main/java/com/google/devtools/build/lib/BUILD @@ -808,6 +808,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib:runtime", "//src/main/java/com/google/devtools/build/lib:skylarkinterface", "//src/main/java/com/google/devtools/build/lib:util", + "//src/main/java/com/google/devtools/build/lib/actions", "//src/main/java/com/google/devtools/build/lib/bazel/repository/cache", "//src/main/java/com/google/devtools/build/lib/bazel/repository/downloader", "//src/main/java/com/google/devtools/build/lib/buildeventstream", diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java b/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java index 63256d77e9..4b72809271 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java +++ b/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java @@ -22,12 +22,12 @@ import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.ActionAnalysisMetadata.MiddlemanType; import com.google.devtools.build.lib.actions.cache.ActionCache; import com.google.devtools.build.lib.actions.cache.DigestUtils; -import com.google.devtools.build.lib.actions.cache.Metadata; import com.google.devtools.build.lib.actions.cache.MetadataHandler; import com.google.devtools.build.lib.actions.cache.Protos.ActionCacheStatistics.MissReason; import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.events.EventKind; +import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; import java.io.IOException; import java.util.ArrayList; @@ -51,27 +51,7 @@ import javax.annotation.Nullable; */ public class ActionCacheChecker { private static final byte[] EMPTY_DIGEST = new byte[0]; - private static final Metadata CONSTANT_METADATA = new Metadata() { - @Override - public FileStateType getType() { - return FileStateType.REGULAR_FILE; - } - - @Override - public byte[] getDigest() { - return EMPTY_DIGEST; - } - - @Override - public long getSize() { - return 0; - } - - @Override - public long getModifiedTime() { - return -1; - } - }; + private static final FileArtifactValue CONSTANT_METADATA = new ConstantMetadataValue(); private final ActionCache actionCache; private final ActionKeyContext actionKeyContext; @@ -164,7 +144,7 @@ public class ActionCacheChecker { Iterable artifacts = checkOutput ? Iterables.concat(action.getOutputs(), actionInputs) : actionInputs; - Map mdMap = new HashMap<>(); + Map mdMap = new HashMap<>(); for (Artifact artifact : artifacts) { mdMap.put(artifact.getExecPathString(), getMetadataMaybe(metadataHandler, artifact)); } @@ -324,8 +304,8 @@ public class ActionCacheChecker { return false; } - private static Metadata getMetadataOrConstant(MetadataHandler metadataHandler, Artifact artifact) - throws IOException { + private static FileArtifactValue getMetadataOrConstant( + MetadataHandler metadataHandler, Artifact artifact) throws IOException { if (artifact.isConstantMetadata()) { return CONSTANT_METADATA; } else { @@ -337,7 +317,8 @@ public class ActionCacheChecker { // to trigger a re-execution, so we should catch the IOException explicitly there. In others, we // should propagate the exception, because it is unexpected (e.g., bad file system state). @Nullable - private static Metadata getMetadataMaybe(MetadataHandler metadataHandler, Artifact artifact) { + private static FileArtifactValue getMetadataMaybe( + MetadataHandler metadataHandler, Artifact artifact) { try { return getMetadataOrConstant(metadataHandler, artifact); } catch (IOException e) { @@ -373,7 +354,7 @@ public class ActionCacheChecker { // 'constant' metadata for the volatile workspace status output. The volatile output // contains information such as timestamps, and even when --stamp is enabled, we don't want // to rebuild everything if only that file changes. - Metadata metadata = getMetadataOrConstant(metadataHandler, output); + FileArtifactValue metadata = getMetadataOrConstant(metadataHandler, output); Preconditions.checkState(metadata != null); entry.addFile(output.getExecPath(), metadata); } @@ -554,4 +535,33 @@ public class ActionCacheChecker { this.cacheKey = Preconditions.checkNotNull(cacheKey); } } + + private static final class ConstantMetadataValue extends FileArtifactValue + implements FileArtifactValue.Singleton { + @Override + public FileStateType getType() { + return FileStateType.REGULAR_FILE; + } + + @Override + public byte[] getDigest() { + return EMPTY_DIGEST; + } + + @Override + public long getSize() { + return 0; + } + + @Override + public long getModifiedTime() { + return -1; + } + + @Override + public boolean wasModifiedSinceDigest(Path path) { + throw new UnsupportedOperationException( + "ConstantMetadataValue doesn't support wasModifiedSinceDigest " + path.toString()); + } + } } diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionInputMap.java b/src/main/java/com/google/devtools/build/lib/actions/ActionInputMap.java index c938b07419..09014fe25a 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/ActionInputMap.java +++ b/src/main/java/com/google/devtools/build/lib/actions/ActionInputMap.java @@ -14,15 +14,14 @@ package com.google.devtools.build.lib.actions; import com.google.common.base.Preconditions; -import com.google.devtools.build.lib.actions.cache.Metadata; import java.util.Arrays; import javax.annotation.Nullable; /** * Helper for {@link MetadataProvider} implementations. * - *

Allows {@link Metadata} lookups by exec path or {@link ActionInput}. Also allows {@link - * ActionInput} to be looked up by exec path. + *

Allows {@link FileArtifactValue} lookups by exec path or {@link ActionInput}. Also + * allows {@link ActionInput} to be looked up by exec path. * *

This class is thread-compatible. */ @@ -30,7 +29,7 @@ public final class ActionInputMap implements MetadataProvider { /** * {@link ActionInput} keys stored in even indices * - *

{@link Metadata} values stored in odd indices + *

{@link FileArtifactValue} values stored in odd indices */ private Object[] data; @@ -55,19 +54,19 @@ public final class ActionInputMap implements MetadataProvider { @Nullable @Override - public Metadata getMetadata(ActionInput input) { + public FileArtifactValue getMetadata(ActionInput input) { return getMetadata(input.getExecPathString()); } @Nullable - public Metadata getMetadata(String execPathString) { + public FileArtifactValue getMetadata(String execPathString) { int hashCode = execPathString.hashCode(); int probe = getProbe(hashCode); ActionInput nextKey; while ((nextKey = (ActionInput) data[probe]) != null) { if (hashCode == nextKey.getExecPathString().hashCode() && nextKey.getExecPathString().equals(execPathString)) { - return (Metadata) data[probe + 1]; + return (FileArtifactValue) data[probe + 1]; } probe = incProbe(probe); } @@ -96,7 +95,7 @@ public final class ActionInputMap implements MetadataProvider { } /** @return true if an entry was added, false if the map already contains {@code input} */ - public boolean put(ActionInput input, Metadata metadata) { + public boolean put(ActionInput input, FileArtifactValue metadata) { Preconditions.checkNotNull(input); if (size * 4 >= data.length) { resize(); @@ -119,7 +118,7 @@ public final class ActionInputMap implements MetadataProvider { for (int i = 0; i < oldData.length; i += 2) { ActionInput key = (ActionInput) oldData[i]; if (key != null) { - Metadata value = (Metadata) oldData[i + 1]; + FileArtifactValue value = (FileArtifactValue) oldData[i + 1]; putImpl(key, value); } } @@ -131,7 +130,7 @@ public final class ActionInputMap implements MetadataProvider { * *

REQUIRES: there are free positions in {@link data}. */ - private boolean putImpl(ActionInput key, Metadata value) { + private boolean putImpl(ActionInput key, FileArtifactValue value) { int hashCode = key.getExecPathString().hashCode(); int probe = getProbe(hashCode); while (true) { diff --git a/src/main/java/com/google/devtools/build/lib/actions/FileArtifactValue.java b/src/main/java/com/google/devtools/build/lib/actions/FileArtifactValue.java new file mode 100644 index 0000000000..f9f80eefcf --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/actions/FileArtifactValue.java @@ -0,0 +1,502 @@ +// Copyright 2014 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package com.google.devtools.build.lib.actions; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; +import com.google.common.io.BaseEncoding; +import com.google.devtools.build.lib.actions.cache.DigestUtils; +import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; +import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; +import com.google.devtools.build.lib.vfs.FileStatus; +import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.Symlinks; +import com.google.devtools.build.skyframe.SkyValue; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.Objects; +import javax.annotation.Nullable; + +/** + * State of a file system object for the execution phase. + * + *

This is not used by Skyframe for invalidation, it is primarily used by the action cache and + * the various {@link com.google.devtools.build.lib.exec.SpawnRunner} implementations. + * + *

We have the following cases: + * + *

    + *
  • an ordinary file, in which case we would expect to see a digest and size; + *
  • a directory, in which case we would expect to see an mtime; + *
  • an intentionally omitted file which the build system is aware of but doesn't actually + * exist, where all access methods are unsupported; + *
  • a "middleman marker" object, which has a null digest, 0 size, and mtime of 0. + *
  • The "self data" of a TreeArtifact, where we would expect to see a digest representing the + * artifact's contents, and a size of 0. + *
+ */ +@Immutable +@ThreadSafe +public abstract class FileArtifactValue implements SkyValue { + @AutoCodec public static final FileArtifactValue DEFAULT_MIDDLEMAN = new SingletonMarkerValue(); + /** Data that marks that a file is not present on the filesystem. */ + @AutoCodec public static final FileArtifactValue MISSING_FILE_MARKER = new SingletonMarkerValue(); + + /** + * Represents an omitted file -- we are aware of it but it doesn't exist. All access methods are + * unsupported. + */ + @AutoCodec public static final FileArtifactValue OMITTED_FILE_MARKER = new OmittedFileValue(); + + /** + * Marker interface for singleton implementations of this class. + * + *

Needed for a correct implementation of {@code equals}. + */ + public interface Singleton {} + + /** + * The type of the underlying file system object. If it is a regular file, then it is guaranteed + * to have a digest. Otherwise it does not have a digest. + */ + public abstract FileStateType getType(); + + /** + * Returns a digest of the content of the underlying file system object; must always return a + * non-null value for instances of type {@link FileStateType#REGULAR_FILE}. Otherwise may return + * null. + * + *

All instances of this interface must either have a digest or return a last-modified time. + * Clients should prefer using the digest for content identification (e.g., for caching), and only + * fall back to the last-modified time if no digest is available. + * + *

The return value is owned by this object and must not be modified. + */ + @Nullable + public abstract byte[] getDigest(); + + /** Returns the file's size, or 0 if the underlying file system object is not a file. */ + // TODO(ulfjack): Throw an exception if it's not a file. + public abstract long getSize(); + + /** + * Returns the last modified time; see the documentation of {@link #getDigest} for when this can + * and should be called. + */ + public abstract long getModifiedTime(); + + /** + * Index used to resolve remote files. + * + *

0 indicates that no such information is available which can mean that it's either a local + * file or empty. + */ + public int getLocationIndex() { + return 0; + } + + /** + * Provides a best-effort determination whether the file was changed since the digest was + * computed. This method performs file system I/O, so may be expensive. It's primarily intended to + * avoid storing bad cache entries in an action cache. It should return true if there is a chance + * that the file was modified since the digest was computed. Better not upload if we are not sure + * that the cache entry is reliable. + */ + public abstract boolean wasModifiedSinceDigest(Path path) throws IOException; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof FileArtifactValue)) { + return false; + } + if ((this instanceof Singleton) || (o instanceof Singleton)) { + return false; + } + FileArtifactValue m = (FileArtifactValue) o; + if (getType() != m.getType()) { + return false; + } + if (getDigest() != null) { + return Arrays.equals(getDigest(), m.getDigest()) && getSize() == m.getSize(); + } else { + return getModifiedTime() == m.getModifiedTime(); + } + } + + @Override + public int hashCode() { + if (this instanceof Singleton) { + return System.identityHashCode(this); + } + // Hash digest by content, not reference. + if (getDigest() != null) { + return 37 * Long.hashCode(getSize()) + Arrays.hashCode(getDigest()); + } else { + return Long.hashCode(getModifiedTime()); + } + } + + public static FileArtifactValue create(Artifact artifact, FileValue fileValue) + throws IOException { + boolean isFile = fileValue.isFile(); + FileContentsProxy proxy = getProxyFromFileStateValue(fileValue.realFileStateValue()); + return create( + artifact.getPath(), + isFile, + isFile ? fileValue.getSize() : 0, + proxy, + isFile ? fileValue.getDigest() : null); + } + + public static FileArtifactValue create( + Artifact artifact, FileValue fileValue, @Nullable byte[] injectedDigest) throws IOException { + boolean isFile = fileValue.isFile(); + FileContentsProxy proxy = getProxyFromFileStateValue(fileValue.realFileStateValue()); + return create( + artifact.getPath(), isFile, isFile ? fileValue.getSize() : 0, proxy, injectedDigest); + } + + @VisibleForTesting + public static FileArtifactValue create(Artifact artifact) throws IOException { + return create(artifact.getPath()); + } + + @VisibleForTesting + public static FileArtifactValue create(Path path) throws IOException { + // Caution: there's a race condition between stating the file and computing the + // digest. We need to stat first, since we're using the stat to detect changes. + // We follow symlinks here to be consistent with getDigest. + FileStatus stat = path.stat(Symlinks.FOLLOW); + return create(path, stat.isFile(), stat.getSize(), FileContentsProxy.create(stat), null); + } + + private static FileArtifactValue create( + Path path, boolean isFile, long size, FileContentsProxy proxy, @Nullable byte[] digest) + throws IOException { + if (!isFile) { + // In this case, we need to store the mtime because the action cache uses mtime for + // directories to determine if this artifact has changed. We want this code path to go away + // somehow. + return new DirectoryArtifactValue(path.getLastModifiedTime()); + } + if (digest == null) { + digest = DigestUtils.getDigestOrFail(path, size); + } + Preconditions.checkState(digest != null, path); + return new RegularFileArtifactValue(digest, proxy, size); + } + + public static FileArtifactValue createForVirtualActionInput(byte[] digest, long size) { + return new RegularFileArtifactValue(digest, /*proxy=*/ null, size); + } + + public static FileArtifactValue createNormalFile( + byte[] digest, @Nullable FileContentsProxy proxy, long size) { + return new RegularFileArtifactValue(digest, proxy, size); + } + + public static FileArtifactValue createNormalFile(FileValue fileValue) { + FileContentsProxy proxy = getProxyFromFileStateValue(fileValue.realFileStateValue()); + return new RegularFileArtifactValue(fileValue.getDigest(), proxy, fileValue.getSize()); + } + + @VisibleForTesting + public static FileArtifactValue createNormalFile(byte[] digest, long size) { + return createNormalFile(digest, /*proxy=*/ null, size); + } + + public static FileArtifactValue createDirectory(long mtime) { + return new DirectoryArtifactValue(mtime); + } + + /** + * Creates a FileArtifactValue used as a 'proxy' input for other ArtifactValues. These are used in + * {@link com.google.devtools.build.lib.actions.ActionCacheChecker}. + */ + public static FileArtifactValue createProxy(byte[] digest) { + Preconditions.checkNotNull(digest); + return createNormalFile(digest, /*proxy=*/ null, /*size=*/ 0); + } + + private static final class DirectoryArtifactValue extends FileArtifactValue { + private final long mtime; + + private DirectoryArtifactValue(long mtime) { + this.mtime = mtime; + } + + @Override + public FileStateType getType() { + return FileStateType.DIRECTORY; + } + + @Nullable + @Override + public byte[] getDigest() { + return null; + } + + @Override + public long getModifiedTime() { + return mtime; + } + + @Override + public long getSize() { + return 0; + } + + @Override + public boolean wasModifiedSinceDigest(Path path) throws IOException { + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("mtime", mtime).toString(); + } + } + + private static final class RegularFileArtifactValue extends FileArtifactValue { + private final byte[] digest; + @Nullable private final FileContentsProxy proxy; + private final long size; + + private RegularFileArtifactValue(byte[] digest, @Nullable FileContentsProxy proxy, long size) { + this.digest = Preconditions.checkNotNull(digest); + this.proxy = proxy; + this.size = size; + } + + @Override + public FileStateType getType() { + return FileStateType.REGULAR_FILE; + } + + @Override + public byte[] getDigest() { + return digest; + } + + @Override + public long getSize() { + return size; + } + + @Override + public boolean wasModifiedSinceDigest(Path path) throws IOException { + if (proxy == null) { + return false; + } + FileStatus stat = path.statIfFound(Symlinks.FOLLOW); + return stat == null || !stat.isFile() || !proxy.equals(FileContentsProxy.create(stat)); + } + + @Override + public long getModifiedTime() { + throw new UnsupportedOperationException( + "regular file's mtime should never be called. (" + this + ")"); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("digest", BaseEncoding.base16().lowerCase().encode(digest)) + .add("size", size) + .add("proxy", proxy).toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof RegularFileArtifactValue)) { + return false; + } + RegularFileArtifactValue r = (RegularFileArtifactValue) o; + return Arrays.equals(digest, r.digest) && Objects.equals(proxy, r.proxy) && size == r.size; + } + + @Override + public int hashCode() { + return (proxy != null ? 127 * proxy.hashCode() : 0) + + 37 * Long.hashCode(getSize()) + Arrays.hashCode(getDigest()); + } + } + + /** Metadata for remotely stored files. */ + public static final class RemoteFileArtifactValue extends FileArtifactValue { + private final byte[] digest; + private final long size; + private final int locationIndex; + + public RemoteFileArtifactValue(byte[] digest, long size, int locationIndex) { + this.digest = digest; + this.size = size; + this.locationIndex = locationIndex; + } + + @Override + public FileStateType getType() { + return FileStateType.REGULAR_FILE; + } + + @Override + public byte[] getDigest() { + return digest; + } + + @Override + public long getSize() { + return size; + } + + @Override + public long getModifiedTime() { + throw new UnsupportedOperationException( + "RemoteFileArifactValue doesn't support getModifiedTime"); + } + + @Override + public int getLocationIndex() { + return locationIndex; + } + + @Override + public boolean wasModifiedSinceDigest(Path path) { + throw new UnsupportedOperationException(); + } + } + + /** File stored inline in metadata. */ + public static final class InlineFileArtifactValue extends FileArtifactValue { + private final byte[] data; + private final byte[] digest; + + public InlineFileArtifactValue(byte[] data, byte[] digest) { + this.data = Preconditions.checkNotNull(data); + this.digest = Preconditions.checkNotNull(digest); + } + + public ByteArrayInputStream getInputStream() { + return new ByteArrayInputStream(data); + } + + @Override + public FileStateType getType() { + return FileStateType.REGULAR_FILE; + } + + @Override + public byte[] getDigest() { + return digest; + } + + @Override + public long getSize() { + return data.length; + } + + @Override + public long getModifiedTime() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean wasModifiedSinceDigest(Path path) { + throw new UnsupportedOperationException(); + } + } + + private static FileContentsProxy getProxyFromFileStateValue(FileStateValue value) { + if (value instanceof FileStateValue.RegularFileStateValue) { + return ((FileStateValue.RegularFileStateValue) value).getContentsProxy(); + } else if (value instanceof FileStateValue.SpecialFileStateValue) { + return ((FileStateValue.SpecialFileStateValue) value).getContentsProxy(); + } + return null; + } + + private static final class SingletonMarkerValue extends FileArtifactValue implements Singleton { + @Override + public FileStateType getType() { + return FileStateType.NONEXISTENT; + } + + @Nullable + @Override + public byte[] getDigest() { + return null; + } + + @Override + public long getSize() { + return 0; + } + + @Override + public long getModifiedTime() { + return 0; + } + + @Override + public boolean wasModifiedSinceDigest(Path path) throws IOException { + return false; + } + + @Override + public String toString() { + return "singleton marker artifact value (" + hashCode() + ")"; + } + } + + private static final class OmittedFileValue extends FileArtifactValue implements Singleton { + @Override + public FileStateType getType() { + return FileStateType.NONEXISTENT; + } + + @Override + public byte[] getDigest() { + throw new UnsupportedOperationException(); + } + + @Override + public long getSize() { + throw new UnsupportedOperationException(); + } + + @Override + public long getModifiedTime() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean wasModifiedSinceDigest(Path path) throws IOException { + return false; + } + + @Override + public String toString() { + return "OMITTED_FILE_MARKER"; + } + } +} diff --git a/src/main/java/com/google/devtools/build/lib/actions/FileContentsProxy.java b/src/main/java/com/google/devtools/build/lib/actions/FileContentsProxy.java new file mode 100644 index 0000000000..b8a571bd25 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/actions/FileContentsProxy.java @@ -0,0 +1,87 @@ +// Copyright 2014 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package com.google.devtools.build.lib.actions; + +import com.google.devtools.build.lib.vfs.FileStatus; +import java.io.IOException; +import java.io.Serializable; +import java.util.Objects; + +/** + * In case we can't get a fast digest from the filesystem, we store this metadata as a proxy to the + * file contents. Currently it is a pair of a relevant timestamp and a "node id". On Linux the + * former is the ctime and the latter is the inode number. We might want to add the device number in + * the future. + * + *

For a Linux example of why mtime alone is insufficient, note that 'mv' preserves timestamps. + * So if files 'a' and 'b' initially have the same timestamp, then we would think 'b' is unchanged + * after the user executes `mv a b` between two builds. + */ +public final class FileContentsProxy implements Serializable { + private final long ctime; + private final long nodeId; + + /** + * Visible for serialization / deserialization. Do not use this method, but call {@link #create} + * instead. + */ + public FileContentsProxy(long ctime, long nodeId) { + this.ctime = ctime; + this.nodeId = nodeId; + } + + public static FileContentsProxy create(FileStatus stat) throws IOException { + // Note: there are file systems that return mtime for this call instead of ctime, such as the + // WindowsFileSystem. + return new FileContentsProxy(stat.getLastChangeTime(), stat.getNodeId()); + } + + /** Visible for serialization / deserialization. Do not use this method; use {@link #equals}. */ + public long getCTime() { + return ctime; + } + + /** Visible for serialization / deserialization. Do not use this method; use {@link #equals}. */ + public long getNodeId() { + return nodeId; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof FileContentsProxy)) { + return false; + } + + FileContentsProxy that = (FileContentsProxy) other; + return ctime == that.ctime && nodeId == that.nodeId; + } + + @Override + public int hashCode() { + return Objects.hash(ctime, nodeId); + } + + @Override + public String toString() { + return prettyPrint(); + } + + public String prettyPrint() { + return String.format("ctime of %d and nodeId of %d", ctime, nodeId); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/actions/FileStateValue.java b/src/main/java/com/google/devtools/build/lib/actions/FileStateValue.java new file mode 100644 index 0000000000..bc4b51ad71 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/actions/FileStateValue.java @@ -0,0 +1,438 @@ +// Copyright 2014 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package com.google.devtools.build.lib.actions; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; +import com.google.common.collect.Interner; +import com.google.devtools.build.lib.concurrent.BlazeInterners; +import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; +import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor; +import com.google.devtools.build.lib.vfs.FileStatus; +import com.google.devtools.build.lib.vfs.FileStatusWithDigest; +import com.google.devtools.build.lib.vfs.FileStatusWithDigestAdapter; +import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.RootedPath; +import com.google.devtools.build.lib.vfs.Symlinks; +import com.google.devtools.build.skyframe.AbstractSkyKey; +import com.google.devtools.build.skyframe.SkyFunctionName; +import com.google.devtools.build.skyframe.SkyValue; +import java.io.IOException; +import java.util.Arrays; +import java.util.Objects; +import javax.annotation.Nullable; + +/** + * Encapsulates the filesystem operations needed to get state for a path. This is equivalent to an + * 'lstat' that does not follow symlinks to determine what type of file the path is. + *

    + *
  • For a non-existent file, the non-existence is noted. + *
  • For a symlink, the symlink target is noted. + *
  • For a directory, the existence is noted. + *
  • For a file, the existence is noted, along with metadata about the file (e.g. + * file digest). See {@link RegularFileStateValue}. + *
      + * + *

      This class is an implementation detail of {@link FileValue} and should not be used by + * {@link com.google.devtools.build.skyframe.SkyFunction}s other than {@link FileFunction}. Instead, + * {@link FileValue} should be used by {@link com.google.devtools.build.skyframe.SkyFunction} + * consumers that care about files. + * + *

      All subclasses must implement {@link #equals} and {@link #hashCode} properly. + */ +@VisibleForTesting +public abstract class FileStateValue implements SkyValue { + public static final SkyFunctionName FILE_STATE = SkyFunctionName.create("FILE_STATE"); + + @AutoCodec + public static final DirectoryFileStateValue DIRECTORY_FILE_STATE_NODE = + new DirectoryFileStateValue(); + + @AutoCodec + public static final NonexistentFileStateValue NONEXISTENT_FILE_STATE_NODE = + new NonexistentFileStateValue(); + + protected FileStateValue() { + } + + public static FileStateValue create(RootedPath rootedPath, + @Nullable TimestampGranularityMonitor tsgm) throws InconsistentFilesystemException, + IOException { + Path path = rootedPath.asPath(); + // Stat, but don't throw an exception for the common case of a nonexistent file. This still + // throws an IOException in case any other IO error is encountered. + FileStatus stat = path.statIfFound(Symlinks.NOFOLLOW); + if (stat == null) { + return NONEXISTENT_FILE_STATE_NODE; + } + return createWithStatNoFollow(rootedPath, FileStatusWithDigestAdapter.adapt(stat), tsgm); + } + + public static FileStateValue createWithStatNoFollow( + RootedPath rootedPath, + FileStatusWithDigest statNoFollow, + @Nullable TimestampGranularityMonitor tsgm) + throws InconsistentFilesystemException, IOException { + Path path = rootedPath.asPath(); + if (statNoFollow.isFile()) { + return statNoFollow.isSpecialFile() + ? SpecialFileStateValue.fromStat(path.asFragment(), statNoFollow, tsgm) + : RegularFileStateValue.fromPath(path, statNoFollow, tsgm); + } else if (statNoFollow.isDirectory()) { + return DIRECTORY_FILE_STATE_NODE; + } else if (statNoFollow.isSymbolicLink()) { + return new SymlinkFileStateValue(path.readSymbolicLinkUnchecked()); + } + throw new InconsistentFilesystemException("according to stat, existing path " + path + " is " + + "neither a file nor directory nor symlink."); + } + + @VisibleForTesting + @ThreadSafe + public static Key key(RootedPath rootedPath) { + return Key.create(rootedPath); + } + + @AutoCodec.VisibleForSerialization + @AutoCodec + static class Key extends AbstractSkyKey { + private static final Interner interner = BlazeInterners.newWeakInterner(); + + private Key(RootedPath arg) { + super(arg); + } + + @AutoCodec.VisibleForSerialization + @AutoCodec.Instantiator + static Key create(RootedPath arg) { + return interner.intern(new Key(arg)); + } + + @Override + public SkyFunctionName functionName() { + return FILE_STATE; + } + } + + public abstract FileStateType getType(); + + /** Returns the target of the symlink, or throws an exception if this is not a symlink. */ + public PathFragment getSymlinkTarget() { + throw new IllegalStateException(); + } + + long getSize() { + throw new IllegalStateException(); + } + + @Nullable + byte[] getDigest() { + throw new IllegalStateException(); + } + + @Override + public String toString() { + return prettyPrint(); + } + + abstract String prettyPrint(); + + /** + * Implementation of {@link FileStateValue} for regular files that exist. + * + *

      A union of (digest, mtime). We use digests only if a fast digest lookup is available from + * the filesystem. If not, we fall back to mtime-based digests. This avoids the case where Blaze + * must read all files involved in the build in order to check for modifications in the case where + * fast digest lookups are not available. + */ + @ThreadSafe + @AutoCodec + public static final class RegularFileStateValue extends FileStateValue { + private final long size; + @Nullable private final byte[] digest; + @Nullable private final FileContentsProxy contentsProxy; + + public RegularFileStateValue(long size, byte[] digest, FileContentsProxy contentsProxy) { + Preconditions.checkState((digest == null) != (contentsProxy == null)); + this.size = size; + this.digest = digest; + this.contentsProxy = contentsProxy; + } + + /** + * Create a FileFileStateValue instance corresponding to the given existing file. + * @param stat must be of type "File". (Not a symlink). + */ + private static RegularFileStateValue fromPath(Path path, FileStatusWithDigest stat, + @Nullable TimestampGranularityMonitor tsgm) + throws InconsistentFilesystemException { + Preconditions.checkState(stat.isFile(), path); + + try { + byte[] digest = tryGetDigest(path, stat); + if (digest == null) { + // Note that TimestampGranularityMonitor#notifyDependenceOnFileTime is a thread-safe + // method. + if (tsgm != null) { + tsgm.notifyDependenceOnFileTime(path.asFragment(), stat.getLastChangeTime()); + } + return new RegularFileStateValue(stat.getSize(), null, FileContentsProxy.create(stat)); + } else { + // We are careful here to avoid putting the value ID into FileMetadata if we already have + // a digest. Arbitrary filesystems may do weird things with the value ID; a digest is more + // robust. + return new RegularFileStateValue(stat.getSize(), digest, null); + } + } catch (IOException e) { + String errorMessage = e.getMessage() != null + ? "error '" + e.getMessage() + "'" : "an error"; + throw new InconsistentFilesystemException("'stat' said " + path + " is a file but then we " + + "later encountered " + errorMessage + " which indicates that " + path + " is no " + + "longer a file. Did you delete it during the build?"); + } + } + + @Nullable + private static byte[] tryGetDigest(Path path, FileStatusWithDigest stat) throws IOException { + try { + byte[] digest = stat.getDigest(); + return digest != null ? digest : path.getFastDigest(); + } catch (IOException ioe) { + if (!path.isReadable()) { + return null; + } + throw ioe; + } + } + + @Override + public FileStateType getType() { + return FileStateType.REGULAR_FILE; + } + + @Override + public long getSize() { + return size; + } + + @Override + @Nullable + public byte[] getDigest() { + return digest; + } + + public FileContentsProxy getContentsProxy() { + return contentsProxy; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof RegularFileStateValue)) { + return false; + } + RegularFileStateValue other = (RegularFileStateValue) obj; + return size == other.size + && Arrays.equals(digest, other.digest) + && Objects.equals(contentsProxy, other.contentsProxy); + } + + @Override + public int hashCode() { + return Objects.hash(size, Arrays.hashCode(digest), contentsProxy); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("digest", digest) + .add("size", size) + .add("contentsProxy", contentsProxy).toString(); + } + + @Override + public String prettyPrint() { + String contents = digest != null + ? String.format("digest of %s", Arrays.toString(digest)) + : contentsProxy.prettyPrint(); + return String.format("regular file with size of %d and %s", size, contents); + } + } + + /** Implementation of {@link FileStateValue} for special files that exist. */ + @AutoCodec + public static final class SpecialFileStateValue extends FileStateValue { + private final FileContentsProxy contentsProxy; + + public SpecialFileStateValue(FileContentsProxy contentsProxy) { + this.contentsProxy = contentsProxy; + } + + static SpecialFileStateValue fromStat(PathFragment path, FileStatus stat, + @Nullable TimestampGranularityMonitor tsgm) throws IOException { + // Note that TimestampGranularityMonitor#notifyDependenceOnFileTime is a thread-safe method. + if (tsgm != null) { + tsgm.notifyDependenceOnFileTime(path, stat.getLastChangeTime()); + } + return new SpecialFileStateValue(FileContentsProxy.create(stat)); + } + + @Override + public FileStateType getType() { + return FileStateType.SPECIAL_FILE; + } + + @Override + long getSize() { + return 0; + } + + @Override + @Nullable + byte[] getDigest() { + return null; + } + + public FileContentsProxy getContentsProxy() { + return contentsProxy; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof SpecialFileStateValue)) { + return false; + } + SpecialFileStateValue other = (SpecialFileStateValue) obj; + return Objects.equals(contentsProxy, other.contentsProxy); + } + + @Override + public int hashCode() { + return contentsProxy.hashCode(); + } + + @Override + public String prettyPrint() { + return String.format("special file with %s", contentsProxy.prettyPrint()); + } + } + + /** Implementation of {@link FileStateValue} for directories that exist. */ + public static final class DirectoryFileStateValue extends FileStateValue { + + private DirectoryFileStateValue() { + } + + @Override + public FileStateType getType() { + return FileStateType.DIRECTORY; + } + + @Override + public String prettyPrint() { + return "directory"; + } + + // This object is normally a singleton, but deserialization produces copies. + @Override + public boolean equals(Object obj) { + return obj instanceof DirectoryFileStateValue; + } + + @Override + public int hashCode() { + return 7654321; + } + } + + /** Implementation of {@link FileStateValue} for symlinks. */ + @AutoCodec + public static final class SymlinkFileStateValue extends FileStateValue { + + private final PathFragment symlinkTarget; + + public SymlinkFileStateValue(PathFragment symlinkTarget) { + this.symlinkTarget = symlinkTarget; + } + + @Override + public FileStateType getType() { + return FileStateType.SYMLINK; + } + + @Override + public PathFragment getSymlinkTarget() { + return symlinkTarget; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof SymlinkFileStateValue)) { + return false; + } + SymlinkFileStateValue other = (SymlinkFileStateValue) obj; + return symlinkTarget.equals(other.symlinkTarget); + } + + @Override + public int hashCode() { + return symlinkTarget.hashCode(); + } + + @Override + public String prettyPrint() { + return "symlink to " + symlinkTarget; + } + } + + /** Implementation of {@link FileStateValue} for nonexistent files. */ + @AutoCodec.VisibleForSerialization + static final class NonexistentFileStateValue extends FileStateValue { + + private NonexistentFileStateValue() { + } + + @Override + public FileStateType getType() { + return FileStateType.NONEXISTENT; + } + + @Override + public String prettyPrint() { + return "nonexistent path"; + } + + // This object is normally a singleton, but deserialization produces copies. + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + return obj instanceof NonexistentFileStateValue; + } + + @Override + public int hashCode() { + return 8765432; + } + } +} diff --git a/src/main/java/com/google/devtools/build/lib/actions/FileValue.java b/src/main/java/com/google/devtools/build/lib/actions/FileValue.java new file mode 100644 index 0000000000..1fc72c1cae --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/actions/FileValue.java @@ -0,0 +1,343 @@ +// Copyright 2014 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package com.google.devtools.build.lib.actions; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; +import com.google.common.collect.Interner; +import com.google.devtools.build.lib.concurrent.BlazeInterners; +import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; +import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; +import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.RootedPath; +import com.google.devtools.build.skyframe.AbstractSkyKey; +import com.google.devtools.build.skyframe.SkyFunctionName; +import com.google.devtools.build.skyframe.SkyValue; +import java.util.Objects; +import javax.annotation.Nullable; + +/** + * A value that corresponds to a file (or directory or symlink or non-existent file), fully + * accounting for symlinks (e.g. proper dependencies on ancestor symlinks so as to be incrementally + * correct). Anything in Skyframe that cares about the fully resolved path of a file (e.g. anything + * that cares about the contents of a file) should have a dependency on the corresponding {@link + * FileValue}. + * + *

      Note that the existence of a file value does not imply that the file exists on the filesystem. + * File values for missing files will be created on purpose in order to facilitate incremental + * builds in the case those files have reappeared. + * + *

      This class contains the relevant metadata for a file, although not the contents. Note that + * since a FileValue doesn't store its corresponding SkyKey, it's possible for the FileValues for + * two different paths to be the same. + * + *

      This should not be used for build outputs; use {@link ArtifactSkyKey} to create keys for + * those. + */ +@Immutable +@ThreadSafe +public abstract class FileValue implements SkyValue { + public static final SkyFunctionName FILE = SkyFunctionName.create("FILE"); + + /** + * Exists to accommodate the control flow of {@link ActionMetadataHandler#getMetadata}. + * + *

      {@link ActionMetadataHandler#getMetadata} always checks {@link + * ActionMetadataHandler#outputArtifactData} before checking {@link + * ActionMetadataHandler#additionalOutputData} so some placeholder value is needed to allow an + * injected {@link FileArtifactValue} to be returned. + */ + @AutoCodec public static final FileValue PLACEHOLDER = new PlaceholderFileValue(); + + public boolean exists() { + return realFileStateValue().getType() != FileStateType.NONEXISTENT; + } + + /** Returns true if the original path is a symlink; the target path can never be a symlink. */ + public boolean isSymlink() { + return false; + } + + /** + * Returns true if this value corresponds to a file or symlink to an existing regular or special + * file. If so, its parent directory is guaranteed to exist. + */ + public boolean isFile() { + return realFileStateValue().getType() == FileStateType.REGULAR_FILE + || realFileStateValue().getType() == FileStateType.SPECIAL_FILE; + } + + /** + * Returns true if this value corresponds to a file or symlink to an existing special file. If so, + * its parent directory is guaranteed to exist. + */ + public boolean isSpecialFile() { + return realFileStateValue().getType() == FileStateType.SPECIAL_FILE; + } + + /** + * Returns true if the file is a directory or a symlink to an existing directory. If so, its + * parent directory is guaranteed to exist. + */ + public boolean isDirectory() { + return realFileStateValue().getType() == FileStateType.DIRECTORY; + } + + /** + * Returns the real rooted path of the file, taking ancestor symlinks into account. For example, + * the rooted path ['root']/['a/b'] is really ['root']/['c/b'] if 'a' is a symlink to 'b'. Note + * that ancestor symlinks outside the root boundary are not taken into consideration. + */ + public abstract RootedPath realRootedPath(); + + public abstract FileStateValue realFileStateValue(); + + /** + * Returns the unresolved link target if {@link #isSymlink()}. + * + *

      This is useful if the caller wants to, for example, duplicate a relative symlink. An actual + * example could be a build rule that copies a set of input files to the output directory, but + * upon encountering symbolic links it can decide between copying or following them. + */ + public PathFragment getUnresolvedLinkTarget() { + throw new IllegalStateException(this.toString()); + } + + public long getSize() { + Preconditions.checkState(isFile(), this); + return realFileStateValue().getSize(); + } + + @Nullable + public byte[] getDigest() { + Preconditions.checkState(isFile(), this); + return realFileStateValue().getDigest(); + } + + /** Returns a key for building a file value for the given root-relative path. */ + @ThreadSafe + public static Key key(RootedPath rootedPath) { + return Key.create(rootedPath); + } + + @AutoCodec.VisibleForSerialization + @AutoCodec + static class Key extends AbstractSkyKey { + private static final Interner interner = BlazeInterners.newWeakInterner(); + + private Key(RootedPath arg) { + super(arg); + } + + @AutoCodec.VisibleForSerialization + @AutoCodec.Instantiator + static Key create(RootedPath arg) { + return interner.intern(new Key(arg)); + } + + @Override + public SkyFunctionName functionName() { + return FILE; + } + } + + /** Only intended to be used by {@link FileFunction}. Should not be used for symlink cycles. */ + public static FileValue value( + RootedPath rootedPath, + FileStateValue fileStateValue, + RootedPath realRootedPath, + FileStateValue realFileStateValue) { + if (rootedPath.equals(realRootedPath)) { + Preconditions.checkState(fileStateValue.getType() != FileStateType.SYMLINK, + "rootedPath: %s, fileStateValue: %s, realRootedPath: %s, realFileStateValue: %s", + rootedPath, fileStateValue, realRootedPath, realFileStateValue); + return new RegularFileValue(rootedPath, fileStateValue); + } else { + if (fileStateValue.getType() == FileStateType.SYMLINK) { + return new SymlinkFileValue(realRootedPath, realFileStateValue, + fileStateValue.getSymlinkTarget()); + } else { + return new DifferentRealPathFileValue( + realRootedPath, realFileStateValue); + } + } + } + + /** + * Implementation of {@link FileValue} for files whose fully resolved path is the same as the + * requested path. For example, this is the case for the path "foo/bar/baz" if neither 'foo' nor + * 'foo/bar' nor 'foo/bar/baz' are symlinks. + */ + @VisibleForTesting + @AutoCodec + public static final class RegularFileValue extends FileValue { + + private final RootedPath rootedPath; + private final FileStateValue fileStateValue; + + public RegularFileValue(RootedPath rootedPath, FileStateValue fileStateValue) { + this.rootedPath = Preconditions.checkNotNull(rootedPath); + this.fileStateValue = Preconditions.checkNotNull(fileStateValue); + } + + @Override + public RootedPath realRootedPath() { + return rootedPath; + } + + @Override + public FileStateValue realFileStateValue() { + return fileStateValue; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj.getClass() != RegularFileValue.class) { + return false; + } + RegularFileValue other = (RegularFileValue) obj; + return rootedPath.equals(other.rootedPath) && fileStateValue.equals(other.fileStateValue); + } + + @Override + public int hashCode() { + return Objects.hash(rootedPath, fileStateValue); + } + + @Override + public String toString() { + return rootedPath + ", " + fileStateValue; + } + } + + /** + * Base class for {@link FileValue}s for files whose fully resolved path is different than the + * requested path. For example, this is the case for the path "foo/bar/baz" if at least one of + * 'foo', 'foo/bar', or 'foo/bar/baz' is a symlink. + */ + @AutoCodec.VisibleForSerialization + @AutoCodec + public static class DifferentRealPathFileValue extends FileValue { + + protected final RootedPath realRootedPath; + protected final FileStateValue realFileStateValue; + + public DifferentRealPathFileValue( + RootedPath realRootedPath, FileStateValue realFileStateValue) { + this.realRootedPath = Preconditions.checkNotNull(realRootedPath); + this.realFileStateValue = Preconditions.checkNotNull(realFileStateValue); + } + + @Override + public RootedPath realRootedPath() { + return realRootedPath; + } + + @Override + public FileStateValue realFileStateValue() { + return realFileStateValue; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj.getClass() != DifferentRealPathFileValue.class) { + return false; + } + DifferentRealPathFileValue other = (DifferentRealPathFileValue) obj; + return realRootedPath.equals(other.realRootedPath) + && realFileStateValue.equals(other.realFileStateValue); + } + + @Override + public int hashCode() { + return Objects.hash(realRootedPath, realFileStateValue); + } + + @Override + public String toString() { + return realRootedPath + ", " + realFileStateValue + " (symlink ancestor)"; + } + } + + /** Implementation of {@link FileValue} for files that are symlinks. */ + @VisibleForTesting + @AutoCodec + public static final class SymlinkFileValue extends DifferentRealPathFileValue { + private final PathFragment linkTarget; + + @VisibleForTesting + public SymlinkFileValue( + RootedPath realRootedPath, FileStateValue realFileStateValue, PathFragment linkTarget) { + super(realRootedPath, realFileStateValue); + this.linkTarget = linkTarget; + } + + @Override + public boolean isSymlink() { + return true; + } + + @Override + public PathFragment getUnresolvedLinkTarget() { + return linkTarget; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj.getClass() != SymlinkFileValue.class) { + return false; + } + SymlinkFileValue other = (SymlinkFileValue) obj; + return realRootedPath.equals(other.realRootedPath) + && realFileStateValue.equals(other.realFileStateValue) + && linkTarget.equals(other.linkTarget); + } + + @Override + public int hashCode() { + return Objects.hash(realRootedPath, realFileStateValue, linkTarget, Boolean.TRUE); + } + + @Override + public String toString() { + return String.format( + "symlink (real_path=%s, real_state=%s, link_value=%s)", + realRootedPath, realFileStateValue, linkTarget); + } + } + + private static final class PlaceholderFileValue extends FileValue { + private PlaceholderFileValue() {} + + @Override + public RootedPath realRootedPath() { + throw new UnsupportedOperationException(); + } + + @Override + public FileStateValue realFileStateValue() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/src/main/java/com/google/devtools/build/lib/actions/InconsistentFilesystemException.java b/src/main/java/com/google/devtools/build/lib/actions/InconsistentFilesystemException.java new file mode 100644 index 0000000000..e0b0f9a1c6 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/actions/InconsistentFilesystemException.java @@ -0,0 +1,29 @@ +// Copyright 2014 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package com.google.devtools.build.lib.actions; + +import java.io.IOException; + +/** + * Used to indicate a filesystem inconsistency, e.g. file 'a/b' exists but directory 'a' doesn't + * exist. This generally means the result of the build is undefined but we shouldn't crash hard. + */ +public class InconsistentFilesystemException extends IOException { + public InconsistentFilesystemException(String inconsistencyMessage) { + super("Inconsistent filesystem operations. " + inconsistencyMessage + " The results of the " + + "build are not guaranteed to be correct. You should probably run 'blaze clean' and " + + "investigate the filesystem inconsistency (likely due to filesytem updates concurrent " + + "with the build)"); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/actions/MetadataProvider.java b/src/main/java/com/google/devtools/build/lib/actions/MetadataProvider.java index 80d4104686..60db714d17 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/MetadataProvider.java +++ b/src/main/java/com/google/devtools/build/lib/actions/MetadataProvider.java @@ -13,7 +13,6 @@ // limitations under the License. package com.google.devtools.build.lib.actions; -import com.google.devtools.build.lib.actions.cache.Metadata; import java.io.IOException; import javax.annotation.Nullable; @@ -30,21 +29,18 @@ public interface MetadataProvider { * calls. * *

      Returned {@link Metadata} instance correspond to the final target of a symlink, and - * therefore must not have a type of - * {@link com.google.devtools.build.lib.actions.FileStateType#SYMLINK} themselves. + * therefore must not have a type of {@link FileStateType#SYMLINK} themselves. * - * The return value is owned by the cache and must not be modified. + *

      The return value is owned by the cache and must not be modified. * * @param input the input to retrieve the digest for * @return the artifact's digest or null if digest cannot be obtained (due to artifact - * non-existence, lookup errors, or any other reason) - * + * non-existence, lookup errors, or any other reason) * @throws DigestOfDirectoryException in case {@code input} is a directory. * @throws IOException If the file cannot be digested. - * */ @Nullable - Metadata getMetadata(ActionInput input) throws IOException; + FileArtifactValue getMetadata(ActionInput input) throws IOException; /** Looks up an input from its exec path. */ @Nullable diff --git a/src/main/java/com/google/devtools/build/lib/actions/cache/ActionCache.java b/src/main/java/com/google/devtools/build/lib/actions/cache/ActionCache.java index fc21b41a2d..c6ab5604a2 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/cache/ActionCache.java +++ b/src/main/java/com/google/devtools/build/lib/actions/cache/ActionCache.java @@ -18,6 +18,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.actions.cache.Protos.ActionCacheStatistics; import com.google.devtools.build.lib.actions.cache.Protos.ActionCacheStatistics.MissReason; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible; @@ -79,7 +80,7 @@ public interface ActionCache { // Null iff the corresponding action does not do input discovery. private final List files; // If null, md5Digest is non-null and the entry is immutable. - private Map mdMap; + private Map mdMap; private Md5Digest md5Digest; private final Md5Digest usedClientEnvDigest; @@ -103,10 +104,10 @@ public interface ActionCache { } /** - * Adds the artifact, specified by the executable relative path and its - * metadata into the cache entry. + * Adds the artifact, specified by the executable relative path and its metadata into the cache + * entry. */ - public void addFile(PathFragment relativePath, Metadata md) { + public void addFile(PathFragment relativePath, FileArtifactValue md) { Preconditions.checkState(mdMap != null); Preconditions.checkState(!isCorrupted()); Preconditions.checkState(md5Digest == null); diff --git a/src/main/java/com/google/devtools/build/lib/actions/cache/DigestUtils.java b/src/main/java/com/google/devtools/build/lib/actions/cache/DigestUtils.java index d16d1bae89..5e0f198273 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/cache/DigestUtils.java +++ b/src/main/java/com/google/devtools/build/lib/actions/cache/DigestUtils.java @@ -19,6 +19,7 @@ import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheStats; import com.google.common.io.BaseEncoding; import com.google.common.primitives.Longs; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.clock.BlazeClock; import com.google.devtools.build.lib.profiler.Profiler; import com.google.devtools.build.lib.profiler.ProfilerTask; @@ -286,15 +287,15 @@ public class DigestUtils { } /** - * @param mdMap A collection of (execPath, Metadata) pairs. Values may be null. + * @param mdMap A collection of (execPath, FileArtifactValue) pairs. Values may be null. * @return an order-independent digest from the given "set" of (path, metadata) pairs. */ - public static Md5Digest fromMetadata(Map mdMap) { + public static Md5Digest fromMetadata(Map mdMap) { byte[] result = new byte[Md5Digest.MD5_SIZE]; // Profiling showed that MD5 engine instantiation was a hotspot, so create one instance for // this computation to amortize its cost. Fingerprint fp = new Fingerprint(); - for (Map.Entry entry : mdMap.entrySet()) { + for (Map.Entry entry : mdMap.entrySet()) { xorWith(result, getDigest(fp, entry.getKey(), entry.getValue())); } return new Md5Digest(result); @@ -315,7 +316,7 @@ public class DigestUtils { return new Md5Digest(result); } - private static byte[] getDigest(Fingerprint fp, String execPath, Metadata md) { + private static byte[] getDigest(Fingerprint fp, String execPath, FileArtifactValue md) { fp.addString(execPath); if (md == null) { diff --git a/src/main/java/com/google/devtools/build/lib/actions/cache/Metadata.java b/src/main/java/com/google/devtools/build/lib/actions/cache/Metadata.java deleted file mode 100644 index b9a137d248..0000000000 --- a/src/main/java/com/google/devtools/build/lib/actions/cache/Metadata.java +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.lib.actions.cache; - -import com.google.devtools.build.lib.actions.FileStateType; -import javax.annotation.Nullable; - -/** - * An interface to represent the state of a file system object for the execution phase. This is not - * used by Skyframe for invalidation, it is primarily used by the action cache and the various - * {@link com.google.devtools.build.lib.exec.SpawnRunner} implementations. - */ -public interface Metadata { - /** - * Marker interface for singleton implementations of the Metadata interface. This is only needed - * for a correct implementation of {@code equals}. - */ - public interface Singleton { - } - - /** - * The type of the underlying file system object. If it is a regular file, then it is - * guaranteed to have a digest. Otherwise it does not have a digest. - */ - FileStateType getType(); - - /** - * Returns a digest of the content of the underlying file system object; must always return a - * non-null value for instances of type {@link FileStateType#REGULAR_FILE}. Otherwise may return - * null. - * - *

      All instances of this interface must either have a digest or return a last-modified time. - * Clients should prefer using the digest for content identification (e.g., for caching), and only - * fall back to the last-modified time if no digest is available. - * - *

      The return value is owned by this object and must not be modified. - */ - @Nullable - byte[] getDigest(); - - /** Returns the file's size, or 0 if the underlying file system object is not a file. */ - // TODO(ulfjack): Throw an exception if it's not a file. - long getSize(); - - /** - * Returns the last modified time; see the documentation of {@link #getDigest} for when this can - * and should be called. - */ - long getModifiedTime(); - - /** - * Index used to resolve remote files. - * - *

      0 indicates that no such information is available which can mean that it's either a local - * file or empty. - */ - default int getLocationIndex() { - return 0; - } -} diff --git a/src/main/java/com/google/devtools/build/lib/actions/cache/MetadataHandler.java b/src/main/java/com/google/devtools/build/lib/actions/cache/MetadataHandler.java index fc7e8b9983..62d03fd372 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/cache/MetadataHandler.java +++ b/src/main/java/com/google/devtools/build/lib/actions/cache/MetadataHandler.java @@ -16,16 +16,19 @@ package com.google.devtools.build.lib.actions.cache; import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.vfs.FileStatus; import java.io.IOException; /** - * Retrieves {@link Metadata} of {@link Artifact}s, and inserts virtual metadata as well. Some - * methods on this interface may only be called after a call to {@link #discardOutputMetadata}. - * Calling them before such a call results in an {@link IllegalStateException}. + * Retrieves {@link FileArtifactValue} of {@link Artifact}s, and inserts virtual metadata as well. * - *

      Note that implementations of this interface call chmod on output files if - * {@link #discardOutputMetadata} has been called. + *

      Some methods on this interface may only be called after a call to {@link + * #discardOutputMetadata}. Calling them before such a call results in an {@link + * IllegalStateException}. + * + *

      Note that implementations of this interface call chmod on output files if {@link + * #discardOutputMetadata} has been called. */ public interface MetadataHandler { /** @@ -35,7 +38,7 @@ public interface MetadataHandler { * @return metadata instance * @throws IOException if metadata could not be obtained. */ - Metadata getMetadata(Artifact artifact) throws IOException; + FileArtifactValue getMetadata(Artifact artifact) throws IOException; /** Sets digest for virtual artifacts (e.g. middlemen). {@code md5Digest} must not be null. */ void setDigestForVirtualArtifact(Artifact artifact, Md5Digest md5Digest); diff --git a/src/main/java/com/google/devtools/build/lib/actions/cache/VirtualActionInput.java b/src/main/java/com/google/devtools/build/lib/actions/cache/VirtualActionInput.java index e4c52747e2..1c80cb4364 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/cache/VirtualActionInput.java +++ b/src/main/java/com/google/devtools/build/lib/actions/cache/VirtualActionInput.java @@ -15,6 +15,7 @@ package com.google.devtools.build.lib.actions.cache; import com.google.common.base.Preconditions; import com.google.devtools.build.lib.actions.ActionInput; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.protobuf.ByteString; import java.io.IOException; @@ -38,11 +39,11 @@ public interface VirtualActionInput extends ActionInput { ByteString getBytes() throws IOException; /** - * Returns the Metadata for this input if available. Null otherwise. + * Returns the metadata for this input if available. Null otherwise. * * @throws IOException */ - default Metadata getMetadata() throws IOException { + default FileArtifactValue getMetadata() throws IOException { return null; } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenServerFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenServerFunction.java index 566e52b072..6e0a8b0fd8 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenServerFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenServerFunction.java @@ -16,6 +16,7 @@ package com.google.devtools.build.lib.bazel.repository; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.bazel.rules.workspace.MavenServerRule; import com.google.devtools.build.lib.packages.Rule; @@ -24,7 +25,6 @@ import com.google.devtools.build.lib.repository.ExternalPackageUtil; import com.google.devtools.build.lib.repository.ExternalRuleNotFoundException; import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException; import com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper; -import com.google.devtools.build.lib.skyframe.FileValue; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.Fingerprint; diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java index fce8bf687b..f245e1dc73 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java @@ -18,6 +18,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.bazel.repository.DecompressorDescriptor; import com.google.devtools.build.lib.bazel.repository.DecompressorValue; import com.google.devtools.build.lib.bazel.repository.cache.RepositoryCache.KeyType; @@ -32,7 +33,6 @@ import com.google.devtools.build.lib.packages.StructProvider; import com.google.devtools.build.lib.rules.repository.RepositoryFunction; import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException; import com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper; -import com.google.devtools.build.lib.skyframe.FileValue; import com.google.devtools.build.lib.skylarkbuildapi.repository.SkylarkRepositoryContextApi; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.EvalUtils; diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java index cf61da68b9..c4a1d77e27 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java @@ -17,6 +17,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSortedSet; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.AndroidNdkCrosstools; @@ -34,7 +35,6 @@ import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue; import com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper; import com.google.devtools.build.lib.skyframe.DirectoryListingValue; -import com.google.devtools.build.lib.skyframe.FileValue; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.ResourceFileLoader; diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidRepositoryFunction.java index ccf3d53346..7118de468b 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidRepositoryFunction.java @@ -14,11 +14,11 @@ package com.google.devtools.build.lib.bazel.rules.android; import com.google.common.collect.ImmutableSortedSet; +import com.google.devtools.build.lib.actions.FileValue; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.rules.repository.RepositoryFunction; import com.google.devtools.build.lib.skyframe.DirectoryListingValue; import com.google.devtools.build.lib.skyframe.Dirents; -import com.google.devtools.build.lib.skyframe.FileValue; -import com.google.devtools.build.lib.skyframe.InconsistentFilesystemException; import com.google.devtools.build.lib.vfs.Dirent; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java index f42c575ce1..ede9cd2620 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java @@ -22,6 +22,8 @@ import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Streams; +import com.google.devtools.build.lib.actions.FileValue; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.packages.Rule; @@ -29,8 +31,6 @@ import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue; import com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper; import com.google.devtools.build.lib.skyframe.DirectoryListingValue; import com.google.devtools.build.lib.skyframe.Dirents; -import com.google.devtools.build.lib.skyframe.FileValue; -import com.google.devtools.build.lib.skyframe.InconsistentFilesystemException; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.ResourceFileLoader; diff --git a/src/main/java/com/google/devtools/build/lib/exec/BinTools.java b/src/main/java/com/google/devtools/build/lib/exec/BinTools.java index c754386c56..651fea5238 100644 --- a/src/main/java/com/google/devtools/build/lib/exec/BinTools.java +++ b/src/main/java/com/google/devtools/build/lib/exec/BinTools.java @@ -23,10 +23,9 @@ import com.google.common.io.ByteStreams; import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.EnvironmentalExecException; import com.google.devtools.build.lib.actions.ExecException; -import com.google.devtools.build.lib.actions.cache.Metadata; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.actions.cache.VirtualActionInput; import com.google.devtools.build.lib.analysis.BlazeDirectories; -import com.google.devtools.build.lib.skyframe.FileArtifactValue; import com.google.devtools.build.lib.vfs.Dirent; import com.google.devtools.build.lib.vfs.FileSystem.HashFunction; import com.google.devtools.build.lib.vfs.FileSystemUtils; @@ -231,7 +230,7 @@ public final class BinTools { public static final class PathActionInput implements VirtualActionInput { private final Path path; private final PathFragment execPath; - private Metadata metadata; + private FileArtifactValue metadata; public PathActionInput(Path path, PathFragment execPath) { this.path = path; @@ -253,7 +252,7 @@ public final class BinTools { } @Override - public synchronized Metadata getMetadata() throws IOException { + public synchronized FileArtifactValue getMetadata() throws IOException { // We intentionally delay hashing until it is necessary. if (metadata == null) { metadata = hash(path); @@ -261,7 +260,7 @@ public final class BinTools { return metadata; } - private static Metadata hash(Path path) throws IOException { + private static FileArtifactValue hash(Path path) throws IOException { HashFunction hashFn = path.getFileSystem().getDigestFunction(); Hasher hasher = hashFn.getHash().newHasher(); int bytesCopied = 0; diff --git a/src/main/java/com/google/devtools/build/lib/exec/SingleBuildFileCache.java b/src/main/java/com/google/devtools/build/lib/exec/SingleBuildFileCache.java index 073e3d989c..10a816c886 100644 --- a/src/main/java/com/google/devtools/build/lib/exec/SingleBuildFileCache.java +++ b/src/main/java/com/google/devtools/build/lib/exec/SingleBuildFileCache.java @@ -19,8 +19,7 @@ import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ActionInputFileCache; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.DigestOfDirectoryException; -import com.google.devtools.build.lib.actions.cache.Metadata; -import com.google.devtools.build.lib.skyframe.FileArtifactValue; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.Path; import java.io.IOException; @@ -55,7 +54,7 @@ public class SingleBuildFileCache implements ActionInputFileCache { .build(); @Override - public Metadata getMetadata(ActionInput input) throws IOException { + public FileArtifactValue getMetadata(ActionInput input) throws IOException { try { return pathToMetadata .get( @@ -95,11 +94,11 @@ public class SingleBuildFileCache implements ActionInputFileCache { /** Container class for caching I/O around ActionInputs. */ private static class ActionInputMetadata { private final ActionInput input; - private final Metadata metadata; + private final FileArtifactValue metadata; private final IOException exceptionOnAccess; /** Constructor for a successful lookup. */ - ActionInputMetadata(ActionInput input, Metadata metadata) { + ActionInputMetadata(ActionInput input, FileArtifactValue metadata) { this.input = input; this.metadata = metadata; this.exceptionOnAccess = null; @@ -112,7 +111,7 @@ public class SingleBuildFileCache implements ActionInputFileCache { this.metadata = null; } - Metadata getMetadata() throws IOException { + FileArtifactValue getMetadata() throws IOException { maybeRaiseException(); return metadata; } diff --git a/src/main/java/com/google/devtools/build/lib/exec/SpawnLogContext.java b/src/main/java/com/google/devtools/build/lib/exec/SpawnLogContext.java index c5952350bc..89d91e4b68 100644 --- a/src/main/java/com/google/devtools/build/lib/exec/SpawnLogContext.java +++ b/src/main/java/com/google/devtools/build/lib/exec/SpawnLogContext.java @@ -18,11 +18,11 @@ import com.google.common.hash.HashCode; import com.google.devtools.build.lib.actions.ActionContext; import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ExecutionStrategy; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.actions.MetadataProvider; import com.google.devtools.build.lib.actions.Spawn; import com.google.devtools.build.lib.actions.SpawnResult; import com.google.devtools.build.lib.actions.Spawns; -import com.google.devtools.build.lib.actions.cache.Metadata; import com.google.devtools.build.lib.actions.cache.VirtualActionInput; import com.google.devtools.build.lib.analysis.platform.PlatformInfo; import com.google.devtools.build.lib.cmdline.Label; @@ -39,7 +39,6 @@ import com.google.devtools.build.lib.vfs.Symlinks; import com.google.protobuf.TextFormat; import com.google.protobuf.TextFormat.ParseException; import java.io.ByteArrayOutputStream; - import java.io.IOException; import java.time.Duration; import java.util.ArrayList; @@ -228,7 +227,7 @@ public class SpawnLogContext implements ActionContext { } // Try to access the cached metadata, otherwise fall back to local computation. try { - Metadata metadata = metadataProvider.getMetadata(input); + FileArtifactValue metadata = metadataProvider.getMetadata(input); if (metadata != null) { byte[] hash = metadata.getDigest(); if (hash != null) { diff --git a/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java b/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java index 311171cc4a..382a8d2f73 100644 --- a/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java +++ b/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java @@ -40,6 +40,7 @@ import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.google.devtools.build.lib.actions.FileStateValue; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.PackageIdentifier; import com.google.devtools.build.lib.cmdline.TargetParsingException; @@ -87,7 +88,6 @@ import com.google.devtools.build.lib.query2.engine.Uniquifier; import com.google.devtools.build.lib.query2.engine.VariableContext; import com.google.devtools.build.lib.skyframe.BlacklistedPackagePrefixesValue; import com.google.devtools.build.lib.skyframe.ContainingPackageLookupFunction; -import com.google.devtools.build.lib.skyframe.FileStateValue; import com.google.devtools.build.lib.skyframe.GraphBackedRecursivePackageProvider; import com.google.devtools.build.lib.skyframe.PackageLookupValue; import com.google.devtools.build.lib.skyframe.PackageValue; diff --git a/src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnCache.java b/src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnCache.java index 8a304cf89a..837d53347e 100644 --- a/src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnCache.java +++ b/src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnCache.java @@ -18,11 +18,11 @@ import static com.google.common.base.Strings.isNullOrEmpty; import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ExecException; import com.google.devtools.build.lib.actions.ExecutionStrategy; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.actions.Spawn; import com.google.devtools.build.lib.actions.SpawnResult; import com.google.devtools.build.lib.actions.SpawnResult.Status; import com.google.devtools.build.lib.actions.Spawns; -import com.google.devtools.build.lib.actions.cache.Metadata; import com.google.devtools.build.lib.actions.cache.VirtualActionInput; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; import com.google.devtools.build.lib.events.Event; @@ -34,7 +34,6 @@ import com.google.devtools.build.lib.remote.TreeNodeRepository.TreeNode; import com.google.devtools.build.lib.remote.util.DigestUtil; import com.google.devtools.build.lib.remote.util.DigestUtil.ActionKey; import com.google.devtools.build.lib.remote.util.TracingMetadataUtils; -import com.google.devtools.build.lib.skyframe.FileArtifactValue; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.remoteexecution.v1test.Action; @@ -205,7 +204,7 @@ final class RemoteSpawnCache implements SpawnCache { if (input instanceof VirtualActionInput) { continue; } - Metadata metadata = context.getActionInputFileCache().getMetadata(input); + FileArtifactValue metadata = context.getActionInputFileCache().getMetadata(input); if (metadata instanceof FileArtifactValue) { FileArtifactValue artifactValue = (FileArtifactValue) metadata; Path path = execRoot.getRelative(input.getExecPath()); diff --git a/src/main/java/com/google/devtools/build/lib/remote/TreeNodeRepository.java b/src/main/java/com/google/devtools/build/lib/remote/TreeNodeRepository.java index 6ffbd135b7..114ce46ddc 100644 --- a/src/main/java/com/google/devtools/build/lib/remote/TreeNodeRepository.java +++ b/src/main/java/com/google/devtools/build/lib/remote/TreeNodeRepository.java @@ -28,8 +28,8 @@ import com.google.common.io.BaseEncoding; import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ActionInputHelper; import com.google.devtools.build.lib.actions.DigestOfDirectoryException; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.actions.MetadataProvider; -import com.google.devtools.build.lib.actions.cache.Metadata; import com.google.devtools.build.lib.actions.cache.VirtualActionInput; import com.google.devtools.build.lib.concurrent.BlazeInterners; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; @@ -441,7 +441,7 @@ public final class TreeNodeRepository { if (input instanceof VirtualActionInput) { return Preconditions.checkNotNull(virtualInputDigestCache.get(input)); } - Metadata metadata = getInputMetadata(input); + FileArtifactValue metadata = getInputMetadata(input); byte[] digest = metadata.getDigest(); if (digest == null) { // If the artifact does not have a digest, it is because it is a directory. @@ -492,8 +492,8 @@ public final class TreeNodeRepository { } } - private Metadata getInputMetadata(ActionInput input) throws IOException { - Metadata metadata = + private FileArtifactValue getInputMetadata(ActionInput input) throws IOException { + FileArtifactValue metadata = Preconditions.checkNotNull( inputFileCache.getMetadata(input), "Missing metadata for: %s", input); if (metadata.getDigest() != null) { diff --git a/src/main/java/com/google/devtools/build/lib/remote/util/DigestUtil.java b/src/main/java/com/google/devtools/build/lib/remote/util/DigestUtil.java index ae8b109d55..defc0652cc 100644 --- a/src/main/java/com/google/devtools/build/lib/remote/util/DigestUtil.java +++ b/src/main/java/com/google/devtools/build/lib/remote/util/DigestUtil.java @@ -20,9 +20,9 @@ import com.google.common.hash.HashCode; import com.google.common.hash.HashingOutputStream; import com.google.common.io.BaseEncoding; import com.google.devtools.build.lib.actions.ActionInput; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.actions.MetadataProvider; import com.google.devtools.build.lib.actions.cache.DigestUtils; -import com.google.devtools.build.lib.actions.cache.Metadata; import com.google.devtools.build.lib.actions.cache.VirtualActionInput; import com.google.devtools.build.lib.vfs.FileSystem.HashFunction; import com.google.devtools.build.lib.vfs.Path; @@ -123,7 +123,7 @@ public class DigestUtil { public static Digest getFromInputCache(ActionInput input, MetadataProvider cache) throws IOException { - Metadata metadata = cache.getMetadata(input); + FileArtifactValue metadata = cache.getMetadata(input); Preconditions.checkNotNull(metadata, "Input cache %s returned no value for %s", cache, input); Preconditions.checkNotNull( metadata.getDigest(), diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java index ddbe96e913..512661dfc4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java @@ -27,13 +27,13 @@ import com.google.common.collect.Iterables; import com.google.common.io.ByteSource; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.ArtifactRoot; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.AnalysisEnvironment; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration; -import com.google.devtools.build.lib.skyframe.FileValue; import com.google.devtools.build.lib.skyframe.PrecomputedValue; import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java index a335d9db8b..904f771b3f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java @@ -14,11 +14,11 @@ package com.google.devtools.build.lib.rules.repository; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.packages.BuildFileName; import com.google.devtools.build.lib.packages.Rule; -import com.google.devtools.build.lib.skyframe.FileValue; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.lib.vfs.RootedPath; diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java index bcf15976f0..a7111ce0ca 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java @@ -14,12 +14,12 @@ package com.google.devtools.build.lib.rules.repository; +import com.google.devtools.build.lib.actions.FileValue; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.skyframe.DirectoryListingValue; -import com.google.devtools.build.lib.skyframe.FileValue; -import com.google.devtools.build.lib.skyframe.InconsistentFilesystemException; import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/NewRepositoryFileHandler.java b/src/main/java/com/google/devtools/build/lib/rules/repository/NewRepositoryFileHandler.java index 14efd5e10b..5e3e92f0ac 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/NewRepositoryFileHandler.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/NewRepositoryFileHandler.java @@ -14,12 +14,12 @@ package com.google.devtools.build.lib.rules.repository; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.LabelSyntaxException; import com.google.devtools.build.lib.cmdline.LabelValidator; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException; -import com.google.devtools.build.lib.skyframe.FileValue; import com.google.devtools.build.lib.skyframe.PackageLookupValue; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.Type; diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java index f8f1c26af2..db74f31652 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java @@ -16,6 +16,7 @@ package com.google.devtools.build.lib.rules.repository; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.events.Event; @@ -25,7 +26,6 @@ import com.google.devtools.build.lib.repository.ExternalPackageException; import com.google.devtools.build.lib.repository.ExternalPackageUtil; import com.google.devtools.build.lib.repository.ExternalRuleNotFoundException; import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException; -import com.google.devtools.build.lib.skyframe.FileValue; import com.google.devtools.build.lib.skyframe.PrecomputedValue; import com.google.devtools.build.lib.skyframe.PrecomputedValue.Precomputed; import com.google.devtools.build.lib.util.Fingerprint; diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java index 2b15ced504..565780d478 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java @@ -18,6 +18,8 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.io.BaseEncoding; +import com.google.devtools.build.lib.actions.FileStateValue.RegularFileStateValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.cmdline.Label; @@ -34,8 +36,6 @@ import com.google.devtools.build.lib.repository.ExternalPackageException; import com.google.devtools.build.lib.repository.ExternalPackageUtil; import com.google.devtools.build.lib.repository.ExternalRuleNotFoundException; import com.google.devtools.build.lib.skyframe.ActionEnvironmentFunction; -import com.google.devtools.build.lib.skyframe.FileStateValue.RegularFileStateValue; -import com.google.devtools.build.lib.skyframe.FileValue; import com.google.devtools.build.lib.skyframe.PackageLookupValue; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.Type; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java index b1f816d87a..df74c5e1a1 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java @@ -14,6 +14,8 @@ package com.google.devtools.build.lib.skyframe; +import com.google.devtools.build.lib.actions.FileValue; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.packages.BuildFileNotFoundException; import com.google.devtools.build.lib.packages.RuleClassProvider; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionFunction.java index fa22da4584..2ffe103975 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionFunction.java @@ -25,11 +25,13 @@ import com.google.devtools.build.lib.actions.Action; import com.google.devtools.build.lib.actions.ActionCacheChecker.Token; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; +import com.google.devtools.build.lib.actions.ActionInputMap; import com.google.devtools.build.lib.actions.ActionLookupData; import com.google.devtools.build.lib.actions.ActionLookupValue; import com.google.devtools.build.lib.actions.ActionLookupValue.ActionLookupKey; import com.google.devtools.build.lib.actions.AlreadyReportedActionExecutionException; import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.actions.FilesetOutputSymlink; import com.google.devtools.build.lib.actions.MissingInputFileException; import com.google.devtools.build.lib.actions.NotifyOnActionCacheHit; @@ -42,7 +44,6 @@ import com.google.devtools.build.lib.cmdline.PackageIdentifier; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.rules.cpp.IncludeScannable; -import com.google.devtools.build.lib.skyframe.InputArtifactData.MutableInputArtifactData; import com.google.devtools.build.lib.util.Pair; import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor; import com.google.devtools.build.lib.vfs.Path; @@ -151,7 +152,7 @@ public class ActionExecutionFunction implements SkyFunction, CompletionReceiver env.getValues(state.allInputs.keysRequested); Preconditions.checkState(!env.valuesMissing(), "%s %s", action, state); } - Pair>> checkedInputs = null; + Pair>> checkedInputs = null; try { // Declare deps on known inputs to action. We do this unconditionally to maintain our // invariant of asking for the same deps each build. @@ -574,13 +575,13 @@ public class ActionExecutionFunction implements SkyFunction, CompletionReceiver }; private static Iterable newlyDiscoveredInputsToSkyKeys( - Iterable discoveredInputs, MutableInputArtifactData inputArtifactData) { + Iterable discoveredInputs, ActionInputMap inputArtifactData) { return Iterables.transform( filterKnownInputs(discoveredInputs, inputArtifactData), TO_NONMANDATORY_SKYKEY); } private static void addDiscoveredInputs( - MutableInputArtifactData inputData, + ActionInputMap inputData, Map> expandedArtifacts, Iterable discoveredInputs, Environment env) @@ -663,7 +664,7 @@ public class ActionExecutionFunction implements SkyFunction, CompletionReceiver * Declare dependency on all known inputs of action. Throws exception if any are known to be * missing. Some inputs may not yet be in the graph, in which case the builder should abort. */ - private Pair>> checkInputs( + private Pair>> checkInputs( Environment env, Action action, Map> inputDeps) @@ -676,8 +677,7 @@ public class ActionExecutionFunction implements SkyFunction, CompletionReceiver // some deps are still missing. boolean populateInputData = !env.valuesMissing(); NestedSetBuilder rootCauses = NestedSetBuilder.stableOrder(); - MutableInputArtifactData inputArtifactData = - new MutableInputArtifactData(populateInputData ? inputDeps.size() : 0); + ActionInputMap inputArtifactData = new ActionInputMap(populateInputData ? inputDeps.size() : 0); Map> expandedArtifacts = new HashMap<>(populateInputData ? 128 : 0); @@ -768,8 +768,8 @@ public class ActionExecutionFunction implements SkyFunction, CompletionReceiver } private static Iterable filterKnownInputs( - Iterable newInputs, MutableInputArtifactData inputArtifactData) { - return Iterables.filter(newInputs, input -> !inputArtifactData.contains(input)); + Iterable newInputs, ActionInputMap inputArtifactData) { + return Iterables.filter(newInputs, input -> inputArtifactData.getMetadata(input) == null); } /** @@ -824,7 +824,7 @@ public class ActionExecutionFunction implements SkyFunction, CompletionReceiver private static class ContinuationState { AllInputs allInputs; /** Mutable map containing metadata for known artifacts. */ - MutableInputArtifactData inputArtifactData = null; + ActionInputMap inputArtifactData = null; Map> expandedArtifacts = null; Token token = null; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java index a45983c1e9..8ddb52a905 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java @@ -23,6 +23,9 @@ import com.google.common.collect.Maps; import com.google.devtools.build.lib.actions.ActionLookupData; import com.google.devtools.build.lib.actions.ActionLookupValue; import com.google.devtools.build.lib.actions.Artifact; +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.actions.FilesetOutputSymlink; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionFileSystem.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionFileSystem.java index cd99db964f..591dd6c224 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionFileSystem.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionFileSystem.java @@ -23,11 +23,13 @@ import com.google.common.hash.Hashing; import com.google.common.io.BaseEncoding; import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ActionInputFileCache; +import com.google.devtools.build.lib.actions.ActionInputMap; import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.actions.FileArtifactValue; +import com.google.devtools.build.lib.actions.FileArtifactValue.RemoteFileArtifactValue; import com.google.devtools.build.lib.actions.FileStateType; import com.google.devtools.build.lib.profiler.Profiler; import com.google.devtools.build.lib.profiler.ProfilerTask; -import com.google.devtools.build.lib.skyframe.FileArtifactValue.RemoteFileArtifactValue; import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; @@ -67,7 +69,7 @@ final class ActionFileSystem extends FileSystem implements ActionInputFileCache, private final Path execRootPath; private final ImmutableList sourceRoots; - private final InputArtifactData inputArtifactData; + private final ActionInputMap inputArtifactData; /** exec path → artifact and metadata */ private final HashMap optionalInputs; @@ -93,7 +95,7 @@ final class ActionFileSystem extends FileSystem implements ActionInputFileCache, FileSystem delegate, Path execRoot, ImmutableList sourceRoots, - InputArtifactData inputArtifactData, + ActionInputMap inputArtifactData, Iterable allowedInputs, Iterable outputArtifacts) { try { @@ -119,7 +121,7 @@ final class ActionFileSystem extends FileSystem implements ActionInputFileCache, // // TODO(shahan): there are no currently known cases where metadata is requested for an // optional source input. If there are any, we may want to stage those. - if (input.isSourceArtifact() || inputArtifactData.contains(input)) { + if (input.isSourceArtifact() || inputArtifactData.getMetadata(input) != null) { continue; } optionalInputs.computeIfAbsent( @@ -157,6 +159,12 @@ final class ActionFileSystem extends FileSystem implements ActionInputFileCache, return getMetadataChecked(actionInput.getExecPath()); } + @Override + @Nullable + public ActionInput getInput(String execPath) { + return inputArtifactData.getInput(execPath); + } + // -------------------- InjectionListener Implementation -------------------- @Override @@ -265,7 +273,7 @@ final class ActionFileSystem extends FileSystem implements ActionInputFileCache, @Override protected void createSymbolicLink(Path linkPath, PathFragment targetFragment) throws IOException { PathFragment targetExecPath = asExecPath(targetFragment); - FileArtifactValue inputMetadata = inputArtifactData.get(targetExecPath); + FileArtifactValue inputMetadata = inputArtifactData.getMetadata(targetExecPath.getPathString()); if (inputMetadata == null) { OptionalInputMetadata metadataHolder = optionalInputs.get(targetExecPath); if (metadataHolder != null) { @@ -381,7 +389,7 @@ final class ActionFileSystem extends FileSystem implements ActionInputFileCache, @Nullable private FileArtifactValue getMetadataChecked(PathFragment execPath) throws IOException { { - FileArtifactValue metadata = inputArtifactData.get(execPath); + FileArtifactValue metadata = inputArtifactData.getMetadata(execPath.getPathString()); if (metadata != null) { return metadata; } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java index b68930e492..af2a14347b 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java @@ -22,11 +22,14 @@ import com.google.common.collect.Sets; import com.google.common.io.BaseEncoding; import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ActionInputHelper; +import com.google.devtools.build.lib.actions.ActionInputMap; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact; import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact; +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.actions.cache.Md5Digest; -import com.google.devtools.build.lib.actions.cache.Metadata; import com.google.devtools.build.lib.actions.cache.MetadataHandler; import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor; import com.google.devtools.build.lib.vfs.FileStatus; @@ -78,7 +81,7 @@ public class ActionMetadataHandler implements MetadataHandler { * *

      This should never be read directly. Use {@link #getInputFileArtifactValue} instead. */ - private final InputArtifactData inputArtifactData; + private final ActionInputMap inputArtifactData; /** FileValues for each output Artifact. */ private final ConcurrentMap outputArtifactData = @@ -130,7 +133,7 @@ public class ActionMetadataHandler implements MetadataHandler { @VisibleForTesting public ActionMetadataHandler( - InputArtifactData inputArtifactData, + ActionInputMap inputArtifactData, Iterable outputs, TimestampGranularityMonitor tsgm, ArtifactPathResolver artifactPathResolver) { @@ -153,7 +156,8 @@ public class ActionMetadataHandler implements MetadataHandler { return artifact.isConstantMetadata() ? null : tsgm; } - private static Metadata metadataFromValue(FileArtifactValue value) throws FileNotFoundException { + private static FileArtifactValue metadataFromValue(FileArtifactValue value) + throws FileNotFoundException { if (value == FileArtifactValue.MISSING_FILE_MARKER || value == FileArtifactValue.OMITTED_FILE_MARKER) { throw new FileNotFoundException(); @@ -171,11 +175,11 @@ public class ActionMetadataHandler implements MetadataHandler { return null; } - return inputArtifactData.get(input); + return inputArtifactData.getMetadata(input); } @Override - public Metadata getMetadata(Artifact artifact) throws IOException { + public FileArtifactValue getMetadata(Artifact artifact) throws IOException { FileArtifactValue value = getInputFileArtifactValue(artifact); if (value != null) { return metadataFromValue(value); @@ -248,8 +252,8 @@ public class ActionMetadataHandler implements MetadataHandler { * for normal (non-middleman) artifacts. */ @Nullable - private Metadata maybeStoreAdditionalData(Artifact artifact, FileValue data, - @Nullable byte[] injectedDigest) throws IOException { + private FileArtifactValue maybeStoreAdditionalData( + Artifact artifact, FileValue data, @Nullable byte[] injectedDigest) throws IOException { if (!data.exists()) { // Nonexistent files should only occur before executing an action. throw new FileNotFoundException(artifact.prettyPrint() + " does not exist"); diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AggregatingArtifactValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/AggregatingArtifactValue.java index 2fb2199e7c..e6e045bce4 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/AggregatingArtifactValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/AggregatingArtifactValue.java @@ -15,6 +15,7 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.util.Pair; import com.google.devtools.build.skyframe.SkyValue; import java.util.Collection; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java index bee72a2321..6913091c73 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java @@ -28,6 +28,8 @@ import com.google.devtools.build.lib.actions.ActionLookupValue.ActionLookupKey; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact; import com.google.devtools.build.lib.actions.ArtifactOwner; +import com.google.devtools.build.lib.actions.FileArtifactValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.actions.MissingInputFileException; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.events.Event; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java index 79498d734b..24cd665d6b 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java @@ -21,6 +21,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.actions.Actions; import com.google.devtools.build.lib.actions.Actions.GeneratingActions; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException; import com.google.devtools.build.lib.analysis.AliasProvider; import com.google.devtools.build.lib.analysis.AspectResolver; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesFunction.java index 8d96dd3d40..eb0f645987 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesFunction.java @@ -16,6 +16,8 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.collect.ImmutableSet; import com.google.common.io.CharStreams; import com.google.common.io.LineProcessor; +import com.google.devtools.build.lib.actions.FileValue; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.lib.vfs.Root; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/DirectoryListingFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/DirectoryListingFunction.java index 97ee8b78bc..35265ce12b 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/DirectoryListingFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/DirectoryListingFunction.java @@ -13,6 +13,8 @@ // limitations under the License. package com.google.devtools.build.lib.skyframe; +import com.google.devtools.build.lib.actions.FileValue; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyFunctionException; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/DirectoryListingValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/DirectoryListingValue.java index 8d19cc1739..8fc8afde8f 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/DirectoryListingValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/DirectoryListingValue.java @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.collect.Interner; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.concurrent.BlazeInterners; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/DirtinessCheckerUtils.java b/src/main/java/com/google/devtools/build/lib/skyframe/DirtinessCheckerUtils.java index 94a1a3b1d2..ce4de19e82 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/DirtinessCheckerUtils.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/DirtinessCheckerUtils.java @@ -13,12 +13,13 @@ // limitations under the License. package com.google.devtools.build.lib.skyframe; +import static com.google.devtools.build.lib.actions.FileStateValue.FILE_STATE; import static com.google.devtools.build.lib.skyframe.SkyFunctions.DIRECTORY_LISTING_STATE; -import static com.google.devtools.build.lib.skyframe.SkyFunctions.FILE_STATE; import com.google.common.base.Objects; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.actions.FileStateValue; import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.FileType; import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor; import com.google.devtools.build.lib.vfs.Root; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/EnvironmentBackedRecursivePackageProvider.java b/src/main/java/com/google/devtools/build/lib/skyframe/EnvironmentBackedRecursivePackageProvider.java index f110ef82b6..7256adab7b 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/EnvironmentBackedRecursivePackageProvider.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/EnvironmentBackedRecursivePackageProvider.java @@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.cmdline.PackageIdentifier; import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.events.Event; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileArtifactValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/FileArtifactValue.java deleted file mode 100644 index b5add7ca4e..0000000000 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FileArtifactValue.java +++ /dev/null @@ -1,500 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -package com.google.devtools.build.lib.skyframe; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.MoreObjects; -import com.google.common.base.Preconditions; -import com.google.common.io.BaseEncoding; -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.actions.FileStateType; -import com.google.devtools.build.lib.actions.cache.DigestUtils; -import com.google.devtools.build.lib.actions.cache.Metadata; -import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; -import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; -import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; -import com.google.devtools.build.lib.vfs.FileStatus; -import com.google.devtools.build.lib.vfs.Path; -import com.google.devtools.build.lib.vfs.Symlinks; -import com.google.devtools.build.skyframe.SkyValue; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.Arrays; -import java.util.Objects; -import javax.annotation.Nullable; - -/** - * Stores the actual metadata data of a file. We have the following cases: - * - *

        - *
      • an ordinary file, in which case we would expect to see a digest and size; - *
      • a directory, in which case we would expect to see an mtime; - *
      • an intentionally omitted file which the build system is aware of but doesn't actually exist, - * where all access methods are unsupported; - *
      • a "middleman marker" object, which has a null digest, 0 size, and mtime of 0. - *
      • The "self data" of a TreeArtifact, where we would expect to see a digest representing the - * artifact's contents, and a size of 0. - *
      - */ -// TODO(janakr): make this an interface once JDK8 allows us to have static methods on interfaces. -@Immutable @ThreadSafe -public abstract class FileArtifactValue implements SkyValue, Metadata { - private static final class SingletonMarkerValue extends FileArtifactValue implements Singleton { - @Override - public FileStateType getType() { - return FileStateType.NONEXISTENT; - } - - @Nullable - @Override - public byte[] getDigest() { - return null; - } - - @Override - public long getSize() { - return 0; - } - - @Override - public long getModifiedTime() { - return 0; - } - - @Override - public boolean wasModifiedSinceDigest(Path path) throws IOException { - return false; - } - - @Override - public String toString() { - return "singleton marker artifact value (" + hashCode() + ")"; - } - } - - private static final class OmittedFileValue extends FileArtifactValue implements Singleton { - @Override - public FileStateType getType() { - return FileStateType.NONEXISTENT; - } - - @Override - public byte[] getDigest() { - throw new UnsupportedOperationException(); - } - - @Override - public long getSize() { - throw new UnsupportedOperationException(); - } - - @Override - public long getModifiedTime() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean wasModifiedSinceDigest(Path path) throws IOException { - return false; - } - - @Override - public String toString() { - return "OMITTED_FILE_MARKER"; - } - } - - @AutoCodec static final FileArtifactValue DEFAULT_MIDDLEMAN = new SingletonMarkerValue(); - /** Data that marks that a file is not present on the filesystem. */ - @VisibleForTesting @AutoCodec - public static final FileArtifactValue MISSING_FILE_MARKER = new SingletonMarkerValue(); - - /** - * Represents an omitted file -- we are aware of it but it doesn't exist. All access methods are - * unsupported. - */ - @AutoCodec static final FileArtifactValue OMITTED_FILE_MARKER = new OmittedFileValue(); - - @AutoCodec.VisibleForSerialization - @AutoCodec - static final class DirectoryArtifactValue extends FileArtifactValue { - private final long mtime; - - @AutoCodec.VisibleForSerialization - DirectoryArtifactValue(long mtime) { - this.mtime = mtime; - } - - @Override - public FileStateType getType() { - return FileStateType.DIRECTORY; - } - - @Nullable - @Override - public byte[] getDigest() { - return null; - } - - @Override - public long getModifiedTime() { - return mtime; - } - - @Override - public long getSize() { - return 0; - } - - @Override - public boolean wasModifiedSinceDigest(Path path) throws IOException { - return false; - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this).add("mtime", mtime).toString(); - } - } - - @AutoCodec.VisibleForSerialization - @AutoCodec - static final class RegularFileArtifactValue extends FileArtifactValue { - private final byte[] digest; - @Nullable private final FileContentsProxy proxy; - private final long size; - - @AutoCodec.VisibleForSerialization - RegularFileArtifactValue(byte[] digest, @Nullable FileContentsProxy proxy, long size) { - this.digest = Preconditions.checkNotNull(digest); - this.proxy = proxy; - this.size = size; - } - - @Override - public FileStateType getType() { - return FileStateType.REGULAR_FILE; - } - - @Override - public byte[] getDigest() { - return digest; - } - - @Override - public long getSize() { - return size; - } - - @Override - public boolean wasModifiedSinceDigest(Path path) throws IOException { - if (proxy == null) { - return false; - } - FileStatus stat = path.statIfFound(Symlinks.FOLLOW); - return stat == null || !stat.isFile() || !proxy.equals(FileContentsProxy.create(stat)); - } - - @Override - public long getModifiedTime() { - throw new UnsupportedOperationException( - "regular file's mtime should never be called. (" + this + ")"); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("digest", BaseEncoding.base16().lowerCase().encode(digest)) - .add("size", size) - .add("proxy", proxy).toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof RegularFileArtifactValue)) { - return false; - } - RegularFileArtifactValue r = (RegularFileArtifactValue) o; - return Arrays.equals(digest, r.digest) && Objects.equals(proxy, r.proxy) && size == r.size; - } - - @Override - public int hashCode() { - return (proxy != null ? 127 * proxy.hashCode() : 0) - + 37 * Long.hashCode(getSize()) + Arrays.hashCode(getDigest()); - } - } - - static final class RemoteFileArtifactValue extends FileArtifactValue { - private final byte[] digest; - private final long size; - private final int locationIndex; - - RemoteFileArtifactValue(byte[] digest, long size, int locationIndex) { - this.digest = digest; - this.size = size; - this.locationIndex = locationIndex; - } - - @Override - public FileStateType getType() { - return FileStateType.REGULAR_FILE; - } - - @Override - public byte[] getDigest() { - return digest; - } - - @Override - public long getSize() { - return size; - } - - @Override - public long getModifiedTime() { - throw new UnsupportedOperationException( - "RemoteFileArifactValue doesn't support getModifiedTime"); - } - - @Override - public int getLocationIndex() { - return locationIndex; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof RemoteFileArtifactValue)) { - return false; - } - RemoteFileArtifactValue r = (RemoteFileArtifactValue) o; - return Arrays.equals(digest, r.digest) && size == r.size; - } - - @Override - public int hashCode() { - return Objects.hash(Arrays.hashCode(digest), size); - } - - @Override - public boolean wasModifiedSinceDigest(Path path) { - throw new UnsupportedOperationException(); - } - } - - static final class InlineFileArtifactValue extends FileArtifactValue { - private final byte[] data; - private final byte[] digest; - - InlineFileArtifactValue(byte[] data, byte[] digest) { - this.data = Preconditions.checkNotNull(data); - this.digest = Preconditions.checkNotNull(digest); - } - - public ByteArrayInputStream getInputStream() { - return new ByteArrayInputStream(data); - } - - @Override - public FileStateType getType() { - return FileStateType.REGULAR_FILE; - } - - @Override - public byte[] getDigest() { - return digest; - } - - @Override - public long getSize() { - return data.length; - } - - @Override - public long getModifiedTime() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof InlineFileArtifactValue)) { - return false; - } - InlineFileArtifactValue that = (InlineFileArtifactValue) o; - return Arrays.equals(digest, that.digest); - } - - @Override - public int hashCode() { - return Arrays.hashCode(digest); - } - - @Override - public boolean wasModifiedSinceDigest(Path path) { - throw new UnsupportedOperationException(); - } - } - - static FileArtifactValue create(Artifact artifact, FileValue fileValue) throws IOException { - boolean isFile = fileValue.isFile(); - FileContentsProxy proxy = getProxyFromFileStateValue(fileValue.realFileStateValue()); - return create(artifact.getPath(), isFile, isFile ? fileValue.getSize() : 0, proxy, - isFile ? fileValue.getDigest() : null); - } - - static FileArtifactValue create( - Artifact artifact, FileValue fileValue, @Nullable byte[] injectedDigest) throws IOException { - boolean isFile = fileValue.isFile(); - FileContentsProxy proxy = getProxyFromFileStateValue(fileValue.realFileStateValue()); - return create(artifact.getPath(), isFile, isFile ? fileValue.getSize() : 0, proxy, - injectedDigest); - } - - @VisibleForTesting - public static FileArtifactValue create(Artifact artifact) throws IOException { - return create(artifact.getPath()); - } - - @VisibleForTesting - public static FileArtifactValue create(Path path) throws IOException { - // Caution: there's a race condition between stating the file and computing the - // digest. We need to stat first, since we're using the stat to detect changes. - // We follow symlinks here to be consistent with getDigest. - FileStatus stat = path.stat(Symlinks.FOLLOW); - return create(path, stat.isFile(), stat.getSize(), FileContentsProxy.create(stat), null); - } - - private static FileArtifactValue create( - Path path, boolean isFile, long size, FileContentsProxy proxy, @Nullable byte[] digest) - throws IOException { - if (!isFile) { - // In this case, we need to store the mtime because the action cache uses mtime for - // directories to determine if this artifact has changed. We want this code path to go away - // somehow (maybe by implementing FileSet in Skyframe). - return new DirectoryArtifactValue(path.getLastModifiedTime()); - } - if (digest == null) { - digest = DigestUtils.getDigestOrFail(path, size); - } - Preconditions.checkState(digest != null, path); - return new RegularFileArtifactValue(digest, proxy, size); - } - - public static FileArtifactValue createForVirtualActionInput(byte[] digest, long size) { - return new RegularFileArtifactValue(digest, /*proxy=*/ null, size); - } - - public static FileArtifactValue createNormalFile( - byte[] digest, @Nullable FileContentsProxy proxy, long size) { - return new RegularFileArtifactValue(digest, proxy, size); - } - - static FileArtifactValue createNormalFile(FileValue fileValue) { - FileContentsProxy proxy = getProxyFromFileStateValue(fileValue.realFileStateValue()); - return new RegularFileArtifactValue(fileValue.getDigest(), proxy, fileValue.getSize()); - } - - private static FileContentsProxy getProxyFromFileStateValue(FileStateValue value) { - if (value instanceof FileStateValue.RegularFileStateValue) { - return ((FileStateValue.RegularFileStateValue) value).getContentsProxy(); - } else if (value instanceof FileStateValue.SpecialFileStateValue) { - return ((FileStateValue.SpecialFileStateValue) value).getContentsProxy(); - } - return null; - } - - @VisibleForTesting - public static FileArtifactValue createNormalFile(byte[] digest, long size) { - return createNormalFile(digest, /*proxy=*/null, size); - } - - public static FileArtifactValue createDirectory(long mtime) { - return new DirectoryArtifactValue(mtime); - } - - /** - * Creates a FileArtifactValue used as a 'proxy' input for other ArtifactValues. - * These are used in {@link com.google.devtools.build.lib.actions.ActionCacheChecker}. - */ - static FileArtifactValue createProxy(byte[] digest) { - Preconditions.checkNotNull(digest); - return createNormalFile(digest, /*proxy=*/ null, /*size=*/ 0); - } - - @Override - public abstract FileStateType getType(); - - @Nullable - @Override - public abstract byte[] getDigest(); - - @Override - public abstract long getSize(); - - @Override - public abstract long getModifiedTime(); - - /** - * Provides a best-effort determination whether the file was changed since the digest was - * computed. This method performs file system I/O, so may be expensive. It's primarily intended to - * avoid storing bad cache entries in an action cache. It should return true if there is a chance - * that the file was modified since the digest was computed. Better not upload if we are not sure - * that the cache entry is reliable. - */ - public abstract boolean wasModifiedSinceDigest(Path path) throws IOException; - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof Metadata)) { - return false; - } - if ((this instanceof Singleton) || (o instanceof Singleton)) { - return false; - } - Metadata m = (Metadata) o; - if (getType() != m.getType()) { - return false; - } - if (getDigest() != null) { - return Arrays.equals(getDigest(), m.getDigest()) && getSize() == m.getSize(); - } else { - return getModifiedTime() == m.getModifiedTime(); - } - } - - @Override - public int hashCode() { - if (this instanceof Singleton) { - return System.identityHashCode(this); - } - // Hash digest by content, not reference. - if (getDigest() != null) { - return 37 * Long.hashCode(getSize()) + Arrays.hashCode(getDigest()); - } else { - return Long.hashCode(getModifiedTime()); - } - } -} diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileContentsProxy.java b/src/main/java/com/google/devtools/build/lib/skyframe/FileContentsProxy.java deleted file mode 100644 index 2b845edc38..0000000000 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FileContentsProxy.java +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -package com.google.devtools.build.lib.skyframe; - -import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; -import com.google.devtools.build.lib.vfs.FileStatus; -import java.io.IOException; -import java.io.Serializable; -import java.util.Objects; - -/** - * In case we can't get a fast digest from the filesystem, we store this metadata as a proxy to the - * file contents. Currently it is a pair of a relevant timestamp and a "node id". On Linux the - * former is the ctime and the latter is the inode number. We might want to add the device number in - * the future. - * - *

      For a Linux example of why mtime alone is insufficient, note that 'mv' preserves timestamps. - * So if files 'a' and 'b' initially have the same timestamp, then we would think 'b' is unchanged - * after the user executes `mv a b` between two builds. - */ -@AutoCodec -public final class FileContentsProxy implements Serializable { - private final long ctime; - private final long nodeId; - - /** - * Visible for serialization / deserialization. Do not use this method, but call {@link #create} - * instead. - */ - public FileContentsProxy(long ctime, long nodeId) { - this.ctime = ctime; - this.nodeId = nodeId; - } - - public static FileContentsProxy create(FileStatus stat) throws IOException { - // Note: there are file systems that return mtime for this call instead of ctime, such as the - // WindowsFileSystem. - return new FileContentsProxy(stat.getLastChangeTime(), stat.getNodeId()); - } - - /** Visible for serialization / deserialization. Do not use this method; use {@link #equals}. */ - public long getCTime() { - return ctime; - } - - /** Visible for serialization / deserialization. Do not use this method; use {@link #equals}. */ - public long getNodeId() { - return nodeId; - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - if (!(other instanceof FileContentsProxy)) { - return false; - } - - FileContentsProxy that = (FileContentsProxy) other; - return ctime == that.ctime && nodeId == that.nodeId; - } - - @Override - public int hashCode() { - return Objects.hash(ctime, nodeId); - } - - @Override - public String toString() { - return prettyPrint(); - } - - public String prettyPrint() { - return String.format("ctime of %d and nodeId of %d", ctime, nodeId); - } -} - diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/FileFunction.java index dc04d4b306..53b1cec194 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FileFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/FileFunction.java @@ -19,6 +19,9 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; import com.google.devtools.build.lib.actions.FileStateType; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; import com.google.devtools.build.lib.util.Pair; import com.google.devtools.build.lib.vfs.Path; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileStateFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/FileStateFunction.java index 52876f2264..8eba4cd769 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FileStateFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/FileStateFunction.java @@ -13,6 +13,7 @@ // limitations under the License. package com.google.devtools.build.lib.skyframe; +import com.google.devtools.build.lib.actions.FileStateValue; import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileStateValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/FileStateValue.java deleted file mode 100644 index f92e561ffa..0000000000 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FileStateValue.java +++ /dev/null @@ -1,437 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -package com.google.devtools.build.lib.skyframe; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.MoreObjects; -import com.google.common.base.Preconditions; -import com.google.common.collect.Interner; -import com.google.devtools.build.lib.actions.FileStateType; -import com.google.devtools.build.lib.concurrent.BlazeInterners; -import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; -import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; -import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor; -import com.google.devtools.build.lib.vfs.FileStatus; -import com.google.devtools.build.lib.vfs.FileStatusWithDigest; -import com.google.devtools.build.lib.vfs.FileStatusWithDigestAdapter; -import com.google.devtools.build.lib.vfs.Path; -import com.google.devtools.build.lib.vfs.PathFragment; -import com.google.devtools.build.lib.vfs.RootedPath; -import com.google.devtools.build.lib.vfs.Symlinks; -import com.google.devtools.build.skyframe.AbstractSkyKey; -import com.google.devtools.build.skyframe.SkyFunctionName; -import com.google.devtools.build.skyframe.SkyValue; -import java.io.IOException; -import java.util.Arrays; -import java.util.Objects; -import javax.annotation.Nullable; - -/** - * Encapsulates the filesystem operations needed to get state for a path. This is equivalent to an - * 'lstat' that does not follow symlinks to determine what type of file the path is. - *

        - *
      • For a non-existent file, the non-existence is noted. - *
      • For a symlink, the symlink target is noted. - *
      • For a directory, the existence is noted. - *
      • For a file, the existence is noted, along with metadata about the file (e.g. - * file digest). See {@link RegularFileStateValue}. - *
          - * - *

          This class is an implementation detail of {@link FileValue} and should not be used by - * {@link com.google.devtools.build.skyframe.SkyFunction}s other than {@link FileFunction}. Instead, - * {@link FileValue} should be used by {@link com.google.devtools.build.skyframe.SkyFunction} - * consumers that care about files. - * - *

          All subclasses must implement {@link #equals} and {@link #hashCode} properly. - */ -@VisibleForTesting -public abstract class FileStateValue implements SkyValue { - - @AutoCodec - public static final DirectoryFileStateValue DIRECTORY_FILE_STATE_NODE = - new DirectoryFileStateValue(); - - @AutoCodec - public static final NonexistentFileStateValue NONEXISTENT_FILE_STATE_NODE = - new NonexistentFileStateValue(); - - protected FileStateValue() { - } - - public static FileStateValue create(RootedPath rootedPath, - @Nullable TimestampGranularityMonitor tsgm) throws InconsistentFilesystemException, - IOException { - Path path = rootedPath.asPath(); - // Stat, but don't throw an exception for the common case of a nonexistent file. This still - // throws an IOException in case any other IO error is encountered. - FileStatus stat = path.statIfFound(Symlinks.NOFOLLOW); - if (stat == null) { - return NONEXISTENT_FILE_STATE_NODE; - } - return createWithStatNoFollow(rootedPath, FileStatusWithDigestAdapter.adapt(stat), tsgm); - } - - static FileStateValue createWithStatNoFollow(RootedPath rootedPath, - FileStatusWithDigest statNoFollow, @Nullable TimestampGranularityMonitor tsgm) - throws InconsistentFilesystemException, IOException { - Path path = rootedPath.asPath(); - if (statNoFollow.isFile()) { - return statNoFollow.isSpecialFile() - ? SpecialFileStateValue.fromStat(path.asFragment(), statNoFollow, tsgm) - : RegularFileStateValue.fromPath(path, statNoFollow, tsgm); - } else if (statNoFollow.isDirectory()) { - return DIRECTORY_FILE_STATE_NODE; - } else if (statNoFollow.isSymbolicLink()) { - return new SymlinkFileStateValue(path.readSymbolicLinkUnchecked()); - } - throw new InconsistentFilesystemException("according to stat, existing path " + path + " is " - + "neither a file nor directory nor symlink."); - } - - @VisibleForTesting - @ThreadSafe - public static Key key(RootedPath rootedPath) { - return Key.create(rootedPath); - } - - @AutoCodec.VisibleForSerialization - @AutoCodec - static class Key extends AbstractSkyKey { - private static final Interner interner = BlazeInterners.newWeakInterner(); - - private Key(RootedPath arg) { - super(arg); - } - - @AutoCodec.VisibleForSerialization - @AutoCodec.Instantiator - static Key create(RootedPath arg) { - return interner.intern(new Key(arg)); - } - - @Override - public SkyFunctionName functionName() { - return SkyFunctions.FILE_STATE; - } - } - - public abstract FileStateType getType(); - - /** Returns the target of the symlink, or throws an exception if this is not a symlink. */ - PathFragment getSymlinkTarget() { - throw new IllegalStateException(); - } - - long getSize() { - throw new IllegalStateException(); - } - - @Nullable - byte[] getDigest() { - throw new IllegalStateException(); - } - - @Override - public String toString() { - return prettyPrint(); - } - - abstract String prettyPrint(); - - /** - * Implementation of {@link FileStateValue} for regular files that exist. - * - *

          A union of (digest, mtime). We use digests only if a fast digest lookup is available from - * the filesystem. If not, we fall back to mtime-based digests. This avoids the case where Blaze - * must read all files involved in the build in order to check for modifications in the case where - * fast digest lookups are not available. - */ - @ThreadSafe - @AutoCodec - public static final class RegularFileStateValue extends FileStateValue { - private final long size; - @Nullable private final byte[] digest; - @Nullable private final FileContentsProxy contentsProxy; - - public RegularFileStateValue(long size, byte[] digest, FileContentsProxy contentsProxy) { - Preconditions.checkState((digest == null) != (contentsProxy == null)); - this.size = size; - this.digest = digest; - this.contentsProxy = contentsProxy; - } - - /** - * Create a FileFileStateValue instance corresponding to the given existing file. - * @param stat must be of type "File". (Not a symlink). - */ - private static RegularFileStateValue fromPath(Path path, FileStatusWithDigest stat, - @Nullable TimestampGranularityMonitor tsgm) - throws InconsistentFilesystemException { - Preconditions.checkState(stat.isFile(), path); - - try { - byte[] digest = tryGetDigest(path, stat); - if (digest == null) { - // Note that TimestampGranularityMonitor#notifyDependenceOnFileTime is a thread-safe - // method. - if (tsgm != null) { - tsgm.notifyDependenceOnFileTime(path.asFragment(), stat.getLastChangeTime()); - } - return new RegularFileStateValue(stat.getSize(), null, FileContentsProxy.create(stat)); - } else { - // We are careful here to avoid putting the value ID into FileMetadata if we already have - // a digest. Arbitrary filesystems may do weird things with the value ID; a digest is more - // robust. - return new RegularFileStateValue(stat.getSize(), digest, null); - } - } catch (IOException e) { - String errorMessage = e.getMessage() != null - ? "error '" + e.getMessage() + "'" : "an error"; - throw new InconsistentFilesystemException("'stat' said " + path + " is a file but then we " - + "later encountered " + errorMessage + " which indicates that " + path + " is no " - + "longer a file. Did you delete it during the build?"); - } - } - - @Nullable - private static byte[] tryGetDigest(Path path, FileStatusWithDigest stat) throws IOException { - try { - byte[] digest = stat.getDigest(); - return digest != null ? digest : path.getFastDigest(); - } catch (IOException ioe) { - if (!path.isReadable()) { - return null; - } - throw ioe; - } - } - - @Override - public FileStateType getType() { - return FileStateType.REGULAR_FILE; - } - - @Override - public long getSize() { - return size; - } - - @Override - @Nullable - public byte[] getDigest() { - return digest; - } - - public FileContentsProxy getContentsProxy() { - return contentsProxy; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof RegularFileStateValue)) { - return false; - } - RegularFileStateValue other = (RegularFileStateValue) obj; - return size == other.size - && Arrays.equals(digest, other.digest) - && Objects.equals(contentsProxy, other.contentsProxy); - } - - @Override - public int hashCode() { - return Objects.hash(size, Arrays.hashCode(digest), contentsProxy); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("digest", digest) - .add("size", size) - .add("contentsProxy", contentsProxy).toString(); - } - - @Override - public String prettyPrint() { - String contents = digest != null - ? String.format("digest of %s", Arrays.toString(digest)) - : contentsProxy.prettyPrint(); - return String.format("regular file with size of %d and %s", size, contents); - } - } - - /** Implementation of {@link FileStateValue} for special files that exist. */ - @AutoCodec - public static final class SpecialFileStateValue extends FileStateValue { - private final FileContentsProxy contentsProxy; - - public SpecialFileStateValue(FileContentsProxy contentsProxy) { - this.contentsProxy = contentsProxy; - } - - static SpecialFileStateValue fromStat(PathFragment path, FileStatus stat, - @Nullable TimestampGranularityMonitor tsgm) throws IOException { - // Note that TimestampGranularityMonitor#notifyDependenceOnFileTime is a thread-safe method. - if (tsgm != null) { - tsgm.notifyDependenceOnFileTime(path, stat.getLastChangeTime()); - } - return new SpecialFileStateValue(FileContentsProxy.create(stat)); - } - - @Override - public FileStateType getType() { - return FileStateType.SPECIAL_FILE; - } - - @Override - long getSize() { - return 0; - } - - @Override - @Nullable - byte[] getDigest() { - return null; - } - - public FileContentsProxy getContentsProxy() { - return contentsProxy; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof SpecialFileStateValue)) { - return false; - } - SpecialFileStateValue other = (SpecialFileStateValue) obj; - return Objects.equals(contentsProxy, other.contentsProxy); - } - - @Override - public int hashCode() { - return contentsProxy.hashCode(); - } - - @Override - public String prettyPrint() { - return String.format("special file with %s", contentsProxy.prettyPrint()); - } - } - - /** Implementation of {@link FileStateValue} for directories that exist. */ - @AutoCodec.VisibleForSerialization - static final class DirectoryFileStateValue extends FileStateValue { - - private DirectoryFileStateValue() { - } - - @Override - public FileStateType getType() { - return FileStateType.DIRECTORY; - } - - @Override - public String prettyPrint() { - return "directory"; - } - - // This object is normally a singleton, but deserialization produces copies. - @Override - public boolean equals(Object obj) { - return obj instanceof DirectoryFileStateValue; - } - - @Override - public int hashCode() { - return 7654321; - } - } - - /** Implementation of {@link FileStateValue} for symlinks. */ - @AutoCodec - public static final class SymlinkFileStateValue extends FileStateValue { - - private final PathFragment symlinkTarget; - - public SymlinkFileStateValue(PathFragment symlinkTarget) { - this.symlinkTarget = symlinkTarget; - } - - @Override - public FileStateType getType() { - return FileStateType.SYMLINK; - } - - @Override - public PathFragment getSymlinkTarget() { - return symlinkTarget; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof SymlinkFileStateValue)) { - return false; - } - SymlinkFileStateValue other = (SymlinkFileStateValue) obj; - return symlinkTarget.equals(other.symlinkTarget); - } - - @Override - public int hashCode() { - return symlinkTarget.hashCode(); - } - - @Override - public String prettyPrint() { - return "symlink to " + symlinkTarget; - } - } - - /** Implementation of {@link FileStateValue} for nonexistent files. */ - @AutoCodec.VisibleForSerialization - static final class NonexistentFileStateValue extends FileStateValue { - - private NonexistentFileStateValue() { - } - - @Override - public FileStateType getType() { - return FileStateType.NONEXISTENT; - } - - @Override - public String prettyPrint() { - return "nonexistent path"; - } - - // This object is normally a singleton, but deserialization produces copies. - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - return obj instanceof NonexistentFileStateValue; - } - - @Override - public int hashCode() { - return 8765432; - } - } -} diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/FileValue.java deleted file mode 100644 index eeb9fc6f91..0000000000 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FileValue.java +++ /dev/null @@ -1,342 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -package com.google.devtools.build.lib.skyframe; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Preconditions; -import com.google.common.collect.Interner; -import com.google.devtools.build.lib.actions.FileStateType; -import com.google.devtools.build.lib.concurrent.BlazeInterners; -import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; -import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; -import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; -import com.google.devtools.build.lib.vfs.PathFragment; -import com.google.devtools.build.lib.vfs.RootedPath; -import com.google.devtools.build.skyframe.AbstractSkyKey; -import com.google.devtools.build.skyframe.SkyFunctionName; -import com.google.devtools.build.skyframe.SkyValue; -import java.util.Objects; -import javax.annotation.Nullable; - -/** - * A value that corresponds to a file (or directory or symlink or non-existent file), fully - * accounting for symlinks (e.g. proper dependencies on ancestor symlinks so as to be incrementally - * correct). Anything in Skyframe that cares about the fully resolved path of a file (e.g. anything - * that cares about the contents of a file) should have a dependency on the corresponding {@link - * FileValue}. - * - *

          Note that the existence of a file value does not imply that the file exists on the filesystem. - * File values for missing files will be created on purpose in order to facilitate incremental - * builds in the case those files have reappeared. - * - *

          This class contains the relevant metadata for a file, although not the contents. Note that - * since a FileValue doesn't store its corresponding SkyKey, it's possible for the FileValues for - * two different paths to be the same. - * - *

          This should not be used for build outputs; use {@link ArtifactSkyKey} to create keys for - * those. - */ -@Immutable -@ThreadSafe -public abstract class FileValue implements SkyValue { - - /** - * Exists to accommodate the control flow of {@link ActionMetadataHandler#getMetadata}. - * - *

          {@link ActionMetadataHandler#getMetadata} always checks {@link - * ActionMetadataHandler#outputArtifactData} before checking {@link - * ActionMetadataHandler#additionalOutputData} so some placeholder value is needed to allow an - * injected {@link FileArtifactValue} to be returned. - */ - @AutoCodec public static final FileValue PLACEHOLDER = new PlaceholderFileValue(); - - public boolean exists() { - return realFileStateValue().getType() != FileStateType.NONEXISTENT; - } - - /** Returns true if the original path is a symlink; the target path can never be a symlink. */ - public boolean isSymlink() { - return false; - } - - /** - * Returns true if this value corresponds to a file or symlink to an existing regular or special - * file. If so, its parent directory is guaranteed to exist. - */ - public boolean isFile() { - return realFileStateValue().getType() == FileStateType.REGULAR_FILE - || realFileStateValue().getType() == FileStateType.SPECIAL_FILE; - } - - /** - * Returns true if this value corresponds to a file or symlink to an existing special file. If so, - * its parent directory is guaranteed to exist. - */ - public boolean isSpecialFile() { - return realFileStateValue().getType() == FileStateType.SPECIAL_FILE; - } - - /** - * Returns true if the file is a directory or a symlink to an existing directory. If so, its - * parent directory is guaranteed to exist. - */ - public boolean isDirectory() { - return realFileStateValue().getType() == FileStateType.DIRECTORY; - } - - /** - * Returns the real rooted path of the file, taking ancestor symlinks into account. For example, - * the rooted path ['root']/['a/b'] is really ['root']/['c/b'] if 'a' is a symlink to 'b'. Note - * that ancestor symlinks outside the root boundary are not taken into consideration. - */ - public abstract RootedPath realRootedPath(); - - public abstract FileStateValue realFileStateValue(); - - /** - * Returns the unresolved link target if {@link #isSymlink()}. - * - *

          This is useful if the caller wants to, for example, duplicate a relative symlink. An actual - * example could be a build rule that copies a set of input files to the output directory, but - * upon encountering symbolic links it can decide between copying or following them. - */ - PathFragment getUnresolvedLinkTarget() { - throw new IllegalStateException(this.toString()); - } - - long getSize() { - Preconditions.checkState(isFile(), this); - return realFileStateValue().getSize(); - } - - @Nullable - byte[] getDigest() { - Preconditions.checkState(isFile(), this); - return realFileStateValue().getDigest(); - } - - /** Returns a key for building a file value for the given root-relative path. */ - @ThreadSafe - public static Key key(RootedPath rootedPath) { - return Key.create(rootedPath); - } - - @AutoCodec.VisibleForSerialization - @AutoCodec - static class Key extends AbstractSkyKey { - private static final Interner interner = BlazeInterners.newWeakInterner(); - - private Key(RootedPath arg) { - super(arg); - } - - @AutoCodec.VisibleForSerialization - @AutoCodec.Instantiator - static Key create(RootedPath arg) { - return interner.intern(new Key(arg)); - } - - @Override - public SkyFunctionName functionName() { - return SkyFunctions.FILE; - } - } - - /** - * Only intended to be used by {@link FileFunction}. Should not be used for symlink cycles. - */ - static FileValue value(RootedPath rootedPath, FileStateValue fileStateValue, - RootedPath realRootedPath, FileStateValue realFileStateValue) { - if (rootedPath.equals(realRootedPath)) { - Preconditions.checkState(fileStateValue.getType() != FileStateType.SYMLINK, - "rootedPath: %s, fileStateValue: %s, realRootedPath: %s, realFileStateValue: %s", - rootedPath, fileStateValue, realRootedPath, realFileStateValue); - return new RegularFileValue(rootedPath, fileStateValue); - } else { - if (fileStateValue.getType() == FileStateType.SYMLINK) { - return new SymlinkFileValue(realRootedPath, realFileStateValue, - fileStateValue.getSymlinkTarget()); - } else { - return new DifferentRealPathFileValue( - realRootedPath, realFileStateValue); - } - } - } - - /** - * Implementation of {@link FileValue} for files whose fully resolved path is the same as the - * requested path. For example, this is the case for the path "foo/bar/baz" if neither 'foo' nor - * 'foo/bar' nor 'foo/bar/baz' are symlinks. - */ - @VisibleForTesting - @AutoCodec - public static final class RegularFileValue extends FileValue { - - private final RootedPath rootedPath; - private final FileStateValue fileStateValue; - - public RegularFileValue(RootedPath rootedPath, FileStateValue fileStateValue) { - this.rootedPath = Preconditions.checkNotNull(rootedPath); - this.fileStateValue = Preconditions.checkNotNull(fileStateValue); - } - - @Override - public RootedPath realRootedPath() { - return rootedPath; - } - - @Override - public FileStateValue realFileStateValue() { - return fileStateValue; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (obj.getClass() != RegularFileValue.class) { - return false; - } - RegularFileValue other = (RegularFileValue) obj; - return rootedPath.equals(other.rootedPath) && fileStateValue.equals(other.fileStateValue); - } - - @Override - public int hashCode() { - return Objects.hash(rootedPath, fileStateValue); - } - - @Override - public String toString() { - return rootedPath + ", " + fileStateValue; - } - } - - /** - * Base class for {@link FileValue}s for files whose fully resolved path is different than the - * requested path. For example, this is the case for the path "foo/bar/baz" if at least one of - * 'foo', 'foo/bar', or 'foo/bar/baz' is a symlink. - */ - @AutoCodec.VisibleForSerialization - @AutoCodec - static class DifferentRealPathFileValue extends FileValue { - - protected final RootedPath realRootedPath; - protected final FileStateValue realFileStateValue; - - @AutoCodec.VisibleForSerialization - DifferentRealPathFileValue(RootedPath realRootedPath, FileStateValue realFileStateValue) { - this.realRootedPath = Preconditions.checkNotNull(realRootedPath); - this.realFileStateValue = Preconditions.checkNotNull(realFileStateValue); - } - - @Override - public RootedPath realRootedPath() { - return realRootedPath; - } - - @Override - public FileStateValue realFileStateValue() { - return realFileStateValue; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (obj.getClass() != DifferentRealPathFileValue.class) { - return false; - } - DifferentRealPathFileValue other = (DifferentRealPathFileValue) obj; - return realRootedPath.equals(other.realRootedPath) - && realFileStateValue.equals(other.realFileStateValue); - } - - @Override - public int hashCode() { - return Objects.hash(realRootedPath, realFileStateValue); - } - - @Override - public String toString() { - return realRootedPath + ", " + realFileStateValue + " (symlink ancestor)"; - } - } - - /** Implementation of {@link FileValue} for files that are symlinks. */ - @VisibleForTesting - @AutoCodec - static final class SymlinkFileValue extends DifferentRealPathFileValue { - private final PathFragment linkTarget; - - @VisibleForTesting - SymlinkFileValue( - RootedPath realRootedPath, FileStateValue realFileStateValue, PathFragment linkTarget) { - super(realRootedPath, realFileStateValue); - this.linkTarget = linkTarget; - } - - @Override - public boolean isSymlink() { - return true; - } - - @Override - public PathFragment getUnresolvedLinkTarget() { - return linkTarget; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (obj.getClass() != SymlinkFileValue.class) { - return false; - } - SymlinkFileValue other = (SymlinkFileValue) obj; - return realRootedPath.equals(other.realRootedPath) - && realFileStateValue.equals(other.realFileStateValue) - && linkTarget.equals(other.linkTarget); - } - - @Override - public int hashCode() { - return Objects.hash(realRootedPath, realFileStateValue, linkTarget, Boolean.TRUE); - } - - @Override - public String toString() { - return String.format( - "symlink (real_path=%s, real_state=%s, link_value=%s)", - realRootedPath, realFileStateValue, linkTarget); - } - } - - private static final class PlaceholderFileValue extends FileValue { - private PlaceholderFileValue() {} - - @Override - public RootedPath realRootedPath() { - throw new UnsupportedOperationException(); - } - - @Override - public FileStateValue realFileStateValue() { - throw new UnsupportedOperationException(); - } - } -} diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FilesystemValueChecker.java b/src/main/java/com/google/devtools/build/lib/skyframe/FilesystemValueChecker.java index bd2f0263b3..e154a08780 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FilesystemValueChecker.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/FilesystemValueChecker.java @@ -25,6 +25,7 @@ import com.google.common.collect.Range; import com.google.common.collect.Sets; import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.concurrent.ExecutorUtil; import com.google.devtools.build.lib.concurrent.Sharder; import com.google.devtools.build.lib.concurrent.ThrowableRecordingRunnableWrapper; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/GlobFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/GlobFunction.java index 3dcb7f604f..9d2c94ac8f 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/GlobFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/GlobFunction.java @@ -18,6 +18,8 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import com.google.devtools.build.lib.actions.FileValue; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.cmdline.PackageIdentifier; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/GraphBackedRecursivePackageProvider.java b/src/main/java/com/google/devtools/build/lib/skyframe/GraphBackedRecursivePackageProvider.java index 86effea4ac..2c3ebcad41 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/GraphBackedRecursivePackageProvider.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/GraphBackedRecursivePackageProvider.java @@ -21,6 +21,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; import com.google.common.collect.Sets.SetView; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.cmdline.PackageIdentifier; import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.cmdline.TargetPattern; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/InconsistentFilesystemException.java b/src/main/java/com/google/devtools/build/lib/skyframe/InconsistentFilesystemException.java deleted file mode 100644 index 5397fb4937..0000000000 --- a/src/main/java/com/google/devtools/build/lib/skyframe/InconsistentFilesystemException.java +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -package com.google.devtools.build.lib.skyframe; - -import java.io.IOException; - -/** - * Used to indicate a filesystem inconsistency, e.g. file 'a/b' exists but directory 'a' doesn't - * exist. This generally means the result of the build is undefined but we shouldn't crash hard. - */ -public class InconsistentFilesystemException extends IOException { - public InconsistentFilesystemException(String inconsistencyMessage) { - super("Inconsistent filesystem operations. " + inconsistencyMessage + " The results of the " - + "build are not guaranteed to be correct. You should probably run 'blaze clean' and " - + "investigate the filesystem inconsistency (likely due to filesytem updates concurrent " - + "with the build)"); - } -} diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/InputArtifactData.java b/src/main/java/com/google/devtools/build/lib/skyframe/InputArtifactData.java deleted file mode 100644 index 65b16d7462..0000000000 --- a/src/main/java/com/google/devtools/build/lib/skyframe/InputArtifactData.java +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2018 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -package com.google.devtools.build.lib.skyframe; - -import static java.nio.charset.StandardCharsets.US_ASCII; - -import com.google.common.io.BaseEncoding; -import com.google.devtools.build.lib.actions.ActionInput; -import com.google.devtools.build.lib.actions.ActionInputMap; -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.vfs.PathFragment; -import com.google.protobuf.ByteString; -import javax.annotation.Nullable; - -/** A mapping from artifacts to metadata. */ -interface InputArtifactData { - - boolean contains(ActionInput input); - - @Nullable - FileArtifactValue get(ActionInput input); - - @Nullable - FileArtifactValue get(PathFragment execPath); - - @Nullable - ActionInput getInput(String execpath); - - /** - * This implementation has a privileged {@link put} method supporting mutations. - * - *

          Action execution has distinct phases where this data can be read from multiple threads. It's - * important that the underlying data is not modified during those phases. - */ - final class MutableInputArtifactData implements InputArtifactData { - private final ActionInputMap inputs; - - public MutableInputArtifactData(int sizeHint) { - this.inputs = new ActionInputMap(sizeHint); - } - - @Override - public boolean contains(ActionInput input) { - return inputs.getMetadata(input) != null; - } - - @Override - @Nullable - public FileArtifactValue get(ActionInput input) { - return (FileArtifactValue) inputs.getMetadata(input); - } - - @Override - @Nullable - public FileArtifactValue get(PathFragment execPath) { - return (FileArtifactValue) inputs.getMetadata(execPath.getPathString()); - } - - @Override - public ActionInput getInput(String execPath) { - return inputs.getInput(execPath); - } - - public void put(Artifact artifact, FileArtifactValue value) { - inputs.put(artifact, value); - } - - @Override - public String toString() { - return inputs.toString(); - } - - private static ByteString toByteString(byte[] digest) { - return ByteString.copyFrom( - BaseEncoding.base16().lowerCase().encode(digest).getBytes(US_ASCII)); - } - } -} diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunction.java index 4c699ab635..cb1012df1d 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunction.java @@ -16,6 +16,8 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; +import com.google.devtools.build.lib.actions.FileValue; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.LabelSyntaxException; import com.google.devtools.build.lib.cmdline.RepositoryName; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java index 6f7a53f96b..635040e66f 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java @@ -25,6 +25,8 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import com.google.devtools.build.lib.actions.FileValue; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.clock.BlazeClock; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.LabelSyntaxException; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java index 4b26017315..bc1b80a049 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java @@ -16,6 +16,8 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.lib.actions.FileValue; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.LabelValidator; import com.google.devtools.build.lib.cmdline.PackageIdentifier; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PerActionFileCache.java b/src/main/java/com/google/devtools/build/lib/skyframe/PerActionFileCache.java index 54dc3a1835..b5660181e4 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PerActionFileCache.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PerActionFileCache.java @@ -16,8 +16,9 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.base.Preconditions; import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ActionInputFileCache; +import com.google.devtools.build.lib.actions.ActionInputMap; import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.actions.cache.Metadata; +import com.google.devtools.build.lib.actions.FileArtifactValue; import javax.annotation.Nullable; /** @@ -28,7 +29,7 @@ import javax.annotation.Nullable; * the source of truth. */ class PerActionFileCache implements ActionInputFileCache { - private final InputArtifactData inputArtifactData; + private final ActionInputMap inputArtifactData; private final boolean missingArtifactsAllowed; /** @@ -36,18 +37,19 @@ class PerActionFileCache implements ActionInputFileCache { * @param missingArtifactsAllowed whether to tolerate missing artifacts: can happen during input * discovery. */ - PerActionFileCache(InputArtifactData inputArtifactData, boolean missingArtifactsAllowed) { + PerActionFileCache(ActionInputMap inputArtifactData, boolean missingArtifactsAllowed) { this.inputArtifactData = Preconditions.checkNotNull(inputArtifactData); this.missingArtifactsAllowed = missingArtifactsAllowed; } @Nullable @Override - public Metadata getMetadata(ActionInput input) { + public FileArtifactValue getMetadata(ActionInput input) { + // TODO(shahan): is this bypass needed? if (!(input instanceof Artifact)) { return null; } - Metadata result = inputArtifactData.get(input); + FileArtifactValue result = inputArtifactData.getMetadata(input); Preconditions.checkState(missingArtifactsAllowed || result != null, "null for %s", input); return result; } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ProcessPackageDirectory.java b/src/main/java/com/google/devtools/build/lib/skyframe/ProcessPackageDirectory.java index 2768bde16d..40dce87169 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ProcessPackageDirectory.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ProcessPackageDirectory.java @@ -18,6 +18,8 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.lib.actions.FileValue; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.PackageIdentifier; 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 2948e4e16d..a03f87977f 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 @@ -18,6 +18,9 @@ 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.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; import com.google.devtools.build.lib.events.Event; 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 8d16da6439..05bce4b1d4 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,6 +18,7 @@ import com.google.common.base.Objects; 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.FileStateValue; import com.google.devtools.build.lib.actions.FilesetTraversalParams.DirectTraversalRoot; import com.google.devtools.build.lib.actions.FilesetTraversalParams.PackageBoundaryMode; import com.google.devtools.build.lib.collect.nestedset.NestedSet; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RunfilesArtifactValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/RunfilesArtifactValue.java index 8969a2cbc6..644bd5e331 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/RunfilesArtifactValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/RunfilesArtifactValue.java @@ -15,6 +15,7 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.util.Pair; /** The artifacts behind a runfiles middleman. */ diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java index cf49cc96c8..b1cd6b022a 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java @@ -29,6 +29,8 @@ import com.google.common.collect.Sets; import com.google.devtools.build.lib.actions.ActionKeyContext; import com.google.devtools.build.lib.actions.ArtifactRoot; import com.google.devtools.build.lib.actions.CommandLineExpansionException; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.AnalysisProtos.ActionGraphContainer; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.ConfiguredTarget; @@ -313,8 +315,8 @@ public final class SequencedSkyframeExecutor extends SkyframeExecutor { private static final ImmutableSet PACKAGE_LOCATOR_DEPENDENT_VALUES = ImmutableSet.of( SkyFunctions.AST_FILE_LOOKUP, - SkyFunctions.FILE_STATE, - SkyFunctions.FILE, + FileStateValue.FILE_STATE, + FileValue.FILE, SkyFunctions.DIRECTORY_LISTING_STATE, SkyFunctions.TARGET_PATTERN, SkyFunctions.PREPARE_DEPS_OF_PATTERN, @@ -561,8 +563,8 @@ public final class SequencedSkyframeExecutor extends SkyframeExecutor { private static int getNumberOfModifiedFiles(Iterable modifiedValues) { // We are searching only for changed files, DirectoryListingValues don't depend on // child values, that's why they are invalidated separately - return Iterables.size(Iterables.filter(modifiedValues, - SkyFunctionName.functionIs(SkyFunctions.FILE_STATE))); + return Iterables.size( + Iterables.filter(modifiedValues, SkyFunctionName.functionIs(FileStateValue.FILE_STATE))); } /** diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java index 7b9ca6d81f..0ef296c944 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java @@ -27,14 +27,12 @@ public final class SkyFunctions { SkyFunctionName.create("CLIENT_ENVIRONMENT_VARIABLE"); public static final SkyFunctionName ACTION_ENVIRONMENT_VARIABLE = SkyFunctionName.create("ACTION_ENVIRONMENT_VARIABLE"); - public static final SkyFunctionName FILE_STATE = SkyFunctionName.create("FILE_STATE"); public static final SkyFunctionName DIRECTORY_LISTING_STATE = SkyFunctionName.create("DIRECTORY_LISTING_STATE"); public static final SkyFunctionName FILE_SYMLINK_CYCLE_UNIQUENESS = SkyFunctionName.create("FILE_SYMLINK_CYCLE_UNIQUENESS"); public static final SkyFunctionName FILE_SYMLINK_INFINITE_EXPANSION_UNIQUENESS = SkyFunctionName.create("FILE_SYMLINK_INFINITE_EXPANSION_UNIQUENESS"); - public static final SkyFunctionName FILE = SkyFunctionName.create("FILE"); public static final SkyFunctionName DIRECTORY_LISTING = SkyFunctionName.create("DIRECTORY_LISTING"); public static final SkyFunctionName PACKAGE_LOOKUP = SkyFunctionName.create("PACKAGE_LOOKUP"); diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java index 5efc8cdddb..d0cb1433a6 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java @@ -55,6 +55,7 @@ import com.google.devtools.build.lib.actions.ArtifactPrefixConflictException; import com.google.devtools.build.lib.actions.CachedActionEvent; import com.google.devtools.build.lib.actions.EnvironmentalExecException; import com.google.devtools.build.lib.actions.Executor; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.actions.FilesetOutputSymlink; import com.google.devtools.build.lib.actions.MapBasedActionGraph; import com.google.devtools.build.lib.actions.MutableActionGraph; @@ -63,7 +64,6 @@ import com.google.devtools.build.lib.actions.NotifyOnActionCacheHit; import com.google.devtools.build.lib.actions.NotifyOnActionCacheHit.ActionCachedContext; import com.google.devtools.build.lib.actions.PackageRootResolver; import com.google.devtools.build.lib.actions.TargetOutOfDateException; -import com.google.devtools.build.lib.actions.cache.Metadata; import com.google.devtools.build.lib.actions.cache.MetadataHandler; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.concurrent.ExecutorUtil; @@ -1266,8 +1266,8 @@ public final class SkyframeActionExecutor { } @Override - public Metadata getMetadata(ActionInput input) throws IOException { - Metadata metadata = perActionCache.getMetadata(input); + public FileArtifactValue getMetadata(ActionInput input) throws IOException { + FileArtifactValue metadata = perActionCache.getMetadata(input); return (metadata != null) && (metadata != FileArtifactValue.MISSING_FILE_MARKER) ? metadata : perBuildFileCache.getMetadata(input); diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java index dea750e808..2b4da1b4a0 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java @@ -53,6 +53,8 @@ import com.google.devtools.build.lib.actions.CommandLineExpansionException; import com.google.devtools.build.lib.actions.EnvironmentalExecException; import com.google.devtools.build.lib.actions.Executor; import com.google.devtools.build.lib.actions.FileStateType; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.actions.ResourceManager; import com.google.devtools.build.lib.analysis.AnalysisProtos.ActionGraphContainer; import com.google.devtools.build.lib.analysis.AspectCollection; @@ -405,14 +407,14 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory { map.put(SkyFunctions.PRECOMPUTED, new PrecomputedFunction()); map.put(SkyFunctions.CLIENT_ENVIRONMENT_VARIABLE, new ClientEnvironmentFunction(clientEnv)); map.put(SkyFunctions.ACTION_ENVIRONMENT_VARIABLE, new ActionEnvironmentFunction()); - map.put(SkyFunctions.FILE_STATE, new FileStateFunction(tsgm, externalFilesHelper)); + map.put(FileStateValue.FILE_STATE, new FileStateFunction(tsgm, externalFilesHelper)); map.put(SkyFunctions.DIRECTORY_LISTING_STATE, new DirectoryListingStateFunction(externalFilesHelper)); map.put(SkyFunctions.FILE_SYMLINK_CYCLE_UNIQUENESS, new FileSymlinkCycleUniquenessFunction()); map.put(SkyFunctions.FILE_SYMLINK_INFINITE_EXPANSION_UNIQUENESS, new FileSymlinkInfiniteExpansionUniquenessFunction()); - map.put(SkyFunctions.FILE, new FileFunction(pkgLocator)); + map.put(FileValue.FILE, new FileFunction(pkgLocator)); map.put(SkyFunctions.DIRECTORY_LISTING, new DirectoryListingFunction()); map.put( SkyFunctions.PACKAGE_LOOKUP, @@ -1038,7 +1040,7 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory { Map valuesToInject = new HashMap<>(); for (Map.Entry entry : diff.changedKeysWithNewAndOldValues().entrySet()) { SkyKey key = entry.getKey(); - Preconditions.checkState(key.functionName().equals(SkyFunctions.FILE_STATE), key); + Preconditions.checkState(key.functionName().equals(FileStateValue.FILE_STATE), key); RootedPath rootedPath = (RootedPath) key.argument(); Delta delta = entry.getValue(); FileStateValue oldValue = (FileStateValue) delta.getOldValue(); @@ -1074,7 +1076,7 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory { } } for (SkyKey key : diff.changedKeysWithoutNewValues()) { - Preconditions.checkState(key.functionName().equals(SkyFunctions.FILE_STATE), key); + Preconditions.checkState(key.functionName().equals(FileStateValue.FILE_STATE), key); RootedPath rootedPath = (RootedPath) key.argument(); valuesToInvalidate.add(parentDirectoryListingStateKey(rootedPath)); } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeIncrementalBuildMonitor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeIncrementalBuildMonitor.java index 462e51f852..3ab37e296d 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeIncrementalBuildMonitor.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeIncrementalBuildMonitor.java @@ -16,6 +16,7 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.collect.ImmutableSet; import com.google.common.eventbus.EventBus; import com.google.devtools.build.lib.actions.ChangedFilesMessage; +import com.google.devtools.build.lib.actions.FileStateValue; import com.google.devtools.build.lib.concurrent.ThreadSafety; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.lib.vfs.RootedPath; @@ -37,7 +38,7 @@ class SkyframeIncrementalBuildMonitor { public void accrue(Iterable invalidatedValues) { for (SkyKey skyKey : invalidatedValues) { - if (skyKey.functionName().equals(SkyFunctions.FILE_STATE)) { + if (skyKey.functionName().equals(FileStateValue.FILE_STATE)) { RootedPath file = (RootedPath) skyKey.argument(); maybeAddFile(file.getRootRelativePath()); } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframePackageLoaderWithValueEnvironment.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframePackageLoaderWithValueEnvironment.java index 9903969613..a674abb8f5 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframePackageLoaderWithValueEnvironment.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframePackageLoaderWithValueEnvironment.java @@ -13,6 +13,7 @@ // limitations under the License. package com.google.devtools.build.lib.skyframe; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Fragment; import com.google.devtools.build.lib.analysis.config.BuildOptions; import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java index 93f7596723..9dc5ed80ab 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java @@ -26,6 +26,7 @@ import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.LabelSyntaxException; import com.google.devtools.build.lib.cmdline.PackageIdentifier; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TargetMarkerFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/TargetMarkerFunction.java index 1758fb3f1f..234eb6c9ec 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/TargetMarkerFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/TargetMarkerFunction.java @@ -13,6 +13,7 @@ // limitations under the License. package com.google.devtools.build.lib.skyframe; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.PackageIdentifier; import com.google.devtools.build.lib.packages.BuildFileNotFoundException; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TreeArtifactValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/TreeArtifactValue.java index 4cf001457a..b7ca9088e5 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/TreeArtifactValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/TreeArtifactValue.java @@ -21,8 +21,8 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.actions.cache.DigestUtils; -import com.google.devtools.build.lib.actions.cache.Metadata; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; @@ -61,7 +61,7 @@ class TreeArtifactValue implements SkyValue { * and their corresponding FileArtifactValues. */ static TreeArtifactValue create(Map childFileValues) { - Map digestBuilder = + Map digestBuilder = Maps.newHashMapWithExpectedSize(childFileValues.size()); for (Map.Entry e : childFileValues.entrySet()) { digestBuilder.put(e.getKey().getParentRelativePath().getPathString(), e.getValue()); @@ -76,7 +76,7 @@ class TreeArtifactValue implements SkyValue { return FileArtifactValue.createProxy(digest); } - Metadata getMetadata() { + FileArtifactValue getMetadata() { return getSelfData(); } @@ -129,57 +129,57 @@ class TreeArtifactValue implements SkyValue { } /** - * A TreeArtifactValue that represents a missing TreeArtifact. - * This is occasionally useful because Java's concurrent collections disallow null members. + * A TreeArtifactValue that represents a missing TreeArtifact. This is occasionally useful because + * Java's concurrent collections disallow null members. */ - static final TreeArtifactValue MISSING_TREE_ARTIFACT = new TreeArtifactValue(null, - ImmutableMap.of()) { - @Override - FileArtifactValue getSelfData() { - throw new UnsupportedOperationException(); - } + static final TreeArtifactValue MISSING_TREE_ARTIFACT = + new TreeArtifactValue(null, ImmutableMap.of()) { + @Override + FileArtifactValue getSelfData() { + throw new UnsupportedOperationException(); + } - @Override - Iterable getChildren() { - throw new UnsupportedOperationException(); - } + @Override + Iterable getChildren() { + throw new UnsupportedOperationException(); + } - @Override - Map getChildValues() { - throw new UnsupportedOperationException(); - } + @Override + Map getChildValues() { + throw new UnsupportedOperationException(); + } - @Override - Metadata getMetadata() { - throw new UnsupportedOperationException(); - } + @Override + FileArtifactValue getMetadata() { + throw new UnsupportedOperationException(); + } - @Override - Set getChildPaths() { - throw new UnsupportedOperationException(); - } + @Override + Set getChildPaths() { + throw new UnsupportedOperationException(); + } - @Nullable - @Override - byte[] getDigest() { - throw new UnsupportedOperationException(); - } + @Nullable + @Override + byte[] getDigest() { + throw new UnsupportedOperationException(); + } - @Override - public int hashCode() { - return 24; // my favorite number - } + @Override + public int hashCode() { + return 24; // my favorite number + } - @Override - public boolean equals(Object other) { - return this == other; - } + @Override + public boolean equals(Object other) { + return this == other; + } - @Override - public String toString() { - return "MISSING_TREE_ARTIFACT"; - } - }; + @Override + public String toString() { + return "MISSING_TREE_ARTIFACT"; + } + }; private static void explodeDirectory(Artifact treeArtifact, PathFragment pathToExplode, ImmutableSet.Builder valuesBuilder) diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java index a36fd32677..a8d14cae61 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java @@ -15,6 +15,7 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException; import com.google.devtools.build.lib.packages.RuleClassProvider; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java b/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java index d8f4cb8b83..d0f74c5957 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java @@ -23,6 +23,8 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.eventbus.EventBus; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.ServerDirectories; import com.google.devtools.build.lib.clock.BlazeClock; @@ -388,12 +390,12 @@ public abstract class AbstractPackageLoader implements PackageLoader { ImmutableMap.Builder builder = ImmutableMap.builder(); builder .put(SkyFunctions.PRECOMPUTED, new PrecomputedFunction()) - .put(SkyFunctions.FILE_STATE, new FileStateFunction(tsgm, externalFilesHelper)) + .put(FileStateValue.FILE_STATE, new FileStateFunction(tsgm, externalFilesHelper)) .put(SkyFunctions.FILE_SYMLINK_CYCLE_UNIQUENESS, new FileSymlinkCycleUniquenessFunction()) .put( SkyFunctions.FILE_SYMLINK_INFINITE_EXPANSION_UNIQUENESS, new FileSymlinkInfiniteExpansionUniquenessFunction()) - .put(SkyFunctions.FILE, new FileFunction(pkgLocatorRef)) + .put(FileValue.FILE, new FileFunction(pkgLocatorRef)) .put( SkyFunctions.PACKAGE_LOOKUP, new PackageLookupFunction( diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/packages/BUILD b/src/main/java/com/google/devtools/build/lib/skyframe/packages/BUILD index 7cb108a81d..1fc1d1730b 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/packages/BUILD +++ b/src/main/java/com/google/devtools/build/lib/skyframe/packages/BUILD @@ -17,6 +17,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib:events", "//src/main/java/com/google/devtools/build/lib:io", "//src/main/java/com/google/devtools/build/lib:packages-internal", + "//src/main/java/com/google/devtools/build/lib/actions", "//src/main/java/com/google/devtools/build/lib/bazel/repository/cache", "//src/main/java/com/google/devtools/build/lib/bazel/repository/downloader", "//src/main/java/com/google/devtools/build/lib/clock", diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerFilesHash.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerFilesHash.java index ddc7da791f..f35823a83e 100644 --- a/src/main/java/com/google/devtools/build/lib/worker/WorkerFilesHash.java +++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerFilesHash.java @@ -23,8 +23,8 @@ import com.google.devtools.build.lib.actions.ActionInputFileCache; import com.google.devtools.build.lib.actions.ActionInputHelper; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.actions.Spawn; -import com.google.devtools.build.lib.actions.cache.Metadata; import com.google.devtools.build.lib.vfs.PathFragment; import java.io.IOException; import java.nio.charset.Charset; @@ -72,7 +72,7 @@ class WorkerFilesHash { for (Map.Entry mapping : rootAndMappings.getValue().entrySet()) { Artifact localArtifact = mapping.getValue(); if (localArtifact != null) { - Metadata metadata = actionInputFileCache.getMetadata(localArtifact); + FileArtifactValue metadata = actionInputFileCache.getMetadata(localArtifact); if (metadata.getType().isFile()) { workerFilesMap.put( root.getRelative(mapping.getKey()), diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD index 0e83b5905a..29b35fd409 100644 --- a/src/test/java/com/google/devtools/build/lib/BUILD +++ b/src/test/java/com/google/devtools/build/lib/BUILD @@ -1487,6 +1487,7 @@ java_test( "//src/main/java/com/google/devtools/build/lib:events", "//src/main/java/com/google/devtools/build/lib:io", "//src/main/java/com/google/devtools/build/lib:packages-internal", + "//src/main/java/com/google/devtools/build/lib/actions", "//src/main/java/com/google/devtools/build/lib/vfs", "//src/main/java/com/google/devtools/build/skyframe", "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects", diff --git a/src/test/java/com/google/devtools/build/lib/actions/ActionCacheCheckerTest.java b/src/test/java/com/google/devtools/build/lib/actions/ActionCacheCheckerTest.java index 87578eb195..a84efb34ca 100644 --- a/src/test/java/com/google/devtools/build/lib/actions/ActionCacheCheckerTest.java +++ b/src/test/java/com/google/devtools/build/lib/actions/ActionCacheCheckerTest.java @@ -22,7 +22,6 @@ import com.google.devtools.build.lib.actions.ActionCacheChecker.Token; import com.google.devtools.build.lib.actions.cache.ActionCache; import com.google.devtools.build.lib.actions.cache.CompactPersistentActionCache; import com.google.devtools.build.lib.actions.cache.Md5Digest; -import com.google.devtools.build.lib.actions.cache.Metadata; import com.google.devtools.build.lib.actions.cache.MetadataHandler; import com.google.devtools.build.lib.actions.cache.Protos.ActionCacheStatistics; import com.google.devtools.build.lib.actions.cache.Protos.ActionCacheStatistics.MissDetail; @@ -32,7 +31,6 @@ import com.google.devtools.build.lib.actions.util.ActionsTestUtil.FakeMetadataHa import com.google.devtools.build.lib.actions.util.ActionsTestUtil.MissDetailsBuilder; import com.google.devtools.build.lib.actions.util.ActionsTestUtil.NullAction; import com.google.devtools.build.lib.clock.Clock; -import com.google.devtools.build.lib.skyframe.FileArtifactValue; import com.google.devtools.build.lib.testutil.ManualClock; import com.google.devtools.build.lib.testutil.Scratch; import com.google.devtools.build.lib.util.Fingerprint; @@ -335,7 +333,7 @@ public class ActionCacheCheckerTest { /** A fake metadata handler that is able to obtain metadata from the file system. */ private static class FakeMetadataHandler extends FakeMetadataHandlerBase { @Override - public Metadata getMetadata(Artifact artifact) throws IOException { + public FileArtifactValue getMetadata(Artifact artifact) throws IOException { return FileArtifactValue.create(artifact); } diff --git a/src/test/java/com/google/devtools/build/lib/actions/ActionInputMapTest.java b/src/test/java/com/google/devtools/build/lib/actions/ActionInputMapTest.java index 5690fecaf5..2f3313e2ea 100644 --- a/src/test/java/com/google/devtools/build/lib/actions/ActionInputMapTest.java +++ b/src/test/java/com/google/devtools/build/lib/actions/ActionInputMapTest.java @@ -16,7 +16,7 @@ package com.google.devtools.build.lib.actions; import static com.google.common.truth.Truth.assertThat; import static java.nio.charset.StandardCharsets.US_ASCII; -import com.google.devtools.build.lib.actions.cache.Metadata; +import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; import java.util.ArrayList; import java.util.Collections; @@ -160,7 +160,7 @@ public final class ActionInputMapTest { } } - private static class TestMetadata implements Metadata { + private static class TestMetadata extends FileArtifactValue { private final int id; public TestMetadata(int id) { @@ -187,6 +187,11 @@ public final class ActionInputMapTest { throw new UnsupportedOperationException(); } + @Override + public boolean wasModifiedSinceDigest(Path path) { + throw new UnsupportedOperationException(); + } + @Override @SuppressWarnings("EqualsHashCode") public boolean equals(Object o) { diff --git a/src/test/java/com/google/devtools/build/lib/actions/cache/CompactPersistentActionCacheTest.java b/src/test/java/com/google/devtools/build/lib/actions/cache/CompactPersistentActionCacheTest.java index 90eec0c6ce..54b4d9dc28 100644 --- a/src/test/java/com/google/devtools/build/lib/actions/cache/CompactPersistentActionCacheTest.java +++ b/src/test/java/com/google/devtools/build/lib/actions/cache/CompactPersistentActionCacheTest.java @@ -17,7 +17,7 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import com.google.common.collect.ImmutableMap; -import com.google.devtools.build.lib.skyframe.FileArtifactValue; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.testutil.ManualClock; import com.google.devtools.build.lib.testutil.Scratch; import com.google.devtools.build.lib.vfs.Path; diff --git a/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java b/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java index bad5203a0c..013f57e162 100644 --- a/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java +++ b/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java @@ -46,11 +46,11 @@ import com.google.devtools.build.lib.actions.ArtifactOwner; import com.google.devtools.build.lib.actions.ArtifactResolver; import com.google.devtools.build.lib.actions.ArtifactRoot; import com.google.devtools.build.lib.actions.Executor; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.actions.MutableActionGraph; import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException; import com.google.devtools.build.lib.actions.PackageRootResolver; import com.google.devtools.build.lib.actions.cache.Md5Digest; -import com.google.devtools.build.lib.actions.cache.Metadata; import com.google.devtools.build.lib.actions.cache.MetadataHandler; import com.google.devtools.build.lib.actions.cache.Protos.ActionCacheStatistics.MissDetail; import com.google.devtools.build.lib.actions.cache.Protos.ActionCacheStatistics.MissReason; @@ -709,7 +709,7 @@ public final class ActionsTestUtil { */ public static class FakeMetadataHandlerBase implements MetadataHandler { @Override - public Metadata getMetadata(Artifact artifact) throws IOException { + public FileArtifactValue getMetadata(Artifact artifact) throws IOException { throw new UnsupportedOperationException(); } diff --git a/src/test/java/com/google/devtools/build/lib/exec/SpawnInputExpanderTest.java b/src/test/java/com/google/devtools/build/lib/exec/SpawnInputExpanderTest.java index 211dbe911b..67be7faaf4 100644 --- a/src/test/java/com/google/devtools/build/lib/exec/SpawnInputExpanderTest.java +++ b/src/test/java/com/google/devtools/build/lib/exec/SpawnInputExpanderTest.java @@ -27,12 +27,12 @@ import com.google.devtools.build.lib.actions.ActionInputHelper; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.ArtifactRoot; import com.google.devtools.build.lib.actions.EmptyRunfilesSupplier; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.actions.FilesetOutputSymlink; import com.google.devtools.build.lib.actions.RunfilesSupplier; import com.google.devtools.build.lib.analysis.Runfiles; import com.google.devtools.build.lib.analysis.RunfilesSupplierImpl; import com.google.devtools.build.lib.exec.util.FakeActionInputFileCache; -import com.google.devtools.build.lib.skyframe.FileArtifactValue; import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; diff --git a/src/test/java/com/google/devtools/build/lib/exec/util/FakeActionInputFileCache.java b/src/test/java/com/google/devtools/build/lib/exec/util/FakeActionInputFileCache.java index 9c215fceb4..6eb2668981 100644 --- a/src/test/java/com/google/devtools/build/lib/exec/util/FakeActionInputFileCache.java +++ b/src/test/java/com/google/devtools/build/lib/exec/util/FakeActionInputFileCache.java @@ -16,24 +16,24 @@ package com.google.devtools.build.lib.exec.util; import com.google.common.base.Preconditions; import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ActionInputFileCache; -import com.google.devtools.build.lib.actions.cache.Metadata; +import com.google.devtools.build.lib.actions.FileArtifactValue; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** A fake implementation of the {@link ActionInputFileCache} interface. */ public final class FakeActionInputFileCache implements ActionInputFileCache { - private final Map inputs = new HashMap<>(); + private final Map inputs = new HashMap<>(); public FakeActionInputFileCache() { } - public void put(ActionInput artifact, Metadata metadata) { + public void put(ActionInput artifact, FileArtifactValue metadata) { inputs.put(artifact, metadata); } @Override - public Metadata getMetadata(ActionInput input) throws IOException { + public FileArtifactValue getMetadata(ActionInput input) throws IOException { return Preconditions.checkNotNull(inputs.get(input)); } } diff --git a/src/test/java/com/google/devtools/build/lib/remote/FakeActionInputFileCache.java b/src/test/java/com/google/devtools/build/lib/remote/FakeActionInputFileCache.java index 26cc290503..729eeb2dbf 100644 --- a/src/test/java/com/google/devtools/build/lib/remote/FakeActionInputFileCache.java +++ b/src/test/java/com/google/devtools/build/lib/remote/FakeActionInputFileCache.java @@ -19,10 +19,9 @@ import com.google.common.collect.HashBiMap; import com.google.common.hash.HashCode; import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ActionInputFileCache; -import com.google.devtools.build.lib.actions.cache.Metadata; +import com.google.devtools.build.lib.actions.FileArtifactValue; +import com.google.devtools.build.lib.actions.FileContentsProxy; import com.google.devtools.build.lib.remote.util.DigestUtil; -import com.google.devtools.build.lib.skyframe.FileArtifactValue; -import com.google.devtools.build.lib.skyframe.FileContentsProxy; import com.google.devtools.build.lib.vfs.FileStatus; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; @@ -43,7 +42,7 @@ final class FakeActionInputFileCache implements ActionInputFileCache { } @Override - public Metadata getMetadata(ActionInput input) throws IOException { + public FileArtifactValue getMetadata(ActionInput input) throws IOException { String hexDigest = Preconditions.checkNotNull(cas.get(input), input); Path path = execRoot.getRelative(input.getExecPath()); FileStatus stat = path.stat(Symlinks.FOLLOW); diff --git a/src/test/java/com/google/devtools/build/lib/repository/ExternalPackageUtilTest.java b/src/test/java/com/google/devtools/build/lib/repository/ExternalPackageUtilTest.java index 4655acc06a..709d9dc237 100644 --- a/src/test/java/com/google/devtools/build/lib/repository/ExternalPackageUtilTest.java +++ b/src/test/java/com/google/devtools/build/lib/repository/ExternalPackageUtilTest.java @@ -20,6 +20,8 @@ import static com.google.devtools.build.skyframe.EvaluationResultSubjectFactory. import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.ServerDirectories; import com.google.devtools.build.lib.analysis.util.AnalysisMock; @@ -110,10 +112,10 @@ public class ExternalPackageUtilTest extends BuildViewTestCase { CrossRepositoryLabelViolationStrategy.ERROR, BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY)); skyFunctions.put( - SkyFunctions.FILE_STATE, + FileStateValue.FILE_STATE, new FileStateFunction( new AtomicReference(), externalFilesHelper)); - skyFunctions.put(SkyFunctions.FILE, new FileFunction(pkgLocator)); + skyFunctions.put(FileValue.FILE, new FileFunction(pkgLocator)); RuleClassProvider ruleClassProvider = analysisMock.createRuleClassProvider(); skyFunctions.put(SkyFunctions.WORKSPACE_AST, new WorkspaceASTFunction(ruleClassProvider)); skyFunctions.put( diff --git a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java index 78f2d01952..8bde0bc8d2 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java @@ -18,6 +18,8 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.ServerDirectories; import com.google.devtools.build.lib.cmdline.RepositoryName; @@ -98,10 +100,10 @@ public class RepositoryDelegatorTest extends FoundationTestCase { new InMemoryMemoizingEvaluator( ImmutableMap.builder() .put( - SkyFunctions.FILE_STATE, + FileStateValue.FILE_STATE, new FileStateFunction( new AtomicReference(), externalFilesHelper)) - .put(SkyFunctions.FILE, new FileFunction(pkgLocator)) + .put(FileValue.FILE, new FileFunction(pkgLocator)) .put(SkyFunctions.REPOSITORY_DIRECTORY, delegatorFunction) .put( SkyFunctions.PACKAGE, diff --git a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java index c767d51599..f399544ede 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java @@ -18,15 +18,15 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.annotations.VisibleForTesting; import com.google.common.io.BaseEncoding; +import com.google.devtools.build.lib.actions.FileContentsProxy; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileStateValue.RegularFileStateValue; +import com.google.devtools.build.lib.actions.FileValue; +import com.google.devtools.build.lib.actions.FileValue.RegularFileValue; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; import com.google.devtools.build.lib.packages.Rule; -import com.google.devtools.build.lib.skyframe.FileContentsProxy; -import com.google.devtools.build.lib.skyframe.FileStateValue; -import com.google.devtools.build.lib.skyframe.FileStateValue.RegularFileStateValue; -import com.google.devtools.build.lib.skyframe.FileValue; -import com.google.devtools.build.lib.skyframe.FileValue.RegularFileValue; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ActionTemplateExpansionFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ActionTemplateExpansionFunctionTest.java index 9703fb466f..ef300318ac 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/ActionTemplateExpansionFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/ActionTemplateExpansionFunctionTest.java @@ -33,6 +33,7 @@ import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact; import com.google.devtools.build.lib.actions.ArtifactOwner; import com.google.devtools.build.lib.actions.ArtifactPrefixConflictException; import com.google.devtools.build.lib.actions.ArtifactRoot; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException; import com.google.devtools.build.lib.actions.util.ActionsTestUtil; import com.google.devtools.build.lib.analysis.ConfiguredTarget; diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTest.java index 4615783887..2b137edcf2 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTest.java @@ -14,7 +14,7 @@ package com.google.devtools.build.lib.skyframe; import static com.google.common.truth.Truth.assertThat; -import static com.google.devtools.build.lib.skyframe.FileArtifactValue.create; +import static com.google.devtools.build.lib.actions.FileArtifactValue.create; import static org.junit.Assert.fail; import com.google.common.collect.ImmutableList; @@ -33,6 +33,8 @@ import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType; import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact; import com.google.devtools.build.lib.actions.ArtifactRoot; import com.google.devtools.build.lib.actions.BasicActionLookupValue; +import com.google.devtools.build.lib.actions.FileArtifactValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.actions.MissingInputFileException; import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException; import com.google.devtools.build.lib.actions.util.ActionsTestUtil; diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTestCase.java b/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTestCase.java index c0c2d73559..aa736834a8 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTestCase.java @@ -19,6 +19,8 @@ import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.actions.ActionAnalysisMetadata; import com.google.devtools.build.lib.actions.ActionKeyContext; import com.google.devtools.build.lib.actions.ActionLookupValue.ActionLookupKey; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.ServerDirectories; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; @@ -91,10 +93,10 @@ abstract class ArtifactFunctionTestCase { new InMemoryMemoizingEvaluator( ImmutableMap.builder() .put( - SkyFunctions.FILE_STATE, + FileStateValue.FILE_STATE, new FileStateFunction( new AtomicReference(), externalFilesHelper)) - .put(SkyFunctions.FILE, new FileFunction(pkgLocator)) + .put(FileValue.FILE, new FileFunction(pkgLocator)) .put(SkyFunctions.ARTIFACT, new ArtifactFunction()) .put(SkyFunctions.ACTION_EXECUTION, new SimpleActionExecutionFunction()) .put( diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java index 100b0868a5..4c845afc2d 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java @@ -19,6 +19,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.testing.EqualsTester; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.ServerDirectories; import com.google.devtools.build.lib.analysis.util.AnalysisMock; @@ -108,9 +110,11 @@ public class ContainingPackageLookupFunctionTest extends FoundationTestCase { new BlacklistedPackagePrefixesFunction( /*hardcodedBlacklistedPackagePrefixes=*/ ImmutableSet.of(), /*additionalBlacklistedPackagePrefixesFile=*/ PathFragment.EMPTY_FRAGMENT)); - skyFunctions.put(SkyFunctions.FILE_STATE, new FileStateFunction( - new AtomicReference(), externalFilesHelper)); - skyFunctions.put(SkyFunctions.FILE, new FileFunction(pkgLocator)); + skyFunctions.put( + FileStateValue.FILE_STATE, + new FileStateFunction( + new AtomicReference(), externalFilesHelper)); + skyFunctions.put(FileValue.FILE, new FileFunction(pkgLocator)); skyFunctions.put(SkyFunctions.DIRECTORY_LISTING, new DirectoryListingFunction()); skyFunctions.put( SkyFunctions.DIRECTORY_LISTING_STATE, diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FileArtifactValueTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FileArtifactValueTest.java index 87e4bd2a6d..92ed59611f 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/FileArtifactValueTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/FileArtifactValueTest.java @@ -14,11 +14,12 @@ package com.google.devtools.build.lib.skyframe; import static com.google.common.truth.Truth.assertThat; -import static com.google.devtools.build.lib.skyframe.FileArtifactValue.create; +import static com.google.devtools.build.lib.actions.FileArtifactValue.create; import static org.junit.Assert.fail; import com.google.common.io.BaseEncoding; import com.google.common.testing.EqualsTester; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.testutil.ManualClock; import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.FileSystemUtils; diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FileContentsProxyTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FileContentsProxyTest.java index 0ca3da5f80..db4cdc028b 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/FileContentsProxyTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/FileContentsProxyTest.java @@ -16,6 +16,7 @@ package com.google.devtools.build.lib.skyframe; import static com.google.common.truth.Truth.assertThat; import com.google.common.testing.EqualsTester; +import com.google.devtools.build.lib.actions.FileContentsProxy; import com.google.devtools.build.lib.vfs.FileStatus; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java index 926d63b2ac..390436b0c7 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java @@ -30,6 +30,9 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.common.testing.EqualsTester; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.ServerDirectories; import com.google.devtools.build.lib.clock.BlazeClock; @@ -140,7 +143,7 @@ public class FileFunctionTest { new InMemoryMemoizingEvaluator( ImmutableMap.builder() .put( - SkyFunctions.FILE_STATE, + FileStateValue.FILE_STATE, new FileStateFunction( new AtomicReference(), externalFilesHelper)) .put( @@ -149,7 +152,7 @@ public class FileFunctionTest { .put( SkyFunctions.FILE_SYMLINK_INFINITE_EXPANSION_UNIQUENESS, new FileSymlinkInfiniteExpansionUniquenessFunction()) - .put(SkyFunctions.FILE, new FileFunction(pkgLocatorRef)) + .put(FileValue.FILE, new FileFunction(pkgLocatorRef)) .put( SkyFunctions.PACKAGE, new PackageFunction(null, null, null, null, null, null, null)) @@ -765,7 +768,7 @@ public class FileFunctionTest { Iterables.transform( Iterables.filter( graph.getValues().keySet(), - SkyFunctionName.functionIs(SkyFunctions.FILE_STATE)), + SkyFunctionName.functionIs(FileStateValue.FILE_STATE)), new Function() { @Override public Object apply(SkyKey skyKey) { diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FileStateValueTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FileStateValueTest.java index 36f8d248b7..f3b3c5851d 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/FileStateValueTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/FileStateValueTest.java @@ -14,6 +14,8 @@ package com.google.devtools.build.lib.skyframe; +import com.google.devtools.build.lib.actions.FileContentsProxy; +import com.google.devtools.build.lib.actions.FileStateValue; import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester; import com.google.devtools.build.lib.vfs.PathFragment; import org.junit.Test; diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FileValueTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FileValueTest.java index c6d0a34d74..2b059ab170 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/FileValueTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/FileValueTest.java @@ -14,6 +14,8 @@ package com.google.devtools.build.lib.skyframe; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.skyframe.serialization.testutils.FsUtils; import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester; import com.google.devtools.build.lib.vfs.FileSystem; diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunctionTest.java index 02088a9d7e..df0320f16d 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunctionTest.java @@ -26,6 +26,8 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.ArtifactRoot; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.actions.FilesetOutputSymlink; import com.google.devtools.build.lib.actions.FilesetTraversalParams; import com.google.devtools.build.lib.actions.FilesetTraversalParams.PackageBoundaryMode; @@ -101,9 +103,11 @@ public final class FilesetEntryFunctionTest extends FoundationTestCase { Map skyFunctions = new HashMap<>(); - skyFunctions.put(SkyFunctions.FILE_STATE, new FileStateFunction( - new AtomicReference(), externalFilesHelper)); - skyFunctions.put(SkyFunctions.FILE, new FileFunction(pkgLocator)); + skyFunctions.put( + FileStateValue.FILE_STATE, + new FileStateFunction( + new AtomicReference(), externalFilesHelper)); + skyFunctions.put(FileValue.FILE, new FileFunction(pkgLocator)); skyFunctions.put(SkyFunctions.DIRECTORY_LISTING, new DirectoryListingFunction()); skyFunctions.put( SkyFunctions.DIRECTORY_LISTING_STATE, diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FilesystemValueCheckerTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FilesystemValueCheckerTest.java index f0112d4c9f..385b738a19 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/FilesystemValueCheckerTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/FilesystemValueCheckerTest.java @@ -30,6 +30,9 @@ import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType; import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact; import com.google.devtools.build.lib.actions.ArtifactOwner; import com.google.devtools.build.lib.actions.ArtifactRoot; +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.actions.util.TestAction; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.ServerDirectories; @@ -117,9 +120,11 @@ public class FilesystemValueCheckerTest { TestConstants.PRODUCT_NAME); ExternalFilesHelper externalFilesHelper = ExternalFilesHelper.createForTesting( pkgLocator, ExternalFileAction.DEPEND_ON_EXTERNAL_PKG_FOR_EXTERNAL_REPO_PATHS, directories); - skyFunctions.put(SkyFunctions.FILE_STATE, new FileStateFunction( - new AtomicReference(), externalFilesHelper)); - skyFunctions.put(SkyFunctions.FILE, new FileFunction(pkgLocator)); + skyFunctions.put( + FileStateValue.FILE_STATE, + new FileStateFunction( + new AtomicReference(), externalFilesHelper)); + skyFunctions.put(FileValue.FILE, new FileFunction(pkgLocator)); skyFunctions.put( SkyFunctions.FILE_SYMLINK_CYCLE_UNIQUENESS, new FileSymlinkCycleUniquenessFunction()); skyFunctions.put( diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/GlobFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/GlobFunctionTest.java index 167672a346..7d118c6f0c 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/GlobFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/GlobFunctionTest.java @@ -24,6 +24,9 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.testing.EqualsTester; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; +import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.ServerDirectories; import com.google.devtools.build.lib.analysis.util.AnalysisMock; @@ -160,10 +163,10 @@ public abstract class GlobFunctionTest { /*hardcodedBlacklistedPackagePrefixes=*/ ImmutableSet.of(), /*additionalBlacklistedPackagePrefixesFile=*/ PathFragment.EMPTY_FRAGMENT)); skyFunctions.put( - SkyFunctions.FILE_STATE, + FileStateValue.FILE_STATE, new FileStateFunction( new AtomicReference(), externalFilesHelper)); - skyFunctions.put(SkyFunctions.FILE, new FileFunction(pkgLocator)); + skyFunctions.put(FileValue.FILE, new FileFunction(pkgLocator)); skyFunctions.put(SkyFunctions.DIRECTORY_LISTING, new DirectoryListingFunction()); skyFunctions.put( SkyFunctions.DIRECTORY_LISTING_STATE, diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunctionTest.java index 3e457ba8be..30524ff2bf 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunctionTest.java @@ -18,6 +18,8 @@ import static com.google.devtools.build.skyframe.EvaluationResultSubjectFactory. import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.ServerDirectories; import com.google.devtools.build.lib.analysis.util.AnalysisMock; @@ -90,10 +92,10 @@ public class LocalRepositoryLookupFunctionTest extends FoundationTestCase { CrossRepositoryLabelViolationStrategy.ERROR, BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY)); skyFunctions.put( - SkyFunctions.FILE_STATE, + FileStateValue.FILE_STATE, new FileStateFunction( new AtomicReference(), externalFilesHelper)); - skyFunctions.put(SkyFunctions.FILE, new FileFunction(pkgLocator)); + skyFunctions.put(FileValue.FILE, new FileFunction(pkgLocator)); skyFunctions.put(SkyFunctions.DIRECTORY_LISTING, new DirectoryListingFunction()); skyFunctions.put( SkyFunctions.DIRECTORY_LISTING_STATE, diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java index db71edaf96..b6681d023f 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java @@ -22,6 +22,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; import com.google.devtools.build.lib.clock.BlazeClock; import com.google.devtools.build.lib.cmdline.Label; @@ -570,7 +572,7 @@ public class PackageFunctionTest extends BuildViewTestCase { getSkyframeExecutor() .invalidate( Predicates.equalTo( - com.google.devtools.build.lib.skyframe.FileStateValue.key( + FileStateValue.key( RootedPath.toRootedPath( Root.fromPath(workspacePath.getParentDirectory()), PathFragment.create(workspacePath.getBaseName()))))); diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java index 4d6339922f..75625593ae 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java @@ -21,6 +21,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.testing.EqualsTester; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.ServerDirectories; import com.google.devtools.build.lib.analysis.util.AnalysisMock; @@ -117,9 +119,11 @@ public abstract class PackageLookupFunctionTest extends FoundationTestCase { skyFunctions.put( SkyFunctions.PACKAGE, new PackageFunction(null, null, null, null, null, null, null)); - skyFunctions.put(SkyFunctions.FILE_STATE, new FileStateFunction( - new AtomicReference(), externalFilesHelper)); - skyFunctions.put(SkyFunctions.FILE, new FileFunction(pkgLocator)); + skyFunctions.put( + FileStateValue.FILE_STATE, + new FileStateFunction( + new AtomicReference(), externalFilesHelper)); + skyFunctions.put(FileValue.FILE, new FileFunction(pkgLocator)); skyFunctions.put(SkyFunctions.DIRECTORY_LISTING, new DirectoryListingFunction()); skyFunctions.put( SkyFunctions.DIRECTORY_LISTING_STATE, diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java index 6e62d1afdb..6ccaa19a3b 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java @@ -28,6 +28,9 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.ArtifactRoot; +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.actions.FilesetTraversalParams.DirectTraversalRoot; import com.google.devtools.build.lib.actions.FilesetTraversalParams.PackageBoundaryMode; import com.google.devtools.build.lib.analysis.BlazeDirectories; @@ -112,9 +115,10 @@ public final class RecursiveFilesystemTraversalFunctionTest extends FoundationTe ConfiguredRuleClassProvider ruleClassProvider = analysisMock.createRuleClassProvider(); Map skyFunctions = new HashMap<>(); - skyFunctions.put(SkyFunctions.FILE_STATE, new FileStateFunction( - new AtomicReference<>(), externalFilesHelper)); - skyFunctions.put(SkyFunctions.FILE, new FileFunction(pkgLocator)); + skyFunctions.put( + FileStateValue.FILE_STATE, + new FileStateFunction(new AtomicReference<>(), externalFilesHelper)); + skyFunctions.put(FileValue.FILE, new FileFunction(pkgLocator)); skyFunctions.put(SkyFunctions.DIRECTORY_LISTING, new DirectoryListingFunction()); skyFunctions.put( SkyFunctions.DIRECTORY_LISTING_STATE, diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java index 00cdc24dba..3bd08d38ec 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java @@ -29,6 +29,7 @@ import com.google.devtools.build.lib.actions.ActionKeyContext; import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Executor; +import com.google.devtools.build.lib.actions.FileStateValue; import com.google.devtools.build.lib.actions.util.ActionsTestUtil; import com.google.devtools.build.lib.actions.util.DummyExecutor; import com.google.devtools.build.lib.testutil.TimestampGranularityUtils; diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java index e17e673f5f..2b16cdfb1c 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java @@ -44,6 +44,8 @@ import com.google.devtools.build.lib.actions.ArtifactRoot; import com.google.devtools.build.lib.actions.BasicActionLookupValue; import com.google.devtools.build.lib.actions.BuildFailedException; import com.google.devtools.build.lib.actions.Executor; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException; import com.google.devtools.build.lib.actions.ResourceManager; import com.google.devtools.build.lib.actions.ResourceSet; @@ -203,8 +205,8 @@ public abstract class TimestampBuilderTestCase extends FoundationTestCase { final InMemoryMemoizingEvaluator evaluator = new InMemoryMemoizingEvaluator( ImmutableMap.builder() - .put(SkyFunctions.FILE_STATE, new FileStateFunction(tsgmRef, externalFilesHelper)) - .put(SkyFunctions.FILE, new FileFunction(pkgLocator)) + .put(FileStateValue.FILE_STATE, new FileStateFunction(tsgmRef, externalFilesHelper)) + .put(FileValue.FILE, new FileFunction(pkgLocator)) .put(SkyFunctions.ARTIFACT, new ArtifactFunction()) .put( SkyFunctions.ACTION_EXECUTION, diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java index 54a9302f46..1b9b6bc4f8 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java @@ -34,10 +34,11 @@ import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType; import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact; import com.google.devtools.build.lib.actions.ArtifactRoot; import com.google.devtools.build.lib.actions.BasicActionLookupValue; +import com.google.devtools.build.lib.actions.FileArtifactValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.actions.MissingInputFileException; import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException; import com.google.devtools.build.lib.actions.cache.DigestUtils; -import com.google.devtools.build.lib.actions.cache.Metadata; import com.google.devtools.build.lib.actions.util.TestAction.DummyAction; import com.google.devtools.build.lib.events.NullEventHandler; import com.google.devtools.build.lib.vfs.FileStatus; @@ -101,9 +102,9 @@ public class TreeArtifactMetadataTest extends ArtifactFunctionTestCase { // Assertions about digest. As of this writing this logic is essentially the same // as that in TreeArtifact, but it's good practice to unit test anyway to guard against // breaking changes. - Map digestBuilder = new HashMap<>(); + Map digestBuilder = new HashMap<>(); for (PathFragment child : children) { - Metadata subdigest = FileArtifactValue.create(tree.getPath().getRelative(child)); + FileArtifactValue subdigest = FileArtifactValue.create(tree.getPath().getRelative(child)); digestBuilder.put(child.getPathString(), subdigest); } assertThat(DigestUtils.fromMetadata(digestBuilder).getDigestBytesUnsafe()) @@ -114,7 +115,7 @@ public class TreeArtifactMetadataTest extends ArtifactFunctionTestCase { @Test public void testEmptyTreeArtifacts() throws Exception { TreeArtifactValue value = doTestTreeArtifacts(ImmutableList.of()); - // Additional test, only for this test method: we expect the Metadata is equal to + // Additional test, only for this test method: we expect the FileArtifactValue is equal to // the digest [0, 0, ...] assertThat(value.getMetadata().getDigest()).isEqualTo(value.getDigest()); // Java zero-fills arrays. diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunctionTest.java index ece3f59aed..b06f6c7546 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunctionTest.java @@ -16,6 +16,7 @@ package com.google.devtools.build.lib.skyframe; import static com.google.common.truth.Truth.assertThat; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; import com.google.devtools.build.lib.skyframe.WorkspaceFileFunctionTest.FakeFileValue; @@ -67,7 +68,7 @@ public class WorkspaceASTFunctionTest extends BuildViewTestCase { private SkyFunction.Environment getEnv() throws InterruptedException { SkyFunction.Environment env = Mockito.mock(SkyFunction.Environment.class); - Mockito.when(env.getValue(Matchers.argThat(new SkyKeyMatchers(SkyFunctions.FILE)))) + Mockito.when(env.getValue(Matchers.argThat(new SkyKeyMatchers(FileValue.FILE)))) .thenReturn(fakeWorkspaceFileValue); return env; } diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java index 95e9e880fa..4e633e4632 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java @@ -17,6 +17,8 @@ package com.google.devtools.build.lib.skyframe; import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.actions.FileStateValue; +import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; import com.google.devtools.build.lib.cmdline.Label; @@ -131,7 +133,7 @@ public class WorkspaceFileFunctionTest extends BuildViewTestCase { // Dummy harmcrest matcher that match the function name of a skykey static class SkyKeyMatchers extends BaseMatcher { private final SkyFunctionName functionName; - + public SkyKeyMatchers(SkyFunctionName functionName) { this.functionName = functionName; } @@ -142,14 +144,14 @@ public class WorkspaceFileFunctionTest extends BuildViewTestCase { } return false; } - + @Override public void describeTo(Description description) {} } private SkyFunction.Environment getEnv() throws InterruptedException { SkyFunction.Environment env = Mockito.mock(SkyFunction.Environment.class); - Mockito.when(env.getValue(Matchers.argThat(new SkyKeyMatchers(SkyFunctions.FILE)))) + Mockito.when(env.getValue(Matchers.argThat(new SkyKeyMatchers(FileValue.FILE)))) .thenReturn(fakeWorkspaceFileValue); Mockito.when(env.getValue(Matchers.argThat(new SkyKeyMatchers(SkyFunctions.WORKSPACE_FILE)))) .then( -- cgit v1.2.3