ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/extra/ReadMostlyVector.java
Revision: 1.19
Committed: Sat Dec 31 06:21:46 2011 UTC (12 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.18: +6 -16 lines
Log Message:
more concise version of firstElement and lastElement

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