prio-queue: add 'peek' operation
When consuming a priority queue, it can be convenient to inspect the next object that will be dequeued without actually dequeueing it. Our existing library did not have such a 'peek' operation, so add it as prio_queue_peek(). Add a reference-level comparison in t/helper/test-prio-queue.c so this method is exercised by t0009-prio-queue.sh. Further, add a test that checks the behavior when the compare function is NULL (i.e. the queue becomes a stack). Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Derrick Stolee committed
Nov 1, 2018 at 13:46 UTC
aca4240f6a32423df5f95de6a9354b524fe57ec5
4 files changed
+47
-8
prio-queue.c
+9
@@ -85,3 +85,12 @@ void *prio_queue_get(struct prio_queue *queue)
85
}
86
return result;
87
}
88
+
89
+void *prio_queue_peek(struct prio_queue *queue)
90
+{
91
+ if (!queue->nr)
92
+ return NULL;
93
+ if (!queue->compare)
94
+ return queue->array[queue->nr - 1].data;
95
+ return queue->array[0].data;
96
+}
prio-queue.h
+6
@@ -46,6 +46,12 @@ extern void prio_queue_put(struct prio_queue *, void *thing);
46
*/
47
extern void *prio_queue_get(struct prio_queue *);
48
49
+/*
50
+ * Gain access to the "thing" that would be returned by
51
+ * prio_queue_get, but do not remove it from the queue.
52
+ */
53
+extern void *prio_queue_peek(struct prio_queue *);
54
+
55
extern void clear_prio_queue(struct prio_queue *);
56
57
/* Reverse the LIFO elements */
t/helper/test-prio-queue.c
+18
-8
@@ -22,14 +22,24 @@ int cmd__prio_queue(int argc, const char **argv)
22
struct prio_queue pq = { intcmp };
23
24
while (*++argv) {
25
- if (!strcmp(*argv, "get"))
26
- show(prio_queue_get(&pq));
27
- else if (!strcmp(*argv, "dump")) {
28
- int *v;
29
- while ((v = prio_queue_get(&pq)))
30
- show(v);
31
- }
32
- else {
25
+ if (!strcmp(*argv, "get")) {
26
+ void *peek = prio_queue_peek(&pq);
27
+ void *get = prio_queue_get(&pq);
28
+ if (peek != get)
29
+ BUG("peek and get results do not match");
30
+ show(get);
31
+ } else if (!strcmp(*argv, "dump")) {
32
+ void *peek;
33
+ void *get;
34
+ while ((peek = prio_queue_peek(&pq))) {
35
+ get = prio_queue_get(&pq);
36
+ if (peek != get)
37
+ BUG("peek and get results do not match");
38
+ show(get);
39
+ }
40
+ } else if (!strcmp(*argv, "stack")) {
41
+ pq.compare = NULL;
42
+ } else {
43
int *v = malloc(sizeof(*v));
44
*v = atoi(*argv);
45
prio_queue_put(&pq, v);
t/t0009-prio-queue.sh
+14
@@ -47,4 +47,18 @@ test_expect_success 'notice empty queue' '
47
test_cmp expect actual
48
'
49
50
+cat >expect <<'EOF'
51
+3
52
+2
53
+6
54
+4
55
+5
56
+1
57
+8
58
+EOF
59
+test_expect_success 'stack order' '
60
+ test-tool prio-queue stack 8 1 5 4 6 2 3 dump >actual &&
61
+ test_cmp expect actual
62
+'
63
+
64
test_done