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 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); } } }
@Override public boolean isEntryAheadOfConsumer(QueueEntry entry, QueueConsumer<?,?> sub) { QueueContext context = sub.getQueueContext(); if(context != null) { QueueEntry releasedNode = context.getReleasedEntry(); return releasedNode != null && releasedNode.compareTo(entry) < 0; } else { return false; } }
private void updateSubRequeueEntry(final QueueConsumer<?,?> sub, final QueueEntry entry) { QueueContext subContext = sub.getQueueContext(); if(subContext != null) { QueueEntry oldEntry; while((oldEntry = subContext.getReleasedEntry()) == null || oldEntry.compareTo(entry) > 0) { if(QueueContext._releasedUpdater.compareAndSet(subContext, oldEntry, entry)) { notifyConsumer(sub); break; } } } }
@Override protected void checkConsumersNotAheadOfDelivery(final QueueEntry entry) { // check that all consumers are not in advance of the entry Iterator<QueueConsumer<?,?>> consumerIterator = getQueueConsumerManager().getAllIterator(); while (consumerIterator.hasNext() && !entry.isAcquired()) { QueueConsumer<?,?> consumer = consumerIterator.next(); if(!consumer.isClosed()) { QueueContext context = consumer.getQueueContext(); if(context != null) { QueueEntry released = context.getReleasedEntry(); while(!entry.isAcquired() && (released == null || released.compareTo(entry) > 0)) { if(QueueContext._releasedUpdater.compareAndSet(context,released,entry)) { break; } else { released = context.getReleasedEntry(); } } } } } }