summaryrefslogtreecommitdiff
path: root/src/commit_list.c
diff options
context:
space:
mode:
authorlhchavez <lhchavez@lhchavez.com>2021-01-05 19:45:23 -0800
committerlhchavez <lhchavez@lhchavez.com>2021-07-26 18:46:17 -0700
commit6f544140a097002fe5f15e43a4d3215c944140b7 (patch)
tree223ae3e5cd541c58dcf8065914951604f5787804 /src/commit_list.c
parent2370e4910262f941a3bb0f70ce05ff7a90679fe1 (diff)
downloadlibgit2-6f544140a097002fe5f15e43a4d3215c944140b7.tar.gz
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
Diffstat (limited to 'src/commit_list.c')
-rw-r--r--src/commit_list.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/commit_list.c b/src/commit_list.c
index 11cc2e7d2..692b1495f 100644
--- a/src/commit_list.c
+++ b/src/commit_list.c
@@ -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;