use commit_stack instead of prio_queue in LIFO mode

A prio_queue with a NULL compare function acts as a stack -- the last
element in is the first one out (LIFO).  Use an actual commit_stack
instead where possible, as it documents the behavior better, provides
type safety and saves some memory because prio_queue stores an
additional tie-breaking counter per element.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
René Scharfe 2026-03-17 22:40:07 +01:00 committed by Junio C Hamano
parent ca1db8a0f7
commit 1ae7a359ae
3 changed files with 17 additions and 19 deletions

View File

@ -12,7 +12,6 @@
#include "object-name.h" #include "object-name.h"
#include "pager.h" #include "pager.h"
#include "parse-options.h" #include "parse-options.h"
#include "prio-queue.h"
#include "hash-lookup.h" #include "hash-lookup.h"
#include "commit-slab.h" #include "commit-slab.h"
#include "commit-graph.h" #include "commit-graph.h"
@ -178,7 +177,7 @@ static void name_rev(struct commit *start_commit,
const char *tip_name, timestamp_t taggerdate, const char *tip_name, timestamp_t taggerdate,
int from_tag, int deref, struct mem_pool *string_pool) int from_tag, int deref, struct mem_pool *string_pool)
{ {
struct prio_queue queue; struct commit_stack stack = COMMIT_STACK_INIT;
struct commit *commit; struct commit *commit;
struct commit_stack parents_to_queue = COMMIT_STACK_INIT; struct commit_stack parents_to_queue = COMMIT_STACK_INIT;
struct rev_name *start_name; struct rev_name *start_name;
@ -197,10 +196,9 @@ static void name_rev(struct commit *start_commit,
else else
start_name->tip_name = mem_pool_strdup(string_pool, tip_name); start_name->tip_name = mem_pool_strdup(string_pool, tip_name);


memset(&queue, 0, sizeof(queue)); /* Use the prio_queue as LIFO */ commit_stack_push(&stack, start_commit);
prio_queue_put(&queue, start_commit);


while ((commit = prio_queue_get(&queue))) { while ((commit = commit_stack_pop(&stack))) {
struct rev_name *name = get_commit_rev_name(commit); struct rev_name *name = get_commit_rev_name(commit);
struct commit_list *parents; struct commit_list *parents;
int parent_number = 1; int parent_number = 1;
@ -241,13 +239,13 @@ static void name_rev(struct commit *start_commit,
} }
} }


/* The first parent must come out first from the prio_queue */ /* The first parent must come out first from the stack */
while (parents_to_queue.nr) while (parents_to_queue.nr)
prio_queue_put(&queue, commit_stack_push(&stack,
commit_stack_pop(&parents_to_queue)); commit_stack_pop(&parents_to_queue));
} }


clear_prio_queue(&queue); commit_stack_clear(&stack);
commit_stack_clear(&parents_to_queue); commit_stack_clear(&parents_to_queue);
} }



View File

@ -57,19 +57,19 @@ static int clear_marks(const struct reference *ref, void *cb_data UNUSED)
static void mark_common(struct negotiation_state *ns, struct commit *commit, static void mark_common(struct negotiation_state *ns, struct commit *commit,
int ancestors_only, int dont_parse) int ancestors_only, int dont_parse)
{ {
struct prio_queue queue = { NULL }; struct commit_stack stack = COMMIT_STACK_INIT;


if (!commit || (commit->object.flags & COMMON)) if (!commit || (commit->object.flags & COMMON))
return; return;


prio_queue_put(&queue, commit); commit_stack_push(&stack, commit);
if (!ancestors_only) { if (!ancestors_only) {
commit->object.flags |= COMMON; commit->object.flags |= COMMON;


if ((commit->object.flags & SEEN) && !(commit->object.flags & POPPED)) if ((commit->object.flags & SEEN) && !(commit->object.flags & POPPED))
ns->non_common_revs--; ns->non_common_revs--;
} }
while ((commit = prio_queue_get(&queue))) { while ((commit = commit_stack_pop(&stack))) {
struct object *o = (struct object *)commit; struct object *o = (struct object *)commit;


if (!(o->flags & SEEN)) if (!(o->flags & SEEN))
@ -94,12 +94,12 @@ static void mark_common(struct negotiation_state *ns, struct commit *commit,
if ((p->object.flags & SEEN) && !(p->object.flags & POPPED)) if ((p->object.flags & SEEN) && !(p->object.flags & POPPED))
ns->non_common_revs--; ns->non_common_revs--;


prio_queue_put(&queue, parents->item); commit_stack_push(&stack, parents->item);
} }
} }
} }


clear_prio_queue(&queue); commit_stack_clear(&stack);
} }


/* /*

View File

@ -91,15 +91,15 @@ static int clear_marks(const struct reference *ref, void *cb_data UNUSED)
*/ */
static void mark_common(struct data *data, struct commit *seen_commit) static void mark_common(struct data *data, struct commit *seen_commit)
{ {
struct prio_queue queue = { NULL }; struct commit_stack stack = COMMIT_STACK_INIT;
struct commit *c; struct commit *c;


if (seen_commit->object.flags & COMMON) if (seen_commit->object.flags & COMMON)
return; return;


prio_queue_put(&queue, seen_commit); commit_stack_push(&stack, seen_commit);
seen_commit->object.flags |= COMMON; seen_commit->object.flags |= COMMON;
while ((c = prio_queue_get(&queue))) { while ((c = commit_stack_pop(&stack))) {
struct commit_list *p; struct commit_list *p;


if (!(c->object.flags & POPPED)) if (!(c->object.flags & POPPED))
@ -113,11 +113,11 @@ static void mark_common(struct data *data, struct commit *seen_commit)
continue; continue;


p->item->object.flags |= COMMON; p->item->object.flags |= COMMON;
prio_queue_put(&queue, p->item); commit_stack_push(&stack, p->item);
} }
} }


clear_prio_queue(&queue); commit_stack_clear(&stack);
} }


/* /*