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

Re: [PATCH 14/16] bisect: use a modified breadth-first search to find relevant weights

From
Stephan Beyer <s-beyer@gmx.net>
Date
Feb 26, 2016, 20:55 UTC
Message-ID
<56D0BBB4.9020305@gmx.net>
In-Reply-To
<xmqqr3g0kvzx.fsf@gitster.mtv.corp.google.com>
Hi,
On 02/26/2016 04:09 AM, Junio C Hamano wrote:
Show 7 quoted lines
> Interesting.  So you walk from the bottom commits, incrementing the
> weight while walking on a part of the graph that is single strand of
> pearls, or doing the "count the reachable ones the hard way" when
> you hit a merge [*1*], but either way, once you know the commit you
> are looking at is above the mid-way, i.e. reaches more than half of
> the graph, then stop walking because its children will never be
> better than that commit?
Exactly. Maybe that's an even better description for the commit message l-)
> I haven't studied the code carefully, but your mention of BFS makes
> me wonder if you can "narrow" down the search space even more.

I had an idea that aimed at accomplishing this by finding the highest-distance merge commit using binary search. (The BFS collected all merge commits, in that order, then you could do binary search.) So you have O(log(#mergecommits)) "do it the hard way" weight computations. However, in the worst case (or even in every case, I did not thoroughly think about the cases that can occur), it could happen that it also had to do these "do it the hard way" computations for all merge commits with smaller weight... That's why I dropped this idea in favor of the more simple approach that I sent to the list.

Show 12 quoted lines
> In an earlier step of the series, you introduced a work queue to
> replace the recursion.  The recursion forces the algorithm to work
> along the topology of the history, but you have more latitude in
> selecting the commit to dig further with a work queue.
> 
> I wonder if you can sort the elements on the work queue based on
> their distance (i.e. by using a priority queue).  You know the total
> upfront, so you may find a commit whose weight is exactly half of it
> before traversing all the bottom half of the history and it may turn
> out to be even more efficient.  After all, you are only looking for
> just one such commit, not trying to find all the commits with the
> best weight.

For the compute_weight() function (the "doing it the hard way" function), this would not make sense since all parent commits (of a merge commit we call compute_weight() on) will have smaller distance.

However, your idea can help: I just noticed that it's not important that I use a *B*FS because of the acyclity. So I could also use a DFS that is "more greedy" going towards high numbers. Note that the traversal is always on trees because the merge commits are cut out. So whenever a branching (a commit with more than one child) occurs, the DFS should follow the branch of maximum length to its leaf. (These maximum lengths can be saved during build_reversed_dag().) Then, if there is a halfway commit, we stop. If not, we can just go on with the remaining DFS... I think I only rethought and rephrased your idea. :) Sounds good to me. I'm going to add commits for that.

Show 7 quoted lines
> [Footnote]
> 
> *1* A merge between a commit that reaches N commits and another that
> reaches M commits may have weight smaller than the sum of N and M,
> and that is why I left the original "truly stupid algorithm" Linus
> wrote as-is when I did the obvious optimization for the linear parts
> of the history.

Yes. In fact, the "truly stupid algorithm" is not truly stupid. I'm not quite sure, but I think it's still the best algorithm known so far for that problem. (But maybe the problem is just not very interesting in science.)

> *2* Whenever I revisited the bisection in my head, I thought about
> ways to improve that "truly stupid" counting, but never thought
> about an approach to simply reduce the number of times the "truly
> stupid" counting has to be done.

Well, I also improved that "truly stupid" counting a little in a former commit (patch 7). But it's just the implementation that I improved (time/memory trade-off), not the algorithm. :)

Cheers,
  Stephan
Previous: Junio C HamanoNext: Stephan Beyer
Message 28 of 34 in “git bisect improvements”
  1. 00/16 git bisect improvementsStephan Beyer, Feb 26, 2016
  2. 01/16 bisect: write about `bisect next` in documentationStephan Beyer, Feb 26, 2016
  3. Jacob KellerFeb 26, 2016
  4. Junio C HamanoFeb 26, 2016
  5. Stephan BeyerFeb 27, 2016
  6. Junio C HamanoFeb 27, 2016
  7. Stephan BeyerFeb 27, 2016
  8. Junio C HamanoFeb 28, 2016
  9. 02/16 bisect: add test for the bisect algorithmStephan Beyer, Feb 26, 2016
  10. Christian CouderFeb 26, 2016
  11. Stephan BeyerFeb 26, 2016
  12. Christian CouderFeb 27, 2016
  13. Matthieu MoyFeb 27, 2016
  14. 03/16 bisect: make bisect compile if DEBUG_BISECT is setStephan Beyer, Feb 26, 2016
  15. 04/16 bisect: make algorithm behavior independent of DEBUG_BISECTStephan Beyer, Feb 26, 2016
  16. 05/16 bisect: get rid of recursion in count_distance()Stephan Beyer, Feb 26, 2016
  17. 06/16 bisect: use struct node_data array instead of int arrayStephan Beyer, Feb 26, 2016
  18. 07/16 bisect: replace clear_distance() by unique markersStephan Beyer, Feb 26, 2016
  19. 08/16 bisect: use commit instead of commit list as arguments when appropriateStephan Beyer, Feb 26, 2016
  20. Junio C HamanoFeb 26, 2016
  21. 09/16 bisect: extract get_distance() function from code duplicationStephan Beyer, Feb 26, 2016
  22. 10/16 bisect: introduce distance_direction()Stephan Beyer, Feb 26, 2016
  23. 11/16 bisect: make total number of commits globalStephan Beyer, Feb 26, 2016
  24. 12/16 bisect: rename count_distance() to compute_weight()Stephan Beyer, Feb 26, 2016
  25. 13/16 bisect: prepare for different algorithms based on find_allStephan Beyer, Feb 26, 2016
  26. 14/16 bisect: use a modified breadth-first search to find relevant weightsStephan Beyer, Feb 26, 2016
  27. Junio C HamanoFeb 26, 2016
  28. Stephan BeyerFeb 26, 2016
  29. 15/16 bisect: compute best bisection in compute_relevant_weights()Stephan Beyer, Feb 26, 2016
  30. 16/16 bisect: get back halfway shortcutStephan Beyer, Feb 26, 2016
  31. Pranit BauvaMar 20, 2016
  32. Stephan BeyerMar 21, 2016
  33. Christian CouderMar 22, 2016
  34. Pranit BauvaMar 22, 2016

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.