From a218eb6f6fe07d572c90bc3bfac3f5a8cde6f5ab Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Sat, 27 Apr 2013 08:55:16 +0900 Subject: [PATCH] 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. --- .../netty/buffer/PooledByteBufAllocator.java | 75 +++++++++++++------ 1 file changed, 54 insertions(+), 21 deletions(-) diff --git a/buffer/src/main/java/io/netty/buffer/PooledByteBufAllocator.java b/buffer/src/main/java/io/netty/buffer/PooledByteBufAllocator.java index a14830e073..34766c3404 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledByteBufAllocator.java +++ b/buffer/src/main/java/io/netty/buffer/PooledByteBufAllocator.java @@ -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[] heapArenas; private final PoolArena[] directArenas; + private final UnpooledByteBufAllocator unpooledAllocator; final ThreadLocal threadCache = new ThreadLocal() { 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 heapArena; + final PoolArena 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 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 directArena = cache.directArena; + if (directArena != null) { + return directArena.allocate(cache, initialCapacity, maxCapacity); + } else { + return unpooledAllocator.newDirectBuffer(initialCapacity, maxCapacity); + } } public String toString() {