mirror of
https://github.com/git/git.git
synced 2025-12-12 20:36:24 +01:00
prio-queue: add prio_queue_replace()
Add a function to replace the top element of the queue that basically does the same as prio_queue_get() followed by prio_queue_put(), but without the work by prio_queue_get() to rebalance the heap. It can be used to optimize loops that get one element and then immediately add another one. That's common e.g., with commit history traversal, where we get out a commit and then put in its parents. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
d6ec08788e
commit
3d5091d232
45
prio-queue.c
45
prio-queue.c
@@ -58,22 +58,10 @@ void prio_queue_put(struct prio_queue *queue, void *thing)
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
@@ -86,6 +74,23 @@ void *prio_queue_get(struct prio_queue *queue)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -97,3 +102,17 @@ void *prio_queue_peek(struct prio_queue *queue)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user