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));
             }
         }
     }


Reply via email to