aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/FileContentsProxy.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/FileStateValue.java16
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/FileValue.java44
-rw-r--r--src/test/java/com/google/devtools/build/lib/skyframe/FileStateValueTest.java45
-rw-r--r--src/test/java/com/google/devtools/build/lib/skyframe/FileValueTest.java44
5 files changed, 133 insertions, 26 deletions
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
index 8dca37c391..2b845edc38 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/FileContentsProxy.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/FileContentsProxy.java
@@ -13,21 +13,23 @@
// 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.
+ * 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.
*
* <p>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;
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
index 56988b8adb..f92e561ffa 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/FileStateValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/FileStateValue.java
@@ -58,8 +58,11 @@ import javax.annotation.Nullable;
@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();
@@ -151,10 +154,11 @@ public abstract class FileStateValue implements SkyValue {
*
* <p>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.
+ * 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;
@@ -270,6 +274,7 @@ public abstract class FileStateValue implements SkyValue {
}
/** Implementation of {@link FileStateValue} for special files that exist. */
+ @AutoCodec
public static final class SpecialFileStateValue extends FileStateValue {
private final FileContentsProxy contentsProxy;
@@ -330,7 +335,8 @@ public abstract class FileStateValue implements SkyValue {
}
/** Implementation of {@link FileStateValue} for directories that exist. */
- public static final class DirectoryFileStateValue extends FileStateValue {
+ @AutoCodec.VisibleForSerialization
+ static final class DirectoryFileStateValue extends FileStateValue {
private DirectoryFileStateValue() {
}
@@ -358,6 +364,7 @@ public abstract class FileStateValue implements SkyValue {
}
/** Implementation of {@link FileStateValue} for symlinks. */
+ @AutoCodec
public static final class SymlinkFileStateValue extends FileStateValue {
private final PathFragment symlinkTarget;
@@ -397,7 +404,8 @@ public abstract class FileStateValue implements SkyValue {
}
/** Implementation of {@link FileStateValue} for nonexistent files. */
- public static final class NonexistentFileStateValue extends FileStateValue {
+ @AutoCodec.VisibleForSerialization
+ static final class NonexistentFileStateValue extends FileStateValue {
private NonexistentFileStateValue() {
}
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
index a0fe84db92..46e75cef19 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/FileValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/FileValue.java
@@ -13,6 +13,7 @@
// 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;
@@ -168,14 +169,16 @@ public abstract class FileValue implements SkyValue {
* 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 fileState) {
+ public RegularFileValue(RootedPath rootedPath, FileStateValue fileStateValue) {
this.rootedPath = Preconditions.checkNotNull(rootedPath);
- this.fileStateValue = Preconditions.checkNotNull(fileState);
+ this.fileStateValue = Preconditions.checkNotNull(fileStateValue);
}
@Override
@@ -216,13 +219,15 @@ public abstract class FileValue implements SkyValue {
* 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.
*/
- public static class DifferentRealPathFileValue extends FileValue {
+ @AutoCodec.VisibleForSerialization
+ @AutoCodec
+ static class DifferentRealPathFileValue extends FileValue {
protected final RootedPath realRootedPath;
protected final FileStateValue realFileStateValue;
- public DifferentRealPathFileValue(RootedPath realRootedPath,
- FileStateValue realFileStateValue) {
+ @AutoCodec.VisibleForSerialization
+ DifferentRealPathFileValue(RootedPath realRootedPath, FileStateValue realFileStateValue) {
this.realRootedPath = Preconditions.checkNotNull(realRootedPath);
this.realFileStateValue = Preconditions.checkNotNull(realFileStateValue);
}
@@ -262,13 +267,16 @@ public abstract class FileValue implements SkyValue {
}
/** Implementation of {@link FileValue} for files that are symlinks. */
- public static final class SymlinkFileValue extends DifferentRealPathFileValue {
- private final PathFragment linkValue;
-
- public SymlinkFileValue(RootedPath realRootedPath, FileStateValue realFileState,
- PathFragment linkTarget) {
- super(realRootedPath, realFileState);
- this.linkValue = linkTarget;
+ @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
@@ -278,7 +286,7 @@ public abstract class FileValue implements SkyValue {
@Override
public PathFragment getUnresolvedLinkTarget() {
- return linkValue;
+ return linkTarget;
}
@Override
@@ -292,19 +300,19 @@ public abstract class FileValue implements SkyValue {
SymlinkFileValue other = (SymlinkFileValue) obj;
return realRootedPath.equals(other.realRootedPath)
&& realFileStateValue.equals(other.realFileStateValue)
- && linkValue.equals(other.linkValue);
+ && linkTarget.equals(other.linkTarget);
}
@Override
public int hashCode() {
- return Objects.hash(
- realRootedPath, realFileStateValue, linkValue, Boolean.TRUE);
+ 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, linkValue);
+ return String.format(
+ "symlink (real_path=%s, real_state=%s, link_value=%s)",
+ realRootedPath, realFileStateValue, linkTarget);
}
}
}
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
new file mode 100644
index 0000000000..36f8d248b7
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/FileStateValueTest.java
@@ -0,0 +1,45 @@
+// 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 com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link FileStateValue}. */
+@RunWith(JUnit4.class)
+public class FileStateValueTest {
+ @Test
+ public void testCodec() throws Exception {
+ new SerializationTester(
+ new FileStateValue.RegularFileStateValue(
+ /*size=*/ 1, /*digest=*/ new byte[] {1, 2, 3}, /*contentsProxy=*/ null),
+ new FileStateValue.RegularFileStateValue(
+ /*size=*/ 1, /*digest=*/ new byte[0], /*contentsProxy=*/ null),
+ new FileStateValue.RegularFileStateValue(
+ /*size=*/ 1,
+ /*digest=*/ null,
+ new FileContentsProxy(/* ctime= */ 2, /* nodeId= */ 42)),
+ new FileStateValue.SpecialFileStateValue(
+ new FileContentsProxy(/* ctime= */ 4, /* nodeId= */ 84)),
+ FileStateValue.DIRECTORY_FILE_STATE_NODE,
+ new FileStateValue.SymlinkFileStateValue(PathFragment.create("somewhere/elses")),
+ FileStateValue.NONEXISTENT_FILE_STATE_NODE)
+ .runTests();
+ }
+
+}
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
new file mode 100644
index 0000000000..c6d0a34d74
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/FileValueTest.java
@@ -0,0 +1,44 @@
+// 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 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;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link FileValue}. */
+@RunWith(JUnit4.class)
+public class FileValueTest {
+ @Test
+ public void testCodec() throws Exception {
+ new SerializationTester(
+ // Assume we have adequate coverage for FileStateValue serialization.
+ new FileValue.RegularFileValue(
+ FsUtils.TEST_ROOT, FileStateValue.NONEXISTENT_FILE_STATE_NODE),
+ new FileValue.DifferentRealPathFileValue(
+ FsUtils.TEST_ROOT, FileStateValue.DIRECTORY_FILE_STATE_NODE),
+ new FileValue.SymlinkFileValue(
+ FsUtils.TEST_ROOT,
+ new FileStateValue.RegularFileStateValue(
+ /*size=*/ 100, /*digest=*/ new byte[] {1, 2, 3, 4, 5}, /*contentsProxy=*/ null),
+ PathFragment.create("somewhere/else")))
+ .addDependency(FileSystem.class, FsUtils.TEST_FILESYSTEM)
+ .runTests();
+ }
+}