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>
Jeff King committed
Oct 11, 2016 at 17:20 UTC
5411b10cef90377afc584fc2562f26ac051fc357
1 file changed
+7
-6
upload-pack.c
+7
-6
@@ -16,6 +16,7 @@
16
#include "string-list.h"
17
#include "parse-options.h"
18
#include "argv-array.h"
19
+#include "prio-queue.h"
20
21
static const char * const upload_pack_usage[] = {
22
N_("git upload-pack [<options>] <dir>"),
@@ -319,12 +320,12 @@ static int got_sha1(const char *hex, unsigned char *sha1)
320
321
static int reachable(struct commit *want)
322
{
322
- struct commit_list *work = NULL;
323
+ struct prio_queue work = { compare_commits_by_commit_date };
324
324
- commit_list_insert_by_date(want, &work);
325
- while (work) {
325
+ prio_queue_put(&work, want);
326
+ while (work.nr) {
327
struct commit_list *list;
327
- struct commit *commit = pop_commit(&work);
328
+ struct commit *commit = prio_queue_get(&work);
329
330
if (commit->object.flags & THEY_HAVE) {
331
want->object.flags |= COMMON_KNOWN;
@@ -340,12 +341,12 @@ static int reachable(struct commit *want)
341
for (list = commit->parents; list; list = list->next) {
342
struct commit *parent = list->item;
343
if (!(parent->object.flags & REACHABLE))
343
- commit_list_insert_by_date(parent, &work);
344
+ prio_queue_put(&work, parent);
345
}
346
}
347
want->object.flags |= REACHABLE;
348
clear_commit_marks(want, REACHABLE);
348
- free_commit_list(work);
349
+ clear_prio_queue(&work);
350
return (want->object.flags & COMMON_KNOWN);
351
}
352