Skip to content

Commit d8ee62b

Browse files
committed
Merge branch 'kk/prio-queue-cascade-sift' into seen
prio_queue_get() has been optimized by using a cascade-down approach (promoting the smaller child at each level and sifting up the last element from the leaf vacancy), which halves the number of comparisons per extract-min operation in the common case. * kk/prio-queue-cascade-sift: prio-queue: use cascade-down for faster extract-min
2 parents 25f57a6 + 413d517 commit d8ee62b

1 file changed

Lines changed: 24 additions & 2 deletions

File tree

prio-queue.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,29 @@ static void sift_down_root(struct prio_queue *queue)
7676
}
7777
}
7878

79+
static void sift_up_rebalance(struct prio_queue *queue)
80+
{
81+
size_t ix, child;
82+
83+
/* Cascade: promote smaller child at each level. */
84+
for (ix = 0; (child = ix * 2 + 1) < queue->nr; ix = child) {
85+
if (child + 1 < queue->nr &&
86+
compare(queue, child, child + 1) >= 0)
87+
child++;
88+
queue->array[ix] = queue->array[child];
89+
}
90+
91+
/* Place the last element at the vacancy and sift up. */
92+
queue->array[ix] = queue->array[queue->nr];
93+
while (ix) {
94+
size_t parent = (ix - 1) / 2;
95+
if (compare(queue, parent, ix) <= 0)
96+
break;
97+
swap(queue, parent, ix);
98+
ix = parent;
99+
}
100+
}
101+
79102
void *prio_queue_get(struct prio_queue *queue)
80103
{
81104
void *result;
@@ -89,8 +112,7 @@ void *prio_queue_get(struct prio_queue *queue)
89112
if (!--queue->nr)
90113
return result;
91114

92-
queue->array[0] = queue->array[queue->nr];
93-
sift_down_root(queue);
115+
sift_up_rebalance(queue);
94116
return result;
95117
}
96118

0 commit comments

Comments
 (0)