Add Recycler.Handle.recycle() so that it's possible to recycle an object without an explicit reference to Recycler

This commit is contained in:
Trustin Lee 2013-12-18 23:05:37 +09:00
parent ca1c82642a
commit 04ec2e1330
8 changed files with 36 additions and 47 deletions

View File

@ -17,13 +17,14 @@
package io.netty.buffer; package io.netty.buffer;
import io.netty.util.Recycler; import io.netty.util.Recycler;
import io.netty.util.Recycler.Handle;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
abstract class PooledByteBuf<T> extends AbstractReferenceCountedByteBuf { abstract class PooledByteBuf<T> extends AbstractReferenceCountedByteBuf {
private final Recycler.Handle recyclerHandle; private final Recycler.Handle<PooledByteBuf<T>> recyclerHandle;
protected PoolChunk<T> chunk; protected PoolChunk<T> chunk;
protected long handle; protected long handle;
@ -34,9 +35,10 @@ abstract class PooledByteBuf<T> extends AbstractReferenceCountedByteBuf {
private ByteBuffer tmpNioBuf; private ByteBuffer tmpNioBuf;
protected PooledByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) { @SuppressWarnings("unchecked")
protected PooledByteBuf(Recycler.Handle<? extends PooledByteBuf<T>> recyclerHandle, int maxCapacity) {
super(maxCapacity); super(maxCapacity);
this.recyclerHandle = recyclerHandle; this.recyclerHandle = (Handle<PooledByteBuf<T>>) recyclerHandle;
} }
void init(PoolChunk<T> chunk, long handle, int offset, int length, int maxLength) { void init(PoolChunk<T> chunk, long handle, int offset, int length, int maxLength) {
@ -147,14 +149,9 @@ abstract class PooledByteBuf<T> extends AbstractReferenceCountedByteBuf {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void recycle() { private void recycle() {
Recycler.Handle recyclerHandle = this.recyclerHandle; recyclerHandle.recycle(this);
if (recyclerHandle != null) {
((Recycler<Object>) recycler()).recycle(this, recyclerHandle);
}
} }
protected abstract Recycler<?> recycler();
protected final int idx(int index) { protected final int idx(int index) {
return offset + index; return offset + index;
} }

View File

@ -30,7 +30,7 @@ final class PooledDirectByteBuf extends PooledByteBuf<ByteBuffer> {
private static final Recycler<PooledDirectByteBuf> RECYCLER = new Recycler<PooledDirectByteBuf>() { private static final Recycler<PooledDirectByteBuf> RECYCLER = new Recycler<PooledDirectByteBuf>() {
@Override @Override
protected PooledDirectByteBuf newObject(Handle handle) { protected PooledDirectByteBuf newObject(Handle<PooledDirectByteBuf> handle) {
return new PooledDirectByteBuf(handle, 0); return new PooledDirectByteBuf(handle, 0);
} }
}; };
@ -42,7 +42,7 @@ final class PooledDirectByteBuf extends PooledByteBuf<ByteBuffer> {
return buf; return buf;
} }
private PooledDirectByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) { private PooledDirectByteBuf(Recycler.Handle<PooledDirectByteBuf> recyclerHandle, int maxCapacity) {
super(recyclerHandle, maxCapacity); super(recyclerHandle, maxCapacity);
} }
@ -369,9 +369,4 @@ final class PooledDirectByteBuf extends PooledByteBuf<ByteBuffer> {
public long memoryAddress() { public long memoryAddress() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
protected Recycler<?> recycler() {
return RECYCLER;
}
} }

View File

@ -29,7 +29,7 @@ final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
private static final Recycler<PooledHeapByteBuf> RECYCLER = new Recycler<PooledHeapByteBuf>() { private static final Recycler<PooledHeapByteBuf> RECYCLER = new Recycler<PooledHeapByteBuf>() {
@Override @Override
protected PooledHeapByteBuf newObject(Handle handle) { protected PooledHeapByteBuf newObject(Handle<PooledHeapByteBuf> handle) {
return new PooledHeapByteBuf(handle, 0); return new PooledHeapByteBuf(handle, 0);
} }
}; };
@ -41,7 +41,7 @@ final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
return buf; return buf;
} }
private PooledHeapByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) { private PooledHeapByteBuf(Recycler.Handle<PooledHeapByteBuf> recyclerHandle, int maxCapacity) {
super(recyclerHandle, maxCapacity); super(recyclerHandle, maxCapacity);
} }
@ -299,9 +299,4 @@ final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
protected ByteBuffer newInternalNioBuffer(byte[] memory) { protected ByteBuffer newInternalNioBuffer(byte[] memory) {
return ByteBuffer.wrap(memory); return ByteBuffer.wrap(memory);
} }
@Override
protected Recycler<?> recycler() {
return RECYCLER;
}
} }

View File

@ -34,7 +34,7 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
private static final Recycler<PooledUnsafeDirectByteBuf> RECYCLER = new Recycler<PooledUnsafeDirectByteBuf>() { private static final Recycler<PooledUnsafeDirectByteBuf> RECYCLER = new Recycler<PooledUnsafeDirectByteBuf>() {
@Override @Override
protected PooledUnsafeDirectByteBuf newObject(Handle handle) { protected PooledUnsafeDirectByteBuf newObject(Handle<PooledUnsafeDirectByteBuf> handle) {
return new PooledUnsafeDirectByteBuf(handle, 0); return new PooledUnsafeDirectByteBuf(handle, 0);
} }
}; };
@ -48,7 +48,7 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
private long memoryAddress; private long memoryAddress;
private PooledUnsafeDirectByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) { private PooledUnsafeDirectByteBuf(Recycler.Handle<PooledUnsafeDirectByteBuf> recyclerHandle, int maxCapacity) {
super(recyclerHandle, maxCapacity); super(recyclerHandle, maxCapacity);
} }
@ -381,9 +381,4 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
private long addr(int index) { private long addr(int index) {
return memoryAddress + index; return memoryAddress + index;
} }
@Override
protected Recycler<?> recycler() {
return RECYCLER;
}
} }

View File

@ -42,7 +42,7 @@ public abstract class Recycler<T> {
return o; return o;
} }
public final boolean recycle(T o, Handle handle) { public final boolean recycle(T o, Handle<T> handle) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Stack<T> stack = (Stack<T>) handle; Stack<T> stack = (Stack<T>) handle;
if (stack.parent != this) { if (stack.parent != this) {
@ -57,11 +57,13 @@ public abstract class Recycler<T> {
return true; return true;
} }
protected abstract T newObject(Handle handle); protected abstract T newObject(Handle<T> handle);
public interface Handle { } public interface Handle<T> {
void recycle(T object);
}
static final class Stack<T> implements Handle { static final class Stack<T> implements Handle<T> {
private static final int INITIAL_CAPACITY = 256; private static final int INITIAL_CAPACITY = 256;
@ -78,6 +80,11 @@ public abstract class Recycler<T> {
elements = newArray(INITIAL_CAPACITY); elements = newArray(INITIAL_CAPACITY);
} }
@Override
public void recycle(T object) {
parent.recycle(object, this);
}
T pop() { T pop() {
int size = this.size; int size = this.size;
if (size == 0) { if (size == 0) {

View File

@ -25,7 +25,7 @@ import io.netty.util.concurrent.Promise;
public final class PendingWrite { public final class PendingWrite {
private static final Recycler<PendingWrite> RECYCLER = new Recycler<PendingWrite>() { private static final Recycler<PendingWrite> RECYCLER = new Recycler<PendingWrite>() {
@Override @Override
protected PendingWrite newObject(Handle handle) { protected PendingWrite newObject(Handle<PendingWrite> handle) {
return new PendingWrite(handle); return new PendingWrite(handle);
} }
}; };
@ -40,11 +40,11 @@ public final class PendingWrite {
return pending; return pending;
} }
private final Recycler.Handle handle; private final Recycler.Handle<PendingWrite> handle;
private Object msg; private Object msg;
private Promise<Void> promise; private Promise<Void> promise;
private PendingWrite(Recycler.Handle handle) { private PendingWrite(Recycler.Handle<PendingWrite> handle) {
this.handle = handle; this.handle = handle;
} }

View File

@ -35,7 +35,7 @@ public final class RecyclableArrayList extends ArrayList<Object> {
private static final Recycler<RecyclableArrayList> RECYCLER = new Recycler<RecyclableArrayList>() { private static final Recycler<RecyclableArrayList> RECYCLER = new Recycler<RecyclableArrayList>() {
@Override @Override
protected RecyclableArrayList newObject(Handle handle) { protected RecyclableArrayList newObject(Handle<RecyclableArrayList> handle) {
return new RecyclableArrayList(handle); return new RecyclableArrayList(handle);
} }
}; };
@ -56,13 +56,13 @@ public final class RecyclableArrayList extends ArrayList<Object> {
return ret; return ret;
} }
private final Handle handle; private final Handle<RecyclableArrayList> handle;
private RecyclableArrayList(Handle handle) { private RecyclableArrayList(Handle<RecyclableArrayList> handle) {
this(handle, DEFAULT_INITIAL_CAPACITY); this(handle, DEFAULT_INITIAL_CAPACITY);
} }
private RecyclableArrayList(Handle handle, int initialCapacity) { private RecyclableArrayList(Handle<RecyclableArrayList> handle, int initialCapacity) {
super(initialCapacity); super(initialCapacity);
this.handle = handle; this.handle = handle;
} }

View File

@ -57,7 +57,7 @@ public final class ChannelOutboundBuffer {
private static final Recycler<ChannelOutboundBuffer> RECYCLER = new Recycler<ChannelOutboundBuffer>() { private static final Recycler<ChannelOutboundBuffer> RECYCLER = new Recycler<ChannelOutboundBuffer>() {
@Override @Override
protected ChannelOutboundBuffer newObject(Handle handle) { protected ChannelOutboundBuffer newObject(Handle<ChannelOutboundBuffer> handle) {
return new ChannelOutboundBuffer(handle); return new ChannelOutboundBuffer(handle);
} }
}; };
@ -70,7 +70,7 @@ public final class ChannelOutboundBuffer {
return buffer; return buffer;
} }
private final Handle handle; private final Handle<ChannelOutboundBuffer> handle;
private AbstractChannel channel; private AbstractChannel channel;
@ -98,7 +98,7 @@ public final class ChannelOutboundBuffer {
private volatile int writable = 1; private volatile int writable = 1;
private ChannelOutboundBuffer(Handle handle) { private ChannelOutboundBuffer(Handle<ChannelOutboundBuffer> handle) {
this.handle = handle; this.handle = handle;
buffer = new Entry[INITIAL_CAPACITY]; buffer = new Entry[INITIAL_CAPACITY];
@ -618,16 +618,16 @@ public final class ChannelOutboundBuffer {
} }
static final class ThreadLocalPooledByteBuf extends UnpooledDirectByteBuf { static final class ThreadLocalPooledByteBuf extends UnpooledDirectByteBuf {
private final Recycler.Handle handle; private final Recycler.Handle<ThreadLocalPooledByteBuf> handle;
private static final Recycler<ThreadLocalPooledByteBuf> RECYCLER = new Recycler<ThreadLocalPooledByteBuf>() { private static final Recycler<ThreadLocalPooledByteBuf> RECYCLER = new Recycler<ThreadLocalPooledByteBuf>() {
@Override @Override
protected ThreadLocalPooledByteBuf newObject(Handle handle) { protected ThreadLocalPooledByteBuf newObject(Handle<ThreadLocalPooledByteBuf> handle) {
return new ThreadLocalPooledByteBuf(handle); return new ThreadLocalPooledByteBuf(handle);
} }
}; };
private ThreadLocalPooledByteBuf(Recycler.Handle handle) { private ThreadLocalPooledByteBuf(Recycler.Handle<ThreadLocalPooledByteBuf> handle) {
super(UnpooledByteBufAllocator.DEFAULT, 256, Integer.MAX_VALUE); super(UnpooledByteBufAllocator.DEFAULT, 256, Integer.MAX_VALUE);
this.handle = handle; this.handle = handle;
} }