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.5 by dl, Sat Jul 16 16:05:32 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 661 | Line 663 | public class ReadMostlyVector<E> impleme
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;
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();
682          try {
# Line 716 | Line 729 | public class ReadMostlyVector<E> impleme
729              if (index < 0 || index >= count)
730                  throw new ArrayIndexOutOfBoundsException(index);
731              oldValue = array[index];
732 <            internalRemoveAt(index);
732 >            rawRemoveAt(index);
733          } finally {
734              lock.unlock();
735          }
# Line 728 | Line 741 | public class ReadMostlyVector<E> impleme
741          boolean removed;
742          lock.lock();
743          try {
744 <            removed = internalRemoveAt(rawIndexOf(o, 0, count));
744 >            removed = rawRemoveAt(rawIndexOf(o, 0, count));
745          } finally {
746              lock.unlock();
747          }
# Line 797 | Line 810 | public class ReadMostlyVector<E> impleme
810          lock.lock();
811          try {
812              if (rawIndexOf(e, 0, count) < 0) {
813 <                internalAdd(e);
813 >                rawAdd(e);
814                  added = true;
815              }
816              else
# Line 829 | Line 842 | public class ReadMostlyVector<E> impleme
842                  for (int i = 0; i < clen; ++i) {
843                      Object e = cs[i];
844                      if (rawIndexOf(e, 0, count) < 0) {
845 <                        internalAdd(e);
845 >                        rawAdd(e);
846                          ++added;
847                      }
848                  }
# Line 840 | Line 853 | public class ReadMostlyVector<E> impleme
853          return added;
854      }
855  
856 +    /**
857 +     * Returns an iterator operating over a snapshot copy of the
858 +     * elements of this collection created upon construction of the
859 +     * iterator. The iterator does <em>NOT</em> support the
860 +     * <tt>remove</tt> method.
861 +     *
862 +     * @return an iterator over the elements in this list in proper sequence
863 +     */
864 +    public Iterator<E> snapshotIterator() {
865 +        return new SnapshotIterator<E>(this);
866 +    }
867 +
868 +    static final class SnapshotIterator<E> implements Iterator<E> {
869 +        final Object[] items;
870 +        int cursor;
871 +        SnapshotIterator(ReadMostlyVector<E> v) { items = v.toArray(); }
872 +        public boolean hasNext() { return cursor < items.length; }
873 +        public E next() {
874 +            if (cursor < items.length)
875 +                return (E) items[cursor++];
876 +            throw new NoSuchElementException();
877 +        }
878 +        public void remove() { throw new UnsupportedOperationException() ; }
879 +    }
880 +
881      // Vector-only methods
882  
883      /** See {@link Vector#firstElement} */
# Line 1256 | Line 1294 | public class ReadMostlyVector<E> impleme
1294              lock.lock();
1295              try {
1296                  int c = size;
1297 <                list.internalAddAt(c + offset, element);
1297 >                list.rawAddAt(c + offset, element);
1298                  size = c + 1;
1299              } finally {
1300                  lock.unlock();
# Line 1270 | Line 1308 | public class ReadMostlyVector<E> impleme
1308              try {
1309                  if (index < 0 || index > size)
1310                      throw new ArrayIndexOutOfBoundsException(index);
1311 <                list.internalAddAt(index + offset, element);
1311 >                list.rawAddAt(index + offset, element);
1312                  ++size;
1313              } finally {
1314                  lock.unlock();
# Line 1285 | Line 1323 | public class ReadMostlyVector<E> impleme
1323              try {
1324                  int s = size;
1325                  int pc = list.count;
1326 <                list.internalAddAllAt(offset + s, elements);
1326 >                list.rawAddAllAt(offset + s, elements);
1327                  added = list.count - pc;
1328                  size = s + added;
1329              } finally {
# Line 1304 | Line 1342 | public class ReadMostlyVector<E> impleme
1342                  if (index < 0 || index > s)
1343                      throw new ArrayIndexOutOfBoundsException(index);
1344                  int pc = list.count;
1345 <                list.internalAddAllAt(index + offset, elements);
1345 >                list.rawAddAllAt(index + offset, elements);
1346                  added = list.count - pc;
1347                  size = s + added;
1348              } finally {
# Line 1356 | Line 1394 | public class ReadMostlyVector<E> impleme
1394              Object[] items = list.array;
1395              int c = list.count;
1396              if (c <= items.length) {
1397 <                int idx = list.validatedIndexOf(o, items, offset, offset+size, seq);
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();
1403              try {
1404 <                int idx = list.rawIndexOf(o, offset, offset+size);
1404 >                int idx = list.rawIndexOf(o, offset, offset + size);
1405                  return idx < 0 ? -1 : idx - offset;
1406              } finally {
1407                  lock.unlock();
# Line 1410 | Line 1449 | public class ReadMostlyVector<E> impleme
1449              SequenceLock lock = list.lock;
1450              lock.lock();
1451              try {
1452 <                if (index < 0 || index >= size)
1414 <                    throw new ArrayIndexOutOfBoundsException(index);
1452 >                Object[] items = list.array;
1453                  int i = index + offset;
1454 <                result = list.array[i];
1455 <                list.internalRemoveAt(i);
1454 >                if (index < 0 || index >= size || i >= items.length)
1455 >                    throw new ArrayIndexOutOfBoundsException(index);
1456 >                result = items[i];
1457 >                list.rawRemoveAt(i);
1458                  size--;
1459              } finally {
1460                  lock.unlock();
# Line 1427 | Line 1467 | public class ReadMostlyVector<E> impleme
1467              SequenceLock lock = list.lock;
1468              lock.lock();
1469              try {
1470 <                if (list.internalRemoveAt(list.rawIndexOf(o, offset,
1471 <                                                          offset + size))) {
1470 >                if (list.rawRemoveAt(list.rawIndexOf(o, offset,
1471 >                                                     offset + size))) {
1472                      removed = true;
1473                      --size;
1474                  }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines