public void testReverse() { PriorityQueue q = new MinHeap(N); Item items[] = new Item[N]; for (int i = 0; i < N; i++) { Item e = new Item(N - i - 1); q.insert(e); items[i] = e; } for (int i = 0; i < N; i++) { q.changePriority(items[i], i); } int j = 0; double pr_last = Double.NEGATIVE_INFINITY; assertTrue("ascending size", q.size() == N); while (q.size() > 0) { assertTrue("ascending extract", j < N); QueueElement e = q.extractMin(); assertTrue("ascending order", e.getPriority() > pr_last); pr_last = e.getPriority(); assertEquals("ascending priority", items[j].getPriority(), e.getPriority()); assertEquals("ascending identity", items[j], e); j++; } }
/** * Dequeue the oldest object on the queue. Used only by the run() method. * * @return the oldest object on the queue. * @exception java.lang.InterruptedException if any thread has interrupted this thread. */ private synchronized QueueElement dequeue() throws InterruptedException { while (tail == null) wait(); QueueElement elt = tail; tail = elt.prev; if (tail == null) { head = null; } else { tail.next = null; } elt.prev = elt.next = null; return elt; }
/** * Enqueue an event. * * @param event Either a <tt>NamingExceptionEvent</tt> or a subclass of <tt>NamingEvent</tt> or * <tt>UnsolicitedNotificatoniEvent</tt>. If it is a subclass of <tt>NamingEvent</tt>, all * listeners must implement the corresponding subinterface of <tt>NamingListener</tt>. For * example, for a <tt>ObjectAddedEvent</tt>, all listeners <em>must</em> implement the * <tt>ObjectAddedListener</tt> interface. <em>The current implementation does not check this * before dispatching the event.</em> If the event is a <tt>NamingExceptionEvent</tt>, then * all listeners are notified. * @param vector List of NamingListeners that will be notified of event. */ synchronized void enqueue(EventObject event, Vector vector) { QueueElement newElt = new QueueElement(event, vector); if (head == null) { head = newElt; tail = newElt; } else { newElt.next = head; head.prev = newElt; head = newElt; } notify(); }
public static void constructHull() { QueueElement<Vertex> v = ConvexHull.vertices.getFirst(); { if (!v.getElem().getMark()) { v.getElem().setMark(true); addOne(v.getElem()); Cleaning.cleanUp(); } v = v.getNext(); } while (v != ConvexHull.vertices.getFirst()) ; }
public static boolean addOne(Vertex p) { boolean visible = false; // mark from p visible faces QueueElement<Face> wf = ConvexHull.faces.getFirst(); while (wf.getNext() != null) { Face f = wf.getElem(); if (volume(f, p) < 0) { f.visible = true; visible = true; } wf = wf.getNext(); } // no faces visible, p is inside of hull if (!visible) { p.onhull = false; return false; } QueueElement<Edge> we = ConvexHull.edges.getFirst(); while (we.getNext() != null) { Edge e = we.getElem(); if (e.getAdjface(0).visible && e.getAdjface(1).visible) { e.deleted = true; } else { if (e.getAdjface(0).visible || e.getAdjface(1).visible) { e.newface = makeStructs(e, p); } } we = we.getNext(); } return true; }
public void testChangePriority() { PriorityQueue q = new MinHeap(N); Item items[] = new Item[N]; for (int i = 0; i < N; i++) { Item e = new Item(N - i - 1); q.insert(e); items[i] = e; } q.changePriority(items[N - 1], -2); q.changePriority(items[N / 2], -1); q.changePriority(items[N / 2 + 1], N * 2); int j = 0; double pr_last = Double.NEGATIVE_INFINITY; assertTrue("descending size", q.size() == N); while (q.size() > 0) { assertTrue("descending extract", j < N); QueueElement e = q.extractMin(); assertTrue("descending order", e.getPriority() > pr_last); pr_last = e.getPriority(); if (j == 0) assertTrue("lowest elt", e.getPriority() == -2); if (j == 1) assertTrue("second-lowest elt", e.getPriority() == -1); if (q.size() == 1) assertTrue("penultimate elt", e.getPriority() == N - 1); if (q.size() == 0) assertTrue("final elt", e.getPriority() == N * 2); j++; } }
/** * Insert the specified {@link QueueElement} element into the queue. * * @param queueElement the {@link QueueElement} element to add. * @param ignoreSize if the queue is bound to a maximum size and the maximum size is reached, this * parameter (if set to <tt>true</tt>) allows to ignore the maximum size and add the element * to the queue. * @return <tt>true</tt> if the element has been inserted, <tt>false</tt> if the element was not * inserted (the queue has reached its maximum size). * @throws NullPointerException if the specified element is null */ boolean offer(QueueElement<E> queueElement, boolean ignoreSize) { if (queueElement == null) { throw new NullPointerException("queueElement is NULL"); } if (queueElement.getPriority() < 0 || queueElement.getPriority() >= priorities) { throw new IllegalArgumentException("priority out of range: " + queueElement); } if (queueElement.inQueue) { throw new IllegalStateException("queueElement already in a queue: " + queueElement); } if (!ignoreSize && currentSize != null && currentSize.get() >= maxSize) { return false; } boolean accepted; lock.lock(); try { accepted = queues[queueElement.getPriority()].offer(queueElement); debug( "offer([{0}]), to P[{1}] delay[{2}ms] accepted[{3}]", queueElement.getElement().toString(), queueElement.getPriority(), queueElement.getDelay(TimeUnit.MILLISECONDS), accepted); if (accepted) { if (currentSize != null) { currentSize.incrementAndGet(); } queueElement.inQueue = true; } } finally { lock.unlock(); } return accepted; }
public void testDescending() { PriorityQueue q = new MinHeap(N); double p[] = new double[N]; for (int i = 0; i < N; i++) { p[i] = i; Item e = new Item(N - i - 1); q.insert(e); } int j = 0; double pr = Double.NEGATIVE_INFINITY; assertTrue("descending size", q.size() == N); while (q.size() > 0) { assertTrue("descending extract", j < N); QueueElement e = q.extractMin(); assertTrue("descending order", e.getPriority() > pr); assertEquals("descending priority", e.getPriority(), p[j++], 1e-5); pr = e.getPriority(); } }
public void testEqualKeys() { PriorityQueue q = new MinHeap(N); Item[] items = new Item[20]; int j = 0; for (int i = 0; i < 5; i++) { items[j] = new Item(5); q.insert(items[j]); j++; } for (int i = 0; i < 5; i++) { items[j] = new Item(3); q.insert(items[j]); j++; } for (int i = 0; i < 5; i++) { items[j] = new Item(4); q.insert(items[j]); j++; } for (int i = 0; i < 5; i++) { items[j] = new Item(7); q.insert(items[j]); j++; } assertEquals(20, q.size()); for (int i = 0; i < items.length; i++) { assertTrue(q.contains(items[i])); } for (int i = 0; i < 5; i++) { QueueElement e = q.extractMin(); assertTrue(q.contains(q.min())); assertEquals(3.0, e.getPriority()); } for (int i = 0; i < 5; i++) { QueueElement e = q.extractMin(); assertTrue(q.contains(q.min())); assertEquals(4.0, e.getPriority()); } for (int i = 0; i < 5; i++) { QueueElement e = q.extractMin(); assertTrue(q.contains(q.min())); assertEquals(5.0, e.getPriority()); } for (int i = 0; i < 5; i++) { QueueElement e = q.extractMin(); if (q.size() > 0) assertTrue(q.contains(q.min())); assertEquals(7.0, e.getPriority()); } }
/** * Promote elements beyond max wait time from a lower priority sub-queue to a higher priority * sub-queue. * * @param lowerQ lower priority sub-queue. * @param higherQ higher priority sub-queue. * @param msg sub-queues msg (from-to) for debugging purposes. */ private void antiStarvation( DelayQueue<QueueElement<E>> lowerQ, DelayQueue<QueueElement<E>> higherQ, String msg) { int moved = 0; QueueElement<E> e = lowerQ.poll(); while (e != null && e.getDelay(TimeUnit.MILLISECONDS) < -maxWait) { e.setDelay(0, TimeUnit.MILLISECONDS); if (!higherQ.offer(e)) { throw new IllegalStateException( "Could not move element to higher sub-queue, element rejected"); } e.priority++; e = lowerQ.poll(); moved++; } if (e != null) { if (!lowerQ.offer(e)) { throw new IllegalStateException( "Could not reinsert element to current sub-queue, element rejected"); } } debug("anti-starvation, moved {0} element(s) {1}", moved, msg); }
/** * Retrieve and remove the head of this queue, or return <tt>null</tt> if this queue has no * elements with an expired delay. * * <p>The retrieved element is the oldest one from the highest priority sub-queue. * * <p>Invocations to this method run the anti-starvation (once every interval check). * * @return the head of this queue, or <tt>null</tt> if this queue has no elements with an expired * delay. */ @Override public QueueElement<E> poll() { lock.lock(); try { antiStarvation(); QueueElement<E> e = null; int i = priorities; for (; e == null && i > 0; i--) { e = queues[i - 1].poll(); } if (e != null) { if (currentSize != null) { currentSize.decrementAndGet(); } e.inQueue = false; debug("poll(): [{0}], from P[{1}]", e.getElement().toString(), i); } return e; } finally { lock.unlock(); } }
/** * Retrieve, but does not remove, the head of this queue, or returns <tt>null</tt> if this queue * is empty. Unlike <tt>poll</tt>, if no expired elements are available in the queue, this method * returns the element that will expire next, if one exists. * * @return the head of this queue, or <tt>null</tt> if this queue is empty. */ @Override public QueueElement<E> peek() { lock.lock(); try { antiStarvation(); QueueElement<E> e = null; QueueElement<E>[] seeks = new QueueElement[priorities]; boolean foundElement = false; for (int i = priorities - 1; i > -1; i--) { e = queues[i].peek(); debug("peek(): considering [{0}] from P[{1}]", e, i); seeks[priorities - i - 1] = e; foundElement |= e != null; } if (foundElement) { e = null; for (int i = 0; e == null && i < priorities; i++) { if (seeks[i] != null && seeks[i].getDelay(TimeUnit.MILLISECONDS) > 0) { debug("peek, ignoring [{0}]", seeks[i]); } else { e = seeks[i]; } } if (e != null) { debug("peek(): choosing [{0}]", e); } if (e == null) { int first; for (first = 0; e == null && first < priorities; first++) { e = seeks[first]; } if (e != null) { debug("peek(): initial choosing [{0}]", e); } for (int i = first; i < priorities; i++) { QueueElement<E> ee = seeks[i]; if (ee != null && ee.getDelay(TimeUnit.MILLISECONDS) < e.getDelay(TimeUnit.MILLISECONDS)) { debug("peek(): choosing [{0}] over [{1}]", ee, e); e = ee; } } } } if (e != null) { debug("peek(): [{0}], from P[{1}]", e.getElement().toString(), e.getPriority()); } else { debug("peek(): NULL"); } return e; } finally { lock.unlock(); } }
public static void buildTetrahedron() { QueueElement<Vertex> v0; QueueElement<Vertex> v3; int volume; // find 3 noncollinear points v0 = ConvexHull.vertices.getFirst(); while (collinear(v0.getElem(), v0.getNext().getElem(), v0.getNext().getNext().getElem())) { v0 = v0.getNext(); if (v0.getNext() == ConvexHull.vertices.getFirst()) { System.err.println("All points are collinear"); System.exit(0); } } // mark vertices as processed v0.getElem().setMark(true); v0.getNext().getElem().setMark(true); v0.getNext().getNext().getElem().setMark(true); Edge e0 = Edge.makeEdge(v0.getElem(), v0.getNext().getElem()); Edge e1 = Edge.makeEdge(v0.getNext().getElem(), v0.getNext().getNext().getElem()); Edge e2 = Edge.makeEdge(v0.getNext().getNext().getElem(), v0.getElem()); Face f = Face.makeFace(e0, e1, e2); f.setVertices(v0.getElem(), v0.getNext().getElem(), v0.getNext().getNext().getElem()); e0.setAdjface(0, f); e1.setAdjface(0, f); e1.setAdjface(0, f); // try to find another noncollinear vertex v3 = v0.getNext().getNext().getNext(); volume = volume(f, v3.getElem()); while (volume == 0) { v3 = v3.getNext(); if (v3 == ConvexHull.vertices.getFirst()) { System.err.println("All points are coplanar"); System.exit(0); } volume = volume(f, v3.getElem()); } v3.getElem().setMark(true); // store vertices in ccw order if (volume < 0) { swap(f.getVertex(1), f.getVertex(2)); swap(f.getEdge(1), f.getEdge(2)); } e0.setAdjface(1, makeStructs(e0, v3.getElem())); e1.setAdjface(1, makeStructs(e1, v3.getElem())); e2.setAdjface(1, makeStructs(e2, v3.getElem())); Cleaning.cleanUp(); }