ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/extra/ReadMostlyVector.java
(Generate patch)

Comparing jsr166/src/jsr166e/extra/ReadMostlyVector.java (file contents):
Revision 1.5 by dl, Sat Jul 16 16:05:32 2011 UTC vs.
Revision 1.29 by jsr166, Fri Oct 12 16:23:28 2012 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines