Rename CodecOutput to RecyclableArrayList and move it to internal package.

* Also reuse it in SslHandler
This commit is contained in:
Norman Maurer 2013-07-10 07:50:26 +02:00
parent 768152cf88
commit da5c6add14
7 changed files with 42 additions and 35 deletions

View File

@ -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
*/

View File

@ -105,8 +105,8 @@ public abstract class MessageToByteEncoder<I> 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

View File

@ -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<I> 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<I> 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<Object> out) throws Exception;

View File

@ -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<I> 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<I> 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
*/

View File

@ -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<S> 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<S> 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()) {

View File

@ -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<Object> {
public final class RecyclableArrayList extends ArrayList<Object> {
private static final long serialVersionUID = -8605125654176467947L;
private static final int DEFAULT_INITIAL_CAPACITY = 8;
private static final Recycler<CodecOutput> RECYCLER = new Recycler<CodecOutput>() {
private static final Recycler<RecyclableArrayList> RECYCLER = new Recycler<RecyclableArrayList>() {
@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<Object> {
/**
* Clear and recycle this instance.
*/
boolean recycle() {
public boolean recycle() {
clear();
return RECYCLER.recycle(this, handle);
}

View File

@ -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<Object> messageList = new ArrayList<Object>();
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();
}
}