ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/extra/ReadMostlyVector.java
Revision: 1.4
Committed: Sat Jul 16 15:05:04 2011 UTC (12 years, 10 months ago) by dl
Branch: MAIN
Changes since 1.3: +67 -55 lines
Log Message:
Various improvements

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