git
/
prio-queue.c
96 строк · 2.0 Кб
1#include "git-compat-util.h"2#include "prio-queue.h"3
4static inline int compare(struct prio_queue *queue, int i, int j)5{
6int cmp = queue->compare(queue->array[i].data, queue->array[j].data,7queue->cb_data);8if (!cmp)9cmp = queue->array[i].ctr - queue->array[j].ctr;10return cmp;11}
12
13static inline void swap(struct prio_queue *queue, int i, int j)14{
15SWAP(queue->array[i], queue->array[j]);16}
17
18void prio_queue_reverse(struct prio_queue *queue)19{
20int i, j;21
22if (queue->compare)23BUG("prio_queue_reverse() on non-LIFO queue");24for (i = 0; i < (j = (queue->nr - 1) - i); i++)25swap(queue, i, j);26}
27
28void clear_prio_queue(struct prio_queue *queue)29{
30FREE_AND_NULL(queue->array);31queue->nr = 0;32queue->alloc = 0;33queue->insertion_ctr = 0;34}
35
36void prio_queue_put(struct prio_queue *queue, void *thing)37{
38int ix, parent;39
40/* Append at the end */41ALLOC_GROW(queue->array, queue->nr + 1, queue->alloc);42queue->array[queue->nr].ctr = queue->insertion_ctr++;43queue->array[queue->nr].data = thing;44queue->nr++;45if (!queue->compare)46return; /* LIFO */47
48/* Bubble up the new one */49for (ix = queue->nr - 1; ix; ix = parent) {50parent = (ix - 1) / 2;51if (compare(queue, parent, ix) <= 0)52break;53
54swap(queue, parent, ix);55}56}
57
58void *prio_queue_get(struct prio_queue *queue)59{
60void *result;61int ix, child;62
63if (!queue->nr)64return NULL;65if (!queue->compare)66return queue->array[--queue->nr].data; /* LIFO */67
68result = queue->array[0].data;69if (!--queue->nr)70return result;71
72queue->array[0] = queue->array[queue->nr];73
74/* Push down the one at the root */75for (ix = 0; ix * 2 + 1 < queue->nr; ix = child) {76child = ix * 2 + 1; /* left */77if (child + 1 < queue->nr &&78compare(queue, child, child + 1) >= 0)79child++; /* use right child */80
81if (compare(queue, ix, child) <= 0)82break;83
84swap(queue, child, ix);85}86return result;87}
88
89void *prio_queue_peek(struct prio_queue *queue)90{
91if (!queue->nr)92return NULL;93if (!queue->compare)94return queue->array[queue->nr - 1].data;95return queue->array[0].data;96}
97