aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/java/util/concurrent
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2016-09-30 16:24:48 +0000
committerAndrew Haley <aph@gcc.gnu.org>2016-09-30 16:24:48 +0000
commit07b78716af6a9d7c9fd1e94d9baf94a52c873947 (patch)
tree3f22b3241c513ad168c8353805614ae1249410f4 /libjava/classpath/java/util/concurrent
parenteae993948bae8b788c53772bcb9217c063716f93 (diff)
downloadgcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.zip
gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.tar.gz
gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.tar.bz2
Makefile.def: Remove libjava.
2016-09-30 Andrew Haley <aph@redhat.com> * Makefile.def: Remove libjava. * Makefile.tpl: Likewise. * Makefile.in: Regenerate. * configure.ac: Likewise. * configure: Likewise. * gcc/java: Remove. * libjava: Likewise. From-SVN: r240662
Diffstat (limited to 'libjava/classpath/java/util/concurrent')
-rw-r--r--libjava/classpath/java/util/concurrent/CopyOnWriteArrayList.java1463
1 files changed, 0 insertions, 1463 deletions
diff --git a/libjava/classpath/java/util/concurrent/CopyOnWriteArrayList.java b/libjava/classpath/java/util/concurrent/CopyOnWriteArrayList.java
deleted file mode 100644
index f9f1ac1..0000000
--- a/libjava/classpath/java/util/concurrent/CopyOnWriteArrayList.java
+++ /dev/null
@@ -1,1463 +0,0 @@
-/* CopyOnWriteArrayList.java
- Copyright (C) 2006 Free Software Foundation
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath 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
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING. If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library. Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module. An independent module is a module which is not derived from
-or based on this library. If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so. If you do not wish to do so, delete this
-exception statement from your version. */
-
-package java.util.concurrent;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-
-import java.lang.reflect.Array;
-
-import java.util.AbstractList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-import java.util.RandomAccess;
-
-/**
- * A thread-safe implementation of an ArrayList. A CopyOnWriteArrayList is
- * as special ArrayList which performs copies of the underlying storage
- * each time a write (<code>remove</code>, <code>add</code> etc..) operation
- * is performed.<br />
- * <br />
- * The update operation in this class run usually in <code>O(n)</code> or worse,
- * but traversal operations are fast and efficient, especially when running in
- * a multi-thread environment without the need to design complex synchronize
- * mechanisms.<br />
- * <br />
- * <code>Iterator</code>s in this class work on a snapshot of the backing store
- * at the moment the iterator itself was created, hence the iterator will not
- * reflect changes in the underlying storage. Thus, update operation on the
- * <code>Iterator</code>s are not supported, but as interferences from other
- * threads are impossible, no <code>ConcurrentModificationException</code>
- * will be ever thrown from within the <code>Iterator</code>.
- * <br /><br />
- * This class is especially useful when used with event handling, like the
- * following code demonstrates:<br />
- * <code><pre>
- *
- * CopyOnWriteArrayList<EventListener> listeners =
- * new CopyOnWriteArrayList<EventListener>();
- *
- * [...]
- *
- * for (final EventListener listener : listeners)
- * {
- * Runnable dispatcher = new Runnable() {
- * public void run()
- * {
- * listener.preferenceChange(event);
- * }
- * };
- *
- * Executor executor = Executors.newSingleThreadExecutor();
- * executor.execute(dispatcher);
- * }
- * </pre></code>
- *
- * @since 1.5
- */
-public class CopyOnWriteArrayList<E>
- implements List<E>, RandomAccess, Cloneable, Serializable
-{
- /**
- *
- */
- private static final long serialVersionUID = 8673264195747942595L;
-
- /**
- * Where the data is stored.
- */
- private transient E[] data;
-
- /**
- * Construct a new ArrayList with the default capacity (16).
- */
- public CopyOnWriteArrayList()
- {
- data = (E[]) new Object[0];
- }
-
- /**
- * Construct a new ArrayList, and initialize it with the elements in the
- * supplied Collection. The initial capacity is 110% of the Collection's size.
- *
- * @param c
- * the collection whose elements will initialize this list
- * @throws NullPointerException
- * if c is null
- */
- public CopyOnWriteArrayList(Collection< ? extends E> c)
- {
- // FIXME ... correct? use c.toArray()
- data = (E[]) new Object[c.size()];
- int index = 0;
- for (E value : c)
- data[index++] = value;
- }
-
- /**
- * Construct a new ArrayList, and initialize it with the elements in the
- * supplied array.
- *
- * @param array
- * the array used to initialize this list
- * @throws NullPointerException
- * if array is null
- */
- public CopyOnWriteArrayList(E[] array)
- {
- data = (E[]) array.clone();
- }
-
- /**
- * Returns the number of elements in this list.
- *
- * @return the list size
- */
- public int size()
- {
- return data.length;
- }
-
- /**
- * Checks if the list is empty.
- *
- * @return true if there are no elements
- */
- public boolean isEmpty()
- {
- return data.length == 0;
- }
-
- /**
- * Returns true if element is in this ArrayList.
- *
- * @param e
- * the element whose inclusion in the List is being tested
- * @return true if the list contains e
- */
- public boolean contains(Object e)
- {
- return indexOf(e) != -1;
- }
-
- /**
- * Tests whether this collection contains all the elements in a given
- * collection. This implementation iterates over the given collection,
- * testing whether each element is contained in this collection. If any one
- * is not, false is returned. Otherwise true is returned.
- *
- * @param c the collection to test against
- * @return true if this collection contains all the elements in the given
- * collection
- * @throws NullPointerException if the given collection is null
- * @see #contains(Object)
- */
- public boolean containsAll(Collection<?> c)
- {
- Iterator<?> itr = c.iterator();
- int pos = c.size();
- while (--pos >= 0)
- if (!contains(itr.next()))
- return false;
- return true;
- }
-
- /**
- * Returns the lowest index at which element appears in this List, or -1 if it
- * does not appear.
- *
- * @param e
- * the element whose inclusion in the List is being tested
- * @return the index where e was found
- */
- public int indexOf(Object e)
- {
- E[] data = this.data;
- for (int i = 0; i < data.length; i++)
- if (equals(e, data[i]))
- return i;
- return -1;
- }
-
- /**
- * Return the lowest index greater equal <code>index</code> at which
- * <code>e</code> appears in this List, or -1 if it does not
- * appear.
- *
- * @param e the element whose inclusion in the list is being tested
- * @param index the index at which the search begins
- * @return the index where <code>e</code> was found
- */
- public int indexOf(E e, int index)
- {
- E[] data = this.data;
-
- for (int i = index; i < data.length; i++)
- if (equals(e, data[i]))
- return i;
- return -1;
- }
-
- /**
- * Returns the highest index at which element appears in this List, or -1 if
- * it does not appear.
- *
- * @param e
- * the element whose inclusion in the List is being tested
- * @return the index where e was found
- */
- public int lastIndexOf(Object e)
- {
- E[] data = this.data;
- for (int i = data.length - 1; i >= 0; i--)
- if (equals(e, data[i]))
- return i;
- return -1;
- }
-
- /**
- * Returns the highest index lesser equal <code>index</code> at
- * which <code>e</code> appears in this List, or -1 if it does not
- * appear.
- *
- * @param e the element whose inclusion in the list is being tested
- * @param index the index at which the search begins
- * @return the index where <code>e</code> was found
- */
- public int lastIndexOf(E e, int index)
- {
- E[] data = this.data;
-
- for (int i = index; i >= 0; i--)
- if (equals(e, data[i]))
- return i;
- return -1;
- }
-
- /**
- * Creates a shallow copy of this ArrayList (elements are not cloned).
- *
- * @return the cloned object
- */
- public Object clone()
- {
- CopyOnWriteArrayList<E> clone = null;
- try
- {
- clone = (CopyOnWriteArrayList<E>) super.clone();
- }
- catch (CloneNotSupportedException e)
- {
- // Impossible to get here.
- }
- return clone;
- }
-
- /**
- * Returns an Object array containing all of the elements in this ArrayList.
- * The array is independent of this list.
- *
- * @return an array representation of this list
- */
- public Object[] toArray()
- {
- E[] data = this.data;
- E[] array = (E[]) new Object[data.length];
- System.arraycopy(data, 0, array, 0, data.length);
- return array;
- }
-
- /**
- * Returns an Array whose component type is the runtime component type of the
- * passed-in Array. The returned Array is populated with all of the elements
- * in this ArrayList. If the passed-in Array is not large enough to store all
- * of the elements in this List, a new Array will be created and returned; if
- * the passed-in Array is <i>larger</i> than the size of this List, then
- * size() index will be set to null.
- *
- * @param a
- * the passed-in Array
- * @return an array representation of this list
- * @throws ArrayStoreException
- * if the runtime type of a does not allow an element in this list
- * @throws NullPointerException
- * if a is null
- */
- public <T> T[] toArray(T[] a)
- {
- E[] data = this.data;
- if (a.length < data.length)
- a = (T[]) Array.newInstance(a.getClass().getComponentType(), data.length);
- else if (a.length > data.length)
- a[data.length] = null;
- System.arraycopy(data, 0, a, 0, data.length);
- return a;
- }
-
- /**
- * Retrieves the element at the user-supplied index.
- *
- * @param index
- * the index of the element we are fetching
- * @throws IndexOutOfBoundsException
- * if index &lt; 0 || index &gt;= size()
- */
- public E get(int index)
- {
- return data[index];
- }
-
- /**
- * Sets the element at the specified index. The new element, e, can be an
- * object of any type or null.
- *
- * @param index
- * the index at which the element is being set
- * @param e
- * the element to be set
- * @return the element previously at the specified index
- * @throws IndexOutOfBoundsException
- * if index &lt; 0 || index &gt;= 0
- */
- public synchronized E set(int index, E e)
- {
- E result = data[index];
- E[] newData = (E[]) data.clone();
- newData[index] = e;
- data = newData;
- return result;
- }
-
- /**
- * Appends the supplied element to the end of this list. The element, e, can
- * be an object of any type or null.
- *
- * @param e
- * the element to be appended to this list
- * @return true, the add will always succeed
- */
- public synchronized boolean add(E e)
- {
- E[] data = this.data;
- E[] newData = (E[]) new Object[data.length + 1];
- System.arraycopy(data, 0, newData, 0, data.length);
- newData[data.length] = e;
- this.data = newData;
- return true;
- }
-
- /**
- * Adds the supplied element at the specified index, shifting all elements
- * currently at that index or higher one to the right. The element, e, can be
- * an object of any type or null.
- *
- * @param index
- * the index at which the element is being added
- * @param e
- * the item being added
- * @throws IndexOutOfBoundsException
- * if index &lt; 0 || index &gt; size()
- */
- public synchronized void add(int index, E e)
- {
- E[] data = this.data;
- E[] newData = (E[]) new Object[data.length + 1];
- System.arraycopy(data, 0, newData, 0, index);
- newData[index] = e;
- System.arraycopy(data, index, newData, index + 1, data.length - index);
- this.data = newData;
- }
-
- /**
- * Removes the element at the user-supplied index.
- *
- * @param index
- * the index of the element to be removed
- * @return the removed Object
- * @throws IndexOutOfBoundsException
- * if index &lt; 0 || index &gt;= size()
- */
- public synchronized E remove(int index)
- {
- if (index < 0 || index >= this.size())
- throw new IndexOutOfBoundsException("index = " + index);
-
- E[] snapshot = this.data;
- E[] newData = (E[]) new Object[snapshot.length - 1];
-
- E result = snapshot[index];
-
- if (index > 0)
- System.arraycopy(snapshot, 0, newData, 0, index);
-
- System.arraycopy(snapshot, index + 1, newData, index,
- snapshot.length - index - 1);
-
- this.data = newData;
-
- return result;
- }
-
- /**
- * Remove the first occurrence, if any, of the given object from this list,
- * returning <code>true</code> if the object was removed, <code>false</code>
- * otherwise.
- *
- * @param element the object to be removed.
- * @return true if element was removed, false otherwise. false means also that
- * the underlying storage was unchanged after this operation concluded.
- */
- public synchronized boolean remove(Object element)
- {
- E[] snapshot = this.data;
- int len = snapshot.length;
-
- if (len == 0)
- return false;
-
- E[] newData = (E[]) new Object[len - 1];
-
- // search the element to remove while filling the backup array
- // this way we can run this method in O(n)
- int elementIndex = -1;
- for (int i = 0; i < snapshot.length; i++)
- {
- if (equals(element, snapshot[i]))
- {
- elementIndex = i;
- break;
- }
-
- if (i < newData.length)
- newData[i] = snapshot[i];
- }
-
- if (elementIndex < 0)
- return false;
-
- System.arraycopy(snapshot, elementIndex + 1, newData, elementIndex,
- snapshot.length - elementIndex - 1);
- this.data = newData;
-
- return true;
- }
-
- /**
- * Removes all the elements contained in the given collection.
- * This method removes the elements that are contained in both
- * this list and in the given collection.
- *
- * @param c the collection containing the elements to be removed from this
- * list.
- * @return true if at least one element was removed, indicating that
- * the list internal storage changed as a result, false otherwise.
- */
- public synchronized boolean removeAll(Collection<?> c)
- {
- if (c.size() == 0)
- return false;
-
- E [] snapshot = this.data;
- E [] storage = (E[]) new Object[this.data.length];
- boolean changed = false;
-
- int length = 0;
- for (E element : snapshot)
- {
- // copy all the elements, including null values
- // if the collection can hold it
- // FIXME: slow operation
- if (c.contains(element))
- changed = true;
- else
- storage[length++] = element;
- }
-
- if (!changed)
- return false;
-
- E[] newData = (E[]) new Object[length];
- System.arraycopy(storage, 0, newData, 0, length);
-
- this.data = newData;
-
- return true;
- }
-
- /**
- * Removes all the elements that are not in the passed collection.
- * If the collection is void, this method has the same effect of
- * <code>clear()</code>.
- * Please, note that this method is extremely slow (unless the argument has
- * <code>size == 0</code>) and has bad performance is both space and time
- * usage.
- *
- * @param c the collection containing the elements to be retained by this
- * list.
- * @return true the list internal storage changed as a result of this
- * operation, false otherwise.
- */
- public synchronized boolean retainAll(Collection<?> c)
- {
- // if the given collection does not contain elements
- // we remove all the elements from our storage
- if (c.size() == 0)
- {
- this.clear();
- return true;
- }
-
- E [] snapshot = this.data;
- E [] storage = (E[]) new Object[this.data.length];
-
- int length = 0;
- for (E element : snapshot)
- {
- if (c.contains(element))
- storage[length++] = element;
- }
-
- // means we retained all the elements previously in our storage
- // we are running already slow here, but at least we avoid copying
- // another array and changing the internal storage
- if (length == snapshot.length)
- return false;
-
- E[] newData = (E[]) new Object[length];
- System.arraycopy(storage, 0, newData, 0, length);
-
- this.data = newData;
-
- return true;
- }
-
- /**
- * Removes all elements from this List
- */
- public synchronized void clear()
- {
- data = (E[]) new Object[0];
- }
-
- /**
- * Add each element in the supplied Collection to this List. It is undefined
- * what happens if you modify the list while this is taking place; for
- * example, if the collection contains this list. c can contain objects of any
- * type, as well as null values.
- *
- * @param c
- * a Collection containing elements to be added to this List
- * @return true if the list was modified, in other words c is not empty
- * @throws NullPointerException
- * if c is null
- */
- public synchronized boolean addAll(Collection< ? extends E> c)
- {
- return addAll(data.length, c);
- }
-
- /**
- * Add all elements in the supplied collection, inserting them beginning at
- * the specified index. c can contain objects of any type, as well as null
- * values.
- *
- * @param index
- * the index at which the elements will be inserted
- * @param c
- * the Collection containing the elements to be inserted
- * @throws IndexOutOfBoundsException
- * if index &lt; 0 || index &gt; 0
- * @throws NullPointerException
- * if c is null
- */
- public synchronized boolean addAll(int index, Collection< ? extends E> c)
- {
- if (index < 0 || index > this.size())
- throw new IndexOutOfBoundsException("index = " + index);
-
- int csize = c.size();
- if (csize == 0)
- return false;
-
- E[] data = this.data;
- Iterator<? extends E> itr = c.iterator();
-
- E[] newData = (E[]) new Object[data.length + csize];
-
- // avoid this call at all if we were asked to put the elements at the
- // beginning of our storage
- if (index != 0)
- System.arraycopy(data, 0, newData, 0, index);
-
- int itemsLeft = index;
-
- for (E value : c)
- newData[index++] = value;
-
- // now copy the remaining elements
- System.arraycopy(data, itemsLeft, newData, 0, data.length - itemsLeft);
-
- this.data = newData;
-
- return true;
- }
-
- /**
- * Adds an element if the list does not contains it already.
- *
- * @param val the element to add to the list.
- * @return true if the element was added, false otherwise.
- */
- public synchronized boolean addIfAbsent(E val)
- {
- if (contains(val))
- return false;
- add(val);
- return true;
- }
-
- /**
- * Adds all the element from the given collection that are not already
- * in this list.
- *
- * @param c the Collection containing the elements to be inserted
- * @return true the list internal storage changed as a result of this
- * operation, false otherwise.
- */
- public synchronized int addAllAbsent(Collection<? extends E> c)
- {
- int size = c.size();
- if (size == 0)
- return 0;
-
- E [] snapshot = this.data;
- E [] storage = (E[]) new Object[size];
-
- size = 0;
- for (E val : c)
- {
- if (!this.contains(val))
- storage[size++] = val;
- }
-
- if (size == 0)
- return 0;
-
- // append storage to data
- E [] newData = (E[]) new Object[snapshot.length + size];
-
- System.arraycopy(snapshot, 0, newData, 0, snapshot.length);
- System.arraycopy(storage, 0, newData, snapshot.length, size);
-
- this.data = newData;
-
- return size;
- }
-
- public String toString()
- {
- return Arrays.toString(this.data);
- }
-
- public boolean equals(Object o)
- {
- if (o == null)
- return false;
-
- if (this == o)
- return true;
-
- // let's see if 'o' is a list, if so, we need to compare the elements
- // as returned by the iterator
- if (o instanceof List)
- {
- List<?> source = (List<?>) o;
-
- if (source.size() != this.size())
- return false;
-
- Iterator<?> sourceIterator = source.iterator();
- for (E element : this)
- {
- if (!element.equals(sourceIterator.next()))
- return false;
- }
-
- return true;
- }
-
- return false;
- }
-
- public int hashCode()
- {
- // see http://java.sun.com/6/docs/api/java/util/List.html#hashcode()
- int hashcode = 1;
- for (E element : this)
- {
- hashcode = 31 * hashcode + (element == null ? 0 : element.hashCode());
- }
- return hashcode;
- }
-
- /**
- * Return an Iterator containing the elements of this list.
- * The Iterator uses a snapshot of the state of the internal storage
- * at the moment this method is called and does <strong>not</strong> support
- * update operations, so no synchronization is needed to traverse the
- * iterator.
- *
- * @return an Iterator containing the elements of this list in sequence.
- */
- public Iterator<E> iterator()
- {
- return new Iterator<E>()
- {
- E [] iteratorData = CopyOnWriteArrayList.this.data;
- int currentElement = 0;
-
- public boolean hasNext()
- {
- return (currentElement < iteratorData.length);
- }
-
- public E next()
- {
- return iteratorData[currentElement++];
- }
-
- public void remove()
- {
- throw new UnsupportedOperationException("updating of elements in " +
- "iterators is not supported " +
- "by this class");
- }
- };
- }
-
- /**
- * Return a ListIterator containing the elements of this list.
- * The Iterator uses a snapshot of the state of the internal storage
- * at the moment this method is called and does <strong>not</strong> support
- * update operations, so no synchronization is needed to traverse the
- * iterator.
- *
- * @return a ListIterator containing the elements of this list in sequence.
- */
- public ListIterator<E> listIterator()
- {
- return listIterator(0);
- }
-
- /**
- * Return a ListIterator over the elements of this list starting at
- * the specified index. An initial call to {@code next()} will thus
- * return the element at {@code index}, while an initial call to
- * {@code previous()} will return the element at {@code index-1}. The
- * Iterator uses a snapshot of the state of the internal storage
- * at the moment this method is called and does <strong>not</strong> support
- * update operations, so no synchronization is needed to traverse the
- * iterator.
- *
- * @param index the index at which to start iterating.
- * @return a ListIterator containing the elements of this list in sequence.
- */
- public ListIterator<E> listIterator(final int index)
- {
- if (index < 0 || index > size())
- throw new IndexOutOfBoundsException("Index: " + index + ", Size:"
- + size());
-
- return new ListIterator<E>()
- {
- E [] iteratorData = CopyOnWriteArrayList.this.data;
- int currentElement = index;
-
- public void add(E o)
- {
- throw new UnsupportedOperationException("updating of elements in " +
- "iterators is not supported " +
- "by this class");
- }
-
- public boolean hasNext()
- {
- return (currentElement < iteratorData.length);
- }
-
- public boolean hasPrevious()
- {
- return (currentElement > 0);
- }
-
- public E next()
- {
- if (hasNext() == false)
- throw new java.util.NoSuchElementException();
-
- return iteratorData[currentElement++];
- }
-
- public int nextIndex()
- {
- return (currentElement + 1);
- }
-
- public E previous()
- {
- if (hasPrevious() == false)
- throw new java.util.NoSuchElementException();
-
- return iteratorData[--currentElement];
- }
-
- public int previousIndex()
- {
- return (currentElement - 1);
- }
-
- public void remove()
- {
- throw new UnsupportedOperationException("updating of elements in " +
- "iterators is not supported " +
- "by this class");
- }
-
- public void set(E o)
- {
- throw new UnsupportedOperationException("updating of elements in " +
- "iterators is not supported " +
- "by this class");
- }
-
- };
- }
-
- /**
- * Obtain a List view of a subsection of this list, from fromIndex
- * (inclusive) to toIndex (exclusive). If the two indices are equal, the
- * sublist is empty. The returned list should be modifiable if and only
- * if this list is modifiable. Changes to the returned list should be
- * reflected in this list. If this list is structurally modified in
- * any way other than through the returned list, the result of any subsequent
- * operations on the returned list is undefined.
- * <p>
- *
- * This implementation returns a subclass of AbstractList. It stores, in
- * private fields, the offset and size of the sublist, and the expected
- * modCount of the backing list. If the backing list implements RandomAccess,
- * the sublist will also.
- * <p>
- *
- * The subclass's <code>set(int, Object)</code>, <code>get(int)</code>,
- * <code>add(int, Object)</code>, <code>remove(int)</code>,
- * <code>addAll(int, Collection)</code> and
- * <code>removeRange(int, int)</code> methods all delegate to the
- * corresponding methods on the backing abstract list, after
- * bounds-checking the index and adjusting for the offset. The
- * <code>addAll(Collection c)</code> method merely returns addAll(size, c).
- * The <code>listIterator(int)</code> method returns a "wrapper object"
- * over a list iterator on the backing list, which is created with the
- * corresponding method on the backing list. The <code>iterator()</code>
- * method merely returns listIterator(), and the <code>size()</code> method
- * merely returns the subclass's size field.
- * <p>
- *
- * All methods first check to see if the actual modCount of the backing
- * list is equal to its expected value, and throw a
- * ConcurrentModificationException if it is not.
- *
- * @param fromIndex the index that the returned list should start from
- * (inclusive)
- * @param toIndex the index that the returned list should go to (exclusive)
- * @return a List backed by a subsection of this list
- * @throws IndexOutOfBoundsException if fromIndex &lt; 0
- * || toIndex &gt; size()
- * @throws IndexOutOfBoundsException if fromIndex &gt; toIndex
- * @see ConcurrentModificationException
- * @see RandomAccess
- */
- public synchronized List<E> subList(int fromIndex, int toIndex)
- {
- // This follows the specification of AbstractList, but is inconsistent
- // with the one in List. Don't you love Sun's inconsistencies?
- if (fromIndex > toIndex)
- throw new IndexOutOfBoundsException(fromIndex + " > " + toIndex);
- if (fromIndex < 0 || toIndex > size())
- throw new IndexOutOfBoundsException();
-
- if (this instanceof RandomAccess)
- return new RandomAccessSubList<E>(this, fromIndex, toIndex);
- return new SubList<E>(this, fromIndex, toIndex);
- }
-
- /**
- * This class follows the implementation requirements set forth in
- * {@link AbstractList#subList(int, int)}. It matches Sun's implementation
- * by using a non-public top-level class in the same package.
- *
- * @author Original author unknown
- * @author Eric Blake (ebb9@email.byu.edu)
- */
- private static class SubList<E>
- extends AbstractList<E>
- {
- // Package visible, for use by iterator.
- /** The original list. */
- final CopyOnWriteArrayList<E> backingList;
- /** The index of the first element of the sublist. */
- final int offset;
- /** The size of the sublist. */
- int size;
- /** The backing data */
- E[] data;
-
- /**
- * Construct the sublist.
- *
- * @param backing the list this comes from
- * @param fromIndex the lower bound, inclusive
- * @param toIndex the upper bound, exclusive
- */
- SubList(CopyOnWriteArrayList<E> backing, int fromIndex, int toIndex)
- {
- backingList = backing;
- data = backing.data;
- offset = fromIndex;
- size = toIndex - fromIndex;
- }
-
- /**
- * This method checks the two modCount fields to ensure that there has
- * not been a concurrent modification, returning if all is okay.
- *
- * @throws ConcurrentModificationException if the backing list has been
- * modified externally to this sublist
- */
- // This can be inlined. Package visible, for use by iterator.
- void checkMod()
- {
- if (data != backingList.data)
- throw new ConcurrentModificationException();
- }
-
- /**
- * This method checks that a value is between 0 and size (inclusive). If
- * it is not, an exception is thrown.
- *
- * @param index the value to check
- * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
- */
- // This will get inlined, since it is private.
- private void checkBoundsInclusive(int index)
- {
- if (index < 0 || index > size)
- throw new IndexOutOfBoundsException("Index: " + index +
- ", Size:" + size);
- }
-
- /**
- * This method checks that a value is between 0 (inclusive) and size
- * (exclusive). If it is not, an exception is thrown.
- *
- * @param index the value to check
- * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
- */
- // This will get inlined, since it is private.
- private void checkBoundsExclusive(int index)
- {
- if (index < 0 || index >= size)
- throw new IndexOutOfBoundsException("Index: " + index +
- ", Size:" + size);
- }
-
- /**
- * Specified by AbstractList.subList to return the private field size.
- *
- * @return the sublist size
- * @throws ConcurrentModificationException if the backing list has been
- * modified externally to this sublist
- */
- public int size()
- {
- synchronized (backingList)
- {
- checkMod();
- return size;
- }
- }
-
- public void clear()
- {
- synchronized (backingList)
- {
- E[] snapshot = backingList.data;
- E[] newData = (E[]) new Object[snapshot.length - size];
-
- int toIndex = size + offset;
-
- System.arraycopy(snapshot, 0, newData, 0, offset);
- System.arraycopy(snapshot, toIndex, newData, offset,
- snapshot.length - toIndex);
-
- backingList.data = newData;
- this.data = backingList.data;
- this.size = 0;
- }
- }
-
- /**
- * Specified by AbstractList.subList to delegate to the backing list.
- *
- * @param index the location to modify
- * @param o the new value
- * @return the old value
- * @throws ConcurrentModificationException if the backing list has been
- * modified externally to this sublist
- * @throws UnsupportedOperationException if the backing list does not
- * support the set operation
- * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
- * @throws ClassCastException if o cannot be added to the backing list due
- * to its type
- * @throws IllegalArgumentException if o cannot be added to the backing list
- * for some other reason
- */
- public E set(int index, E o)
- {
- synchronized (backingList)
- {
- checkMod();
- checkBoundsExclusive(index);
-
- E el = backingList.set(index + offset, o);
- this.data = backingList.data;
-
- return el;
- }
- }
-
- /**
- * Specified by AbstractList.subList to delegate to the backing list.
- *
- * @param index the location to get from
- * @return the object at that location
- * @throws ConcurrentModificationException if the backing list has been
- * modified externally to this sublist
- * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
- */
- public E get(int index)
- {
- synchronized (backingList)
- {
- checkMod();
- checkBoundsExclusive(index);
-
- return backingList.get(index + offset);
- }
- }
-
- /**
- * Specified by AbstractList.subList to delegate to the backing list.
- *
- * @param index the index to insert at
- * @param o the object to add
- * @throws ConcurrentModificationException if the backing list has been
- * modified externally to this sublist
- * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
- * @throws UnsupportedOperationException if the backing list does not
- * support the add operation.
- * @throws ClassCastException if o cannot be added to the backing list due
- * to its type.
- * @throws IllegalArgumentException if o cannot be added to the backing
- * list for some other reason.
- */
- public void add(int index, E o)
- {
- synchronized (backingList)
- {
- checkMod();
- checkBoundsInclusive(index);
-
- backingList.add(index + offset, o);
-
- this.data = backingList.data;
- size++;
- }
- }
-
- /**
- * Specified by AbstractList.subList to delegate to the backing list.
- *
- * @param index the index to remove
- * @return the removed object
- * @throws ConcurrentModificationException if the backing list has been
- * modified externally to this sublist
- * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
- * @throws UnsupportedOperationException if the backing list does not
- * support the remove operation
- */
- public E remove(int index)
- {
- synchronized (backingList)
- {
- checkMod();
- checkBoundsExclusive(index);
- E o = backingList.remove(index + offset);
-
- this.data = backingList.data;
- size--;
-
- return o;
- }
- }
-
- /**
- * Specified by AbstractList.subList to delegate to the backing list.
- *
- * @param index the location to insert at
- * @param c the collection to insert
- * @return true if this list was modified, in other words, c is non-empty
- * @throws ConcurrentModificationException if the backing list has been
- * modified externally to this sublist
- * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
- * @throws UnsupportedOperationException if this list does not support the
- * addAll operation
- * @throws ClassCastException if some element of c cannot be added to this
- * list due to its type
- * @throws IllegalArgumentException if some element of c cannot be added
- * to this list for some other reason
- * @throws NullPointerException if the specified collection is null
- */
- public boolean addAll(int index, Collection<? extends E> c)
- {
- synchronized (backingList)
- {
- checkMod();
- checkBoundsInclusive(index);
- int csize = c.size();
- boolean result = backingList.addAll(offset + index, c);
-
- this.data = backingList.data;
- size += csize;
-
- return result;
- }
- }
-
- /**
- * Specified by AbstractList.subList to return addAll(size, c).
- *
- * @param c the collection to insert
- * @return true if this list was modified, in other words, c is non-empty
- * @throws ConcurrentModificationException if the backing list has been
- * modified externally to this sublist
- * @throws UnsupportedOperationException if this list does not support the
- * addAll operation
- * @throws ClassCastException if some element of c cannot be added to this
- * list due to its type
- * @throws IllegalArgumentException if some element of c cannot be added
- * to this list for some other reason
- * @throws NullPointerException if the specified collection is null
- */
- public boolean addAll(Collection<? extends E> c)
- {
- synchronized (backingList)
- {
- return addAll(size, c);
- }
- }
-
- /**
- * Specified by AbstractList.subList to return listIterator().
- *
- * @return an iterator over the sublist
- */
- public Iterator<E> iterator()
- {
- return listIterator();
- }
-
- /**
- * Specified by AbstractList.subList to return a wrapper around the
- * backing list's iterator.
- *
- * @param index the start location of the iterator
- * @return a list iterator over the sublist
- * @throws ConcurrentModificationException if the backing list has been
- * modified externally to this sublist
- * @throws IndexOutOfBoundsException if the value is out of range
- */
- public ListIterator<E> listIterator(final int index)
- {
- checkMod();
- checkBoundsInclusive(index);
-
- return new ListIterator<E>()
- {
- private final ListIterator<E> i =
- backingList.listIterator(index + offset);
- private int position = index;
-
- /**
- * Tests to see if there are any more objects to
- * return.
- *
- * @return True if the end of the list has not yet been
- * reached.
- */
- public boolean hasNext()
- {
- return position < size;
- }
-
- /**
- * Tests to see if there are objects prior to the
- * current position in the list.
- *
- * @return True if objects exist prior to the current
- * position of the iterator.
- */
- public boolean hasPrevious()
- {
- return position > 0;
- }
-
- /**
- * Retrieves the next object from the list.
- *
- * @return The next object.
- * @throws NoSuchElementException if there are no
- * more objects to retrieve.
- * @throws ConcurrentModificationException if the
- * list has been modified elsewhere.
- */
- public E next()
- {
- if (position == size)
- throw new NoSuchElementException();
- position++;
- return i.next();
- }
-
- /**
- * Retrieves the previous object from the list.
- *
- * @return The next object.
- * @throws NoSuchElementException if there are no
- * previous objects to retrieve.
- * @throws ConcurrentModificationException if the
- * list has been modified elsewhere.
- */
- public E previous()
- {
- if (position == 0)
- throw new NoSuchElementException();
- position--;
- return i.previous();
- }
-
- /**
- * Returns the index of the next element in the
- * list, which will be retrieved by <code>next()</code>
- *
- * @return The index of the next element.
- */
- public int nextIndex()
- {
- return i.nextIndex() - offset;
- }
-
- /**
- * Returns the index of the previous element in the
- * list, which will be retrieved by <code>previous()</code>
- *
- * @return The index of the previous element.
- */
- public int previousIndex()
- {
- return i.previousIndex() - offset;
- }
-
- /**
- * Removes the last object retrieved by <code>next()</code>
- * from the list, if the list supports object removal.
- *
- * @throws IllegalStateException if the iterator is positioned
- * before the start of the list or the last object has already
- * been removed.
- * @throws UnsupportedOperationException if the list does
- * not support removing elements.
- */
- public void remove()
- {
- throw new UnsupportedOperationException("Modification not supported " +
- "on CopyOnWriteArrayList iterators");
- }
-
- /**
- * Replaces the last object retrieved by <code>next()</code>
- * or <code>previous</code> with o, if the list supports object
- * replacement and an add or remove operation has not already
- * been performed.
- *
- * @throws IllegalStateException if the iterator is positioned
- * before the start of the list or the last object has already
- * been removed.
- * @throws UnsupportedOperationException if the list doesn't support
- * the addition or removal of elements.
- * @throws ClassCastException if the type of o is not a valid type
- * for this list.
- * @throws IllegalArgumentException if something else related to o
- * prevents its addition.
- * @throws ConcurrentModificationException if the list
- * has been modified elsewhere.
- */
- public void set(E o)
- {
- throw new UnsupportedOperationException("Modification not supported " +
- "on CopyOnWriteArrayList iterators");
- }
-
- /**
- * Adds the supplied object before the element that would be returned
- * by a call to <code>next()</code>, if the list supports addition.
- *
- * @param o The object to add to the list.
- * @throws UnsupportedOperationException if the list doesn't support
- * the addition of new elements.
- * @throws ClassCastException if the type of o is not a valid type
- * for this list.
- * @throws IllegalArgumentException if something else related to o
- * prevents its addition.
- * @throws ConcurrentModificationException if the list
- * has been modified elsewhere.
- */
- public void add(E o)
- {
- throw new UnsupportedOperationException("Modification not supported " +
- "on CopyOnWriteArrayList iterators");
- }
- };
- }
- } // class SubList
-
- /**
- * This class is a RandomAccess version of SubList, as required by
- * {@link AbstractList#subList(int, int)}.
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- */
- private static final class RandomAccessSubList<E> extends SubList<E>
- implements RandomAccess
- {
- /**
- * Construct the sublist.
- *
- * @param backing the list this comes from
- * @param fromIndex the lower bound, inclusive
- * @param toIndex the upper bound, exclusive
- */
- RandomAccessSubList(CopyOnWriteArrayList<E> backing, int fromIndex, int toIndex)
- {
- super(backing, fromIndex, toIndex);
- }
- } // class RandomAccessSubList
-
- /**
- * Serializes this object to the given stream.
- *
- * @param s
- * the stream to write to
- * @throws IOException
- * if the underlying stream fails
- * @serialData the size field (int), the length of the backing array (int),
- * followed by its elements (Objects) in proper order.
- */
- private void writeObject(ObjectOutputStream s) throws IOException
- {
- // The 'size' field.
- s.defaultWriteObject();
- // We serialize unused list entries to preserve capacity.
- int len = data.length;
- s.writeInt(len);
- // it would be more efficient to just write "size" items,
- // this need readObject read "size" items too.
- for (int i = 0; i < data.length; i++)
- s.writeObject(data[i]);
- }
-
- /**
- * Deserializes this object from the given stream.
- *
- * @param s
- * the stream to read from
- * @throws ClassNotFoundException
- * if the underlying stream fails
- * @throws IOException
- * if the underlying stream fails
- * @serialData the size field (int), the length of the backing array (int),
- * followed by its elements (Objects) in proper order.
- */
- private void readObject(ObjectInputStream s) throws IOException,
- ClassNotFoundException
- {
- // the `size' field.
- s.defaultReadObject();
- int capacity = s.readInt();
- data = (E[]) new Object[capacity];
- for (int i = 0; i < capacity; i++)
- data[i] = (E) s.readObject();
- }
-
- static final boolean equals(Object o1, Object o2)
- {
- return o1 == null ? o2 == null : o1.equals(o2);
- }
-
- Object[] getArray()
- {
- return data;
- }
-}