ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/CopyOnWriteArrayList.java
Revision: 1.105
Committed: Thu May 2 06:00:07 2013 UTC (11 years, 1 month ago) by jsr166
Branch: MAIN
Changes since 1.104: +0 -1 lines
Log Message:
port to latest lambda

File Contents

# User Rev Content
1 dl 1.2 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3 dl 1.17 * Expert Group. Adapted and released, under explicit permission,
4 dl 1.15 * from JDK ArrayList.java which carries the following copyright:
5 dl 1.3 *
6     * Copyright 1997 by Sun Microsystems, Inc.,
7     * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
8     * All rights reserved.
9     *
10     * This software is the confidential and proprietary information
11     * of Sun Microsystems, Inc. ("Confidential Information"). You
12     * shall not disclose such Confidential Information and shall use
13     * it only in accordance with the terms of the license agreement
14     * you entered into with Sun.
15 dl 1.2 */
16    
17 tim 1.1 package java.util.concurrent;
18 dl 1.98 import java.util.AbstractList;
19 dl 1.93 import java.util.Arrays;
20     import java.util.Collection;
21 dl 1.98 import java.util.Collections;
22     import java.util.ConcurrentModificationException;
23     import java.util.Iterator;
24 dl 1.93 import java.util.List;
25     import java.util.ListIterator;
26 dl 1.98 import java.util.NoSuchElementException;
27 dl 1.93 import java.util.RandomAccess;
28     import java.util.Spliterator;
29 dl 1.99 import java.util.Spliterators;
30 dl 1.98 import java.util.concurrent.locks.ReentrantLock;
31     import java.util.function.Consumer;
32 dl 1.93 import java.util.stream.Stream;
33 tim 1.1
34     /**
35 dl 1.28 * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
36 jsr166 1.92 * operations ({@code add}, {@code set}, and so on) are implemented by
37 jsr166 1.35 * making a fresh copy of the underlying array.
38 tim 1.1 *
39 jsr166 1.91 * <p>This is ordinarily too costly, but may be <em>more</em> efficient
40 dl 1.12 * than alternatives when traversal operations vastly outnumber
41     * mutations, and is useful when you cannot or don't want to
42     * synchronize traversals, yet need to preclude interference among
43 dl 1.15 * concurrent threads. The "snapshot" style iterator method uses a
44     * reference to the state of the array at the point that the iterator
45     * was created. This array never changes during the lifetime of the
46     * iterator, so interference is impossible and the iterator is
47 jsr166 1.92 * guaranteed not to throw {@code ConcurrentModificationException}.
48 dl 1.15 * The iterator will not reflect additions, removals, or changes to
49     * the list since the iterator was created. Element-changing
50 jsr166 1.92 * operations on iterators themselves ({@code remove}, {@code set}, and
51     * {@code add}) are not supported. These methods throw
52     * {@code UnsupportedOperationException}.
53 dl 1.24 *
54 jsr166 1.92 * <p>All elements are permitted, including {@code null}.
55 jsr166 1.35 *
56 jsr166 1.56 * <p>Memory consistency effects: As with other concurrent
57     * collections, actions in a thread prior to placing an object into a
58     * {@code CopyOnWriteArrayList}
59     * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
60     * actions subsequent to the access or removal of that element from
61     * the {@code CopyOnWriteArrayList} in another thread.
62     *
63 dl 1.24 * <p>This class is a member of the
64 jsr166 1.64 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
65 dl 1.24 * Java Collections Framework</a>.
66     *
67 dl 1.6 * @since 1.5
68     * @author Doug Lea
69 dl 1.19 * @param <E> the type of elements held in this collection
70 dl 1.6 */
71 tim 1.1 public class CopyOnWriteArrayList<E>
72 dl 1.40 implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
73 dl 1.11 private static final long serialVersionUID = 8673264195747942595L;
74 tim 1.1
75 dl 1.42 /** The lock protecting all mutators */
76 jsr166 1.95 final transient ReentrantLock lock = new ReentrantLock();
77 dl 1.42
78 dl 1.40 /** The array, accessed only via getArray/setArray. */
79 jsr166 1.95 private transient volatile Object[] array;
80 tim 1.1
81 dl 1.57 /**
82 jsr166 1.60 * Gets the array. Non-private so as to also be accessible
83     * from CopyOnWriteArraySet class.
84 dl 1.57 */
85 jsr166 1.63 final Object[] getArray() {
86 jsr166 1.59 return array;
87 dl 1.57 }
88    
89     /**
90 jsr166 1.60 * Sets the array.
91 dl 1.57 */
92 jsr166 1.59 final void setArray(Object[] a) {
93     array = a;
94 dl 1.57 }
95 tim 1.1
96     /**
97 dl 1.15 * Creates an empty list.
98 tim 1.1 */
99     public CopyOnWriteArrayList() {
100 dl 1.41 setArray(new Object[0]);
101 tim 1.1 }
102    
103     /**
104 dl 1.15 * Creates a list containing the elements of the specified
105 jsr166 1.32 * collection, in the order they are returned by the collection's
106 tim 1.1 * iterator.
107 jsr166 1.32 *
108 dl 1.6 * @param c the collection of initially held elements
109 jsr166 1.35 * @throws NullPointerException if the specified collection is null
110 tim 1.1 */
111 tim 1.22 public CopyOnWriteArrayList(Collection<? extends E> c) {
112 jsr166 1.67 Object[] elements = c.toArray();
113     // c.toArray might (incorrectly) not return Object[] (see 6260652)
114     if (elements.getClass() != Object[].class)
115     elements = Arrays.copyOf(elements, elements.length, Object[].class);
116     setArray(elements);
117 tim 1.1 }
118    
119     /**
120 jsr166 1.35 * Creates a list holding a copy of the given array.
121 tim 1.9 *
122     * @param toCopyIn the array (a copy of this array is used as the
123     * internal array)
124 jsr166 1.38 * @throws NullPointerException if the specified array is null
125 jsr166 1.30 */
126 tim 1.1 public CopyOnWriteArrayList(E[] toCopyIn) {
127 jsr166 1.67 setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class));
128 tim 1.1 }
129    
130     /**
131 dl 1.15 * Returns the number of elements in this list.
132 tim 1.1 *
133 jsr166 1.35 * @return the number of elements in this list
134 tim 1.1 */
135     public int size() {
136 dl 1.40 return getArray().length;
137 tim 1.1 }
138    
139     /**
140 jsr166 1.92 * Returns {@code true} if this list contains no elements.
141 tim 1.1 *
142 jsr166 1.92 * @return {@code true} if this list contains no elements
143 tim 1.1 */
144     public boolean isEmpty() {
145     return size() == 0;
146     }
147    
148 dl 1.43 /**
149 jsr166 1.90 * Tests for equality, coping with nulls.
150 dl 1.43 */
151     private static boolean eq(Object o1, Object o2) {
152 jsr166 1.102 return (o1 == null) ? o2 == null : o1.equals(o2);
153 dl 1.43 }
154    
155 dl 1.41 /**
156 dl 1.40 * static version of indexOf, to allow repeated calls without
157 dl 1.41 * needing to re-acquire array each time.
158 dl 1.40 * @param o element to search for
159     * @param elements the array
160     * @param index first index to search
161     * @param fence one past last index to search
162     * @return index of element, or -1 if absent
163     */
164 dl 1.41 private static int indexOf(Object o, Object[] elements,
165 dl 1.40 int index, int fence) {
166     if (o == null) {
167     for (int i = index; i < fence; i++)
168     if (elements[i] == null)
169     return i;
170     } else {
171     for (int i = index; i < fence; i++)
172     if (o.equals(elements[i]))
173     return i;
174     }
175     return -1;
176     }
177 dl 1.41
178     /**
179 dl 1.40 * static version of lastIndexOf.
180     * @param o element to search for
181     * @param elements the array
182     * @param index first index to search
183     * @return index of element, or -1 if absent
184     */
185     private static int lastIndexOf(Object o, Object[] elements, int index) {
186     if (o == null) {
187     for (int i = index; i >= 0; i--)
188     if (elements[i] == null)
189     return i;
190     } else {
191     for (int i = index; i >= 0; i--)
192     if (o.equals(elements[i]))
193     return i;
194     }
195     return -1;
196     }
197    
198 tim 1.1 /**
199 jsr166 1.92 * Returns {@code true} if this list contains the specified element.
200     * More formally, returns {@code true} if and only if this list contains
201     * at least one element {@code e} such that
202 jsr166 1.35 * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
203 tim 1.1 *
204 jsr166 1.35 * @param o element whose presence in this list is to be tested
205 jsr166 1.92 * @return {@code true} if this list contains the specified element
206 tim 1.1 */
207 jsr166 1.35 public boolean contains(Object o) {
208 dl 1.41 Object[] elements = getArray();
209 dl 1.40 return indexOf(o, elements, 0, elements.length) >= 0;
210 tim 1.1 }
211    
212     /**
213 jsr166 1.35 * {@inheritDoc}
214 tim 1.1 */
215 jsr166 1.35 public int indexOf(Object o) {
216 dl 1.41 Object[] elements = getArray();
217 dl 1.40 return indexOf(o, elements, 0, elements.length);
218 tim 1.1 }
219    
220     /**
221 jsr166 1.35 * Returns the index of the first occurrence of the specified element in
222 jsr166 1.92 * this list, searching forwards from {@code index}, or returns -1 if
223 jsr166 1.35 * the element is not found.
224 jsr166 1.92 * More formally, returns the lowest index {@code i} such that
225 jsr166 1.35 * <tt>(i&nbsp;&gt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(e==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;e.equals(get(i))))</tt>,
226     * or -1 if there is no such index.
227     *
228     * @param e element to search for
229     * @param index index to start searching from
230     * @return the index of the first occurrence of the element in
231 jsr166 1.92 * this list at position {@code index} or later in the list;
232     * {@code -1} if the element is not found.
233 jsr166 1.35 * @throws IndexOutOfBoundsException if the specified index is negative
234 tim 1.1 */
235 jsr166 1.35 public int indexOf(E e, int index) {
236 dl 1.41 Object[] elements = getArray();
237 jsr166 1.67 return indexOf(e, elements, index, elements.length);
238 tim 1.1 }
239    
240     /**
241 jsr166 1.35 * {@inheritDoc}
242 tim 1.1 */
243 jsr166 1.35 public int lastIndexOf(Object o) {
244 dl 1.41 Object[] elements = getArray();
245 dl 1.40 return lastIndexOf(o, elements, elements.length - 1);
246 tim 1.1 }
247    
248     /**
249 jsr166 1.35 * Returns the index of the last occurrence of the specified element in
250 jsr166 1.92 * this list, searching backwards from {@code index}, or returns -1 if
251 jsr166 1.35 * the element is not found.
252 jsr166 1.92 * More formally, returns the highest index {@code i} such that
253 jsr166 1.35 * <tt>(i&nbsp;&lt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(e==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;e.equals(get(i))))</tt>,
254     * or -1 if there is no such index.
255     *
256     * @param e element to search for
257     * @param index index to start searching backwards from
258     * @return the index of the last occurrence of the element at position
259 jsr166 1.92 * less than or equal to {@code index} in this list;
260 jsr166 1.35 * -1 if the element is not found.
261     * @throws IndexOutOfBoundsException if the specified index is greater
262     * than or equal to the current size of this list
263 tim 1.1 */
264 jsr166 1.35 public int lastIndexOf(E e, int index) {
265 dl 1.41 Object[] elements = getArray();
266 jsr166 1.67 return lastIndexOf(e, elements, index);
267 tim 1.1 }
268    
269     /**
270     * Returns a shallow copy of this list. (The elements themselves
271     * are not copied.)
272     *
273 jsr166 1.35 * @return a clone of this list
274 tim 1.1 */
275     public Object clone() {
276     try {
277 jsr166 1.83 @SuppressWarnings("unchecked")
278     CopyOnWriteArrayList<E> clone =
279     (CopyOnWriteArrayList<E>) super.clone();
280     clone.resetLock();
281     return clone;
282 tim 1.1 } catch (CloneNotSupportedException e) {
283     // this shouldn't happen, since we are Cloneable
284     throw new InternalError();
285     }
286     }
287    
288     /**
289     * Returns an array containing all of the elements in this list
290 jsr166 1.35 * in proper sequence (from first to last element).
291     *
292     * <p>The returned array will be "safe" in that no references to it are
293     * maintained by this list. (In other words, this method must allocate
294     * a new array). The caller is thus free to modify the returned array.
295 jsr166 1.36 *
296 jsr166 1.35 * <p>This method acts as bridge between array-based and collection-based
297     * APIs.
298     *
299     * @return an array containing all the elements in this list
300 tim 1.1 */
301     public Object[] toArray() {
302 dl 1.40 Object[] elements = getArray();
303 jsr166 1.67 return Arrays.copyOf(elements, elements.length);
304 tim 1.1 }
305    
306     /**
307 jsr166 1.35 * Returns an array containing all of the elements in this list in
308     * proper sequence (from first to last element); the runtime type of
309     * the returned array is that of the specified array. If the list fits
310     * in the specified array, it is returned therein. Otherwise, a new
311     * array is allocated with the runtime type of the specified array and
312     * the size of this list.
313 jsr166 1.32 *
314     * <p>If this list fits in the specified array with room to spare
315 jsr166 1.35 * (i.e., the array has more elements than this list), the element in
316     * the array immediately following the end of the list is set to
317 jsr166 1.92 * {@code null}. (This is useful in determining the length of this
318 jsr166 1.35 * list <i>only</i> if the caller knows that this list does not contain
319     * any null elements.)
320     *
321     * <p>Like the {@link #toArray()} method, this method acts as bridge between
322     * array-based and collection-based APIs. Further, this method allows
323     * precise control over the runtime type of the output array, and may,
324     * under certain circumstances, be used to save allocation costs.
325     *
326 jsr166 1.92 * <p>Suppose {@code x} is a list known to contain only strings.
327 jsr166 1.35 * The following code can be used to dump the list into a newly
328 jsr166 1.92 * allocated array of {@code String}:
329 jsr166 1.35 *
330 jsr166 1.81 * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
331 jsr166 1.35 *
332 jsr166 1.92 * Note that {@code toArray(new Object[0])} is identical in function to
333     * {@code toArray()}.
334 tim 1.1 *
335     * @param a the array into which the elements of the list are to
336 jsr166 1.35 * be stored, if it is big enough; otherwise, a new array of the
337     * same runtime type is allocated for this purpose.
338     * @return an array containing all the elements in this list
339     * @throws ArrayStoreException if the runtime type of the specified array
340     * is not a supertype of the runtime type of every element in
341     * this list
342     * @throws NullPointerException if the specified array is null
343 tim 1.1 */
344 jsr166 1.66 @SuppressWarnings("unchecked")
345 tim 1.1 public <T> T[] toArray(T a[]) {
346 dl 1.41 Object[] elements = getArray();
347 dl 1.40 int len = elements.length;
348     if (a.length < len)
349 jsr166 1.67 return (T[]) Arrays.copyOf(elements, len, a.getClass());
350     else {
351     System.arraycopy(elements, 0, a, 0, len);
352     if (a.length > len)
353     a[len] = null;
354     return a;
355     }
356 tim 1.1 }
357    
358     // Positional Access Operations
359    
360 jsr166 1.66 @SuppressWarnings("unchecked")
361     private E get(Object[] a, int index) {
362 jsr166 1.67 return (E) a[index];
363 jsr166 1.66 }
364    
365 tim 1.1 /**
366 jsr166 1.35 * {@inheritDoc}
367 tim 1.1 *
368 jsr166 1.35 * @throws IndexOutOfBoundsException {@inheritDoc}
369 tim 1.1 */
370     public E get(int index) {
371 jsr166 1.66 return get(getArray(), index);
372 tim 1.1 }
373    
374     /**
375 jsr166 1.35 * Replaces the element at the specified position in this list with the
376     * specified element.
377 tim 1.1 *
378 jsr166 1.35 * @throws IndexOutOfBoundsException {@inheritDoc}
379 tim 1.1 */
380 dl 1.42 public E set(int index, E element) {
381 jsr166 1.67 final ReentrantLock lock = this.lock;
382     lock.lock();
383     try {
384     Object[] elements = getArray();
385     E oldValue = get(elements, index);
386    
387     if (oldValue != element) {
388     int len = elements.length;
389     Object[] newElements = Arrays.copyOf(elements, len);
390     newElements[index] = element;
391     setArray(newElements);
392     } else {
393     // Not quite a no-op; ensures volatile write semantics
394     setArray(elements);
395     }
396     return oldValue;
397     } finally {
398     lock.unlock();
399     }
400 tim 1.1 }
401    
402     /**
403     * Appends the specified element to the end of this list.
404     *
405 dl 1.40 * @param e element to be appended to this list
406 jsr166 1.92 * @return {@code true} (as specified by {@link Collection#add})
407 tim 1.1 */
408 dl 1.42 public boolean add(E e) {
409 jsr166 1.67 final ReentrantLock lock = this.lock;
410     lock.lock();
411     try {
412     Object[] elements = getArray();
413     int len = elements.length;
414     Object[] newElements = Arrays.copyOf(elements, len + 1);
415     newElements[len] = e;
416     setArray(newElements);
417     return true;
418     } finally {
419     lock.unlock();
420     }
421 tim 1.1 }
422    
423     /**
424     * Inserts the specified element at the specified position in this
425     * list. Shifts the element currently at that position (if any) and
426     * any subsequent elements to the right (adds one to their indices).
427     *
428 jsr166 1.35 * @throws IndexOutOfBoundsException {@inheritDoc}
429 tim 1.1 */
430 dl 1.42 public void add(int index, E element) {
431 jsr166 1.67 final ReentrantLock lock = this.lock;
432     lock.lock();
433     try {
434     Object[] elements = getArray();
435     int len = elements.length;
436     if (index > len || index < 0)
437     throw new IndexOutOfBoundsException("Index: "+index+
438     ", Size: "+len);
439     Object[] newElements;
440     int numMoved = len - index;
441     if (numMoved == 0)
442     newElements = Arrays.copyOf(elements, len + 1);
443     else {
444     newElements = new Object[len + 1];
445     System.arraycopy(elements, 0, newElements, 0, index);
446     System.arraycopy(elements, index, newElements, index + 1,
447     numMoved);
448     }
449     newElements[index] = element;
450     setArray(newElements);
451     } finally {
452     lock.unlock();
453     }
454 tim 1.1 }
455    
456     /**
457     * Removes the element at the specified position in this list.
458     * Shifts any subsequent elements to the left (subtracts one from their
459 jsr166 1.35 * indices). Returns the element that was removed from the list.
460 tim 1.1 *
461 jsr166 1.35 * @throws IndexOutOfBoundsException {@inheritDoc}
462 tim 1.1 */
463 dl 1.42 public E remove(int index) {
464 jsr166 1.67 final ReentrantLock lock = this.lock;
465     lock.lock();
466     try {
467     Object[] elements = getArray();
468     int len = elements.length;
469     E oldValue = get(elements, index);
470     int numMoved = len - index - 1;
471     if (numMoved == 0)
472     setArray(Arrays.copyOf(elements, len - 1));
473     else {
474     Object[] newElements = new Object[len - 1];
475     System.arraycopy(elements, 0, newElements, 0, index);
476     System.arraycopy(elements, index + 1, newElements, index,
477     numMoved);
478     setArray(newElements);
479     }
480     return oldValue;
481     } finally {
482     lock.unlock();
483     }
484 tim 1.1 }
485    
486     /**
487 jsr166 1.35 * Removes the first occurrence of the specified element from this list,
488     * if it is present. If this list does not contain the element, it is
489     * unchanged. More formally, removes the element with the lowest index
490 jsr166 1.92 * {@code i} such that
491 jsr166 1.35 * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
492 jsr166 1.92 * (if such an element exists). Returns {@code true} if this list
493 jsr166 1.35 * contained the specified element (or equivalently, if this list
494     * changed as a result of the call).
495 tim 1.1 *
496 jsr166 1.35 * @param o element to be removed from this list, if present
497 jsr166 1.92 * @return {@code true} if this list contained the specified element
498 tim 1.1 */
499 dl 1.42 public boolean remove(Object o) {
500 jsr166 1.104 Object[] snapshot = getArray();
501     int index = indexOf(o, snapshot, 0, snapshot.length);
502     return (index < 0) ? false : remove(o, snapshot, index);
503     }
504    
505     /**
506     * A version of remove(Object) using the strong hint that given
507     * recent snapshot contains o at the given index.
508     */
509     private boolean remove(Object o, Object[] snapshot, int index) {
510 jsr166 1.67 final ReentrantLock lock = this.lock;
511     lock.lock();
512     try {
513 jsr166 1.104 Object[] current = getArray();
514     int len = current.length;
515     if (snapshot != current) findIndex: {
516     int prefix = Math.min(index, len);
517     for (int i = 0; i < prefix; i++) {
518     if (current[i] != snapshot[i] && eq(o, current[i])) {
519     index = i;
520     break findIndex;
521     }
522 jsr166 1.67 }
523 jsr166 1.104 if (index >= len)
524     return false;
525     if (current[index] == o)
526     break findIndex;
527     index = indexOf(o, current, index, len);
528     if (index < 0)
529     return false;
530 jsr166 1.67 }
531 jsr166 1.104 Object[] newElements = new Object[len - 1];
532     System.arraycopy(current, 0, newElements, 0, index);
533     System.arraycopy(current, index + 1,
534     newElements, index,
535     len - index - 1);
536     setArray(newElements);
537     return true;
538 jsr166 1.67 } finally {
539     lock.unlock();
540     }
541 tim 1.1 }
542    
543     /**
544 jsr166 1.35 * Removes from this list all of the elements whose index is between
545 jsr166 1.92 * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
546 jsr166 1.35 * Shifts any succeeding elements to the left (reduces their index).
547 jsr166 1.92 * This call shortens the list by {@code (toIndex - fromIndex)} elements.
548     * (If {@code toIndex==fromIndex}, this operation has no effect.)
549 tim 1.1 *
550 jsr166 1.35 * @param fromIndex index of first element to be removed
551     * @param toIndex index after last element to be removed
552 jsr166 1.66 * @throws IndexOutOfBoundsException if fromIndex or toIndex out of range
553 jsr166 1.86 * ({@code fromIndex < 0 || toIndex > size() || toIndex < fromIndex})
554 tim 1.1 */
555 jsr166 1.84 void removeRange(int fromIndex, int toIndex) {
556 jsr166 1.67 final ReentrantLock lock = this.lock;
557     lock.lock();
558     try {
559     Object[] elements = getArray();
560     int len = elements.length;
561    
562     if (fromIndex < 0 || toIndex > len || toIndex < fromIndex)
563     throw new IndexOutOfBoundsException();
564     int newlen = len - (toIndex - fromIndex);
565     int numMoved = len - toIndex;
566     if (numMoved == 0)
567     setArray(Arrays.copyOf(elements, newlen));
568     else {
569     Object[] newElements = new Object[newlen];
570     System.arraycopy(elements, 0, newElements, 0, fromIndex);
571     System.arraycopy(elements, toIndex, newElements,
572     fromIndex, numMoved);
573     setArray(newElements);
574     }
575     } finally {
576     lock.unlock();
577     }
578 tim 1.1 }
579    
580     /**
581 jsr166 1.90 * Appends the element, if not present.
582 jsr166 1.38 *
583 dl 1.40 * @param e element to be added to this list, if absent
584 jsr166 1.92 * @return {@code true} if the element was added
585 jsr166 1.30 */
586 dl 1.42 public boolean addIfAbsent(E e) {
587 jsr166 1.104 Object[] snapshot = getArray();
588     return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
589     addIfAbsent(e, snapshot);
590     }
591    
592     /**
593     * A version of addIfAbsent using the strong hint that given
594     * recent snapshot does not contain e.
595     */
596     private boolean addIfAbsent(E e, Object[] snapshot) {
597 jsr166 1.67 final ReentrantLock lock = this.lock;
598     lock.lock();
599     try {
600 jsr166 1.104 Object[] current = getArray();
601     int len = current.length;
602     if (snapshot != current) {
603     // Optimize for lost race to another addXXX operation
604     int common = Math.min(snapshot.length, len);
605     for (int i = 0; i < common; i++)
606     if (current[i] != snapshot[i] && eq(e, current[i]))
607     return false;
608     if (indexOf(e, current, common, len) >= 0)
609     return false;
610 jsr166 1.67 }
611 jsr166 1.104 Object[] newElements = Arrays.copyOf(current, len + 1);
612 jsr166 1.67 newElements[len] = e;
613     setArray(newElements);
614     return true;
615     } finally {
616     lock.unlock();
617     }
618 tim 1.1 }
619    
620     /**
621 jsr166 1.92 * Returns {@code true} if this list contains all of the elements of the
622 jsr166 1.32 * specified collection.
623 jsr166 1.34 *
624 jsr166 1.36 * @param c collection to be checked for containment in this list
625 jsr166 1.92 * @return {@code true} if this list contains all of the elements of the
626 jsr166 1.35 * specified collection
627     * @throws NullPointerException if the specified collection is null
628 jsr166 1.38 * @see #contains(Object)
629 tim 1.1 */
630 tim 1.7 public boolean containsAll(Collection<?> c) {
631 dl 1.41 Object[] elements = getArray();
632 dl 1.40 int len = elements.length;
633 jsr166 1.67 for (Object e : c) {
634 dl 1.41 if (indexOf(e, elements, 0, len) < 0)
635 tim 1.1 return false;
636 jsr166 1.67 }
637 tim 1.1 return true;
638     }
639    
640     /**
641 jsr166 1.32 * Removes from this list all of its elements that are contained in
642     * the specified collection. This is a particularly expensive operation
643 tim 1.1 * in this class because of the need for an internal temporary array.
644     *
645 jsr166 1.35 * @param c collection containing elements to be removed from this list
646 jsr166 1.92 * @return {@code true} if this list changed as a result of the call
647 jsr166 1.38 * @throws ClassCastException if the class of an element of this list
648 dl 1.73 * is incompatible with the specified collection
649 dl 1.74 * (<a href="../Collection.html#optional-restrictions">optional</a>)
650 jsr166 1.38 * @throws NullPointerException if this list contains a null element and the
651 dl 1.73 * specified collection does not permit null elements
652 dl 1.75 * (<a href="../Collection.html#optional-restrictions">optional</a>),
653 jsr166 1.38 * or if the specified collection is null
654     * @see #remove(Object)
655 tim 1.1 */
656 dl 1.42 public boolean removeAll(Collection<?> c) {
657 dl 1.88 if (c == null) throw new NullPointerException();
658 jsr166 1.67 final ReentrantLock lock = this.lock;
659     lock.lock();
660     try {
661     Object[] elements = getArray();
662     int len = elements.length;
663     if (len != 0) {
664     // temp array holds those elements we know we want to keep
665     int newlen = 0;
666     Object[] temp = new Object[len];
667     for (int i = 0; i < len; ++i) {
668     Object element = elements[i];
669     if (!c.contains(element))
670     temp[newlen++] = element;
671     }
672     if (newlen != len) {
673     setArray(Arrays.copyOf(temp, newlen));
674     return true;
675     }
676     }
677     return false;
678     } finally {
679     lock.unlock();
680     }
681 tim 1.1 }
682    
683     /**
684 jsr166 1.32 * Retains only the elements in this list that are contained in the
685 jsr166 1.35 * specified collection. In other words, removes from this list all of
686     * its elements that are not contained in the specified collection.
687 jsr166 1.32 *
688 jsr166 1.35 * @param c collection containing elements to be retained in this list
689 jsr166 1.92 * @return {@code true} if this list changed as a result of the call
690 jsr166 1.38 * @throws ClassCastException if the class of an element of this list
691 dl 1.73 * is incompatible with the specified collection
692 dl 1.74 * (<a href="../Collection.html#optional-restrictions">optional</a>)
693 jsr166 1.38 * @throws NullPointerException if this list contains a null element and the
694 dl 1.73 * specified collection does not permit null elements
695 dl 1.75 * (<a href="../Collection.html#optional-restrictions">optional</a>),
696 jsr166 1.38 * or if the specified collection is null
697     * @see #remove(Object)
698 tim 1.1 */
699 dl 1.42 public boolean retainAll(Collection<?> c) {
700 dl 1.88 if (c == null) throw new NullPointerException();
701 jsr166 1.67 final ReentrantLock lock = this.lock;
702     lock.lock();
703     try {
704     Object[] elements = getArray();
705     int len = elements.length;
706     if (len != 0) {
707     // temp array holds those elements we know we want to keep
708     int newlen = 0;
709     Object[] temp = new Object[len];
710     for (int i = 0; i < len; ++i) {
711     Object element = elements[i];
712     if (c.contains(element))
713     temp[newlen++] = element;
714     }
715     if (newlen != len) {
716     setArray(Arrays.copyOf(temp, newlen));
717     return true;
718     }
719     }
720     return false;
721     } finally {
722     lock.unlock();
723     }
724 tim 1.1 }
725    
726     /**
727 jsr166 1.32 * Appends all of the elements in the specified collection that
728 tim 1.1 * are not already contained in this list, to the end of
729     * this list, in the order that they are returned by the
730 jsr166 1.32 * specified collection's iterator.
731 tim 1.1 *
732 jsr166 1.36 * @param c collection containing elements to be added to this list
733 tim 1.1 * @return the number of elements added
734 jsr166 1.35 * @throws NullPointerException if the specified collection is null
735 jsr166 1.38 * @see #addIfAbsent(Object)
736 tim 1.1 */
737 dl 1.42 public int addAllAbsent(Collection<? extends E> c) {
738 jsr166 1.67 Object[] cs = c.toArray();
739     if (cs.length == 0)
740     return 0;
741     final ReentrantLock lock = this.lock;
742     lock.lock();
743     try {
744     Object[] elements = getArray();
745     int len = elements.length;
746     int added = 0;
747 jsr166 1.103 // uniquify and compact elements in cs
748     for (int i = 0; i < cs.length; ++i) {
749 jsr166 1.67 Object e = cs[i];
750     if (indexOf(e, elements, 0, len) < 0 &&
751 jsr166 1.103 indexOf(e, cs, 0, added) < 0)
752     cs[added++] = e;
753 jsr166 1.67 }
754     if (added > 0) {
755     Object[] newElements = Arrays.copyOf(elements, len + added);
756 jsr166 1.103 System.arraycopy(cs, 0, newElements, len, added);
757 jsr166 1.67 setArray(newElements);
758     }
759     return added;
760     } finally {
761     lock.unlock();
762     }
763 tim 1.1 }
764    
765     /**
766     * Removes all of the elements from this list.
767 jsr166 1.38 * The list will be empty after this call returns.
768 tim 1.1 */
769 dl 1.42 public void clear() {
770 jsr166 1.67 final ReentrantLock lock = this.lock;
771     lock.lock();
772     try {
773     setArray(new Object[0]);
774     } finally {
775     lock.unlock();
776     }
777 tim 1.1 }
778    
779     /**
780 jsr166 1.32 * Appends all of the elements in the specified collection to the end
781     * of this list, in the order that they are returned by the specified
782     * collection's iterator.
783 tim 1.1 *
784 jsr166 1.36 * @param c collection containing elements to be added to this list
785 jsr166 1.92 * @return {@code true} if this list changed as a result of the call
786 jsr166 1.35 * @throws NullPointerException if the specified collection is null
787 jsr166 1.38 * @see #add(Object)
788 tim 1.1 */
789 dl 1.42 public boolean addAll(Collection<? extends E> c) {
790 jsr166 1.67 Object[] cs = c.toArray();
791     if (cs.length == 0)
792     return false;
793     final ReentrantLock lock = this.lock;
794     lock.lock();
795     try {
796     Object[] elements = getArray();
797     int len = elements.length;
798     Object[] newElements = Arrays.copyOf(elements, len + cs.length);
799     System.arraycopy(cs, 0, newElements, len, cs.length);
800     setArray(newElements);
801     return true;
802     } finally {
803     lock.unlock();
804     }
805 tim 1.1 }
806    
807     /**
808 jsr166 1.35 * Inserts all of the elements in the specified collection into this
809 tim 1.1 * list, starting at the specified position. Shifts the element
810     * currently at that position (if any) and any subsequent elements to
811     * the right (increases their indices). The new elements will appear
812 jsr166 1.38 * in this list in the order that they are returned by the
813     * specified collection's iterator.
814 tim 1.1 *
815 jsr166 1.35 * @param index index at which to insert the first element
816     * from the specified collection
817 jsr166 1.36 * @param c collection containing elements to be added to this list
818 jsr166 1.92 * @return {@code true} if this list changed as a result of the call
819 jsr166 1.35 * @throws IndexOutOfBoundsException {@inheritDoc}
820     * @throws NullPointerException if the specified collection is null
821 jsr166 1.38 * @see #add(int,Object)
822 tim 1.1 */
823 dl 1.42 public boolean addAll(int index, Collection<? extends E> c) {
824 jsr166 1.67 Object[] cs = c.toArray();
825     final ReentrantLock lock = this.lock;
826     lock.lock();
827     try {
828     Object[] elements = getArray();
829     int len = elements.length;
830     if (index > len || index < 0)
831     throw new IndexOutOfBoundsException("Index: "+index+
832     ", Size: "+len);
833     if (cs.length == 0)
834     return false;
835     int numMoved = len - index;
836     Object[] newElements;
837     if (numMoved == 0)
838     newElements = Arrays.copyOf(elements, len + cs.length);
839     else {
840     newElements = new Object[len + cs.length];
841     System.arraycopy(elements, 0, newElements, 0, index);
842     System.arraycopy(elements, index,
843     newElements, index + cs.length,
844     numMoved);
845     }
846     System.arraycopy(cs, 0, newElements, index, cs.length);
847     setArray(newElements);
848     return true;
849     } finally {
850     lock.unlock();
851     }
852 tim 1.1 }
853    
854     /**
855 jsr166 1.87 * Saves this list to a stream (that is, serializes it).
856 tim 1.1 *
857     * @serialData The length of the array backing the list is emitted
858     * (int), followed by all of its elements (each an Object)
859     * in the proper order.
860     */
861     private void writeObject(java.io.ObjectOutputStream s)
862 jsr166 1.85 throws java.io.IOException {
863 tim 1.1
864     s.defaultWriteObject();
865    
866 dl 1.41 Object[] elements = getArray();
867 tim 1.1 // Write out array length
868 jsr166 1.71 s.writeInt(elements.length);
869 tim 1.1
870     // Write out all elements in the proper order.
871 jsr166 1.71 for (Object element : elements)
872     s.writeObject(element);
873 tim 1.1 }
874    
875     /**
876 jsr166 1.87 * Reconstitutes this list from a stream (that is, deserializes it).
877 tim 1.1 */
878 dl 1.12 private void readObject(java.io.ObjectInputStream s)
879 tim 1.1 throws java.io.IOException, ClassNotFoundException {
880    
881     s.defaultReadObject();
882    
883 dl 1.42 // bind to new lock
884     resetLock();
885    
886 tim 1.1 // Read in array length and allocate array
887 dl 1.40 int len = s.readInt();
888 dl 1.41 Object[] elements = new Object[len];
889 tim 1.1
890     // Read in all elements in the proper order.
891 dl 1.40 for (int i = 0; i < len; i++)
892 dl 1.41 elements[i] = s.readObject();
893 dl 1.40 setArray(elements);
894 tim 1.1 }
895    
896     /**
897 jsr166 1.55 * Returns a string representation of this list. The string
898     * representation consists of the string representations of the list's
899     * elements in the order they are returned by its iterator, enclosed in
900 jsr166 1.92 * square brackets ({@code "[]"}). Adjacent elements are separated by
901     * the characters {@code ", "} (comma and space). Elements are
902 jsr166 1.55 * converted to strings as by {@link String#valueOf(Object)}.
903     *
904     * @return a string representation of this list
905 tim 1.1 */
906     public String toString() {
907 jsr166 1.67 return Arrays.toString(getArray());
908 tim 1.1 }
909    
910     /**
911 jsr166 1.35 * Compares the specified object with this list for equality.
912 jsr166 1.60 * Returns {@code true} if the specified object is the same object
913     * as this object, or if it is also a {@link List} and the sequence
914     * of elements returned by an {@linkplain List#iterator() iterator}
915     * over the specified list is the same as the sequence returned by
916     * an iterator over this list. The two sequences are considered to
917     * be the same if they have the same length and corresponding
918     * elements at the same position in the sequence are <em>equal</em>.
919     * Two elements {@code e1} and {@code e2} are considered
920     * <em>equal</em> if {@code (e1==null ? e2==null : e1.equals(e2))}.
921 tim 1.1 *
922 jsr166 1.35 * @param o the object to be compared for equality with this list
923 jsr166 1.60 * @return {@code true} if the specified object is equal to this list
924 tim 1.1 */
925     public boolean equals(Object o) {
926     if (o == this)
927     return true;
928     if (!(o instanceof List))
929     return false;
930    
931 dl 1.57 List<?> list = (List<?>)(o);
932 jsr166 1.67 Iterator<?> it = list.iterator();
933     Object[] elements = getArray();
934     int len = elements.length;
935 jsr166 1.60 for (int i = 0; i < len; ++i)
936     if (!it.hasNext() || !eq(elements[i], it.next()))
937 dl 1.57 return false;
938 jsr166 1.60 if (it.hasNext())
939 tim 1.1 return false;
940     return true;
941     }
942    
943     /**
944 jsr166 1.35 * Returns the hash code value for this list.
945 dl 1.26 *
946 jsr166 1.47 * <p>This implementation uses the definition in {@link List#hashCode}.
947     *
948     * @return the hash code value for this list
949 tim 1.1 */
950     public int hashCode() {
951     int hashCode = 1;
952 jsr166 1.67 Object[] elements = getArray();
953     int len = elements.length;
954     for (int i = 0; i < len; ++i) {
955     Object obj = elements[i];
956 jsr166 1.45 hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
957 tim 1.1 }
958     return hashCode;
959     }
960    
961     /**
962 jsr166 1.35 * Returns an iterator over the elements in this list in proper sequence.
963     *
964     * <p>The returned iterator provides a snapshot of the state of the list
965     * when the iterator was constructed. No synchronization is needed while
966     * traversing the iterator. The iterator does <em>NOT</em> support the
967 jsr166 1.92 * {@code remove} method.
968 jsr166 1.35 *
969     * @return an iterator over the elements in this list in proper sequence
970 tim 1.1 */
971     public Iterator<E> iterator() {
972 dl 1.40 return new COWIterator<E>(getArray(), 0);
973 tim 1.1 }
974    
975     /**
976 jsr166 1.35 * {@inheritDoc}
977 tim 1.1 *
978 jsr166 1.35 * <p>The returned iterator provides a snapshot of the state of the list
979     * when the iterator was constructed. No synchronization is needed while
980     * traversing the iterator. The iterator does <em>NOT</em> support the
981 jsr166 1.92 * {@code remove}, {@code set} or {@code add} methods.
982 tim 1.1 */
983     public ListIterator<E> listIterator() {
984 dl 1.40 return new COWIterator<E>(getArray(), 0);
985 tim 1.1 }
986    
987     /**
988 jsr166 1.35 * {@inheritDoc}
989     *
990 jsr166 1.50 * <p>The returned iterator provides a snapshot of the state of the list
991     * when the iterator was constructed. No synchronization is needed while
992     * traversing the iterator. The iterator does <em>NOT</em> support the
993 jsr166 1.92 * {@code remove}, {@code set} or {@code add} methods.
994 jsr166 1.35 *
995     * @throws IndexOutOfBoundsException {@inheritDoc}
996 tim 1.1 */
997     public ListIterator<E> listIterator(final int index) {
998 dl 1.41 Object[] elements = getArray();
999 dl 1.40 int len = elements.length;
1000 jsr166 1.45 if (index<0 || index>len)
1001     throw new IndexOutOfBoundsException("Index: "+index);
1002 tim 1.1
1003 dl 1.48 return new COWIterator<E>(elements, index);
1004 tim 1.1 }
1005    
1006 dl 1.100 public Spliterator<E> spliterator() {
1007 dl 1.99 return Spliterators.spliterator
1008 dl 1.98 (getArray(), Spliterator.IMMUTABLE | Spliterator.ORDERED);
1009     }
1010    
1011 dl 1.93 static final class COWIterator<E> implements ListIterator<E> {
1012 jsr166 1.68 /** Snapshot of the array */
1013 dl 1.41 private final Object[] snapshot;
1014 dl 1.40 /** Index of element to be returned by subsequent call to next. */
1015 tim 1.1 private int cursor;
1016    
1017 dl 1.41 private COWIterator(Object[] elements, int initialCursor) {
1018 tim 1.1 cursor = initialCursor;
1019 dl 1.40 snapshot = elements;
1020 tim 1.1 }
1021    
1022     public boolean hasNext() {
1023 dl 1.40 return cursor < snapshot.length;
1024 tim 1.1 }
1025    
1026     public boolean hasPrevious() {
1027     return cursor > 0;
1028     }
1029    
1030 jsr166 1.67 @SuppressWarnings("unchecked")
1031 tim 1.1 public E next() {
1032 jsr166 1.67 if (! hasNext())
1033 tim 1.1 throw new NoSuchElementException();
1034 jsr166 1.67 return (E) snapshot[cursor++];
1035 tim 1.1 }
1036    
1037 jsr166 1.67 @SuppressWarnings("unchecked")
1038 tim 1.1 public E previous() {
1039 jsr166 1.67 if (! hasPrevious())
1040 tim 1.1 throw new NoSuchElementException();
1041 jsr166 1.67 return (E) snapshot[--cursor];
1042 tim 1.1 }
1043    
1044     public int nextIndex() {
1045     return cursor;
1046     }
1047    
1048     public int previousIndex() {
1049 jsr166 1.45 return cursor-1;
1050 tim 1.1 }
1051    
1052     /**
1053     * Not supported. Always throws UnsupportedOperationException.
1054 jsr166 1.92 * @throws UnsupportedOperationException always; {@code remove}
1055 jsr166 1.32 * is not supported by this iterator.
1056 tim 1.1 */
1057     public void remove() {
1058     throw new UnsupportedOperationException();
1059     }
1060    
1061     /**
1062     * Not supported. Always throws UnsupportedOperationException.
1063 jsr166 1.92 * @throws UnsupportedOperationException always; {@code set}
1064 jsr166 1.32 * is not supported by this iterator.
1065 tim 1.1 */
1066 jsr166 1.33 public void set(E e) {
1067 tim 1.1 throw new UnsupportedOperationException();
1068     }
1069    
1070     /**
1071     * Not supported. Always throws UnsupportedOperationException.
1072 jsr166 1.92 * @throws UnsupportedOperationException always; {@code add}
1073 jsr166 1.32 * is not supported by this iterator.
1074 tim 1.1 */
1075 jsr166 1.33 public void add(E e) {
1076 tim 1.1 throw new UnsupportedOperationException();
1077     }
1078     }
1079    
1080     /**
1081 dl 1.40 * Returns a view of the portion of this list between
1082 jsr166 1.92 * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
1083 dl 1.40 * The returned list is backed by this list, so changes in the
1084 jsr166 1.66 * returned list are reflected in this list.
1085 dl 1.40 *
1086     * <p>The semantics of the list returned by this method become
1087 jsr166 1.66 * undefined if the backing list (i.e., this list) is modified in
1088     * any way other than via the returned list.
1089 tim 1.1 *
1090 jsr166 1.35 * @param fromIndex low endpoint (inclusive) of the subList
1091     * @param toIndex high endpoint (exclusive) of the subList
1092     * @return a view of the specified range within this list
1093     * @throws IndexOutOfBoundsException {@inheritDoc}
1094 tim 1.1 */
1095 dl 1.42 public List<E> subList(int fromIndex, int toIndex) {
1096 jsr166 1.67 final ReentrantLock lock = this.lock;
1097     lock.lock();
1098     try {
1099     Object[] elements = getArray();
1100     int len = elements.length;
1101     if (fromIndex < 0 || toIndex > len || fromIndex > toIndex)
1102     throw new IndexOutOfBoundsException();
1103     return new COWSubList<E>(this, fromIndex, toIndex);
1104     } finally {
1105     lock.unlock();
1106     }
1107 tim 1.1 }
1108    
1109 dl 1.42 /**
1110     * Sublist for CopyOnWriteArrayList.
1111     * This class extends AbstractList merely for convenience, to
1112     * avoid having to define addAll, etc. This doesn't hurt, but
1113     * is wasteful. This class does not need or use modCount
1114     * mechanics in AbstractList, but does need to check for
1115     * concurrent modification using similar mechanics. On each
1116     * operation, the array that we expect the backing list to use
1117     * is checked and updated. Since we do this for all of the
1118     * base operations invoked by those defined in AbstractList,
1119     * all is well. While inefficient, this is not worth
1120     * improving. The kinds of list operations inherited from
1121     * AbstractList are already so slow on COW sublists that
1122     * adding a bit more space/time doesn't seem even noticeable.
1123     */
1124 jsr166 1.66 private static class COWSubList<E>
1125 jsr166 1.67 extends AbstractList<E>
1126     implements RandomAccess
1127 jsr166 1.66 {
1128 tim 1.1 private final CopyOnWriteArrayList<E> l;
1129     private final int offset;
1130     private int size;
1131 dl 1.41 private Object[] expectedArray;
1132 tim 1.1
1133 jsr166 1.45 // only call this holding l's lock
1134 jsr166 1.66 COWSubList(CopyOnWriteArrayList<E> list,
1135 jsr166 1.67 int fromIndex, int toIndex) {
1136 tim 1.1 l = list;
1137 dl 1.40 expectedArray = l.getArray();
1138 tim 1.1 offset = fromIndex;
1139     size = toIndex - fromIndex;
1140     }
1141    
1142     // only call this holding l's lock
1143     private void checkForComodification() {
1144 dl 1.40 if (l.getArray() != expectedArray)
1145 tim 1.1 throw new ConcurrentModificationException();
1146     }
1147    
1148     // only call this holding l's lock
1149     private void rangeCheck(int index) {
1150 jsr166 1.45 if (index<0 || index>=size)
1151     throw new IndexOutOfBoundsException("Index: "+index+
1152 jsr166 1.67 ",Size: "+size);
1153 tim 1.1 }
1154    
1155     public E set(int index, E element) {
1156 jsr166 1.67 final ReentrantLock lock = l.lock;
1157     lock.lock();
1158     try {
1159 tim 1.1 rangeCheck(index);
1160     checkForComodification();
1161 jsr166 1.45 E x = l.set(index+offset, element);
1162 dl 1.40 expectedArray = l.getArray();
1163 tim 1.1 return x;
1164 jsr166 1.67 } finally {
1165     lock.unlock();
1166     }
1167 tim 1.1 }
1168    
1169     public E get(int index) {
1170 jsr166 1.67 final ReentrantLock lock = l.lock;
1171     lock.lock();
1172     try {
1173 tim 1.1 rangeCheck(index);
1174     checkForComodification();
1175 jsr166 1.45 return l.get(index+offset);
1176 jsr166 1.67 } finally {
1177     lock.unlock();
1178     }
1179 tim 1.1 }
1180    
1181     public int size() {
1182 jsr166 1.67 final ReentrantLock lock = l.lock;
1183     lock.lock();
1184     try {
1185 tim 1.1 checkForComodification();
1186     return size;
1187 jsr166 1.67 } finally {
1188     lock.unlock();
1189     }
1190 tim 1.1 }
1191    
1192     public void add(int index, E element) {
1193 jsr166 1.67 final ReentrantLock lock = l.lock;
1194     lock.lock();
1195     try {
1196 tim 1.1 checkForComodification();
1197     if (index<0 || index>size)
1198     throw new IndexOutOfBoundsException();
1199 jsr166 1.45 l.add(index+offset, element);
1200 dl 1.40 expectedArray = l.getArray();
1201 tim 1.1 size++;
1202 jsr166 1.67 } finally {
1203     lock.unlock();
1204     }
1205 tim 1.1 }
1206    
1207 dl 1.13 public void clear() {
1208 jsr166 1.67 final ReentrantLock lock = l.lock;
1209     lock.lock();
1210     try {
1211 dl 1.13 checkForComodification();
1212     l.removeRange(offset, offset+size);
1213 dl 1.40 expectedArray = l.getArray();
1214 dl 1.13 size = 0;
1215 jsr166 1.67 } finally {
1216     lock.unlock();
1217     }
1218 dl 1.13 }
1219    
1220 tim 1.1 public E remove(int index) {
1221 jsr166 1.67 final ReentrantLock lock = l.lock;
1222     lock.lock();
1223     try {
1224 tim 1.1 rangeCheck(index);
1225     checkForComodification();
1226 jsr166 1.45 E result = l.remove(index+offset);
1227 dl 1.40 expectedArray = l.getArray();
1228 tim 1.1 size--;
1229     return result;
1230 jsr166 1.67 } finally {
1231     lock.unlock();
1232     }
1233 tim 1.1 }
1234    
1235 jsr166 1.66 public boolean remove(Object o) {
1236 jsr166 1.67 int index = indexOf(o);
1237     if (index == -1)
1238     return false;
1239     remove(index);
1240     return true;
1241 jsr166 1.66 }
1242    
1243 tim 1.1 public Iterator<E> iterator() {
1244 jsr166 1.67 final ReentrantLock lock = l.lock;
1245     lock.lock();
1246     try {
1247 tim 1.1 checkForComodification();
1248 tim 1.8 return new COWSubListIterator<E>(l, 0, offset, size);
1249 jsr166 1.67 } finally {
1250     lock.unlock();
1251     }
1252 tim 1.1 }
1253    
1254     public ListIterator<E> listIterator(final int index) {
1255 jsr166 1.67 final ReentrantLock lock = l.lock;
1256     lock.lock();
1257     try {
1258 tim 1.1 checkForComodification();
1259     if (index<0 || index>size)
1260 dl 1.40 throw new IndexOutOfBoundsException("Index: "+index+
1261 jsr166 1.67 ", Size: "+size);
1262 tim 1.8 return new COWSubListIterator<E>(l, index, offset, size);
1263 jsr166 1.67 } finally {
1264     lock.unlock();
1265     }
1266 tim 1.1 }
1267    
1268 tim 1.7 public List<E> subList(int fromIndex, int toIndex) {
1269 jsr166 1.67 final ReentrantLock lock = l.lock;
1270     lock.lock();
1271     try {
1272 tim 1.7 checkForComodification();
1273     if (fromIndex<0 || toIndex>size)
1274     throw new IndexOutOfBoundsException();
1275 dl 1.41 return new COWSubList<E>(l, fromIndex + offset,
1276 jsr166 1.67 toIndex + offset);
1277     } finally {
1278     lock.unlock();
1279     }
1280 tim 1.7 }
1281 tim 1.1
1282 dl 1.100 public Spliterator<E> spliterator() {
1283 dl 1.93 int lo = offset;
1284     int hi = offset + size;
1285     Object[] a = expectedArray;
1286     if (l.getArray() != a)
1287     throw new ConcurrentModificationException();
1288     if (lo < 0 || hi > a.length)
1289     throw new IndexOutOfBoundsException();
1290 dl 1.99 return Spliterators.spliterator
1291 dl 1.98 (a, lo, hi, Spliterator.IMMUTABLE | Spliterator.ORDERED);
1292     }
1293    
1294 tim 1.7 }
1295 tim 1.1
1296 tim 1.7 private static class COWSubListIterator<E> implements ListIterator<E> {
1297 jsr166 1.80 private final ListIterator<E> it;
1298 tim 1.7 private final int offset;
1299     private final int size;
1300 jsr166 1.66
1301 jsr166 1.79 COWSubListIterator(List<E> l, int index, int offset, int size) {
1302 tim 1.7 this.offset = offset;
1303     this.size = size;
1304 jsr166 1.80 it = l.listIterator(index+offset);
1305 tim 1.7 }
1306 tim 1.1
1307 tim 1.7 public boolean hasNext() {
1308     return nextIndex() < size;
1309     }
1310 tim 1.1
1311 tim 1.7 public E next() {
1312     if (hasNext())
1313 jsr166 1.80 return it.next();
1314 tim 1.7 else
1315     throw new NoSuchElementException();
1316     }
1317 tim 1.1
1318 tim 1.7 public boolean hasPrevious() {
1319     return previousIndex() >= 0;
1320     }
1321 tim 1.1
1322 tim 1.7 public E previous() {
1323     if (hasPrevious())
1324 jsr166 1.80 return it.previous();
1325 tim 1.7 else
1326     throw new NoSuchElementException();
1327     }
1328 tim 1.1
1329 tim 1.7 public int nextIndex() {
1330 jsr166 1.80 return it.nextIndex() - offset;
1331 tim 1.7 }
1332 tim 1.1
1333 tim 1.7 public int previousIndex() {
1334 jsr166 1.80 return it.previousIndex() - offset;
1335 tim 1.1 }
1336    
1337 tim 1.7 public void remove() {
1338     throw new UnsupportedOperationException();
1339     }
1340 tim 1.1
1341 jsr166 1.33 public void set(E e) {
1342 tim 1.7 throw new UnsupportedOperationException();
1343 tim 1.1 }
1344    
1345 jsr166 1.33 public void add(E e) {
1346 tim 1.7 throw new UnsupportedOperationException();
1347     }
1348 tim 1.1 }
1349    
1350 dl 1.42 // Support for resetting lock while deserializing
1351 dl 1.72 private void resetLock() {
1352     UNSAFE.putObjectVolatile(this, lockOffset, new ReentrantLock());
1353     }
1354     private static final sun.misc.Unsafe UNSAFE;
1355 dl 1.42 private static final long lockOffset;
1356     static {
1357     try {
1358 dl 1.72 UNSAFE = sun.misc.Unsafe.getUnsafe();
1359 jsr166 1.76 Class<?> k = CopyOnWriteArrayList.class;
1360 dl 1.72 lockOffset = UNSAFE.objectFieldOffset
1361     (k.getDeclaredField("lock"));
1362     } catch (Exception e) {
1363     throw new Error(e);
1364     }
1365 dl 1.42 }
1366 tim 1.1 }