+/*
+ * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+/**
+ * @file
+ * @author Christian Wuerdig, Matthias Braun
+ * @brief Priority Queue implementation based on the heap datastructure
+ */
+#include "config.h"
+
#include "array.h"
#include "pqueue.h"
+#include "error.h"
-/**
+/*
* Implements a heap.
*
* Implementation note: It might seem strange that we start indexing at 0
* implementations or the ugly (i+1)*2 - 1 and (i+1)*2 for calculating the
* left and right child. (At the expense that stuff easily breaks when you make
* changes and don't think that the left child of 0 is 0 :-/)
- * @author matze
*
*/
-typedef struct _pqueue_el_t {
+typedef struct pqueue_el_t {
void *data;
- int key;
+ int priority;
} pqueue_el_t;
-struct _pqueue_t {
+struct pqueue_t {
pqueue_el_t *elems;
};
* Enforces the heap characteristics if the queue
* starting from element at position @p pos.
*/
-static void pqueue_heapify(pqueue *q, int pos) {
- int len = ARR_LEN(q->elems);
+static void pqueue_heapify(pqueue_t *q, size_t pos)
+{
+ size_t len = ARR_LEN(q->elems);
while (pos * 2 < len) {
pqueue_el_t tmp;
- int exchange = pos;
+ size_t exchange = pos;
- if (q->elems[exchange].key < q->elems[pos * 2].key) {
+ if (q->elems[exchange].priority < q->elems[pos * 2].priority) {
exchange = pos * 2;
}
- if ((pos * 2 + 1) < len && q->elems[exchange].key < q->elems[pos * 2 + 1].key) {
+ if ((pos * 2 + 1) < len
+ && q->elems[exchange].priority < q->elems[pos * 2 + 1].priority) {
exchange = pos * 2 + 1;
}
/**
* Sifts up a newly inserted element at position @p pos.
*/
-static void pqueue_sift_up(pqueue *q, int pos) {
- while(q->elems[pos].key > q->elems[pos / 2].key) {
+static void pqueue_sift_up(pqueue_t *q, size_t pos)
+{
+ while (q->elems[pos].priority > q->elems[pos / 2].priority) {
pqueue_el_t tmp;
tmp = q->elems[pos];
}
}
-/**
- * Creates a new priority queue.
- * @return A priority queue of initial length 0.
- */
-pqueue *new_pqueue(void) {
- pqueue *res = xmalloc(sizeof(*res));
+pqueue_t *new_pqueue(void)
+{
+ pqueue_t *res = XMALLOC(pqueue_t);
res->elems = NEW_ARR_F(pqueue_el_t, 0);
return res;
}
-/**
- * Frees all memory allocated by the priority queue.
- * @param q The priority queue to destroy.
- */
-void del_pqueue(pqueue *q) {
+void del_pqueue(pqueue_t *q)
+{
DEL_ARR_F(q->elems);
free(q);
}
-/**
- * Inserts a new element into a priority queue.
- * @param q The priority queue the element should be inserted to.
- * @param data The actual data which should be stored in the queue.
- * @param key The priority for the data.
- */
-void pqueue_put(pqueue *q, void *data, int key) {
+void pqueue_put(pqueue_t *q, void *data, int priority)
+{
pqueue_el_t el;
- el.data = data;
- el.key = key;
+ el.data = data;
+ el.priority = priority;
ARR_APP1(pqueue_el_t, q->elems, el);
pqueue_sift_up(q, ARR_LEN(q->elems) - 1);
}
-/**
- * Returns and removes the first element, ie. that one with the highest priority, from the queue.
- * @param q The priority queue.
- * @return The first element of the queue. Asserts if queue is empty.
- */
-void *pqueue_get(pqueue *q) {
- switch(ARR_LEN(q->elems)) {
+void *pqueue_pop_front(pqueue_t *q)
+{
+ switch (ARR_LEN(q->elems)) {
case 0:
- assert(0 && "Attempt to retrieve element from empty priority queue.");
- return NULL;
- break;
+ panic("Attempt to retrieve element from empty priority queue.");
case 1:
ARR_SHRINKLEN(q->elems, 0);
return q->elems[0].data;
- break;
default: {
- void *data = q->elems[0].data;
- int len = ARR_LEN(q->elems) - 1;
+ void *data = q->elems[0].data;
+ size_t len = ARR_LEN(q->elems) - 1;
q->elems[0] = q->elems[len];
ARR_SHRINKLEN(q->elems, len);
}
}
-/**
- * Get the length of the priority queue.
- * @param q The priority queue.
- * @return The length of the queue.
- */
-int pqueue_length(pqueue *q) {
+size_t pqueue_length(const pqueue_t *q)
+{
return ARR_LEN(q->elems);
}
-/**
- * Returns true if queue is empty.
- * @param q The priority queue.
- * @return 1 if the queue is empty, 0 otherwise.
- */
-int pqueue_empty(pqueue *q) {
+int pqueue_empty(const pqueue_t *q)
+{
return ARR_LEN(q->elems) == 0;
}