Skip to content

Commit

Permalink
Avoid excessive buffering when writing to a memory store.
Browse files Browse the repository at this point in the history
  • Loading branch information
christian-schlichtherle committed Dec 2, 2020
1 parent 99c16f2 commit b438b4d
Showing 1 changed file with 17 additions and 6 deletions.
23 changes: 17 additions & 6 deletions bios/src/main/java/global/namespace/fun/io/bios/MemoryStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,28 @@ final class MemoryStore implements Store {
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
private Optional<byte[]> optContent = Optional.empty();

private int length; // only valid if optContent.isPresent() == true

MemoryStore(final int bufferSize) {
if (0 > (this.bufferSize = bufferSize)) {
throw new IllegalArgumentException(bufferSize + " is a negative buffer size.");
}
}

@Override
public Socket<InputStream> input() { return () -> new ByteArrayInputStream(checkedContent()); }
public Socket<InputStream> input() {
return () -> new ByteArrayInputStream(checkedContent(), 0, length);
}

@Override
public Socket<OutputStream> output() {
return () -> new ByteArrayOutputStream(bufferSize) {

@Override
public void close() { optContent = Optional.of(copyOf(buf, count)); }
public void close() {
optContent = Optional.of(buf);
length = count;
}
};
}

Expand All @@ -59,11 +67,13 @@ public void delete() throws IOException {

@Override
public OptionalLong size() throws IOException {
return optContent.map(bytes -> OptionalLong.of(bytes.length)).orElseGet(OptionalLong::empty);
return optContent.isPresent() ? OptionalLong.of(length) : OptionalLong.empty();
}

@Override
public boolean exists() { return optContent.isPresent(); }
public boolean exists() {
return optContent.isPresent();
}

private byte[] checkedContent() throws NoContentException {
return optContent.orElseThrow(NoContentException::new);
Expand All @@ -77,9 +87,9 @@ public byte[] content(final int max) throws IOException {
final Optional<byte[]> optContent = this.optContent;
if (optContent.isPresent()) {
final byte[] content = optContent.get();
final int length = content.length;
final int length = this.length;
if (length <= max) {
return content.clone();
return copyOf(content, length);
} else {
throw new ContentTooLargeException(length, max);
}
Expand All @@ -91,5 +101,6 @@ public byte[] content(final int max) throws IOException {
@Override
public void content(byte[] b, int off, int len) {
optContent = Optional.of(copyOfRange(b, off, off + len));
length = len;
}
}

0 comments on commit b438b4d

Please sign in to comment.