Re: [PATCH v3 3/4] refs: selectively set prefix in the seek functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Junio C Hamano <gitster@xxxxxxxxx> writes:

> Patrick Steinhardt <ps@xxxxxx> writes:
>
>>> + * When the REF_ITERATOR_SEEK_SET_PREFIX flag is set, the iterator's prefix is
>>> + * updated to match the seek string, affecting all subsequent iterations. If
>>> + * not, the iterator seeks to the specified reference and clears any previously
>>> + * set prefix.
>>>   *
>>>   * Returns 0 on success, a negative error code otherwise.
>>>   */
>>> -int ref_iterator_seek(struct ref_iterator *ref_iterator,
>>> -		      const char *prefix);
>>> +int ref_iterator_seek(struct ref_iterator *ref_iterator, const char *seek,
>>> +		      unsigned int flags);
>>
>> Another tiny nit: instead of calling the variable `seek` we can just
>> call it `refname`. That might give a bit more of a hint what you're
>> actually seeking for.
>>
>> But other than that I'm happy with the new behaviour, where we are now
>> consistently either setting or resetting the prefix depending on whether
>> or not the caller set the flag.
>
> I am not sure.  The way the "prefix" is used, if I understand correctly, is
>
>  - it is set by iterator-begin, typically to the area to iterate
>    over (e.g. "refs/heads/" for iterating over branches) in the
>    for_each_ref_*() family of helpers, and internally we seek to
>    that area (skipping anything that come strictly before
>    "refs/heads/" for example).
>
>  - iterator-advance looks at it and decides we are done when the
>    iterator points beyond that prefix
>

That's right.

> So if you are iterating inside "refs/heads/" hierarchy and seek to
> "refs/heads/m", don't you still want to stop when you step outside
> "refs/heads/" by keeping the original prefix, instead of unsetting
> the prefix to empty?  A postimage of this patch for packed backend
> (picked at random) reads like this:
>
>         static int packed_ref_iterator_seek(struct ref_iterator *ref_iterator,
>                                             const char *seek, unsigned int flags)
>         {
>                 struct packed_ref_iterator *iter =
>                         (struct packed_ref_iterator *)ref_iterator;
>                 const char *start;
>
>                 if (seek && *seek)
>                         start = find_reference_location(iter->snapshot, seek, 0);
>                 else
>                         start = iter->snapshot->start;
>
>                 /* Unset any previously set prefix */
>                 FREE_AND_NULL(iter->prefix);
>
>                 if (flags & REF_ITERATOR_SEEK_SET_PREFIX)
>                         iter->prefix = xstrdup_or_null(seek);
>
> so after (true) seeking that does not have the SET_PREFIX flag on,
> wouldn't our iterator-advance run through the end since it no longer
> is aware of where to stop?
>

That's also right and that is indeed the intention. We're trying to make
the actions more intentional.

So if a user sets a 'prefix' for the iterator, all previous state of the
iterator is reset. So, the same function for seeking an iterator should
also have the same side-effect of resetting the previous state.

There could be a usecase where we add support for keeping the prefix,
while also seeking the iterator. That would be an explicit change
(perhaps with a corresponding flag?) that we'd have to build, add tests
for and call out. Until then, we explicitly reset the state whenever a
user calls 'ref_iterator_seek()', they can be sure that any previous
state is reset.

> Thanks.

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux