@Override public OrderedQueueEntry getNextValidEntry() { OrderedQueueEntry next = getNextNode(); while(next != null && next.isDeleted()) { final OrderedQueueEntry newNext = next.getNextNode(); if(newNext != null) { OrderedQueueEntryList._nextUpdater.compareAndSet(this,next, newNext); next = getNextNode(); } else { next = null; } } return next; }
@Override public void release() { super.release(); discardIfReleasedEntryIsNoLongerLatest(); }
@Override public QueueEntry add(ServerMessage message, final MessageEnqueueRecord enqueueRecord) { final OrderedQueueEntry node = createQueueEntry(message, enqueueRecord); updateStatsOnEnqueue(node); for (;;) { OrderedQueueEntry tail = _tail; OrderedQueueEntry next = tail.getNextNode(); if (tail == _tail) { if (next == null) { node.setEntryId(tail.getEntryId()+1); if (_nextUpdater.compareAndSet(tail, null, node)) { _tailUpdater.compareAndSet(this, tail, node); return node; } } else { _tailUpdater.compareAndSet(this,tail, next); } } } }
@Override public void entryDeleted(QueueEntry queueEntry) { QueueEntry next = _head.getNextNode(); QueueEntry newNext = _head.getNextValidEntry(); // the head of the queue has not been deleted, hence the deletion must have been mid queue. if (next == newNext) { QueueEntry unscavengedHWM = _unscavengedHWM.get(); while(unscavengedHWM == null || unscavengedHWM.compareTo(queueEntry)<0) { _unscavengedHWM.compareAndSet(unscavengedHWM, queueEntry); unscavengedHWM = _unscavengedHWM.get(); } if (_scavenges.incrementAndGet() > _scavengeCount) { _scavenges.set(0L); scavenge(); } } else { QueueEntry unscavengedHWM = _unscavengedHWM.get(); if(unscavengedHWM != null && (next == null || unscavengedHWM.compareTo(next) < 0)) { _unscavengedHWM.compareAndSet(unscavengedHWM, null); } } }
void scavenge() { QueueEntry hwm = _unscavengedHWM.getAndSet(null); QueueEntry next = _head.getNextValidEntry(); if(hwm != null) { while (next != null && hwm.compareTo(next)>0) { next = next.getNextValidEntry(); } } }
@Override public int compareTo(final QueueEntry o) { PriorityQueueEntry other = (PriorityQueueEntry)o; PriorityQueueEntrySubList pqel = (PriorityQueueEntrySubList)other.getQueueEntryList(); int otherPriority = pqel.getListPriority(); int thisPriority = ((PriorityQueueEntrySubList) getQueueEntryList()).getListPriority(); if(thisPriority != otherPriority) { /* * Different priorities, so answer can only be greater than or less than * * A message with higher priority (e.g. 5) is conceptually 'earlier' in the * priority queue than one with a lower priority (e.g. 4). */ return thisPriority > otherPriority ? -1 : 1; } else { return super.compareTo(o); } } }
@Override public void release(MessageInstanceConsumer<?> consumer) { super.release(consumer); discardIfReleasedEntryIsNoLongerLatest(); }