68 |
|
* |
69 |
|
* Because in a circular array, elements are in general stored in |
70 |
|
* two disjoint such slices, we help the VM by writing unusual |
71 |
< |
* nested loops for all traversals over the elements. |
71 |
> |
* nested loops for all traversals over the elements. Having only |
72 |
> |
* one hot inner loop body instead of two or three eases human |
73 |
> |
* maintenance and encourages VM loop inlining into the caller. |
74 |
|
*/ |
75 |
|
|
76 |
|
/** |
77 |
|
* The array in which the elements of the deque are stored. |
78 |
< |
* We guarantee that all array cells not holding deque elements |
79 |
< |
* are always null. |
78 |
> |
* All array cells not holding deque elements are always null. |
79 |
> |
* The array always has at least one null slot (at tail). |
80 |
|
*/ |
81 |
|
transient Object[] elements; |
82 |
|
|
90 |
|
|
91 |
|
/** |
92 |
|
* The index at which the next element would be added to the tail |
93 |
< |
* of the deque (via addLast(E), add(E), or push(E)). |
93 |
> |
* of the deque (via addLast(E), add(E), or push(E)); |
94 |
> |
* elements[tail] is always null. |
95 |
|
*/ |
96 |
|
transient int tail; |
97 |
|
|
190 |
|
* @param numElements lower bound on initial capacity of the deque |
191 |
|
*/ |
192 |
|
public ArrayDeque(int numElements) { |
193 |
< |
elements = new Object[Math.max(1, numElements + 1)]; |
193 |
> |
elements = |
194 |
> |
new Object[(numElements < 1) ? 1 : |
195 |
> |
(numElements == Integer.MAX_VALUE) ? Integer.MAX_VALUE : |
196 |
> |
numElements + 1]; |
197 |
|
} |
198 |
|
|
199 |
|
/** |
207 |
|
* @throws NullPointerException if the specified collection is null |
208 |
|
*/ |
209 |
|
public ArrayDeque(Collection<? extends E> c) { |
210 |
< |
elements = new Object[c.size() + 1]; |
210 |
> |
this(c.size()); |
211 |
|
addAll(c); |
212 |
|
} |
213 |
|
|
230 |
|
} |
231 |
|
|
232 |
|
/** |
233 |
< |
* Adds i and j, mod modulus. |
234 |
< |
* Precondition and postcondition: 0 <= i < modulus, 0 <= j <= modulus. |
233 |
> |
* Circularly adds the given distance to index i, mod modulus. |
234 |
> |
* Precondition: 0 <= i < modulus, 0 <= distance <= modulus. |
235 |
> |
* @return index 0 <= i < modulus |
236 |
|
*/ |
237 |
< |
static final int add(int i, int j, int modulus) { |
238 |
< |
if ((i += j) - modulus >= 0) i -= modulus; |
237 |
> |
static final int add(int i, int distance, int modulus) { |
238 |
> |
if ((i += distance) - modulus >= 0) distance -= modulus; |
239 |
|
return i; |
240 |
|
} |
241 |
|
|
242 |
|
/** |
243 |
|
* Subtracts j from i, mod modulus. |
244 |
< |
* Index i must be logically ahead of j. |
245 |
< |
* Returns the "circular distance" from j to i. |
246 |
< |
* Precondition and postcondition: 0 <= i < modulus, 0 <= j < modulus. |
244 |
> |
* Index i must be logically ahead of index j. |
245 |
> |
* Precondition: 0 <= i < modulus, 0 <= j < modulus. |
246 |
> |
* @return the "circular distance" from j to i; corner case i == j |
247 |
> |
* is diambiguated to "empty", returning 0. |
248 |
|
*/ |
249 |
|
static final int sub(int i, int j, int modulus) { |
250 |
|
if ((i -= j) < 0) i += modulus; |
870 |
|
if ((t = fence) < 0) t = getFence(); |
871 |
|
if (t == (i = cursor)) |
872 |
|
return false; |
873 |
< |
final Object[] es; |
866 |
< |
action.accept(nonNullElementAt(es = elements, i)); |
873 |
> |
final Object[] es = elements; |
874 |
|
cursor = inc(i, es.length); |
875 |
+ |
action.accept(nonNullElementAt(es, i)); |
876 |
|
return true; |
877 |
|
} |
878 |
|
|
1240 |
|
|
1241 |
|
/** debugging */ |
1242 |
|
void checkInvariants() { |
1243 |
+ |
// Use head and tail fields with empty slot at tail strategy. |
1244 |
+ |
// head == tail disambiguates to "empty". |
1245 |
|
try { |
1246 |
|
int capacity = elements.length; |
1247 |
|
// assert head >= 0 && head < capacity; |