ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/extra/ReadMostlyVector.java
Revision: 1.17
Committed: Sat Dec 31 05:38:24 2011 UTC (12 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.16: +1 -22 lines
Log Message:
indexOf(Object) should delegate to indexOf(Object,int)

File Contents

# User Rev Content
1 dl 1.1 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4     * http://creativecommons.org/publicdomain/zero/1.0/
5     */
6    
7     package jsr166e.extra;
8     import jsr166e.*;
9     import java.util.*;
10    
11     /**
12 dl 1.2 * A class with the same methods and array-based characteristics as
13     * {@link java.util.Vector} but with reduced contention and improved
14 dl 1.1 * throughput when invocations of read-only methods by multiple
15 jsr166 1.3 * threads are most common.
16 dl 1.1 *
17     * <p> The iterators returned by this class's {@link #iterator()
18     * iterator} and {@link #listIterator(int) listIterator} methods are
19     * best-effort in the presence of concurrent modifications, and do
20     * <em>NOT</em> throw {@link ConcurrentModificationException}. An
21     * iterator's {@code next()} method returns consecutive elements as
22 jsr166 1.13 * they appear in the underlying array upon each access. Alternatively,
23 dl 1.5 * method {@link #snapshotIterator} may be used for deterministic
24     * traversals, at the expense of making a copy, and unavailability of
25     * method {@code Iterator.remove}.
26 dl 1.1 *
27     * <p>Otherwise, this class supports all methods, under the same
28     * documented specifications, as {@code Vector}. Consult {@link
29     * java.util.Vector} for detailed specifications. Additionally, this
30     * class provides methods {@link #addIfAbsent} and {@link
31     * #addAllAbsent}.
32     *
33     * @author Doug Lea
34     */
35 jsr166 1.14 public class ReadMostlyVector<E>
36     implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
37 dl 1.1 private static final long serialVersionUID = 8673264195747942595L;
38    
39     /*
40     * This class exists mainly as a vehicle to exercise various
41 dl 1.2 * constructions using SequenceLocks. Read-only methods
42     * take one of a few forms:
43     *
44     * Short methods,including get(index), continually retry obtaining
45     * a snapshot of array, count, and element, using sequence number
46     * to validate.
47 jsr166 1.3 *
48 dl 1.2 * Methods that are potentially O(n) (or worse) try once in
49     * read-only mode, and then lock. When in read-only mode, they
50     * validate only at the end of an array scan unless the element is
51     * actually used (for example, as an argument of method equals).
52 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 dl 1.2 if (n > items.length)
652 dl 1.1 continue;
653 jsr166 1.14 boolean outOfBounds = (index < 0 || index >= n);
654     @SuppressWarnings("unchecked")
655     E e = outOfBounds ? null : (E) items[index];
656 dl 1.1 if (lock.getSequence() == seq) {
657 jsr166 1.14 if (outOfBounds)
658 dl 1.1 throw new ArrayIndexOutOfBoundsException(index);
659     else
660 jsr166 1.14 return e;
661 dl 1.1 }
662     }
663     }
664    
665     public int hashCode() {
666     return internalHashCode(0, -1);
667     }
668    
669     public int indexOf(Object o) {
670 jsr166 1.17 return indexOf(o, 0);
671 dl 1.1 }
672    
673     public boolean isEmpty() {
674     return count == 0;
675     }
676    
677     public Iterator<E> iterator() {
678 jsr166 1.10 return new Itr<E>(this, 0);
679 dl 1.1 }
680    
681     public int lastIndexOf(Object o) {
682 jsr166 1.14 final SequenceLock lock = this.lock;
683 dl 1.7 for (;;) {
684     long seq = lock.awaitAvailability();
685     Object[] items = array;
686     int n = count;
687 jsr166 1.8 if (n <= items.length) {
688 dl 1.7 for (int i = n - 1; i >= 0; --i) {
689     Object e = items[i];
690     if (lock.getSequence() != seq) {
691     lock.lock();
692     try {
693     return rawLastIndexOf(o, 0, count);
694     } finally {
695     lock.unlock();
696     }
697     }
698     else if ((o == null) ? e == null : o.equals(e))
699     return i;
700     }
701     return -1;
702     }
703 dl 1.1 }
704     }
705    
706     public ListIterator<E> listIterator() {
707 jsr166 1.10 return new Itr<E>(this, 0);
708 dl 1.1 }
709    
710     public ListIterator<E> listIterator(int index) {
711 jsr166 1.10 return new Itr<E>(this, index);
712 dl 1.1 }
713    
714     public E remove(int index) {
715 jsr166 1.14 final SequenceLock lock = this.lock;
716 dl 1.1 lock.lock();
717     try {
718     if (index < 0 || index >= count)
719     throw new ArrayIndexOutOfBoundsException(index);
720 jsr166 1.14 @SuppressWarnings("unchecked")
721     E oldValue = (E) array[index];
722 dl 1.4 rawRemoveAt(index);
723 jsr166 1.14 return oldValue;
724 dl 1.1 } finally {
725     lock.unlock();
726     }
727     }
728    
729     public boolean remove(Object o) {
730 jsr166 1.14 final SequenceLock lock = this.lock;
731 dl 1.1 lock.lock();
732     try {
733 jsr166 1.14 return rawRemoveAt(rawIndexOf(o, 0, count));
734 dl 1.1 } finally {
735     lock.unlock();
736     }
737     }
738    
739     public boolean removeAll(Collection<?> c) {
740     return internalRemoveAll(c, 0, -1);
741     }
742    
743     public boolean retainAll(Collection<?> c) {
744     return internalRetainAll(c, 0, -1);
745     }
746    
747     public E set(int index, E element) {
748 jsr166 1.14 final SequenceLock lock = this.lock;
749 dl 1.1 lock.lock();
750     try {
751 dl 1.11 Object[] items = array;
752 dl 1.1 if (index < 0 || index >= count)
753     throw new ArrayIndexOutOfBoundsException(index);
754 jsr166 1.14 @SuppressWarnings("unchecked")
755     E oldValue = (E) items[index];
756 dl 1.11 items[index] = element;
757 jsr166 1.14 return oldValue;
758 dl 1.1 } finally {
759     lock.unlock();
760     }
761     }
762    
763     public int size() {
764     return count;
765     }
766    
767     public List<E> subList(int fromIndex, int toIndex) {
768     int c = size();
769     int ssize = toIndex - fromIndex;
770     if (fromIndex < 0 || toIndex > c || ssize < 0)
771     throw new IndexOutOfBoundsException();
772 jsr166 1.10 return new ReadMostlyVectorSublist<E>(this, fromIndex, ssize);
773 dl 1.1 }
774    
775     public Object[] toArray() {
776     return internalToArray(0, -1);
777     }
778    
779     public <T> T[] toArray(T[] a) {
780     return internalToArray(a, 0, -1);
781     }
782    
783     public String toString() {
784     return internalToString(0, -1);
785     }
786    
787     // ReadMostlyVector-only methods
788    
789     /**
790     * Append the element if not present.
791     *
792     * @param e element to be added to this list, if absent
793 jsr166 1.9 * @return {@code true} if the element was added
794 dl 1.1 */
795     public boolean addIfAbsent(E e) {
796 jsr166 1.14 final SequenceLock lock = this.lock;
797 dl 1.1 lock.lock();
798     try {
799 dl 1.2 if (rawIndexOf(e, 0, count) < 0) {
800 dl 1.4 rawAdd(e);
801 jsr166 1.14 return true;
802 dl 1.1 }
803     else
804 jsr166 1.14 return false;
805 dl 1.1 } finally {
806     lock.unlock();
807     }
808     }
809    
810     /**
811     * Appends all of the elements in the specified collection that
812     * are not already contained in this list, to the end of
813     * this list, in the order that they are returned by the
814     * specified collection's iterator.
815     *
816     * @param c collection containing elements to be added to this list
817     * @return the number of elements added
818     * @throws NullPointerException if the specified collection is null
819     * @see #addIfAbsent(Object)
820     */
821     public int addAllAbsent(Collection<? extends E> c) {
822     int added = 0;
823     Object[] cs = c.toArray();
824     int clen = cs.length;
825     if (clen != 0) {
826     lock.lock();
827     try {
828     for (int i = 0; i < clen; ++i) {
829 jsr166 1.14 @SuppressWarnings("unchecked")
830     E e = (E) cs[i];
831 dl 1.2 if (rawIndexOf(e, 0, count) < 0) {
832 dl 1.4 rawAdd(e);
833 dl 1.1 ++added;
834     }
835     }
836     } finally {
837     lock.unlock();
838     }
839     }
840     return added;
841     }
842    
843 dl 1.5 /**
844     * Returns an iterator operating over a snapshot copy of the
845     * elements of this collection created upon construction of the
846     * iterator. The iterator does <em>NOT</em> support the
847 jsr166 1.9 * {@code remove} method.
848 dl 1.5 *
849     * @return an iterator over the elements in this list in proper sequence
850     */
851     public Iterator<E> snapshotIterator() {
852     return new SnapshotIterator<E>(this);
853     }
854    
855     static final class SnapshotIterator<E> implements Iterator<E> {
856 jsr166 1.14 private final Object[] items;
857     private int cursor;
858 dl 1.5 SnapshotIterator(ReadMostlyVector<E> v) { items = v.toArray(); }
859     public boolean hasNext() { return cursor < items.length; }
860 jsr166 1.14 @SuppressWarnings("unchecked")
861 dl 1.5 public E next() {
862     if (cursor < items.length)
863     return (E) items[cursor++];
864     throw new NoSuchElementException();
865     }
866     public void remove() { throw new UnsupportedOperationException() ; }
867     }
868    
869 dl 1.1 // Vector-only methods
870    
871     /** See {@link Vector#firstElement} */
872     public E firstElement() {
873 jsr166 1.14 final SequenceLock lock = this.lock;
874 dl 1.1 for (;;) {
875     long seq = lock.awaitAvailability();
876     Object[] items = array;
877     int len = items.length;
878 dl 1.2 int n = count;
879     if (n > len)
880 dl 1.1 continue;
881 jsr166 1.14 boolean empty = (n == 0);
882     @SuppressWarnings("unchecked")
883     E e = empty ? null : (E) items[0];
884 dl 1.1 if (lock.getSequence() == seq) {
885 jsr166 1.14 if (empty)
886 dl 1.1 throw new NoSuchElementException();
887     else
888 jsr166 1.14 return e;
889 dl 1.1 }
890     }
891     }
892    
893     /** See {@link Vector#lastElement} */
894     public E lastElement() {
895 jsr166 1.14 final SequenceLock lock = this.lock;
896 dl 1.1 for (;;) {
897     long seq = lock.awaitAvailability();
898     Object[] items = array;
899     int len = items.length;
900 dl 1.2 int n = count;
901     if (n > len)
902 dl 1.1 continue;
903 jsr166 1.14 boolean empty = (n == 0);
904     @SuppressWarnings("unchecked")
905     E e = empty ? null : (E) items[n - 1];
906 dl 1.1 if (lock.getSequence() == seq) {
907 jsr166 1.14 if (empty)
908 dl 1.1 throw new NoSuchElementException();
909     else
910 jsr166 1.14 return e;
911 dl 1.1 }
912     }
913     }
914    
915     /** See {@link Vector#indexOf(Object, int)} */
916     public int indexOf(Object o, int index) {
917 jsr166 1.14 final SequenceLock lock = this.lock;
918 dl 1.1 int idx = 0;
919     boolean ex = false;
920     long seq = lock.awaitAvailability();
921     Object[] items = array;
922 dl 1.2 int n = count;
923 dl 1.1 boolean retry = false;
924 dl 1.2 if (n > items.length)
925 dl 1.1 retry = true;
926     else if (index < 0)
927     ex = true;
928     else
929 dl 1.2 idx = validatedIndexOf(o, items, index, n, seq);
930 dl 1.1 if (retry || lock.getSequence() != seq) {
931     lock.lock();
932     try {
933     if (index < 0)
934     ex = true;
935     else
936 jsr166 1.16 idx = rawIndexOf(o, index, count);
937 dl 1.1 } finally {
938     lock.unlock();
939     }
940     }
941     if (ex)
942     throw new ArrayIndexOutOfBoundsException(index);
943     return idx;
944     }
945    
946     /** See {@link Vector#lastIndexOf(Object, int)} */
947     public int lastIndexOf(Object o, int index) {
948 jsr166 1.14 final SequenceLock lock = this.lock;
949 dl 1.1 int idx = 0;
950     boolean ex = false;
951     long seq = lock.awaitAvailability();
952     Object[] items = array;
953 dl 1.2 int n = count;
954 dl 1.1 boolean retry = false;
955 dl 1.2 if (n > items.length)
956 dl 1.1 retry = true;
957 dl 1.2 else if (index >= n)
958 dl 1.1 ex = true;
959     else
960 dl 1.2 idx = validatedLastIndexOf(o, items, index, 0, seq);
961 dl 1.1 if (retry || lock.getSequence() != seq) {
962     lock.lock();
963     try {
964     if (index >= count)
965     ex = true;
966     else
967 dl 1.2 idx = rawLastIndexOf(o, index, 0);
968 dl 1.1 } finally {
969     lock.unlock();
970     }
971     }
972     if (ex)
973     throw new ArrayIndexOutOfBoundsException(index);
974     return idx;
975     }
976    
977     /** See {@link Vector#setSize} */
978     public void setSize(int newSize) {
979     if (newSize < 0)
980     throw new ArrayIndexOutOfBoundsException(newSize);
981 jsr166 1.14 final SequenceLock lock = this.lock;
982 dl 1.1 lock.lock();
983     try {
984 dl 1.2 int n = count;
985     if (newSize > n)
986 dl 1.1 grow(newSize);
987     else {
988 dl 1.11 Object[] items = array;
989 dl 1.2 for (int i = newSize ; i < n ; i++)
990 dl 1.11 items[i] = null;
991 dl 1.1 }
992     count = newSize;
993     } finally {
994     lock.unlock();
995     }
996     }
997    
998     /** See {@link Vector#copyInto} */
999     public void copyInto(Object[] anArray) {
1000 jsr166 1.14 final SequenceLock lock = this.lock;
1001 dl 1.1 lock.lock();
1002     try {
1003     System.arraycopy(array, 0, anArray, 0, count);
1004     } finally {
1005     lock.unlock();
1006     }
1007     }
1008    
1009     /** See {@link Vector#trimToSize} */
1010     public void trimToSize() {
1011 jsr166 1.14 final SequenceLock lock = this.lock;
1012 dl 1.1 lock.lock();
1013     try {
1014 dl 1.11 Object[] items = array;
1015 dl 1.12 int n = count;
1016     if (n < items.length)
1017     array = Arrays.copyOf(items, n);
1018 dl 1.1 } finally {
1019     lock.unlock();
1020     }
1021     }
1022    
1023     /** See {@link Vector#ensureCapacity} */
1024     public void ensureCapacity(int minCapacity) {
1025     if (minCapacity > 0) {
1026 jsr166 1.14 final SequenceLock lock = this.lock;
1027 dl 1.1 lock.lock();
1028     try {
1029     if (minCapacity - array.length > 0)
1030     grow(minCapacity);
1031     } finally {
1032     lock.unlock();
1033     }
1034     }
1035     }
1036    
1037     /** See {@link Vector#elements} */
1038     public Enumeration<E> elements() {
1039 jsr166 1.10 return new Itr<E>(this, 0);
1040 dl 1.1 }
1041    
1042     /** See {@link Vector#capacity} */
1043     public int capacity() {
1044     return array.length;
1045     }
1046    
1047     /** See {@link Vector#elementAt} */
1048     public E elementAt(int index) {
1049     return get(index);
1050     }
1051    
1052     /** See {@link Vector#setElementAt} */
1053     public void setElementAt(E obj, int index) {
1054     set(index, obj);
1055     }
1056    
1057     /** See {@link Vector#removeElementAt} */
1058     public void removeElementAt(int index) {
1059     remove(index);
1060     }
1061    
1062     /** See {@link Vector#insertElementAt} */
1063     public void insertElementAt(E obj, int index) {
1064     add(index, obj);
1065     }
1066    
1067     /** See {@link Vector#addElement} */
1068     public void addElement(E obj) {
1069     add(obj);
1070     }
1071    
1072     /** See {@link Vector#removeElement} */
1073     public boolean removeElement(Object obj) {
1074     return remove(obj);
1075     }
1076    
1077     /** See {@link Vector#removeAllElements} */
1078     public void removeAllElements() {
1079     clear();
1080     }
1081    
1082     // other methods
1083    
1084 jsr166 1.10 public ReadMostlyVector<E> clone() {
1085 jsr166 1.14 final SequenceLock lock = this.lock;
1086 dl 1.1 Object[] a = null;
1087     boolean retry = false;
1088     long seq = lock.awaitAvailability();
1089     Object[] items = array;
1090 dl 1.2 int n = count;
1091     if (n <= items.length)
1092     a = Arrays.copyOf(items, n);
1093 dl 1.1 else
1094     retry = true;
1095     if (retry || lock.getSequence() != seq) {
1096     lock.lock();
1097     try {
1098 dl 1.2 n = count;
1099     a = Arrays.copyOf(array, n);
1100 dl 1.1 } finally {
1101     lock.unlock();
1102     }
1103     }
1104 jsr166 1.10 return new ReadMostlyVector<E>(a, n, capacityIncrement);
1105 dl 1.1 }
1106    
1107     private void writeObject(java.io.ObjectOutputStream s)
1108     throws java.io.IOException {
1109 jsr166 1.14 final SequenceLock lock = this.lock;
1110 dl 1.1 lock.lock();
1111     try {
1112     s.defaultWriteObject();
1113     } finally {
1114     lock.unlock();
1115     }
1116     }
1117    
1118 jsr166 1.15 static final class Itr<E> implements ListIterator<E>, Enumeration<E> {
1119 dl 1.1 final ReadMostlyVector<E> list;
1120     final SequenceLock lock;
1121     Object[] items;
1122 jsr166 1.14 E next, prev;
1123 dl 1.1 long seq;
1124     int cursor;
1125     int fence;
1126     int lastRet;
1127 dl 1.2 boolean validNext, validPrev;
1128 dl 1.1
1129     Itr(ReadMostlyVector<E> list, int index) {
1130     this.list = list;
1131     this.lock = list.lock;
1132     this.cursor = index;
1133     this.lastRet = -1;
1134     refresh();
1135     if (index < 0 || index > fence)
1136     throw new ArrayIndexOutOfBoundsException(index);
1137     }
1138    
1139     private void refresh() {
1140 dl 1.2 validNext = validPrev = false;
1141 dl 1.1 do {
1142     seq = lock.awaitAvailability();
1143     items = list.array;
1144 dl 1.2 } while ((fence = list.count) > items.length ||
1145     lock.getSequence() != seq);
1146 dl 1.1 }
1147    
1148 jsr166 1.14 @SuppressWarnings("unchecked")
1149 dl 1.1 public boolean hasNext() {
1150 dl 1.2 boolean valid;
1151 dl 1.1 int i = cursor;
1152 dl 1.2 for (;;) {
1153     if (i >= fence || i < 0 || i >= items.length) {
1154     valid = false;
1155     break;
1156     }
1157 jsr166 1.14 next = (E) items[i];
1158 dl 1.1 if (lock.getSequence() == seq) {
1159 dl 1.2 valid = true;
1160     break;
1161 dl 1.1 }
1162     refresh();
1163     }
1164 dl 1.2 return validNext = valid;
1165 dl 1.1 }
1166    
1167 jsr166 1.14 @SuppressWarnings("unchecked")
1168 dl 1.1 public boolean hasPrevious() {
1169 dl 1.2 boolean valid;
1170     int i = cursor - 1;
1171     for (;;) {
1172     if (i >= fence || i < 0 || i >= items.length) {
1173     valid = false;
1174     break;
1175     }
1176 jsr166 1.14 prev = (E) items[i];
1177 dl 1.1 if (lock.getSequence() == seq) {
1178 dl 1.2 valid = true;
1179     break;
1180 dl 1.1 }
1181     refresh();
1182     }
1183 dl 1.2 return validPrev = valid;
1184 dl 1.1 }
1185    
1186     public E next() {
1187 dl 1.2 if (validNext || hasNext()) {
1188     validNext = false;
1189     lastRet = cursor++;
1190 jsr166 1.14 return next;
1191 dl 1.2 }
1192     throw new NoSuchElementException();
1193 dl 1.1 }
1194    
1195     public E previous() {
1196 dl 1.2 if (validPrev || hasPrevious()) {
1197     validPrev = false;
1198     lastRet = cursor--;
1199 jsr166 1.14 return prev;
1200 dl 1.2 }
1201     throw new NoSuchElementException();
1202 dl 1.1 }
1203    
1204     public void remove() {
1205     int i = lastRet;
1206     if (i < 0)
1207     throw new IllegalStateException();
1208     lock.lock();
1209     try {
1210     if (i < list.count)
1211     list.remove(i);
1212     } finally {
1213     lock.unlock();
1214     }
1215     cursor = i;
1216     lastRet = -1;
1217     refresh();
1218     }
1219    
1220     public void set(E e) {
1221     int i = lastRet;
1222     if (i < 0)
1223     throw new IllegalStateException();
1224     lock.lock();
1225     try {
1226     if (i < list.count)
1227     list.set(i, e);
1228     } finally {
1229     lock.unlock();
1230     }
1231     refresh();
1232     }
1233    
1234     public void add(E e) {
1235     int i = cursor;
1236     if (i < 0)
1237     throw new IllegalStateException();
1238     lock.lock();
1239     try {
1240     if (i <= list.count)
1241     list.add(i, e);
1242     } finally {
1243     lock.unlock();
1244     }
1245     cursor = i + 1;
1246     lastRet = -1;
1247     refresh();
1248     }
1249    
1250     public boolean hasMoreElements() { return hasNext(); }
1251     public E nextElement() { return next(); }
1252     public int nextIndex() { return cursor; }
1253     public int previousIndex() { return cursor - 1; }
1254     }
1255    
1256 jsr166 1.14 static final class ReadMostlyVectorSublist<E>
1257     implements List<E>, RandomAccess, java.io.Serializable {
1258     static final long serialVersionUID = 3041673470172026059L;
1259    
1260 dl 1.1 final ReadMostlyVector<E> list;
1261     final int offset;
1262     volatile int size;
1263    
1264 jsr166 1.14 ReadMostlyVectorSublist(ReadMostlyVector<E> list,
1265     int offset, int size) {
1266 dl 1.1 this.list = list;
1267     this.offset = offset;
1268     this.size = size;
1269     }
1270    
1271     private void rangeCheck(int index) {
1272     if (index < 0 || index >= size)
1273     throw new ArrayIndexOutOfBoundsException(index);
1274     }
1275    
1276     public boolean add(E element) {
1277 jsr166 1.14 final SequenceLock lock = list.lock;
1278 dl 1.1 lock.lock();
1279     try {
1280     int c = size;
1281 dl 1.4 list.rawAddAt(c + offset, element);
1282 dl 1.1 size = c + 1;
1283     } finally {
1284     lock.unlock();
1285     }
1286     return true;
1287     }
1288    
1289     public void add(int index, E element) {
1290 jsr166 1.14 final SequenceLock lock = list.lock;
1291 dl 1.1 lock.lock();
1292     try {
1293     if (index < 0 || index > size)
1294     throw new ArrayIndexOutOfBoundsException(index);
1295 dl 1.4 list.rawAddAt(index + offset, element);
1296 dl 1.1 ++size;
1297     } finally {
1298     lock.unlock();
1299     }
1300     }
1301    
1302     public boolean addAll(Collection<? extends E> c) {
1303     Object[] elements = c.toArray();
1304 jsr166 1.14 final SequenceLock lock = list.lock;
1305 dl 1.1 lock.lock();
1306     try {
1307     int s = size;
1308     int pc = list.count;
1309 dl 1.4 list.rawAddAllAt(offset + s, elements);
1310 jsr166 1.14 int added = list.count - pc;
1311 dl 1.1 size = s + added;
1312 jsr166 1.14 return added != 0;
1313 dl 1.1 } finally {
1314     lock.unlock();
1315     }
1316     }
1317    
1318     public boolean addAll(int index, Collection<? extends E> c) {
1319     Object[] elements = c.toArray();
1320 jsr166 1.14 final SequenceLock lock = list.lock;
1321 dl 1.1 lock.lock();
1322     try {
1323     int s = size;
1324     if (index < 0 || index > s)
1325     throw new ArrayIndexOutOfBoundsException(index);
1326     int pc = list.count;
1327 dl 1.4 list.rawAddAllAt(index + offset, elements);
1328 jsr166 1.14 int added = list.count - pc;
1329 dl 1.1 size = s + added;
1330 jsr166 1.14 return added != 0;
1331 dl 1.1 } finally {
1332     lock.unlock();
1333     }
1334     }
1335    
1336     public void clear() {
1337 jsr166 1.14 final SequenceLock lock = list.lock;
1338 dl 1.1 lock.lock();
1339     try {
1340 dl 1.2 list.internalClear(offset, offset + size);
1341 dl 1.1 size = 0;
1342     } finally {
1343     lock.unlock();
1344     }
1345     }
1346    
1347     public boolean contains(Object o) {
1348     return indexOf(o) >= 0;
1349     }
1350    
1351     public boolean containsAll(Collection<?> c) {
1352 dl 1.2 return list.internalContainsAll(c, offset, offset + size);
1353 dl 1.1 }
1354    
1355     public boolean equals(Object o) {
1356     if (o == this)
1357     return true;
1358     if (!(o instanceof List))
1359     return false;
1360 dl 1.2 return list.internalEquals((List<?>)(o), offset, offset + size);
1361 dl 1.1 }
1362    
1363     public E get(int index) {
1364     if (index < 0 || index >= size)
1365     throw new ArrayIndexOutOfBoundsException(index);
1366     return list.get(index + offset);
1367     }
1368    
1369     public int hashCode() {
1370 dl 1.2 return list.internalHashCode(offset, offset + size);
1371 dl 1.1 }
1372    
1373     public int indexOf(Object o) {
1374 jsr166 1.14 final SequenceLock lock = list.lock;
1375 dl 1.1 long seq = lock.awaitAvailability();
1376     Object[] items = list.array;
1377     int c = list.count;
1378     if (c <= items.length) {
1379 dl 1.4 int idx = list.validatedIndexOf(o, items, offset,
1380     offset + size, seq);
1381 dl 1.1 if (lock.getSequence() == seq)
1382     return idx < 0 ? -1 : idx - offset;
1383     }
1384     lock.lock();
1385     try {
1386 dl 1.4 int idx = list.rawIndexOf(o, offset, offset + size);
1387 dl 1.1 return idx < 0 ? -1 : idx - offset;
1388     } finally {
1389     lock.unlock();
1390     }
1391     }
1392    
1393     public boolean isEmpty() {
1394     return size == 0;
1395     }
1396    
1397     public Iterator<E> iterator() {
1398 jsr166 1.10 return new SubItr<E>(this, offset);
1399 dl 1.1 }
1400    
1401     public int lastIndexOf(Object o) {
1402 jsr166 1.14 final SequenceLock lock = list.lock;
1403 dl 1.1 long seq = lock.awaitAvailability();
1404     Object[] items = list.array;
1405     int c = list.count;
1406     if (c <= items.length) {
1407 jsr166 1.3 int idx = list.validatedLastIndexOf(o, items, offset+size-1,
1408 dl 1.2 offset, seq);
1409 dl 1.1 if (lock.getSequence() == seq)
1410     return idx < 0 ? -1 : idx - offset;
1411     }
1412     lock.lock();
1413     try {
1414 dl 1.2 int idx = list.rawLastIndexOf(o, offset + size - 1, offset);
1415 dl 1.1 return idx < 0 ? -1 : idx - offset;
1416     } finally {
1417     lock.unlock();
1418     }
1419     }
1420    
1421     public ListIterator<E> listIterator() {
1422 jsr166 1.10 return new SubItr<E>(this, offset);
1423 dl 1.1 }
1424    
1425     public ListIterator<E> listIterator(int index) {
1426 jsr166 1.10 return new SubItr<E>(this, index + offset);
1427 dl 1.1 }
1428    
1429     public E remove(int index) {
1430 jsr166 1.14 final SequenceLock lock = list.lock;
1431 dl 1.1 lock.lock();
1432     try {
1433 dl 1.4 Object[] items = list.array;
1434     int i = index + offset;
1435     if (index < 0 || index >= size || i >= items.length)
1436 dl 1.1 throw new ArrayIndexOutOfBoundsException(index);
1437 jsr166 1.14 @SuppressWarnings("unchecked")
1438     E result = (E) items[i];
1439 dl 1.4 list.rawRemoveAt(i);
1440 dl 1.1 size--;
1441 jsr166 1.14 return result;
1442 dl 1.1 } finally {
1443     lock.unlock();
1444     }
1445     }
1446    
1447     public boolean remove(Object o) {
1448 jsr166 1.14 final SequenceLock lock = list.lock;
1449 dl 1.1 lock.lock();
1450     try {
1451 dl 1.4 if (list.rawRemoveAt(list.rawIndexOf(o, offset,
1452     offset + size))) {
1453 dl 1.1 --size;
1454 jsr166 1.14 return true;
1455 dl 1.1 }
1456 jsr166 1.14 else
1457     return false;
1458 dl 1.1 } finally {
1459     lock.unlock();
1460     }
1461     }
1462    
1463     public boolean removeAll(Collection<?> c) {
1464 dl 1.2 return list.internalRemoveAll(c, offset, offset + size);
1465 dl 1.1 }
1466    
1467     public boolean retainAll(Collection<?> c) {
1468 dl 1.2 return list.internalRetainAll(c, offset, offset + size);
1469 dl 1.1 }
1470    
1471     public E set(int index, E element) {
1472     if (index < 0 || index >= size)
1473     throw new ArrayIndexOutOfBoundsException(index);
1474     return list.set(index+offset, element);
1475     }
1476    
1477     public int size() {
1478     return size;
1479     }
1480    
1481     public List<E> subList(int fromIndex, int toIndex) {
1482     int c = size;
1483     int ssize = toIndex - fromIndex;
1484     if (fromIndex < 0 || toIndex > c || ssize < 0)
1485     throw new IndexOutOfBoundsException();
1486 jsr166 1.10 return new ReadMostlyVectorSublist<E>(list, offset+fromIndex, ssize);
1487 dl 1.1 }
1488    
1489     public Object[] toArray() {
1490 dl 1.2 return list.internalToArray(offset, offset + size);
1491 dl 1.1 }
1492    
1493     public <T> T[] toArray(T[] a) {
1494 dl 1.2 return list.internalToArray(a, offset, offset + size);
1495 dl 1.1 }
1496    
1497     public String toString() {
1498 dl 1.2 return list.internalToString(offset, offset + size);
1499 dl 1.1 }
1500    
1501     }
1502    
1503     static final class SubItr<E> implements ListIterator<E> {
1504     final ReadMostlyVectorSublist<E> sublist;
1505     final ReadMostlyVector<E> list;
1506     final SequenceLock lock;
1507     Object[] items;
1508 jsr166 1.14 E next, prev;
1509 dl 1.1 long seq;
1510     int cursor;
1511     int fence;
1512     int lastRet;
1513 dl 1.2 boolean validNext, validPrev;
1514 dl 1.1
1515     SubItr(ReadMostlyVectorSublist<E> sublist, int index) {
1516     this.sublist = sublist;
1517     this.list = sublist.list;
1518     this.lock = list.lock;
1519     this.cursor = index;
1520     this.lastRet = -1;
1521     refresh();
1522     if (index < 0 || index > fence)
1523     throw new ArrayIndexOutOfBoundsException(index);
1524     }
1525    
1526     private void refresh() {
1527 dl 1.2 validNext = validPrev = false;
1528 dl 1.1 do {
1529 dl 1.2 int n;
1530 dl 1.1 seq = lock.awaitAvailability();
1531     items = list.array;
1532 dl 1.2 if ((n = list.count) > items.length)
1533     continue;
1534 dl 1.1 int b = sublist.offset + sublist.size;
1535 dl 1.2 fence = b < n ? b : n;
1536 dl 1.1 } while (lock.getSequence() != seq);
1537     }
1538    
1539 jsr166 1.14 @SuppressWarnings("unchecked")
1540 dl 1.1 public boolean hasNext() {
1541 dl 1.2 boolean valid;
1542 dl 1.1 int i = cursor;
1543 dl 1.2 for (;;) {
1544     if (i >= fence || i < 0 || i >= items.length) {
1545     valid = false;
1546     break;
1547     }
1548 jsr166 1.14 next = (E) items[i];
1549 dl 1.1 if (lock.getSequence() == seq) {
1550 dl 1.2 valid = true;
1551     break;
1552 dl 1.1 }
1553     refresh();
1554     }
1555 dl 1.2 return validNext = valid;
1556 dl 1.1 }
1557    
1558 jsr166 1.14 @SuppressWarnings("unchecked")
1559 dl 1.1 public boolean hasPrevious() {
1560 dl 1.2 boolean valid;
1561     int i = cursor - 1;
1562     for (;;) {
1563     if (i >= fence || i < 0 || i >= items.length) {
1564     valid = false;
1565     break;
1566     }
1567 jsr166 1.14 prev = (E) items[i];
1568 dl 1.1 if (lock.getSequence() == seq) {
1569 dl 1.2 valid = true;
1570     break;
1571 dl 1.1 }
1572     refresh();
1573     }
1574 dl 1.2 return validPrev = valid;
1575 dl 1.1 }
1576    
1577     public E next() {
1578 dl 1.2 if (validNext || hasNext()) {
1579     validNext = false;
1580     lastRet = cursor++;
1581 jsr166 1.14 return next;
1582 dl 1.2 }
1583     throw new NoSuchElementException();
1584 dl 1.1 }
1585    
1586     public E previous() {
1587 dl 1.2 if (validPrev || hasPrevious()) {
1588     validPrev = false;
1589     lastRet = cursor--;
1590 jsr166 1.14 return prev;
1591 dl 1.2 }
1592     throw new NoSuchElementException();
1593 dl 1.1 }
1594    
1595     public int nextIndex() {
1596     return cursor - sublist.offset;
1597     }
1598    
1599     public int previousIndex() {
1600     return cursor - 1 - sublist.offset;
1601     }
1602    
1603     public void remove() {
1604     int i = lastRet;
1605     if (i < 0)
1606     throw new IllegalStateException();
1607     cursor = i;
1608     lastRet = -1;
1609     lock.lock();
1610     try {
1611     if (i < list.count) {
1612     list.remove(i);
1613     --sublist.size;
1614     }
1615     } finally {
1616     lock.unlock();
1617     }
1618     refresh();
1619     }
1620    
1621     public void set(E e) {
1622     int i = lastRet;
1623     if (i < 0)
1624     throw new IllegalStateException();
1625     lock.lock();
1626     try {
1627     if (i < list.count)
1628     list.set(i, e);
1629     } finally {
1630     lock.unlock();
1631     }
1632     refresh();
1633     }
1634    
1635     public void add(E e) {
1636     int i = cursor;
1637     if (i < 0)
1638     throw new IllegalStateException();
1639     cursor = i + 1;
1640     lastRet = -1;
1641     lock.lock();
1642     try {
1643     if (i <= list.count) {
1644     list.add(i, e);
1645     ++sublist.size;
1646     }
1647     } finally {
1648     lock.unlock();
1649     }
1650     refresh();
1651     }
1652    
1653     }
1654     }
1655