summaryrefslogtreecommitdiff
path: root/src/commit_list.c
diff options
context:
space:
mode:
authorlhchavez <lhchavez@lhchavez.com>2021-01-05 17:20:27 -0800
committerlhchavez <lhchavez@lhchavez.com>2021-03-10 07:09:47 -0800
commit248606ebb0906076367fcfce9574f522f818c26f (patch)
treea3d349ff8cc13ca5fc3a432c9967703f26a63328 /src/commit_list.c
parent4f4b1139d23a7b38cceb9d83acbfaf73151f522f (diff)
downloadlibgit2-248606ebb0906076367fcfce9574f522f818c26f.tar.gz
commit-graph: Use the commit-graph in revwalks
This change makes revwalks a bit faster by using the `commit-graph` file (if present). This is thanks to the `commit-graph` allow much faster parsing of the commit information by requiring near-zero I/O (aside from reading a few dozen bytes off of a `mmap(2)`-ed file) for each commit, instead of having to read the ODB, inflate the commit, and parse it. This is done by modifying `git_commit_list_parse()` and letting it use the ODB-owned commit-graph file. Part of: #5757
Diffstat (limited to 'src/commit_list.c')
-rw-r--r--src/commit_list.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/commit_list.c b/src/commit_list.c
index 2e103ec22..dfdd5daab 100644
--- a/src/commit_list.c
+++ b/src/commit_list.c
@@ -124,6 +124,7 @@ static int commit_quick_parse(
return -1;
}
+ node->generation = 0;
node->time = commit->committer->when.time;
node->out_degree = (uint16_t) git_array_size(commit->parent_ids);
node->parents = alloc_parents(walk, node, node->out_degree);
@@ -143,11 +144,38 @@ static int commit_quick_parse(
int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit)
{
git_odb_object *obj;
+ git_commit_graph_file *cgraph = NULL;
int error;
if (commit->parsed)
return 0;
+ /* Let's try to use the commit graph first. */
+ git_odb__get_commit_graph(&cgraph, walk->odb);
+ if (cgraph) {
+ git_commit_graph_entry e;
+
+ error = git_commit_graph_entry_find(&e, cgraph, &commit->oid, GIT_OID_RAWSZ);
+ if (error == 0 && git__is_uint16(e.parent_count)) {
+ size_t i;
+ commit->generation = (uint32_t)e.generation;
+ commit->time = e.commit_time;
+ commit->out_degree = (uint16_t)e.parent_count;
+ commit->parents = alloc_parents(walk, commit, commit->out_degree);
+ GIT_ERROR_CHECK_ALLOC(commit->parents);
+
+ for (i = 0; i < commit->out_degree; ++i) {
+ git_commit_graph_entry parent;
+ error = git_commit_graph_entry_parent(&parent, cgraph, &e, i);
+ if (error < 0)
+ return error;
+ commit->parents[i] = git_revwalk__commit_lookup(walk, &parent.sha1);
+ }
+ commit->parsed = 1;
+ return 0;
+ }
+ }
+
if ((error = git_odb_read(&obj, walk->odb, &commit->oid)) < 0)
return error;