git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Michael Haggerty <mhagger@alum.mit.edu>
To: Junio C Hamano <gitster@pobox.com>
Cc: Jeff King <peff@peff.net>, Heiko Voigt <hvoigt@hvoigt.net>,
	git@vger.kernel.org
Subject: Re: [PATCH 14/33] refs: extract a function peel_entry()
Date: Wed, 17 Apr 2013 00:01:57 +0200	[thread overview]
Message-ID: <516DCA55.8030601@alum.mit.edu> (raw)
In-Reply-To: <7vhaj6mkcb.fsf@alter.siamese.dyndns.org>

On 04/16/2013 07:55 PM, Junio C Hamano wrote:
> Michael Haggerty <mhagger@alum.mit.edu> writes:
> 
>> On 04/15/2013 07:38 PM, Junio C Hamano wrote:
>>> Michael Haggerty <mhagger@alum.mit.edu> writes:
>>>
>>>>  	if (read_ref_full(refname, base, 1, &flag))
>>>>  		return -1;
>>>>  
>>>> -	if ((flag & REF_ISPACKED)) {
>>>> +	/*
>>>> +	 * If the reference is packed, read its ref_entry from the
>>>> +	 * cache in the hope that we already know its peeled value.
>>>> +	 * We only try this optimization on packed references because
>>>> +	 * (a) forcing the filling of the loose reference cache could
>>>> +	 * be expensive and (b) loose references anyway usually do not
>>>> +	 * have REF_KNOWS_PEELED.
>>>> +	 */
>>>> +	if (flag & REF_ISPACKED) {
>>>>  		struct ref_entry *r = get_packed_ref(refname);
>>>
>>> This code makes the reader wonder what happens when a new loose ref
>>> masks a stale packed ref, but the worry is unfounded because the
>>> read_ref_full() wouldn't have gave us REF_ISPACKED in the flag in
>>> such a case.
>>>
>>> But somehow the calling sequence looks like such a mistake waiting
>>> to happen.  It would be much more clear if a function that returns a
>>> "struct ref_entry *" is used instead of read_ref_full() above, and
>>> we checked (r->flag & REF_ISPACKED) in the conditional, without a
>>> separate get_packed_ref(refname).
>>
>> As I'm sure you realize, I didn't change the code that you are referring
>> to; I just added a comment.
> 
> Yes.
> 
>> But yes, I sympathize with your complaint.  Additionally, the code has
>> the drawback that get_packed_ref() is called twice: once in
>> read_ref_full() and again in the if block here.  Unfortunately, this
>> isn't so easy to fix because read_ref_full() doesn't use the loose
>> reference cache, so the reference that it returns might not even have a
>> ref_entry associated with it (specifically, unless the returned flag
>> value has REF_ISPACKED set).  So there are a couple options:
>>
>> * Always read loose references through the cache; that way there would
>> always be a ref_entry in which the return value could be presented.
>> This would not be a good idea at the moment because the loose reference
>> cache is populated one directory at a time, and reading a whole
>> directory of loose references could be expensive.  So before
>> implementing this, it would be advisable to change the code to populate
>> the loose reference cache more selectively when single loose references
>> are needed.  -> This approach would be well beyond the scope of this
>> patch series.
>>
>> * Implement a function like read_ref_full() with an additional (struct
>> ref_entry **entry) argument that is written to *in the case* that the
>> reference that was returned has a ref_entry associated with it, and NULL
>> otherwise.  This would have to be an internal function because we don't
>> want to expose the ref_entry structure outside of refs.c.
>> read_ref_full() would be implemented on top of the new function.
> 
> Isn't there another?
> 
> Instead of using read_ref_full() at this callsite, can it call a
> function, given a refname, returns a pointer to "struct ref_entry",
> using the proper "a loose ref covers the packed ref with the same
> name" semantics?
> 
> I guess that may need the same machinery for your first option to
> implement it efficiently; right now read_ref_full() goes directly to
> the single file that would hold the named ref without scanning and
> populating sibling refs in the in-core loose ref hierarchy, and
> without doing so you cannot return a struct ref_entry.  Hmm...

Yes, that's the crux.  Without the ref_cache, there is no persistent
ref_entry that can be returned to the caller.

Somewhere I have a prototype patch series (never submitted) that would
make it reasonable to access all references via the cache.  For single
reference accesses, it wouldn't read all of the loose references in the
whole directory but rather only create stub REF_INCOMPLETE ref_entries
for the refs that are not needed immediately.  These entries would be
filled when they are accessed.  There was also going to be a bulk read
command to be used when it is expected that the whole directory will be
needed.  With this change we really would have a ref_entry for every
reference and your suggestion would become plausible.  Someday...

But for the current issue it would be totally sufficient to return an
additional pointer to the ref_entry *if it is available*, because for
packed refs it will always be available.

Actually, for the current patch series I don't see the urgency of
changing *anything*.  The code works as is and is no worse than the old
code.  I'd rather do this change (if I get to it) in a separate series.

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

  reply	other threads:[~2013-04-16 22:02 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-14 12:54 [PATCH 00/33] Various cleanups around reference packing and peeling Michael Haggerty
2013-04-14 12:54 ` [PATCH 01/33] refs: document flags constants REF_* Michael Haggerty
2013-04-14 12:54 ` [PATCH 02/33] refs: document the fields of struct ref_value Michael Haggerty
2013-04-14 12:54 ` [PATCH 03/33] refs: document do_for_each_ref() and do_one_ref() Michael Haggerty
2013-04-15 17:38   ` Junio C Hamano
2013-04-16  9:11     ` Michael Haggerty
2013-04-14 12:54 ` [PATCH 04/33] refs: document how current_ref is used Michael Haggerty
2013-04-14 12:54 ` [PATCH 05/33] refs: define constant PEELED_LINE_LENGTH Michael Haggerty
2013-04-14 12:54 ` [PATCH 06/33] do_for_each_ref_in_dirs(): remove dead code Michael Haggerty
2013-04-14 12:54 ` [PATCH 07/33] get_packed_ref(): return a ref_entry Michael Haggerty
2013-04-14 12:54 ` [PATCH 08/33] peel_ref(): use function get_packed_ref() Michael Haggerty
2013-04-14 12:54 ` [PATCH 09/33] repack_without_ref(): " Michael Haggerty
2013-04-14 12:54 ` [PATCH 10/33] refs: extract a function ref_resolves_to_object() Michael Haggerty
2013-04-15 16:51   ` Junio C Hamano
2013-04-16  9:27     ` Michael Haggerty
2013-04-16 18:08       ` Junio C Hamano
2013-04-14 12:54 ` [PATCH 11/33] refs: extract function peel_object() Michael Haggerty
2013-04-14 12:54 ` [PATCH 12/33] peel_object(): give more specific information in return value Michael Haggerty
2013-04-15 17:38   ` Junio C Hamano
2013-04-14 12:54 ` [PATCH 13/33] peel_ref(): fix return value for non-peelable, not-current reference Michael Haggerty
2013-04-15 17:38   ` Junio C Hamano
2013-04-16  9:38     ` Michael Haggerty
2013-04-14 12:54 ` [PATCH 14/33] refs: extract a function peel_entry() Michael Haggerty
2013-04-15 17:38   ` Junio C Hamano
2013-04-16 13:07     ` Michael Haggerty
2013-04-16 17:55       ` Junio C Hamano
2013-04-16 22:01         ` Michael Haggerty [this message]
2013-04-14 12:54 ` [PATCH 15/33] refs: change the internal reference-iteration API Michael Haggerty
2013-04-15 17:38   ` Junio C Hamano
2013-04-16 13:27     ` Michael Haggerty
2013-04-16 17:47       ` Junio C Hamano
2013-04-14 12:54 ` [PATCH 16/33] t3210: test for spurious error messages for dangling packed refs Michael Haggerty
2013-04-15 17:39   ` Junio C Hamano
2013-04-16 14:14     ` Michael Haggerty
2013-04-16 23:22       ` Junio C Hamano
2013-04-16 23:57         ` Jeff King
2013-04-17  4:42           ` Junio C Hamano
2013-04-17 22:38             ` Junio C Hamano
2013-04-18  7:46               ` [PATCH 0/2] Add documentation for new expiry option values Michael Haggerty
2013-04-18  7:46                 ` [PATCH 1/2] git-gc.txt, git-reflog.txt: document new expiry options Michael Haggerty
2013-04-18  7:46                 ` [PATCH 2/2] api-parse-options.txt: document "no-" for non-boolean options Michael Haggerty
2013-04-25 18:13                 ` [PATCH] prune: introduce OPT_EXPIRY_DATE() and use it Junio C Hamano
2013-04-17  8:11         ` [PATCH 16/33] t3210: test for spurious error messages for dangling packed refs Michael Haggerty
2013-04-14 12:54 ` [PATCH 17/33] repack_without_ref(): silence errors " Michael Haggerty
2013-04-15 17:39   ` Junio C Hamano
2013-04-17  8:41     ` Michael Haggerty
2013-04-14 12:54 ` [PATCH 18/33] search_ref_dir(): return an index rather than a pointer Michael Haggerty
2013-04-14 12:54 ` [PATCH 19/33] refs: change how packed refs are deleted Michael Haggerty
2013-04-14 12:54 ` [PATCH 20/33] t3211: demonstrate loss of peeled refs if a packed ref is deleted Michael Haggerty
2013-04-14 12:54 ` [PATCH 21/33] repack_without_ref(): write peeled refs in the rewritten file Michael Haggerty
2013-04-15 17:39   ` Junio C Hamano
2013-04-14 12:54 ` [PATCH 22/33] refs: extract a function write_packed_entry() Michael Haggerty
2013-04-14 12:54 ` [PATCH 23/33] pack-refs: rename handle_one_ref() to pack_one_ref() Michael Haggerty
2013-04-14 12:54 ` [PATCH 24/33] pack-refs: merge code from pack-refs.{c,h} into refs.{c,h} Michael Haggerty
2013-04-14 12:54 ` [PATCH 25/33] pack_one_ref(): rename "path" parameter to "refname" Michael Haggerty
2013-04-14 12:54 ` [PATCH 26/33] refs: use same lock_file object for both ref-packing functions Michael Haggerty
2013-04-14 12:54 ` [PATCH 27/33] pack_refs(): change to use do_for_each_entry() Michael Haggerty
2013-04-14 12:54 ` [PATCH 28/33] refs: inline function do_not_prune() Michael Haggerty
2013-04-14 12:54 ` [PATCH 29/33] pack_one_ref(): use function peel_entry() Michael Haggerty
2013-04-14 12:54 ` [PATCH 30/33] pack_one_ref(): use write_packed_entry() to do the writing Michael Haggerty
2013-04-14 12:54 ` [PATCH 31/33] pack_one_ref(): do some cheap tests before a more expensive one Michael Haggerty
2013-04-14 12:54 ` [PATCH 32/33] refs: change do_for_each_*() functions to take ref_cache arguments Michael Haggerty
2013-04-15 17:40   ` Junio C Hamano
2013-04-14 12:54 ` [PATCH 33/33] refs: handle the main ref_cache specially Michael Haggerty

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=516DCA55.8030601@alum.mit.edu \
    --to=mhagger@alum.mit.edu \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=hvoigt@hvoigt.net \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).