package com.datascience.scheduler; import com.google.common.base.Objects; import java.util.*; /** * @Author: konrad */ public class IterablePriorityQueue<T> implements IIterablePriorityQueue<T> { protected NavigableSet<ElementWithPriority> queue; protected Map<T, ElementWithPriority> finder; protected Comparator<T> comparator; public IterablePriorityQueue(Comparator<T> comparator){ this.comparator = comparator; clear(); } @Override public void clear(){ queue = new TreeSet<ElementWithPriority>(); finder = new HashMap<T, ElementWithPriority>(); } @Override public void addReplacing(T object, double priority) { remove(object); ElementWithPriority element = new ElementWithPriority(object, priority); finder.put(object, element); queue.add(element); } @Override public void remove(T object) { ElementWithPriority el = finder.get(object); if (el != null){ queue.remove(el); finder.remove(object); } } @Override public T first() { if (queue.isEmpty()) return null; return queue.first().element; } @Override public T getAndRemoveFirst() { T el = first(); remove(el); return el; } @Override public Iterator<T> iterator() { return new IPCIterator(queue.iterator()); } protected class ElementWithPriority implements Comparable<ElementWithPriority>{ protected T element; protected double priority; public ElementWithPriority(T element, double priority){ this.element = element; this.priority = priority; } @Override public int compareTo(ElementWithPriority other) { int cmp = Double.compare(priority, other.priority); if (cmp == 0) { return comparator.compare(element, other.element); } return cmp; } @Override public boolean equals(Object object){ if (object instanceof IterablePriorityQueue.ElementWithPriority){ ElementWithPriority other = (IterablePriorityQueue.ElementWithPriority) object; return compareTo(other) == 0; } return false; } @Override public int hashCode(){ return Objects.hashCode(priority, element); } } protected class IPCIterator implements Iterator<T>{ protected Iterator<ElementWithPriority> internalIterator; public IPCIterator(Iterator<ElementWithPriority> internalIterator){ this.internalIterator = internalIterator; } @Override public boolean hasNext() { return internalIterator.hasNext(); } @Override public T next() { return internalIterator.next().element; } @Override public void remove() { internalIterator.remove(); } } }