1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-28 08:06:23 +02:00

upload-pack: use priority queue in reachable() check

Like a lot of old commit-traversal code, this keeps a
commit_list in commit-date order, and and inserts parents
into the list. This means each insertion is potentially
linear, and the whole thing is quadratic (though the exact
runtime depends on the relationship between the commit dates
and the parent topology).

These days we have a priority queue, which can do the same
thing with a much better worst-case time.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King 2016-10-11 17:20:16 -04:00 committed by Junio C Hamano
parent 8a36cd87b7
commit 5411b10cef

View File

@ -16,6 +16,7 @@
#include "string-list.h"
#include "parse-options.h"
#include "argv-array.h"
#include "prio-queue.h"
static const char * const upload_pack_usage[] = {
N_("git upload-pack [<options>] <dir>"),
@ -319,12 +320,12 @@ static int got_sha1(const char *hex, unsigned char *sha1)
static int reachable(struct commit *want)
{
struct commit_list *work = NULL;
struct prio_queue work = { compare_commits_by_commit_date };
commit_list_insert_by_date(want, &work);
while (work) {
prio_queue_put(&work, want);
while (work.nr) {
struct commit_list *list;
struct commit *commit = pop_commit(&work);
struct commit *commit = prio_queue_get(&work);
if (commit->object.flags & THEY_HAVE) {
want->object.flags |= COMMON_KNOWN;
@ -340,12 +341,12 @@ static int reachable(struct commit *want)
for (list = commit->parents; list; list = list->next) {
struct commit *parent = list->item;
if (!(parent->object.flags & REACHABLE))
commit_list_insert_by_date(parent, &work);
prio_queue_put(&work, parent);
}
}
want->object.flags |= REACHABLE;
clear_commit_marks(want, REACHABLE);
free_commit_list(work);
clear_prio_queue(&work);
return (want->object.flags & COMMON_KNOWN);
}