diff --git a/RELEASE-NOTES.html b/RELEASE-NOTES.html index 49f5046ee..d2c7f3112 100644 --- a/RELEASE-NOTES.html +++ b/RELEASE-NOTES.html @@ -86,6 +86,7 @@ If this causes major headaches to anyone please contact commons-dev at jakarta.a
  • AbstractMapBag.BagIterator.remove - Removing the last entry used to break the class invariants [35747]
  • BoundedFifoBuffer/CircularFifoBuffer - Fix serialization to work in case where buffer serialized when full [31433]
  • BoundedFifoBuffer - Fix iterator remove bug causing ArrayIndexOutOfBounds error [33071]
  • +
  • UnboundedFifoBuffer - Fix iterator remove bug causing ArrayIndexOutOfBounds error [35733]
  • IteratorChain.remove() - Fix to avoid IllegalStateException when one of the underlying iterators is a FilterIterator [34267]
  • ExtendedProperties.convertProperties() - Fix to handle default properties maps correctly [32204]
  • Add casts to avoid some JDK1.5 compilation warnings [35474]
  • diff --git a/project.xml b/project.xml index 466230b84..938f3d0d0 100644 --- a/project.xml +++ b/project.xml @@ -300,6 +300,9 @@ Jon Schewe + + Andreas Schlosser + Christian Siefkes diff --git a/src/java/org/apache/commons/collections/UnboundedFifoBuffer.java b/src/java/org/apache/commons/collections/UnboundedFifoBuffer.java index cd2358524..8ffab4d24 100644 --- a/src/java/org/apache/commons/collections/UnboundedFifoBuffer.java +++ b/src/java/org/apache/commons/collections/UnboundedFifoBuffer.java @@ -49,6 +49,7 @@ import java.util.NoSuchElementException; * @author Berin Loritsch * @author Paul Jack * @author Stephen Colebourne + * @author Andreas Schlosser */ public class UnboundedFifoBuffer extends AbstractCollection implements Buffer { @@ -254,15 +255,10 @@ public class UnboundedFifoBuffer extends AbstractCollection implements Buffer { } // Other elements require us to shift the subsequent elements - int i = lastReturnedIndex + 1; + int i = increment(lastReturnedIndex); while (i != m_tail) { - if (i >= m_buffer.length) { - m_buffer[i - 1] = m_buffer[0]; - i = 0; - } else { - m_buffer[i - 1] = m_buffer[i]; - i++; - } + m_buffer[decrement(i)] = m_buffer[i]; + i = increment(i); } lastReturnedIndex = -1; diff --git a/src/java/org/apache/commons/collections/buffer/UnboundedFifoBuffer.java b/src/java/org/apache/commons/collections/buffer/UnboundedFifoBuffer.java index 9dbd8021e..53cffdc5f 100644 --- a/src/java/org/apache/commons/collections/buffer/UnboundedFifoBuffer.java +++ b/src/java/org/apache/commons/collections/buffer/UnboundedFifoBuffer.java @@ -294,15 +294,10 @@ public class UnboundedFifoBuffer extends AbstractCollection implements Buffer, S } // Other elements require us to shift the subsequent elements - int i = lastReturnedIndex + 1; + int i = increment(lastReturnedIndex); while (i != tail) { - if (i >= buffer.length) { - buffer[i - 1] = buffer[0]; - i = 0; - } else { - buffer[i - 1] = buffer[i]; - i++; - } + buffer[decrement(i)] = buffer[i]; + i = increment(i); } lastReturnedIndex = -1; diff --git a/src/test/org/apache/commons/collections/TestUnboundedFifoBuffer.java b/src/test/org/apache/commons/collections/TestUnboundedFifoBuffer.java index b93a99efb..6462566c0 100644 --- a/src/test/org/apache/commons/collections/TestUnboundedFifoBuffer.java +++ b/src/test/org/apache/commons/collections/TestUnboundedFifoBuffer.java @@ -142,5 +142,272 @@ public class TestUnboundedFifoBuffer extends AbstractTestCollection { } fail(); } -} + //----------------------------------------------------------------------- + public void testInternalStateAdd() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(2); + assertEquals(3, test.m_buffer.length); + assertEquals(0, test.m_head); + assertEquals(0, test.m_tail); + test.add("A"); + assertEquals(3, test.m_buffer.length); + assertEquals(0, test.m_head); + assertEquals(1, test.m_tail); + test.add("B"); + assertEquals(3, test.m_buffer.length); + assertEquals(0, test.m_head); + assertEquals(2, test.m_tail); + test.add("C"); // forces m_buffer increase + assertEquals(5, test.m_buffer.length); + assertEquals(0, test.m_head); + assertEquals(3, test.m_tail); + test.add("D"); + assertEquals(5, test.m_buffer.length); + assertEquals(0, test.m_head); + assertEquals(4, test.m_tail); + } + + public void testInternalStateAddWithWrap() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(3); + assertEquals(4, test.m_buffer.length); + assertEquals(0, test.m_head); + assertEquals(0, test.m_tail); + test.add("A"); + assertEquals(4, test.m_buffer.length); + assertEquals(0, test.m_head); + assertEquals(1, test.m_tail); + test.add("B"); + assertEquals(4, test.m_buffer.length); + assertEquals(0, test.m_head); + assertEquals(2, test.m_tail); + test.add("C"); + assertEquals(4, test.m_buffer.length); + assertEquals(0, test.m_head); + assertEquals(3, test.m_tail); + test.remove("A"); + assertEquals(4, test.m_buffer.length); + assertEquals(1, test.m_head); + assertEquals(3, test.m_tail); + test.remove("B"); + assertEquals(4, test.m_buffer.length); + assertEquals(2, test.m_head); + assertEquals(3, test.m_tail); + test.add("D"); + assertEquals(4, test.m_buffer.length); + assertEquals(2, test.m_head); + assertEquals(0, test.m_tail); + test.add("E"); + assertEquals(4, test.m_buffer.length); + assertEquals(2, test.m_head); + assertEquals(1, test.m_tail); + } + + public void testInternalStateRemove1() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(4); + test.add("A"); + test.add("B"); + test.add("C"); + assertEquals(5, test.m_buffer.length); + assertEquals(0, test.m_head); + assertEquals(3, test.m_tail); + + test.remove("A"); + assertEquals(5, test.m_buffer.length); + assertEquals(1, test.m_head); + assertEquals(3, test.m_tail); + + test.add("D"); + assertEquals(5, test.m_buffer.length); + assertEquals(1, test.m_head); + assertEquals(4, test.m_tail); + } + + public void testInternalStateRemove2() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(4); + test.add("A"); + test.add("B"); + test.add("C"); + assertEquals(5, test.m_buffer.length); + assertEquals(0, test.m_head); + assertEquals(3, test.m_tail); + + test.remove("B"); + assertEquals(5, test.m_buffer.length); + assertEquals(0, test.m_head); + assertEquals(2, test.m_tail); + + test.add("D"); + assertEquals(5, test.m_buffer.length); + assertEquals(0, test.m_head); + assertEquals(3, test.m_tail); + } + + public void testInternalStateIteratorRemove1() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(4); + test.add("A"); + test.add("B"); + test.add("C"); + assertEquals(5, test.m_buffer.length); + assertEquals(0, test.m_head); + assertEquals(3, test.m_tail); + + Iterator it = test.iterator(); + it.next(); + it.remove(); + assertEquals(5, test.m_buffer.length); + assertEquals(1, test.m_head); + assertEquals(3, test.m_tail); + + test.add("D"); + assertEquals(5, test.m_buffer.length); + assertEquals(1, test.m_head); + assertEquals(4, test.m_tail); + } + + public void testInternalStateIteratorRemove2() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(4); + test.add("A"); + test.add("B"); + test.add("C"); + + Iterator it = test.iterator(); + it.next(); + it.next(); + it.remove(); + assertEquals(5, test.m_buffer.length); + assertEquals(0, test.m_head); + assertEquals(2, test.m_tail); + + test.add("D"); + assertEquals(5, test.m_buffer.length); + assertEquals(0, test.m_head); + assertEquals(3, test.m_tail); + } + + public void testInternalStateIteratorRemoveWithTailAtEnd1() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(3); + test.add("A"); + test.add("B"); + test.add("C"); + test.remove("A"); + test.add("D"); + assertEquals(4, test.m_buffer.length); + assertEquals(1, test.m_head); + assertEquals(0, test.m_tail); + + Iterator it = test.iterator(); + assertEquals("B", it.next()); + it.remove(); + assertEquals(4, test.m_buffer.length); + assertEquals(2, test.m_head); + assertEquals(0, test.m_tail); + } + + public void testInternalStateIteratorRemoveWithTailAtEnd2() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(3); + test.add("A"); + test.add("B"); + test.add("C"); + test.remove("A"); + test.add("D"); + assertEquals(4, test.m_buffer.length); + assertEquals(1, test.m_head); + assertEquals(0, test.m_tail); + + Iterator it = test.iterator(); + assertEquals("B", it.next()); + assertEquals("C", it.next()); + it.remove(); + assertEquals(4, test.m_buffer.length); + assertEquals(1, test.m_head); + assertEquals(3, test.m_tail); + } + + public void testInternalStateIteratorRemoveWithTailAtEnd3() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(3); + test.add("A"); + test.add("B"); + test.add("C"); + test.remove("A"); + test.add("D"); + assertEquals(4, test.m_buffer.length); + assertEquals(1, test.m_head); + assertEquals(0, test.m_tail); + + Iterator it = test.iterator(); + assertEquals("B", it.next()); + assertEquals("C", it.next()); + assertEquals("D", it.next()); + it.remove(); + assertEquals(4, test.m_buffer.length); + assertEquals(1, test.m_head); + assertEquals(3, test.m_tail); + } + + public void testInternalStateIteratorRemoveWithWrap1() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(3); + test.add("A"); + test.add("B"); + test.add("C"); + test.remove("A"); + test.remove("B"); + test.add("D"); + test.add("E"); + assertEquals(4, test.m_buffer.length); + assertEquals(2, test.m_head); + assertEquals(1, test.m_tail); + + Iterator it = test.iterator(); + assertEquals("C", it.next()); + it.remove(); + assertEquals(4, test.m_buffer.length); + assertEquals(3, test.m_head); + assertEquals(1, test.m_tail); + } + + public void testInternalStateIteratorRemoveWithWrap2() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(3); + test.add("A"); + test.add("B"); + test.add("C"); + test.remove("A"); + test.remove("B"); + test.add("D"); + test.add("E"); + assertEquals(4, test.m_buffer.length); + assertEquals(2, test.m_head); + assertEquals(1, test.m_tail); + + Iterator it = test.iterator(); + assertEquals("C", it.next()); + assertEquals("D", it.next()); + it.remove(); + assertEquals(4, test.m_buffer.length); + assertEquals(2, test.m_head); + assertEquals(0, test.m_tail); + } + + public void testInternalStateIteratorRemoveWithWrap3() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(3); + test.add("A"); + test.add("B"); + test.add("C"); + test.remove("A"); + test.remove("B"); + test.add("D"); + test.add("E"); + assertEquals(4, test.m_buffer.length); + assertEquals(2, test.m_head); + assertEquals(1, test.m_tail); + + Iterator it = test.iterator(); + assertEquals("C", it.next()); + assertEquals("D", it.next()); + assertEquals("E", it.next()); + it.remove(); + assertEquals(4, test.m_buffer.length); + assertEquals(2, test.m_head); + assertEquals(0, test.m_tail); + } + +} diff --git a/src/test/org/apache/commons/collections/buffer/TestUnboundedFifoBuffer.java b/src/test/org/apache/commons/collections/buffer/TestUnboundedFifoBuffer.java index e6b9b2ed8..c6207218a 100644 --- a/src/test/org/apache/commons/collections/buffer/TestUnboundedFifoBuffer.java +++ b/src/test/org/apache/commons/collections/buffer/TestUnboundedFifoBuffer.java @@ -144,6 +144,274 @@ public class TestUnboundedFifoBuffer extends AbstractTestCollection { fail(); } + //----------------------------------------------------------------------- + public void testInternalStateAdd() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(2); + assertEquals(3, test.buffer.length); + assertEquals(0, test.head); + assertEquals(0, test.tail); + test.add("A"); + assertEquals(3, test.buffer.length); + assertEquals(0, test.head); + assertEquals(1, test.tail); + test.add("B"); + assertEquals(3, test.buffer.length); + assertEquals(0, test.head); + assertEquals(2, test.tail); + test.add("C"); // forces buffer increase + assertEquals(5, test.buffer.length); + assertEquals(0, test.head); + assertEquals(3, test.tail); + test.add("D"); + assertEquals(5, test.buffer.length); + assertEquals(0, test.head); + assertEquals(4, test.tail); + } + + public void testInternalStateAddWithWrap() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(3); + assertEquals(4, test.buffer.length); + assertEquals(0, test.head); + assertEquals(0, test.tail); + test.add("A"); + assertEquals(4, test.buffer.length); + assertEquals(0, test.head); + assertEquals(1, test.tail); + test.add("B"); + assertEquals(4, test.buffer.length); + assertEquals(0, test.head); + assertEquals(2, test.tail); + test.add("C"); + assertEquals(4, test.buffer.length); + assertEquals(0, test.head); + assertEquals(3, test.tail); + test.remove("A"); + assertEquals(4, test.buffer.length); + assertEquals(1, test.head); + assertEquals(3, test.tail); + test.remove("B"); + assertEquals(4, test.buffer.length); + assertEquals(2, test.head); + assertEquals(3, test.tail); + test.add("D"); + assertEquals(4, test.buffer.length); + assertEquals(2, test.head); + assertEquals(0, test.tail); + test.add("E"); + assertEquals(4, test.buffer.length); + assertEquals(2, test.head); + assertEquals(1, test.tail); + } + + public void testInternalStateRemove1() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(4); + test.add("A"); + test.add("B"); + test.add("C"); + assertEquals(5, test.buffer.length); + assertEquals(0, test.head); + assertEquals(3, test.tail); + + test.remove("A"); + assertEquals(5, test.buffer.length); + assertEquals(1, test.head); + assertEquals(3, test.tail); + + test.add("D"); + assertEquals(5, test.buffer.length); + assertEquals(1, test.head); + assertEquals(4, test.tail); + } + + public void testInternalStateRemove2() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(4); + test.add("A"); + test.add("B"); + test.add("C"); + assertEquals(5, test.buffer.length); + assertEquals(0, test.head); + assertEquals(3, test.tail); + + test.remove("B"); + assertEquals(5, test.buffer.length); + assertEquals(0, test.head); + assertEquals(2, test.tail); + + test.add("D"); + assertEquals(5, test.buffer.length); + assertEquals(0, test.head); + assertEquals(3, test.tail); + } + + public void testInternalStateIteratorRemove1() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(4); + test.add("A"); + test.add("B"); + test.add("C"); + assertEquals(5, test.buffer.length); + assertEquals(0, test.head); + assertEquals(3, test.tail); + + Iterator it = test.iterator(); + it.next(); + it.remove(); + assertEquals(5, test.buffer.length); + assertEquals(1, test.head); + assertEquals(3, test.tail); + + test.add("D"); + assertEquals(5, test.buffer.length); + assertEquals(1, test.head); + assertEquals(4, test.tail); + } + + public void testInternalStateIteratorRemove2() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(4); + test.add("A"); + test.add("B"); + test.add("C"); + + Iterator it = test.iterator(); + it.next(); + it.next(); + it.remove(); + assertEquals(5, test.buffer.length); + assertEquals(0, test.head); + assertEquals(2, test.tail); + + test.add("D"); + assertEquals(5, test.buffer.length); + assertEquals(0, test.head); + assertEquals(3, test.tail); + } + + public void testInternalStateIteratorRemoveWithTailAtEnd1() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(3); + test.add("A"); + test.add("B"); + test.add("C"); + test.remove("A"); + test.add("D"); + assertEquals(4, test.buffer.length); + assertEquals(1, test.head); + assertEquals(0, test.tail); + + Iterator it = test.iterator(); + assertEquals("B", it.next()); + it.remove(); + assertEquals(4, test.buffer.length); + assertEquals(2, test.head); + assertEquals(0, test.tail); + } + + public void testInternalStateIteratorRemoveWithTailAtEnd2() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(3); + test.add("A"); + test.add("B"); + test.add("C"); + test.remove("A"); + test.add("D"); + assertEquals(4, test.buffer.length); + assertEquals(1, test.head); + assertEquals(0, test.tail); + + Iterator it = test.iterator(); + assertEquals("B", it.next()); + assertEquals("C", it.next()); + it.remove(); + assertEquals(4, test.buffer.length); + assertEquals(1, test.head); + assertEquals(3, test.tail); + } + + public void testInternalStateIteratorRemoveWithTailAtEnd3() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(3); + test.add("A"); + test.add("B"); + test.add("C"); + test.remove("A"); + test.add("D"); + assertEquals(4, test.buffer.length); + assertEquals(1, test.head); + assertEquals(0, test.tail); + + Iterator it = test.iterator(); + assertEquals("B", it.next()); + assertEquals("C", it.next()); + assertEquals("D", it.next()); + it.remove(); + assertEquals(4, test.buffer.length); + assertEquals(1, test.head); + assertEquals(3, test.tail); + } + + public void testInternalStateIteratorRemoveWithWrap1() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(3); + test.add("A"); + test.add("B"); + test.add("C"); + test.remove("A"); + test.remove("B"); + test.add("D"); + test.add("E"); + assertEquals(4, test.buffer.length); + assertEquals(2, test.head); + assertEquals(1, test.tail); + + Iterator it = test.iterator(); + assertEquals("C", it.next()); + it.remove(); + assertEquals(4, test.buffer.length); + assertEquals(3, test.head); + assertEquals(1, test.tail); + } + + public void testInternalStateIteratorRemoveWithWrap2() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(3); + test.add("A"); + test.add("B"); + test.add("C"); + test.remove("A"); + test.remove("B"); + test.add("D"); + test.add("E"); + assertEquals(4, test.buffer.length); + assertEquals(2, test.head); + assertEquals(1, test.tail); + + Iterator it = test.iterator(); + assertEquals("C", it.next()); + assertEquals("D", it.next()); + it.remove(); + assertEquals(4, test.buffer.length); + assertEquals(2, test.head); + assertEquals(0, test.tail); + } + + public void testInternalStateIteratorRemoveWithWrap3() { + UnboundedFifoBuffer test = new UnboundedFifoBuffer(3); + test.add("A"); + test.add("B"); + test.add("C"); + test.remove("A"); + test.remove("B"); + test.add("D"); + test.add("E"); + assertEquals(4, test.buffer.length); + assertEquals(2, test.head); + assertEquals(1, test.tail); + + Iterator it = test.iterator(); + assertEquals("C", it.next()); + assertEquals("D", it.next()); + assertEquals("E", it.next()); + it.remove(); + assertEquals(4, test.buffer.length); + assertEquals(2, test.head); + assertEquals(0, test.tail); + } + + //----------------------------------------------------------------------- public String getCompatibilityVersion() { return "3.1"; }