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.2 by dl, Sat Jul 16 13:20:35 2011 UTC vs.
Revision 1.11 by dl, Wed Jul 20 20:29:33 2011 UTC

# Line 12 | Line 12 | import java.util.*;
12   * A class with the same methods and array-based characteristics as
13   * {@link java.util.Vector} but with reduced contention and improved
14   * throughput when invocations of read-only methods by multiple
15 < * threads are most common.
15 > * threads are most common.
16   *
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.
22 > * they appear in the underlying array upon each access. Alternatvely,
23 > * method {@link #snapshotIterator} may be used for deterministic
24 > * traversals, at the expense of making a copy, and unavailability of
25 > * method {@code Iterator.remove}.
26   *
27   * <p>Otherwise, this class supports all methods, under the same
28   * documented specifications, as {@code Vector}.  Consult {@link
# Line 40 | Line 43 | public class ReadMostlyVector<E> impleme
43       * Short methods,including get(index), continually retry obtaining
44       * a snapshot of array, count, and element, using sequence number
45       * to validate.
46 <     *
46 >     *
47       * Methods that are potentially O(n) (or worse) try once in
48       * read-only mode, and then lock. When in read-only mode, they
49       * validate only at the end of an array scan unless the element is
# Line 54 | Line 57 | public class ReadMostlyVector<E> impleme
57      private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
58  
59      // fields are non-private to simpify nested class access
60 <    Object[] array;
60 >    volatile Object[] array;
61      final SequenceLock lock;
62 <    int count;
62 >    volatile int count;
63      final int capacityIncrement;
64  
65      /**
# Line 151 | Line 154 | public class ReadMostlyVector<E> impleme
154       * as well as sublist and iterator classes.
155       */
156  
157 <    final int validatedIndexOf(Object x, Object[] items, int index, int fence,
157 >    // Version of indexOf that returns -1 if either not present or invalid
158 >    final int validatedIndexOf(Object x, Object[] items, int index, int fence,
159                                 long seq) {
160          for (int i = index; i < fence; ++i) {
161              Object e = items[i];
162              if (lock.getSequence() != seq)
163                  break;
164 <            if (x == null? e == null : (e != null && x.equals(e)))
164 >            if ((x == null) ? e == null : x.equals(e))
165                  return i;
166          }
167          return -1;
# Line 167 | Line 171 | public class ReadMostlyVector<E> impleme
171          Object[] items = array;
172          for (int i = index; i < fence; ++i) {
173              Object e = items[i];
174 <            if (x == null? e == null : (e != null && x.equals(e)))
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,
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 : (e != null && x.equals(e)))
186 >            if ((x == null) ? e == null : x.equals(e))
187                  return i;
188          }
189          return -1;
# Line 189 | Line 193 | public class ReadMostlyVector<E> impleme
193          Object[] items = array;
194          for (int i = index; i >= origin; --i) {
195              Object e = items[i];
196 <            if (x == null? e == null : (e != null && x.equals(e)))
196 >            if ((x == null) ? e == null : x.equals(e))
197                  return i;
198          }
199          return -1;
200      }
201  
202 <    final void internalAdd(Object e) {
202 >    final void rawAdd(Object e) {
203          int n = count;
204 <        if (n >= array.length)
204 >        Object[] items = array;
205 >        if (n < items.length)
206 >            items[n] = e;
207 >        else {
208              grow(n + 1);
209 <        array[n] = e;
209 >            array[n] = e;
210 >        }
211          count = n + 1;
212      }
213  
214 <    final void internalAddAt(int index, Object e) {
214 >    final void rawAddAt(int index, Object e) {
215          int n = count;
216          if (index > n)
217              throw new ArrayIndexOutOfBoundsException(index);
218          if (n >= array.length)
219              grow(n + 1);
220 +        Object[] items = array;
221          if (index < n)
222 <            System.arraycopy(array, index, array, index + 1, n - index);
223 <        array[index] = e;
222 >            System.arraycopy(items, index, items, index + 1, n - index);
223 >        items[index] = e;
224          count = n + 1;
225      }
226  
227 <    final boolean internalAddAllAt(int index, Object[] elements) {
227 >    final boolean rawAddAllAt(int index, Object[] elements) {
228          int n = count;
229          if (index < 0 || index > n)
230              throw new ArrayIndexOutOfBoundsException(index);
# Line 225 | Line 234 | public class ReadMostlyVector<E> impleme
234          int newCount = n + len;
235          if (newCount >= array.length)
236              grow(newCount);
237 <        int mv = count - index;
237 >        Object[] items = array;
238 >        int mv = n - index;
239          if (mv > 0)
240 <            System.arraycopy(array, index, array, index + len, mv);
241 <        System.arraycopy(elements, 0, array, index, len);
240 >            System.arraycopy(items, index, items, index + len, mv);
241 >        System.arraycopy(elements, 0, items, index, len);
242          count = newCount;
243          return true;
244      }
245  
246 <    final boolean internalRemoveAt(int index) {
246 >    final boolean rawRemoveAt(int index) {
247 >        Object[] items = array;
248          int n = count - 1;
249          if (index < 0 || index > n)
250              return false;
251          int mv = n - index;
252          if (mv > 0)
253 <            System.arraycopy(array, index + 1, array, index, mv);
254 <        array[n] = null;
253 >            System.arraycopy(items, index + 1, items, index, mv);
254 >        items[n] = null;
255          count = n;
256          return true;
257      }
# Line 261 | Line 272 | public class ReadMostlyVector<E> impleme
272              int fence = bound < 0 || bound > n ? n : bound;
273              if (origin >= 0 && origin < fence) {
274                  for (Object x : c) {
275 <                    while (internalRemoveAt(rawIndexOf(x, origin, fence)))
275 >                    while (rawRemoveAt(rawIndexOf(x, origin, fence)))
276                          removed = true;
277                  }
278              }
# Line 277 | Line 288 | public class ReadMostlyVector<E> impleme
288          if (c != this) {
289              lock.lock();
290              try {
291 +                Object[] items = array;
292                  int i = origin;
293                  int n = count;
294                  int fence = bound < 0 || bound > n ? n : bound;
295 <                while (i < fence) {
296 <                    if (c.contains(array[i]))
295 >                while (i >= 0 && i < fence) {
296 >                    if (c.contains(items[i]))
297                          ++i;
298                      else {
299                          --fence;
300                          int mv = --count - i;
301                          if (mv > 0)
302 <                            System.arraycopy(array, i + 1, array, i, mv);
302 >                            System.arraycopy(items, i + 1, items, i, mv);
303                          removed = true;
304                      }
305                  }
# Line 299 | Line 311 | public class ReadMostlyVector<E> impleme
311      }
312  
313      final void internalClear(int origin, int bound) {
314 +        Object[] items = array;
315          int n = count;
316          int fence = bound < 0 || bound > n ? n : bound;
317          if (origin >= 0 && origin < fence) {
# Line 306 | Line 319 | public class ReadMostlyVector<E> impleme
319              int newCount = n - removed;
320              int mv = n - (origin + removed);
321              if (mv > 0)
322 <                System.arraycopy(array, origin + removed, array, origin, mv);
322 >                System.arraycopy(items, origin + removed, items, origin, mv);
323              for (int i = n; i < newCount; ++i)
324 <                array[i] = null;
324 >                items[i] = null;
325              count = newCount;
326          }
327      }
# Line 331 | Line 344 | public class ReadMostlyVector<E> impleme
344                  else {
345                      contained = true;
346                      for (Object e : c) {
347 <                        if (validatedIndexOf(e, items, origin, fence, seq) < 0) {
347 >                        int idx = (locked ?
348 >                                   rawIndexOf(e, origin, fence) :
349 >                                   validatedIndexOf(e, items, origin,
350 >                                                    fence, seq));
351 >                        if (idx < 0) {
352                              contained = false;
353                              break;
354                          }
# Line 351 | Line 368 | public class ReadMostlyVector<E> impleme
368  
369      final boolean internalEquals(List<?> list, int origin, int bound) {
370          SequenceLock lock = this.lock;
354        boolean equal;
371          boolean locked = false;
372 +        boolean equal;
373          try {
374 <            outer:for (;;) {
358 <                equal = true;
374 >            for (;;) {
375                  long seq = lock.awaitAvailability();
376                  Object[] items = array;
361                int len = items.length;
377                  int n = count;
378 <                if (n > len)
364 <                    continue;
365 <                int fence = bound < 0 || bound > n ? n : bound;
366 <                if (origin < 0)
378 >                if (n > items.length || origin < 0)
379                      equal = false;
380                  else {
381 +                    equal = true;
382 +                    int fence = bound < 0 || bound > n ? n : bound;
383                      Iterator<?> it = list.iterator();
384                      for (int i = origin; i < fence; ++i) {
385 <                        if (!it.hasNext()) {
386 <                            equal = false;
387 <                            break;
388 <                        }
389 <                        Object x = it.next();
390 <                        Object y = items[i];
377 <                        if (lock.getSequence() != seq)
378 <                            continue outer;
379 <                        if (x == null? y != null : (y == null || !x.equals(y))) {
385 >                        Object x = items[i];
386 >                        Object y;
387 >                        if ((!locked && lock.getSequence() != seq) ||
388 >                            !it.hasNext() ||
389 >                            (y = it.next()) == null ?
390 >                            x != null : !y.equals(x)) {
391                              equal = false;
392                              break;
393                          }
# Line 450 | Line 461 | public class ReadMostlyVector<E> impleme
461                          Object e = items[i];
462                          if (e == this)
463                              sb.append("(this Collection)");
464 <                        else if (lock.getSequence() != seq)
464 >                        else if (!locked && lock.getSequence() != seq)
465                              continue outer;
466                          else
467                              sb.append(e.toString());
# Line 518 | Line 529 | public class ReadMostlyVector<E> impleme
529                      continue;
530                  int fence = bound < 0 || bound > n ? n : bound;
531                  int rlen = fence - origin;
532 +                if (rlen < 0)
533 +                    rlen = 0;
534                  if (origin < 0 || alen >= rlen) {
535 <                    if (rlen < 0)
536 <                        rlen = 0;
524 <                    else if (rlen > 0)
525 <                        System.arraycopy(array, 0, a, origin, rlen);
535 >                    if (rlen > 0)
536 >                        System.arraycopy(items, 0, a, origin, rlen);
537                      if (alen > rlen)
538                          a[rlen] = null;
539                      result = a;
540                  }
541 <                else
542 <                    result = (T[]) Arrays.copyOfRange(array, origin,
541 >                else
542 >                    result = (T[]) Arrays.copyOfRange(items, origin,
543                                                        fence, a.getClass());
544                  if (lock.getSequence() == seq)
545                      break;
# Line 548 | Line 559 | public class ReadMostlyVector<E> impleme
559          SequenceLock lock = this.lock;
560          lock.lock();
561          try {
562 <            internalAdd(e);
562 >            rawAdd(e);
563          } finally {
564              lock.unlock();
565          }
# Line 559 | Line 570 | public class ReadMostlyVector<E> impleme
570          SequenceLock lock = this.lock;
571          lock.lock();
572          try {
573 <            internalAddAt(index, element);
573 >            rawAddAt(index, element);
574          } finally {
575              lock.unlock();
576          }
# Line 590 | Line 601 | public class ReadMostlyVector<E> impleme
601          Object[] elements = c.toArray();
602          lock.lock();
603          try {
604 <            ret = internalAddAllAt(index, elements);
604 >            ret = rawAddAllAt(index, elements);
605          } finally {
606              lock.unlock();
607          }
# Line 601 | Line 612 | public class ReadMostlyVector<E> impleme
612          SequenceLock lock = this.lock;
613          lock.lock();
614          try {
615 +            Object[] items = array;
616              for (int i = 0; i < count; i++)
617 <                array[i] = null;
617 >                items[i] = null;
618              count = 0;
619          } finally {
620              lock.unlock();
# Line 622 | Line 634 | public class ReadMostlyVector<E> impleme
634              return true;
635          if (!(o instanceof List))
636              return false;
637 <        return internalEquals((List<?>)(o), 0, -1);
637 >        return internalEquals((List<?>)o, 0, -1);
638      }
639  
640      public E get(int index) {
# Line 657 | Line 669 | public class ReadMostlyVector<E> impleme
669  
670      public int indexOf(Object o) {
671          SequenceLock lock = this.lock;
672 <        long seq = lock.awaitAvailability();
673 <        Object[] items = array;
674 <        int n = count;
675 <        if (n <= items.length) {
676 <            int idx = validatedIndexOf(o, items, 0, n, seq);
677 <            if (lock.getSequence() == seq)
678 <                return idx;
679 <        }
680 <        lock.lock();
681 <        try {
682 <            return rawIndexOf(o, 0, count);
683 <        } finally {
684 <            lock.unlock();
672 >        for (;;) {
673 >            long seq = lock.awaitAvailability();
674 >            Object[] items = array;
675 >            int n = count;
676 >            if (n <= items.length) {
677 >                for (int i = 0; i < n; ++i) {
678 >                    Object e = items[i];
679 >                    if (lock.getSequence() != seq) {
680 >                        lock.lock();
681 >                        try {
682 >                            return rawIndexOf(o, 0, count);
683 >                        } finally {
684 >                            lock.unlock();
685 >                        }
686 >                    }
687 >                    else if ((o == null) ? e == null : o.equals(e))
688 >                        return i;
689 >                }
690 >                return -1;
691 >            }
692          }
693      }
694  
695      public boolean isEmpty() {
677        long ignore = lock.getSequence();
696          return count == 0;
697      }
698  
699      public Iterator<E> iterator() {
700 <        return new Itr(this, 0);
700 >        return new Itr<E>(this, 0);
701      }
702  
703      public int lastIndexOf(Object o) {
704          SequenceLock lock = this.lock;
705 <        long seq = lock.awaitAvailability();
706 <        Object[] items = array;
707 <        int n = count;
708 <        if (n <= items.length) {
709 <            int idx = validatedLastIndexOf(o, items, n - 1, 0, seq);
710 <            if (lock.getSequence() == seq)
711 <                return idx;
712 <        }
713 <        lock.lock();
714 <        try {
715 <            return rawLastIndexOf(o, count - 1, 0);
716 <        } finally {
717 <            lock.unlock();
705 >        for (;;) {
706 >            long seq = lock.awaitAvailability();
707 >            Object[] items = array;
708 >            int n = count;
709 >            if (n <= items.length) {
710 >                for (int i = n - 1; i >= 0; --i) {
711 >                    Object e = items[i];
712 >                    if (lock.getSequence() != seq) {
713 >                        lock.lock();
714 >                        try {
715 >                            return rawLastIndexOf(o, 0, count);
716 >                        } finally {
717 >                            lock.unlock();
718 >                        }
719 >                    }
720 >                    else if ((o == null) ? e == null : o.equals(e))
721 >                        return i;
722 >                }
723 >                return -1;
724 >            }
725          }
726      }
727  
728      public ListIterator<E> listIterator() {
729 <        return new Itr(this, 0);
729 >        return new Itr<E>(this, 0);
730      }
731  
732      public ListIterator<E> listIterator(int index) {
733 <        return new Itr(this, index);
733 >        return new Itr<E>(this, index);
734      }
735  
736      public E remove(int index) {
# Line 716 | Line 741 | public class ReadMostlyVector<E> impleme
741              if (index < 0 || index >= count)
742                  throw new ArrayIndexOutOfBoundsException(index);
743              oldValue = array[index];
744 <            internalRemoveAt(index);
744 >            rawRemoveAt(index);
745          } finally {
746              lock.unlock();
747          }
# Line 728 | Line 753 | public class ReadMostlyVector<E> impleme
753          boolean removed;
754          lock.lock();
755          try {
756 <            removed = internalRemoveAt(rawIndexOf(o, 0, count));
756 >            removed = rawRemoveAt(rawIndexOf(o, 0, count));
757          } finally {
758              lock.unlock();
759          }
# Line 748 | Line 773 | public class ReadMostlyVector<E> impleme
773          SequenceLock lock = this.lock;
774          lock.lock();
775          try {
776 +            Object[] items = array;
777              if (index < 0 || index >= count)
778                  throw new ArrayIndexOutOfBoundsException(index);
779 <            oldValue = array[index];
780 <            array[index] = element;
779 >            oldValue = items[index];
780 >            items[index] = element;
781          } finally {
782              lock.unlock();
783          }
# Line 759 | Line 785 | public class ReadMostlyVector<E> impleme
785      }
786  
787      public int size() {
762        long ignore = lock.getSequence();
788          return count;
789      }
790  
# Line 768 | Line 793 | public class ReadMostlyVector<E> impleme
793          int ssize = toIndex - fromIndex;
794          if (fromIndex < 0 || toIndex > c || ssize < 0)
795              throw new IndexOutOfBoundsException();
796 <        return new ReadMostlyVectorSublist(this, fromIndex, ssize);
796 >        return new ReadMostlyVectorSublist<E>(this, fromIndex, ssize);
797      }
798  
799      public Object[] toArray() {
# Line 789 | Line 814 | public class ReadMostlyVector<E> impleme
814       * Append the element if not present.
815       *
816       * @param e element to be added to this list, if absent
817 <     * @return <tt>true</tt> if the element was added
817 >     * @return {@code true} if the element was added
818       */
819      public boolean addIfAbsent(E e) {
820          boolean added;
# Line 797 | Line 822 | public class ReadMostlyVector<E> impleme
822          lock.lock();
823          try {
824              if (rawIndexOf(e, 0, count) < 0) {
825 <                internalAdd(e);
825 >                rawAdd(e);
826                  added = true;
827              }
828              else
# Line 829 | Line 854 | public class ReadMostlyVector<E> impleme
854                  for (int i = 0; i < clen; ++i) {
855                      Object e = cs[i];
856                      if (rawIndexOf(e, 0, count) < 0) {
857 <                        internalAdd(e);
857 >                        rawAdd(e);
858                          ++added;
859                      }
860                  }
# Line 840 | Line 865 | public class ReadMostlyVector<E> impleme
865          return added;
866      }
867  
868 +    /**
869 +     * Returns an iterator operating over a snapshot copy of the
870 +     * elements of this collection created upon construction of the
871 +     * iterator. The iterator does <em>NOT</em> support the
872 +     * {@code remove} method.
873 +     *
874 +     * @return an iterator over the elements in this list in proper sequence
875 +     */
876 +    public Iterator<E> snapshotIterator() {
877 +        return new SnapshotIterator<E>(this);
878 +    }
879 +
880 +    static final class SnapshotIterator<E> implements Iterator<E> {
881 +        final Object[] items;
882 +        int cursor;
883 +        SnapshotIterator(ReadMostlyVector<E> v) { items = v.toArray(); }
884 +        public boolean hasNext() { return cursor < items.length; }
885 +        public E next() {
886 +            if (cursor < items.length)
887 +                return (E) items[cursor++];
888 +            throw new NoSuchElementException();
889 +        }
890 +        public void remove() { throw new UnsupportedOperationException() ; }
891 +    }
892 +
893      // Vector-only methods
894  
895      /** See {@link Vector#firstElement} */
# Line 971 | Line 1021 | public class ReadMostlyVector<E> impleme
1021              if (newSize > n)
1022                  grow(newSize);
1023              else {
1024 +                Object[] items = array;
1025                  for (int i = newSize ; i < n ; i++)
1026 <                    array[i] = null;
1026 >                    items[i] = null;
1027              }
1028              count = newSize;
1029          } finally {
# Line 996 | Line 1047 | public class ReadMostlyVector<E> impleme
1047          SequenceLock lock = this.lock;
1048          lock.lock();
1049          try {
1050 <            if (count < array.length)
1051 <                array = Arrays.copyOf(array, count);
1050 >            Object[] items = array;
1051 >            if (count < items.length)
1052 >                array = Arrays.copyOf(items, count);
1053          } finally {
1054              lock.unlock();
1055          }
# Line 1019 | Line 1071 | public class ReadMostlyVector<E> impleme
1071  
1072      /** See {@link Vector#elements} */
1073      public Enumeration<E> elements() {
1074 <        return new Itr(this, 0);
1074 >        return new Itr<E>(this, 0);
1075      }
1076  
1077      /** See {@link Vector#capacity} */
1078      public int capacity() {
1027        long ignore = lock.getSequence();
1079          return array.length;
1080      }
1081  
# Line 1065 | Line 1116 | public class ReadMostlyVector<E> impleme
1116  
1117      // other methods
1118  
1119 <    public Object clone() {
1119 >    public ReadMostlyVector<E> clone() {
1120          SequenceLock lock = this.lock;
1121          Object[] a = null;
1122          boolean retry = false;
# Line 1085 | Line 1136 | public class ReadMostlyVector<E> impleme
1136                  lock.unlock();
1137              }
1138          }
1139 <        return new ReadMostlyVector(a, n, capacityIncrement);
1139 >        return new ReadMostlyVector<E>(a, n, capacityIncrement);
1140      }
1141  
1142      private void writeObject(java.io.ObjectOutputStream s)
# Line 1256 | Line 1307 | public class ReadMostlyVector<E> impleme
1307              lock.lock();
1308              try {
1309                  int c = size;
1310 <                list.internalAddAt(c + offset, element);
1310 >                list.rawAddAt(c + offset, element);
1311                  size = c + 1;
1312              } finally {
1313                  lock.unlock();
# Line 1270 | Line 1321 | public class ReadMostlyVector<E> impleme
1321              try {
1322                  if (index < 0 || index > size)
1323                      throw new ArrayIndexOutOfBoundsException(index);
1324 <                list.internalAddAt(index + offset, element);
1324 >                list.rawAddAt(index + offset, element);
1325                  ++size;
1326              } finally {
1327                  lock.unlock();
# Line 1285 | Line 1336 | public class ReadMostlyVector<E> impleme
1336              try {
1337                  int s = size;
1338                  int pc = list.count;
1339 <                list.internalAddAllAt(offset + s, elements);
1339 >                list.rawAddAllAt(offset + s, elements);
1340                  added = list.count - pc;
1341                  size = s + added;
1342              } finally {
# Line 1304 | Line 1355 | public class ReadMostlyVector<E> impleme
1355                  if (index < 0 || index > s)
1356                      throw new ArrayIndexOutOfBoundsException(index);
1357                  int pc = list.count;
1358 <                list.internalAddAllAt(index + offset, elements);
1358 >                list.rawAddAllAt(index + offset, elements);
1359                  added = list.count - pc;
1360                  size = s + added;
1361              } finally {
# Line 1356 | Line 1407 | public class ReadMostlyVector<E> impleme
1407              Object[] items = list.array;
1408              int c = list.count;
1409              if (c <= items.length) {
1410 <                int idx = list.validatedIndexOf(o, items, offset, offset+size, seq);
1410 >                int idx = list.validatedIndexOf(o, items, offset,
1411 >                                                offset + size, seq);
1412                  if (lock.getSequence() == seq)
1413                      return idx < 0 ? -1 : idx - offset;
1414              }
1415              lock.lock();
1416              try {
1417 <                int idx = list.rawIndexOf(o, offset, offset+size);
1417 >                int idx = list.rawIndexOf(o, offset, offset + size);
1418                  return idx < 0 ? -1 : idx - offset;
1419              } finally {
1420                  lock.unlock();
# Line 1374 | Line 1426 | public class ReadMostlyVector<E> impleme
1426          }
1427  
1428          public Iterator<E> iterator() {
1429 <            return new SubItr(this, offset);
1429 >            return new SubItr<E>(this, offset);
1430          }
1431  
1432          public int lastIndexOf(Object o) {
# Line 1383 | Line 1435 | public class ReadMostlyVector<E> impleme
1435              Object[] items = list.array;
1436              int c = list.count;
1437              if (c <= items.length) {
1438 <                int idx = list.validatedLastIndexOf(o, items, offset+size-1,
1438 >                int idx = list.validatedLastIndexOf(o, items, offset+size-1,
1439                                                      offset, seq);
1440                  if (lock.getSequence() == seq)
1441                      return idx < 0 ? -1 : idx - offset;
# Line 1398 | Line 1450 | public class ReadMostlyVector<E> impleme
1450          }
1451  
1452          public ListIterator<E> listIterator() {
1453 <            return new SubItr(this, offset);
1453 >            return new SubItr<E>(this, offset);
1454          }
1455  
1456          public ListIterator<E> listIterator(int index) {
1457 <            return new SubItr(this, index + offset);
1457 >            return new SubItr<E>(this, index + offset);
1458          }
1459  
1460          public E remove(int index) {
# Line 1410 | Line 1462 | public class ReadMostlyVector<E> impleme
1462              SequenceLock lock = list.lock;
1463              lock.lock();
1464              try {
1465 <                if (index < 0 || index >= size)
1414 <                    throw new ArrayIndexOutOfBoundsException(index);
1465 >                Object[] items = list.array;
1466                  int i = index + offset;
1467 <                result = list.array[i];
1468 <                list.internalRemoveAt(i);
1467 >                if (index < 0 || index >= size || i >= items.length)
1468 >                    throw new ArrayIndexOutOfBoundsException(index);
1469 >                result = items[i];
1470 >                list.rawRemoveAt(i);
1471                  size--;
1472              } finally {
1473                  lock.unlock();
# Line 1427 | Line 1480 | public class ReadMostlyVector<E> impleme
1480              SequenceLock lock = list.lock;
1481              lock.lock();
1482              try {
1483 <                if (list.internalRemoveAt(list.rawIndexOf(o, offset,
1484 <                                                          offset + size))) {
1483 >                if (list.rawRemoveAt(list.rawIndexOf(o, offset,
1484 >                                                     offset + size))) {
1485                      removed = true;
1486                      --size;
1487                  }
# Line 1461 | Line 1514 | public class ReadMostlyVector<E> impleme
1514              int ssize = toIndex - fromIndex;
1515              if (fromIndex < 0 || toIndex > c || ssize < 0)
1516                  throw new IndexOutOfBoundsException();
1517 <            return new ReadMostlyVectorSublist(list, offset+fromIndex, ssize);
1517 >            return new ReadMostlyVectorSublist<E>(list, offset+fromIndex, ssize);
1518          }
1519  
1520          public Object[] toArray() {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines