131 |
|
* Call only when holding lock. |
132 |
|
*/ |
133 |
|
private void enqueue(E x) { |
134 |
< |
assert lock.getHoldCount() == 1; |
135 |
< |
assert items[putIndex] == null; |
134 |
> |
// assert lock.getHoldCount() == 1; |
135 |
> |
// assert items[putIndex] == null; |
136 |
|
items[putIndex] = x; |
137 |
|
putIndex = inc(putIndex); |
138 |
|
count++; |
144 |
|
* Call only when holding lock. |
145 |
|
*/ |
146 |
|
private E dequeue() { |
147 |
< |
assert lock.getHoldCount() == 1; |
148 |
< |
assert items[takeIndex] != null; |
147 |
> |
// assert lock.getHoldCount() == 1; |
148 |
> |
// assert items[takeIndex] != null; |
149 |
|
final Object[] items = this.items; |
150 |
|
@SuppressWarnings("unchecked") E x = (E) items[takeIndex]; |
151 |
|
items[takeIndex] = null; |
163 |
|
* Call only when holding lock. |
164 |
|
*/ |
165 |
|
void removeAt(final int removeIndex) { |
166 |
< |
assert lock.getHoldCount() == 1; |
167 |
< |
assert items[removeIndex] != null; |
168 |
< |
assert removeIndex >= 0 && removeIndex < items.length; |
166 |
> |
// assert lock.getHoldCount() == 1; |
167 |
> |
// assert items[removeIndex] != null; |
168 |
> |
// assert removeIndex >= 0 && removeIndex < items.length; |
169 |
|
final Object[] items = this.items; |
170 |
|
if (removeIndex == takeIndex) { |
171 |
|
// removing front item; just advance |
808 |
|
* there is known to be at least one iterator to collect |
809 |
|
*/ |
810 |
|
void doSomeSweeping(boolean tryHarder) { |
811 |
< |
assert lock.getHoldCount() == 1; |
812 |
< |
assert head != null; |
811 |
> |
// assert lock.getHoldCount() == 1; |
812 |
> |
// assert head != null; |
813 |
|
int probes = tryHarder ? LONG_SWEEP_PROBES : SHORT_SWEEP_PROBES; |
814 |
|
Node o, p; |
815 |
|
final Node sweeper = this.sweeper; |
864 |
|
* Adds a new iterator to the linked list of tracked iterators. |
865 |
|
*/ |
866 |
|
void register(Itr itr) { |
867 |
< |
assert lock.getHoldCount() == 1; |
867 |
> |
// assert lock.getHoldCount() == 1; |
868 |
|
head = new Node(itr, head); |
869 |
|
} |
870 |
|
|
874 |
|
* Notifies all iterators, and expunges any that are now stale. |
875 |
|
*/ |
876 |
|
void takeIndexWrapped() { |
877 |
< |
assert lock.getHoldCount() == 1; |
877 |
> |
// assert lock.getHoldCount() == 1; |
878 |
|
cycles++; |
879 |
|
for (Node o = null, p = head; p != null;) { |
880 |
|
final Itr it = p.get(); |
881 |
|
final Node next = p.next; |
882 |
|
if (it == null || it.takeIndexWrapped()) { |
883 |
|
// unlink p |
884 |
< |
assert it == null || it.isDetached(); |
884 |
> |
// assert it == null || it.isDetached(); |
885 |
|
p.clear(); |
886 |
|
p.next = null; |
887 |
|
if (o == null) |
908 |
|
final Node next = p.next; |
909 |
|
if (it == null || it.removedAt(removedIndex)) { |
910 |
|
// unlink p |
911 |
< |
assert it == null || it.isDetached(); |
911 |
> |
// assert it == null || it.isDetached(); |
912 |
|
p.clear(); |
913 |
|
p.next = null; |
914 |
|
if (o == null) |
931 |
|
* clears all weak refs, and unlinks the itrs datastructure. |
932 |
|
*/ |
933 |
|
void queueIsEmpty() { |
934 |
< |
assert lock.getHoldCount() == 1; |
934 |
> |
// assert lock.getHoldCount() == 1; |
935 |
|
for (Node p = head; p != null; p = p.next) { |
936 |
|
Itr it = p.get(); |
937 |
|
if (it != null) { |
947 |
|
* Called whenever an element has been dequeued (at takeIndex). |
948 |
|
*/ |
949 |
|
void elementDequeued() { |
950 |
< |
assert lock.getHoldCount() == 1; |
950 |
> |
// assert lock.getHoldCount() == 1; |
951 |
|
if (count == 0) |
952 |
|
queueIsEmpty(); |
953 |
|
else if (takeIndex == 0) |
1008 |
|
private static final int DETACHED = -3; |
1009 |
|
|
1010 |
|
Itr() { |
1011 |
< |
assert lock.getHoldCount() == 0; |
1011 |
> |
// assert lock.getHoldCount() == 0; |
1012 |
|
lastRet = NONE; |
1013 |
|
final ReentrantLock lock = ArrayBlockingQueue.this.lock; |
1014 |
|
lock.lock(); |
1015 |
|
try { |
1016 |
|
if (count == 0) { |
1017 |
< |
assert itrs == null; |
1017 |
> |
// assert itrs == null; |
1018 |
|
cursor = NONE; |
1019 |
|
nextIndex = NONE; |
1020 |
|
prevTakeIndex = DETACHED; |
1030 |
|
itrs.doSomeSweeping(false); |
1031 |
|
} |
1032 |
|
prevCycles = itrs.cycles; |
1033 |
< |
assert takeIndex >= 0; |
1034 |
< |
assert prevTakeIndex == takeIndex; |
1035 |
< |
assert nextIndex >= 0; |
1036 |
< |
assert nextItem != null; |
1033 |
> |
// assert takeIndex >= 0; |
1034 |
> |
// assert prevTakeIndex == takeIndex; |
1035 |
> |
// assert nextIndex >= 0; |
1036 |
> |
// assert nextItem != null; |
1037 |
|
} |
1038 |
|
} finally { |
1039 |
|
lock.unlock(); |
1041 |
|
} |
1042 |
|
|
1043 |
|
boolean isDetached() { |
1044 |
< |
assert lock.getHoldCount() == 1; |
1044 |
> |
// assert lock.getHoldCount() == 1; |
1045 |
|
return prevTakeIndex < 0; |
1046 |
|
} |
1047 |
|
|
1048 |
|
private int incCursor(int index) { |
1049 |
< |
assert lock.getHoldCount() == 1; |
1049 |
> |
// assert lock.getHoldCount() == 1; |
1050 |
|
index = inc(index); |
1051 |
|
if (index == putIndex) |
1052 |
|
index = NONE; |
1072 |
|
* operation on this iterator. Call only from iterating thread. |
1073 |
|
*/ |
1074 |
|
private void incorporateDequeues() { |
1075 |
< |
assert lock.getHoldCount() == 1; |
1076 |
< |
assert itrs != null; |
1077 |
< |
assert !isDetached(); |
1078 |
< |
assert count > 0; |
1075 |
> |
// assert lock.getHoldCount() == 1; |
1076 |
> |
// assert itrs != null; |
1077 |
> |
// assert !isDetached(); |
1078 |
> |
// assert count > 0; |
1079 |
|
|
1080 |
|
final int cycles = itrs.cycles; |
1081 |
|
final int takeIndex = ArrayBlockingQueue.this.takeIndex; |
1115 |
|
*/ |
1116 |
|
private void detach() { |
1117 |
|
// Switch to detached mode |
1118 |
< |
assert lock.getHoldCount() == 1; |
1119 |
< |
assert cursor == NONE; |
1120 |
< |
assert nextIndex < 0; |
1121 |
< |
assert lastRet < 0 || nextItem == null; |
1122 |
< |
assert lastRet < 0 ^ lastItem != null; |
1118 |
> |
// assert lock.getHoldCount() == 1; |
1119 |
> |
// assert cursor == NONE; |
1120 |
> |
// assert nextIndex < 0; |
1121 |
> |
// assert lastRet < 0 || nextItem == null; |
1122 |
> |
// assert lastRet < 0 ^ lastItem != null; |
1123 |
|
if (prevTakeIndex >= 0) { |
1124 |
< |
assert itrs != null; |
1124 |
> |
// assert itrs != null; |
1125 |
|
prevTakeIndex = DETACHED; |
1126 |
|
// try to unlink from itrs (but not too hard) |
1127 |
|
itrs.doSomeSweeping(true); |
1135 |
|
* triggered by queue modifications. |
1136 |
|
*/ |
1137 |
|
public boolean hasNext() { |
1138 |
< |
assert lock.getHoldCount() == 0; |
1138 |
> |
// assert lock.getHoldCount() == 0; |
1139 |
|
if (nextItem != null) |
1140 |
|
return true; |
1141 |
|
noNext(); |
1146 |
|
final ReentrantLock lock = ArrayBlockingQueue.this.lock; |
1147 |
|
lock.lock(); |
1148 |
|
try { |
1149 |
< |
assert cursor == NONE; |
1150 |
< |
assert nextIndex == NONE; |
1149 |
> |
// assert cursor == NONE; |
1150 |
> |
// assert nextIndex == NONE; |
1151 |
|
if (!isDetached()) { |
1152 |
< |
assert lastRet >= 0; |
1152 |
> |
// assert lastRet >= 0; |
1153 |
|
incorporateDequeues(); // might update lastRet |
1154 |
|
if (lastRet >= 0) { |
1155 |
|
lastItem = itemAt(lastRet); |
1156 |
< |
assert lastItem != null; |
1156 |
> |
// assert lastItem != null; |
1157 |
|
detach(); |
1158 |
|
} |
1159 |
|
} |
1160 |
< |
assert isDetached(); |
1161 |
< |
assert lastRet < 0 ^ lastItem != null; |
1160 |
> |
// assert isDetached(); |
1161 |
> |
// assert lastRet < 0 ^ lastItem != null; |
1162 |
|
} finally { |
1163 |
|
lock.unlock(); |
1164 |
|
} |
1165 |
|
} |
1166 |
|
|
1167 |
|
public E next() { |
1168 |
< |
assert lock.getHoldCount() == 0; |
1168 |
> |
// assert lock.getHoldCount() == 0; |
1169 |
|
final E x = nextItem; |
1170 |
|
if (x == null) |
1171 |
|
throw new NoSuchElementException(); |
1174 |
|
try { |
1175 |
|
if (!isDetached()) |
1176 |
|
incorporateDequeues(); |
1177 |
< |
assert nextIndex != NONE; |
1178 |
< |
assert lastItem == null; |
1177 |
> |
// assert nextIndex != NONE; |
1178 |
> |
// assert lastItem == null; |
1179 |
|
lastRet = nextIndex; |
1180 |
|
final int cursor = this.cursor; |
1181 |
|
if (cursor >= 0) { |
1182 |
|
nextItem = itemAt(nextIndex = cursor); |
1183 |
< |
assert nextItem != null; |
1183 |
> |
// assert nextItem != null; |
1184 |
|
this.cursor = incCursor(cursor); |
1185 |
|
} else { |
1186 |
|
nextIndex = NONE; |
1193 |
|
} |
1194 |
|
|
1195 |
|
public void remove() { |
1196 |
< |
assert lock.getHoldCount() == 0; |
1196 |
> |
// assert lock.getHoldCount() == 0; |
1197 |
|
final ReentrantLock lock = ArrayBlockingQueue.this.lock; |
1198 |
|
lock.lock(); |
1199 |
|
try { |
1206 |
|
removeAt(lastRet); |
1207 |
|
else { |
1208 |
|
final E lastItem = this.lastItem; |
1209 |
< |
assert lastItem != null; |
1209 |
> |
// assert lastItem != null; |
1210 |
|
this.lastItem = null; |
1211 |
|
if (itemAt(lastRet) == lastItem) |
1212 |
|
removeAt(lastRet); |
1221 |
|
detach(); |
1222 |
|
} finally { |
1223 |
|
lock.unlock(); |
1224 |
< |
assert lastRet == NONE; |
1225 |
< |
assert lastItem == null; |
1224 |
> |
// assert lastRet == NONE; |
1225 |
> |
// assert lastItem == null; |
1226 |
|
} |
1227 |
|
} |
1228 |
|
|
1233 |
|
* from next(), as promised by returning true from hasNext(). |
1234 |
|
*/ |
1235 |
|
void shutdown() { |
1236 |
< |
assert lock.getHoldCount() == 1; |
1236 |
> |
// assert lock.getHoldCount() == 1; |
1237 |
|
cursor = NONE; |
1238 |
|
if (nextIndex >= 0) |
1239 |
|
nextIndex = REMOVED; |
1261 |
|
* @return true if this iterator should be unlinked from itrs |
1262 |
|
*/ |
1263 |
|
boolean removedAt(int removedIndex) { |
1264 |
< |
assert lock.getHoldCount() == 1; |
1264 |
> |
// assert lock.getHoldCount() == 1; |
1265 |
|
if (isDetached()) |
1266 |
|
return true; |
1267 |
|
|
1275 |
|
cycleDiff++; |
1276 |
|
final int removedDistance = |
1277 |
|
(cycleDiff * len) + (removedIndex - prevTakeIndex); |
1278 |
< |
assert removedDistance >= 0; |
1278 |
> |
// assert removedDistance >= 0; |
1279 |
|
int cursor = this.cursor; |
1280 |
|
if (cursor >= 0) { |
1281 |
|
int x = distance(cursor, prevTakeIndex, len); |
1284 |
|
this.cursor = cursor = NONE; |
1285 |
|
} |
1286 |
|
else if (x > removedDistance) { |
1287 |
< |
assert cursor != prevTakeIndex; |
1287 |
> |
// assert cursor != prevTakeIndex; |
1288 |
|
this.cursor = cursor = dec(cursor); |
1289 |
|
} |
1290 |
|
} |
1317 |
|
* @return true if this iterator should be unlinked from itrs |
1318 |
|
*/ |
1319 |
|
boolean takeIndexWrapped() { |
1320 |
< |
assert lock.getHoldCount() == 1; |
1320 |
> |
// assert lock.getHoldCount() == 1; |
1321 |
|
if (isDetached()) |
1322 |
|
return true; |
1323 |
|
if (itrs.cycles - prevCycles > 1) { |