2023-02-24 08:09:24 +08:00
|
|
|
#include "git-compat-util.h"
|
|
|
|
#include "alloc.h"
|
2013-06-07 10:13:50 +08:00
|
|
|
#include "prio-queue.h"
|
|
|
|
|
prio-queue: factor out compare and swap operations
When manipulating the priority queue's heap, we frequently
have to compare and swap heap entries. As we are storing
only void pointers right now, this is quite easy to do
inline in a few lines. However, when we start using a more
complicated heap entry in a future patch, that will get
longer. Factoring out these operations lets us make future
changes in one place. It also makes the code a little
shorter and more readable.
Note that we actually accept indices into the queue array
instead of pointers. This is slightly less flexible than
passing pointers-to-pointers (we could not swap items from
unrelated arrays, but we would not want to), but will make
further refactoring simpler (and lets us avoid repeating
"queue->array" at each callsite, which led to some long
lines).
And finally, note that we are cleaning up an accidental use
of a "struct commit" pointer to hold a temporary entry
during swap. Even though we currently only use this code for
commits, it is supposed to be type-agnostic. In practice
this didn't matter anyway because we never dereferenced the
commit pointer (and on most systems, the pointer values
themselves are interchangeable between types).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-14 13:42:50 +08:00
|
|
|
static inline int compare(struct prio_queue *queue, int i, int j)
|
|
|
|
{
|
2014-07-14 13:51:59 +08:00
|
|
|
int cmp = queue->compare(queue->array[i].data, queue->array[j].data,
|
prio-queue: factor out compare and swap operations
When manipulating the priority queue's heap, we frequently
have to compare and swap heap entries. As we are storing
only void pointers right now, this is quite easy to do
inline in a few lines. However, when we start using a more
complicated heap entry in a future patch, that will get
longer. Factoring out these operations lets us make future
changes in one place. It also makes the code a little
shorter and more readable.
Note that we actually accept indices into the queue array
instead of pointers. This is slightly less flexible than
passing pointers-to-pointers (we could not swap items from
unrelated arrays, but we would not want to), but will make
further refactoring simpler (and lets us avoid repeating
"queue->array" at each callsite, which led to some long
lines).
And finally, note that we are cleaning up an accidental use
of a "struct commit" pointer to hold a temporary entry
during swap. Even though we currently only use this code for
commits, it is supposed to be type-agnostic. In practice
this didn't matter anyway because we never dereferenced the
commit pointer (and on most systems, the pointer values
themselves are interchangeable between types).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-14 13:42:50 +08:00
|
|
|
queue->cb_data);
|
2014-07-14 13:51:59 +08:00
|
|
|
if (!cmp)
|
|
|
|
cmp = queue->array[i].ctr - queue->array[j].ctr;
|
prio-queue: factor out compare and swap operations
When manipulating the priority queue's heap, we frequently
have to compare and swap heap entries. As we are storing
only void pointers right now, this is quite easy to do
inline in a few lines. However, when we start using a more
complicated heap entry in a future patch, that will get
longer. Factoring out these operations lets us make future
changes in one place. It also makes the code a little
shorter and more readable.
Note that we actually accept indices into the queue array
instead of pointers. This is slightly less flexible than
passing pointers-to-pointers (we could not swap items from
unrelated arrays, but we would not want to), but will make
further refactoring simpler (and lets us avoid repeating
"queue->array" at each callsite, which led to some long
lines).
And finally, note that we are cleaning up an accidental use
of a "struct commit" pointer to hold a temporary entry
during swap. Even though we currently only use this code for
commits, it is supposed to be type-agnostic. In practice
this didn't matter anyway because we never dereferenced the
commit pointer (and on most systems, the pointer values
themselves are interchangeable between types).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-14 13:42:50 +08:00
|
|
|
return cmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void swap(struct prio_queue *queue, int i, int j)
|
|
|
|
{
|
2017-01-29 05:40:58 +08:00
|
|
|
SWAP(queue->array[i], queue->array[j]);
|
prio-queue: factor out compare and swap operations
When manipulating the priority queue's heap, we frequently
have to compare and swap heap entries. As we are storing
only void pointers right now, this is quite easy to do
inline in a few lines. However, when we start using a more
complicated heap entry in a future patch, that will get
longer. Factoring out these operations lets us make future
changes in one place. It also makes the code a little
shorter and more readable.
Note that we actually accept indices into the queue array
instead of pointers. This is slightly less flexible than
passing pointers-to-pointers (we could not swap items from
unrelated arrays, but we would not want to), but will make
further refactoring simpler (and lets us avoid repeating
"queue->array" at each callsite, which led to some long
lines).
And finally, note that we are cleaning up an accidental use
of a "struct commit" pointer to hold a temporary entry
during swap. Even though we currently only use this code for
commits, it is supposed to be type-agnostic. In practice
this didn't matter anyway because we never dereferenced the
commit pointer (and on most systems, the pointer values
themselves are interchangeable between types).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-14 13:42:50 +08:00
|
|
|
}
|
|
|
|
|
2013-06-07 12:58:12 +08:00
|
|
|
void prio_queue_reverse(struct prio_queue *queue)
|
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
|
2022-05-03 00:50:37 +08:00
|
|
|
if (queue->compare)
|
2018-05-02 17:38:39 +08:00
|
|
|
BUG("prio_queue_reverse() on non-LIFO queue");
|
2017-04-24 19:49:20 +08:00
|
|
|
for (i = 0; i < (j = (queue->nr - 1) - i); i++)
|
prio-queue: factor out compare and swap operations
When manipulating the priority queue's heap, we frequently
have to compare and swap heap entries. As we are storing
only void pointers right now, this is quite easy to do
inline in a few lines. However, when we start using a more
complicated heap entry in a future patch, that will get
longer. Factoring out these operations lets us make future
changes in one place. It also makes the code a little
shorter and more readable.
Note that we actually accept indices into the queue array
instead of pointers. This is slightly less flexible than
passing pointers-to-pointers (we could not swap items from
unrelated arrays, but we would not want to), but will make
further refactoring simpler (and lets us avoid repeating
"queue->array" at each callsite, which led to some long
lines).
And finally, note that we are cleaning up an accidental use
of a "struct commit" pointer to hold a temporary entry
during swap. Even though we currently only use this code for
commits, it is supposed to be type-agnostic. In practice
this didn't matter anyway because we never dereferenced the
commit pointer (and on most systems, the pointer values
themselves are interchangeable between types).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-14 13:42:50 +08:00
|
|
|
swap(queue, i, j);
|
2013-06-07 12:58:12 +08:00
|
|
|
}
|
|
|
|
|
2013-06-07 10:13:50 +08:00
|
|
|
void clear_prio_queue(struct prio_queue *queue)
|
|
|
|
{
|
2017-06-16 07:15:49 +08:00
|
|
|
FREE_AND_NULL(queue->array);
|
2013-06-07 10:13:50 +08:00
|
|
|
queue->nr = 0;
|
|
|
|
queue->alloc = 0;
|
2014-07-14 13:51:59 +08:00
|
|
|
queue->insertion_ctr = 0;
|
2013-06-07 10:13:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void prio_queue_put(struct prio_queue *queue, void *thing)
|
|
|
|
{
|
|
|
|
int ix, parent;
|
|
|
|
|
|
|
|
/* Append at the end */
|
|
|
|
ALLOC_GROW(queue->array, queue->nr + 1, queue->alloc);
|
2014-07-14 13:51:59 +08:00
|
|
|
queue->array[queue->nr].ctr = queue->insertion_ctr++;
|
|
|
|
queue->array[queue->nr].data = thing;
|
|
|
|
queue->nr++;
|
prio-queue: factor out compare and swap operations
When manipulating the priority queue's heap, we frequently
have to compare and swap heap entries. As we are storing
only void pointers right now, this is quite easy to do
inline in a few lines. However, when we start using a more
complicated heap entry in a future patch, that will get
longer. Factoring out these operations lets us make future
changes in one place. It also makes the code a little
shorter and more readable.
Note that we actually accept indices into the queue array
instead of pointers. This is slightly less flexible than
passing pointers-to-pointers (we could not swap items from
unrelated arrays, but we would not want to), but will make
further refactoring simpler (and lets us avoid repeating
"queue->array" at each callsite, which led to some long
lines).
And finally, note that we are cleaning up an accidental use
of a "struct commit" pointer to hold a temporary entry
during swap. Even though we currently only use this code for
commits, it is supposed to be type-agnostic. In practice
this didn't matter anyway because we never dereferenced the
commit pointer (and on most systems, the pointer values
themselves are interchangeable between types).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-14 13:42:50 +08:00
|
|
|
if (!queue->compare)
|
2013-06-07 10:13:50 +08:00
|
|
|
return; /* LIFO */
|
|
|
|
|
|
|
|
/* Bubble up the new one */
|
|
|
|
for (ix = queue->nr - 1; ix; ix = parent) {
|
|
|
|
parent = (ix - 1) / 2;
|
prio-queue: factor out compare and swap operations
When manipulating the priority queue's heap, we frequently
have to compare and swap heap entries. As we are storing
only void pointers right now, this is quite easy to do
inline in a few lines. However, when we start using a more
complicated heap entry in a future patch, that will get
longer. Factoring out these operations lets us make future
changes in one place. It also makes the code a little
shorter and more readable.
Note that we actually accept indices into the queue array
instead of pointers. This is slightly less flexible than
passing pointers-to-pointers (we could not swap items from
unrelated arrays, but we would not want to), but will make
further refactoring simpler (and lets us avoid repeating
"queue->array" at each callsite, which led to some long
lines).
And finally, note that we are cleaning up an accidental use
of a "struct commit" pointer to hold a temporary entry
during swap. Even though we currently only use this code for
commits, it is supposed to be type-agnostic. In practice
this didn't matter anyway because we never dereferenced the
commit pointer (and on most systems, the pointer values
themselves are interchangeable between types).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-14 13:42:50 +08:00
|
|
|
if (compare(queue, parent, ix) <= 0)
|
2013-06-07 10:13:50 +08:00
|
|
|
break;
|
|
|
|
|
prio-queue: factor out compare and swap operations
When manipulating the priority queue's heap, we frequently
have to compare and swap heap entries. As we are storing
only void pointers right now, this is quite easy to do
inline in a few lines. However, when we start using a more
complicated heap entry in a future patch, that will get
longer. Factoring out these operations lets us make future
changes in one place. It also makes the code a little
shorter and more readable.
Note that we actually accept indices into the queue array
instead of pointers. This is slightly less flexible than
passing pointers-to-pointers (we could not swap items from
unrelated arrays, but we would not want to), but will make
further refactoring simpler (and lets us avoid repeating
"queue->array" at each callsite, which led to some long
lines).
And finally, note that we are cleaning up an accidental use
of a "struct commit" pointer to hold a temporary entry
during swap. Even though we currently only use this code for
commits, it is supposed to be type-agnostic. In practice
this didn't matter anyway because we never dereferenced the
commit pointer (and on most systems, the pointer values
themselves are interchangeable between types).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-14 13:42:50 +08:00
|
|
|
swap(queue, parent, ix);
|
2013-06-07 10:13:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void *prio_queue_get(struct prio_queue *queue)
|
|
|
|
{
|
prio-queue: factor out compare and swap operations
When manipulating the priority queue's heap, we frequently
have to compare and swap heap entries. As we are storing
only void pointers right now, this is quite easy to do
inline in a few lines. However, when we start using a more
complicated heap entry in a future patch, that will get
longer. Factoring out these operations lets us make future
changes in one place. It also makes the code a little
shorter and more readable.
Note that we actually accept indices into the queue array
instead of pointers. This is slightly less flexible than
passing pointers-to-pointers (we could not swap items from
unrelated arrays, but we would not want to), but will make
further refactoring simpler (and lets us avoid repeating
"queue->array" at each callsite, which led to some long
lines).
And finally, note that we are cleaning up an accidental use
of a "struct commit" pointer to hold a temporary entry
during swap. Even though we currently only use this code for
commits, it is supposed to be type-agnostic. In practice
this didn't matter anyway because we never dereferenced the
commit pointer (and on most systems, the pointer values
themselves are interchangeable between types).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-14 13:42:50 +08:00
|
|
|
void *result;
|
2013-06-07 10:13:50 +08:00
|
|
|
int ix, child;
|
|
|
|
|
|
|
|
if (!queue->nr)
|
|
|
|
return NULL;
|
prio-queue: factor out compare and swap operations
When manipulating the priority queue's heap, we frequently
have to compare and swap heap entries. As we are storing
only void pointers right now, this is quite easy to do
inline in a few lines. However, when we start using a more
complicated heap entry in a future patch, that will get
longer. Factoring out these operations lets us make future
changes in one place. It also makes the code a little
shorter and more readable.
Note that we actually accept indices into the queue array
instead of pointers. This is slightly less flexible than
passing pointers-to-pointers (we could not swap items from
unrelated arrays, but we would not want to), but will make
further refactoring simpler (and lets us avoid repeating
"queue->array" at each callsite, which led to some long
lines).
And finally, note that we are cleaning up an accidental use
of a "struct commit" pointer to hold a temporary entry
during swap. Even though we currently only use this code for
commits, it is supposed to be type-agnostic. In practice
this didn't matter anyway because we never dereferenced the
commit pointer (and on most systems, the pointer values
themselves are interchangeable between types).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-14 13:42:50 +08:00
|
|
|
if (!queue->compare)
|
2014-07-14 13:51:59 +08:00
|
|
|
return queue->array[--queue->nr].data; /* LIFO */
|
2013-06-07 10:13:50 +08:00
|
|
|
|
2014-07-14 13:51:59 +08:00
|
|
|
result = queue->array[0].data;
|
2013-06-07 10:13:50 +08:00
|
|
|
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 */
|
prio-queue: factor out compare and swap operations
When manipulating the priority queue's heap, we frequently
have to compare and swap heap entries. As we are storing
only void pointers right now, this is quite easy to do
inline in a few lines. However, when we start using a more
complicated heap entry in a future patch, that will get
longer. Factoring out these operations lets us make future
changes in one place. It also makes the code a little
shorter and more readable.
Note that we actually accept indices into the queue array
instead of pointers. This is slightly less flexible than
passing pointers-to-pointers (we could not swap items from
unrelated arrays, but we would not want to), but will make
further refactoring simpler (and lets us avoid repeating
"queue->array" at each callsite, which led to some long
lines).
And finally, note that we are cleaning up an accidental use
of a "struct commit" pointer to hold a temporary entry
during swap. Even though we currently only use this code for
commits, it is supposed to be type-agnostic. In practice
this didn't matter anyway because we never dereferenced the
commit pointer (and on most systems, the pointer values
themselves are interchangeable between types).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-14 13:42:50 +08:00
|
|
|
if (child + 1 < queue->nr &&
|
|
|
|
compare(queue, child, child + 1) >= 0)
|
2013-06-07 10:13:50 +08:00
|
|
|
child++; /* use right child */
|
|
|
|
|
prio-queue: factor out compare and swap operations
When manipulating the priority queue's heap, we frequently
have to compare and swap heap entries. As we are storing
only void pointers right now, this is quite easy to do
inline in a few lines. However, when we start using a more
complicated heap entry in a future patch, that will get
longer. Factoring out these operations lets us make future
changes in one place. It also makes the code a little
shorter and more readable.
Note that we actually accept indices into the queue array
instead of pointers. This is slightly less flexible than
passing pointers-to-pointers (we could not swap items from
unrelated arrays, but we would not want to), but will make
further refactoring simpler (and lets us avoid repeating
"queue->array" at each callsite, which led to some long
lines).
And finally, note that we are cleaning up an accidental use
of a "struct commit" pointer to hold a temporary entry
during swap. Even though we currently only use this code for
commits, it is supposed to be type-agnostic. In practice
this didn't matter anyway because we never dereferenced the
commit pointer (and on most systems, the pointer values
themselves are interchangeable between types).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-14 13:42:50 +08:00
|
|
|
if (compare(queue, ix, child) <= 0)
|
2013-06-07 10:13:50 +08:00
|
|
|
break;
|
|
|
|
|
prio-queue: factor out compare and swap operations
When manipulating the priority queue's heap, we frequently
have to compare and swap heap entries. As we are storing
only void pointers right now, this is quite easy to do
inline in a few lines. However, when we start using a more
complicated heap entry in a future patch, that will get
longer. Factoring out these operations lets us make future
changes in one place. It also makes the code a little
shorter and more readable.
Note that we actually accept indices into the queue array
instead of pointers. This is slightly less flexible than
passing pointers-to-pointers (we could not swap items from
unrelated arrays, but we would not want to), but will make
further refactoring simpler (and lets us avoid repeating
"queue->array" at each callsite, which led to some long
lines).
And finally, note that we are cleaning up an accidental use
of a "struct commit" pointer to hold a temporary entry
during swap. Even though we currently only use this code for
commits, it is supposed to be type-agnostic. In practice
this didn't matter anyway because we never dereferenced the
commit pointer (and on most systems, the pointer values
themselves are interchangeable between types).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-14 13:42:50 +08:00
|
|
|
swap(queue, child, ix);
|
2013-06-07 10:13:50 +08:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
2018-11-01 21:46:17 +08:00
|
|
|
|
|
|
|
void *prio_queue_peek(struct prio_queue *queue)
|
|
|
|
{
|
|
|
|
if (!queue->nr)
|
|
|
|
return NULL;
|
|
|
|
if (!queue->compare)
|
|
|
|
return queue->array[queue->nr - 1].data;
|
|
|
|
return queue->array[0].data;
|
|
|
|
}
|