aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/remote/SimpleBlobStoreActionCache.java
diff options
context:
space:
mode:
authorGravatar ulfjack <ulfjack@google.com>2017-07-05 10:08:21 -0400
committerGravatar John Cater <jcater@google.com>2017-07-05 10:59:34 -0400
commit28f3b617f91f1a9ee9714b26f10d928ee4e1f970 (patch)
tree90c1de32fdecdbef279f2792e96d9fabf2d8190a /src/main/java/com/google/devtools/build/lib/remote/SimpleBlobStoreActionCache.java
parente212c0514df05c5df8da097ff9ce443e0dde43e9 (diff)
Change the SimpleBlobStore API to use Input/OutputStreams
This avoid having to load all the data into memory at once in most cases, especially for large files. PiperOrigin-RevId: 160954187
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/remote/SimpleBlobStoreActionCache.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/remote/SimpleBlobStoreActionCache.java58
1 files changed, 37 insertions, 21 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/remote/SimpleBlobStoreActionCache.java b/src/main/java/com/google/devtools/build/lib/remote/SimpleBlobStoreActionCache.java
index 559d55d3fc..8c0fcdc93a 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/SimpleBlobStoreActionCache.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/SimpleBlobStoreActionCache.java
@@ -35,8 +35,10 @@ import com.google.devtools.remoteexecution.v1test.OutputDirectory;
import com.google.devtools.remoteexecution.v1test.OutputFile;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.concurrent.Semaphore;
@@ -98,15 +100,12 @@ public final class SimpleBlobStoreActionCache implements RemoteActionCache {
throws IOException, InterruptedException {
// This unconditionally reads the whole file into memory first!
if (input instanceof VirtualActionInput) {
- ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- ((VirtualActionInput) input).writeTo(buffer);
- byte[] blob = buffer.toByteArray();
+ byte[] blob = ((VirtualActionInput) input).getBytes().toByteArray();
return uploadBlob(blob, Digests.computeDigest(blob));
}
- return uploadBlob(
- ByteString.readFrom(execRoot.getRelative(input.getExecPathString()).getInputStream())
- .toByteArray(),
- Digests.getDigestFromInputCache(input, inputCache));
+ try (InputStream in = execRoot.getRelative(input.getExecPathString()).getInputStream()) {
+ return uploadBlob(Digests.getDigestFromInputCache(input, inputCache), in);
+ }
}
@Override
@@ -159,7 +158,8 @@ public final class SimpleBlobStoreActionCache implements RemoteActionCache {
Digest stdout = uploadFileContents(outErr.getOutputPath());
result.setStdoutDigest(stdout);
}
- blobStore.put(actionKey.getDigest().getHash(), result.build().toByteArray());
+ blobStore.put(
+ actionKey.getDigest().getHash(), new ByteArrayInputStream(result.build().toByteArray()));
}
public void upload(ActionResult.Builder result, Path execRoot, Collection<Path> files)
@@ -203,8 +203,11 @@ public final class SimpleBlobStoreActionCache implements RemoteActionCache {
private void downloadFileContents(Digest digest, Path dest, boolean executable)
throws IOException, CacheNotFoundException, InterruptedException {
- // This unconditionally downloads the whole file into memory first!
- createFile(downloadBlob(digest), dest, executable);
+ FileSystemUtils.createDirectoryAndParents(dest.getParentDirectory());
+ try (OutputStream out = dest.getOutputStream()) {
+ downloadBlob(digest, out);
+ }
+ dest.setExecutable(executable);
}
private void createFile(byte[] contents, Path dest, boolean executable) throws IOException {
@@ -232,13 +235,29 @@ public final class SimpleBlobStoreActionCache implements RemoteActionCache {
checkBlobSize(blobSizeKBytes, "Upload");
uploadMemoryAvailable.acquire(blobSizeKBytes);
try {
- blobStore.put(digest.getHash(), blob);
+ return uploadBlob(digest, new ByteArrayInputStream(blob));
} finally {
uploadMemoryAvailable.release(blobSizeKBytes);
}
+ }
+
+ private Digest uploadBlob(Digest digest, InputStream in)
+ throws IOException, InterruptedException {
+ blobStore.put(digest.getHash(), in);
return digest;
}
+ public void downloadBlob(Digest digest, OutputStream out)
+ throws IOException, CacheNotFoundException, InterruptedException {
+ if (digest.getSizeBytes() == 0) {
+ return;
+ }
+ boolean success = blobStore.get(digest.getHash(), out);
+ if (!success) {
+ throw new CacheNotFoundException(digest);
+ }
+ }
+
public byte[] downloadBlob(Digest digest)
throws IOException, CacheNotFoundException, InterruptedException {
if (digest.getSizeBytes() == 0) {
@@ -246,11 +265,9 @@ public final class SimpleBlobStoreActionCache implements RemoteActionCache {
}
// This unconditionally downloads the whole blob into memory!
checkBlobSize(digest.getSizeBytes() / 1024, "Download");
- byte[] data = blobStore.get(digest.getHash());
- if (data == null) {
- throw new CacheNotFoundException(digest);
- }
- return data;
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ downloadBlob(digest, out);
+ return out.toByteArray();
}
public boolean containsKey(Digest digest) throws IOException, InterruptedException {
@@ -260,20 +277,19 @@ public final class SimpleBlobStoreActionCache implements RemoteActionCache {
@Override
public ActionResult getCachedActionResult(ActionKey actionKey)
throws IOException, InterruptedException {
- byte[] data = blobStore.get(actionKey.getDigest().getHash());
- if (data == null) {
- return null;
- }
try {
+ byte[] data = downloadBlob(actionKey.getDigest());
return ActionResult.parseFrom(data);
} catch (InvalidProtocolBufferException e) {
return null;
+ } catch (CacheNotFoundException e) {
+ return null;
}
}
public void setCachedActionResult(ActionKey actionKey, ActionResult result)
throws IOException, InterruptedException {
- blobStore.put(actionKey.getDigest().getHash(), result.toByteArray());
+ blobStore.put(actionKey.getDigest().getHash(), new ByteArrayInputStream(result.toByteArray()));
}
@Override