Skip to content

Commit ae85ff2

Browse files
committed
[PERF] BytesBackedLiteral: Size is known upon copy
Specifying the size enable a clean copy directly in the resulting byte array, avoiding an extra copy to an intermediate byte array. Also avoids sizing issue of the byte array that yields extra copies and. Also prevent allocation of the copy buffer that might have a non negligible impact for small payloads . BytesBackedLiteral::copy was responsible of 0.65% of total memory allocation. Care needs to be taken to fully read the stream and trigger the EOL check.
1 parent e17f30a commit ae85ff2

File tree

3 files changed

+14
-4
lines changed

3 files changed

+14
-4
lines changed

protocols/imap/src/main/java/org/apache/james/imap/decode/ImapRequestStreamLineReader.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ public Literal read(int size, boolean extraCRLF) throws IOException {
8383
InputStream limited = ByteStreams.limit(input, size);
8484

8585
if (extraCRLF) {
86-
return BytesBackedLiteral.copy(new EolInputStream(this, limited));
86+
return BytesBackedLiteral.copy(new EolInputStream(this, limited), size);
8787
} else {
88-
return BytesBackedLiteral.copy(limited);
88+
return BytesBackedLiteral.copy(limited, size);
8989
}
9090
}
9191

protocols/imap/src/main/java/org/apache/james/imap/message/BytesBackedLiteral.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,23 @@
2424
import java.io.IOException;
2525
import java.io.InputStream;
2626

27+
import org.apache.commons.io.IOUtils;
28+
2729
public class BytesBackedLiteral implements Literal {
2830
public static BytesBackedLiteral copy(InputStream stream) throws IOException {
2931
ByteArrayOutputStream out = new ByteArrayOutputStream();
3032
stream.transferTo(out);
3133
return of(out.toByteArray());
3234
}
3335

36+
public static BytesBackedLiteral copy(InputStream stream, int size) throws IOException {
37+
byte[] buffer = IOUtils.toByteArray(stream, size);
38+
if (stream.read() != -1) {
39+
throw new IOException("Got a stream of the wrong size...");
40+
}
41+
return of(buffer);
42+
}
43+
3444
public static BytesBackedLiteral of(byte[] bytes) {
3545
return new BytesBackedLiteral(bytes);
3646
}

server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapRequestLineReader.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,9 @@ public Literal read(int size, boolean extraCRLF) throws DecodingException {
106106
// limit the size via commons-io as ByteBufInputStream size limiting is buggy
107107
InputStream in = new BoundedInputStream(new ByteBufInputStream(buffer), size);
108108
if (extraCRLF) {
109-
return BytesBackedLiteral.copy(new EolInputStream(this, in));
109+
return BytesBackedLiteral.copy(new EolInputStream(this, in), size);
110110
} else {
111-
return BytesBackedLiteral.copy(in);
111+
return BytesBackedLiteral.copy(in, size);
112112
}
113113
} catch (IOException e) {
114114
throw new DecodingException(HumanReadableText.SOCKET_IO_FAILURE, "Can not read literal", e);

0 commit comments

Comments
 (0)