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 |
|
/** |
653 |
|
long seq = lock.awaitAvailability(); |
654 |
|
int n = count; |
655 |
|
Object[] items = array; |
651 |
– |
if (n > items.length) |
652 |
– |
continue; |
653 |
– |
boolean outOfBounds = (index < 0 || index >= n); |
656 |
|
@SuppressWarnings("unchecked") |
657 |
< |
E e = outOfBounds ? null : (E) items[index]; |
657 |
> |
E e = (index < items.length) ? (E) items[index] : null; |
658 |
|
if (lock.getSequence() == seq) { |
659 |
< |
if (outOfBounds) |
659 |
> |
if (index >= n) |
660 |
|
throw new ArrayIndexOutOfBoundsException(index); |
661 |
< |
else |
660 |
< |
return e; |
661 |
> |
return e; |
662 |
|
} |
663 |
|
} |
664 |
|
} |
668 |
|
} |
669 |
|
|
670 |
|
public int indexOf(Object o) { |
671 |
< |
final SequenceLock lock = this.lock; |
671 |
< |
for (;;) { |
672 |
< |
long seq = lock.awaitAvailability(); |
673 |
< |
Object[] items = array; |
674 |
< |
int n = count; |
675 |
< |
if (n <= items.length) { |
676 |
< |
for (int i = 0; i < n; ++i) { |
677 |
< |
Object e = items[i]; |
678 |
< |
if (lock.getSequence() != seq) { |
679 |
< |
lock.lock(); |
680 |
< |
try { |
681 |
< |
return rawIndexOf(o, 0, count); |
682 |
< |
} finally { |
683 |
< |
lock.unlock(); |
684 |
< |
} |
685 |
< |
} |
686 |
< |
else if ((o == null) ? e == null : o.equals(e)) |
687 |
< |
return i; |
688 |
< |
} |
689 |
< |
return -1; |
690 |
< |
} |
691 |
< |
} |
671 |
> |
return indexOf(o, 0); |
672 |
|
} |
673 |
|
|
674 |
|
public boolean isEmpty() { |
691 |
|
if (lock.getSequence() != seq) { |
692 |
|
lock.lock(); |
693 |
|
try { |
694 |
< |
return rawLastIndexOf(o, 0, count); |
694 |
> |
return rawLastIndexOf(o, count - 1, 0); |
695 |
|
} finally { |
696 |
|
lock.unlock(); |
697 |
|
} |
875 |
|
for (;;) { |
876 |
|
long seq = lock.awaitAvailability(); |
877 |
|
Object[] items = array; |
898 |
– |
int len = items.length; |
878 |
|
int n = count; |
900 |
– |
if (n > len) |
901 |
– |
continue; |
902 |
– |
boolean empty = (n == 0); |
879 |
|
@SuppressWarnings("unchecked") |
880 |
< |
E e = empty ? null : (E) items[0]; |
880 |
> |
E e = (items.length > 0) ? (E) items[0] : null; |
881 |
|
if (lock.getSequence() == seq) { |
882 |
< |
if (empty) |
882 |
> |
if (n <= 0) |
883 |
|
throw new NoSuchElementException(); |
884 |
< |
else |
909 |
< |
return e; |
884 |
> |
return e; |
885 |
|
} |
886 |
|
} |
887 |
|
} |
892 |
|
for (;;) { |
893 |
|
long seq = lock.awaitAvailability(); |
894 |
|
Object[] items = array; |
920 |
– |
int len = items.length; |
895 |
|
int n = count; |
922 |
– |
if (n > len) |
923 |
– |
continue; |
924 |
– |
boolean empty = (n == 0); |
896 |
|
@SuppressWarnings("unchecked") |
897 |
< |
E e = empty ? null : (E) items[n - 1]; |
897 |
> |
E e = (n > 0 && items.length >= n) ? (E) items[n - 1] : null; |
898 |
|
if (lock.getSequence() == seq) { |
899 |
< |
if (empty) |
899 |
> |
if (n <= 0) |
900 |
|
throw new NoSuchElementException(); |
901 |
< |
else |
931 |
< |
return e; |
901 |
> |
return e; |
902 |
|
} |
903 |
|
} |
904 |
|
} |