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