You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by tn...@apache.org on 2013/04/16 21:53:49 UTC
svn commit: r1468578 - in /commons/proper/collections/trunk/src:
main/java/org/apache/commons/collections/queue/
test/java/org/apache/commons/collections/queue/ test/resources/data/test/
Author: tn
Date: Tue Apr 16 19:53:49 2013
New Revision: 1468578
URL: http://svn.apache.org/r1468578
Log:
[COLLECTIONS-432] Add CircularFifoQueue based on CircularFifoBuffer.
Added:
commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/queue/CircularFifoQueue.java (with props)
commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/queue/CircularFifoQueueTest.java (with props)
commons/proper/collections/trunk/src/test/resources/data/test/CircularFifoQueue.emptyCollection.version4.obj (with props)
commons/proper/collections/trunk/src/test/resources/data/test/CircularFifoQueue.fullCollection.version4.obj (with props)
Modified:
commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/queue/package-info.java
Added: commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/queue/CircularFifoQueue.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/queue/CircularFifoQueue.java?rev=1468578&view=auto
==============================================================================
--- commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/queue/CircularFifoQueue.java (added)
+++ commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/queue/CircularFifoQueue.java Tue Apr 16 19:53:49 2013
@@ -0,0 +1,415 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections.queue;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.AbstractCollection;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+
+import org.apache.commons.collections.BoundedCollection;
+
+/**
+ * CircularFifoQueue is a first-in first-out queue with a fixed size that
+ * replaces its oldest element if full.
+ * <p>
+ * The removal order of a {@link CircularFifoQueue} is based on the
+ * insertion order; elements are removed in the same order in which they
+ * were added. The iteration order is the same as the removal order.
+ * <p>
+ * The {@link #add(Object)}, {@link #remove()} and {@link #get()} operations
+ * all perform in constant time. All other operations perform in linear
+ * time or worse.
+ * <p>
+ * This queue prevents null objects from being added.
+ *
+ * @since 4.0
+ * @version $Id$
+ */
+public class CircularFifoQueue<E> extends AbstractCollection<E>
+ implements Queue<E>, BoundedCollection<E>, Serializable {
+
+ /** Serialization version. */
+ private static final long serialVersionUID = -8423413834657610406L;
+
+ /** Underlying storage array. */
+ private transient E[] elements;
+
+ /** Array index of first (oldest) queue element. */
+ private transient int start = 0;
+
+ /**
+ * Index mod maxElements of the array position following the last queue
+ * element. Queue elements start at elements[start] and "wrap around"
+ * elements[maxElements-1], ending at elements[decrement(end)].
+ * For example, elements = {c,a,b}, start=1, end=1 corresponds to
+ * the queue [a,b,c].
+ */
+ private transient int end = 0;
+
+ /** Flag to indicate if the queue is currently full. */
+ private transient boolean full = false;
+
+ /** Capacity of the queue. */
+ private final int maxElements;
+
+ /**
+ * Constructor that creates a queue with the default size of 32.
+ */
+ public CircularFifoQueue() {
+ this(32);
+ }
+
+ /**
+ * Constructor that creates a queue with the specified size.
+ *
+ * @param size the size of the queue (cannot be changed)
+ * @throws IllegalArgumentException if the size is < 1
+ */
+ @SuppressWarnings("unchecked")
+ public CircularFifoQueue(final int size) {
+ if (size <= 0) {
+ throw new IllegalArgumentException("The size must be greater than 0");
+ }
+ elements = (E[]) new Object[size];
+ maxElements = elements.length;
+ }
+
+ /**
+ * Constructor that creates a queue from the specified collection.
+ * The collection size also sets the queue size.
+ *
+ * @param coll the collection to copy into the queue, may not be null
+ * @throws NullPointerException if the collection is null
+ */
+ public CircularFifoQueue(final Collection<E> coll) {
+ this(coll.size());
+ addAll(coll);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Write the queue out using a custom routine.
+ *
+ * @param out the output stream
+ * @throws IOException if an I/O error occurs while writing to the output stream
+ */
+ private void writeObject(final ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ out.writeInt(size());
+ for (final E e : this) {
+ out.writeObject(e);
+ }
+ }
+
+ /**
+ * Read the queue in using a custom routine.
+ *
+ * @param in the input stream
+ * @throws IOException if an I/O error occurs while writing to the output stream
+ * @throws ClassNotFoundException if the class of a serialized object can not be found
+ */
+ @SuppressWarnings("unchecked")
+ private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ elements = (E[]) new Object[maxElements];
+ final int size = in.readInt();
+ for (int i = 0; i < size; i++) {
+ elements[i] = (E) in.readObject();
+ }
+ start = 0;
+ full = size == maxElements;
+ if (full) {
+ end = 0;
+ } else {
+ end = size;
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns the number of elements stored in the queue.
+ *
+ * @return this queue's size
+ */
+ @Override
+ public int size() {
+ int size = 0;
+
+ if (end < start) {
+ size = maxElements - start + end;
+ } else if (end == start) {
+ size = full ? maxElements : 0;
+ } else {
+ size = end - start;
+ }
+
+ return size;
+ }
+
+ /**
+ * Returns true if this queue is empty; false otherwise.
+ *
+ * @return true if this queue is empty
+ */
+ @Override
+ public boolean isEmpty() {
+ return size() == 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * A {@code CircularFifoQueue} can never be full, thus this returns always
+ * {@code false}.
+ *
+ * @return always returns {@code false}
+ */
+ public boolean isFull() {
+ return false;
+ }
+
+ private boolean isAtFullCapacity() {
+ return size() == maxElements;
+ }
+
+ /**
+ * Gets the maximum size of the collection (the bound).
+ *
+ * @return the maximum number of elements the collection can hold
+ */
+ public int maxSize() {
+ return maxElements;
+ }
+
+ /**
+ * Clears this queue.
+ */
+ @Override
+ public void clear() {
+ full = false;
+ start = 0;
+ end = 0;
+ Arrays.fill(elements, null);
+ }
+
+ /**
+ * Adds the given element to this queue. If the queue is full, the least recently added
+ * element is discarded so that a new element can be inserted.
+ *
+ * @param element the element to add
+ * @return true, always
+ * @throws NullPointerException if the given element is null
+ */
+ @Override
+ public boolean add(final E element) {
+ if (null == element) {
+ throw new NullPointerException("Attempted to add null object to queue");
+ }
+
+ if (isAtFullCapacity()) {
+ remove();
+ }
+
+ elements[end++] = element;
+
+ if (end >= maxElements) {
+ end = 0;
+ }
+
+ if (end == start) {
+ full = true;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the element at the specified position in this queue.
+ *
+ * @param index the position of the element in the queue
+ * @return the element at position {@code index}
+ * @throws NoSuchElementException if the requested position is outside the range [0, size)
+ */
+ public E get(final int index) {
+ final int sz = size();
+ if (index < 0 || index >= sz) {
+ throw new NoSuchElementException(
+ String.format("The specified index (%1$d) is outside the available range [0, %2$d)",
+ index, sz));
+ }
+
+ final int idx = (start + index) % maxElements;
+ return elements[idx];
+ }
+
+ //-----------------------------------------------------------------------
+
+ /**
+ * Adds the given element to this queue. If the queue is full, the least recently added
+ * element is discarded so that a new element can be inserted.
+ *
+ * @param element the element to add
+ * @return true, always
+ * @throws NullPointerException if the given element is null
+ */
+ public boolean offer(E element) {
+ return add(element);
+ }
+
+ public E poll() {
+ if (isEmpty()) {
+ return null;
+ } else {
+ return remove();
+ }
+ }
+
+ public E element() {
+ if (isEmpty()) {
+ throw new NoSuchElementException("queue is empty");
+ } else {
+ return peek();
+ }
+ }
+
+ public E peek() {
+ if (isEmpty()) {
+ return null;
+ }
+ return elements[start];
+ }
+
+ public E remove() {
+ if (isEmpty()) {
+ throw new NoSuchElementException("queue is empty");
+ }
+
+ final E element = elements[start];
+ if (null != element) {
+ elements[start++] = null;
+
+ if (start >= maxElements) {
+ start = 0;
+ }
+ full = false;
+ }
+ return element;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Increments the internal index.
+ *
+ * @param index the index to increment
+ * @return the updated index
+ */
+ private int increment(int index) {
+ index++;
+ if (index >= maxElements) {
+ index = 0;
+ }
+ return index;
+ }
+
+ /**
+ * Decrements the internal index.
+ *
+ * @param index the index to decrement
+ * @return the updated index
+ */
+ private int decrement(int index) {
+ index--;
+ if (index < 0) {
+ index = maxElements - 1;
+ }
+ return index;
+ }
+
+ /**
+ * Returns an iterator over this queue's elements.
+ *
+ * @return an iterator over this queue's elements
+ */
+ @Override
+ public Iterator<E> iterator() {
+ return new Iterator<E>() {
+
+ private int index = start;
+ private int lastReturnedIndex = -1;
+ private boolean isFirst = full;
+
+ public boolean hasNext() {
+ return isFirst || index != end;
+ }
+
+ public E next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ isFirst = false;
+ lastReturnedIndex = index;
+ index = increment(index);
+ return elements[lastReturnedIndex];
+ }
+
+ public void remove() {
+ if (lastReturnedIndex == -1) {
+ throw new IllegalStateException();
+ }
+
+ // First element can be removed quickly
+ if (lastReturnedIndex == start) {
+ CircularFifoQueue.this.remove();
+ lastReturnedIndex = -1;
+ return;
+ }
+
+ int pos = lastReturnedIndex + 1;
+ if (start < lastReturnedIndex && pos < end) {
+ // shift in one part
+ System.arraycopy(elements, pos, elements, lastReturnedIndex, end - pos);
+ } else {
+ // Other elements require us to shift the subsequent elements
+ while (pos != end) {
+ if (pos >= maxElements) {
+ elements[pos - 1] = elements[0];
+ pos = 0;
+ } else {
+ elements[decrement(pos)] = elements[pos];
+ pos = increment(pos);
+ }
+ }
+ }
+
+ lastReturnedIndex = -1;
+ end = decrement(end);
+ elements[end] = null;
+ full = false;
+ index = decrement(index);
+ }
+
+ };
+ }
+
+}
Propchange: commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/queue/CircularFifoQueue.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/queue/CircularFifoQueue.java
------------------------------------------------------------------------------
svn:keywords = Id Revision HeadURL
Propchange: commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/queue/CircularFifoQueue.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/queue/package-info.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/queue/package-info.java?rev=1468578&r1=1468577&r2=1468578&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/queue/package-info.java (original)
+++ commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/queue/package-info.java Tue Apr 16 19:53:49 2013
@@ -15,7 +15,12 @@
* limitations under the License.
*/
/**
- * This package contains decorators for the {@link java.util.Queue Queue} interface.
+ * This package contains implementations for the {@link java.util.Queue Queue} interface.
+ * <p>
+ * The following implementations are provided in the package:
+ * <ul>
+ * <li>CircularFifoQueue - implements a queue with a fixed size that discards oldest when full
+ * </ul>
* <p>
* The following decorators are provided in the package:
* <ul>
Added: commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/queue/CircularFifoQueueTest.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/queue/CircularFifoQueueTest.java?rev=1468578&view=auto
==============================================================================
--- commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/queue/CircularFifoQueueTest.java (added)
+++ commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/queue/CircularFifoQueueTest.java Tue Apr 16 19:53:49 2013
@@ -0,0 +1,461 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections.queue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+
+import junit.framework.Test;
+import org.apache.commons.collections.BulkTest;
+import org.apache.commons.collections.collection.AbstractCollectionTest;
+
+/**
+ * Test cases for CircularFifoQueue.
+ *
+ * @version $Id$
+ */
+public class CircularFifoQueueTest<E> extends AbstractCollectionTest<E> {
+
+ public CircularFifoQueueTest(final String n) {
+ super(n);
+ }
+
+ public static Test suite() {
+ return BulkTest.makeSuite(CircularFifoQueueTest.class);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Runs through the regular verifications, but also verifies that
+ * the buffer contains the same elements in the same sequence as the
+ * list.
+ */
+ @Override
+ public void verify() {
+ super.verify();
+ final Iterator<E> iterator1 = getCollection().iterator();
+ final Iterator<E> iterator2 = getConfirmed().iterator();
+ while (iterator2.hasNext()) {
+ assertTrue(iterator1.hasNext());
+ final Object o1 = iterator1.next();
+ final Object o2 = iterator2.next();
+ assertEquals(o1, o2);
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Overridden because CircularFifoQueue doesn't allow null elements.
+ * @return false
+ */
+ @Override
+ public boolean isNullSupported() {
+ return false;
+ }
+
+ /**
+ * Overridden because CircularFifoQueue isn't fail fast.
+ * @return false
+ */
+ @Override
+ public boolean isFailFastSupported() {
+ return false;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns an empty ArrayList.
+ *
+ * @return an empty ArrayList
+ */
+ @Override
+ public Collection<E> makeConfirmedCollection() {
+ return new ArrayList<E>();
+ }
+
+ /**
+ * Returns a full ArrayList.
+ *
+ * @return a full ArrayList
+ */
+ @Override
+ public Collection<E> makeConfirmedFullCollection() {
+ final Collection<E> c = makeConfirmedCollection();
+ c.addAll(java.util.Arrays.asList(getFullElements()));
+ return c;
+ }
+
+ /**
+ * Returns an empty CircularFifoQueue that won't overflow.
+ *
+ * @return an empty CircularFifoQueue
+ */
+ @Override
+ public Collection<E> makeObject() {
+ return new CircularFifoQueue<E>(100);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Tests that the removal operation actually removes the first element.
+ */
+ @SuppressWarnings("unchecked")
+ public void testCircularFifoQueueCircular() {
+ final List<E> list = new ArrayList<E>();
+ list.add((E) "A");
+ list.add((E) "B");
+ list.add((E) "C");
+ final Queue<E> queue = new CircularFifoQueue<E>(list);
+
+ assertEquals(true, queue.contains("A"));
+ assertEquals(true, queue.contains("B"));
+ assertEquals(true, queue.contains("C"));
+
+ queue.add((E) "D");
+
+ assertEquals(false, queue.contains("A"));
+ assertEquals(true, queue.contains("B"));
+ assertEquals(true, queue.contains("C"));
+ assertEquals(true, queue.contains("D"));
+
+ assertEquals("B", queue.peek());
+ assertEquals("B", queue.remove());
+ assertEquals("C", queue.remove());
+ assertEquals("D", queue.remove());
+ }
+
+ /**
+ * Tests that the removal operation actually removes the first element.
+ */
+ public void testCircularFifoQueueRemove() {
+ resetFull();
+ final int size = getConfirmed().size();
+ for (int i = 0; i < size; i++) {
+ final Object o1 = getCollection().remove();
+ final Object o2 = getConfirmed().remove(0);
+ assertEquals("Removed objects should be equal", o1, o2);
+ verify();
+ }
+
+ try {
+ getCollection().remove();
+ fail("Empty queue should raise Underflow.");
+ } catch (final NoSuchElementException e) {
+ // expected
+ }
+ }
+
+ /**
+ * Tests that the constructor correctly throws an exception.
+ */
+ public void testConstructorException1() {
+ try {
+ new CircularFifoQueue<E>(0);
+ } catch (final IllegalArgumentException ex) {
+ return;
+ }
+ fail();
+ }
+
+ /**
+ * Tests that the constructor correctly throws an exception.
+ */
+ public void testConstructorException2() {
+ try {
+ new CircularFifoQueue<E>(-20);
+ } catch (final IllegalArgumentException ex) {
+ return;
+ }
+ fail();
+ }
+
+ /**
+ * Tests that the constructor correctly throws an exception.
+ */
+ public void testConstructorException3() {
+ try {
+ new CircularFifoQueue<E>(null);
+ } catch (final NullPointerException ex) {
+ return;
+ }
+ fail();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testRemoveError1() throws Exception {
+ // based on bug 33071
+ final CircularFifoQueue<E> fifo = new CircularFifoQueue<E>(5);
+ fifo.add((E) "1");
+ fifo.add((E) "2");
+ fifo.add((E) "3");
+ fifo.add((E) "4");
+ fifo.add((E) "5");
+
+ assertEquals("[1, 2, 3, 4, 5]", fifo.toString());
+
+ fifo.remove("3");
+ assertEquals("[1, 2, 4, 5]", fifo.toString());
+
+ fifo.remove("4");
+ assertEquals("[1, 2, 5]", fifo.toString());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testRemoveError2() throws Exception {
+ // based on bug 33071
+ final CircularFifoQueue<E> fifo = new CircularFifoQueue<E>(5);
+ fifo.add((E) "1");
+ fifo.add((E) "2");
+ fifo.add((E) "3");
+ fifo.add((E) "4");
+ fifo.add((E) "5");
+ fifo.add((E) "6");
+
+ assertEquals(5, fifo.size());
+ assertEquals("[2, 3, 4, 5, 6]", fifo.toString());
+
+ fifo.remove("3");
+ assertEquals("[2, 4, 5, 6]", fifo.toString());
+
+ fifo.remove("4");
+ assertEquals("[2, 5, 6]", fifo.toString());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testRemoveError3() throws Exception {
+ // based on bug 33071
+ final CircularFifoQueue<E> fifo = new CircularFifoQueue<E>(5);
+ fifo.add((E) "1");
+ fifo.add((E) "2");
+ fifo.add((E) "3");
+ fifo.add((E) "4");
+ fifo.add((E) "5");
+
+ assertEquals("[1, 2, 3, 4, 5]", fifo.toString());
+
+ fifo.remove("3");
+ assertEquals("[1, 2, 4, 5]", fifo.toString());
+
+ fifo.add((E) "6");
+ fifo.add((E) "7");
+ assertEquals("[2, 4, 5, 6, 7]", fifo.toString());
+
+ fifo.remove("4");
+ assertEquals("[2, 5, 6, 7]", fifo.toString());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testRemoveError4() throws Exception {
+ // based on bug 33071
+ final CircularFifoQueue<E> fifo = new CircularFifoQueue<E>(5);
+ fifo.add((E) "1");
+ fifo.add((E) "2");
+ fifo.add((E) "3");
+ fifo.add((E) "4");
+ fifo.add((E) "5"); // end=0
+ fifo.add((E) "6"); // end=1
+ fifo.add((E) "7"); // end=2
+
+ assertEquals("[3, 4, 5, 6, 7]", fifo.toString());
+
+ fifo.remove("4"); // remove element in middle of array, after start
+ assertEquals("[3, 5, 6, 7]", fifo.toString());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testRemoveError5() throws Exception {
+ // based on bug 33071
+ final CircularFifoQueue<E> fifo = new CircularFifoQueue<E>(5);
+ fifo.add((E) "1");
+ fifo.add((E) "2");
+ fifo.add((E) "3");
+ fifo.add((E) "4");
+ fifo.add((E) "5"); // end=0
+ fifo.add((E) "6"); // end=1
+ fifo.add((E) "7"); // end=2
+
+ assertEquals("[3, 4, 5, 6, 7]", fifo.toString());
+
+ fifo.remove("5"); // remove element at last pos in array
+ assertEquals("[3, 4, 6, 7]", fifo.toString());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testRemoveError6() throws Exception {
+ // based on bug 33071
+ final CircularFifoQueue<E> fifo = new CircularFifoQueue<E>(5);
+ fifo.add((E) "1");
+ fifo.add((E) "2");
+ fifo.add((E) "3");
+ fifo.add((E) "4");
+ fifo.add((E) "5"); // end=0
+ fifo.add((E) "6"); // end=1
+ fifo.add((E) "7"); // end=2
+
+ assertEquals("[3, 4, 5, 6, 7]", fifo.toString());
+
+ fifo.remove("6"); // remove element at position zero in array
+ assertEquals("[3, 4, 5, 7]", fifo.toString());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testRemoveError7() throws Exception {
+ // based on bug 33071
+ final CircularFifoQueue<E> fifo = new CircularFifoQueue<E>(5);
+ fifo.add((E) "1");
+ fifo.add((E) "2");
+ fifo.add((E) "3");
+ fifo.add((E) "4");
+ fifo.add((E) "5"); // end=0
+ fifo.add((E) "6"); // end=1
+ fifo.add((E) "7"); // end=2
+
+ assertEquals("[3, 4, 5, 6, 7]", fifo.toString());
+
+ fifo.remove("7"); // remove element at position one in array
+ assertEquals("[3, 4, 5, 6]", fifo.toString());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testRemoveError8() throws Exception {
+ // based on bug 33071
+ final CircularFifoQueue<E> fifo = new CircularFifoQueue<E>(5);
+ fifo.add((E) "1");
+ fifo.add((E) "2");
+ fifo.add((E) "3");
+ fifo.add((E) "4");
+ fifo.add((E) "5"); // end=0
+ fifo.add((E) "6"); // end=1
+ fifo.add((E) "7"); // end=2
+ fifo.add((E) "8"); // end=3
+
+ assertEquals("[4, 5, 6, 7, 8]", fifo.toString());
+
+ fifo.remove("7"); // remove element at position one in array, need to shift 8
+ assertEquals("[4, 5, 6, 8]", fifo.toString());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testRemoveError9() throws Exception {
+ // based on bug 33071
+ final CircularFifoQueue<E> fifo = new CircularFifoQueue<E>(5);
+ fifo.add((E) "1");
+ fifo.add((E) "2");
+ fifo.add((E) "3");
+ fifo.add((E) "4");
+ fifo.add((E) "5"); // end=0
+ fifo.add((E) "6"); // end=1
+ fifo.add((E) "7"); // end=2
+ fifo.add((E) "8"); // end=3
+
+ assertEquals("[4, 5, 6, 7, 8]", fifo.toString());
+
+ fifo.remove("8"); // remove element at position two in array
+ assertEquals("[4, 5, 6, 7]", fifo.toString());
+ }
+
+ //-----------------------------------------------------------------------
+ @SuppressWarnings("unchecked")
+ public void testRepeatedSerialization() throws Exception {
+ // bug 31433
+ final CircularFifoQueue<E> b = new CircularFifoQueue<E>(2);
+ b.add((E) "a");
+ assertEquals(1, b.size());
+ assertEquals(true, b.contains("a"));
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ new ObjectOutputStream(bos).writeObject(b);
+
+ final CircularFifoQueue<E> b2 = (CircularFifoQueue<E>) new ObjectInputStream(
+ new ByteArrayInputStream(bos.toByteArray())).readObject();
+
+ assertEquals(1, b2.size());
+ assertEquals(true, b2.contains("a"));
+ b2.add((E) "b");
+ assertEquals(2, b2.size());
+ assertEquals(true, b2.contains("a"));
+ assertEquals(true, b2.contains("b"));
+
+ bos = new ByteArrayOutputStream();
+ new ObjectOutputStream(bos).writeObject(b2);
+
+ final CircularFifoQueue<E> b3 = (CircularFifoQueue<E>) new ObjectInputStream(
+ new ByteArrayInputStream(bos.toByteArray())).readObject();
+
+ assertEquals(2, b3.size());
+ assertEquals(true, b3.contains("a"));
+ assertEquals(true, b3.contains("b"));
+ b3.add((E) "c");
+ assertEquals(2, b3.size());
+ assertEquals(true, b3.contains("b"));
+ assertEquals(true, b3.contains("c"));
+ }
+
+ public void testGetIndex() {
+ resetFull();
+
+ final CircularFifoQueue<E> queue = getCollection();
+ final List<E> confirmed = getConfirmed();
+ for (int i = 0; i < confirmed.size(); i++) {
+ assertEquals(confirmed.get(i), queue.get(i));
+ }
+
+ // remove the first two elements and check again
+ queue.remove();
+ queue.remove();
+
+ for (int i = 0; i < queue.size(); i++) {
+ assertEquals(confirmed.get(i + 2), queue.get(i));
+ }
+ }
+
+ @Override
+ public String getCompatibilityVersion() {
+ return "4";
+ }
+
+// public void testCreate() throws Exception {
+// resetEmpty();
+// writeExternalFormToDisk((java.io.Serializable) getCollection(), "src/test/resources/data/test/CircularFifoQueue.emptyCollection.version4.obj");
+// resetFull();
+// writeExternalFormToDisk((java.io.Serializable) getCollection(), "src/test/resources/data/test/CircularFifoQueue.fullCollection.version4.obj");
+// }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public CircularFifoQueue<E> getCollection() {
+ return (CircularFifoQueue<E>) super.getCollection();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<E> getConfirmed() {
+ return (List<E>) super.getConfirmed();
+ }
+}
Propchange: commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/queue/CircularFifoQueueTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/queue/CircularFifoQueueTest.java
------------------------------------------------------------------------------
svn:keywords = Id Revision HeadURL
Propchange: commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/queue/CircularFifoQueueTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: commons/proper/collections/trunk/src/test/resources/data/test/CircularFifoQueue.emptyCollection.version4.obj
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/test/resources/data/test/CircularFifoQueue.emptyCollection.version4.obj?rev=1468578&view=auto
==============================================================================
Binary file - no diff available.
Propchange: commons/proper/collections/trunk/src/test/resources/data/test/CircularFifoQueue.emptyCollection.version4.obj
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: commons/proper/collections/trunk/src/test/resources/data/test/CircularFifoQueue.fullCollection.version4.obj
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/test/resources/data/test/CircularFifoQueue.fullCollection.version4.obj?rev=1468578&view=auto
==============================================================================
Binary file - no diff available.
Propchange: commons/proper/collections/trunk/src/test/resources/data/test/CircularFifoQueue.fullCollection.version4.obj
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream