Merge branch 'rs/pop-recent-commit-with-prio-queue'

The pop_most_recent_commit() function can have quite expensive
worst case performance characteristics, which has been optimized by
using prio-queue data structure.

* rs/pop-recent-commit-with-prio-queue:
  commit: use prio_queue_replace() in pop_most_recent_commit()
  prio-queue: add prio_queue_replace()
  commit: convert pop_most_recent_commit() to prio_queue
This commit is contained in:
Junio C Hamano
2025-07-28 12:02:34 -07:00
10 changed files with 170 additions and 34 deletions

View File

@@ -34,6 +34,7 @@
#include "commit-graph.h"
#include "sigchain.h"
#include "mergesort.h"
#include "prio-queue.h"
static int transfer_unpack_limit = -1;
static int fetch_unpack_limit = -1;
@@ -601,7 +602,7 @@ done:
return count ? retval : 0;
}
static struct commit_list *complete;
static struct prio_queue complete = { compare_commits_by_commit_date };
static int mark_complete(const struct object_id *oid)
{
@@ -609,7 +610,7 @@ static int mark_complete(const struct object_id *oid)
if (commit && !(commit->object.flags & COMPLETE)) {
commit->object.flags |= COMPLETE;
commit_list_insert(commit, &complete);
prio_queue_put(&complete, commit);
}
return 0;
}
@@ -626,9 +627,12 @@ static int mark_complete_oid(const char *refname UNUSED,
static void mark_recent_complete_commits(struct fetch_pack_args *args,
timestamp_t cutoff)
{
while (complete && cutoff <= complete->item->date) {
while (complete.nr) {
struct commit *item = prio_queue_peek(&complete);
if (item->date < cutoff)
break;
print_verbose(args, _("Marking %s as complete"),
oid_to_hex(&complete->item->object.oid));
oid_to_hex(&item->object.oid));
pop_most_recent_commit(&complete, COMPLETE);
}
}
@@ -798,7 +802,6 @@ static void mark_complete_and_common_ref(struct fetch_negotiator *negotiator,
refs_for_each_rawref(get_main_ref_store(the_repository),
mark_complete_oid, NULL);
for_each_cached_alternate(NULL, mark_alternate_complete);
commit_list_sort_by_date(&complete);
if (cutoff)
mark_recent_complete_commits(args, cutoff);
}