package info.opencards.learnstrats.ltm;
import info.opencards.core.Item;
import java.util.*;
/**
* An unltra-short-term-memory scheduler which allows to put in <code>Item</code>s and provides theses files after a
* defined amount of time in a FIFO manner.
*
* @author Holger Brandl
*/
class USTMScheduler {
private Timer timer;
/**
* The itmes which are already timeouted.
*/
private final List<Item> rescheduledItems = new ArrayList<Item>();
/**
* The map which contains all *running* delay-timers.
*/
private final Map<Item, ItemReschedulerTask> itemTimers = new HashMap<Item, ItemReschedulerTask>();
/**
* The delay to be used to delay a not-learnt item.
*/
private long delay;
public USTMScheduler(long delayMs) {
assert delayMs > 1000; // less make absolutely no sense and the asserts should block values in seconds
this.delay = delayMs;
timer = new Timer();
}
public synchronized void reschedule(Item item) {
if (itemTimers.containsKey(item)) {
itemTimers.get(item).cancel();
}
ItemReschedulerTask reschedulerTask = new ItemReschedulerTask(item);
timer.schedule(reschedulerTask, delay);
itemTimers.put(item, reschedulerTask);
}
public boolean hasScheduledItems() {
return !rescheduledItems.isEmpty();
}
public Item getScheduledItem() {
return hasScheduledItems() ? rescheduledItems.remove(0) : null;
}
public void stop() {
timer.cancel();
}
public Collection<Item> getAllCurrentItems() {
return new ArrayList<Item>(itemTimers.keySet());
}
public synchronized Item cancelNextTask() {
Item item = Collections.min(itemTimers.keySet(), new Comparator<Item>() {
public int compare(Item o1, Item o2) {
return (int) (itemTimers.get(o1).scheduledExecutionTime() - itemTimers.get(o2).scheduledExecutionTime());
}
});
// cancel the task if still possible
itemTimers.remove(item).cancel();
return item;
}
class ItemReschedulerTask extends TimerTask {
private final Item item;
public ItemReschedulerTask(Item item) {
this.item = item;
}
public void run() {
rescheduledItems.add(item);
itemTimers.remove(item);
}
}
}