#include "cache.h" #include "commit.h" #include "prio-queue.h" void prio_queue_reverse(struct prio_queue *queue) { int i, j; if (queue->compare != NULL) die("BUG: prio_queue_reverse() on non-LIFO queue"); for (i = 0; i <= (j = (queue->nr - 1) - i); i++) { struct commit *swap = queue->array[i]; queue->array[i] = queue->array[j]; queue->array[j] = swap; } } void clear_prio_queue(struct prio_queue *queue) { free(queue->array); queue->nr = 0; queue->alloc = 0; queue->array = NULL; } void prio_queue_put(struct prio_queue *queue, void *thing) { prio_queue_compare_fn compare = queue->compare; int ix, parent; /* Append at the end */ ALLOC_GROW(queue->array, queue->nr + 1, queue->alloc); queue->array[queue->nr++] = thing; if (!compare) return; /* LIFO */ /* Bubble up the new one */ for (ix = queue->nr - 1; ix; ix = parent) { parent = (ix - 1) / 2; if (compare(queue->array[parent], queue->array[ix], queue->cb_data) <= 0) break; thing = queue->array[parent]; queue->array[parent] = queue->array[ix]; queue->array[ix] = thing; } } void *prio_queue_get(struct prio_queue *queue) { void *result, *swap; int ix, child; prio_queue_compare_fn compare = queue->compare; if (!queue->nr) return NULL; if (!compare) return queue->array[--queue->nr]; /* LIFO */ result = queue->array[0]; if (!--queue->nr) return result; queue->array[0] = queue->array[queue->nr]; /* Push down the one at the root */ for (ix = 0; ix * 2 + 1 < queue->nr; ix = child) { child = ix * 2 + 1; /* left */ if ((child + 1 < queue->nr) && (compare(queue->array[child], queue->array[child + 1], queue->cb_data) >= 0)) child++; /* use right child */ if (compare(queue->array[ix], queue->array[child], queue->cb_data) <= 0) break; swap = queue->array[child]; queue->array[child] = queue->array[ix]; queue->array[ix] = swap; } return result; }