HttpObjectDecoder configurable initial buffer size

Motivation:
The initial buffer size used to decode HTTP objects is currently fixed at 128. This may be too small for some use cases and create a high amount of overhead associated with resizing/copying. The user should be able to configure the initial size as they please.

Modifications:
- Make HttpObjectDecoder's AppendableCharSequence initial size configurable

Result:
Users can more finely tune initial buffer size for increased performance or to save memory.
Fixes https://github.com/netty/netty/issues/4807
This commit is contained in:
Scott Mitchell 2016-02-05 14:33:57 -08:00
parent 2b3b36b818
commit 1bd4b702be
5 changed files with 46 additions and 3 deletions

View File

@ -94,6 +94,17 @@ public final class HttpClientCodec
this.failOnMissingResponse = failOnMissingResponse; this.failOnMissingResponse = failOnMissingResponse;
} }
/**
* Creates a new instance with the specified decoder options.
*/
public HttpClientCodec(
int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, boolean failOnMissingResponse,
boolean validateHeaders, int initialBufferSize) {
init(new Decoder(maxInitialLineLength, maxHeaderSize, maxChunkSize, validateHeaders, initialBufferSize),
new Encoder());
this.failOnMissingResponse = failOnMissingResponse;
}
private final class Encoder extends HttpRequestEncoder { private final class Encoder extends HttpRequestEncoder {
@Override @Override
@ -120,6 +131,11 @@ public final class HttpClientCodec
super(maxInitialLineLength, maxHeaderSize, maxChunkSize, validateHeaders); super(maxInitialLineLength, maxHeaderSize, maxChunkSize, validateHeaders);
} }
Decoder(int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, boolean validateHeaders,
int initialBufferSize) {
super(maxInitialLineLength, maxHeaderSize, maxChunkSize, validateHeaders, initialBufferSize);
}
@Override @Override
protected void decode( protected void decode(
ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception { ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {

View File

@ -162,7 +162,12 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
protected HttpObjectDecoder( protected HttpObjectDecoder(
int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, int maxInitialLineLength, int maxHeaderSize, int maxChunkSize,
boolean chunkedSupported, boolean validateHeaders) { boolean chunkedSupported, boolean validateHeaders) {
this(maxInitialLineLength, maxHeaderSize, maxChunkSize, chunkedSupported, validateHeaders, 128);
}
protected HttpObjectDecoder(
int maxInitialLineLength, int maxHeaderSize, int maxChunkSize,
boolean chunkedSupported, boolean validateHeaders, int initialBufferSize) {
if (maxInitialLineLength <= 0) { if (maxInitialLineLength <= 0) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"maxInitialLineLength must be a positive integer: " + "maxInitialLineLength must be a positive integer: " +
@ -178,12 +183,12 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
"maxChunkSize must be a positive integer: " + "maxChunkSize must be a positive integer: " +
maxChunkSize); maxChunkSize);
} }
AppendableCharSequence seq = new AppendableCharSequence(initialBufferSize);
lineParser = new LineParser(seq, maxInitialLineLength);
headerParser = new HeaderParser(seq, maxHeaderSize);
this.maxChunkSize = maxChunkSize; this.maxChunkSize = maxChunkSize;
this.chunkedSupported = chunkedSupported; this.chunkedSupported = chunkedSupported;
this.validateHeaders = validateHeaders; this.validateHeaders = validateHeaders;
AppendableCharSequence seq = new AppendableCharSequence(128);
lineParser = new LineParser(seq, maxInitialLineLength);
headerParser = new HeaderParser(seq, maxHeaderSize);
} }
@Override @Override

View File

@ -76,6 +76,12 @@ public class HttpRequestDecoder extends HttpObjectDecoder {
super(maxInitialLineLength, maxHeaderSize, maxChunkSize, true, validateHeaders); super(maxInitialLineLength, maxHeaderSize, maxChunkSize, true, validateHeaders);
} }
public HttpRequestDecoder(
int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, boolean validateHeaders,
int initialBufferSize) {
super(maxInitialLineLength, maxHeaderSize, maxChunkSize, true, validateHeaders, initialBufferSize);
}
@Override @Override
protected HttpMessage createMessage(String[] initialLine) throws Exception { protected HttpMessage createMessage(String[] initialLine) throws Exception {
return new DefaultHttpRequest( return new DefaultHttpRequest(

View File

@ -107,6 +107,12 @@ public class HttpResponseDecoder extends HttpObjectDecoder {
super(maxInitialLineLength, maxHeaderSize, maxChunkSize, true, validateHeaders); super(maxInitialLineLength, maxHeaderSize, maxChunkSize, true, validateHeaders);
} }
public HttpResponseDecoder(
int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, boolean validateHeaders,
int initialBufferSize) {
super(maxInitialLineLength, maxHeaderSize, maxChunkSize, true, validateHeaders, initialBufferSize);
}
@Override @Override
protected HttpMessage createMessage(String[] initialLine) { protected HttpMessage createMessage(String[] initialLine) {
return new DefaultHttpResponse( return new DefaultHttpResponse(

View File

@ -50,4 +50,14 @@ public final class HttpServerCodec
super(new HttpRequestDecoder(maxInitialLineLength, maxHeaderSize, maxChunkSize, validateHeaders), super(new HttpRequestDecoder(maxInitialLineLength, maxHeaderSize, maxChunkSize, validateHeaders),
new HttpResponseEncoder()); new HttpResponseEncoder());
} }
/**
* Creates a new instance with the specified decoder options.
*/
public HttpServerCodec(int maxInitialLineLength, int maxHeaderSize, int maxChunkSize, boolean validateHeaders,
int initialBufferSize) {
super(
new HttpRequestDecoder(maxInitialLineLength, maxHeaderSize, maxChunkSize, validateHeaders, initialBufferSize),
new HttpResponseEncoder());
}
} }