--- jsr166/src/jsr166e/extra/ReadMostlyVector.java 2011/08/05 17:08:04 1.13 +++ jsr166/src/jsr166e/extra/ReadMostlyVector.java 2011/12/31 21:16:14 1.22 @@ -32,7 +32,8 @@ import java.util.*; * * @author Doug Lea */ -public class ReadMostlyVector implements List, RandomAccess, Cloneable, java.io.Serializable { +public class ReadMostlyVector + implements List, RandomAccess, Cloneable, java.io.Serializable { private static final long serialVersionUID = 8673264195747942595L; /* @@ -48,6 +49,11 @@ public class ReadMostlyVector impleme * read-only mode, and then lock. When in read-only mode, they * validate only at the end of an array scan unless the element is * actually used (for example, as an argument of method equals). + * + * We rely on some invariants that are always true, even for field + * reads in read-only mode that have not yet been validated: + * - array != null + * - count >= 0 */ /** @@ -199,7 +205,7 @@ public class ReadMostlyVector impleme return -1; } - final void rawAdd(Object e) { + final void rawAdd(E e) { int n = count; Object[] items = array; if (n >= items.length) @@ -208,7 +214,7 @@ public class ReadMostlyVector impleme count = n + 1; } - final void rawAddAt(int index, Object e) { + final void rawAddAt(int index, E e) { int n = count; Object[] items = array; if (index > n) @@ -261,7 +267,7 @@ public class ReadMostlyVector impleme * field under lock. */ final boolean internalRemoveAll(Collection c, int origin, int bound) { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; boolean removed = false; lock.lock(); try { @@ -280,7 +286,7 @@ public class ReadMostlyVector impleme } final boolean internalRetainAll(Collection c, int origin, int bound) { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; boolean removed = false; if (c != this) { lock.lock(); @@ -327,7 +333,7 @@ public class ReadMostlyVector impleme } final boolean internalContainsAll(Collection c, int origin, int bound) { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; boolean contained; boolean locked = false; try { @@ -367,7 +373,7 @@ public class ReadMostlyVector impleme } final boolean internalEquals(List list, int origin, int bound) { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; boolean locked = false; boolean equal; try { @@ -408,7 +414,7 @@ public class ReadMostlyVector impleme } final int internalHashCode(int origin, int bound) { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; int hash; boolean locked = false; try { @@ -440,7 +446,7 @@ public class ReadMostlyVector impleme } final String internalToString(int origin, int bound) { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; String ret; boolean locked = false; try { @@ -487,7 +493,7 @@ public class ReadMostlyVector impleme final Object[] internalToArray(int origin, int bound) { Object[] result; - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; boolean locked = false; try { for (;;) { @@ -514,10 +520,11 @@ public class ReadMostlyVector impleme return result; } + @SuppressWarnings("unchecked") final T[] internalToArray(T[] a, int origin, int bound) { int alen = a.length; T[] result; - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; boolean locked = false; try { for (;;) { @@ -556,7 +563,7 @@ public class ReadMostlyVector impleme // public List methods public boolean add(E e) { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; lock.lock(); try { rawAdd(e); @@ -567,7 +574,7 @@ public class ReadMostlyVector impleme } public void add(int index, E element) { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; lock.lock(); try { rawAddAt(index, element); @@ -581,7 +588,7 @@ public class ReadMostlyVector impleme int len = elements.length; if (len == 0) return false; - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; lock.lock(); try { Object[] items = array; @@ -598,7 +605,7 @@ public class ReadMostlyVector impleme } public boolean addAll(int index, Collection c) { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; boolean ret; Object[] elements = c.toArray(); lock.lock(); @@ -611,7 +618,7 @@ public class ReadMostlyVector impleme } public void clear() { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; lock.lock(); try { int n = count; @@ -641,27 +648,17 @@ public class ReadMostlyVector impleme } public E get(int index) { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; for (;;) { long seq = lock.awaitAvailability(); int n = count; Object[] items = array; - if (n > items.length) - continue; - Object e; boolean ex; - if (index < 0 || index >= n) { - e = null; - ex = true; - } - else { - e = items[index]; - ex = false; - } + @SuppressWarnings("unchecked") + E e = (index < items.length) ? (E) items[index] : null; if (lock.getSequence() == seq) { - if (ex) + if (index >= n) throw new ArrayIndexOutOfBoundsException(index); - else - return (E)e; + return e; } } } @@ -671,28 +668,7 @@ public class ReadMostlyVector impleme } public int indexOf(Object o) { - SequenceLock lock = this.lock; - for (;;) { - long seq = lock.awaitAvailability(); - Object[] items = array; - int n = count; - if (n <= items.length) { - for (int i = 0; i < n; ++i) { - Object e = items[i]; - if (lock.getSequence() != seq) { - lock.lock(); - try { - return rawIndexOf(o, 0, count); - } finally { - lock.unlock(); - } - } - else if ((o == null) ? e == null : o.equals(e)) - return i; - } - return -1; - } - } + return indexOf(o, 0); } public boolean isEmpty() { @@ -704,7 +680,7 @@ public class ReadMostlyVector impleme } public int lastIndexOf(Object o) { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; for (;;) { long seq = lock.awaitAvailability(); Object[] items = array; @@ -715,7 +691,7 @@ public class ReadMostlyVector impleme if (lock.getSequence() != seq) { lock.lock(); try { - return rawLastIndexOf(o, 0, count); + return rawLastIndexOf(o, count - 1, 0); } finally { lock.unlock(); } @@ -737,30 +713,28 @@ public class ReadMostlyVector impleme } public E remove(int index) { - SequenceLock lock = this.lock; - Object oldValue; + final SequenceLock lock = this.lock; lock.lock(); try { if (index < 0 || index >= count) throw new ArrayIndexOutOfBoundsException(index); - oldValue = array[index]; + @SuppressWarnings("unchecked") + E oldValue = (E) array[index]; rawRemoveAt(index); + return oldValue; } finally { lock.unlock(); } - return (E)oldValue; } public boolean remove(Object o) { - SequenceLock lock = this.lock; - boolean removed; + final SequenceLock lock = this.lock; lock.lock(); try { - removed = rawRemoveAt(rawIndexOf(o, 0, count)); + return rawRemoveAt(rawIndexOf(o, 0, count)); } finally { lock.unlock(); } - return removed; } public boolean removeAll(Collection c) { @@ -772,19 +746,19 @@ public class ReadMostlyVector impleme } public E set(int index, E element) { - Object oldValue; - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; lock.lock(); try { Object[] items = array; if (index < 0 || index >= count) throw new ArrayIndexOutOfBoundsException(index); - oldValue = items[index]; + @SuppressWarnings("unchecked") + E oldValue = (E) items[index]; items[index] = element; + return oldValue; } finally { lock.unlock(); } - return (E)oldValue; } public int size() { @@ -820,20 +794,18 @@ public class ReadMostlyVector impleme * @return {@code true} if the element was added */ public boolean addIfAbsent(E e) { - boolean added; - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; lock.lock(); try { if (rawIndexOf(e, 0, count) < 0) { rawAdd(e); - added = true; + return true; } else - added = false; + return false; } finally { lock.unlock(); } - return added; } /** @@ -855,7 +827,8 @@ public class ReadMostlyVector impleme lock.lock(); try { for (int i = 0; i < clen; ++i) { - Object e = cs[i]; + @SuppressWarnings("unchecked") + E e = (E) cs[i]; if (rawIndexOf(e, 0, count) < 0) { rawAdd(e); ++added; @@ -881,10 +854,11 @@ public class ReadMostlyVector impleme } static final class SnapshotIterator implements Iterator { - final Object[] items; - int cursor; + private final Object[] items; + private int cursor; SnapshotIterator(ReadMostlyVector v) { items = v.toArray(); } public boolean hasNext() { return cursor < items.length; } + @SuppressWarnings("unchecked") public E next() { if (cursor < items.length) return (E) items[cursor++]; @@ -897,63 +871,41 @@ public class ReadMostlyVector impleme /** See {@link Vector#firstElement} */ public E firstElement() { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; for (;;) { long seq = lock.awaitAvailability(); Object[] items = array; - int len = items.length; int n = count; - if (n > len) - continue; - Object e; boolean ex; - if (n > 0) { - e = items[0]; - ex = false; - } - else { - e = null; - ex = true; - } + @SuppressWarnings("unchecked") + E e = (items.length > 0) ? (E) items[0] : null; if (lock.getSequence() == seq) { - if (ex) + if (n <= 0) throw new NoSuchElementException(); - else - return (E)e; + return e; } } } /** See {@link Vector#lastElement} */ public E lastElement() { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; for (;;) { long seq = lock.awaitAvailability(); Object[] items = array; - int len = items.length; int n = count; - if (n > len) - continue; - Object e; boolean ex; - if (n > 0) { - e = items[n - 1]; - ex = false; - } - else { - e = null; - ex = true; - } + @SuppressWarnings("unchecked") + E e = (n > 0 && items.length >= n) ? (E) items[n - 1] : null; if (lock.getSequence() == seq) { - if (ex) + if (n <= 0) throw new NoSuchElementException(); - else - return (E)e; + return e; } } } /** See {@link Vector#indexOf(Object, int)} */ public int indexOf(Object o, int index) { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; int idx = 0; boolean ex = false; long seq = lock.awaitAvailability(); @@ -972,7 +924,7 @@ public class ReadMostlyVector impleme if (index < 0) ex = true; else - idx = rawIndexOf(o, 0, count); + idx = rawIndexOf(o, index, count); } finally { lock.unlock(); } @@ -984,7 +936,7 @@ public class ReadMostlyVector impleme /** See {@link Vector#lastIndexOf(Object, int)} */ public int lastIndexOf(Object o, int index) { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; int idx = 0; boolean ex = false; long seq = lock.awaitAvailability(); @@ -1017,7 +969,7 @@ public class ReadMostlyVector impleme public void setSize(int newSize) { if (newSize < 0) throw new ArrayIndexOutOfBoundsException(newSize); - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; lock.lock(); try { int n = count; @@ -1036,7 +988,7 @@ public class ReadMostlyVector impleme /** See {@link Vector#copyInto} */ public void copyInto(Object[] anArray) { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; lock.lock(); try { System.arraycopy(array, 0, anArray, 0, count); @@ -1047,7 +999,7 @@ public class ReadMostlyVector impleme /** See {@link Vector#trimToSize} */ public void trimToSize() { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; lock.lock(); try { Object[] items = array; @@ -1062,7 +1014,7 @@ public class ReadMostlyVector impleme /** See {@link Vector#ensureCapacity} */ public void ensureCapacity(int minCapacity) { if (minCapacity > 0) { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; lock.lock(); try { if (minCapacity - array.length > 0) @@ -1121,7 +1073,7 @@ public class ReadMostlyVector impleme // other methods public ReadMostlyVector clone() { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; Object[] a = null; boolean retry = false; long seq = lock.awaitAvailability(); @@ -1145,7 +1097,7 @@ public class ReadMostlyVector impleme private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { - SequenceLock lock = this.lock; + final SequenceLock lock = this.lock; lock.lock(); try { s.defaultWriteObject(); @@ -1154,11 +1106,11 @@ public class ReadMostlyVector impleme } } - static final class Itr implements ListIterator, Enumeration { + static final class Itr implements ListIterator, Enumeration { final ReadMostlyVector list; final SequenceLock lock; Object[] items; - Object next, prev; + E next, prev; long seq; int cursor; int fence; @@ -1184,6 +1136,7 @@ public class ReadMostlyVector impleme lock.getSequence() != seq); } + @SuppressWarnings("unchecked") public boolean hasNext() { boolean valid; int i = cursor; @@ -1192,7 +1145,7 @@ public class ReadMostlyVector impleme valid = false; break; } - next = items[i]; + next = (E) items[i]; if (lock.getSequence() == seq) { valid = true; break; @@ -1202,6 +1155,7 @@ public class ReadMostlyVector impleme return validNext = valid; } + @SuppressWarnings("unchecked") public boolean hasPrevious() { boolean valid; int i = cursor - 1; @@ -1210,7 +1164,7 @@ public class ReadMostlyVector impleme valid = false; break; } - prev = items[i]; + prev = (E) items[i]; if (lock.getSequence() == seq) { valid = true; break; @@ -1224,7 +1178,7 @@ public class ReadMostlyVector impleme if (validNext || hasNext()) { validNext = false; lastRet = cursor++; - return (E) next; + return next; } throw new NoSuchElementException(); } @@ -1233,7 +1187,7 @@ public class ReadMostlyVector impleme if (validPrev || hasPrevious()) { validPrev = false; lastRet = cursor--; - return (E) prev; + return prev; } throw new NoSuchElementException(); } @@ -1290,12 +1244,16 @@ public class ReadMostlyVector impleme public int previousIndex() { return cursor - 1; } } - static final class ReadMostlyVectorSublist implements List, RandomAccess, java.io.Serializable { + static final class ReadMostlyVectorSublist + implements List, RandomAccess, java.io.Serializable { + static final long serialVersionUID = 3041673470172026059L; + final ReadMostlyVector list; final int offset; volatile int size; - ReadMostlyVectorSublist(ReadMostlyVector list, int offset, int size) { + ReadMostlyVectorSublist(ReadMostlyVector list, + int offset, int size) { this.list = list; this.offset = offset; this.size = size; @@ -1307,7 +1265,7 @@ public class ReadMostlyVector impleme } public boolean add(E element) { - SequenceLock lock = list.lock; + final SequenceLock lock = list.lock; lock.lock(); try { int c = size; @@ -1320,7 +1278,7 @@ public class ReadMostlyVector impleme } public void add(int index, E element) { - SequenceLock lock = list.lock; + final SequenceLock lock = list.lock; lock.lock(); try { if (index < 0 || index > size) @@ -1334,25 +1292,23 @@ public class ReadMostlyVector impleme public boolean addAll(Collection c) { Object[] elements = c.toArray(); - int added; - SequenceLock lock = list.lock; + final SequenceLock lock = list.lock; lock.lock(); try { int s = size; int pc = list.count; list.rawAddAllAt(offset + s, elements); - added = list.count - pc; + int added = list.count - pc; size = s + added; + return added != 0; } finally { lock.unlock(); } - return added != 0; } public boolean addAll(int index, Collection c) { Object[] elements = c.toArray(); - int added; - SequenceLock lock = list.lock; + final SequenceLock lock = list.lock; lock.lock(); try { int s = size; @@ -1360,16 +1316,16 @@ public class ReadMostlyVector impleme throw new ArrayIndexOutOfBoundsException(index); int pc = list.count; list.rawAddAllAt(index + offset, elements); - added = list.count - pc; + int added = list.count - pc; size = s + added; + return added != 0; } finally { lock.unlock(); } - return added != 0; } public void clear() { - SequenceLock lock = list.lock; + final SequenceLock lock = list.lock; lock.lock(); try { list.internalClear(offset, offset + size); @@ -1406,7 +1362,7 @@ public class ReadMostlyVector impleme } public int indexOf(Object o) { - SequenceLock lock = list.lock; + final SequenceLock lock = list.lock; long seq = lock.awaitAvailability(); Object[] items = list.array; int c = list.count; @@ -1434,7 +1390,7 @@ public class ReadMostlyVector impleme } public int lastIndexOf(Object o) { - SequenceLock lock = list.lock; + final SequenceLock lock = list.lock; long seq = lock.awaitAvailability(); Object[] items = list.array; int c = list.count; @@ -1462,37 +1418,37 @@ public class ReadMostlyVector impleme } public E remove(int index) { - Object result; - SequenceLock lock = list.lock; + final SequenceLock lock = list.lock; lock.lock(); try { Object[] items = list.array; int i = index + offset; if (index < 0 || index >= size || i >= items.length) throw new ArrayIndexOutOfBoundsException(index); - result = items[i]; + @SuppressWarnings("unchecked") + E result = (E) items[i]; list.rawRemoveAt(i); size--; + return result; } finally { lock.unlock(); } - return (E)result; } public boolean remove(Object o) { - boolean removed = false; - SequenceLock lock = list.lock; + final SequenceLock lock = list.lock; lock.lock(); try { if (list.rawRemoveAt(list.rawIndexOf(o, offset, offset + size))) { - removed = true; --size; + return true; } + else + return false; } finally { lock.unlock(); } - return removed; } public boolean removeAll(Collection c) { @@ -1540,7 +1496,7 @@ public class ReadMostlyVector impleme final ReadMostlyVector list; final SequenceLock lock; Object[] items; - Object next, prev; + E next, prev; long seq; int cursor; int fence; @@ -1571,6 +1527,7 @@ public class ReadMostlyVector impleme } while (lock.getSequence() != seq); } + @SuppressWarnings("unchecked") public boolean hasNext() { boolean valid; int i = cursor; @@ -1579,7 +1536,7 @@ public class ReadMostlyVector impleme valid = false; break; } - next = items[i]; + next = (E) items[i]; if (lock.getSequence() == seq) { valid = true; break; @@ -1589,6 +1546,7 @@ public class ReadMostlyVector impleme return validNext = valid; } + @SuppressWarnings("unchecked") public boolean hasPrevious() { boolean valid; int i = cursor - 1; @@ -1597,7 +1555,7 @@ public class ReadMostlyVector impleme valid = false; break; } - prev = items[i]; + prev = (E) items[i]; if (lock.getSequence() == seq) { valid = true; break; @@ -1611,7 +1569,7 @@ public class ReadMostlyVector impleme if (validNext || hasNext()) { validNext = false; lastRet = cursor++; - return (E) next; + return next; } throw new NoSuchElementException(); } @@ -1620,7 +1578,7 @@ public class ReadMostlyVector impleme if (validPrev || hasPrevious()) { validPrev = false; lastRet = cursor--; - return (E) prev; + return prev; } throw new NoSuchElementException(); }