}
}
-void *prio_queue_get(struct prio_queue *queue)
+static void sift_down_root(struct prio_queue *queue)
{
- void *result;
size_t ix, child;
- if (!queue->nr)
- return NULL;
- if (!queue->compare)
- return queue->array[--queue->nr].data; /* LIFO */
-
- result = queue->array[0].data;
- 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 */
swap(queue, child, ix);
}
+}
+
+void *prio_queue_get(struct prio_queue *queue)
+{
+ void *result;
+
+ if (!queue->nr)
+ return NULL;
+ if (!queue->compare)
+ return queue->array[--queue->nr].data; /* LIFO */
+
+ result = queue->array[0].data;
+ if (!--queue->nr)
+ return result;
+
+ queue->array[0] = queue->array[queue->nr];
+ sift_down_root(queue);
return result;
}
return queue->array[queue->nr - 1].data;
return queue->array[0].data;
}
+
+void prio_queue_replace(struct prio_queue *queue, void *thing)
+{
+ if (!queue->nr) {
+ prio_queue_put(queue, thing);
+ } else if (!queue->compare) {
+ queue->array[queue->nr - 1].ctr = queue->insertion_ctr++;
+ queue->array[queue->nr - 1].data = thing;
+ } else {
+ queue->array[0].ctr = queue->insertion_ctr++;
+ queue->array[0].data = thing;
+ sift_down_root(queue);
+ }
+}
*/
void *prio_queue_peek(struct prio_queue *);
+/*
+ * Replace the "thing" that compares the smallest with a new "thing",
+ * like prio_queue_get()+prio_queue_put() would do, but in a more
+ * efficient way. Does the same as prio_queue_put() if the queue is
+ * empty.
+ */
+void prio_queue_replace(struct prio_queue *queue, void *thing);
+
void clear_prio_queue(struct prio_queue *);
/* Reverse the LIFO elements */
#define STACK -3
#define GET -4
#define REVERSE -5
+#define REPLACE -6
static int show(int *v)
{
case REVERSE:
prio_queue_reverse(&pq);
break;
+ case REPLACE:
+ peek = prio_queue_peek(&pq);
+ cl_assert(i + 1 < input_size);
+ cl_assert(input[i + 1] >= 0);
+ cl_assert(j < result_size);
+ cl_assert_equal_i(result[j], show(peek));
+ j++;
+ prio_queue_replace(&pq, &input[++i]);
+ break;
default:
prio_queue_put(&pq, &input[i]);
break;
((int []){ 1, 2, MISSING, 1, 2, MISSING }));
}
+void test_prio_queue__replace(void)
+{
+ TEST_INPUT(((int []){ REPLACE, 6, 2, 4, REPLACE, 5, 7, GET,
+ REPLACE, 1, DUMP }),
+ ((int []){ MISSING, 2, 4, 5, 1, 6, 7 }));
+}
+
void test_prio_queue__stack(void)
{
TEST_INPUT(((int []){ STACK, 8, 1, 5, 4, 6, 2, 3, DUMP }),
TEST_INPUT(((int []){ STACK, 1, 2, 3, 4, 5, 6, REVERSE, DUMP }),
((int []){ 1, 2, 3, 4, 5, 6 }));
}
+
+void test_prio_queue__replace_stack(void)
+{
+ TEST_INPUT(((int []){ STACK, 8, 1, 5, REPLACE, 4, 6, 2, 3, DUMP }),
+ ((int []){ 5, 3, 2, 6, 4, 1, 8 }));
+}