/*1* Written by Josh Bloch of Google Inc. and released to the public domain,2* as explained at http://creativecommons.org/publicdomain/zero/1.0/.3*/45package com.artifex.mupdfdemo;67import java.util.AbstractCollection;8import java.util.Arrays;9import java.util.Collection;10import java.util.ConcurrentModificationException;11import java.util.Iterator;12import java.util.LinkedList;13import java.util.List;14import java.util.NoSuchElementException;15import java.util.Queue;16import java.util.Stack;1718// BEGIN android-note19// removed link to collections framework docs20// END android-note2122/**23* Resizable-array implementation of the {@link Deque} interface. Array24* deques have no capacity restrictions; they grow as necessary to support25* usage. They are not thread-safe; in the absence of external26* synchronization, they do not support concurrent access by multiple threads.27* Null elements are prohibited. This class is likely to be faster than28* {@link Stack} when used as a stack, and faster than {@link LinkedList}29* when used as a queue.30*31* <p>Most <tt>ArrayDeque</tt> operations run in amortized constant time.32* Exceptions include {@link #remove(Object) remove}, {@link33* #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence34* removeLastOccurrence}, {@link #contains contains}, {@link #iterator35* iterator.remove()}, and the bulk operations, all of which run in linear36* time.37*38* <p>The iterators returned by this class's <tt>iterator</tt> method are39* <i>fail-fast</i>: If the deque is modified at any time after the iterator40* is created, in any way except through the iterator's own <tt>remove</tt>41* method, the iterator will generally throw a {@link42* ConcurrentModificationException}. Thus, in the face of concurrent43* modification, the iterator fails quickly and cleanly, rather than risking44* arbitrary, non-deterministic behavior at an undetermined time in the45* future.46*47* <p>Note that the fail-fast behavior of an iterator cannot be guaranteed48* as it is, generally speaking, impossible to make any hard guarantees in the49* presence of unsynchronized concurrent modification. Fail-fast iterators50* throw <tt>ConcurrentModificationException</tt> on a best-effort basis.51* Therefore, it would be wrong to write a program that depended on this52* exception for its correctness: <i>the fail-fast behavior of iterators53* should be used only to detect bugs.</i>54*55* <p>This class and its iterator implement all of the56* <em>optional</em> methods of the {@link Collection} and {@link57* Iterator} interfaces.58*59* @author Josh Bloch and Doug Lea60* @since 1.661* @param <E> the type of elements held in this collection62*/63public class ArrayDeque<E> extends AbstractCollection<E>64implements Deque<E>, Cloneable, java.io.Serializable65{66/**67* The array in which the elements of the deque are stored.68* The capacity of the deque is the length of this array, which is69* always a power of two. The array is never allowed to become70* full, except transiently within an addX method where it is71* resized (see doubleCapacity) immediately upon becoming full,72* thus avoiding head and tail wrapping around to equal each73* other. We also guarantee that all array cells not holding74* deque elements are always null.75*/76private transient Object[] elements;7778/**79* The index of the element at the head of the deque (which is the80* element that would be removed by remove() or pop()); or an81* arbitrary number equal to tail if the deque is empty.82*/83private transient int head;8485/**86* The index at which the next element would be added to the tail87* of the deque (via addLast(E), add(E), or push(E)).88*/89private transient int tail;9091/**92* The minimum capacity that we'll use for a newly created deque.93* Must be a power of 2.94*/95private static final int MIN_INITIAL_CAPACITY = 8;9697// ****** Array allocation and resizing utilities ******9899/**100* Allocate empty array to hold the given number of elements.101*102* @param numElements the number of elements to hold103*/104private void allocateElements(int numElements) {105int initialCapacity = MIN_INITIAL_CAPACITY;106// Find the best power of two to hold elements.107// Tests "<=" because arrays aren't kept full.108if (numElements >= initialCapacity) {109initialCapacity = numElements;110initialCapacity |= (initialCapacity >>> 1);111initialCapacity |= (initialCapacity >>> 2);112initialCapacity |= (initialCapacity >>> 4);113initialCapacity |= (initialCapacity >>> 8);114initialCapacity |= (initialCapacity >>> 16);115initialCapacity++;116117if (initialCapacity < 0) // Too many elements, must back off118initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements119}120elements = new Object[initialCapacity];121}122123/**124* Double the capacity of this deque. Call only when full, i.e.,125* when head and tail have wrapped around to become equal.126*/127private void doubleCapacity() {128// assert head == tail;129int p = head;130int n = elements.length;131int r = n - p; // number of elements to the right of p132int newCapacity = n << 1;133if (newCapacity < 0)134throw new IllegalStateException("Sorry, deque too big");135Object[] a = new Object[newCapacity];136System.arraycopy(elements, p, a, 0, r);137System.arraycopy(elements, 0, a, r, p);138elements = a;139head = 0;140tail = n;141}142143/**144* Copies the elements from our element array into the specified array,145* in order (from first to last element in the deque). It is assumed146* that the array is large enough to hold all elements in the deque.147*148* @return its argument149*/150private <T> T[] copyElements(T[] a) {151if (head < tail) {152System.arraycopy(elements, head, a, 0, size());153} else if (head > tail) {154int headPortionLen = elements.length - head;155System.arraycopy(elements, head, a, 0, headPortionLen);156System.arraycopy(elements, 0, a, headPortionLen, tail);157}158return a;159}160161/**162* Constructs an empty array deque with an initial capacity163* sufficient to hold 16 elements.164*/165public ArrayDeque() {166elements = new Object[16];167}168169/**170* Constructs an empty array deque with an initial capacity171* sufficient to hold the specified number of elements.172*173* @param numElements lower bound on initial capacity of the deque174*/175public ArrayDeque(int numElements) {176allocateElements(numElements);177}178179/**180* Constructs a deque containing the elements of the specified181* collection, in the order they are returned by the collection's182* iterator. (The first element returned by the collection's183* iterator becomes the first element, or <i>front</i> of the184* deque.)185*186* @param c the collection whose elements are to be placed into the deque187* @throws NullPointerException if the specified collection is null188*/189public ArrayDeque(Collection<? extends E> c) {190allocateElements(c.size());191addAll(c);192}193194// The main insertion and extraction methods are addFirst,195// addLast, pollFirst, pollLast. The other methods are defined in196// terms of these.197198/**199* Inserts the specified element at the front of this deque.200*201* @param e the element to add202* @throws NullPointerException if the specified element is null203*/204public void addFirst(E e) {205if (e == null)206throw new NullPointerException("e == null");207elements[head = (head - 1) & (elements.length - 1)] = e;208if (head == tail)209doubleCapacity();210}211212/**213* Inserts the specified element at the end of this deque.214*215* <p>This method is equivalent to {@link #add}.216*217* @param e the element to add218* @throws NullPointerException if the specified element is null219*/220public void addLast(E e) {221if (e == null)222throw new NullPointerException("e == null");223elements[tail] = e;224if ( (tail = (tail + 1) & (elements.length - 1)) == head)225doubleCapacity();226}227228/**229* Inserts the specified element at the front of this deque.230*231* @param e the element to add232* @return <tt>true</tt> (as specified by {@link Deque#offerFirst})233* @throws NullPointerException if the specified element is null234*/235public boolean offerFirst(E e) {236addFirst(e);237return true;238}239240/**241* Inserts the specified element at the end of this deque.242*243* @param e the element to add244* @return <tt>true</tt> (as specified by {@link Deque#offerLast})245* @throws NullPointerException if the specified element is null246*/247public boolean offerLast(E e) {248addLast(e);249return true;250}251252/**253* @throws NoSuchElementException {@inheritDoc}254*/255public E removeFirst() {256E x = pollFirst();257if (x == null)258throw new NoSuchElementException();259return x;260}261262/**263* @throws NoSuchElementException {@inheritDoc}264*/265public E removeLast() {266E x = pollLast();267if (x == null)268throw new NoSuchElementException();269return x;270}271272public E pollFirst() {273int h = head;274@SuppressWarnings("unchecked") E result = (E) elements[h];275// Element is null if deque empty276if (result == null)277return null;278elements[h] = null; // Must null out slot279head = (h + 1) & (elements.length - 1);280return result;281}282283public E pollLast() {284int t = (tail - 1) & (elements.length - 1);285@SuppressWarnings("unchecked") E result = (E) elements[t];286if (result == null)287return null;288elements[t] = null;289tail = t;290return result;291}292293/**294* @throws NoSuchElementException {@inheritDoc}295*/296public E getFirst() {297@SuppressWarnings("unchecked") E result = (E) elements[head];298if (result == null)299throw new NoSuchElementException();300return result;301}302303/**304* @throws NoSuchElementException {@inheritDoc}305*/306public E getLast() {307@SuppressWarnings("unchecked")308E result = (E) elements[(tail - 1) & (elements.length - 1)];309if (result == null)310throw new NoSuchElementException();311return result;312}313314public E peekFirst() {315@SuppressWarnings("unchecked") E result = (E) elements[head];316// elements[head] is null if deque empty317return result;318}319320public E peekLast() {321@SuppressWarnings("unchecked")322E result = (E) elements[(tail - 1) & (elements.length - 1)];323return result;324}325326/**327* Removes the first occurrence of the specified element in this328* deque (when traversing the deque from head to tail).329* If the deque does not contain the element, it is unchanged.330* More formally, removes the first element <tt>e</tt> such that331* <tt>o.equals(e)</tt> (if such an element exists).332* Returns <tt>true</tt> if this deque contained the specified element333* (or equivalently, if this deque changed as a result of the call).334*335* @param o element to be removed from this deque, if present336* @return <tt>true</tt> if the deque contained the specified element337*/338public boolean removeFirstOccurrence(Object o) {339if (o == null)340return false;341int mask = elements.length - 1;342int i = head;343Object x;344while ( (x = elements[i]) != null) {345if (o.equals(x)) {346delete(i);347return true;348}349i = (i + 1) & mask;350}351return false;352}353354/**355* Removes the last occurrence of the specified element in this356* deque (when traversing the deque from head to tail).357* If the deque does not contain the element, it is unchanged.358* More formally, removes the last element <tt>e</tt> such that359* <tt>o.equals(e)</tt> (if such an element exists).360* Returns <tt>true</tt> if this deque contained the specified element361* (or equivalently, if this deque changed as a result of the call).362*363* @param o element to be removed from this deque, if present364* @return <tt>true</tt> if the deque contained the specified element365*/366public boolean removeLastOccurrence(Object o) {367if (o == null)368return false;369int mask = elements.length - 1;370int i = (tail - 1) & mask;371Object x;372while ( (x = elements[i]) != null) {373if (o.equals(x)) {374delete(i);375return true;376}377i = (i - 1) & mask;378}379return false;380}381382// *** Queue methods ***383384/**385* Inserts the specified element at the end of this deque.386*387* <p>This method is equivalent to {@link #addLast}.388*389* @param e the element to add390* @return <tt>true</tt> (as specified by {@link Collection#add})391* @throws NullPointerException if the specified element is null392*/393public boolean add(E e) {394addLast(e);395return true;396}397398/**399* Inserts the specified element at the end of this deque.400*401* <p>This method is equivalent to {@link #offerLast}.402*403* @param e the element to add404* @return <tt>true</tt> (as specified by {@link Queue#offer})405* @throws NullPointerException if the specified element is null406*/407public boolean offer(E e) {408return offerLast(e);409}410411/**412* Retrieves and removes the head of the queue represented by this deque.413*414* This method differs from {@link #poll poll} only in that it throws an415* exception if this deque is empty.416*417* <p>This method is equivalent to {@link #removeFirst}.418*419* @return the head of the queue represented by this deque420* @throws NoSuchElementException {@inheritDoc}421*/422public E remove() {423return removeFirst();424}425426/**427* Retrieves and removes the head of the queue represented by this deque428* (in other words, the first element of this deque), or returns429* <tt>null</tt> if this deque is empty.430*431* <p>This method is equivalent to {@link #pollFirst}.432*433* @return the head of the queue represented by this deque, or434* <tt>null</tt> if this deque is empty435*/436public E poll() {437return pollFirst();438}439440/**441* Retrieves, but does not remove, the head of the queue represented by442* this deque. This method differs from {@link #peek peek} only in443* that it throws an exception if this deque is empty.444*445* <p>This method is equivalent to {@link #getFirst}.446*447* @return the head of the queue represented by this deque448* @throws NoSuchElementException {@inheritDoc}449*/450public E element() {451return getFirst();452}453454/**455* Retrieves, but does not remove, the head of the queue represented by456* this deque, or returns <tt>null</tt> if this deque is empty.457*458* <p>This method is equivalent to {@link #peekFirst}.459*460* @return the head of the queue represented by this deque, or461* <tt>null</tt> if this deque is empty462*/463public E peek() {464return peekFirst();465}466467// *** Stack methods ***468469/**470* Pushes an element onto the stack represented by this deque. In other471* words, inserts the element at the front of this deque.472*473* <p>This method is equivalent to {@link #addFirst}.474*475* @param e the element to push476* @throws NullPointerException if the specified element is null477*/478public void push(E e) {479addFirst(e);480}481482/**483* Pops an element from the stack represented by this deque. In other484* words, removes and returns the first element of this deque.485*486* <p>This method is equivalent to {@link #removeFirst()}.487*488* @return the element at the front of this deque (which is the top489* of the stack represented by this deque)490* @throws NoSuchElementException {@inheritDoc}491*/492public E pop() {493return removeFirst();494}495496private void checkInvariants() {497// assert elements[tail] == null;498// assert head == tail ? elements[head] == null :499// (elements[head] != null &&500// elements[(tail - 1) & (elements.length - 1)] != null);501// assert elements[(head - 1) & (elements.length - 1)] == null;502}503504/**505* Removes the element at the specified position in the elements array,506* adjusting head and tail as necessary. This can result in motion of507* elements backwards or forwards in the array.508*509* <p>This method is called delete rather than remove to emphasize510* that its semantics differ from those of {@link List#remove(int)}.511*512* @return true if elements moved backwards513*/514private boolean delete(int i) {515//checkInvariants();516final Object[] elements = this.elements;517final int mask = elements.length - 1;518final int h = head;519final int t = tail;520final int front = (i - h) & mask;521final int back = (t - i) & mask;522523// Invariant: head <= i < tail mod circularity524if (front >= ((t - h) & mask))525throw new ConcurrentModificationException();526527// Optimize for least element motion528if (front < back) {529if (h <= i) {530System.arraycopy(elements, h, elements, h + 1, front);531} else { // Wrap around532System.arraycopy(elements, 0, elements, 1, i);533elements[0] = elements[mask];534System.arraycopy(elements, h, elements, h + 1, mask - h);535}536elements[h] = null;537head = (h + 1) & mask;538return false;539} else {540if (i < t) { // Copy the null tail as well541System.arraycopy(elements, i + 1, elements, i, back);542tail = t - 1;543} else { // Wrap around544System.arraycopy(elements, i + 1, elements, i, mask - i);545elements[mask] = elements[0];546System.arraycopy(elements, 1, elements, 0, t);547tail = (t - 1) & mask;548}549return true;550}551}552553// *** Collection Methods ***554555/**556* Returns the number of elements in this deque.557*558* @return the number of elements in this deque559*/560public int size() {561return (tail - head) & (elements.length - 1);562}563564/**565* Returns <tt>true</tt> if this deque contains no elements.566*567* @return <tt>true</tt> if this deque contains no elements568*/569public boolean isEmpty() {570return head == tail;571}572573/**574* Returns an iterator over the elements in this deque. The elements575* will be ordered from first (head) to last (tail). This is the same576* order that elements would be dequeued (via successive calls to577* {@link #remove} or popped (via successive calls to {@link #pop}).578*579* @return an iterator over the elements in this deque580*/581public Iterator<E> iterator() {582return new DeqIterator();583}584585public Iterator<E> descendingIterator() {586return new DescendingIterator();587}588589private class DeqIterator implements Iterator<E> {590/**591* Index of element to be returned by subsequent call to next.592*/593private int cursor = head;594595/**596* Tail recorded at construction (also in remove), to stop597* iterator and also to check for comodification.598*/599private int fence = tail;600601/**602* Index of element returned by most recent call to next.603* Reset to -1 if element is deleted by a call to remove.604*/605private int lastRet = -1;606607public boolean hasNext() {608return cursor != fence;609}610611public E next() {612if (cursor == fence)613throw new NoSuchElementException();614@SuppressWarnings("unchecked") E result = (E) elements[cursor];615// This check doesn't catch all possible comodifications,616// but does catch the ones that corrupt traversal617if (tail != fence || result == null)618throw new ConcurrentModificationException();619lastRet = cursor;620cursor = (cursor + 1) & (elements.length - 1);621return result;622}623624public void remove() {625if (lastRet < 0)626throw new IllegalStateException();627if (delete(lastRet)) { // if left-shifted, undo increment in next()628cursor = (cursor - 1) & (elements.length - 1);629fence = tail;630}631lastRet = -1;632}633}634635private class DescendingIterator implements Iterator<E> {636/*637* This class is nearly a mirror-image of DeqIterator, using638* tail instead of head for initial cursor, and head instead of639* tail for fence.640*/641private int cursor = tail;642private int fence = head;643private int lastRet = -1;644645public boolean hasNext() {646return cursor != fence;647}648649public E next() {650if (cursor == fence)651throw new NoSuchElementException();652cursor = (cursor - 1) & (elements.length - 1);653@SuppressWarnings("unchecked") E result = (E) elements[cursor];654if (head != fence || result == null)655throw new ConcurrentModificationException();656lastRet = cursor;657return result;658}659660public void remove() {661if (lastRet < 0)662throw new IllegalStateException();663if (!delete(lastRet)) {664cursor = (cursor + 1) & (elements.length - 1);665fence = head;666}667lastRet = -1;668}669}670671/**672* Returns <tt>true</tt> if this deque contains the specified element.673* More formally, returns <tt>true</tt> if and only if this deque contains674* at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.675*676* @param o object to be checked for containment in this deque677* @return <tt>true</tt> if this deque contains the specified element678*/679public boolean contains(Object o) {680if (o == null)681return false;682int mask = elements.length - 1;683int i = head;684Object x;685while ( (x = elements[i]) != null) {686if (o.equals(x))687return true;688i = (i + 1) & mask;689}690return false;691}692693/**694* Removes a single instance of the specified element from this deque.695* If the deque does not contain the element, it is unchanged.696* More formally, removes the first element <tt>e</tt> such that697* <tt>o.equals(e)</tt> (if such an element exists).698* Returns <tt>true</tt> if this deque contained the specified element699* (or equivalently, if this deque changed as a result of the call).700*701* <p>This method is equivalent to {@link #removeFirstOccurrence}.702*703* @param o element to be removed from this deque, if present704* @return <tt>true</tt> if this deque contained the specified element705*/706public boolean remove(Object o) {707return removeFirstOccurrence(o);708}709710/**711* Removes all of the elements from this deque.712* The deque will be empty after this call returns.713*/714public void clear() {715int h = head;716int t = tail;717if (h != t) { // clear all cells718head = tail = 0;719int i = h;720int mask = elements.length - 1;721do {722elements[i] = null;723i = (i + 1) & mask;724} while (i != t);725}726}727728/**729* Returns an array containing all of the elements in this deque730* in proper sequence (from first to last element).731*732* <p>The returned array will be "safe" in that no references to it are733* maintained by this deque. (In other words, this method must allocate734* a new array). The caller is thus free to modify the returned array.735*736* <p>This method acts as bridge between array-based and collection-based737* APIs.738*739* @return an array containing all of the elements in this deque740*/741public Object[] toArray() {742return copyElements(new Object[size()]);743}744745/**746* Returns an array containing all of the elements in this deque in747* proper sequence (from first to last element); the runtime type of the748* returned array is that of the specified array. If the deque fits in749* the specified array, it is returned therein. Otherwise, a new array750* is allocated with the runtime type of the specified array and the751* size of this deque.752*753* <p>If this deque fits in the specified array with room to spare754* (i.e., the array has more elements than this deque), the element in755* the array immediately following the end of the deque is set to756* <tt>null</tt>.757*758* <p>Like the {@link #toArray()} method, this method acts as bridge between759* array-based and collection-based APIs. Further, this method allows760* precise control over the runtime type of the output array, and may,761* under certain circumstances, be used to save allocation costs.762*763* <p>Suppose <tt>x</tt> is a deque known to contain only strings.764* The following code can be used to dump the deque into a newly765* allocated array of <tt>String</tt>:766*767* <pre> {@code String[] y = x.toArray(new String[0]);}</pre>768*769* Note that <tt>toArray(new Object[0])</tt> is identical in function to770* <tt>toArray()</tt>.771*772* @param a the array into which the elements of the deque are to773* be stored, if it is big enough; otherwise, a new array of the774* same runtime type is allocated for this purpose775* @return an array containing all of the elements in this deque776* @throws ArrayStoreException if the runtime type of the specified array777* is not a supertype of the runtime type of every element in778* this deque779* @throws NullPointerException if the specified array is null780*/781@SuppressWarnings("unchecked")782public <T> T[] toArray(T[] a) {783int size = size();784if (a.length < size)785a = (T[])java.lang.reflect.Array.newInstance(786a.getClass().getComponentType(), size);787copyElements(a);788if (a.length > size)789a[size] = null;790return a;791}792793// *** Object methods ***794795/**796* Returns a copy of this deque.797*798* @return a copy of this deque799*/800public ArrayDeque<E> clone() {801try {802@SuppressWarnings("unchecked")803ArrayDeque<E> result = (ArrayDeque<E>) super.clone();804result.elements = Arrays.copyOf(elements, elements.length);805return result;806807} catch (CloneNotSupportedException e) {808throw new AssertionError();809}810}811812/**813* Appease the serialization gods.814*/815private static final long serialVersionUID = 2340985798034038923L;816817/**818* Serialize this deque.819*820* @serialData The current size (<tt>int</tt>) of the deque,821* followed by all of its elements (each an object reference) in822* first-to-last order.823*/824private void writeObject(java.io.ObjectOutputStream s)825throws java.io.IOException {826s.defaultWriteObject();827828// Write out size829s.writeInt(size());830831// Write out elements in order.832int mask = elements.length - 1;833for (int i = head; i != tail; i = (i + 1) & mask)834s.writeObject(elements[i]);835}836837/**838* Deserialize this deque.839*/840private void readObject(java.io.ObjectInputStream s)841throws java.io.IOException, ClassNotFoundException {842s.defaultReadObject();843844// Read in size and allocate array845int size = s.readInt();846allocateElements(size);847head = 0;848tail = size;849850// Read in all elements in the proper order.851for (int i = 0; i < size; i++)852elements[i] = s.readObject();853}854}855856857