Allow to disable only heap or direct buffer pool

- Fixes #1315

If a user specifies the arena size of 0, the pool is now disabled
instead of raising an IllegalArgumentException. Using this, you can
disable only heap or direct buffer pool easily. Once disabled,
PooledByteBufAllocator will delegate the allocation request to
UnpooledByteBufAllocator.
This commit is contained in:
Trustin Lee 2013-04-27 08:55:16 +09:00
parent 8bb6d5b303
commit a218eb6f6f
1 changed files with 54 additions and 21 deletions

View File

@ -29,9 +29,9 @@ public class PooledByteBufAllocator extends AbstractByteBufAllocator {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(PooledByteBufAllocator.class);
private static final int DEFAULT_NUM_HEAP_ARENA = Math.max(1, SystemPropertyUtil.getInt(
private static final int DEFAULT_NUM_HEAP_ARENA = Math.max(0, SystemPropertyUtil.getInt(
"io.netty.allocator.numHeapArenas", Runtime.getRuntime().availableProcessors()));
private static final int DEFAULT_NUM_DIRECT_ARENA = Math.max(1, SystemPropertyUtil.getInt(
private static final int DEFAULT_NUM_DIRECT_ARENA = Math.max(0, SystemPropertyUtil.getInt(
"io.netty.allocator.numDirectArenas", Runtime.getRuntime().availableProcessors()));
private static final int DEFAULT_PAGE_SIZE;
private static final int DEFAULT_MAX_ORDER; // 8192 << 11 = 16 MiB per chunk
@ -82,15 +82,29 @@ public class PooledByteBufAllocator extends AbstractByteBufAllocator {
private final PoolArena<byte[]>[] heapArenas;
private final PoolArena<ByteBuffer>[] directArenas;
private final UnpooledByteBufAllocator unpooledAllocator;
final ThreadLocal<PoolThreadCache> threadCache = new ThreadLocal<PoolThreadCache>() {
private final AtomicInteger index = new AtomicInteger();
@Override
protected PoolThreadCache initialValue() {
int idx = index.getAndIncrement();
int heapIdx = Math.abs(idx % heapArenas.length);
int directIdx = Math.abs(idx % directArenas.length);
return new PoolThreadCache(heapArenas[heapIdx], directArenas[directIdx]);
final int idx = index.getAndIncrement();
final PoolArena<byte[]> heapArena;
final PoolArena<ByteBuffer> directArena;
if (heapArenas != null) {
heapArena = heapArenas[Math.abs(idx % heapArenas.length)];
} else {
heapArena = null;
}
if (directArenas != null) {
directArena = directArenas[Math.abs(idx % directArenas.length)];
} else {
directArena = null;
}
return new PoolThreadCache(heapArena, directArena);
}
};
@ -106,30 +120,39 @@ public class PooledByteBufAllocator extends AbstractByteBufAllocator {
this(false, nHeapArena, nDirectArena, pageSize, maxOrder);
}
public PooledByteBufAllocator(
boolean directByDefault, int nHeapArena, int nDirectArena, int pageSize, int maxOrder) {
super(directByDefault);
public PooledByteBufAllocator(boolean preferDirect, int nHeapArena, int nDirectArena, int pageSize, int maxOrder) {
super(preferDirect);
final int chunkSize = validateAndCalculateChunkSize(pageSize, maxOrder);
if (nHeapArena <= 0) {
throw new IllegalArgumentException("nHeapArena: " + nHeapArena + " (expected: 1+)");
if (nHeapArena < 0) {
throw new IllegalArgumentException("nHeapArena: " + nHeapArena + " (expected: >= 0)");
}
if (nDirectArena <= 0) {
throw new IllegalArgumentException("nDirectArea: " + nDirectArena + " (expected: 1+)");
if (nDirectArena < 0) {
throw new IllegalArgumentException("nDirectArea: " + nDirectArena + " (expected: >= 0)");
}
int pageShifts = validateAndCalculatePageShifts(pageSize);
heapArenas = newArenaArray(nHeapArena);
for (int i = 0; i < heapArenas.length; i ++) {
heapArenas[i] = new PoolArena.HeapArena(this, pageSize, maxOrder, pageShifts, chunkSize);
if (nHeapArena > 0) {
heapArenas = newArenaArray(nHeapArena);
for (int i = 0; i < heapArenas.length; i ++) {
heapArenas[i] = new PoolArena.HeapArena(this, pageSize, maxOrder, pageShifts, chunkSize);
}
} else {
heapArenas = null;
}
directArenas = newArenaArray(nDirectArena);
for (int i = 0; i < directArenas.length; i ++) {
directArenas[i] = new PoolArena.DirectArena(this, pageSize, maxOrder, pageShifts, chunkSize);
if (nHeapArena > 0) {
directArenas = newArenaArray(nDirectArena);
for (int i = 0; i < directArenas.length; i ++) {
directArenas[i] = new PoolArena.DirectArena(this, pageSize, maxOrder, pageShifts, chunkSize);
}
} else {
directArenas = null;
}
unpooledAllocator = new UnpooledByteBufAllocator(preferDirect);
}
@SuppressWarnings("unchecked")
@ -181,13 +204,23 @@ public class PooledByteBufAllocator extends AbstractByteBufAllocator {
@Override
protected ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity) {
PoolThreadCache cache = threadCache.get();
return cache.heapArena.allocate(cache, initialCapacity, maxCapacity);
PoolArena<byte[]> heapArena = cache.heapArena;
if (heapArena != null) {
return heapArena.allocate(cache, initialCapacity, maxCapacity);
} else {
return unpooledAllocator.newDirectBuffer(initialCapacity, maxCapacity);
}
}
@Override
protected ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity) {
PoolThreadCache cache = threadCache.get();
return cache.directArena.allocate(cache, initialCapacity, maxCapacity);
PoolArena<ByteBuffer> directArena = cache.directArena;
if (directArena != null) {
return directArena.allocate(cache, initialCapacity, maxCapacity);
} else {
return unpooledAllocator.newDirectBuffer(initialCapacity, maxCapacity);
}
}
public String toString() {