All of lore.kernel.org
 help / color / mirror / Atom feed
From: Derrick Stolee <stolee@gmail.com>
To: Jakub Narebski <jnareb@gmail.com>
Cc: Derrick Stolee <dstolee@microsoft.com>,
	git@vger.kernel.org, "peff@peff.net" <peff@peff.net>,
	"avarab@gmail.com" <avarab@gmail.com>,
	"sbeller@google.com" <sbeller@google.com>,
	"larsxschneider@gmail.com" <larsxschneider@gmail.com>,
	"bmwill@google.com" <bmwill@google.com>,
	"gitster@pobox.com" <gitster@pobox.com>,
	"sunshine@sunshineco.com" <sunshine@sunshineco.com>,
	"jonathantanmy@google.com" <jonathantanmy@google.com>
Subject: Re: [PATCH v3 7/9] commit: add short-circuit to paint_down_to_common()
Date: Tue, 24 Apr 2018 08:31:07 -0400	[thread overview]
Message-ID: <b32b7548-6b58-9619-b53e-aa0bad7a81eb@gmail.com> (raw)
In-Reply-To: <86efj5fvrz.fsf@gmail.com>

On 4/23/2018 5:38 PM, Jakub Narebski wrote:
> Derrick Stolee <stolee@gmail.com> writes:
>
>> On 4/18/2018 7:19 PM, Jakub Narebski wrote:
>>> Derrick Stolee <dstolee@microsoft.com> writes:
>>>
>> [...]
>>>> [...], and this saves time during 'git branch --contains' queries
>>>> that would otherwise walk "around" the commit we are inspecting.
>>>>
>>> If I understand the code properly, what happens is that we can now
>>> short-circuit if all commits that are left are lower than the target
>>> commit.
>>>
>>> This is because max-order priority queue is used: if the commit with
>>> maximum generation number is below generation number of target commit,
>>> then target commit is not reachable from any commit in the priority
>>> queue (all of which has generation number less or equal than the commit
>>> at head of queue, i.e. all are same level or deeper); compare what I
>>> have written in [1]
>>>
>>> [1]: https://public-inbox.org/git/866052dkju.fsf@gmail.com/
>>>
>>> Do I have that right?  If so, it looks all right to me.
>> Yes, the priority queue needs to compare via generation number first
>> or there will be errors. This is why we could not use commit time
>> before.
> I was more concerned about getting right the order in the priority queue
> (does it return minimal or maximal generation number).
>
> I understand that the cutoff could not be used without generation
> numbers because of the possibility of clock skew - using cutoff on dates
> could lead to wrong results.

Maximal generation number is important so we do not visit commits 
multiple times (say, once with PARENT1 set, and a second time when 
PARENT2 is set). A minimal generation number order would create a DFS 
order and walk until the cutoff every time.

In cases without clock skew, maximal generation number order will walk 
the same set of commits as maximal commit time; the order may differ, 
but only between incomparable commits.

>>>> For a copy of the Linux repository, where HEAD is checked out at
>>>> v4.13~100, we get the following performance improvement for
>>>> 'git branch --contains' over the previous commit:
>>>>
>>>> Before: 0.21s
>>>> After:  0.13s
>>>> Rel %: -38%
>>> [...]
>>>>    		flags = commit->object.flags & (PARENT1 | PARENT2 | STALE);
>>>>    		if (flags == (PARENT1 | PARENT2)) {
>>>>    			if (!(commit->object.flags & RESULT)) {
>>>> @@ -876,7 +886,7 @@ static struct commit_list *merge_bases_many(struct commit *one, int n, struct co
>>>>    			return NULL;
>>>>    	}
>>>>    -	list = paint_down_to_common(one, n, twos);
>>>> +	list = paint_down_to_common(one, n, twos, 0);
>>>>      	while (list) {
>>>>    		struct commit *commit = pop_commit(&list);
>>>> @@ -943,7 +953,7 @@ static int remove_redundant(struct commit **array, int cnt)
>>>>    			filled_index[filled] = j;
>>>>    			work[filled++] = array[j];
>>>>    		}
>>>> -		common = paint_down_to_common(array[i], filled, work);
>>>> +		common = paint_down_to_common(array[i], filled, work, 0);
>>>>    		if (array[i]->object.flags & PARENT2)
>>>>    			redundant[i] = 1;
>>>>    		for (j = 0; j < filled; j++)
>>>> @@ -1067,7 +1077,7 @@ int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit *
>>>>    	if (commit->generation > min_generation)
>>>>    		return 0;
>>>>    -	bases = paint_down_to_common(commit, nr_reference, reference);
>>>> +	bases = paint_down_to_common(commit, nr_reference, reference, commit->generation);
>>> Is it the only case where we would call paint_down_to_common() with
>>> non-zero last parameter?  Would we always use commit->generation where
>>> commit is the first parameter of paint_down_to_common()?
>>>
>>> If both are true and will remain true, then in my humble opinion it is
>>> not necessary to change the signature of this function.
>> We need to change the signature some way, but maybe the way I chose is
>> not the best.
> No, after taking longer I think the new signature is a good choice.
>
>> To elaborate: paint_down_to_common() is used for multiple
>> purposes. The caller here that supplies 'commit->generation' is used
>> only to compute reachability (by testing if the flag PARENT2 exists on
>> the commit, then clears all flags). The other callers expect the full
>> walk down to the common commits, and keeps those PARENT1, PARENT2, and
>> STALE flags for future use (such as reporting merge bases). Usually
>> the call to paint_down_to_common() is followed by a revision walk that
>> only halts when reaching root commits or commits with both PARENT1 and
>> PARENT2 flags on, so always short-circuiting on generations would
>> break the functionality; this is confirmed by the
>> t5318-commit-graph.sh.
> Right.
>
> I have realized that just after sending the email.  I'm sorry about this.
>
>> An alternative to the signature change is to add a boolean parameter
>> "use_cutoff" or something, that specifies "don't walk beyond the
>> commit". This may give a more of a clear description of what it will
>> do with the generation value, but since we are already performing
>> generation comparisons before calling paint_down_to_common() I find
>> this simple enough.
> Two things:
>
> 1. The signature proposed in the patch is more generic.  The cutoff does
>     not need to be equal to the generation number of the commit, though
>     currently it always (all of one time the new mechanism is used) is.
>
>     So now I think the new signature of paint_down_to_common() is all
>     right as it is proposed here.
>
> 2. The way generation numbers are defined (with 0 being a special case,
>     and generation numbers starting from 1 for parent-less commits), and
>     the way they are compared (using strict comparison, to avoid having
>     to special-case _ZERO, _MAX and _INFINITY generation numbers) the
>     cutoff of 0 means no cutoff.
>
>     On the other hand cutoff of 0 can be understood as meaning no cutoff
>     as a special case.
>
>     It could be made more clear to use (as I proposed elsewhere in this
>     thread) symbolic name for this no-cutoff case via preprocessor
>     constants or enums, e.g. GENERATION_NO_CUTOFF:
>
>      @@ -876,7 +886,7 @@ static struct commit_list *merge_bases_many(struct commit *one, int n, struct co
>        			return NULL;
>        	}
>        -	list = paint_down_to_common(one, n, twos);
>      +	list = paint_down_to_common(one, n, twos, GENERATION_NO_CUTOFF);
>          	while (list) {
>        		struct commit *commit = pop_commit(&list);
>      @@ -943,7 +953,7 @@ static int remove_redundant(struct commit **array, int cnt)
>        			filled_index[filled] = j;
>        			work[filled++] = array[j];
>        		}
>      -		common = paint_down_to_common(array[i], filled, work);
>      +		common = paint_down_to_common(array[i], filled, work, GENERATION_NO_CUTOFF);
>        		if (array[i]->object.flags & PARENT2)
>        			redundant[i] = 1;
>        		for (j = 0; j < filled; j++)
>
>
>     But whether it makes code more readable, or less readable, is a
>     matter of opinion and taste.
>

Since paint_down_to_common() is static to this file, I think 0 is 
cleaner. If the method was external and used by other .c files, then I 
would use this macro trick to clarify "what does this zero parameter mean?".

Thanks,
-Stolee

  reply	other threads:[~2018-04-24 12:31 UTC|newest]

Thread overview: 162+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-03 16:51 [PATCH 0/6] Compute and consume generation numbers Derrick Stolee
2018-04-03 16:51 ` [PATCH 1/6] object.c: parse commit in graph first Derrick Stolee
2018-04-03 18:21   ` Jonathan Tan
2018-04-03 18:28     ` Jeff King
2018-04-03 18:32       ` Derrick Stolee
2018-04-03 16:51 ` [PATCH 2/6] commit: add generation number to struct commmit Derrick Stolee
2018-04-03 18:05   ` Brandon Williams
2018-04-03 18:28     ` Jeff King
2018-04-03 18:31       ` Derrick Stolee
2018-04-03 18:32       ` Brandon Williams
2018-04-03 18:44       ` Stefan Beller
2018-04-03 23:17       ` Ramsay Jones
2018-04-03 23:19         ` Jeff King
2018-04-03 18:24   ` Jonathan Tan
2018-04-03 16:51 ` [PATCH 3/6] commit-graph: compute generation numbers Derrick Stolee
2018-04-03 18:30   ` Jonathan Tan
2018-04-03 18:49     ` Stefan Beller
2018-04-03 16:51 ` [PATCH 4/6] commit: use generations in paint_down_to_common() Derrick Stolee
2018-04-03 18:31   ` Stefan Beller
2018-04-03 18:31   ` Jonathan Tan
2018-04-03 16:51 ` [PATCH 5/6] commit.c: use generation to halt paint walk Derrick Stolee
2018-04-03 19:01   ` Jonathan Tan
2018-04-03 16:51 ` [PATCH 6/6] commit-graph.txt: update future work Derrick Stolee
2018-04-03 19:04   ` Jonathan Tan
2018-04-03 16:56 ` [PATCH 0/6] Compute and consume generation numbers Derrick Stolee
2018-04-03 18:03 ` Brandon Williams
2018-04-03 18:29   ` Derrick Stolee
2018-04-03 18:47     ` Jeff King
2018-04-03 19:05       ` Jeff King
2018-04-04 15:45         ` [PATCH 7/6] ref-filter: use generation number for --contains Derrick Stolee
2018-04-04 15:45           ` [PATCH 8/6] commit: use generation numbers for in_merge_bases() Derrick Stolee
2018-04-04 15:48             ` Derrick Stolee
2018-04-04 17:01               ` Brandon Williams
2018-04-04 18:24               ` Jeff King
2018-04-04 18:53                 ` Derrick Stolee
2018-04-04 18:59                   ` Jeff King
2018-04-04 18:22           ` [PATCH 7/6] ref-filter: use generation number for --contains Jeff King
2018-04-04 19:06             ` Derrick Stolee
2018-04-04 19:16               ` Jeff King
2018-04-04 19:22                 ` Derrick Stolee
2018-04-04 19:42                   ` Jeff King
2018-04-04 19:45                     ` Derrick Stolee
2018-04-04 19:46                       ` Jeff King
2018-04-07 17:09     ` [PATCH 0/6] Compute and consume generation numbers Jakub Narebski
2018-04-07 16:55 ` Jakub Narebski
2018-04-08  1:06   ` Derrick Stolee
2018-04-11 19:32     ` Jakub Narebski
2018-04-11 19:58       ` Derrick Stolee
2018-04-14 16:52         ` Jakub Narebski
2018-04-21 20:44           ` Jakub Narebski
2018-04-23 13:54             ` Derrick Stolee
2018-04-09 16:41 ` [PATCH v2 00/10] " Derrick Stolee
2018-04-09 16:41   ` [PATCH v2 01/10] object.c: parse commit in graph first Derrick Stolee
2018-04-09 16:41   ` [PATCH v2 02/10] merge: check config before loading commits Derrick Stolee
2018-04-11  2:12     ` Junio C Hamano
2018-04-11 12:49       ` Derrick Stolee
2018-04-09 16:42   ` [PATCH v2 03/10] commit: add generation number to struct commmit Derrick Stolee
2018-04-09 17:59     ` Stefan Beller
2018-04-11  2:31     ` Junio C Hamano
2018-04-11 12:57       ` Derrick Stolee
2018-04-11 23:28         ` Junio C Hamano
2018-04-09 16:42   ` [PATCH v2 04/10] commit-graph: compute generation numbers Derrick Stolee
2018-04-11  2:51     ` Junio C Hamano
2018-04-11 13:02       ` Derrick Stolee
2018-04-11 18:49         ` Stefan Beller
2018-04-11 19:26         ` Eric Sunshine
2018-04-09 16:42   ` [PATCH v2 05/10] commit: use generations in paint_down_to_common() Derrick Stolee
2018-04-09 16:42   ` [PATCH v2 06/10] commit.c: use generation to halt paint walk Derrick Stolee
2018-04-11  3:02     ` Junio C Hamano
2018-04-11 13:24       ` Derrick Stolee
2018-04-09 16:42   ` [PATCH v2 07/10] commit-graph.txt: update future work Derrick Stolee
2018-04-12  9:12     ` Junio C Hamano
2018-04-12 11:35       ` Derrick Stolee
2018-04-13  9:53         ` Jakub Narebski
2018-04-09 16:42   ` [PATCH v2 08/10] ref-filter: use generation number for --contains Derrick Stolee
2018-04-09 16:42   ` [PATCH v2 09/10] commit: use generation numbers for in_merge_bases() Derrick Stolee
2018-04-09 16:42   ` [PATCH v2 10/10] commit: add short-circuit to paint_down_to_common() Derrick Stolee
2018-04-17 17:00   ` [PATCH v3 0/9] Compute and consume generation numbers Derrick Stolee
2018-04-17 17:00     ` [PATCH v3 1/9] commit: add generation number to struct commmit Derrick Stolee
2018-04-17 17:00     ` [PATCH v3 2/9] commit-graph: compute generation numbers Derrick Stolee
2018-04-17 17:00     ` [PATCH v3 3/9] commit: use generations in paint_down_to_common() Derrick Stolee
2018-04-18 14:31       ` Jakub Narebski
2018-04-18 14:46         ` Derrick Stolee
2018-04-17 17:00     ` [PATCH v3 4/9] commit-graph.txt: update design document Derrick Stolee
2018-04-18 19:47       ` Jakub Narebski
2018-04-17 17:00     ` [PATCH v3 5/9] ref-filter: use generation number for --contains Derrick Stolee
2018-04-18 21:02       ` Jakub Narebski
2018-04-23 14:22         ` Derrick Stolee
2018-04-24 18:56           ` Jakub Narebski
2018-04-25 14:11             ` Derrick Stolee
2018-04-17 17:00     ` [PATCH v3 6/9] commit: use generation numbers for in_merge_bases() Derrick Stolee
2018-04-18 22:15       ` Jakub Narebski
2018-04-23 14:31         ` Derrick Stolee
2018-04-17 17:00     ` [PATCH v3 7/9] commit: add short-circuit to paint_down_to_common() Derrick Stolee
2018-04-18 23:19       ` Jakub Narebski
2018-04-23 14:40         ` Derrick Stolee
2018-04-23 21:38           ` Jakub Narebski
2018-04-24 12:31             ` Derrick Stolee [this message]
2018-04-19  8:32       ` Jakub Narebski
2018-04-17 17:00     ` [PATCH v3 8/9] commit-graph: always load commit-graph information Derrick Stolee
2018-04-17 17:50       ` Derrick Stolee
2018-04-19  0:02       ` Jakub Narebski
2018-04-23 14:49         ` Derrick Stolee
2018-04-17 17:00     ` [PATCH v3 9/9] merge: check config before loading commits Derrick Stolee
2018-04-19  0:04     ` [PATCH v3 0/9] Compute and consume generation numbers Jakub Narebski
2018-04-23 14:54       ` Derrick Stolee
2018-04-25 14:37     ` [PATCH v4 00/10] " Derrick Stolee
2018-04-25 14:37       ` [PATCH v4 01/10] ref-filter: fix outdated comment on in_commit_list Derrick Stolee
2018-04-28 17:54         ` Jakub Narebski
2018-04-25 14:37       ` [PATCH v4 02/10] commit: add generation number to struct commmit Derrick Stolee
2018-04-28 22:35         ` Jakub Narebski
2018-04-30 12:05           ` Derrick Stolee
2018-04-25 14:37       ` [PATCH v4 03/10] commit-graph: compute generation numbers Derrick Stolee
2018-04-26  2:35         ` Junio C Hamano
2018-04-26 12:58           ` Derrick Stolee
2018-04-26 13:49             ` Derrick Stolee
2018-04-29  9:08         ` Jakub Narebski
2018-05-01 12:10           ` Derrick Stolee
2018-05-02 16:15             ` Jakub Narebski
2018-04-25 14:37       ` [PATCH v4 04/10] commit: use generations in paint_down_to_common() Derrick Stolee
2018-04-26  3:22         ` Junio C Hamano
2018-04-26  9:02           ` Jakub Narebski
2018-04-28 14:38             ` Jakub Narebski
2018-04-29 15:40         ` Jakub Narebski
2018-04-25 14:37       ` [PATCH v4 06/10] ref-filter: use generation number for --contains Derrick Stolee
2018-04-30 16:34         ` Jakub Narebski
2018-04-25 14:37       ` [PATCH v4 05/10] commit-graph: always load commit-graph information Derrick Stolee
2018-04-29 22:14         ` Jakub Narebski
2018-05-01 12:19           ` Derrick Stolee
2018-04-29 22:18         ` Jakub Narebski
2018-04-25 14:37       ` [PATCH v4 07/10] commit: use generation numbers for in_merge_bases() Derrick Stolee
2018-04-30 17:05         ` Jakub Narebski
2018-04-25 14:38       ` [PATCH v4 08/10] commit: add short-circuit to paint_down_to_common() Derrick Stolee
2018-04-30 22:19         ` Jakub Narebski
2018-05-01 11:47           ` Derrick Stolee
2018-05-02 13:05             ` Jakub Narebski
2018-05-02 13:42               ` Derrick Stolee
2018-04-25 14:38       ` [PATCH v4 09/10] merge: check config before loading commits Derrick Stolee
2018-04-30 22:54         ` Jakub Narebski
2018-05-01 11:52           ` Derrick Stolee
2018-05-02 11:41             ` Jakub Narebski
2018-04-25 14:38       ` [PATCH v4 10/10] commit-graph.txt: update design document Derrick Stolee
2018-04-30 23:32         ` Jakub Narebski
2018-05-01 12:00           ` Derrick Stolee
2018-05-02  7:57             ` Jakub Narebski
2018-04-25 14:40       ` [PATCH v4 00/10] Compute and consume generation numbers Derrick Stolee
2018-04-28 17:28         ` Jakub Narebski
2018-05-01 12:47       ` [PATCH v5 00/11] " Derrick Stolee
2018-05-01 12:47         ` [PATCH v5 01/11] ref-filter: fix outdated comment on in_commit_list Derrick Stolee
2018-05-01 12:47         ` [PATCH v5 02/11] commit: add generation number to struct commmit Derrick Stolee
2018-05-01 12:47         ` [PATCH v5 03/11] commit-graph: compute generation numbers Derrick Stolee
2018-05-01 12:47         ` [PATCH v5 04/11] commit: use generations in paint_down_to_common() Derrick Stolee
2018-05-01 12:47         ` [PATCH v5 05/11] commit-graph: always load commit-graph information Derrick Stolee
2018-05-01 12:47         ` [PATCH v5 06/11] ref-filter: use generation number for --contains Derrick Stolee
2018-05-01 12:47         ` [PATCH v5 07/11] commit: use generation numbers for in_merge_bases() Derrick Stolee
2018-05-01 12:47         ` [PATCH v5 08/11] commit: add short-circuit to paint_down_to_common() Derrick Stolee
2018-05-01 12:47         ` [PATCH v5 09/11] commit: use generation number in remove_redundant() Derrick Stolee
2018-05-01 15:37           ` Derrick Stolee
2018-05-03 18:45           ` Jakub Narebski
2018-05-01 12:47         ` [PATCH v5 10/11] merge: check config before loading commits Derrick Stolee
2018-05-01 12:47         ` [PATCH v5 11/11] commit-graph.txt: update design document Derrick Stolee
2018-05-03 11:18         ` [PATCH v5 00/11] Compute and consume generation numbers Jakub Narebski

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=b32b7548-6b58-9619-b53e-aa0bad7a81eb@gmail.com \
    --to=stolee@gmail.com \
    --cc=avarab@gmail.com \
    --cc=bmwill@google.com \
    --cc=dstolee@microsoft.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jnareb@gmail.com \
    --cc=jonathantanmy@google.com \
    --cc=larsxschneider@gmail.com \
    --cc=peff@peff.net \
    --cc=sbeller@google.com \
    --cc=sunshine@sunshineco.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.