Optimize HttpContentEncoder to do less memory copies as those are not needed
This commit is contained in:
parent
d900f8c21d
commit
9f0f653588
@ -17,7 +17,6 @@ package io.netty.handler.codec.http;
|
|||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufHolder;
|
import io.netty.buffer.ByteBufHolder;
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.MessageList;
|
import io.netty.channel.MessageList;
|
||||||
import io.netty.channel.embedded.EmbeddedChannel;
|
import io.netty.channel.embedded.EmbeddedChannel;
|
||||||
@ -163,9 +162,8 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec<HttpReque
|
|||||||
}
|
}
|
||||||
case AWAIT_CONTENT: {
|
case AWAIT_CONTENT: {
|
||||||
ensureContent(msg);
|
ensureContent(msg);
|
||||||
HttpContent[] encoded = encodeContent((HttpContent) msg);
|
encodeContent((HttpContent) msg, out);
|
||||||
out.add(encoded);
|
if (msg instanceof LastHttpContent) {
|
||||||
if (encoded[encoded.length - 1] instanceof LastHttpContent) {
|
|
||||||
state = State.AWAIT_HEADERS;
|
state = State.AWAIT_HEADERS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -198,31 +196,18 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec<HttpReque
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpContent[] encodeContent(HttpContent c) {
|
private void encodeContent(HttpContent c, MessageList<Object> out) {
|
||||||
ByteBuf newContent = Unpooled.buffer();
|
|
||||||
ByteBuf content = c.content();
|
ByteBuf content = c.content();
|
||||||
|
|
||||||
encode(content, newContent);
|
encode(content, out);
|
||||||
|
|
||||||
if (c instanceof LastHttpContent) {
|
if (c instanceof LastHttpContent) {
|
||||||
ByteBuf lastProduct = Unpooled.buffer();
|
finishEncode(out);
|
||||||
finishEncode(lastProduct);
|
|
||||||
|
|
||||||
// Generate an additional chunk if the decoder produced
|
// Generate an additional chunk if the decoder produced
|
||||||
// the last product on closure,
|
// the last product on closure,
|
||||||
if (lastProduct.isReadable()) {
|
out.add(LastHttpContent.EMPTY_LAST_CONTENT);
|
||||||
if (newContent.isReadable()) {
|
|
||||||
return new HttpContent[] {
|
|
||||||
new DefaultHttpContent(newContent), new DefaultLastHttpContent(lastProduct)};
|
|
||||||
} else {
|
|
||||||
return new HttpContent[] { new DefaultLastHttpContent(lastProduct) };
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return new HttpContent[] { new DefaultLastHttpContent(newContent) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new HttpContent[] { new DefaultHttpContent(newContent) };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -271,30 +256,26 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec<HttpReque
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encode(ByteBuf in, ByteBuf out) {
|
private void encode(ByteBuf in, MessageList<Object> out) {
|
||||||
// call retain here as it will call release after its written to the channel
|
// call retain here as it will call release after its written to the channel
|
||||||
encoder.writeOutbound(in.retain());
|
encoder.writeOutbound(in.retain());
|
||||||
fetchEncoderOutput(out);
|
fetchEncoderOutput(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void finishEncode(ByteBuf out) {
|
private void finishEncode(MessageList<Object> out) {
|
||||||
if (encoder.finish()) {
|
if (encoder.finish()) {
|
||||||
fetchEncoderOutput(out);
|
fetchEncoderOutput(out);
|
||||||
}
|
}
|
||||||
encoder = null;
|
encoder = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchEncoderOutput(ByteBuf out) {
|
private void fetchEncoderOutput(MessageList<Object> out) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ByteBuf buf = (ByteBuf) encoder.readOutbound();
|
ByteBuf buf = (ByteBuf) encoder.readOutbound();
|
||||||
if (buf == null) {
|
if (buf == null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
out.writeBytes(buf);
|
out.add(new DefaultHttpContent(buf));
|
||||||
|
|
||||||
// Need to release the buffer after write it
|
|
||||||
// See https://github.com/netty/netty/issues/1524
|
|
||||||
buf.release();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user