Improve ready for release

git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/collections/trunk@404804 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Stephen Colebourne 2006-05-07 17:33:02 +00:00
parent 50071f17ac
commit a9c42edbcb
2 changed files with 66 additions and 30 deletions

View File

@ -45,6 +45,7 @@ public class BoundedBuffer extends SynchronizedBuffer implements BoundedCollecti
/** The serialization version. */ /** The serialization version. */
private static final long serialVersionUID = 1536432911093974264L; private static final long serialVersionUID = 1536432911093974264L;
/** The maximum size. */ /** The maximum size. */
private final int maximumSize; private final int maximumSize;
/** The timeout milliseconds. */ /** The timeout milliseconds. */
@ -52,13 +53,17 @@ public class BoundedBuffer extends SynchronizedBuffer implements BoundedCollecti
/** /**
* Factory method to create a bounded buffer. * Factory method to create a bounded buffer.
* <p>
* When the buffer is full, it will immediately throw a
* <code>BufferOverflowException</code> on calling <code>add()</code>.
* *
* @param buffer the buffer to decorate, must not be null * @param buffer the buffer to decorate, must not be null
* @param maximumSize the maximum size * @param maximumSize the maximum size, must be size one or greater
* @return a new bounded buffer * @return a new bounded buffer
* @throws IllegalArgumentException if the buffer is null * @throws IllegalArgumentException if the buffer is null
* @throws IllegalArgumentException if the maximum size is zero or less
*/ */
public static Buffer decorate(Buffer buffer, int maximumSize) { public static BoundedBuffer decorate(Buffer buffer, int maximumSize) {
return new BoundedBuffer(buffer, maximumSize, 0L); return new BoundedBuffer(buffer, maximumSize, 0L);
} }
@ -67,26 +72,32 @@ public class BoundedBuffer extends SynchronizedBuffer implements BoundedCollecti
* amount of time. * amount of time.
* *
* @param buffer the buffer to decorate, must not be null * @param buffer the buffer to decorate, must not be null
* @param maximumSize the maximum size * @param maximumSize the maximum size, must be size one or greater
* @param timeout the maximum amount of time to wait in milliseconds * @param timeout the maximum amount of time to wait in milliseconds
* @return a new bounded buffer * @return a new bounded buffer
* @throws IllegalArgumentException if the buffer is null * @throws IllegalArgumentException if the buffer is null
* @throws IllegalArgumentException if the maximum size is zero or less
*/ */
public static Buffer decorate(Buffer buffer, int maximumSize, long timeout) { public static BoundedBuffer decorate(Buffer buffer, int maximumSize, long timeout) {
return new BoundedBuffer(buffer, maximumSize, timeout); return new BoundedBuffer(buffer, maximumSize, timeout);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
/** /**
* Constructor that wraps (not copies) another buffer, making it bounded waiting only up to * Constructor that wraps (not copies) another buffer, making it bounded
* a maximum amount of time. * waiting only up to a maximum amount of time.
*
* @param buffer the buffer to wrap, must not be null * @param buffer the buffer to wrap, must not be null
* @param maximumSize the maximum size of the buffer * @param maximumSize the maximum size, must be size one or greater
* @param timeout the maximum amount of time to wait * @param timeout the maximum amount of time to wait
* @throws IllegalArgumentException if the buffer is null * @throws IllegalArgumentException if the buffer is null
* @throws IllegalArgumentException if the maximum size is zero or less
*/ */
protected BoundedBuffer( Buffer buffer, int maximumSize, long timeout ) { protected BoundedBuffer(Buffer buffer, int maximumSize, long timeout) {
super( buffer ); super(buffer);
if (maximumSize < 1) {
throw new IllegalArgumentException();
}
this.maximumSize = maximumSize; this.maximumSize = maximumSize;
this.timeout = timeout; this.timeout = timeout;
} }
@ -119,20 +130,28 @@ public class BoundedBuffer extends SynchronizedBuffer implements BoundedCollecti
} }
private void timeoutWait(final int nAdditions) { private void timeoutWait(final int nAdditions) {
synchronized (lock) { // method synchronized by callers
if (timeout < 0 && getBuffer().size() + nAdditions > maximumSize) { if (nAdditions > maximumSize) {
throw new BufferOverflowException( throw new BufferOverflowException(
"Buffer size cannot exceed " + maximumSize); "Buffer size cannot exceed " + maximumSize);
} }
if (timeout <= 0) {
// no wait period (immediate timeout)
if (getBuffer().size() + nAdditions > maximumSize) {
throw new BufferOverflowException(
"Buffer size cannot exceed " + maximumSize);
}
return;
}
final long expiration = System.currentTimeMillis() + timeout; final long expiration = System.currentTimeMillis() + timeout;
long timeLeft = expiration - System.currentTimeMillis(); long timeLeft = expiration - System.currentTimeMillis();
while (timeLeft > 0 && getBuffer().size() + nAdditions > maximumSize) { while (timeLeft > 0 && getBuffer().size() + nAdditions > maximumSize) {
try { try {
lock.wait(timeLeft); lock.wait(timeLeft);
timeLeft = expiration - System.currentTimeMillis(); timeLeft = expiration - System.currentTimeMillis();
} catch (InterruptedException e) { } catch (InterruptedException ex) {
PrintWriter out = new PrintWriter(new StringWriter()); PrintWriter out = new PrintWriter(new StringWriter());
e.printStackTrace(out); ex.printStackTrace(out);
throw new BufferUnderflowException( throw new BufferUnderflowException(
"Caused by InterruptedException: " + out.toString()); "Caused by InterruptedException: " + out.toString());
} }
@ -141,10 +160,10 @@ public class BoundedBuffer extends SynchronizedBuffer implements BoundedCollecti
throw new BufferOverflowException("Timeout expired"); throw new BufferOverflowException("Timeout expired");
} }
} }
}
public boolean isFull() { public boolean isFull() {
return (collection.size() == maxSize()); // size() is synchronized
return (size() == maxSize());
} }
public int maxSize() { public int maxSize() {

View File

@ -66,6 +66,14 @@ public class TestBoundedBuffer extends AbstractTestObject {
assertEquals(true, bc.isFull()); assertEquals(true, bc.isFull());
bounded.remove(); bounded.remove();
assertEquals(false, bc.isFull()); assertEquals(false, bc.isFull());
try {
BoundedBuffer.decorate(new UnboundedFifoBuffer(), 0);
fail();
} catch (IllegalArgumentException ex) {}
try {
BoundedBuffer.decorate(new UnboundedFifoBuffer(), -1);
fail();
} catch (IllegalArgumentException ex) {}
} }
public void testAddToFullBufferNoTimeout() { public void testAddToFullBufferNoTimeout() {
@ -88,6 +96,15 @@ public class TestBoundedBuffer extends AbstractTestObject {
} }
} }
public void testAddAllToEmptyBufferExceedMaxSizeNoTimeout() {
final Buffer bounded = BoundedBuffer.decorate(new UnboundedFifoBuffer(), 1);
try {
bounded.addAll(Collections.nCopies(2, "test"));
fail();
} catch (BufferOverflowException e) {
}
}
public void testAddToFullBufferRemoveViaIterator() { public void testAddToFullBufferRemoveViaIterator() {
final Buffer bounded = BoundedBuffer.decorate(new UnboundedFifoBuffer(), 1, 500); final Buffer bounded = BoundedBuffer.decorate(new UnboundedFifoBuffer(), 1, 500);
bounded.add( "Hello" ); bounded.add( "Hello" );