JCLOUDS-1367: Do not open open InputStream in copyBlob

This avoids an unneeded call to ByteStreams2.toByteArrayAndClose in
getBlob for range requests and elides a large memory allocation.
This commit is contained in:
Andrew Gaul 2020-07-25 16:34:46 +09:00 committed by Andrew Gaul
parent 8de7b696e1
commit 9c21bf2cc2
1 changed files with 21 additions and 22 deletions

View File

@ -685,6 +685,7 @@ public final class LocalBlobStore implements BlobStore {
try { try {
byteSource = (ByteSource) blob.getPayload().getRawContent(); byteSource = (ByteSource) blob.getPayload().getRawContent();
} catch (ClassCastException cce) { } catch (ClassCastException cce) {
// This should not happen; both FilesystemStorageStrategyImpl and TransientStorageStrategy return ByteSource
try { try {
byteSource = ByteSource.wrap(ByteStreams2.toByteArrayAndClose(blob.getPayload().openStream())); byteSource = ByteSource.wrap(ByteStreams2.toByteArrayAndClose(blob.getPayload().openStream()));
} catch (IOException e) { } catch (IOException e) {
@ -724,18 +725,31 @@ public final class LocalBlobStore implements BlobStore {
"bytes " + offset + "-" + last + "/" + blob.getPayload().getContentMetadata().getContentLength()); "bytes " + offset + "-" + last + "/" + blob.getPayload().getContentMetadata().getContentLength());
} }
ContentMetadata cmd = blob.getPayload().getContentMetadata(); ContentMetadata cmd = blob.getPayload().getContentMetadata();
// return InputStream to more closely follow real blobstore blob.setPayload(ByteSource.concat(streams.build()));
try {
blob.setPayload(ByteSource.concat(streams.build()).openStream());
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
HttpUtils.copy(cmd, blob.getPayload().getContentMetadata()); HttpUtils.copy(cmd, blob.getPayload().getContentMetadata());
blob.getPayload().getContentMetadata().setContentLength(size); blob.getPayload().getContentMetadata().setContentLength(size);
blob.getMetadata().setSize(size); blob.getMetadata().setSize(size);
} }
} }
checkNotNull(blob.getPayload(), "payload " + blob); checkNotNull(blob.getPayload(), "payload " + blob);
// return InputStream to more closely follow real blobstore
Payload payload;
try {
InputStream is = blob.getPayload().openStream();
if (is instanceof FileInputStream) {
// except for FileInputStream since large MPU can open too many fds
is.close();
payload = blob.getPayload();
} else {
blob.resetPayload(/*release=*/ false);
payload = new InputStreamPayload(is);
}
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
payload.setContentMetadata(blob.getMetadata().getContentMetadata());
blob.setPayload(payload);
copyPayloadHeadersToBlob(blob.getPayload(), blob);
return blob; return blob;
} }
@ -753,22 +767,7 @@ public final class LocalBlobStore implements BlobStore {
private Blob copyBlob(Blob blob) { private Blob copyBlob(Blob blob) {
Blob returnVal = blobFactory.create(BlobStoreUtils.copy(blob.getMetadata())); Blob returnVal = blobFactory.create(BlobStoreUtils.copy(blob.getMetadata()));
// return InputStream to more closely follow real blobstore returnVal.setPayload(blob.getPayload());
Payload payload;
try {
InputStream is = blob.getPayload().openStream();
if (is instanceof FileInputStream) {
// except for FileInputStream since large MPU can open too many fds
is.close();
payload = blob.getPayload();
} else {
payload = new InputStreamPayload(blob.getPayload().openStream());
}
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
payload.setContentMetadata(blob.getMetadata().getContentMetadata());
returnVal.setPayload(payload);
copyPayloadHeadersToBlob(blob.getPayload(), returnVal); copyPayloadHeadersToBlob(blob.getPayload(), returnVal);
return returnVal; return returnVal;
} }