ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/extra/ReadMostlyVector.java
Revision: 1.18
Committed: Sat Dec 31 05:50:22 2011 UTC (12 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.17: +3 -7 lines
Log Message:
more concise version of get(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 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     int len = items.length;
874 dl 1.2 int n = count;
875     if (n > len)
876 dl 1.1 continue;
877 jsr166 1.14 boolean empty = (n == 0);
878     @SuppressWarnings("unchecked")
879     E e = empty ? null : (E) items[0];
880 dl 1.1 if (lock.getSequence() == seq) {
881 jsr166 1.14 if (empty)
882 dl 1.1 throw new NoSuchElementException();
883     else
884 jsr166 1.14 return e;
885 dl 1.1 }
886     }
887     }
888    
889     /** See {@link Vector#lastElement} */
890     public E lastElement() {
891 jsr166 1.14 final SequenceLock lock = this.lock;
892 dl 1.1 for (;;) {
893     long seq = lock.awaitAvailability();
894     Object[] items = array;
895     int len = items.length;
896 dl 1.2 int n = count;
897     if (n > len)
898 dl 1.1 continue;
899 jsr166 1.14 boolean empty = (n == 0);
900     @SuppressWarnings("unchecked")
901     E e = empty ? null : (E) items[n - 1];
902 dl 1.1 if (lock.getSequence() == seq) {
903 jsr166 1.14 if (empty)
904 dl 1.1 throw new NoSuchElementException();
905     else
906 jsr166 1.14 return e;
907 dl 1.1 }
908     }
909     }
910    
911     /** See {@link Vector#indexOf(Object, int)} */
912     public int indexOf(Object o, int index) {
913 jsr166 1.14 final SequenceLock lock = this.lock;
914 dl 1.1 int idx = 0;
915     boolean ex = false;
916     long seq = lock.awaitAvailability();
917     Object[] items = array;
918 dl 1.2 int n = count;
919 dl 1.1 boolean retry = false;
920 dl 1.2 if (n > items.length)
921 dl 1.1 retry = true;
922     else if (index < 0)
923     ex = true;
924     else
925 dl 1.2 idx = validatedIndexOf(o, items, index, n, seq);
926 dl 1.1 if (retry || lock.getSequence() != seq) {
927     lock.lock();
928     try {
929     if (index < 0)
930     ex = true;
931     else
932 jsr166 1.16 idx = rawIndexOf(o, index, count);
933 dl 1.1 } finally {
934     lock.unlock();
935     }
936     }
937     if (ex)
938     throw new ArrayIndexOutOfBoundsException(index);
939     return idx;
940     }
941    
942     /** See {@link Vector#lastIndexOf(Object, int)} */
943     public int lastIndexOf(Object o, int index) {
944 jsr166 1.14 final SequenceLock lock = this.lock;
945 dl 1.1 int idx = 0;
946     boolean ex = false;
947     long seq = lock.awaitAvailability();
948     Object[] items = array;
949 dl 1.2 int n = count;
950 dl 1.1 boolean retry = false;
951 dl 1.2 if (n > items.length)
952 dl 1.1 retry = true;
953 dl 1.2 else if (index >= n)
954 dl 1.1 ex = true;
955     else
956 dl 1.2 idx = validatedLastIndexOf(o, items, index, 0, seq);
957 dl 1.1 if (retry || lock.getSequence() != seq) {
958     lock.lock();
959     try {
960     if (index >= count)
961     ex = true;
962     else
963 dl 1.2 idx = rawLastIndexOf(o, index, 0);
964 dl 1.1 } finally {
965     lock.unlock();
966     }
967     }
968     if (ex)
969     throw new ArrayIndexOutOfBoundsException(index);
970     return idx;
971     }
972    
973     /** See {@link Vector#setSize} */
974     public void setSize(int newSize) {
975     if (newSize < 0)
976     throw new ArrayIndexOutOfBoundsException(newSize);
977 jsr166 1.14 final SequenceLock lock = this.lock;
978 dl 1.1 lock.lock();
979     try {
980 dl 1.2 int n = count;
981     if (newSize > n)
982 dl 1.1 grow(newSize);
983     else {
984 dl 1.11 Object[] items = array;
985 dl 1.2 for (int i = newSize ; i < n ; i++)
986 dl 1.11 items[i] = null;
987 dl 1.1 }
988     count = newSize;
989     } finally {
990     lock.unlock();
991     }
992     }
993    
994     /** See {@link Vector#copyInto} */
995     public void copyInto(Object[] anArray) {
996 jsr166 1.14 final SequenceLock lock = this.lock;
997 dl 1.1 lock.lock();
998     try {
999     System.arraycopy(array, 0, anArray, 0, count);
1000     } finally {
1001     lock.unlock();
1002     }
1003     }
1004    
1005     /** See {@link Vector#trimToSize} */
1006     public void trimToSize() {
1007 jsr166 1.14 final SequenceLock lock = this.lock;
1008 dl 1.1 lock.lock();
1009     try {
1010 dl 1.11 Object[] items = array;
1011 dl 1.12 int n = count;
1012     if (n < items.length)
1013     array = Arrays.copyOf(items, n);
1014 dl 1.1 } finally {
1015     lock.unlock();
1016     }
1017     }
1018    
1019     /** See {@link Vector#ensureCapacity} */
1020     public void ensureCapacity(int minCapacity) {
1021     if (minCapacity > 0) {
1022 jsr166 1.14 final SequenceLock lock = this.lock;
1023 dl 1.1 lock.lock();
1024     try {
1025     if (minCapacity - array.length > 0)
1026     grow(minCapacity);
1027     } finally {
1028     lock.unlock();
1029     }
1030     }
1031     }
1032    
1033     /** See {@link Vector#elements} */
1034     public Enumeration<E> elements() {
1035 jsr166 1.10 return new Itr<E>(this, 0);
1036 dl 1.1 }
1037    
1038     /** See {@link Vector#capacity} */
1039     public int capacity() {
1040     return array.length;
1041     }
1042    
1043     /** See {@link Vector#elementAt} */
1044     public E elementAt(int index) {
1045     return get(index);
1046     }
1047    
1048     /** See {@link Vector#setElementAt} */
1049     public void setElementAt(E obj, int index) {
1050     set(index, obj);
1051     }
1052    
1053     /** See {@link Vector#removeElementAt} */
1054     public void removeElementAt(int index) {
1055     remove(index);
1056     }
1057    
1058     /** See {@link Vector#insertElementAt} */
1059     public void insertElementAt(E obj, int index) {
1060     add(index, obj);
1061     }
1062    
1063     /** See {@link Vector#addElement} */
1064     public void addElement(E obj) {
1065     add(obj);
1066     }
1067    
1068     /** See {@link Vector#removeElement} */
1069     public boolean removeElement(Object obj) {
1070     return remove(obj);
1071     }
1072    
1073     /** See {@link Vector#removeAllElements} */
1074     public void removeAllElements() {
1075     clear();
1076     }
1077    
1078     // other methods
1079    
1080 jsr166 1.10 public ReadMostlyVector<E> clone() {
1081 jsr166 1.14 final SequenceLock lock = this.lock;
1082 dl 1.1 Object[] a = null;
1083     boolean retry = false;
1084     long seq = lock.awaitAvailability();
1085     Object[] items = array;
1086 dl 1.2 int n = count;
1087     if (n <= items.length)
1088     a = Arrays.copyOf(items, n);
1089 dl 1.1 else
1090     retry = true;
1091     if (retry || lock.getSequence() != seq) {
1092     lock.lock();
1093     try {
1094 dl 1.2 n = count;
1095     a = Arrays.copyOf(array, n);
1096 dl 1.1 } finally {
1097     lock.unlock();
1098     }
1099     }
1100 jsr166 1.10 return new ReadMostlyVector<E>(a, n, capacityIncrement);
1101 dl 1.1 }
1102    
1103     private void writeObject(java.io.ObjectOutputStream s)
1104     throws java.io.IOException {
1105 jsr166 1.14 final SequenceLock lock = this.lock;
1106 dl 1.1 lock.lock();
1107     try {
1108     s.defaultWriteObject();
1109     } finally {
1110     lock.unlock();
1111     }
1112     }
1113    
1114 jsr166 1.15 static final class Itr<E> implements ListIterator<E>, Enumeration<E> {
1115 dl 1.1 final ReadMostlyVector<E> list;
1116     final SequenceLock lock;
1117     Object[] items;
1118 jsr166 1.14 E next, prev;
1119 dl 1.1 long seq;
1120     int cursor;
1121     int fence;
1122     int lastRet;
1123 dl 1.2 boolean validNext, validPrev;
1124 dl 1.1
1125     Itr(ReadMostlyVector<E> list, int index) {
1126     this.list = list;
1127     this.lock = list.lock;
1128     this.cursor = index;
1129     this.lastRet = -1;
1130     refresh();
1131     if (index < 0 || index > fence)
1132     throw new ArrayIndexOutOfBoundsException(index);
1133     }
1134    
1135     private void refresh() {
1136 dl 1.2 validNext = validPrev = false;
1137 dl 1.1 do {
1138     seq = lock.awaitAvailability();
1139     items = list.array;
1140 dl 1.2 } while ((fence = list.count) > items.length ||
1141     lock.getSequence() != seq);
1142 dl 1.1 }
1143    
1144 jsr166 1.14 @SuppressWarnings("unchecked")
1145 dl 1.1 public boolean hasNext() {
1146 dl 1.2 boolean valid;
1147 dl 1.1 int i = cursor;
1148 dl 1.2 for (;;) {
1149     if (i >= fence || i < 0 || i >= items.length) {
1150     valid = false;
1151     break;
1152     }
1153 jsr166 1.14 next = (E) items[i];
1154 dl 1.1 if (lock.getSequence() == seq) {
1155 dl 1.2 valid = true;
1156     break;
1157 dl 1.1 }
1158     refresh();
1159     }
1160 dl 1.2 return validNext = valid;
1161 dl 1.1 }
1162    
1163 jsr166 1.14 @SuppressWarnings("unchecked")
1164 dl 1.1 public boolean hasPrevious() {
1165 dl 1.2 boolean valid;
1166     int i = cursor - 1;
1167     for (;;) {
1168     if (i >= fence || i < 0 || i >= items.length) {
1169     valid = false;
1170     break;
1171     }
1172 jsr166 1.14 prev = (E) items[i];
1173 dl 1.1 if (lock.getSequence() == seq) {
1174 dl 1.2 valid = true;
1175     break;
1176 dl 1.1 }
1177     refresh();
1178     }
1179 dl 1.2 return validPrev = valid;
1180 dl 1.1 }
1181    
1182     public E next() {
1183 dl 1.2 if (validNext || hasNext()) {
1184     validNext = false;
1185     lastRet = cursor++;
1186 jsr166 1.14 return next;
1187 dl 1.2 }
1188     throw new NoSuchElementException();
1189 dl 1.1 }
1190    
1191     public E previous() {
1192 dl 1.2 if (validPrev || hasPrevious()) {
1193     validPrev = false;
1194     lastRet = cursor--;
1195 jsr166 1.14 return prev;
1196 dl 1.2 }
1197     throw new NoSuchElementException();
1198 dl 1.1 }
1199    
1200     public void remove() {
1201     int i = lastRet;
1202     if (i < 0)
1203     throw new IllegalStateException();
1204     lock.lock();
1205     try {
1206     if (i < list.count)
1207     list.remove(i);
1208     } finally {
1209     lock.unlock();
1210     }
1211     cursor = i;
1212     lastRet = -1;
1213     refresh();
1214     }
1215    
1216     public void set(E e) {
1217     int i = lastRet;
1218     if (i < 0)
1219     throw new IllegalStateException();
1220     lock.lock();
1221     try {
1222     if (i < list.count)
1223     list.set(i, e);
1224     } finally {
1225     lock.unlock();
1226     }
1227     refresh();
1228     }
1229    
1230     public void add(E e) {
1231     int i = cursor;
1232     if (i < 0)
1233     throw new IllegalStateException();
1234     lock.lock();
1235     try {
1236     if (i <= list.count)
1237     list.add(i, e);
1238     } finally {
1239     lock.unlock();
1240     }
1241     cursor = i + 1;
1242     lastRet = -1;
1243     refresh();
1244     }
1245    
1246     public boolean hasMoreElements() { return hasNext(); }
1247     public E nextElement() { return next(); }
1248     public int nextIndex() { return cursor; }
1249     public int previousIndex() { return cursor - 1; }
1250     }
1251    
1252 jsr166 1.14 static final class ReadMostlyVectorSublist<E>
1253     implements List<E>, RandomAccess, java.io.Serializable {
1254     static final long serialVersionUID = 3041673470172026059L;
1255    
1256 dl 1.1 final ReadMostlyVector<E> list;
1257     final int offset;
1258     volatile int size;
1259    
1260 jsr166 1.14 ReadMostlyVectorSublist(ReadMostlyVector<E> list,
1261     int offset, int size) {
1262 dl 1.1 this.list = list;
1263     this.offset = offset;
1264     this.size = size;
1265     }
1266    
1267     private void rangeCheck(int index) {
1268     if (index < 0 || index >= size)
1269     throw new ArrayIndexOutOfBoundsException(index);
1270     }
1271    
1272     public boolean add(E element) {
1273 jsr166 1.14 final SequenceLock lock = list.lock;
1274 dl 1.1 lock.lock();
1275     try {
1276     int c = size;
1277 dl 1.4 list.rawAddAt(c + offset, element);
1278 dl 1.1 size = c + 1;
1279     } finally {
1280     lock.unlock();
1281     }
1282     return true;
1283     }
1284    
1285     public void add(int index, E element) {
1286 jsr166 1.14 final SequenceLock lock = list.lock;
1287 dl 1.1 lock.lock();
1288     try {
1289     if (index < 0 || index > size)
1290     throw new ArrayIndexOutOfBoundsException(index);
1291 dl 1.4 list.rawAddAt(index + offset, element);
1292 dl 1.1 ++size;
1293     } finally {
1294     lock.unlock();
1295     }
1296     }
1297    
1298     public boolean addAll(Collection<? extends E> c) {
1299     Object[] elements = c.toArray();
1300 jsr166 1.14 final SequenceLock lock = list.lock;
1301 dl 1.1 lock.lock();
1302     try {
1303     int s = size;
1304     int pc = list.count;
1305 dl 1.4 list.rawAddAllAt(offset + s, elements);
1306 jsr166 1.14 int added = list.count - pc;
1307 dl 1.1 size = s + added;
1308 jsr166 1.14 return added != 0;
1309 dl 1.1 } finally {
1310     lock.unlock();
1311     }
1312     }
1313    
1314     public boolean addAll(int index, Collection<? extends E> c) {
1315     Object[] elements = c.toArray();
1316 jsr166 1.14 final SequenceLock lock = list.lock;
1317 dl 1.1 lock.lock();
1318     try {
1319     int s = size;
1320     if (index < 0 || index > s)
1321     throw new ArrayIndexOutOfBoundsException(index);
1322     int pc = list.count;
1323 dl 1.4 list.rawAddAllAt(index + offset, elements);
1324 jsr166 1.14 int added = list.count - pc;
1325 dl 1.1 size = s + added;
1326 jsr166 1.14 return added != 0;
1327 dl 1.1 } finally {
1328     lock.unlock();
1329     }
1330     }
1331    
1332     public void clear() {
1333 jsr166 1.14 final SequenceLock lock = list.lock;
1334 dl 1.1 lock.lock();
1335     try {
1336 dl 1.2 list.internalClear(offset, offset + size);
1337 dl 1.1 size = 0;
1338     } finally {
1339     lock.unlock();
1340     }
1341     }
1342    
1343     public boolean contains(Object o) {
1344     return indexOf(o) >= 0;
1345     }
1346    
1347     public boolean containsAll(Collection<?> c) {
1348 dl 1.2 return list.internalContainsAll(c, offset, offset + size);
1349 dl 1.1 }
1350    
1351     public boolean equals(Object o) {
1352     if (o == this)
1353     return true;
1354     if (!(o instanceof List))
1355     return false;
1356 dl 1.2 return list.internalEquals((List<?>)(o), offset, offset + size);
1357 dl 1.1 }
1358    
1359     public E get(int index) {
1360     if (index < 0 || index >= size)
1361     throw new ArrayIndexOutOfBoundsException(index);
1362     return list.get(index + offset);
1363     }
1364    
1365     public int hashCode() {
1366 dl 1.2 return list.internalHashCode(offset, offset + size);
1367 dl 1.1 }
1368    
1369     public int indexOf(Object o) {
1370 jsr166 1.14 final SequenceLock lock = list.lock;
1371 dl 1.1 long seq = lock.awaitAvailability();
1372     Object[] items = list.array;
1373     int c = list.count;
1374     if (c <= items.length) {
1375 dl 1.4 int idx = list.validatedIndexOf(o, items, offset,
1376     offset + size, seq);
1377 dl 1.1 if (lock.getSequence() == seq)
1378     return idx < 0 ? -1 : idx - offset;
1379     }
1380     lock.lock();
1381     try {
1382 dl 1.4 int idx = list.rawIndexOf(o, offset, offset + size);
1383 dl 1.1 return idx < 0 ? -1 : idx - offset;
1384     } finally {
1385     lock.unlock();
1386     }
1387     }
1388    
1389     public boolean isEmpty() {
1390     return size == 0;
1391     }
1392    
1393     public Iterator<E> iterator() {
1394 jsr166 1.10 return new SubItr<E>(this, offset);
1395 dl 1.1 }
1396    
1397     public int lastIndexOf(Object o) {
1398 jsr166 1.14 final SequenceLock lock = list.lock;
1399 dl 1.1 long seq = lock.awaitAvailability();
1400     Object[] items = list.array;
1401     int c = list.count;
1402     if (c <= items.length) {
1403 jsr166 1.3 int idx = list.validatedLastIndexOf(o, items, offset+size-1,
1404 dl 1.2 offset, seq);
1405 dl 1.1 if (lock.getSequence() == seq)
1406     return idx < 0 ? -1 : idx - offset;
1407     }
1408     lock.lock();
1409     try {
1410 dl 1.2 int idx = list.rawLastIndexOf(o, offset + size - 1, offset);
1411 dl 1.1 return idx < 0 ? -1 : idx - offset;
1412     } finally {
1413     lock.unlock();
1414     }
1415     }
1416    
1417     public ListIterator<E> listIterator() {
1418 jsr166 1.10 return new SubItr<E>(this, offset);
1419 dl 1.1 }
1420    
1421     public ListIterator<E> listIterator(int index) {
1422 jsr166 1.10 return new SubItr<E>(this, index + offset);
1423 dl 1.1 }
1424    
1425     public E remove(int index) {
1426 jsr166 1.14 final SequenceLock lock = list.lock;
1427 dl 1.1 lock.lock();
1428     try {
1429 dl 1.4 Object[] items = list.array;
1430     int i = index + offset;
1431     if (index < 0 || index >= size || i >= items.length)
1432 dl 1.1 throw new ArrayIndexOutOfBoundsException(index);
1433 jsr166 1.14 @SuppressWarnings("unchecked")
1434     E result = (E) items[i];
1435 dl 1.4 list.rawRemoveAt(i);
1436 dl 1.1 size--;
1437 jsr166 1.14 return result;
1438 dl 1.1 } finally {
1439     lock.unlock();
1440     }
1441     }
1442    
1443     public boolean remove(Object o) {
1444 jsr166 1.14 final SequenceLock lock = list.lock;
1445 dl 1.1 lock.lock();
1446     try {
1447 dl 1.4 if (list.rawRemoveAt(list.rawIndexOf(o, offset,
1448     offset + size))) {
1449 dl 1.1 --size;
1450 jsr166 1.14 return true;
1451 dl 1.1 }
1452 jsr166 1.14 else
1453     return false;
1454 dl 1.1 } finally {
1455     lock.unlock();
1456     }
1457     }
1458    
1459     public boolean removeAll(Collection<?> c) {
1460 dl 1.2 return list.internalRemoveAll(c, offset, offset + size);
1461 dl 1.1 }
1462    
1463     public boolean retainAll(Collection<?> c) {
1464 dl 1.2 return list.internalRetainAll(c, offset, offset + size);
1465 dl 1.1 }
1466    
1467     public E set(int index, E element) {
1468     if (index < 0 || index >= size)
1469     throw new ArrayIndexOutOfBoundsException(index);
1470     return list.set(index+offset, element);
1471     }
1472    
1473     public int size() {
1474     return size;
1475     }
1476    
1477     public List<E> subList(int fromIndex, int toIndex) {
1478     int c = size;
1479     int ssize = toIndex - fromIndex;
1480     if (fromIndex < 0 || toIndex > c || ssize < 0)
1481     throw new IndexOutOfBoundsException();
1482 jsr166 1.10 return new ReadMostlyVectorSublist<E>(list, offset+fromIndex, ssize);
1483 dl 1.1 }
1484    
1485     public Object[] toArray() {
1486 dl 1.2 return list.internalToArray(offset, offset + size);
1487 dl 1.1 }
1488    
1489     public <T> T[] toArray(T[] a) {
1490 dl 1.2 return list.internalToArray(a, offset, offset + size);
1491 dl 1.1 }
1492    
1493     public String toString() {
1494 dl 1.2 return list.internalToString(offset, offset + size);
1495 dl 1.1 }
1496    
1497     }
1498    
1499     static final class SubItr<E> implements ListIterator<E> {
1500     final ReadMostlyVectorSublist<E> sublist;
1501     final ReadMostlyVector<E> list;
1502     final SequenceLock lock;
1503     Object[] items;
1504 jsr166 1.14 E next, prev;
1505 dl 1.1 long seq;
1506     int cursor;
1507     int fence;
1508     int lastRet;
1509 dl 1.2 boolean validNext, validPrev;
1510 dl 1.1
1511     SubItr(ReadMostlyVectorSublist<E> sublist, int index) {
1512     this.sublist = sublist;
1513     this.list = sublist.list;
1514     this.lock = list.lock;
1515     this.cursor = index;
1516     this.lastRet = -1;
1517     refresh();
1518     if (index < 0 || index > fence)
1519     throw new ArrayIndexOutOfBoundsException(index);
1520     }
1521    
1522     private void refresh() {
1523 dl 1.2 validNext = validPrev = false;
1524 dl 1.1 do {
1525 dl 1.2 int n;
1526 dl 1.1 seq = lock.awaitAvailability();
1527     items = list.array;
1528 dl 1.2 if ((n = list.count) > items.length)
1529     continue;
1530 dl 1.1 int b = sublist.offset + sublist.size;
1531 dl 1.2 fence = b < n ? b : n;
1532 dl 1.1 } while (lock.getSequence() != seq);
1533     }
1534    
1535 jsr166 1.14 @SuppressWarnings("unchecked")
1536 dl 1.1 public boolean hasNext() {
1537 dl 1.2 boolean valid;
1538 dl 1.1 int i = cursor;
1539 dl 1.2 for (;;) {
1540     if (i >= fence || i < 0 || i >= items.length) {
1541     valid = false;
1542     break;
1543     }
1544 jsr166 1.14 next = (E) items[i];
1545 dl 1.1 if (lock.getSequence() == seq) {
1546 dl 1.2 valid = true;
1547     break;
1548 dl 1.1 }
1549     refresh();
1550     }
1551 dl 1.2 return validNext = valid;
1552 dl 1.1 }
1553    
1554 jsr166 1.14 @SuppressWarnings("unchecked")
1555 dl 1.1 public boolean hasPrevious() {
1556 dl 1.2 boolean valid;
1557     int i = cursor - 1;
1558     for (;;) {
1559     if (i >= fence || i < 0 || i >= items.length) {
1560     valid = false;
1561     break;
1562     }
1563 jsr166 1.14 prev = (E) items[i];
1564 dl 1.1 if (lock.getSequence() == seq) {
1565 dl 1.2 valid = true;
1566     break;
1567 dl 1.1 }
1568     refresh();
1569     }
1570 dl 1.2 return validPrev = valid;
1571 dl 1.1 }
1572    
1573     public E next() {
1574 dl 1.2 if (validNext || hasNext()) {
1575     validNext = false;
1576     lastRet = cursor++;
1577 jsr166 1.14 return next;
1578 dl 1.2 }
1579     throw new NoSuchElementException();
1580 dl 1.1 }
1581    
1582     public E previous() {
1583 dl 1.2 if (validPrev || hasPrevious()) {
1584     validPrev = false;
1585     lastRet = cursor--;
1586 jsr166 1.14 return prev;
1587 dl 1.2 }
1588     throw new NoSuchElementException();
1589 dl 1.1 }
1590    
1591     public int nextIndex() {
1592     return cursor - sublist.offset;
1593     }
1594    
1595     public int previousIndex() {
1596     return cursor - 1 - sublist.offset;
1597     }
1598    
1599     public void remove() {
1600     int i = lastRet;
1601     if (i < 0)
1602     throw new IllegalStateException();
1603     cursor = i;
1604     lastRet = -1;
1605     lock.lock();
1606     try {
1607     if (i < list.count) {
1608     list.remove(i);
1609     --sublist.size;
1610     }
1611     } finally {
1612     lock.unlock();
1613     }
1614     refresh();
1615     }
1616    
1617     public void set(E e) {
1618     int i = lastRet;
1619     if (i < 0)
1620     throw new IllegalStateException();
1621     lock.lock();
1622     try {
1623     if (i < list.count)
1624     list.set(i, e);
1625     } finally {
1626     lock.unlock();
1627     }
1628     refresh();
1629     }
1630    
1631     public void add(E e) {
1632     int i = cursor;
1633     if (i < 0)
1634     throw new IllegalStateException();
1635     cursor = i + 1;
1636     lastRet = -1;
1637     lock.lock();
1638     try {
1639     if (i <= list.count) {
1640     list.add(i, e);
1641     ++sublist.size;
1642     }
1643     } finally {
1644     lock.unlock();
1645     }
1646     refresh();
1647     }
1648    
1649     }
1650     }
1651