Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

keep track of unresolved value of symbolic-ref in iterator #1712

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

john-cai
Copy link
Contributor

@john-cai john-cai commented Apr 21, 2024

For reftable development, it's useful to be able to print out the direct value of a symbolic reference before resolution. This is currently possible with git-for-each-ref, but since the iterators do not keep track of the value of the symbolic ref, a separate call needs to be made each time.

Address this inefficiency by keeping track of the value of the symbolic reference in the ref iterator. This patch series also ends with a commit to use this value in the iterator through callbacks in ref-filter.c.

This series started with [1] but I decided to send a separate patch series since it is substantially different.

Benchmarking shows that with these changes, we experience a significant speedup in git-for-each-ref(1) when %(symref) is used in the format string:

$ hyperfine --warmup 5 "git for-each-ref --format='%(refname) %(objectname) %(symref)'" "~/Projects/git/git for-each-ref --format='%(refname) %(objectname) %(symref)'"

Benchmark 1: git for-each-ref --format='%(refname) %(objectname) %(symref)'
Time (mean ± σ): 210.0 ms ± 9.1 ms [User: 5.8 ms, System: 11.8 ms]
Range (min … max): 203.4 ms … 228.8 ms 12 runs

Benchmark 2: ~/Projects/git/git for-each-ref --format='%(refname) %(objectname) %(symref)'
Time (mean ± σ): 7.4 ms ± 0.7 ms [User: 2.6 ms, System: 3.9 ms]
Range (min … max): 5.9 ms … 11.7 ms 273 runs

Summary
~/Projects/git/git for-each-ref --format='%(refname) %(objectname) %(symref)' ran
28.47 ± 2.86 times faster than git for-each-ref --format='%(refname) %(objectname) %(symref)'

  1. https://lore.kernel.org/git/pull.1684.git.git.1709592718743.gitgitgadget@gmail.com/

cc: Phillip Wood phillip.wood123@gmail.com
cc: "Kristoffer Haugsbakk" code@khaugsbakk.name
cc: Jeff King peff@peff.net
cc: Patrick Steinhardt ps@pks.im
cc: Jean-Noël Avila avila.jn@gmail.com

Since ref iterators do not hold onto the direct value of a reference
without resolving it, the only way to get ahold of a direct value of a
symbolic ref is to make a separate call to refs_read_symbolic_ref.

To make accessing the direct value of a symbolic ref more efficient,
let's save the direct value of the ref in the cache so the iterator has
access to it.

To do so, we need to add an argument to refs_resolve_ref_unsafe to save
the direct value of the reference to.

Signed-off-by: John Cai <johncai86@gmail.com>
There is no way for callers of the refs api functions that use iterators
to get a hold of a direct value of a symbolic ref before its resolved in
the callback functions, as either each_ref_fn nor each_repo_ref_fn have
an argument for this.

The previous commit started to save the value of the direct reference in
the iterator.

Add an argument to each_repo_ref_fn that gets called with the direct
value of a refernce, and pass the value through from the iterator.

Signed-off-by: John Cai <johncai86@gmail.com>
A past commit allows ref iterators to keep the value of a symref. The
previous commit exposed this value through a parameter added to
each_repo_ref_fn for callers to have access to it.

Add the same parameter to each_ref_fn so that callers to the ref APIs
that use this function as a callback also can have acess to the
unresolved value of a symbolic ref.

Signed-off-by: John Cai <johncai86@gmail.com>
With a previous commit, the reference the symbolic ref points is saved
in the ref iterator records. Instead of making a separate call to
resolve_refdup() each time, we can just populate the ref_array_item with
the value from the iterator.

Signed-off-by: John Cai <johncai86@gmail.com>
@john-cai john-cai force-pushed the jc/symbolic-ref-in-iterator branch from 0ce74be to 59acda5 Compare May 24, 2024 14:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant