diff --git a/src/main/java/me/brianlong/git/UniquePriorityFifoQueue.java b/src/main/java/me/brianlong/git/UniquePriorityFifoQueue.java index 40ab2a6..8b72f5f 100644 --- a/src/main/java/me/brianlong/git/UniquePriorityFifoQueue.java +++ b/src/main/java/me/brianlong/git/UniquePriorityFifoQueue.java @@ -3,9 +3,11 @@ package me.brianlong.git; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; +import java.util.HashSet; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Queue; +import java.util.Set; import java.util.TreeSet; public class UniquePriorityFifoQueue implements Queue { @@ -13,15 +15,20 @@ public class UniquePriorityFifoQueue implements Queue { private final Counter counter = new SimpleCounter(); private final Counter fakeCounter = new FakeCounter(); private final TreeSet> elements; + private final Set> uelements; public UniquePriorityFifoQueue() { this.elements = new TreeSet>(); + this.uelements = new HashSet>(); } public UniquePriorityFifoQueue(Collection c) { - this.elements = new TreeSet>(); - for (T element : c) - this.elements.add(new PriorityFifoElement(element, this.counter)); + this(); + for (T e : c) { + PriorityFifoElement element = new PriorityFifoElement(e, this.counter); + this.elements.add(element); + this.uelements.add(element); + } } public UniquePriorityFifoQueue(final Comparator comparator) { @@ -33,29 +40,36 @@ public class UniquePriorityFifoQueue implements Queue { return o1.compareTo(o2); } }); + this.uelements = new HashSet>(); } @Override public boolean add(T e) { - return this.elements.add(new PriorityFifoElement(e, this.counter)); + PriorityFifoElement element = new PriorityFifoElement(e, this.counter); + return this.elements.add(element) && this.uelements.add(element); + } @Override public boolean addAll(Collection c) { - if (c != null) for (T e : c) - this.elements.add(new PriorityFifoElement(e, this.counter)); + if (c != null) for (T e : c) { + PriorityFifoElement element = new PriorityFifoElement(e, this.counter); + this.elements.add(element); + this.uelements.add(element); + } return true; } @Override public void clear() { this.elements.clear(); + this.uelements.clear(); } @SuppressWarnings("unchecked") @Override public boolean contains(Object o) { - return this.elements.contains(new PriorityFifoElement((T)o, this.fakeCounter)); + return this.uelements.contains(new PriorityFifoElement((T)o, this.fakeCounter)); } @Override @@ -80,6 +94,8 @@ public class UniquePriorityFifoQueue implements Queue { public Iterator iterator() { final Iterator> i = this.elements.iterator(); return new Iterator() { + private T lastElement; + @Override public boolean hasNext() { return i.hasNext(); @@ -87,31 +103,37 @@ public class UniquePriorityFifoQueue implements Queue { @Override public T next() { - return i.next().element; + this.lastElement = i.next().element; + return this.lastElement; } @Override public void remove() { i.remove(); + uelements.remove(this.lastElement); } }; } @Override public boolean offer(T e) { - return this.elements.add(new PriorityFifoElement(e, this.counter)); + PriorityFifoElement element = new PriorityFifoElement(e, this.counter); + return this.elements.add(element) && this.uelements.add(element); } @Override public T peek() { - Iterator i = this.iterator(); - return i.hasNext() ? i.next() : null; + Iterator> i = this.elements.iterator(); + return i.hasNext() ? i.next().element : null; } @Override public T poll() { PriorityFifoElement element = this.elements.pollFirst(); - return element == null ? null : element.element; + if (element == null) + return null; + this.uelements.remove(element); + return element.element; } @Override @@ -119,13 +141,18 @@ public class UniquePriorityFifoQueue implements Queue { PriorityFifoElement element = this.elements.pollFirst(); if (element == null) throw new NoSuchElementException(); + this.uelements.remove(element); return element.element; } @SuppressWarnings("unchecked") @Override public boolean remove(Object o) { - return this.elements.remove(new PriorityFifoElement((T)o, this.fakeCounter)); + PriorityFifoElement element = new PriorityFifoElement((T)o, this.fakeCounter); + this.uelements.remove(element); + + element = this.find(element.element); + return this.elements.remove(element); } @Override @@ -139,9 +166,12 @@ public class UniquePriorityFifoQueue implements Queue { public boolean retainAll(Collection c) { Iterator> i = this.elements.iterator(); while (i.hasNext()) { - T e = i.next().element; - if (!c.contains(e)) + PriorityFifoElement e = i.next(); + T element = e.element; + if (!c.contains(element)) { i.remove(); + this.uelements.remove(e); + } } return true; @@ -173,6 +203,15 @@ public class UniquePriorityFifoQueue implements Queue { return a; } + private PriorityFifoElement find(T e) { + for (PriorityFifoElement element : this.elements) { + if (element.element.equals(e)) + return element; + } + + return null; + } + private class PriorityFifoElement implements Comparable> { @@ -187,7 +226,9 @@ public class UniquePriorityFifoQueue implements Queue { @Override public int compareTo(PriorityFifoElement o) { - if (o == null) return 1; + if (this.fifoId < 0) return 0; + else if (o == null) return 1; + else if (o.fifoId < 0) return 0; else return this.fifoId - o.fifoId; } @@ -217,7 +258,7 @@ public class UniquePriorityFifoQueue implements Queue { public class FakeCounter implements Counter { public int next() { - return 0; + return -1; } }