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.3 by jsr166, Sat Jul 16 14:56:30 2011 UTC vs.
Revision 1.8 by jsr166, Mon Jul 18 15:24:08 2011 UTC

# 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.
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 151 | Line 154 | public class ReadMostlyVector<E> impleme
154       * as well as sublist and iterator classes.
155       */
156  
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;
# Line 179 | Line 183 | public class ReadMostlyVector<E> impleme
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)
205              grow(n + 1);
# Line 203 | Line 207 | public class ReadMostlyVector<E> impleme
207          count = n + 1;
208      }
209  
210 <    final void internalAddAt(int index, Object e) {
210 >    final void rawAddAt(int index, Object e) {
211          int n = count;
212          if (index > n)
213              throw new ArrayIndexOutOfBoundsException(index);
# Line 215 | Line 219 | public class ReadMostlyVector<E> impleme
219          count = n + 1;
220      }
221  
222 <    final boolean internalAddAllAt(int index, Object[] elements) {
222 >    final boolean rawAddAllAt(int index, Object[] elements) {
223          int n = count;
224          if (index < 0 || index > n)
225              throw new ArrayIndexOutOfBoundsException(index);
# Line 233 | Line 237 | public class ReadMostlyVector<E> impleme
237          return true;
238      }
239  
240 <    final boolean internalRemoveAt(int index) {
240 >    final boolean rawRemoveAt(int index) {
241          int n = count - 1;
242          if (index < 0 || index > n)
243              return false;
# Line 261 | Line 265 | public class ReadMostlyVector<E> impleme
265              int fence = bound < 0 || bound > n ? n : bound;
266              if (origin >= 0 && origin < fence) {
267                  for (Object x : c) {
268 <                    while (internalRemoveAt(rawIndexOf(x, origin, fence)))
268 >                    while (rawRemoveAt(rawIndexOf(x, origin, fence)))
269                          removed = true;
270                  }
271              }
# Line 280 | Line 284 | public class ReadMostlyVector<E> impleme
284                  int i = origin;
285                  int n = count;
286                  int fence = bound < 0 || bound > n ? n : bound;
287 <                while (i < fence) {
287 >                while (i >= 0 && i < fence) {
288                      if (c.contains(array[i]))
289                          ++i;
290                      else {
# Line 331 | Line 335 | public class ReadMostlyVector<E> impleme
335                  else {
336                      contained = true;
337                      for (Object e : c) {
338 <                        if (validatedIndexOf(e, items, origin, fence, seq) < 0) {
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                          }
# Line 351 | Line 359 | public class ReadMostlyVector<E> impleme
359  
360      final boolean internalEquals(List<?> list, int origin, int bound) {
361          SequenceLock lock = this.lock;
354        boolean equal;
362          boolean locked = false;
363 +        boolean equal;
364          try {
365 <            outer:for (;;) {
358 <                equal = true;
365 >            for (;;) {
366                  long seq = lock.awaitAvailability();
367                  Object[] items = array;
361                int len = items.length;
368                  int n = count;
369 <                if (n > len)
364 <                    continue;
365 <                int fence = bound < 0 || bound > n ? n : bound;
366 <                if (origin < 0)
369 >                if (n > items.length || origin < 0)
370                      equal = false;
371                  else {
372 +                    equal = true;
373 +                    int fence = bound < 0 || bound > n ? n : bound;
374                      Iterator<?> it = list.iterator();
375                      for (int i = origin; i < fence; ++i) {
376 <                        if (!it.hasNext()) {
377 <                            equal = false;
378 <                            break;
379 <                        }
380 <                        Object x = it.next();
381 <                        Object y = items[i];
377 <                        if (lock.getSequence() != seq)
378 <                            continue outer;
379 <                        if ((x == null) ? y != null : (y == null || !x.equals(y))) {
376 >                        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                          }
# Line 450 | Line 452 | public class ReadMostlyVector<E> impleme
452                          Object e = items[i];
453                          if (e == this)
454                              sb.append("(this Collection)");
455 <                        else if (lock.getSequence() != seq)
455 >                        else if (!locked && lock.getSequence() != seq)
456                              continue outer;
457                          else
458                              sb.append(e.toString());
# Line 518 | Line 520 | public class ReadMostlyVector<E> impleme
520                      continue;
521                  int fence = bound < 0 || bound > n ? n : bound;
522                  int rlen = fence - origin;
523 +                if (rlen < 0)
524 +                    rlen = 0;
525                  if (origin < 0 || alen >= rlen) {
526 <                    if (rlen < 0)
523 <                        rlen = 0;
524 <                    else if (rlen > 0)
526 >                    if (rlen > 0)
527                          System.arraycopy(array, 0, a, origin, rlen);
528                      if (alen > rlen)
529                          a[rlen] = null;
# Line 548 | Line 550 | public class ReadMostlyVector<E> impleme
550          SequenceLock lock = this.lock;
551          lock.lock();
552          try {
553 <            internalAdd(e);
553 >            rawAdd(e);
554          } finally {
555              lock.unlock();
556          }
# Line 559 | Line 561 | public class ReadMostlyVector<E> impleme
561          SequenceLock lock = this.lock;
562          lock.lock();
563          try {
564 <            internalAddAt(index, element);
564 >            rawAddAt(index, element);
565          } finally {
566              lock.unlock();
567          }
# Line 590 | Line 592 | public class ReadMostlyVector<E> impleme
592          Object[] elements = c.toArray();
593          lock.lock();
594          try {
595 <            ret = internalAddAllAt(index, elements);
595 >            ret = rawAddAllAt(index, elements);
596          } finally {
597              lock.unlock();
598          }
# Line 622 | Line 624 | public class ReadMostlyVector<E> impleme
624              return true;
625          if (!(o instanceof List))
626              return false;
627 <        return internalEquals((List<?>)(o), 0, -1);
627 >        return internalEquals((List<?>)o, 0, -1);
628      }
629  
630      public E get(int index) {
# Line 657 | Line 659 | public class ReadMostlyVector<E> impleme
659  
660      public int indexOf(Object o) {
661          SequenceLock lock = this.lock;
662 <        long seq = lock.awaitAvailability();
663 <        Object[] items = array;
664 <        int n = count;
665 <        if (n <= items.length) {
666 <            int idx = validatedIndexOf(o, items, 0, n, seq);
667 <            if (lock.getSequence() == seq)
668 <                return idx;
669 <        }
670 <        lock.lock();
671 <        try {
672 <            return rawIndexOf(o, 0, count);
673 <        } finally {
674 <            lock.unlock();
662 >        for (;;) {
663 >            long seq = lock.awaitAvailability();
664 >            Object[] items = array;
665 >            int n = count;
666 >            if (n <= items.length) {
667 >                for (int i = 0; i < n; ++i) {
668 >                    Object e = items[i];
669 >                    if (lock.getSequence() != seq) {
670 >                        lock.lock();
671 >                        try {
672 >                            return rawIndexOf(o, 0, count);
673 >                        } finally {
674 >                            lock.unlock();
675 >                        }
676 >                    }
677 >                    else if ((o == null) ? e == null : o.equals(e))
678 >                        return i;
679 >                }
680 >                return -1;
681 >            }
682          }
683      }
684  
# Line 684 | Line 693 | public class ReadMostlyVector<E> impleme
693  
694      public int lastIndexOf(Object o) {
695          SequenceLock lock = this.lock;
696 <        long seq = lock.awaitAvailability();
697 <        Object[] items = array;
698 <        int n = count;
699 <        if (n <= items.length) {
700 <            int idx = validatedLastIndexOf(o, items, n - 1, 0, seq);
701 <            if (lock.getSequence() == seq)
702 <                return idx;
703 <        }
704 <        lock.lock();
705 <        try {
706 <            return rawLastIndexOf(o, count - 1, 0);
707 <        } finally {
708 <            lock.unlock();
696 >        for (;;) {
697 >            long seq = lock.awaitAvailability();
698 >            Object[] items = array;
699 >            int n = count;
700 >            if (n <= items.length) {
701 >                for (int i = n - 1; i >= 0; --i) {
702 >                    Object e = items[i];
703 >                    if (lock.getSequence() != seq) {
704 >                        lock.lock();
705 >                        try {
706 >                            return rawLastIndexOf(o, 0, count);
707 >                        } finally {
708 >                            lock.unlock();
709 >                        }
710 >                    }
711 >                    else if ((o == null) ? e == null : o.equals(e))
712 >                        return i;
713 >                }
714 >                return -1;
715 >            }
716          }
717      }
718  
# Line 716 | Line 732 | public class ReadMostlyVector<E> impleme
732              if (index < 0 || index >= count)
733                  throw new ArrayIndexOutOfBoundsException(index);
734              oldValue = array[index];
735 <            internalRemoveAt(index);
735 >            rawRemoveAt(index);
736          } finally {
737              lock.unlock();
738          }
# Line 728 | Line 744 | public class ReadMostlyVector<E> impleme
744          boolean removed;
745          lock.lock();
746          try {
747 <            removed = internalRemoveAt(rawIndexOf(o, 0, count));
747 >            removed = rawRemoveAt(rawIndexOf(o, 0, count));
748          } finally {
749              lock.unlock();
750          }
# Line 797 | Line 813 | public class ReadMostlyVector<E> impleme
813          lock.lock();
814          try {
815              if (rawIndexOf(e, 0, count) < 0) {
816 <                internalAdd(e);
816 >                rawAdd(e);
817                  added = true;
818              }
819              else
# Line 829 | Line 845 | public class ReadMostlyVector<E> impleme
845                  for (int i = 0; i < clen; ++i) {
846                      Object e = cs[i];
847                      if (rawIndexOf(e, 0, count) < 0) {
848 <                        internalAdd(e);
848 >                        rawAdd(e);
849                          ++added;
850                      }
851                  }
# Line 840 | Line 856 | public class ReadMostlyVector<E> impleme
856          return added;
857      }
858  
859 +    /**
860 +     * Returns an iterator operating over a snapshot copy of the
861 +     * elements of this collection created upon construction of the
862 +     * iterator. The iterator does <em>NOT</em> support the
863 +     * <tt>remove</tt> method.
864 +     *
865 +     * @return an iterator over the elements in this list in proper sequence
866 +     */
867 +    public Iterator<E> snapshotIterator() {
868 +        return new SnapshotIterator<E>(this);
869 +    }
870 +
871 +    static final class SnapshotIterator<E> implements Iterator<E> {
872 +        final Object[] items;
873 +        int cursor;
874 +        SnapshotIterator(ReadMostlyVector<E> v) { items = v.toArray(); }
875 +        public boolean hasNext() { return cursor < items.length; }
876 +        public E next() {
877 +            if (cursor < items.length)
878 +                return (E) items[cursor++];
879 +            throw new NoSuchElementException();
880 +        }
881 +        public void remove() { throw new UnsupportedOperationException() ; }
882 +    }
883 +
884      // Vector-only methods
885  
886      /** See {@link Vector#firstElement} */
# Line 1256 | Line 1297 | public class ReadMostlyVector<E> impleme
1297              lock.lock();
1298              try {
1299                  int c = size;
1300 <                list.internalAddAt(c + offset, element);
1300 >                list.rawAddAt(c + offset, element);
1301                  size = c + 1;
1302              } finally {
1303                  lock.unlock();
# Line 1270 | Line 1311 | public class ReadMostlyVector<E> impleme
1311              try {
1312                  if (index < 0 || index > size)
1313                      throw new ArrayIndexOutOfBoundsException(index);
1314 <                list.internalAddAt(index + offset, element);
1314 >                list.rawAddAt(index + offset, element);
1315                  ++size;
1316              } finally {
1317                  lock.unlock();
# Line 1285 | Line 1326 | public class ReadMostlyVector<E> impleme
1326              try {
1327                  int s = size;
1328                  int pc = list.count;
1329 <                list.internalAddAllAt(offset + s, elements);
1329 >                list.rawAddAllAt(offset + s, elements);
1330                  added = list.count - pc;
1331                  size = s + added;
1332              } finally {
# Line 1304 | Line 1345 | public class ReadMostlyVector<E> impleme
1345                  if (index < 0 || index > s)
1346                      throw new ArrayIndexOutOfBoundsException(index);
1347                  int pc = list.count;
1348 <                list.internalAddAllAt(index + offset, elements);
1348 >                list.rawAddAllAt(index + offset, elements);
1349                  added = list.count - pc;
1350                  size = s + added;
1351              } finally {
# Line 1356 | Line 1397 | public class ReadMostlyVector<E> impleme
1397              Object[] items = list.array;
1398              int c = list.count;
1399              if (c <= items.length) {
1400 <                int idx = list.validatedIndexOf(o, items, offset, offset+size, seq);
1400 >                int idx = list.validatedIndexOf(o, items, offset,
1401 >                                                offset + size, seq);
1402                  if (lock.getSequence() == seq)
1403                      return idx < 0 ? -1 : idx - offset;
1404              }
1405              lock.lock();
1406              try {
1407 <                int idx = list.rawIndexOf(o, offset, offset+size);
1407 >                int idx = list.rawIndexOf(o, offset, offset + size);
1408                  return idx < 0 ? -1 : idx - offset;
1409              } finally {
1410                  lock.unlock();
# Line 1410 | Line 1452 | public class ReadMostlyVector<E> impleme
1452              SequenceLock lock = list.lock;
1453              lock.lock();
1454              try {
1455 <                if (index < 0 || index >= size)
1414 <                    throw new ArrayIndexOutOfBoundsException(index);
1455 >                Object[] items = list.array;
1456                  int i = index + offset;
1457 <                result = list.array[i];
1458 <                list.internalRemoveAt(i);
1457 >                if (index < 0 || index >= size || i >= items.length)
1458 >                    throw new ArrayIndexOutOfBoundsException(index);
1459 >                result = items[i];
1460 >                list.rawRemoveAt(i);
1461                  size--;
1462              } finally {
1463                  lock.unlock();
# Line 1427 | Line 1470 | public class ReadMostlyVector<E> impleme
1470              SequenceLock lock = list.lock;
1471              lock.lock();
1472              try {
1473 <                if (list.internalRemoveAt(list.rawIndexOf(o, offset,
1474 <                                                          offset + size))) {
1473 >                if (list.rawRemoveAt(list.rawIndexOf(o, offset,
1474 >                                                     offset + size))) {
1475                      removed = true;
1476                      --size;
1477                  }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines