/* XXL: The eXtensible and fleXible Library for data processing Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger Head of the Database Research Group Department of Mathematics and Computer Science University of Marburg Germany This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; If not, see <http://www.gnu.org/licenses/>. http://code.google.com/p/xxl/ */ package xxl.core.collections.queues; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import xxl.core.cursors.Cursors; import xxl.core.functions.AbstractFunction; import xxl.core.functions.Function; /** * The interface queue represents an user specified iteration over a collection * of elements (also known as a <i>sequence</i>) with a <code>peek</code> * method. This interface <b>does not</b> predefine any <i>strategy</i> for * addition and removal of elements so that the user has full control * concerning his <i>strategy</i> (e.g., FIFO (<i>first in, first out</i>), * LIFO (<i>last in, first out</i>) etc.). * * <p>In contrast to sets, queues typically allow duplicate elements. More * formally, queues typically allow pairs of elements <code>e1</code> and * <code>e2</code> such that <code>e1.equals(e2)</code>, and they typically * allow multiple null elements if they allow null elements at all.</p> * * <p>It is important to see that the <code>peek</code> method only shows the * element which currently is the next element. The next call of * <code>dequeue</code> does not have to return the peeked element. This is a * difference to the semantic of <code>peek</code> inside the * <code>Cursor</code> interface.</p> * * @param <E> the type of the elements of this queue. */ public interface Queue<E> { /** * A factory method to create a default queue. Each concrete implementation * of a queue except for ArrayQueue should have a function FACTORY_METHOD * that implements three variants of <code>invoke</code> * <ul> * <dl> * <dt><li><code>Queue invoke()</code>:</dt> * <dd>returns <code>new Queue()</code>.</dd> * <dt><li><code>Queue invoke(Object iterator)</code>:</dt> * <dd>returns <code>new Queue(iterator)</code>.</dd> * <dt><li><code>Queue invoke(List<? extends Object> internalDataStructure)</code>:</dt> * <dd>returns <code>new Queue((<<i>InternalDataStructure></i>)internalDataStructure.get(0))</code>.</dd> * </dl> * </ul> * This factory method creates a new ArrayQueue. It may be invoked with a * <i>parameter list</i> (for further details see {@link Function}) of * object arrays, an iterator or without any parameters. A <i>parameter * list</i> of object arrays will be used to initialize the internally used * array with the object array at index 0 and an iterator will be used to * insert the contained elements into the new ArrayQueue. * * @see Function */ public static final Function<Object, ArrayQueue<Object>> FACTORY_METHOD = new AbstractFunction<Object, ArrayQueue<Object>>() { @Override public ArrayQueue<Object> invoke() { return new ArrayQueue<Object>(); } @Override public ArrayQueue<Object> invoke(Object iterator) { return new ArrayQueue<Object>( Cursors.toArray((Iterator<?>)iterator) ); } @Override public ArrayQueue<Object> invoke(List<? extends Object> list) { return new ArrayQueue<Object>((Object[])list.get(0)); } }; /** * Opens the queue, i.e., signals the queue to reserve resources, open * files, etc. Before a queue has been opened calls to methods like * <code>peek</code> are not guaranteed to yield proper results. Therefore * <code>open</code> must be called before a queue's data can be processed. * Multiple calls to <code>open</code> do not have any effect, i.e., if * <code>open</code> was called the queue remains in the state * <i>opened</i> until its <code>close</code> method is called. * * <p>Note, that a call to the <code>open</code> method of a closed queue * usually does not open it again because of the fact that its state * generally cannot be restored when resources are released respectively * files are closed.</p> */ public abstract void open(); /** * Closes this queue and releases any system resources associated with it. * This operation is idempotent, i.e., multiple calls of this method take * the same effect as a single call.<br /> * <b>Note</b> that this method is very important for queues using external * resources like files or JDBC resources. */ public abstract void close(); /** * Appends the specified element to the <i>end</i> of this queue. The * <i>end</i> of the queue is given by its <i>strategy</i>. * * @param object element to be appended at the <i>end</i> of this queue. * @throws IllegalStateException if the queue is already closed when this * method is called. */ public abstract void enqueue(E object) throws IllegalStateException; /** * Returns the element which currently is the <i>next</i> element in the * queue. The element is <i>not</i> removed from the queue (in contrast to * the method <code>dequeue</code>). The <i>next</i> element of the queue * is given by its <i>strategy</i>. The next call to <code>dequeue</code> * does not have to return the element which was returned by * <code>peek</code>. * * @return the <i>next</i> element in the queue. * @throws IllegalStateException if the queue is already closed when this * method is called. * @throws NoSuchElementException queue has no more elements. */ public abstract E peek() throws IllegalStateException, NoSuchElementException; /** * Returns the <i>next</i> element in the queue and <i>removes</i> it. The * <i>next</i> element of the queue is given by its <i>strategy</i>. * * @return the <i>next</i> element in the queue. * @throws IllegalStateException if the queue is already closed when this * method is called. * @throws NoSuchElementException queue has no more elements. */ public abstract E dequeue() throws IllegalStateException, NoSuchElementException; /** * Returns <code>false</code> if the queue has more elements (in other * words, returns <code>false</code> if <code>next</code> would return an * element rather than throwing an exception). * * @return <code>false</code> if the queue has more elements. */ public abstract boolean isEmpty(); /** * Returns the number of elements in this queue. If this queue contains * more than <code>Integer.MAX_VALUE</code> elements, returns * <code>Integer.MAX_VALUE</code>. * * @return the number of elements in this queue. */ public abstract int size(); /** * Removes all of the elements from this queue. The queue will be empty * after this call returns so that <code>size() == 0</code>.<br /> * <b>Note</b> that the elements will only be removed from the queue but * not from the underlying collection. */ public abstract void clear(); }