ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/extra/ReadMostlyVector.java
Revision: 1.21
Committed: Sat Dec 31 19:26:24 2011 UTC (12 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.20: +5 -0 lines
Log Message:
clarify invariants in read-only mode

File Contents

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