ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/extra/ReadMostlyVector.java
Revision: 1.11
Committed: Wed Jul 20 20:29:33 2011 UTC (12 years, 11 months ago) by dl
Branch: MAIN
Changes since 1.10: +36 -26 lines
Log Message:
Add volatile to advice and sample code

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