Skip to content

Commit

Permalink
Optimize HttpContentEncoder to do less memory copies as those are not…
Browse files Browse the repository at this point in the history
… needed
  • Loading branch information
Norman Maurer committed Jul 5, 2013
1 parent d900f8c commit 9f0f653
Showing 1 changed file with 10 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufHolder;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.channel.embedded.EmbeddedChannel;
Expand Down Expand Up @@ -163,9 +162,8 @@ protected void encode(ChannelHandlerContext ctx, HttpObject msg, MessageList<Obj
}
case AWAIT_CONTENT: {
ensureContent(msg);
HttpContent[] encoded = encodeContent((HttpContent) msg);
out.add(encoded);
if (encoded[encoded.length - 1] instanceof LastHttpContent) {
encodeContent((HttpContent) msg, out);
if (msg instanceof LastHttpContent) {
state = State.AWAIT_HEADERS;
}
break;
Expand Down Expand Up @@ -198,31 +196,18 @@ private static void ensureContent(HttpObject msg) {
}
}

private HttpContent[] encodeContent(HttpContent c) {
ByteBuf newContent = Unpooled.buffer();
private void encodeContent(HttpContent c, MessageList<Object> out) {
ByteBuf content = c.content();

encode(content, newContent);
encode(content, out);

if (c instanceof LastHttpContent) {
ByteBuf lastProduct = Unpooled.buffer();
finishEncode(lastProduct);
finishEncode(out);

// Generate an additional chunk if the decoder produced
// the last product on closure,
if (lastProduct.isReadable()) {
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) };
}
out.add(LastHttpContent.EMPTY_LAST_CONTENT);
}

return new HttpContent[] { new DefaultHttpContent(newContent) };
}

/**
Expand Down Expand Up @@ -271,30 +256,26 @@ private void cleanup() {
}
}

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
encoder.writeOutbound(in.retain());
fetchEncoderOutput(out);
}

private void finishEncode(ByteBuf out) {
private void finishEncode(MessageList<Object> out) {
if (encoder.finish()) {
fetchEncoderOutput(out);
}
encoder = null;
}

private void fetchEncoderOutput(ByteBuf out) {
private void fetchEncoderOutput(MessageList<Object> out) {
for (;;) {
ByteBuf buf = (ByteBuf) encoder.readOutbound();
if (buf == null) {
break;
}
out.writeBytes(buf);

// Need to release the buffer after write it
// See https://github.com/netty/netty/issues/1524
buf.release();
out.add(new DefaultHttpContent(buf));
}
}

Expand Down

0 comments on commit 9f0f653

Please sign in to comment.