From 46540578fcf4bf3778d66dc450339d374cfaa4e7 Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Thu, 4 Apr 2013 14:32:48 +0900 Subject: [PATCH] Optimize OutputMessageBuf.drainToNextInbound/Outbound() - Return early when the buffer is empty - Keep only the number of byte buffers - Remove unnecessary null check in the loop (because we know buffer is not empty at certain point) --- .../netty/handler/codec/OutputMessageBuf.java | 155 +++++++++--------- 1 file changed, 73 insertions(+), 82 deletions(-) diff --git a/codec/src/main/java/io/netty/handler/codec/OutputMessageBuf.java b/codec/src/main/java/io/netty/handler/codec/OutputMessageBuf.java index fc9844eede..7254423d8e 100644 --- a/codec/src/main/java/io/netty/handler/codec/OutputMessageBuf.java +++ b/codec/src/main/java/io/netty/handler/codec/OutputMessageBuf.java @@ -22,8 +22,7 @@ import io.netty.buffer.MessageBuf; import io.netty.channel.ChannelHandlerContext; final class OutputMessageBuf extends DefaultMessageBuf { - private int byteBufs; - private int nonByteBufs; + private int byteBufCnt; private static final ThreadLocal output = new ThreadLocal() { @@ -53,9 +52,7 @@ final class OutputMessageBuf extends DefaultMessageBuf { boolean added = super.offer(e); if (added) { if (e instanceof ByteBuf) { - byteBufs++; - } else { - nonByteBufs++; + byteBufCnt ++; } } return added; @@ -64,12 +61,9 @@ final class OutputMessageBuf extends DefaultMessageBuf { @Override public boolean remove(Object o) { boolean removed = super.remove(o); - if (removed) { if (o instanceof ByteBuf) { - byteBufs--; - } else { - nonByteBufs--; + byteBufCnt --; } } return removed; @@ -82,9 +76,7 @@ final class OutputMessageBuf extends DefaultMessageBuf { return o; } if (o instanceof ByteBuf) { - byteBufs--; - } else { - nonByteBufs--; + byteBufCnt --; } return o; } @@ -92,85 +84,84 @@ final class OutputMessageBuf extends DefaultMessageBuf { @Override public void clear() { super.clear(); - byteBufs = 0; - nonByteBufs = 0; - } - - private boolean containsByteBuf() { - return byteBufs > 0; - } - - private boolean containsNonByteBuf() { - return nonByteBufs > 0; + byteBufCnt = 0; } public boolean drainToNextInbound(ChannelHandlerContext ctx) { - if (containsByteBuf() && ctx.nextInboundBufferType() == BufType.BYTE) { - ByteBuf buf = ctx.nextInboundByteBuffer(); - boolean drained = false; - if (!containsNonByteBuf()) { - for (;;) { - Object o = poll(); - if (o == null) { - break; - } - buf.writeBytes((ByteBuf) o); - drained = true; - } - } else { - // mixed case - MessageBuf msgBuf = ctx.nextInboundMessageBuffer(); - for (;;) { - Object o = poll(); - if (o == null) { - break; - } - if (o instanceof ByteBuf) { - buf.writeBytes((ByteBuf) o); - } else { - msgBuf.add(o); - } - drained = true; - } - } - return drained; - } else { + final int size = size(); + if (size == 0) { + return false; + } + + final int byteBufCnt = this.byteBufCnt; + if (byteBufCnt == 0 || ctx.nextInboundBufferType() != BufType.BYTE) { return drainTo(ctx.nextInboundMessageBuffer()) > 0; } + + final ByteBuf nextByteBuf = ctx.nextInboundByteBuffer(); + if (byteBufCnt == size) { + // Contains only ByteBufs + for (Object o = poll();;) { + nextByteBuf.writeBytes((ByteBuf) o); + if ((o = poll()) == null) { + break; + } + } + } else { + // Contains both ByteBufs and non-ByteBufs (0 < byteBufCnt < size()) + final MessageBuf nextMsgBuf = ctx.nextInboundMessageBuffer(); + for (Object o = poll();;) { + if (o instanceof ByteBuf) { + nextByteBuf.writeBytes((ByteBuf) o); + } else { + nextMsgBuf.add(o); + } + + if ((o = poll()) == null) { + break; + } + } + } + + return true; } public boolean drainToNextOutbound(ChannelHandlerContext ctx) { - if (containsByteBuf() && ctx.nextOutboundBufferType() == BufType.BYTE) { - ByteBuf buf = ctx.nextOutboundByteBuffer(); - boolean drained = false; - if (!containsNonByteBuf()) { - for (;;) { - Object o = poll(); - if (o == null) { - break; - } - buf.writeBytes((ByteBuf) o); - drained = true; - } - } else { - // mixed case - MessageBuf msgBuf = ctx.nextOutboundMessageBuffer(); - for (;;) { - Object o = poll(); - if (o == null) { - break; - } - if (o instanceof ByteBuf) { - buf.writeBytes((ByteBuf) o); - } else { - msgBuf.add(o); - } - drained = true; - } - } - return drained; - } else { + final int size = size(); + if (size == 0) { + return false; + } + + final int byteBufCnt = this.byteBufCnt; + if (byteBufCnt == 0 || ctx.nextOutboundBufferType() != BufType.BYTE) { return drainTo(ctx.nextOutboundMessageBuffer()) > 0; } + + final ByteBuf nextByteBuf = ctx.nextOutboundByteBuffer(); + if (byteBufCnt == size) { + // Contains only ByteBufs + for (Object o = poll();;) { + nextByteBuf.writeBytes((ByteBuf) o); + if ((o = poll()) == null) { + break; + } + } + } else { + // Contains both ByteBufs and non-ByteBufs (0 < byteBufCnt < size()) + final MessageBuf nextMsgBuf = ctx.nextOutboundMessageBuffer(); + for (Object o = poll();;) { + if (o instanceof ByteBuf) { + nextByteBuf.writeBytes((ByteBuf) o); + } else { + nextMsgBuf.add(o); + } + + if ((o = poll()) == null) { + break; + } + } + } + + return true; } }