Commit 6f544140 by lhchavez

commit-graph: Introduce `git_commit_list_generation_cmp`

This change makes calculations of merge-bases a bit faster when there
are complex graphs and the commit times cause visiting nodes multiple
times. This is done by visiting the nodes in the graph in reverse
generation order when the generation number is available instead of
commit timestamp. If the generation number is missing in any pair of
commits, it can safely fall back to the old heuristic with no negative
side-effects.

Part of: #5757
parent 2370e491
......@@ -12,6 +12,24 @@
#include "odb.h"
#include "commit.h"
int git_commit_list_generation_cmp(const void *a, const void *b)
{
uint32_t generation_a = ((git_commit_list_node *) a)->generation;
uint32_t generation_b = ((git_commit_list_node *) b)->generation;
if (!generation_a || !generation_b) {
/* Fall back to comparing by timestamps if at least one commit lacks a generation. */
return git_commit_list_time_cmp(a, b);
}
if (generation_a < generation_b)
return 1;
if (generation_a > generation_b)
return -1;
return 0;
}
int git_commit_list_time_cmp(const void *a, const void *b)
{
int64_t time_a = ((git_commit_list_node *) a)->time;
......
......@@ -46,6 +46,7 @@ typedef struct git_commit_list {
} git_commit_list;
git_commit_list_node *git_commit_list_alloc_node(git_revwalk *walk);
int git_commit_list_generation_cmp(const void *a, const void *b);
int git_commit_list_time_cmp(const void *a, const void *b);
void git_commit_list_free(git_commit_list **list_p);
git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p);
......
......@@ -43,7 +43,7 @@ static int mark_parents(git_revwalk *walk, git_commit_list_node *one,
return 0;
}
if (git_pqueue_init(&list, 0, 2, git_commit_list_time_cmp) < 0)
if (git_pqueue_init(&list, 0, 2, git_commit_list_generation_cmp) < 0)
return -1;
if (git_commit_list_parse(walk, one) < 0)
......
......@@ -387,7 +387,7 @@ static int paint_down_to_common(
int error;
unsigned int i;
if (git_pqueue_init(&list, 0, twos->length * 2, git_commit_list_time_cmp) < 0)
if (git_pqueue_init(&list, 0, twos->length * 2, git_commit_list_generation_cmp) < 0)
return -1;
one->flags |= PARENT1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment