Author: trustin
Date: Tue Nov 6 06:50:55 2007
New Revision: 592442
URL: http://svn.apache.org/viewvc?rev=592442&view=rev
Log:
Made CachedBufferAllocator more customizable
Modified:
mina/trunk/core/src/main/java/org/apache/mina/common/CachedBufferAllocator.java
Modified:
mina/trunk/core/src/main/java/org/apache/mina/common/CachedBufferAllocator.java
URL:
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/CachedBufferAllocator.java?rev=592442&r1=592441&r2=592442&view=diff
==============================================================================
---
mina/trunk/core/src/main/java/org/apache/mina/common/CachedBufferAllocator.java
(original)
+++
mina/trunk/core/src/main/java/org/apache/mina/common/CachedBufferAllocator.java
Tue Nov 6 06:50:55 2007
@@ -61,41 +61,90 @@
*/
public class CachedBufferAllocator implements IoBufferAllocator {
- // FIXME: Make these constructor params.
- private static final int MAX_POOL_SIZE = 8;
- private static final int MAX_CACHED_BUFFER_SIZE = 1 << 18; // 256KB
+ private static final int DEFAULT_MAX_POOL_SIZE = 8;
+ private static final int DEFAULT_MAX_CACHED_BUFFER_SIZE = 1 << 18; // 256KB
- private static Map<Integer, Queue<CachedBuffer>> newPoolMap() {
- Map<Integer, Queue<CachedBuffer>> poolMap =
- new HashMap<Integer, Queue<CachedBuffer>>();
- for (int i = 0; i < 31; i ++) {
- poolMap.put(1 << i, new
CircularQueue<CachedBuffer>(MAX_POOL_SIZE));
- }
- poolMap.put(0, new CircularQueue<CachedBuffer>(MAX_POOL_SIZE));
- poolMap.put(Integer.MAX_VALUE, new
CircularQueue<CachedBuffer>(MAX_POOL_SIZE));
- return poolMap;
- }
+ private final int maxPoolSize;
+ private final int maxCachedBufferSize;
- private final ThreadLocal<Map<Integer, Queue<CachedBuffer>>> heapBuffers =
- new ThreadLocal<Map<Integer, Queue<CachedBuffer>>>() {
+ private final ThreadLocal<Map<Integer, Queue<CachedBuffer>>> heapBuffers;
+ private final ThreadLocal<Map<Integer, Queue<CachedBuffer>>> directBuffers;
+
+ /**
+ * Creates a new instance with the default parameters
+ * ([EMAIL PROTECTED] #DEFAULT_MAX_POOL_SIZE} and [EMAIL PROTECTED]
#DEFAULT_MAX_CACHED_BUFFER_SIZE}).
+ */
+ public CachedBufferAllocator() {
+ this(DEFAULT_MAX_POOL_SIZE, DEFAULT_MAX_CACHED_BUFFER_SIZE);
+ }
+
+ /**
+ * Creates a new instance.
+ *
+ * @param maxPoolSize the maximum number of buffers with the same capacity
per thread.
+ * <tt>0</tt> disables this limitation.
+ * @param maxCachedBufferSize the maximum capacity of a cached buffer.
+ * A buffer whose capacity is bigger than this
value is
+ * not pooled. <tt>0</tt> disables this
limitation.
+ */
+ public CachedBufferAllocator(int maxPoolSize, int maxCachedBufferSize) {
+ if (maxPoolSize < 0) {
+ throw new IllegalArgumentException("maxPoolSize: " + maxPoolSize);
+ }
+ if (maxCachedBufferSize < 0) {
+ throw new IllegalArgumentException("maxCachedBufferSize: " +
maxCachedBufferSize);
+ }
+
+ this.maxPoolSize = maxPoolSize;
+ this.maxCachedBufferSize = maxCachedBufferSize;
+
+ this.heapBuffers = new ThreadLocal<Map<Integer,
Queue<CachedBuffer>>>() {
@Override
protected Map<Integer, Queue<CachedBuffer>> initialValue() {
return newPoolMap();
}
- };
-
- private final ThreadLocal<Map<Integer, Queue<CachedBuffer>>> directBuffers
=
- new ThreadLocal<Map<Integer, Queue<CachedBuffer>>>() {
+ };
+ this.directBuffers = new ThreadLocal<Map<Integer,
Queue<CachedBuffer>>>() {
@Override
protected Map<Integer, Queue<CachedBuffer>> initialValue() {
return newPoolMap();
}
- };
-
+ };
+ }
+
+ /**
+ * Returns the maximum number of buffers with the same capacity per thread.
+ * <tt>0</tt> means 'no limitation'.
+ */
+ public int getMaxPoolSize() {
+ return maxPoolSize;
+ }
+
+ /**
+ * Returns the maximum capacity of a cached buffer. A buffer whose
+ * capacity is bigger than this value is not pooled. <tt>0</tt> means
+ * 'no limitation'.
+ */
+ public int getMaxCachedBufferSize() {
+ return maxCachedBufferSize;
+ }
+
+ private Map<Integer, Queue<CachedBuffer>> newPoolMap() {
+ Map<Integer, Queue<CachedBuffer>> poolMap =
+ new HashMap<Integer, Queue<CachedBuffer>>();
+ int poolSize = maxPoolSize == 0? DEFAULT_MAX_POOL_SIZE : maxPoolSize;
+ for (int i = 0; i < 31; i ++) {
+ poolMap.put(1 << i, new CircularQueue<CachedBuffer>(poolSize));
+ }
+ poolMap.put(0, new CircularQueue<CachedBuffer>(poolSize));
+ poolMap.put(Integer.MAX_VALUE, new
CircularQueue<CachedBuffer>(poolSize));
+ return poolMap;
+ }
+
public IoBuffer allocate(int requestedCapacity, boolean direct) {
int actualCapacity = normalizeCapacity(requestedCapacity);
IoBuffer buf ;
- if (actualCapacity > MAX_CACHED_BUFFER_SIZE) {
+ if (maxCachedBufferSize != 0 && actualCapacity > maxCachedBufferSize) {
if (direct) {
buf = wrap(ByteBuffer.allocateDirect(actualCapacity));
} else {
@@ -227,33 +276,27 @@
}
private void free(ByteBuffer oldBuf) {
- if (oldBuf == null) {
+ if (oldBuf == null || oldBuf.capacity() > ' ||
+ oldBuf.isReadOnly() || isDerived() ||
+ Thread.currentThread() != ownerThread) {
return;
}
- if (oldBuf.capacity() > MAX_CACHED_BUFFER_SIZE) {
- return;
+
+ // Add to the cache.
+ Queue<CachedBuffer> pool;
+ if (oldBuf.isDirect()) {
+ pool = directBuffers.get().get(oldBuf.capacity());
+ } else {
+ pool = heapBuffers.get().get(oldBuf.capacity());
}
- if (Thread.currentThread() != ownerThread) {
+
+ if (pool == null) {
return;
}
- // Add to the cache.
- if (!oldBuf.isReadOnly() && !isDerived()) {
- Queue<CachedBuffer> pool;
- if (oldBuf.isDirect()) {
- pool = directBuffers.get().get(oldBuf.capacity());
- } else {
- pool = heapBuffers.get().get(oldBuf.capacity());
- }
-
- if (pool == null) {
- return;
- }
-
- // Restrict the size of the pool to prevent OOM.
- if (pool.size() < MAX_POOL_SIZE) {
- pool.offer(new CachedBuffer(oldBuf, true));
- }
+ // Restrict the size of the pool to prevent OOM.
+ if (maxPoolSize == 0 || pool.size() < maxPoolSize) {
+ pool.offer(new CachedBuffer(oldBuf, true));
}
}
}