/*******************************************************************************
* Copyright (c) 2012-2015 INRIA.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Generoso Pagano - initial API and implementation
******************************************************************************/
/**
*
*/
package fr.inria.soctrace.framesoc.ui.model;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
/**
* Queue for streaming operations between one loader thread and one consumer
* thread. The elements being queued are lists of objects of a generic type.
*
* The loader thread, at the end of its operations, must call either
* {@link #setComplete()} or {@link #setStop()}, in order to avoid indefinite
* waiting.
*
* The queue keeps the status of the entire load operation.
*
* @author "Generoso Pagano <generoso.pagano@inria.fr>"
*/
public class LoaderQueue<T> {
private Queue<List<T>> queue = new LinkedList<>();
private TimeInterval interval = null;
private boolean complete = false;
private boolean stop = false;
/**
* Pop a list from the queue, blocking if the queue is empty and the loading
* is not completed and the loading has not been stopped.
*
* @return the list corresponding to the head of the queue or an empty list
* @throws InterruptedException
*/
public synchronized List<T> pop() throws InterruptedException {
while (queue.isEmpty() && !complete && !stop) {
wait();
}
if (stop) {
// wake up after stop
return new ArrayList<>();
}
if (!queue.isEmpty()) {
// wake up after push
return queue.remove();
}
// wake up after completed with empty queue
return new ArrayList<>();
}
/**
* Push a new list into the queue.
*
* @param list
* new list
* @param interval
* loaded interval so far
*/
public synchronized void push(List<T> list, TimeInterval interval) {
this.queue.add(list);
this.interval = interval;
notify();
}
/**
* Sets the flag indicating that the load operation has been stopped.
*/
public synchronized void setStop() {
this.stop = true;
notify();
}
/**
* Returns true if the load operation has been stopped.
*
* @return true if the load operation has been stopped.
*/
public synchronized boolean isStop() {
return this.stop;
}
/**
* Sets the flag indicating that the load operation has been completed.
*/
public synchronized void setComplete() {
this.complete = true;
notify();
}
/**
* Returns true if all the requested data has been pushed into the queue.
* Note that the fact that the load is complete, does not mean that the
* queue is empty.
*
* @return true if the load operation is complete
*/
public synchronized boolean isComplete() {
return this.complete;
}
/**
* Returns true when the entire load operation is done; i.e., the loading is
* complete and the queue is empty, or the loading has been stopped.
*
* @return true if all the operations are finished
*/
public synchronized boolean done() {
return (queue.isEmpty() && complete) || stop;
}
/**
* Get the time interval loaded so far.
*
* @return the time interval loaded so far or null if no time interval has
* been loaded yet.
*/
public synchronized TimeInterval getTimeInterval() {
return interval;
}
}