Skip to content

Commit 1644524

Browse files
peffgitster
authored andcommitted
fetch-pack: avoid quadratic list insertion in mark_complete
We insert the commit pointed to by each ref one-by-one into the "complete" commit_list using insert_by_date. Because each insertion is O(n), we end up with O(n^2) behavior. This typically doesn't matter, because the number of refs is reasonably small. And even if there are a lot of refs, they often point to a smaller set of objects (in which case the optimization in commit ea5f220 keeps our "n" small). However, in pathological repositories (hundreds of thousands of refs, each pointing to a unique commit), this quadratic behavior can make a difference. Since we do not care about the list order until we have finished building it, we can simply keep it unsorted during the insertion phase, then sort it afterwards. On a repository like the one described above, this dropped the time to do a no-op fetch from 2.0s to 1.7s. On normal repositories, it probably does not matter at all, but it does not hurt to protect ourselves from pathological cases. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 534f0e0 commit 1644524

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

fetch-pack.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ static int mark_complete(const char *refname, const unsigned char *sha1, int fla
505505
struct commit *commit = (struct commit *)o;
506506
if (!(commit->object.flags & COMPLETE)) {
507507
commit->object.flags |= COMPLETE;
508-
commit_list_insert_by_date(commit, &complete);
508+
commit_list_insert(commit, &complete);
509509
}
510510
}
511511
return 0;
@@ -622,6 +622,7 @@ static int everything_local(struct fetch_pack_args *args,
622622
if (!args->depth) {
623623
for_each_ref(mark_complete, NULL);
624624
for_each_alternate_ref(mark_alternate_complete, NULL);
625+
commit_list_sort_by_date(&complete);
625626
if (cutoff)
626627
mark_recent_complete_commits(args, cutoff);
627628
}

0 commit comments

Comments
 (0)