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

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.

  1. https://lore.kernel.org/git/[email protected]/

cc: Phillip Wood [email protected]
cc: "Kristoffer Haugsbakk" [email protected]
cc: Jeff King [email protected]
cc: Patrick Steinhardt [email protected]
cc: Jean-Noël Avila [email protected]

Since ref iterators do not hold onto the value of a symbolic reference
before resolution, 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 which
can be wasteful when iterating over all references.

To make accessing the direct value of a symbolic ref more efficient,
let's keep track of the value in the iterator so callbacks can have
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. Additionally, adjust
files-backend.c and reftable-backend.c to handle passing this value into
ther respective iterators.

Signed-off-by: John Cai <[email protected]>
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 unresolved value of symref 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 <[email protected]>
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 <[email protected]>
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.

This change results in a nice speedup in git-for-each-ref(1). When run
with about 1300 symbolic references, we see the following benchmark:

Benchmark 1: git for-each-ref

  Time (mean ± σ):      12.7 ms ±   0.7 ms    [User: 5.1 ms, System: 7.6 ms]
  Range (min … max):    11.9 ms …  17.0 ms    168 runs

Benchmark 2: ~/Projects/git/git for-each-ref

  Time (mean ± σ):       7.1 ms ±   0.5 ms    [User: 3.3 ms, System: 3.9 ms]
  Range (min … max):     6.6 ms …  10.7 ms    375 runs

Summary
  '~/Projects/git/git for-each-ref' ran
    1.79 ± 0.15 times faster than 'git for-each-ref'

Signed-off-by: John Cai <[email protected]>
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