beifg: Factorise code to count interference components.
[libfirm] / ir / adt / pqueue.c
index e8495b0..a776480 100644 (file)
@@ -1,7 +1,20 @@
+/*
+ * This file is part of libFirm.
+ * Copyright (C) 2012 University of Karlsruhe.
+ */
+
+/**
+ * @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;
 };
 
@@ -32,18 +44,20 @@ struct _pqueue_t {
  * 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;
                }
 
@@ -61,8 +75,9 @@ static void pqueue_heapify(pqueue *q, int pos) {
 /**
  * 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];
@@ -73,60 +88,42 @@ static void pqueue_sift_up(pqueue *q, int pos) {
        }
 }
 
-/**
- * Creates a new priority queue.
- * @return A priority queue of initial length 0.
- */
-pqueue *new_pqueue() {
-       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));
+       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);
@@ -137,20 +134,12 @@ void *pqueue_get(pqueue *q) {
        }
 }
 
-/**
- * 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;
 }