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.18 by jsr166, Sat Dec 31 05:50:22 2011 UTC vs.
Revision 1.24 by jsr166, Mon Jan 2 23:13:10 2012 UTC

# Line 49 | Line 49 | public class ReadMostlyVector<E>
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 57 | Line 62 | public class ReadMostlyVector<E>
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      volatile Object[] array;
67      final SequenceLock lock;
68      volatile int count;
# Line 155 | Line 160 | public class ReadMostlyVector<E>
160       * as well as sublist and iterator classes.
161       */
162  
163 <    // Version of indexOf that returns -1 if either not present or invalid
163 >    /**
164 >     * Version of indexOf that returns -1 if either not present or invalid.
165 >     *
166 >     * @throws ArrayIndexOutOfBoundsException if index is negative
167 >     */
168      final int validatedIndexOf(Object x, Object[] items, int index, int fence,
169                                 long seq) {
170          for (int i = index; i < fence; ++i) {
# Line 168 | Line 177 | public class ReadMostlyVector<E>
177          return -1;
178      }
179  
180 +    /**
181 +     * @throws ArrayIndexOutOfBoundsException if index is negative
182 +     */
183      final int rawIndexOf(Object x, int index, int fence) {
184          Object[] items = array;
185          for (int i = index; i < fence; ++i) {
# Line 686 | Line 698 | public class ReadMostlyVector<E>
698                      if (lock.getSequence() != seq) {
699                          lock.lock();
700                          try {
701 <                            return rawLastIndexOf(o, 0, count);
701 >                            return rawLastIndexOf(o, count - 1, 0);
702                          } finally {
703                              lock.unlock();
704                          }
# Line 870 | Line 882 | public class ReadMostlyVector<E>
882          for (;;) {
883              long seq = lock.awaitAvailability();
884              Object[] items = array;
873            int len = items.length;
885              int n = count;
875            if (n > len)
876                continue;
877            boolean empty = (n == 0);
886              @SuppressWarnings("unchecked")
887 <            E e = empty ? null : (E) items[0];
887 >            E e = (items.length > 0) ? (E) items[0] : null;
888              if (lock.getSequence() == seq) {
889 <                if (empty)
889 >                if (n <= 0)
890                      throw new NoSuchElementException();
891 <                else
884 <                    return e;
891 >                return e;
892              }
893          }
894      }
# Line 892 | Line 899 | public class ReadMostlyVector<E>
899          for (;;) {
900              long seq = lock.awaitAvailability();
901              Object[] items = array;
895            int len = items.length;
902              int n = count;
897            if (n > len)
898                continue;
899            boolean empty = (n == 0);
903              @SuppressWarnings("unchecked")
904 <            E e = empty ? null : (E) items[n - 1];
904 >            E e = (n > 0 && items.length >= n) ? (E) items[n - 1] : null;
905              if (lock.getSequence() == seq) {
906 <                if (empty)
906 >                if (n <= 0)
907                      throw new NoSuchElementException();
908 <                else
906 <                    return e;
908 >                return e;
909              }
910          }
911      }
# Line 911 | Line 913 | public class ReadMostlyVector<E>
913      /** See {@link Vector#indexOf(Object, int)} */
914      public int indexOf(Object o, int index) {
915          final SequenceLock lock = this.lock;
914        int idx = 0;
915        boolean ex = false;
916          long seq = lock.awaitAvailability();
917          Object[] items = array;
918          int n = count;
919 <        boolean retry = false;
920 <        if (n > items.length)
921 <            retry = true;
922 <        else if (index < 0)
923 <            ex = true;
924 <        else
919 >        int idx = -1;
920 >        if (n <= items.length)
921              idx = validatedIndexOf(o, items, index, n, seq);
922 <        if (retry || lock.getSequence() != seq) {
922 >        if (lock.getSequence() != seq) {
923              lock.lock();
924              try {
925 <                if (index < 0)
930 <                    ex = true;
931 <                else
932 <                    idx = rawIndexOf(o, index, count);
925 >                idx = rawIndexOf(o, index, count);
926              } finally {
927                  lock.unlock();
928              }
929          }
930 <        if (ex)
938 <            throw new ArrayIndexOutOfBoundsException(index);
930 >        // Above code will throw AIOOBE when index < 0
931          return idx;
932      }
933  
934      /** See {@link Vector#lastIndexOf(Object, int)} */
935      public int lastIndexOf(Object o, int index) {
936          final SequenceLock lock = this.lock;
945        int idx = 0;
946        boolean ex = false;
937          long seq = lock.awaitAvailability();
938          Object[] items = array;
939          int n = count;
940 <        boolean retry = false;
941 <        if (n > items.length)
952 <            retry = true;
953 <        else if (index >= n)
954 <            ex = true;
955 <        else
940 >        int idx = -1;
941 >        if (index < Math.min(n, items.length))
942              idx = validatedLastIndexOf(o, items, index, 0, seq);
943 <        if (retry || lock.getSequence() != seq) {
943 >        if (lock.getSequence() != seq) {
944              lock.lock();
945              try {
946 <                if (index >= count)
947 <                    ex = true;
962 <                else
946 >                n = count;
947 >                if (index < n)
948                      idx = rawLastIndexOf(o, index, 0);
949              } finally {
950                  lock.unlock();
951              }
952          }
953 <        if (ex)
954 <            throw new ArrayIndexOutOfBoundsException(index);
953 >        if (index >= n)
954 >            throw new IndexOutOfBoundsException(index + " >= " + n);
955          return idx;
956      }
957  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines