diff options
author | lhchavez <lhchavez@lhchavez.com> | 2021-01-05 17:20:27 -0800 |
---|---|---|
committer | lhchavez <lhchavez@lhchavez.com> | 2021-03-10 07:09:47 -0800 |
commit | 248606ebb0906076367fcfce9574f522f818c26f (patch) | |
tree | a3d349ff8cc13ca5fc3a432c9967703f26a63328 /src/commit_list.c | |
parent | 4f4b1139d23a7b38cceb9d83acbfaf73151f522f (diff) | |
download | libgit2-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.c | 28 |
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; |