private synchronized void updateState() { if (closed.get()) { // remove all empty queues for (Iterator<NamedQueue> iterator = openQueuesBySequenceId.iterator(); iterator.hasNext(); ) { NamedQueue namedQueue = iterator.next(); if (namedQueue.isEmpty()) { namedQueue.setFinished(); iterator.remove(); } } // discard queued pages (not officially in the buffer) and waiters for (QueuedPage queuedPage : queuedPages) { queuedPage.getFuture().set(null); } queuedPages.clear(); } if (state == QueueState.NO_MORE_QUEUES && !openQueuesBySequenceId.isEmpty()) { // advance master sequence id long oldMasterSequenceId = masterSequenceId; masterSequenceId = openQueuesBySequenceId.iterator().next().getSequenceId(); // drop consumed pages int pagesToRemove = Ints.checkedCast(masterSequenceId - oldMasterSequenceId); Preconditions.checkState( pagesToRemove >= 0, "Master sequence id moved backwards: oldMasterSequenceId=%s, newMasterSequenceId=%s", oldMasterSequenceId, masterSequenceId); for (int i = 0; i < pagesToRemove; i++) { Page page = masterQueue.removeFirst(); bufferedBytes -= page.getDataSize().toBytes(); } // refill buffer from queued pages while (!queuedPages.isEmpty() && bufferedBytes < maxBufferedBytes) { QueuedPage queuedPage = queuedPages.removeFirst(); addInternal(queuedPage.getPage()); queuedPage.getFuture().set(null); } } if (state == QueueState.NO_MORE_QUEUES && closed.get() && openQueuesBySequenceId.isEmpty()) { destroy(); } this.notifyAll(); }
public synchronized ListenableFuture<?> enqueue(Page page) { Preconditions.checkNotNull(page, "page is null"); // is the output done if (closed.get()) { return Futures.immediateFuture(true); } // is there room in the buffer if (bufferedBytes < maxBufferedBytes) { addInternal(page); return Futures.immediateFuture(true); } QueuedPage queuedPage = new QueuedPage(page); queuedPages.addLast(queuedPage); return queuedPage.getFuture(); }
/** Destroys the queue, discarding all pages. */ public synchronized void destroy() { closed.set(true); state = QueueState.FINISHED; // drop all of the queues for (NamedQueue namedQueue : openQueuesBySequenceId) { namedQueue.setFinished(); } openQueuesBySequenceId.clear(); // clear the buffer masterQueue.clear(); bufferedBytes = 0; // free queued page waiters for (QueuedPage queuedPage : queuedPages) { queuedPage.getFuture().set(null); } queuedPages.clear(); // notify readers that the buffer has been destroyed this.notifyAll(); }