aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/vfs
diff options
context:
space:
mode:
authorGravatar felly <felly@google.com>2018-07-26 07:46:15 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-07-26 07:47:48 -0700
commit09efb3fb5cbefe48d7c6685b01cfd72f848563c8 (patch)
tree24f28786c42e6245ff0c8f99391a645d7610d741 /src/main/java/com/google/devtools/build/lib/vfs
parent74146fdbcc4eb0463e64588a764b22e253a405ac (diff)
Use the path resolver when dealing with tree artifacts.
RELNOTES: None PiperOrigin-RevId: 206157591
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/vfs')
-rw-r--r--src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/FileInfo.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryContentInfo.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileInfo.java103
-rw-r--r--src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystem.java45
4 files changed, 116 insertions, 45 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/FileInfo.java b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/FileInfo.java
index db2660cd26..4ac878aa56 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/FileInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/FileInfo.java
@@ -16,6 +16,7 @@ package com.google.devtools.build.lib.vfs.inmemoryfs;
import com.google.devtools.build.lib.clock.Clock;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
/**
@@ -47,7 +48,11 @@ public abstract class FileInfo extends InMemoryContentInfo {
return false;
}
- protected abstract byte[] readContent() throws IOException;
+ public abstract OutputStream getOutputStream(boolean append) throws IOException;
- protected abstract OutputStream getOutputStream(boolean append) throws IOException;
+ public abstract InputStream getInputStream() throws IOException;
+
+ public abstract byte[] getxattr(String name) throws IOException;
+
+ public abstract byte[] getFastDigest() throws IOException;
}
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryContentInfo.java b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryContentInfo.java
index 93c4eb294c..155e9762c7 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryContentInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryContentInfo.java
@@ -31,7 +31,7 @@ import java.io.IOException;
@ThreadSafe
public abstract class InMemoryContentInfo implements FileStatus {
- private final Clock clock;
+ protected final Clock clock;
/**
* Stores the time when the file was last modified. This is atomically updated
@@ -95,7 +95,7 @@ public abstract class InMemoryContentInfo implements FileStatus {
* size of links is unspecified.
*/
@Override
- public abstract long getSize() throws IOException;
+ public abstract long getSize();
/**
* Returns the time when the entity denoted by the current object was last
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileInfo.java b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileInfo.java
index 49777190f7..d73c4cc24d 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileInfo.java
@@ -14,10 +14,13 @@
package com.google.devtools.build.lib.vfs.inmemoryfs;
import com.google.common.base.Preconditions;
+import com.google.common.io.ByteStreams;
import com.google.devtools.build.lib.clock.Clock;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
/**
@@ -32,7 +35,7 @@ public class InMemoryFileInfo extends FileInfo {
*/
protected byte[] content;
- protected InMemoryFileInfo(Clock clock) {
+ public InMemoryFileInfo(Clock clock) {
super(clock);
content = new byte[0]; // New files start out empty.
}
@@ -43,8 +46,13 @@ public class InMemoryFileInfo extends FileInfo {
}
@Override
- public synchronized byte[] readContent() {
- return content.clone();
+ public byte[] getxattr(String name) {
+ return null;
+ }
+
+ @Override
+ public byte[] getFastDigest() {
+ return null;
}
private synchronized void setContent(byte[] newContent) {
@@ -53,44 +61,69 @@ public class InMemoryFileInfo extends FileInfo {
}
@Override
- protected synchronized OutputStream getOutputStream(boolean append)
- throws IOException {
- OutputStream out = new ByteArrayOutputStream() {
- private boolean closed = false;
-
- @Override
- public void write(byte[] data) throws IOException {
- Preconditions.checkState(!closed);
- super.write(data);
- }
+ public synchronized InputStream getInputStream() {
+ return new ByteArrayInputStream(content);
+ }
- @Override
- public synchronized void write(int dataByte) {
- Preconditions.checkState(!closed);
- super.write(dataByte);
+ @Override
+ public synchronized OutputStream getOutputStream(boolean append) {
+ OutputStream out = new InMemoryOutputStream(this::setContent);
+ if (append) {
+ try (InputStream in = getInputStream()) {
+ ByteStreams.copy(in, out);
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
}
+ }
+ return out;
+ }
- @Override
- public synchronized void write(byte[] data, int offset, int length) {
- Preconditions.checkState(!closed);
- super.write(data, offset, length);
- }
+ /**
+ * A {@link ByteArrayOutputStream} which notifiers a callback when it has flushed its data.
+ */
+ public static class InMemoryOutputStream extends ByteArrayOutputStream {
+ private final IOByteReceiver receiver;
+ private boolean closed = false;
- @Override
- public void close() {
- flush();
- closed = true;
- }
+ public InMemoryOutputStream(IOByteReceiver receiver) {
+ this.receiver = receiver;
+ }
- @Override
- public void flush() {
- setContent(toByteArray().clone());
- }
- };
+ @Override
+ public void write(byte[] data) throws IOException {
+ Preconditions.checkState(!closed);
+ super.write(data);
+ }
- if (append) {
- out.write(readContent());
+ @Override
+ public synchronized void write(int dataByte) {
+ Preconditions.checkState(!closed);
+ super.write(dataByte);
}
- return out;
+
+ @Override
+ public synchronized void write(byte[] data, int offset, int length) {
+ Preconditions.checkState(!closed);
+ super.write(data, offset, length);
+ }
+
+ @Override
+ public synchronized void close() throws IOException {
+ flush();
+ closed = true;
+ }
+
+ @Override
+ public synchronized void flush() throws IOException {
+ receiver.accept(toByteArray().clone());
+ }
+ }
+
+ /**
+ * Similar to {@link com.google.common.base.Receiver}, but allows implementations to throw
+ * {@link IOException}.
+ */
+ public interface IOByteReceiver {
+ void accept(byte[] bytes) throws IOException;
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystem.java b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystem.java
index bebe5b380c..f24a3d99a8 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystem.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystem.java
@@ -25,7 +25,6 @@ import com.google.devtools.build.lib.vfs.FileStatus;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
-import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -51,7 +50,7 @@ import javax.annotation.Nullable;
public class InMemoryFileSystem extends FileSystem {
private final PathFragment scopeRoot;
- private final Clock clock;
+ protected final Clock clock;
// The root inode (a directory).
private final InMemoryDirectoryInfo rootInode;
@@ -319,13 +318,17 @@ public class InMemoryFileSystem extends FileSystem {
if (!create) {
throw Error.ENOENT.exception(path);
} else {
- child = new InMemoryFileInfo(clock);
+ child = newFile(clock, path);
insert(imdi, name, child, path);
}
}
return child;
}
+ protected FileInfo newFile(Clock clock, Path path) {
+ return new InMemoryFileInfo(clock);
+ }
+
/**
* Low-level path-to-inode lookup routine. Analogous to path_walk() in many UNIX kernels. Given
* 'path', walks the directory tree from the root, resolving all symbolic links, and returns the
@@ -462,7 +465,7 @@ public class InMemoryFileSystem extends FileSystem {
* Version of stat that returns an inode if the input path stays entirely within this file
* system's scope, otherwise throws.
*/
- private InMemoryContentInfo scopeLimitedStat(Path path, boolean followSymlinks)
+ protected InMemoryContentInfo scopeLimitedStat(Path path, boolean followSymlinks)
throws IOException {
if (followSymlinks) {
return pathWalk(path, false);
@@ -747,12 +750,42 @@ public class InMemoryFileSystem extends FileSystem {
throw Error.EACCES.exception(path);
}
Preconditions.checkState(status instanceof FileInfo);
- return new ByteArrayInputStream(((FileInfo) status).readContent());
+ return ((FileInfo) status).getInputStream();
+ }
+ }
+
+ @Override
+ public byte[] getxattr(Path path, String name) throws IOException {
+ synchronized (this) {
+ InMemoryContentInfo status = scopeLimitedStat(path, true);
+ if (status.isDirectory()) {
+ throw Error.EISDIR.exception(path);
+ }
+ if (!path.isReadable()) {
+ throw Error.EACCES.exception(path);
+ }
+ Preconditions.checkState(status instanceof FileInfo);
+ return ((FileInfo) status).getxattr(name);
+ }
+ }
+
+ @Override
+ protected byte[] getFastDigest(Path path) throws IOException {
+ synchronized (this) {
+ InMemoryContentInfo status = scopeLimitedStat(path, true);
+ if (status.isDirectory()) {
+ throw Error.EISDIR.exception(path);
+ }
+ if (!path.isReadable()) {
+ throw Error.EACCES.exception(path);
+ }
+ Preconditions.checkState(status instanceof FileInfo);
+ return ((FileInfo) status).getFastDigest();
}
}
/** Creates a new file at the given path and returns its inode. */
- private InMemoryContentInfo getOrCreateWritableInode(Path path) throws IOException {
+ protected InMemoryContentInfo getOrCreateWritableInode(Path path) throws IOException {
// open(WR_ONLY) of a dangling link writes through the link. That means
// that the usual path lookup operations have to behave differently when
// resolving a path with the intent to create it: instead of failing with