From da5c6add14d1d6ad5c33254d65439b6e3f91a849 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Wed, 10 Jul 2013 07:50:26 +0200 Subject: [PATCH] Rename CodecOutput to RecyclableArrayList and move it to internal package. * Also reuse it in SslHandler --- .../handler/codec/ByteToMessageDecoder.java | 9 ++++--- .../handler/codec/MessageToByteEncoder.java | 4 +-- .../codec/MessageToMessageDecoder.java | 9 ++++--- .../codec/MessageToMessageEncoder.java | 9 ++++--- .../netty/handler/codec/ReplayingDecoder.java | 5 ++-- .../util/internal/RecyclableArrayList.java | 26 +++++++++---------- .../java/io/netty/handler/ssl/SslHandler.java | 15 ++++++----- 7 files changed, 42 insertions(+), 35 deletions(-) rename codec/src/main/java/io/netty/handler/codec/CodecOutput.java => common/src/main/java/io/netty/util/internal/RecyclableArrayList.java (64%) diff --git a/codec/src/main/java/io/netty/handler/codec/ByteToMessageDecoder.java b/codec/src/main/java/io/netty/handler/codec/ByteToMessageDecoder.java index 7756e03334..20854b8586 100644 --- a/codec/src/main/java/io/netty/handler/codec/ByteToMessageDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/ByteToMessageDecoder.java @@ -19,6 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.util.internal.RecyclableArrayList; import io.netty.util.internal.StringUtil; import java.util.List; @@ -120,7 +121,7 @@ public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - CodecOutput out = CodecOutput.newInstance(); + RecyclableArrayList out = RecyclableArrayList.newInstance(); try { if (msg instanceof ByteBuf) { ByteBuf data = (ByteBuf) msg; @@ -189,7 +190,7 @@ public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { - CodecOutput out = CodecOutput.newInstance(); + RecyclableArrayList out = RecyclableArrayList.newInstance(); try { if (cumulation != null) { callDecode(ctx, cumulation, out); @@ -214,7 +215,7 @@ public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter } } - protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, CodecOutput out) { + protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, RecyclableArrayList out) { try { while (in.isReadable()) { int outSize = out.size(); @@ -252,7 +253,7 @@ public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter * * @param ctx the {@link ChannelHandlerContext} which this {@link ByteToMessageDecoder} belongs to * @param in the {@link ByteBuf} from which to read data - * @param out the {@link CodecOutput} to which decoded messages should be added + * @param out the {@link List} to which decoded messages should be added * @throws Exception is thrown if an error accour */ diff --git a/codec/src/main/java/io/netty/handler/codec/MessageToByteEncoder.java b/codec/src/main/java/io/netty/handler/codec/MessageToByteEncoder.java index be3522d906..ff0aec5d8f 100644 --- a/codec/src/main/java/io/netty/handler/codec/MessageToByteEncoder.java +++ b/codec/src/main/java/io/netty/handler/codec/MessageToByteEncoder.java @@ -105,8 +105,8 @@ public abstract class MessageToByteEncoder extends ChannelOutboundHandlerAdap } /** - * Encode a message into a {@link ByteBuf}. This method will be called till the {@link CodecOutput} has - * nothing left. + * Encode a message into a {@link ByteBuf}. This method will be called for each written message that can be handled + * by this encoder. * * @param ctx the {@link ChannelHandlerContext} which this {@link MessageToByteEncoder} belongs to * @param msg the message to encode diff --git a/codec/src/main/java/io/netty/handler/codec/MessageToMessageDecoder.java b/codec/src/main/java/io/netty/handler/codec/MessageToMessageDecoder.java index b5953581d2..be1c41e5b4 100644 --- a/codec/src/main/java/io/netty/handler/codec/MessageToMessageDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/MessageToMessageDecoder.java @@ -19,6 +19,7 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.util.ReferenceCountUtil; import io.netty.util.ReferenceCounted; +import io.netty.util.internal.RecyclableArrayList; import io.netty.util.internal.TypeParameterMatcher; import java.util.List; @@ -65,7 +66,7 @@ public abstract class MessageToMessageDecoder extends ChannelInboundHandlerAd @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - CodecOutput out = CodecOutput.newInstance(); + RecyclableArrayList out = RecyclableArrayList.newInstance(); try { if (acceptInboundMessage(msg)) { @SuppressWarnings("unchecked") @@ -91,12 +92,12 @@ public abstract class MessageToMessageDecoder extends ChannelInboundHandlerAd } /** - * Decode from one message to an other. This method will be called till either the {@link CodecOutput} has - * nothing left or till this method returns {@code null}. + * Decode from one message to an other. This method will be called for each written message that can be handled + * by this encoder. * * @param ctx the {@link ChannelHandlerContext} which this {@link MessageToMessageDecoder} belongs to * @param msg the message to decode to an other one - * @param out the {@link CodecOutput} to which decoded messages should be added + * @param out the {@link List} to which decoded messages should be added * @throws Exception is thrown if an error accour */ protected abstract void decode(ChannelHandlerContext ctx, I msg, List out) throws Exception; diff --git a/codec/src/main/java/io/netty/handler/codec/MessageToMessageEncoder.java b/codec/src/main/java/io/netty/handler/codec/MessageToMessageEncoder.java index 806fe8844b..94eb3d0066 100644 --- a/codec/src/main/java/io/netty/handler/codec/MessageToMessageEncoder.java +++ b/codec/src/main/java/io/netty/handler/codec/MessageToMessageEncoder.java @@ -19,6 +19,7 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.util.ReferenceCountUtil; import io.netty.util.ReferenceCounted; +import io.netty.util.internal.RecyclableArrayList; import io.netty.util.internal.TypeParameterMatcher; import java.util.List; @@ -62,7 +63,7 @@ public abstract class MessageToMessageEncoder extends ChannelOutboundHandlerA @Override public void write(ChannelHandlerContext ctx, Object msg) throws Exception { - CodecOutput out = CodecOutput.newInstance(); + RecyclableArrayList out = RecyclableArrayList.newInstance(); try { if (acceptOutboundMessage(msg)) { @SuppressWarnings("unchecked") @@ -88,12 +89,12 @@ public abstract class MessageToMessageEncoder extends ChannelOutboundHandlerA } /** - * Encode from one message to an other. This method will be called till either the {@link CodecOutput} has nothing - * left or till this method returns {@code null}. + * Encode from one message to an other. This method will be called for each written message that can be handled + * by this encoder. * * @param ctx the {@link ChannelHandlerContext} which this {@link MessageToMessageEncoder} belongs to * @param msg the message to encode to an other one - * @param out the {@link CodecOutput} into which the encoded msg should be added + * @param out the {@link List} into which the encoded msg should be added * needs to do some kind of aggragation * @throws Exception is thrown if an error accour */ diff --git a/codec/src/main/java/io/netty/handler/codec/ReplayingDecoder.java b/codec/src/main/java/io/netty/handler/codec/ReplayingDecoder.java index 3d92d695ff..4220d346bc 100644 --- a/codec/src/main/java/io/netty/handler/codec/ReplayingDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/ReplayingDecoder.java @@ -20,6 +20,7 @@ import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPipeline; import io.netty.util.Signal; +import io.netty.util.internal.RecyclableArrayList; import io.netty.util.internal.StringUtil; /** @@ -319,7 +320,7 @@ public abstract class ReplayingDecoder extends ByteToMessageDecoder { @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { - CodecOutput out = CodecOutput.newInstance(); + RecyclableArrayList out = RecyclableArrayList.newInstance(); try { replayable.terminate(); callDecode(ctx, internalBuffer(), out); @@ -345,7 +346,7 @@ public abstract class ReplayingDecoder extends ByteToMessageDecoder { } @Override - protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, CodecOutput out) { + protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, RecyclableArrayList out) { replayable.setCumulation(in); try { while (in.isReadable()) { diff --git a/codec/src/main/java/io/netty/handler/codec/CodecOutput.java b/common/src/main/java/io/netty/util/internal/RecyclableArrayList.java similarity index 64% rename from codec/src/main/java/io/netty/handler/codec/CodecOutput.java rename to common/src/main/java/io/netty/util/internal/RecyclableArrayList.java index 7f41ce393a..20841c22e8 100644 --- a/codec/src/main/java/io/netty/handler/codec/CodecOutput.java +++ b/common/src/main/java/io/netty/util/internal/RecyclableArrayList.java @@ -14,7 +14,7 @@ * under the License. */ -package io.netty.handler.codec; +package io.netty.util.internal; import io.netty.util.Recycler; import io.netty.util.Recycler.Handle; @@ -24,42 +24,42 @@ import java.util.ArrayList; /** * A simple list that holds the output of a codec. */ -final class CodecOutput extends ArrayList { +public final class RecyclableArrayList extends ArrayList { private static final long serialVersionUID = -8605125654176467947L; private static final int DEFAULT_INITIAL_CAPACITY = 8; - private static final Recycler RECYCLER = new Recycler() { + private static final Recycler RECYCLER = new Recycler() { @Override - protected CodecOutput newObject(Handle handle) { - return new CodecOutput(handle); + protected RecyclableArrayList newObject(Handle handle) { + return new RecyclableArrayList(handle); } }; /** - * Create a new empty {@link CodecOutput} instance + * Create a new empty {@link RecyclableArrayList} instance */ - public static CodecOutput newInstance() { + public static RecyclableArrayList newInstance() { return newInstance(DEFAULT_INITIAL_CAPACITY); } /** - * Create a new empty {@link CodecOutput} instance with the given capacity. + * Create a new empty {@link RecyclableArrayList} instance with the given capacity. */ - public static CodecOutput newInstance(int minCapacity) { - CodecOutput ret = (CodecOutput) RECYCLER.get(); + public static RecyclableArrayList newInstance(int minCapacity) { + RecyclableArrayList ret = RECYCLER.get(); ret.ensureCapacity(minCapacity); return ret; } private final Handle handle; - CodecOutput(Handle handle) { + private RecyclableArrayList(Handle handle) { this(handle, DEFAULT_INITIAL_CAPACITY); } - CodecOutput(Handle handle, int initialCapacity) { + private RecyclableArrayList(Handle handle, int initialCapacity) { super(initialCapacity); this.handle = handle; } @@ -67,7 +67,7 @@ final class CodecOutput extends ArrayList { /** * Clear and recycle this instance. */ - boolean recycle() { + public boolean recycle() { clear(); return RECYCLER.recycle(this, handle); } diff --git a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java index a98e456b6b..2abd7c4a79 100644 --- a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java +++ b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java @@ -36,6 +36,7 @@ import io.netty.util.concurrent.GenericFutureListener; import io.netty.util.concurrent.ImmediateExecutor; import io.netty.util.internal.EmptyArrays; import io.netty.util.internal.PlatformDependent; +import io.netty.util.internal.RecyclableArrayList; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; @@ -50,7 +51,6 @@ import java.nio.channels.ClosedChannelException; import java.nio.channels.DatagramChannel; import java.nio.channels.SocketChannel; import java.util.ArrayDeque; -import java.util.ArrayList; import java.util.Deque; import java.util.List; import java.util.concurrent.Executor; @@ -536,11 +536,14 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH } private void unwrapLater(ChannelHandlerContext ctx) throws SSLException { - // TODO: Optimize this for less Garbage - List messageList = new ArrayList(); - decode(ctx, internalBuffer(), messageList); - for (int i = 0; i < messageList.size(); i++) { - ctx.fireChannelRead(messageList.get(i)); + RecyclableArrayList out = RecyclableArrayList.newInstance(); + try { + decode(ctx, internalBuffer(), out); + for (int i = 0; i < out.size(); i++) { + ctx.fireChannelRead(out.get(i)); + } + } finally { + out.recycle(); } }