git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 03/20] refs_ref_iterator_begin(): new function

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
Apr 16, 2017, 04:39 UTC
Message-ID
<3b508517-80fc-d759-d27f-a582a36286ba@alum.mit.edu>
In-Reply-To
<CACsJy8CECcC1EDpr8u39Pzq75E5KXrYwm_Bz+UTXobWvgV5weA@mail.gmail.com>
On 04/07/2017 12:57 PM, Duy Nguyen wrote:
Show 33 quoted lines
> On Fri, Mar 31, 2017 at 9:11 PM, Michael Haggerty <mhagger@alum.mit.edu> wrote:
>> Extract a new function from `do_for_each_ref()`. It will be useful
>> elsewhere.
>>
>> Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
>> ---
>>  refs.c               | 15 +++++++++++++--
>>  refs/refs-internal.h | 11 +++++++++++
>>  2 files changed, 24 insertions(+), 2 deletions(-)
>>
>> diff --git a/refs.c b/refs.c
>> index 0ed6c3c7a4..aeb704ab92 100644
>> --- a/refs.c
>> +++ b/refs.c
>> @@ -1230,6 +1230,18 @@ int head_ref(each_ref_fn fn, void *cb_data)
>>         return head_ref_submodule(NULL, fn, cb_data);
>>  }
>>
>> +struct ref_iterator *refs_ref_iterator_begin(
>> +               struct ref_store *refs,
>> +               const char *prefix, int trim, int flags)
>> +{
>> +       struct ref_iterator *iter;
>> +
>> +       iter = refs->be->iterator_begin(refs, prefix, flags);
>> +       iter = prefix_ref_iterator_begin(iter, prefix, trim);
> 
> Off topic. This code made me wonder if we really need the prefix
> iterator if prefix is NULL. And in fact we don't since
> prefix_ref_iterator_begin() will return the old iter in that case. But
> it's probably better to move that optimization outside. I think it's
> easier to understand that way, calling prefix_ref_ will always give
> you a new iterator. Don't call it unless you want to have it.

I like this aspect of the design because it is more powerful. Consider for example that some reference backend might (e.g., a future `packed_ref_store`) need to use a `prefix_ref_iterator` to implement `iterator_begin()`, while another (e.g., one based on `ref_cache`) might not. It would be easy to make `prefix_ref_iterator_begin()` check whether its argument is already a `prefix_ref_iterator`, and if so, swap it out with a new one with different arguments (to avoid having to stack them up). It would be inappropriate for the caller to make such an optimization, because it (a) shouldn't have to care what type of reference iterator it is dealing with, and (b) shouldn't have to know enough about `prefix_ref_iterator`s to know that the optimization makes sense.

Show 10 quoted lines
>> +/*
>> + * Return an iterator that goes over each reference in `refs` for
>> + * which the refname begins with prefix. If trim is non-zero, then
>> + * trim that many characters off the beginning of each refname. flags
>> + * can be DO_FOR_EACH_INCLUDE_BROKEN to include broken references in
>> + * the iteration.
>> + */
> 
> Do we need a separate docstring here? I think we document more or less
> the same for ref_iterator_begin_fn (except the include-broken flag).

There is a subtle difference: currently, `ref_iterator_begin_fn()` doesn't use its full `prefix` argument as prefix, but rather `find_containing_dir(prefix)`. (This is basically an implementation detail of `ref_cache` leaking out into the virtual function interface.)

`refs_ref_iterator_begin()`, on the other hand, treats the prefix literally, using `starts_with()`.

I don't like this design and plan to improve it sometime, but for now that's an important difference. The fix, incidentally, would motivate the `prefix_ref_iterator_begin()` optimization mentioned above.

Michael
Previous: Duy NguyenNext: Michael Haggerty
Message 13 of 42 in “Separate `ref_cache` into a separate module”
  1. 00/20 Separate `ref_cache` into a separate moduleMichael Haggerty, Mar 31, 2017
  2. 01/20 get_ref_dir(): don't call read_loose_refs() for "refs/bisect"Michael Haggerty, Mar 31, 2017
  3. Stefan BellerMar 31, 2017
  4. 02/20 refs_read_raw_ref(): new functionMichael Haggerty, Mar 31, 2017
  5. 04/20 refs_verify_refname_available(): implement once for all backendsMichael Haggerty, Mar 31, 2017
  6. Duy NguyenApr 7, 2017
  7. Michael HaggertyApr 16, 2017
  8. 06/20 ref-cache: rename `add_ref()` to `add_ref_entry()`Michael Haggerty, Mar 31, 2017
  9. 07/20 ref-cache: rename `find_ref()` to `find_ref_entry()`Michael Haggerty, Mar 31, 2017
  10. 08/20 ref-cache: rename `remove_entry()` to `remove_entry_from_dir()`Michael Haggerty, Mar 31, 2017
  11. 03/20 refs_ref_iterator_begin(): new functionMichael Haggerty, Mar 31, 2017
  12. Duy NguyenApr 7, 2017
  13. Michael HaggertyApr 16, 2017
  14. 05/20 refs_verify_refname_available(): use function in more placesMichael Haggerty, Mar 31, 2017
  15. 12/20 ref-cache: use a callback function to fill the cacheMichael Haggerty, Mar 31, 2017
  16. 09/20 refs: split `ref_cache` code into separate filesMichael Haggerty, Mar 31, 2017
  17. 15/20 get_loose_ref_dir(): function renamed from get_loose_refs()Michael Haggerty, Mar 31, 2017
  18. 16/20 get_loose_ref_cache(): new functionMichael Haggerty, Mar 31, 2017
  19. 19/20 files_pack_refs(): use reference iterationMichael Haggerty, Mar 31, 2017
  20. Duy NguyenApr 7, 2017
  21. Michael HaggertyApr 16, 2017
  22. 17/20 cache_ref_iterator_begin(): make function smarterMichael Haggerty, Mar 31, 2017
  23. 18/20 commit_packed_refs(): use reference iterationMichael Haggerty, Mar 31, 2017
  24. 13/20 refs: handle "refs/bisect/" in `loose_fill_ref_dir()`Michael Haggerty, Mar 31, 2017
  25. 20/20 do_for_each_entry_in_dir(): delete functionMichael Haggerty, Mar 31, 2017
  26. 10/20 ref-cache: introduce a new type, ref_cacheMichael Haggerty, Mar 31, 2017
  27. Duy NguyenApr 7, 2017
  28. Michael HaggertyApr 16, 2017
  29. 14/20 do_for_each_entry_in_dir(): eliminate `offset` argumentMichael Haggerty, Mar 31, 2017
  30. 11/20 refs: record the ref_store in ref_cache, not ref_dirMichael Haggerty, Mar 31, 2017
  31. Duy NguyenApr 7, 2017
  32. Michael HaggertyApr 16, 2017
  33. Junio C HamanoMar 31, 2017
  34. Michael HaggertyApr 1, 2017
  35. Duy NguyenApr 5, 2017
  36. Duy NguyenApr 7, 2017
  37. Michael HaggertyApr 16, 2017
  38. Ramsay JonesApr 1, 2017
  39. Junio C HamanoApr 2, 2017
  40. Ramsay JonesApr 2, 2017
  41. Junio C HamanoApr 2, 2017
  42. Jeff KingApr 1, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.