Author: trustin
Date: Sat Nov 10 09:21:20 2007
New Revision: 593795

URL: http://svn.apache.org/viewvc?rev=593795&view=rev
Log:
Added autoShrink feature to IoBuffer.

Modified:
    mina/trunk/core/src/main/java/org/apache/mina/common/AbstractIoBuffer.java
    
mina/trunk/core/src/main/java/org/apache/mina/common/CachedBufferAllocator.java
    mina/trunk/core/src/main/java/org/apache/mina/common/IoBuffer.java
    mina/trunk/core/src/main/java/org/apache/mina/common/IoBufferAllocator.java
    mina/trunk/core/src/main/java/org/apache/mina/common/IoBufferWrapper.java
    
mina/trunk/core/src/main/java/org/apache/mina/common/SimpleBufferAllocator.java
    mina/trunk/core/src/test/java/org/apache/mina/common/IoBufferTest.java

Modified: 
mina/trunk/core/src/main/java/org/apache/mina/common/AbstractIoBuffer.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/AbstractIoBuffer.java?rev=593795&r1=593794&r2=593795&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/common/AbstractIoBuffer.java 
(original)
+++ mina/trunk/core/src/main/java/org/apache/mina/common/AbstractIoBuffer.java 
Sat Nov 10 09:21:20 2007
@@ -37,13 +37,16 @@
  *
  * @author The Apache MINA Project ([EMAIL PROTECTED])
  * @version $Rev$, $Date$
- * @noinspection StaticNonFinalField
  * @see IoBufferAllocator
  */
 public abstract class AbstractIoBuffer extends IoBuffer {
+    
+    private final IoBufferAllocator allocator;
+    private final int initialCapacity;
     private final boolean derived;
     private boolean autoExpand;
-    private boolean autoExpandAllowed = true;
+    private boolean autoShrink;
+    private boolean recapacityAllowed = true;
 
     /**
      * We don't have any access to Buffer.markValue(), so we need to track it 
down,
@@ -51,9 +54,25 @@
      */
     private int mark = -1;
 
-    protected AbstractIoBuffer(boolean autoExpandAllowed) {
-        this.autoExpandAllowed = autoExpandAllowed;
-        this.derived = !autoExpandAllowed;
+    /**
+     * Creates a new parent buffer.
+     */
+    protected AbstractIoBuffer(
+            IoBufferAllocator allocator, int initialCapacity) {
+        this.allocator = allocator;
+        this.recapacityAllowed = true;
+        this.derived = false;
+        this.initialCapacity = initialCapacity;
+    }
+    
+    /**
+     * Creates a new derived buffer.
+     */
+    protected AbstractIoBuffer(AbstractIoBuffer parent) {
+        this.allocator = parent.allocator;
+        this.recapacityAllowed = false;
+        this.derived = true;
+        this.initialCapacity = parent.initialCapacity;
     }
 
     @Override
@@ -66,6 +85,11 @@
         return buf().isReadOnly();
     }
 
+    /**
+     * Sets the underlying NIO buffer instance.
+     */
+    protected abstract void buf(ByteBuffer newBuf);
+
     @Override
     public int capacity() {
         return buf().capacity();
@@ -73,13 +97,28 @@
 
     @Override
     public IoBuffer capacity(int newCapacity) {
+        if (!recapacityAllowed) {
+            throw new IllegalStateException(
+                    "Derived buffers and their parent can't be expanded.");
+        }
+
+        // Allocate a new buffer and transfer all settings to it.
         if (newCapacity > capacity()) {
-            // Allocate a new buffer and transfer all settings to it.
+            // Expand:
+            //// Save the state.
             int pos = position();
             int limit = limit();
             ByteOrder bo = order();
 
-            capacity0(newCapacity);
+            //// Reallocate.
+            ByteBuffer oldBuf = buf();
+            ByteBuffer newBuf = 
+                allocator.allocateNioBuffer(newCapacity, isDirect());
+            oldBuf.clear();
+            newBuf.put(oldBuf);
+            buf(newBuf);
+
+            //// Restore the state.
             buf().limit(limit);
             if (mark >= 0) {
                 buf().position(mark);
@@ -88,19 +127,18 @@
             buf().position(pos);
             buf().order(bo);
         }
-
+        
         return this;
     }
 
-    /**
-     * Implement this method to increase the capacity of this buffer.
-     * <tt>newCapacity</tt> is always greater than the current capacity.
-     */
-    protected abstract void capacity0(int newCapacity);
-
     @Override
     public boolean isAutoExpand() {
-        return autoExpand && autoExpandAllowed;
+        return autoExpand && recapacityAllowed;
+    }
+    
+    @Override
+    public boolean isAutoShrink() {
+        return autoShrink && recapacityAllowed;
     }
     
     @Override
@@ -110,16 +148,31 @@
 
     @Override
     public IoBuffer setAutoExpand(boolean autoExpand) {
-        if (!autoExpandAllowed) {
+        if (!recapacityAllowed) {
             throw new IllegalStateException(
-                    "Derived buffers can't be auto-expandable.");
+                    "Derived buffers and their parent can't be expanded.");
         }
         this.autoExpand = autoExpand;
         return this;
     }
 
     @Override
+    public IoBuffer setAutoShrink(boolean autoShrink) {
+        if (!recapacityAllowed) {
+            throw new IllegalStateException(
+                    "Derived buffers and their parent can't be shrinked.");
+        }
+        this.autoShrink = autoShrink;
+        return this;
+    }
+
+    @Override
     public IoBuffer expand(int pos, int expectedRemaining) {
+        if (!recapacityAllowed) {
+            throw new IllegalStateException(
+                    "Derived buffers and their parent can't be expanded.");
+        }
+
         int end = pos + expectedRemaining;
         if (end > capacity()) {
             // The buffer needs expansion.
@@ -248,7 +301,38 @@
 
     @Override
     public IoBuffer compact() {
-        buf().compact();
+        int remaining = remaining();
+        if (isAutoShrink() && remaining <= capacity() >>> 2) {
+            int newCapacity = remaining << 1;
+            if (newCapacity < initialCapacity && initialCapacity == 
capacity()) {
+                buf().compact();
+            } else {
+                newCapacity = Math.max(initialCapacity, newCapacity);
+
+                // Shrink and compact:
+                //// Save the state.
+                ByteOrder bo = order();
+    
+                //// Sanity check.
+                if (remaining > newCapacity) {
+                    throw new IllegalStateException(
+                            "The amount of the remaining bytes is greater than 
" +
+                            "the new capacity.");
+                }
+    
+                //// Reallocate.
+                ByteBuffer oldBuf = buf();
+                ByteBuffer newBuf = 
+                    allocator.allocateNioBuffer(newCapacity, isDirect());
+                newBuf.put(oldBuf);
+                buf(newBuf);
+                
+                //// Restore the state.
+                buf().order(bo);
+            }
+        } else {
+            buf().compact();
+        }
         mark = -1;
         return this;
     }
@@ -440,7 +524,7 @@
 
     @Override
     public final IoBuffer asReadOnlyBuffer() {
-        autoExpandAllowed = false;
+        recapacityAllowed = false;
         return asReadOnlyBuffer0();
     }
 
@@ -452,7 +536,7 @@
 
     @Override
     public final IoBuffer duplicate() {
-        autoExpandAllowed = false;
+        recapacityAllowed = false;
         return duplicate0();
     }
 
@@ -464,7 +548,7 @@
 
     @Override
     public final IoBuffer slice() {
-        autoExpandAllowed = false;
+        recapacityAllowed = false;
         return slice0();
     }
 

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=593795&r1=593794&r2=593795&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 
Sat Nov 10 09:21:20 2007
@@ -177,8 +177,12 @@
         return buf;
     }
     
+    public ByteBuffer allocateNioBuffer(int capacity, boolean direct) {
+        return allocate(capacity, direct).buf();
+    }
+    
     public IoBuffer wrap(ByteBuffer nioBuffer) {
-        return new CachedBuffer(nioBuffer, true);
+        return new CachedBuffer(nioBuffer);
     }
 
     public void dispose() {
@@ -211,12 +215,18 @@
         private final Thread ownerThread;
         private ByteBuffer buf;
 
-        protected CachedBuffer(ByteBuffer buf, boolean autoExpandAllowed) {
-            super(autoExpandAllowed);
+        protected CachedBuffer(ByteBuffer buf) {
+            super(CachedBufferAllocator.this, buf.capacity());
             this.ownerThread = Thread.currentThread();
             this.buf = buf;
             buf.order(ByteOrder.BIG_ENDIAN);
         }
+        
+        protected CachedBuffer(CachedBuffer parent, ByteBuffer buf) {
+            super(parent);
+            this.ownerThread = Thread.currentThread();
+            this.buf = buf;
+        }
 
         @Override
         public ByteBuffer buf() {
@@ -225,33 +235,27 @@
             }
             return buf;
         }
-
+        
         @Override
-        protected void capacity0(int requestedCapacity) {
-            int newCapacity = normalizeCapacity(requestedCapacity);
-
-            ByteBuffer oldBuf = buf();
-            ByteBuffer newBuf = allocate(newCapacity, isDirect()).buf();
-            oldBuf.clear();
-            newBuf.put(oldBuf);
-            this.buf = newBuf;
-            
+        protected void buf(ByteBuffer buf) {
+            ByteBuffer oldBuf = this.buf;
+            this.buf = buf;
             free(oldBuf);
         }
 
         @Override
         protected IoBuffer duplicate0() {
-            return new CachedBuffer(buf().duplicate(), false);
+            return new CachedBuffer(this, buf().duplicate());
         }
 
         @Override
         protected IoBuffer slice0() {
-            return new CachedBuffer(buf().slice(), false);
+            return new CachedBuffer(this, buf().slice());
         }
 
         @Override
         protected IoBuffer asReadOnlyBuffer0() {
-            return new CachedBuffer(buf().asReadOnlyBuffer(), false);
+            return new CachedBuffer(this, buf().asReadOnlyBuffer());
         }
 
         @Override
@@ -296,7 +300,7 @@
 
             // Restrict the size of the pool to prevent OOM.
             if (maxPoolSize == 0 || pool.size() < maxPoolSize) {
-                pool.offer(new CachedBuffer(oldBuf, true));
+                pool.offer(new CachedBuffer(oldBuf));
             }
         }
     }

Modified: mina/trunk/core/src/main/java/org/apache/mina/common/IoBuffer.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/IoBuffer.java?rev=593795&r1=593794&r2=593795&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/common/IoBuffer.java 
(original)
+++ mina/trunk/core/src/main/java/org/apache/mina/common/IoBuffer.java Sat Nov 
10 09:21:20 2007
@@ -103,6 +103,20 @@
  * increase by two times, and its limit will increase to the last position
  * the string is written.
  * </p>
+ * 
+ * <h2>AutoShrink</h2>
+ * <p>
+ * You might also want to decrease the capacity of the buffer when most
+ * of the allocated memory area is not being used.  MINA [EMAIL PROTECTED] 
IoBuffer}
+ * provides <tt>autoShrink</tt> property to take care of this issue.
+ * If <tt>autoShrink</tt> is turned on, [EMAIL PROTECTED] IoBuffer} halves the 
capacity
+ * of the buffer when [EMAIL PROTECTED] #compact()} is invoked and only 1/4 or 
less of
+ * the current capacity is being used. NIO <tt>ByteBuffer</tt> is reallocated
+ * by MINA [EMAIL PROTECTED] IoBuffer} behind the scene, and therefore [EMAIL 
PROTECTED] #buf()}
+ * will return a different [EMAIL PROTECTED] ByteBuffer} instance once 
capacity is
+ * changed.  Please also note [EMAIL PROTECTED] #compact()} will not decrease 
the
+ * capacity if the new capacity is less than the initial capacity of the
+ * buffer. 
  *
  * <h2>Derived Buffers</h2>
  * <p>
@@ -110,9 +124,9 @@
  * [EMAIL PROTECTED] #duplicate()}, [EMAIL PROTECTED] #slice()}, or [EMAIL 
PROTECTED] #asReadOnlyBuffer()}.
  * They are useful especially when you broadcast the same messages to
  * multiple [EMAIL PROTECTED] IoSession}s.  Please note that the buffer 
derived from and
- * its derived buffers are not both auto-expandable.  Trying to call
- * [EMAIL PROTECTED] #setAutoExpand(boolean)} with <tt>true</tt> parameter will
- * raise an [EMAIL PROTECTED] IllegalStateException}.
+ * its derived buffers are not both auto-expandable neither auto-shrinkable.
+ * Trying to call [EMAIL PROTECTED] #setAutoExpand(boolean)} or [EMAIL 
PROTECTED] #setAutoShrink(boolean)}
+ * with <tt>true</tt> parameter will raise an [EMAIL PROTECTED] 
IllegalStateException}.
  * </p>
  *
  * <h2>Changing Buffer Allocation Policy</h2>
@@ -129,7 +143,7 @@
  *
  * @author The Apache MINA Project ([EMAIL PROTECTED])
  * @version $Rev$, $Date$
- * @noinspection StaticNonFinalField
+ * 
  * @see IoBufferAllocator
  */
 public abstract class IoBuffer implements Comparable<IoBuffer> {
@@ -247,7 +261,7 @@
      * Returns the underlying NIO buffer instance.
      */
     public abstract ByteBuffer buf();
-
+    
     /**
      * @see ByteBuffer#isDirect()
      */
@@ -270,7 +284,11 @@
     public abstract int capacity();
 
     /**
-     * Changes the capacity of this buffer.
+     * Increases the capacity of this buffer.  If the new capacity is less than
+     * or equal to the current capacity, this method returns silently.  If the
+     * new capacity is greater than the current capacity, the buffer is
+     * reallocated while retaining the position, limit, mark and the content
+     * of the buffer.
      */
     public abstract IoBuffer capacity(int newCapacity);
 
@@ -283,6 +301,16 @@
      * Turns on or off <tt>autoExpand</tt>.
      */
     public abstract IoBuffer setAutoExpand(boolean autoExpand);
+    
+    /**
+     * Returns <tt>true</tt> if and only if <tt>autoShrink</tt> is turned on.
+     */
+    public abstract boolean isAutoShrink();
+
+    /**
+     * Turns on or off <tt>autoShrink</tt>.
+     */
+    public abstract IoBuffer setAutoShrink(boolean autoShrink);
 
     /**
      * Changes the capacity and limit of this buffer so this buffer get
@@ -297,11 +325,11 @@
     /**
      * Changes the capacity and limit of this buffer so this buffer get
      * the specified <tt>expectedRemaining</tt> room from the specified
-     * <tt>pos</tt>.
+     * <tt>position</tt>.
      * This method works even if you didn't set <tt>autoExpand</tt> to
      * <tt>true</tt>.
      */
-    public abstract IoBuffer expand(int pos, int expectedRemaining);
+    public abstract IoBuffer expand(int position, int expectedRemaining);
 
     /**
      * @see java.nio.Buffer#position()

Modified: 
mina/trunk/core/src/main/java/org/apache/mina/common/IoBufferAllocator.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/IoBufferAllocator.java?rev=593795&r1=593794&r2=593795&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/common/IoBufferAllocator.java 
(original)
+++ mina/trunk/core/src/main/java/org/apache/mina/common/IoBufferAllocator.java 
Sat Nov 10 09:21:20 2007
@@ -39,6 +39,15 @@
     IoBuffer allocate(int capacity, boolean direct);
 
     /**
+     * Returns the NIO buffer which is capable of the specified size.
+     *
+     * @param capacity the capacity of the buffer
+     * @param direct <tt>true</tt> to get a direct buffer,
+     *               <tt>false</tt> to get a heap buffer.
+     */
+    ByteBuffer allocateNioBuffer(int capacity, boolean direct);
+
+    /**
      * Wraps the specified NIO [EMAIL PROTECTED] ByteBuffer} into MINA buffer.
      */
     IoBuffer wrap(ByteBuffer nioBuffer);

Modified: 
mina/trunk/core/src/main/java/org/apache/mina/common/IoBufferWrapper.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/IoBufferWrapper.java?rev=593795&r1=593794&r2=593795&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/common/IoBufferWrapper.java 
(original)
+++ mina/trunk/core/src/main/java/org/apache/mina/common/IoBufferWrapper.java 
Sat Nov 10 09:21:20 2007
@@ -646,4 +646,15 @@
     public boolean isDerived() {
         return buf.isDerived();
     }
+
+    @Override
+    public boolean isAutoShrink() {
+        return buf.isAutoShrink();
+    }
+
+    @Override
+    public IoBuffer setAutoShrink(boolean autoShrink) {
+        buf.setAutoShrink(autoShrink);
+        return this;
+    }
 }

Modified: 
mina/trunk/core/src/main/java/org/apache/mina/common/SimpleBufferAllocator.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/SimpleBufferAllocator.java?rev=593795&r1=593794&r2=593795&view=diff
==============================================================================
--- 
mina/trunk/core/src/main/java/org/apache/mina/common/SimpleBufferAllocator.java 
(original)
+++ 
mina/trunk/core/src/main/java/org/apache/mina/common/SimpleBufferAllocator.java 
Sat Nov 10 09:21:20 2007
@@ -33,90 +33,63 @@
 public class SimpleBufferAllocator implements IoBufferAllocator {
 
     public IoBuffer allocate(int capacity, boolean direct) {
+        return wrap(allocateNioBuffer(capacity, direct));
+    }
+    
+    public ByteBuffer allocateNioBuffer(int capacity, boolean direct) {
         ByteBuffer nioBuffer;
         if (direct) {
             nioBuffer = ByteBuffer.allocateDirect(capacity);
         } else {
             nioBuffer = ByteBuffer.allocate(capacity);
         }
-        return new SimpleBuffer(nioBuffer, true);
+        return nioBuffer;
     }
 
     public IoBuffer wrap(ByteBuffer nioBuffer) {
-        return new SimpleBuffer(nioBuffer, true);
+        return new SimpleBuffer(nioBuffer);
     }
 
     public void dispose() {
     }
 
-    private static class SimpleBuffer extends AbstractIoBuffer {
+    private class SimpleBuffer extends AbstractIoBuffer {
         private ByteBuffer buf;
 
-        protected SimpleBuffer(ByteBuffer buf,
-                boolean autoExpandAllowed) {
-            super(autoExpandAllowed);
+        protected SimpleBuffer(ByteBuffer buf) {
+            super(SimpleBufferAllocator.this, buf.capacity());
             this.buf = buf;
             buf.order(ByteOrder.BIG_ENDIAN);
         }
 
-        @Override
-        public ByteBuffer buf() {
-            return buf;
+        protected SimpleBuffer(SimpleBuffer parent, ByteBuffer buf) {
+            super(parent);
+            this.buf = buf;
         }
 
         @Override
-        protected void capacity0(int requestedCapacity) {
-            int newCapacity = normalizeCapacity(requestedCapacity);
-
-            ByteBuffer oldBuf = this.buf;
-            ByteBuffer newBuf;
-            if (isDirect()) {
-                newBuf = ByteBuffer.allocateDirect(newCapacity);
-            } else {
-                newBuf = ByteBuffer.allocate(newCapacity);
-            }
-
-            newBuf.clear();
-            oldBuf.clear();
-            newBuf.put(oldBuf);
-            this.buf = newBuf;
+        public ByteBuffer buf() {
+            return buf;
         }
         
-        private static int normalizeCapacity(int requestedCapacity) {
-            switch (requestedCapacity) {
-            case 1 <<  0: case 1 <<  1: case 1 <<  2: case 1 <<  3: case 1 <<  
4:
-            case 1 <<  5: case 1 <<  6: case 1 <<  7: case 1 <<  8: case 1 <<  
9:
-            case 1 << 10: case 1 << 11: case 1 << 12: case 1 << 13: case 1 << 
14:
-            case 1 << 15: case 1 << 16: case 1 << 17: case 1 << 18: case 1 << 
19:
-            case 1 << 21: case 1 << 22: case 1 << 23: case 1 << 24: case 1 << 
25:
-            case 1 << 26: case 1 << 27: case 1 << 28: case 1 << 29: case 1 << 
30:
-            case Integer.MAX_VALUE:
-                return requestedCapacity;
-            }
-            
-            int newCapacity = 1;
-            while (newCapacity < requestedCapacity) {
-                newCapacity <<= 1;
-                if (newCapacity < 0) {
-                    return Integer.MAX_VALUE;
-                }
-            }
-            return newCapacity;
+        @Override
+        protected void buf(ByteBuffer buf) {
+            this.buf = buf;
         }
 
         @Override
         protected IoBuffer duplicate0() {
-            return new SimpleBuffer(this.buf.duplicate(), false);
+            return new SimpleBuffer(this, this.buf.duplicate());
         }
 
         @Override
         protected IoBuffer slice0() {
-            return new SimpleBuffer(this.buf.slice(), false);
+            return new SimpleBuffer(this, this.buf.slice());
         }
 
         @Override
         protected IoBuffer asReadOnlyBuffer0() {
-            return new SimpleBuffer(this.buf.asReadOnlyBuffer(), false);
+            return new SimpleBuffer(this, this.buf.asReadOnlyBuffer());
         }
 
         @Override

Modified: mina/trunk/core/src/test/java/org/apache/mina/common/IoBufferTest.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/test/java/org/apache/mina/common/IoBufferTest.java?rev=593795&r1=593794&r2=593795&view=diff
==============================================================================
--- mina/trunk/core/src/test/java/org/apache/mina/common/IoBufferTest.java 
(original)
+++ mina/trunk/core/src/test/java/org/apache/mina/common/IoBufferTest.java Sat 
Nov 10 09:21:20 2007
@@ -116,6 +116,80 @@
         buf.reset();
         Assert.assertEquals(3, buf.position());
     }
+    
+    public void testAutoShrink() throws Exception {
+        IoBuffer buf = IoBuffer.allocate(8).setAutoShrink(true);
+        
+        // Make sure the buffer doesn't shrink too much (less than the initial
+        // capacity.)
+        buf.sweep((byte) 1);
+        buf.fill(7); 
+        buf.compact();
+        Assert.assertEquals(8, buf.capacity());
+        Assert.assertEquals(1, buf.position());
+        Assert.assertEquals(8, buf.limit());
+        buf.clear();
+        Assert.assertEquals(1, buf.get());
+
+        // Expand the buffer.
+        buf.capacity(32).clear();
+        Assert.assertEquals(32, buf.capacity());
+        
+        // Make sure the buffer shrinks when only 1/4 is being used.
+        buf.sweep((byte) 1);
+        buf.fill(24);
+        buf.compact();
+        Assert.assertEquals(16, buf.capacity());
+        Assert.assertEquals(8, buf.position());
+        Assert.assertEquals(16, buf.limit());
+        buf.clear();
+        for (int i = 0; i < 8; i ++) {
+            Assert.assertEquals(1, buf.get());
+        }
+
+        // Expand the buffer.
+        buf.capacity(32).clear();
+        Assert.assertEquals(32, buf.capacity());
+        
+        // Make sure the buffer shrinks when only 1/8 is being used.
+        buf.sweep((byte) 1);
+        buf.fill(28);
+        buf.compact();
+        Assert.assertEquals(8, buf.capacity());
+        Assert.assertEquals(4, buf.position());
+        Assert.assertEquals(8, buf.limit());
+        buf.clear();
+        for (int i = 0; i < 4; i ++) {
+            Assert.assertEquals(1, buf.get());
+        }
+
+        // Expand the buffer.
+        buf.capacity(32).clear();
+        Assert.assertEquals(32, buf.capacity());
+        
+        // Make sure the buffer shrinks when 0 byte is being used.
+        buf.fill(32);
+        buf.compact();
+        Assert.assertEquals(8, buf.capacity());
+        Assert.assertEquals(0, buf.position());
+        Assert.assertEquals(8, buf.limit());
+
+        // Expand the buffer.
+        buf.capacity(32).clear();
+        Assert.assertEquals(32, buf.capacity());
+        
+        // Make sure the buffer doesn't shrink when more than 1/4 is being 
used.
+        buf.sweep((byte) 1);
+        buf.fill(23);
+        buf.compact();
+        Assert.assertEquals(32, buf.capacity());
+        Assert.assertEquals(9, buf.position());
+        Assert.assertEquals(32, buf.limit());
+        buf.clear();
+        for (int i = 0; i < 9; i ++) {
+            Assert.assertEquals(1, buf.get());
+        }
+    }
 
     public void testGetString() throws Exception {
         IoBuffer buf = IoBuffer.allocate(16);


Reply via email to