// *and* that the event we have wasn't rolled off due to max-size limitations, we then
// pull the item off the queue and return it. We're basically doing optimistic concurrency,
// and skewing things so that adding to this should be cheap.
while (true) {
final TaskStatusEvent current = findEldestEvent();
// Didn't find anything that needed processing?
if (current == null) {
return null;
}
final JobId id = current.getStatus().getJob().getId();
final Deque<TaskStatusEvent> deque = items.get(id);
if (deque == null) {
// shouldn't happen because we should be the only one pulling items off, but....
continue;
}
synchronized (deque) {
if (!deque.peek().equals(current)) {
// item got rolled off, try again
continue;
}
// Pull it off the queue and be paranoid.
final TaskStatusEvent newCurrent = deque.poll();
count.decrementAndGet();
checkState(current.equals(newCurrent), "current should equal newCurrent");
// Safe because this is the *only* place we hold these two locks at the same time.
synchronized (items) {
// Extra paranoia: curDeque should always == deque