diff options
author | Andrew Haley <aph@redhat.com> | 2016-09-30 16:24:48 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2016-09-30 16:24:48 +0000 |
commit | 07b78716af6a9d7c9fd1e94d9baf94a52c873947 (patch) | |
tree | 3f22b3241c513ad168c8353805614ae1249410f4 /libjava/classpath/java/util/concurrent | |
parent | eae993948bae8b788c53772bcb9217c063716f93 (diff) | |
download | gcc-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.java | 1463 |
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 < 0 || index >= 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 < 0 || index >= 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 < 0 || index > 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 < 0 || index >= 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 < 0 || index > 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 < 0 - * || toIndex > size() - * @throws IndexOutOfBoundsException if fromIndex > 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 < 0 || index > 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 < 0 || index >= 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 < 0 || index >= 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 < 0 || index >= 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 < 0 || index > 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 < 0 || index >= 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 < 0 || index > 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; - } -} |