ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/extra/ReadMostlyVector.java
Revision: 1.23
Committed: Sat Dec 31 22:50:51 2011 UTC (12 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.22: +20 -30 lines
Log Message:
improve indexOf(Object, int) and lastIndexOf(Object, int)

File Contents

# User Rev Content
1 dl 1.1 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4     * http://creativecommons.org/publicdomain/zero/1.0/
5     */
6    
7     package jsr166e.extra;
8     import jsr166e.*;
9     import java.util.*;
10    
11     /**
12 dl 1.2 * A class with the same methods and array-based characteristics as
13     * {@link java.util.Vector} but with reduced contention and improved
14 dl 1.1 * throughput when invocations of read-only methods by multiple
15 jsr166 1.3 * threads are most common.
16 dl 1.1 *
17     * <p> The iterators returned by this class's {@link #iterator()
18     * iterator} and {@link #listIterator(int) listIterator} methods are
19     * best-effort in the presence of concurrent modifications, and do
20     * <em>NOT</em> throw {@link ConcurrentModificationException}. An
21     * iterator's {@code next()} method returns consecutive elements as
22 jsr166 1.13 * they appear in the underlying array upon each access. Alternatively,
23 dl 1.5 * method {@link #snapshotIterator} may be used for deterministic
24     * traversals, at the expense of making a copy, and unavailability of
25     * method {@code Iterator.remove}.
26 dl 1.1 *
27     * <p>Otherwise, this class supports all methods, under the same
28     * documented specifications, as {@code Vector}. Consult {@link
29     * java.util.Vector} for detailed specifications. Additionally, this
30     * class provides methods {@link #addIfAbsent} and {@link
31     * #addAllAbsent}.
32     *
33     * @author Doug Lea
34     */
35 jsr166 1.14 public class ReadMostlyVector<E>
36     implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
37 dl 1.1 private static final long serialVersionUID = 8673264195747942595L;
38    
39     /*
40     * This class exists mainly as a vehicle to exercise various
41 dl 1.2 * constructions using SequenceLocks. Read-only methods
42     * take one of a few forms:
43     *
44     * Short methods,including get(index), continually retry obtaining
45     * a snapshot of array, count, and element, using sequence number
46     * to validate.
47 jsr166 1.3 *
48 dl 1.2 * Methods that are potentially O(n) (or worse) try once in
49     * read-only mode, and then lock. When in read-only mode, they
50     * validate only at the end of an array scan unless the element is
51     * actually used (for example, as an argument of method equals).
52 jsr166 1.21 *
53     * We rely on some invariants that are always true, even for field
54     * reads in read-only mode that have not yet been validated:
55     * - array != null
56     * - count >= 0
57 dl 1.1 */
58    
59     /**
60     * The maximum size of array to allocate.
61     * See CopyOnWriteArrayList for explanation.
62     */
63     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
64    
65     // fields are non-private to simpify nested class access
66 dl 1.11 volatile Object[] array;
67 dl 1.1 final SequenceLock lock;
68 dl 1.11 volatile int count;
69 dl 1.1 final int capacityIncrement;
70    
71     /**
72     * Creates an empty vector with the given initial capacity and
73     * capacity increment.
74     *
75     * @param initialCapacity the initial capacity of the underlying array
76     * @param capacityIncrement if non-zero, the number to
77     * add when resizing to accommodate additional elements.
78     * If zero, the array size is doubled when resized.
79     *
80     * @throws IllegalArgumentException if initial capacity is negative
81     */
82     public ReadMostlyVector(int initialCapacity, int capacityIncrement) {
83     super();
84     if (initialCapacity < 0)
85     throw new IllegalArgumentException("Illegal Capacity: "+
86     initialCapacity);
87     this.array = new Object[initialCapacity];
88     this.capacityIncrement = capacityIncrement;
89     this.lock = new SequenceLock();
90     }
91    
92     /**
93     * Creates an empty vector with the given initial capacity.
94     *
95     * @param initialCapacity the initial capacity of the underlying array
96     *
97     * @throws IllegalArgumentException if initial capacity is negative
98     */
99     public ReadMostlyVector(int initialCapacity) {
100     this(initialCapacity, 0);
101     }
102    
103     /**
104     * Creates an empty vector with an underlying array of size {@code 10}.
105     */
106     public ReadMostlyVector() {
107     this(10, 0);
108     }
109    
110     /**
111     * Creates a vector containing the elements of the specified
112     * collection, in the order they are returned by the collection's
113     * iterator.
114     *
115     * @param c the collection of initially held elements
116     * @throws NullPointerException if the specified collection is null
117     */
118     public ReadMostlyVector(Collection<? extends E> c) {
119     Object[] elements = c.toArray();
120     // c.toArray might (incorrectly) not return Object[] (see 6260652)
121     if (elements.getClass() != Object[].class)
122     elements = Arrays.copyOf(elements, elements.length, Object[].class);
123     this.array = elements;
124     this.count = elements.length;
125     this.capacityIncrement = 0;
126     this.lock = new SequenceLock();
127     }
128    
129     // internal constructor for clone
130     ReadMostlyVector(Object[] array, int count, int capacityIncrement) {
131     this.array = array;
132     this.count = count;
133     this.capacityIncrement = capacityIncrement;
134     this.lock = new SequenceLock();
135     }
136    
137     // For explanation, see CopyOnWriteArrayList
138 dl 1.12 final Object[] grow(int minCapacity) {
139 dl 1.1 int oldCapacity = array.length;
140     int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
141     capacityIncrement : oldCapacity);
142     if (newCapacity - minCapacity < 0)
143     newCapacity = minCapacity;
144     if (newCapacity - MAX_ARRAY_SIZE > 0)
145     newCapacity = hugeCapacity(minCapacity);
146 dl 1.12 return array = Arrays.copyOf(array, newCapacity);
147 dl 1.1 }
148    
149     static int hugeCapacity(int minCapacity) {
150     if (minCapacity < 0) // overflow
151     throw new OutOfMemoryError();
152     return (minCapacity > MAX_ARRAY_SIZE) ?
153     Integer.MAX_VALUE :
154     MAX_ARRAY_SIZE;
155     }
156    
157     /*
158     * Internal versions of most base functionality, wrapped
159     * in different ways from public methods from this class
160     * as well as sublist and iterator classes.
161     */
162    
163 jsr166 1.23 /**
164     * Version of indexOf that returns -1 if either not present or invalid.
165     *
166     * @throws ArrayIndexOutOfBoundsException if index is negative
167     */
168 jsr166 1.3 final int validatedIndexOf(Object x, Object[] items, int index, int fence,
169 dl 1.2 long seq) {
170     for (int i = index; i < fence; ++i) {
171     Object e = items[i];
172     if (lock.getSequence() != seq)
173     break;
174 jsr166 1.6 if ((x == null) ? e == null : x.equals(e))
175 dl 1.2 return i;
176     }
177     return -1;
178     }
179    
180 jsr166 1.23 /**
181     * @throws ArrayIndexOutOfBoundsException if index is negative
182     */
183 dl 1.2 final int rawIndexOf(Object x, int index, int fence) {
184     Object[] items = array;
185 dl 1.1 for (int i = index; i < fence; ++i) {
186 dl 1.2 Object e = items[i];
187 jsr166 1.6 if ((x == null) ? e == null : x.equals(e))
188 dl 1.1 return i;
189     }
190     return -1;
191     }
192    
193 jsr166 1.3 final int validatedLastIndexOf(Object x, Object[] items,
194 dl 1.2 int index, int origin, long seq) {
195 dl 1.1 for (int i = index; i >= origin; --i) {
196 dl 1.2 Object e = items[i];
197     if (lock.getSequence() != seq)
198     break;
199 jsr166 1.6 if ((x == null) ? e == null : x.equals(e))
200 dl 1.1 return i;
201     }
202     return -1;
203     }
204    
205 dl 1.2 final int rawLastIndexOf(Object x, int index, int origin) {
206     Object[] items = array;
207     for (int i = index; i >= origin; --i) {
208     Object e = items[i];
209 jsr166 1.6 if ((x == null) ? e == null : x.equals(e))
210 dl 1.2 return i;
211     }
212     return -1;
213     }
214    
215 jsr166 1.14 final void rawAdd(E e) {
216 dl 1.2 int n = count;
217 dl 1.11 Object[] items = array;
218 dl 1.12 if (n >= items.length)
219     items = grow(n + 1);
220     items[n] = e;
221 dl 1.2 count = n + 1;
222 dl 1.1 }
223    
224 jsr166 1.14 final void rawAddAt(int index, E e) {
225 dl 1.2 int n = count;
226 dl 1.12 Object[] items = array;
227 dl 1.2 if (index > n)
228 dl 1.1 throw new ArrayIndexOutOfBoundsException(index);
229 dl 1.12 if (n >= items.length)
230     items = grow(n + 1);
231 dl 1.2 if (index < n)
232 dl 1.11 System.arraycopy(items, index, items, index + 1, n - index);
233     items[index] = e;
234 dl 1.2 count = n + 1;
235 dl 1.1 }
236    
237 dl 1.4 final boolean rawAddAllAt(int index, Object[] elements) {
238 dl 1.2 int n = count;
239 dl 1.12 Object[] items = array;
240 dl 1.2 if (index < 0 || index > n)
241 dl 1.1 throw new ArrayIndexOutOfBoundsException(index);
242     int len = elements.length;
243     if (len == 0)
244     return false;
245 dl 1.2 int newCount = n + len;
246 dl 1.12 if (newCount >= items.length)
247     items = grow(newCount);
248 dl 1.11 int mv = n - index;
249 dl 1.1 if (mv > 0)
250 dl 1.11 System.arraycopy(items, index, items, index + len, mv);
251     System.arraycopy(elements, 0, items, index, len);
252 dl 1.1 count = newCount;
253     return true;
254     }
255    
256 dl 1.4 final boolean rawRemoveAt(int index) {
257 dl 1.12 int n = count - 1;
258 dl 1.11 Object[] items = array;
259 dl 1.2 if (index < 0 || index > n)
260 dl 1.1 return false;
261 dl 1.2 int mv = n - index;
262 dl 1.1 if (mv > 0)
263 dl 1.11 System.arraycopy(items, index + 1, items, index, mv);
264     items[n] = null;
265 dl 1.2 count = n;
266 dl 1.1 return true;
267     }
268    
269     /**
270     * Internal version of removeAll for lists and sublists. In this
271 dl 1.2 * and other similar methods below, the bound argument is, if
272     * non-negative, the purported upper bound of a list/sublist, or
273     * is left negative if the bound should be determined via count
274     * field under lock.
275 dl 1.1 */
276 dl 1.2 final boolean internalRemoveAll(Collection<?> c, int origin, int bound) {
277 jsr166 1.14 final SequenceLock lock = this.lock;
278 dl 1.1 boolean removed = false;
279     lock.lock();
280     try {
281 dl 1.2 int n = count;
282     int fence = bound < 0 || bound > n ? n : bound;
283 dl 1.1 if (origin >= 0 && origin < fence) {
284     for (Object x : c) {
285 dl 1.4 while (rawRemoveAt(rawIndexOf(x, origin, fence)))
286 dl 1.1 removed = true;
287     }
288     }
289     } finally {
290     lock.unlock();
291     }
292     return removed;
293     }
294    
295 dl 1.2 final boolean internalRetainAll(Collection<?> c, int origin, int bound) {
296 jsr166 1.14 final SequenceLock lock = this.lock;
297 dl 1.1 boolean removed = false;
298     if (c != this) {
299     lock.lock();
300     try {
301 dl 1.11 Object[] items = array;
302 dl 1.1 int i = origin;
303 dl 1.2 int n = count;
304     int fence = bound < 0 || bound > n ? n : bound;
305 dl 1.4 while (i >= 0 && i < fence) {
306 dl 1.11 if (c.contains(items[i]))
307 dl 1.1 ++i;
308     else {
309     --fence;
310 dl 1.12 int mv = --n - i;
311 dl 1.1 if (mv > 0)
312 dl 1.11 System.arraycopy(items, i + 1, items, i, mv);
313 dl 1.1 }
314     }
315 dl 1.12 if (count != n) {
316     count = n;
317     removed = true;
318     }
319 dl 1.1 } finally {
320     lock.unlock();
321     }
322     }
323     return removed;
324     }
325    
326 dl 1.2 final void internalClear(int origin, int bound) {
327     int n = count;
328     int fence = bound < 0 || bound > n ? n : bound;
329 dl 1.1 if (origin >= 0 && origin < fence) {
330 dl 1.12 Object[] items = array;
331 dl 1.1 int removed = fence - origin;
332 dl 1.2 int newCount = n - removed;
333     int mv = n - (origin + removed);
334 dl 1.1 if (mv > 0)
335 dl 1.11 System.arraycopy(items, origin + removed, items, origin, mv);
336 dl 1.2 for (int i = n; i < newCount; ++i)
337 dl 1.11 items[i] = null;
338 dl 1.1 count = newCount;
339     }
340     }
341    
342 dl 1.2 final boolean internalContainsAll(Collection<?> c, int origin, int bound) {
343 jsr166 1.14 final SequenceLock lock = this.lock;
344 dl 1.1 boolean contained;
345     boolean locked = false;
346     try {
347     for (;;) {
348     long seq = lock.awaitAvailability();
349 dl 1.12 int n = count;
350 dl 1.1 Object[] items = array;
351     int len = items.length;
352 dl 1.2 if (n > len)
353 dl 1.1 continue;
354 dl 1.2 int fence = bound < 0 || bound > n ? n : bound;
355     if (origin < 0)
356 dl 1.1 contained = false;
357     else {
358     contained = true;
359 dl 1.2 for (Object e : c) {
360 jsr166 1.6 int idx = (locked ?
361 dl 1.4 rawIndexOf(e, origin, fence) :
362     validatedIndexOf(e, items, origin,
363     fence, seq));
364     if (idx < 0) {
365 dl 1.1 contained = false;
366     break;
367     }
368     }
369     }
370     if (lock.getSequence() == seq)
371     break;
372     lock.lock();
373     locked = true;
374     }
375     } finally {
376     if (locked)
377     lock.unlock();
378     }
379     return contained;
380     }
381    
382 dl 1.2 final boolean internalEquals(List<?> list, int origin, int bound) {
383 jsr166 1.14 final SequenceLock lock = this.lock;
384 dl 1.4 boolean locked = false;
385 dl 1.1 boolean equal;
386     try {
387 dl 1.4 for (;;) {
388 dl 1.1 long seq = lock.awaitAvailability();
389     Object[] items = array;
390 dl 1.2 int n = count;
391 dl 1.4 if (n > items.length || origin < 0)
392 dl 1.1 equal = false;
393     else {
394 dl 1.4 equal = true;
395     int fence = bound < 0 || bound > n ? n : bound;
396 dl 1.1 Iterator<?> it = list.iterator();
397     for (int i = origin; i < fence; ++i) {
398 dl 1.4 Object x = items[i];
399     Object y;
400     if ((!locked && lock.getSequence() != seq) ||
401     !it.hasNext() ||
402     (y = it.next()) == null ?
403     x != null : !y.equals(x)) {
404 dl 1.1 equal = false;
405     break;
406     }
407     }
408     if (equal && it.hasNext())
409     equal = false;
410     }
411     if (lock.getSequence() == seq)
412     break;
413     lock.lock();
414     locked = true;
415     }
416     } finally {
417     if (locked)
418     lock.unlock();
419     }
420     return equal;
421     }
422    
423 dl 1.2 final int internalHashCode(int origin, int bound) {
424 jsr166 1.14 final SequenceLock lock = this.lock;
425 dl 1.1 int hash;
426     boolean locked = false;
427     try {
428     for (;;) {
429     hash = 1;
430     long seq = lock.awaitAvailability();
431     Object[] items = array;
432 dl 1.12 int n = count;
433 dl 1.1 int len = items.length;
434 dl 1.2 if (n > len)
435 dl 1.1 continue;
436 dl 1.2 int fence = bound < 0 || bound > n ? n : bound;
437     if (origin >= 0) {
438 dl 1.1 for (int i = origin; i < fence; ++i) {
439     Object e = items[i];
440     hash = 31*hash + (e == null ? 0 : e.hashCode());
441     }
442     }
443     if (lock.getSequence() == seq)
444     break;
445     lock.lock();
446     locked = true;
447     }
448     } finally {
449     if (locked)
450     lock.unlock();
451     }
452     return hash;
453     }
454    
455 dl 1.2 final String internalToString(int origin, int bound) {
456 jsr166 1.14 final SequenceLock lock = this.lock;
457 dl 1.1 String ret;
458     boolean locked = false;
459     try {
460 dl 1.2 outer:for (;;) {
461 dl 1.1 long seq = lock.awaitAvailability();
462     Object[] items = array;
463 dl 1.12 int n = count;
464 dl 1.1 int len = items.length;
465 dl 1.2 if (n > len)
466 dl 1.1 continue;
467 dl 1.2 int fence = bound < 0 || bound > n ? n : bound;
468     if (origin < 0 || origin == fence)
469     ret = "[]";
470     else {
471     StringBuilder sb = new StringBuilder();
472     sb.append('[');
473     for (int i = origin;;) {
474     Object e = items[i];
475     if (e == this)
476     sb.append("(this Collection)");
477 dl 1.4 else if (!locked && lock.getSequence() != seq)
478 dl 1.2 continue outer;
479     else
480     sb.append(e.toString());
481     if (++i < fence)
482     sb.append(',').append(' ');
483     else {
484     ret = sb.append(']').toString();
485     break;
486 dl 1.1 }
487     }
488     }
489 dl 1.2 if (lock.getSequence() == seq)
490     break;
491 dl 1.1 lock.lock();
492     locked = true;
493     }
494     } finally {
495     if (locked)
496     lock.unlock();
497     }
498     return ret;
499     }
500    
501 dl 1.2 final Object[] internalToArray(int origin, int bound) {
502 dl 1.1 Object[] result;
503 jsr166 1.14 final SequenceLock lock = this.lock;
504 dl 1.1 boolean locked = false;
505     try {
506     for (;;) {
507     result = null;
508     long seq = lock.awaitAvailability();
509     Object[] items = array;
510 dl 1.12 int n = count;
511 dl 1.1 int len = items.length;
512 dl 1.2 if (n > len)
513     continue;
514     int fence = bound < 0 || bound > n ? n : bound;
515     if (origin >= 0)
516 dl 1.1 result = Arrays.copyOfRange(items, origin, fence,
517     Object[].class);
518 dl 1.2 if (lock.getSequence() == seq)
519     break;
520 dl 1.1 lock.lock();
521     locked = true;
522     }
523     } finally {
524     if (locked)
525     lock.unlock();
526     }
527     return result;
528     }
529    
530 jsr166 1.14 @SuppressWarnings("unchecked")
531 dl 1.2 final <T> T[] internalToArray(T[] a, int origin, int bound) {
532     int alen = a.length;
533 dl 1.1 T[] result;
534 jsr166 1.14 final SequenceLock lock = this.lock;
535 dl 1.1 boolean locked = false;
536     try {
537     for (;;) {
538     long seq = lock.awaitAvailability();
539     Object[] items = array;
540 dl 1.12 int n = count;
541 dl 1.1 int len = items.length;
542 dl 1.2 if (n > len)
543     continue;
544     int fence = bound < 0 || bound > n ? n : bound;
545     int rlen = fence - origin;
546 dl 1.4 if (rlen < 0)
547     rlen = 0;
548 dl 1.2 if (origin < 0 || alen >= rlen) {
549 dl 1.4 if (rlen > 0)
550 dl 1.11 System.arraycopy(items, 0, a, origin, rlen);
551 dl 1.2 if (alen > rlen)
552     a[rlen] = null;
553     result = a;
554 dl 1.1 }
555 jsr166 1.3 else
556 dl 1.11 result = (T[]) Arrays.copyOfRange(items, origin,
557 dl 1.2 fence, a.getClass());
558     if (lock.getSequence() == seq)
559     break;
560 dl 1.1 lock.lock();
561     locked = true;
562     }
563     } finally {
564     if (locked)
565     lock.unlock();
566     }
567     return result;
568     }
569    
570     // public List methods
571    
572     public boolean add(E e) {
573 jsr166 1.14 final SequenceLock lock = this.lock;
574 dl 1.1 lock.lock();
575     try {
576 dl 1.4 rawAdd(e);
577 dl 1.1 } finally {
578     lock.unlock();
579     }
580     return true;
581     }
582    
583     public void add(int index, E element) {
584 jsr166 1.14 final SequenceLock lock = this.lock;
585 dl 1.1 lock.lock();
586     try {
587 dl 1.4 rawAddAt(index, element);
588 dl 1.1 } finally {
589     lock.unlock();
590     }
591     }
592    
593     public boolean addAll(Collection<? extends E> c) {
594     Object[] elements = c.toArray();
595     int len = elements.length;
596     if (len == 0)
597     return false;
598 jsr166 1.14 final SequenceLock lock = this.lock;
599 dl 1.1 lock.lock();
600     try {
601 dl 1.12 Object[] items = array;
602     int n = count;
603     int newCount = n + len;
604     if (newCount >= items.length)
605     items = grow(newCount);
606     System.arraycopy(elements, 0, items, n, len);
607 dl 1.1 count = newCount;
608     } finally {
609     lock.unlock();
610     }
611     return true;
612     }
613    
614     public boolean addAll(int index, Collection<? extends E> c) {
615 jsr166 1.14 final SequenceLock lock = this.lock;
616 dl 1.1 boolean ret;
617     Object[] elements = c.toArray();
618     lock.lock();
619     try {
620 dl 1.4 ret = rawAddAllAt(index, elements);
621 dl 1.1 } finally {
622     lock.unlock();
623     }
624     return ret;
625     }
626    
627     public void clear() {
628 jsr166 1.14 final SequenceLock lock = this.lock;
629 dl 1.1 lock.lock();
630     try {
631 dl 1.12 int n = count;
632 dl 1.11 Object[] items = array;
633 dl 1.12 for (int i = 0; i < n; i++)
634 dl 1.11 items[i] = null;
635 dl 1.1 count = 0;
636     } finally {
637     lock.unlock();
638     }
639     }
640    
641     public boolean contains(Object o) {
642     return indexOf(o, 0) >= 0;
643     }
644    
645     public boolean containsAll(Collection<?> c) {
646     return internalContainsAll(c, 0, -1);
647     }
648    
649     public boolean equals(Object o) {
650     if (o == this)
651     return true;
652     if (!(o instanceof List))
653     return false;
654 dl 1.4 return internalEquals((List<?>)o, 0, -1);
655 dl 1.1 }
656    
657     public E get(int index) {
658 jsr166 1.14 final SequenceLock lock = this.lock;
659 dl 1.1 for (;;) {
660     long seq = lock.awaitAvailability();
661 dl 1.12 int n = count;
662 dl 1.1 Object[] items = array;
663 jsr166 1.14 @SuppressWarnings("unchecked")
664 jsr166 1.18 E e = (index < items.length) ? (E) items[index] : null;
665 dl 1.1 if (lock.getSequence() == seq) {
666 jsr166 1.18 if (index >= n)
667 dl 1.1 throw new ArrayIndexOutOfBoundsException(index);
668 jsr166 1.18 return e;
669 dl 1.1 }
670     }
671     }
672    
673     public int hashCode() {
674     return internalHashCode(0, -1);
675     }
676    
677     public int indexOf(Object o) {
678 jsr166 1.17 return indexOf(o, 0);
679 dl 1.1 }
680    
681     public boolean isEmpty() {
682     return count == 0;
683     }
684    
685     public Iterator<E> iterator() {
686 jsr166 1.10 return new Itr<E>(this, 0);
687 dl 1.1 }
688    
689     public int lastIndexOf(Object o) {
690 jsr166 1.14 final SequenceLock lock = this.lock;
691 dl 1.7 for (;;) {
692     long seq = lock.awaitAvailability();
693     Object[] items = array;
694     int n = count;
695 jsr166 1.8 if (n <= items.length) {
696 dl 1.7 for (int i = n - 1; i >= 0; --i) {
697     Object e = items[i];
698     if (lock.getSequence() != seq) {
699     lock.lock();
700     try {
701 jsr166 1.22 return rawLastIndexOf(o, count - 1, 0);
702 dl 1.7 } finally {
703     lock.unlock();
704     }
705     }
706     else if ((o == null) ? e == null : o.equals(e))
707     return i;
708     }
709     return -1;
710     }
711 dl 1.1 }
712     }
713    
714     public ListIterator<E> listIterator() {
715 jsr166 1.10 return new Itr<E>(this, 0);
716 dl 1.1 }
717    
718     public ListIterator<E> listIterator(int index) {
719 jsr166 1.10 return new Itr<E>(this, index);
720 dl 1.1 }
721    
722     public E remove(int index) {
723 jsr166 1.14 final SequenceLock lock = this.lock;
724 dl 1.1 lock.lock();
725     try {
726     if (index < 0 || index >= count)
727     throw new ArrayIndexOutOfBoundsException(index);
728 jsr166 1.14 @SuppressWarnings("unchecked")
729     E oldValue = (E) array[index];
730 dl 1.4 rawRemoveAt(index);
731 jsr166 1.14 return oldValue;
732 dl 1.1 } finally {
733     lock.unlock();
734     }
735     }
736    
737     public boolean remove(Object o) {
738 jsr166 1.14 final SequenceLock lock = this.lock;
739 dl 1.1 lock.lock();
740     try {
741 jsr166 1.14 return rawRemoveAt(rawIndexOf(o, 0, count));
742 dl 1.1 } finally {
743     lock.unlock();
744     }
745     }
746    
747     public boolean removeAll(Collection<?> c) {
748     return internalRemoveAll(c, 0, -1);
749     }
750    
751     public boolean retainAll(Collection<?> c) {
752     return internalRetainAll(c, 0, -1);
753     }
754    
755     public E set(int index, E element) {
756 jsr166 1.14 final SequenceLock lock = this.lock;
757 dl 1.1 lock.lock();
758     try {
759 dl 1.11 Object[] items = array;
760 dl 1.1 if (index < 0 || index >= count)
761     throw new ArrayIndexOutOfBoundsException(index);
762 jsr166 1.14 @SuppressWarnings("unchecked")
763     E oldValue = (E) items[index];
764 dl 1.11 items[index] = element;
765 jsr166 1.14 return oldValue;
766 dl 1.1 } finally {
767     lock.unlock();
768     }
769     }
770    
771     public int size() {
772     return count;
773     }
774    
775     public List<E> subList(int fromIndex, int toIndex) {
776     int c = size();
777     int ssize = toIndex - fromIndex;
778     if (fromIndex < 0 || toIndex > c || ssize < 0)
779     throw new IndexOutOfBoundsException();
780 jsr166 1.10 return new ReadMostlyVectorSublist<E>(this, fromIndex, ssize);
781 dl 1.1 }
782    
783     public Object[] toArray() {
784     return internalToArray(0, -1);
785     }
786    
787     public <T> T[] toArray(T[] a) {
788     return internalToArray(a, 0, -1);
789     }
790    
791     public String toString() {
792     return internalToString(0, -1);
793     }
794    
795     // ReadMostlyVector-only methods
796    
797     /**
798     * Append the element if not present.
799     *
800     * @param e element to be added to this list, if absent
801 jsr166 1.9 * @return {@code true} if the element was added
802 dl 1.1 */
803     public boolean addIfAbsent(E e) {
804 jsr166 1.14 final SequenceLock lock = this.lock;
805 dl 1.1 lock.lock();
806     try {
807 dl 1.2 if (rawIndexOf(e, 0, count) < 0) {
808 dl 1.4 rawAdd(e);
809 jsr166 1.14 return true;
810 dl 1.1 }
811     else
812 jsr166 1.14 return false;
813 dl 1.1 } finally {
814     lock.unlock();
815     }
816     }
817    
818     /**
819     * Appends all of the elements in the specified collection that
820     * are not already contained in this list, to the end of
821     * this list, in the order that they are returned by the
822     * specified collection's iterator.
823     *
824     * @param c collection containing elements to be added to this list
825     * @return the number of elements added
826     * @throws NullPointerException if the specified collection is null
827     * @see #addIfAbsent(Object)
828     */
829     public int addAllAbsent(Collection<? extends E> c) {
830     int added = 0;
831     Object[] cs = c.toArray();
832     int clen = cs.length;
833     if (clen != 0) {
834     lock.lock();
835     try {
836     for (int i = 0; i < clen; ++i) {
837 jsr166 1.14 @SuppressWarnings("unchecked")
838     E e = (E) cs[i];
839 dl 1.2 if (rawIndexOf(e, 0, count) < 0) {
840 dl 1.4 rawAdd(e);
841 dl 1.1 ++added;
842     }
843     }
844     } finally {
845     lock.unlock();
846     }
847     }
848     return added;
849     }
850    
851 dl 1.5 /**
852     * Returns an iterator operating over a snapshot copy of the
853     * elements of this collection created upon construction of the
854     * iterator. The iterator does <em>NOT</em> support the
855 jsr166 1.9 * {@code remove} method.
856 dl 1.5 *
857     * @return an iterator over the elements in this list in proper sequence
858     */
859     public Iterator<E> snapshotIterator() {
860     return new SnapshotIterator<E>(this);
861     }
862    
863     static final class SnapshotIterator<E> implements Iterator<E> {
864 jsr166 1.14 private final Object[] items;
865     private int cursor;
866 dl 1.5 SnapshotIterator(ReadMostlyVector<E> v) { items = v.toArray(); }
867     public boolean hasNext() { return cursor < items.length; }
868 jsr166 1.14 @SuppressWarnings("unchecked")
869 dl 1.5 public E next() {
870     if (cursor < items.length)
871     return (E) items[cursor++];
872     throw new NoSuchElementException();
873     }
874     public void remove() { throw new UnsupportedOperationException() ; }
875     }
876    
877 dl 1.1 // Vector-only methods
878    
879     /** See {@link Vector#firstElement} */
880     public E firstElement() {
881 jsr166 1.14 final SequenceLock lock = this.lock;
882 dl 1.1 for (;;) {
883     long seq = lock.awaitAvailability();
884     Object[] items = array;
885 dl 1.2 int n = count;
886 jsr166 1.14 @SuppressWarnings("unchecked")
887 jsr166 1.19 E e = (items.length > 0) ? (E) items[0] : null;
888 dl 1.1 if (lock.getSequence() == seq) {
889 jsr166 1.19 if (n <= 0)
890 dl 1.1 throw new NoSuchElementException();
891 jsr166 1.19 return e;
892 dl 1.1 }
893     }
894     }
895    
896     /** See {@link Vector#lastElement} */
897     public E lastElement() {
898 jsr166 1.14 final SequenceLock lock = this.lock;
899 dl 1.1 for (;;) {
900     long seq = lock.awaitAvailability();
901     Object[] items = array;
902 dl 1.2 int n = count;
903 jsr166 1.14 @SuppressWarnings("unchecked")
904 jsr166 1.19 E e = (n > 0 && items.length >= n) ? (E) items[n - 1] : null;
905 dl 1.1 if (lock.getSequence() == seq) {
906 jsr166 1.19 if (n <= 0)
907 dl 1.1 throw new NoSuchElementException();
908 jsr166 1.19 return e;
909 dl 1.1 }
910     }
911     }
912    
913     /** See {@link Vector#indexOf(Object, int)} */
914     public int indexOf(Object o, int index) {
915 jsr166 1.14 final SequenceLock lock = this.lock;
916 dl 1.1 long seq = lock.awaitAvailability();
917     Object[] items = array;
918 dl 1.2 int n = count;
919 jsr166 1.23 int idx = -1;
920     if (n <= items.length)
921 dl 1.2 idx = validatedIndexOf(o, items, index, n, seq);
922 jsr166 1.23 if (lock.getSequence() != seq) {
923 dl 1.1 lock.lock();
924     try {
925 jsr166 1.23 idx = rawIndexOf(o, index, count);
926 dl 1.1 } finally {
927     lock.unlock();
928     }
929     }
930 jsr166 1.23 // Above code will throw AIOOBE when index < 0
931 dl 1.1 return idx;
932     }
933    
934     /** See {@link Vector#lastIndexOf(Object, int)} */
935     public int lastIndexOf(Object o, int index) {
936 jsr166 1.14 final SequenceLock lock = this.lock;
937 dl 1.1 long seq = lock.awaitAvailability();
938     Object[] items = array;
939 dl 1.2 int n = count;
940 jsr166 1.23 int idx = -1;
941     if (index < Math.min(n, items.length))
942 dl 1.2 idx = validatedLastIndexOf(o, items, index, 0, seq);
943 jsr166 1.23 if (lock.getSequence() != seq) {
944 dl 1.1 lock.lock();
945     try {
946 jsr166 1.23 n = count;
947     if (index < n)
948 dl 1.2 idx = rawLastIndexOf(o, index, 0);
949 dl 1.1 } finally {
950     lock.unlock();
951     }
952     }
953 jsr166 1.23 if (index >= n)
954     throw new IndexOutOfBoundsException(index + " >= " + n);
955 dl 1.1 return idx;
956     }
957    
958     /** See {@link Vector#setSize} */
959     public void setSize(int newSize) {
960     if (newSize < 0)
961     throw new ArrayIndexOutOfBoundsException(newSize);
962 jsr166 1.14 final SequenceLock lock = this.lock;
963 dl 1.1 lock.lock();
964     try {
965 dl 1.2 int n = count;
966     if (newSize > n)
967 dl 1.1 grow(newSize);
968     else {
969 dl 1.11 Object[] items = array;
970 dl 1.2 for (int i = newSize ; i < n ; i++)
971 dl 1.11 items[i] = null;
972 dl 1.1 }
973     count = newSize;
974     } finally {
975     lock.unlock();
976     }
977     }
978    
979     /** See {@link Vector#copyInto} */
980     public void copyInto(Object[] anArray) {
981 jsr166 1.14 final SequenceLock lock = this.lock;
982 dl 1.1 lock.lock();
983     try {
984     System.arraycopy(array, 0, anArray, 0, count);
985     } finally {
986     lock.unlock();
987     }
988     }
989    
990     /** See {@link Vector#trimToSize} */
991     public void trimToSize() {
992 jsr166 1.14 final SequenceLock lock = this.lock;
993 dl 1.1 lock.lock();
994     try {
995 dl 1.11 Object[] items = array;
996 dl 1.12 int n = count;
997     if (n < items.length)
998     array = Arrays.copyOf(items, n);
999 dl 1.1 } finally {
1000     lock.unlock();
1001     }
1002     }
1003    
1004     /** See {@link Vector#ensureCapacity} */
1005     public void ensureCapacity(int minCapacity) {
1006     if (minCapacity > 0) {
1007 jsr166 1.14 final SequenceLock lock = this.lock;
1008 dl 1.1 lock.lock();
1009     try {
1010     if (minCapacity - array.length > 0)
1011     grow(minCapacity);
1012     } finally {
1013     lock.unlock();
1014     }
1015     }
1016     }
1017    
1018     /** See {@link Vector#elements} */
1019     public Enumeration<E> elements() {
1020 jsr166 1.10 return new Itr<E>(this, 0);
1021 dl 1.1 }
1022    
1023     /** See {@link Vector#capacity} */
1024     public int capacity() {
1025     return array.length;
1026     }
1027    
1028     /** See {@link Vector#elementAt} */
1029     public E elementAt(int index) {
1030     return get(index);
1031     }
1032    
1033     /** See {@link Vector#setElementAt} */
1034     public void setElementAt(E obj, int index) {
1035     set(index, obj);
1036     }
1037    
1038     /** See {@link Vector#removeElementAt} */
1039     public void removeElementAt(int index) {
1040     remove(index);
1041     }
1042    
1043     /** See {@link Vector#insertElementAt} */
1044     public void insertElementAt(E obj, int index) {
1045     add(index, obj);
1046     }
1047    
1048     /** See {@link Vector#addElement} */
1049     public void addElement(E obj) {
1050     add(obj);
1051     }
1052    
1053     /** See {@link Vector#removeElement} */
1054     public boolean removeElement(Object obj) {
1055     return remove(obj);
1056     }
1057    
1058     /** See {@link Vector#removeAllElements} */
1059     public void removeAllElements() {
1060     clear();
1061     }
1062    
1063     // other methods
1064    
1065 jsr166 1.10 public ReadMostlyVector<E> clone() {
1066 jsr166 1.14 final SequenceLock lock = this.lock;
1067 dl 1.1 Object[] a = null;
1068     boolean retry = false;
1069     long seq = lock.awaitAvailability();
1070     Object[] items = array;
1071 dl 1.2 int n = count;
1072     if (n <= items.length)
1073     a = Arrays.copyOf(items, n);
1074 dl 1.1 else
1075     retry = true;
1076     if (retry || lock.getSequence() != seq) {
1077     lock.lock();
1078     try {
1079 dl 1.2 n = count;
1080     a = Arrays.copyOf(array, n);
1081 dl 1.1 } finally {
1082     lock.unlock();
1083     }
1084     }
1085 jsr166 1.10 return new ReadMostlyVector<E>(a, n, capacityIncrement);
1086 dl 1.1 }
1087    
1088     private void writeObject(java.io.ObjectOutputStream s)
1089     throws java.io.IOException {
1090 jsr166 1.14 final SequenceLock lock = this.lock;
1091 dl 1.1 lock.lock();
1092     try {
1093     s.defaultWriteObject();
1094     } finally {
1095     lock.unlock();
1096     }
1097     }
1098    
1099 jsr166 1.15 static final class Itr<E> implements ListIterator<E>, Enumeration<E> {
1100 dl 1.1 final ReadMostlyVector<E> list;
1101     final SequenceLock lock;
1102     Object[] items;
1103 jsr166 1.14 E next, prev;
1104 dl 1.1 long seq;
1105     int cursor;
1106     int fence;
1107     int lastRet;
1108 dl 1.2 boolean validNext, validPrev;
1109 dl 1.1
1110     Itr(ReadMostlyVector<E> list, int index) {
1111     this.list = list;
1112     this.lock = list.lock;
1113     this.cursor = index;
1114     this.lastRet = -1;
1115     refresh();
1116     if (index < 0 || index > fence)
1117     throw new ArrayIndexOutOfBoundsException(index);
1118     }
1119    
1120     private void refresh() {
1121 dl 1.2 validNext = validPrev = false;
1122 dl 1.1 do {
1123     seq = lock.awaitAvailability();
1124     items = list.array;
1125 dl 1.2 } while ((fence = list.count) > items.length ||
1126     lock.getSequence() != seq);
1127 dl 1.1 }
1128    
1129 jsr166 1.14 @SuppressWarnings("unchecked")
1130 dl 1.1 public boolean hasNext() {
1131 dl 1.2 boolean valid;
1132 dl 1.1 int i = cursor;
1133 dl 1.2 for (;;) {
1134     if (i >= fence || i < 0 || i >= items.length) {
1135     valid = false;
1136     break;
1137     }
1138 jsr166 1.14 next = (E) items[i];
1139 dl 1.1 if (lock.getSequence() == seq) {
1140 dl 1.2 valid = true;
1141     break;
1142 dl 1.1 }
1143     refresh();
1144     }
1145 dl 1.2 return validNext = valid;
1146 dl 1.1 }
1147    
1148 jsr166 1.14 @SuppressWarnings("unchecked")
1149 dl 1.1 public boolean hasPrevious() {
1150 dl 1.2 boolean valid;
1151     int i = cursor - 1;
1152     for (;;) {
1153     if (i >= fence || i < 0 || i >= items.length) {
1154     valid = false;
1155     break;
1156     }
1157 jsr166 1.14 prev = (E) items[i];
1158 dl 1.1 if (lock.getSequence() == seq) {
1159 dl 1.2 valid = true;
1160     break;
1161 dl 1.1 }
1162     refresh();
1163     }
1164 dl 1.2 return validPrev = valid;
1165 dl 1.1 }
1166    
1167     public E next() {
1168 dl 1.2 if (validNext || hasNext()) {
1169     validNext = false;
1170     lastRet = cursor++;
1171 jsr166 1.14 return next;
1172 dl 1.2 }
1173     throw new NoSuchElementException();
1174 dl 1.1 }
1175    
1176     public E previous() {
1177 dl 1.2 if (validPrev || hasPrevious()) {
1178     validPrev = false;
1179     lastRet = cursor--;
1180 jsr166 1.14 return prev;
1181 dl 1.2 }
1182     throw new NoSuchElementException();
1183 dl 1.1 }
1184    
1185     public void remove() {
1186     int i = lastRet;
1187     if (i < 0)
1188     throw new IllegalStateException();
1189     lock.lock();
1190     try {
1191     if (i < list.count)
1192     list.remove(i);
1193     } finally {
1194     lock.unlock();
1195     }
1196     cursor = i;
1197     lastRet = -1;
1198     refresh();
1199     }
1200    
1201     public void set(E e) {
1202     int i = lastRet;
1203     if (i < 0)
1204     throw new IllegalStateException();
1205     lock.lock();
1206     try {
1207     if (i < list.count)
1208     list.set(i, e);
1209     } finally {
1210     lock.unlock();
1211     }
1212     refresh();
1213     }
1214    
1215     public void add(E e) {
1216     int i = cursor;
1217     if (i < 0)
1218     throw new IllegalStateException();
1219     lock.lock();
1220     try {
1221     if (i <= list.count)
1222     list.add(i, e);
1223     } finally {
1224     lock.unlock();
1225     }
1226     cursor = i + 1;
1227     lastRet = -1;
1228     refresh();
1229     }
1230    
1231     public boolean hasMoreElements() { return hasNext(); }
1232     public E nextElement() { return next(); }
1233     public int nextIndex() { return cursor; }
1234     public int previousIndex() { return cursor - 1; }
1235     }
1236    
1237 jsr166 1.14 static final class ReadMostlyVectorSublist<E>
1238     implements List<E>, RandomAccess, java.io.Serializable {
1239     static final long serialVersionUID = 3041673470172026059L;
1240    
1241 dl 1.1 final ReadMostlyVector<E> list;
1242     final int offset;
1243     volatile int size;
1244    
1245 jsr166 1.14 ReadMostlyVectorSublist(ReadMostlyVector<E> list,
1246     int offset, int size) {
1247 dl 1.1 this.list = list;
1248     this.offset = offset;
1249     this.size = size;
1250     }
1251    
1252     private void rangeCheck(int index) {
1253     if (index < 0 || index >= size)
1254     throw new ArrayIndexOutOfBoundsException(index);
1255     }
1256    
1257     public boolean add(E element) {
1258 jsr166 1.14 final SequenceLock lock = list.lock;
1259 dl 1.1 lock.lock();
1260     try {
1261     int c = size;
1262 dl 1.4 list.rawAddAt(c + offset, element);
1263 dl 1.1 size = c + 1;
1264     } finally {
1265     lock.unlock();
1266     }
1267     return true;
1268     }
1269    
1270     public void add(int index, E element) {
1271 jsr166 1.14 final SequenceLock lock = list.lock;
1272 dl 1.1 lock.lock();
1273     try {
1274     if (index < 0 || index > size)
1275     throw new ArrayIndexOutOfBoundsException(index);
1276 dl 1.4 list.rawAddAt(index + offset, element);
1277 dl 1.1 ++size;
1278     } finally {
1279     lock.unlock();
1280     }
1281     }
1282    
1283     public boolean addAll(Collection<? extends E> c) {
1284     Object[] elements = c.toArray();
1285 jsr166 1.14 final SequenceLock lock = list.lock;
1286 dl 1.1 lock.lock();
1287     try {
1288     int s = size;
1289     int pc = list.count;
1290 dl 1.4 list.rawAddAllAt(offset + s, elements);
1291 jsr166 1.14 int added = list.count - pc;
1292 dl 1.1 size = s + added;
1293 jsr166 1.14 return added != 0;
1294 dl 1.1 } finally {
1295     lock.unlock();
1296     }
1297     }
1298    
1299     public boolean addAll(int index, Collection<? extends E> c) {
1300     Object[] elements = c.toArray();
1301 jsr166 1.14 final SequenceLock lock = list.lock;
1302 dl 1.1 lock.lock();
1303     try {
1304     int s = size;
1305     if (index < 0 || index > s)
1306     throw new ArrayIndexOutOfBoundsException(index);
1307     int pc = list.count;
1308 dl 1.4 list.rawAddAllAt(index + offset, elements);
1309 jsr166 1.14 int added = list.count - pc;
1310 dl 1.1 size = s + added;
1311 jsr166 1.14 return added != 0;
1312 dl 1.1 } finally {
1313     lock.unlock();
1314     }
1315     }
1316    
1317     public void clear() {
1318 jsr166 1.14 final SequenceLock lock = list.lock;
1319 dl 1.1 lock.lock();
1320     try {
1321 dl 1.2 list.internalClear(offset, offset + size);
1322 dl 1.1 size = 0;
1323     } finally {
1324     lock.unlock();
1325     }
1326     }
1327    
1328     public boolean contains(Object o) {
1329     return indexOf(o) >= 0;
1330     }
1331    
1332     public boolean containsAll(Collection<?> c) {
1333 dl 1.2 return list.internalContainsAll(c, offset, offset + size);
1334 dl 1.1 }
1335    
1336     public boolean equals(Object o) {
1337     if (o == this)
1338     return true;
1339     if (!(o instanceof List))
1340     return false;
1341 dl 1.2 return list.internalEquals((List<?>)(o), offset, offset + size);
1342 dl 1.1 }
1343    
1344     public E get(int index) {
1345     if (index < 0 || index >= size)
1346     throw new ArrayIndexOutOfBoundsException(index);
1347     return list.get(index + offset);
1348     }
1349    
1350     public int hashCode() {
1351 dl 1.2 return list.internalHashCode(offset, offset + size);
1352 dl 1.1 }
1353    
1354     public int indexOf(Object o) {
1355 jsr166 1.14 final SequenceLock lock = list.lock;
1356 dl 1.1 long seq = lock.awaitAvailability();
1357     Object[] items = list.array;
1358     int c = list.count;
1359     if (c <= items.length) {
1360 dl 1.4 int idx = list.validatedIndexOf(o, items, offset,
1361     offset + size, seq);
1362 dl 1.1 if (lock.getSequence() == seq)
1363     return idx < 0 ? -1 : idx - offset;
1364     }
1365     lock.lock();
1366     try {
1367 dl 1.4 int idx = list.rawIndexOf(o, offset, offset + size);
1368 dl 1.1 return idx < 0 ? -1 : idx - offset;
1369     } finally {
1370     lock.unlock();
1371     }
1372     }
1373    
1374     public boolean isEmpty() {
1375     return size == 0;
1376     }
1377    
1378     public Iterator<E> iterator() {
1379 jsr166 1.10 return new SubItr<E>(this, offset);
1380 dl 1.1 }
1381    
1382     public int lastIndexOf(Object o) {
1383 jsr166 1.14 final SequenceLock lock = list.lock;
1384 dl 1.1 long seq = lock.awaitAvailability();
1385     Object[] items = list.array;
1386     int c = list.count;
1387     if (c <= items.length) {
1388 jsr166 1.3 int idx = list.validatedLastIndexOf(o, items, offset+size-1,
1389 dl 1.2 offset, seq);
1390 dl 1.1 if (lock.getSequence() == seq)
1391     return idx < 0 ? -1 : idx - offset;
1392     }
1393     lock.lock();
1394     try {
1395 dl 1.2 int idx = list.rawLastIndexOf(o, offset + size - 1, offset);
1396 dl 1.1 return idx < 0 ? -1 : idx - offset;
1397     } finally {
1398     lock.unlock();
1399     }
1400     }
1401    
1402     public ListIterator<E> listIterator() {
1403 jsr166 1.10 return new SubItr<E>(this, offset);
1404 dl 1.1 }
1405    
1406     public ListIterator<E> listIterator(int index) {
1407 jsr166 1.10 return new SubItr<E>(this, index + offset);
1408 dl 1.1 }
1409    
1410     public E remove(int index) {
1411 jsr166 1.14 final SequenceLock lock = list.lock;
1412 dl 1.1 lock.lock();
1413     try {
1414 dl 1.4 Object[] items = list.array;
1415     int i = index + offset;
1416     if (index < 0 || index >= size || i >= items.length)
1417 dl 1.1 throw new ArrayIndexOutOfBoundsException(index);
1418 jsr166 1.14 @SuppressWarnings("unchecked")
1419     E result = (E) items[i];
1420 dl 1.4 list.rawRemoveAt(i);
1421 dl 1.1 size--;
1422 jsr166 1.14 return result;
1423 dl 1.1 } finally {
1424     lock.unlock();
1425     }
1426     }
1427    
1428     public boolean remove(Object o) {
1429 jsr166 1.14 final SequenceLock lock = list.lock;
1430 dl 1.1 lock.lock();
1431     try {
1432 dl 1.4 if (list.rawRemoveAt(list.rawIndexOf(o, offset,
1433     offset + size))) {
1434 dl 1.1 --size;
1435 jsr166 1.14 return true;
1436 dl 1.1 }
1437 jsr166 1.14 else
1438     return false;
1439 dl 1.1 } finally {
1440     lock.unlock();
1441     }
1442     }
1443    
1444     public boolean removeAll(Collection<?> c) {
1445 dl 1.2 return list.internalRemoveAll(c, offset, offset + size);
1446 dl 1.1 }
1447    
1448     public boolean retainAll(Collection<?> c) {
1449 dl 1.2 return list.internalRetainAll(c, offset, offset + size);
1450 dl 1.1 }
1451    
1452     public E set(int index, E element) {
1453     if (index < 0 || index >= size)
1454     throw new ArrayIndexOutOfBoundsException(index);
1455     return list.set(index+offset, element);
1456     }
1457    
1458     public int size() {
1459     return size;
1460     }
1461    
1462     public List<E> subList(int fromIndex, int toIndex) {
1463     int c = size;
1464     int ssize = toIndex - fromIndex;
1465     if (fromIndex < 0 || toIndex > c || ssize < 0)
1466     throw new IndexOutOfBoundsException();
1467 jsr166 1.10 return new ReadMostlyVectorSublist<E>(list, offset+fromIndex, ssize);
1468 dl 1.1 }
1469    
1470     public Object[] toArray() {
1471 dl 1.2 return list.internalToArray(offset, offset + size);
1472 dl 1.1 }
1473    
1474     public <T> T[] toArray(T[] a) {
1475 dl 1.2 return list.internalToArray(a, offset, offset + size);
1476 dl 1.1 }
1477    
1478     public String toString() {
1479 dl 1.2 return list.internalToString(offset, offset + size);
1480 dl 1.1 }
1481    
1482     }
1483    
1484     static final class SubItr<E> implements ListIterator<E> {
1485     final ReadMostlyVectorSublist<E> sublist;
1486     final ReadMostlyVector<E> list;
1487     final SequenceLock lock;
1488     Object[] items;
1489 jsr166 1.14 E next, prev;
1490 dl 1.1 long seq;
1491     int cursor;
1492     int fence;
1493     int lastRet;
1494 dl 1.2 boolean validNext, validPrev;
1495 dl 1.1
1496     SubItr(ReadMostlyVectorSublist<E> sublist, int index) {
1497     this.sublist = sublist;
1498     this.list = sublist.list;
1499     this.lock = list.lock;
1500     this.cursor = index;
1501     this.lastRet = -1;
1502     refresh();
1503     if (index < 0 || index > fence)
1504     throw new ArrayIndexOutOfBoundsException(index);
1505     }
1506    
1507     private void refresh() {
1508 dl 1.2 validNext = validPrev = false;
1509 dl 1.1 do {
1510 dl 1.2 int n;
1511 dl 1.1 seq = lock.awaitAvailability();
1512     items = list.array;
1513 dl 1.2 if ((n = list.count) > items.length)
1514     continue;
1515 dl 1.1 int b = sublist.offset + sublist.size;
1516 dl 1.2 fence = b < n ? b : n;
1517 dl 1.1 } while (lock.getSequence() != seq);
1518     }
1519    
1520 jsr166 1.14 @SuppressWarnings("unchecked")
1521 dl 1.1 public boolean hasNext() {
1522 dl 1.2 boolean valid;
1523 dl 1.1 int i = cursor;
1524 dl 1.2 for (;;) {
1525     if (i >= fence || i < 0 || i >= items.length) {
1526     valid = false;
1527     break;
1528     }
1529 jsr166 1.14 next = (E) items[i];
1530 dl 1.1 if (lock.getSequence() == seq) {
1531 dl 1.2 valid = true;
1532     break;
1533 dl 1.1 }
1534     refresh();
1535     }
1536 dl 1.2 return validNext = valid;
1537 dl 1.1 }
1538    
1539 jsr166 1.14 @SuppressWarnings("unchecked")
1540 dl 1.1 public boolean hasPrevious() {
1541 dl 1.2 boolean valid;
1542     int i = cursor - 1;
1543     for (;;) {
1544     if (i >= fence || i < 0 || i >= items.length) {
1545     valid = false;
1546     break;
1547     }
1548 jsr166 1.14 prev = (E) items[i];
1549 dl 1.1 if (lock.getSequence() == seq) {
1550 dl 1.2 valid = true;
1551     break;
1552 dl 1.1 }
1553     refresh();
1554     }
1555 dl 1.2 return validPrev = valid;
1556 dl 1.1 }
1557    
1558     public E next() {
1559 dl 1.2 if (validNext || hasNext()) {
1560     validNext = false;
1561     lastRet = cursor++;
1562 jsr166 1.14 return next;
1563 dl 1.2 }
1564     throw new NoSuchElementException();
1565 dl 1.1 }
1566    
1567     public E previous() {
1568 dl 1.2 if (validPrev || hasPrevious()) {
1569     validPrev = false;
1570     lastRet = cursor--;
1571 jsr166 1.14 return prev;
1572 dl 1.2 }
1573     throw new NoSuchElementException();
1574 dl 1.1 }
1575    
1576     public int nextIndex() {
1577     return cursor - sublist.offset;
1578     }
1579    
1580     public int previousIndex() {
1581     return cursor - 1 - sublist.offset;
1582     }
1583    
1584     public void remove() {
1585     int i = lastRet;
1586     if (i < 0)
1587     throw new IllegalStateException();
1588     cursor = i;
1589     lastRet = -1;
1590     lock.lock();
1591     try {
1592     if (i < list.count) {
1593     list.remove(i);
1594     --sublist.size;
1595     }
1596     } finally {
1597     lock.unlock();
1598     }
1599     refresh();
1600     }
1601    
1602     public void set(E e) {
1603     int i = lastRet;
1604     if (i < 0)
1605     throw new IllegalStateException();
1606     lock.lock();
1607     try {
1608     if (i < list.count)
1609     list.set(i, e);
1610     } finally {
1611     lock.unlock();
1612     }
1613     refresh();
1614     }
1615    
1616     public void add(E e) {
1617     int i = cursor;
1618     if (i < 0)
1619     throw new IllegalStateException();
1620     cursor = i + 1;
1621     lastRet = -1;
1622     lock.lock();
1623     try {
1624     if (i <= list.count) {
1625     list.add(i, e);
1626     ++sublist.size;
1627     }
1628     } finally {
1629     lock.unlock();
1630     }
1631     refresh();
1632     }
1633    
1634     }
1635     }
1636