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

Re: [PATCH on sb/more-repo-in-api] revision: use commit graph in get_reference()

From
Derrick Stolee <stolee@gmail.com>
Date
Dec 7, 2018, 13:49 UTC
Message-ID
<aa0cd481-c135-47aa-2a69-e3dc71661caa@gmail.com>
In-Reply-To
<20181206233626.144072-1-jonathantanmy@google.com>
On 12/6/2018 6:36 PM, Jonathan Tan wrote:
Show 17 quoted lines
>> AFAICT oid_object_info doesn't take advantage of the commit graph,
>> but just looks up the object header, which is still less than completely
>> parsing it. Then lookup_commit is overly strict, as it may return
>> NULL as when there still is a type mismatch (I don't think a mismatch
>> could happen here, as both rely on just the object store, and not the
>> commit graph.), so this would be just defensive programming for
>> the sake of it. I dunno.
>>
>>      struct commit *c;
>>
>>      if (oid_object_info(revs->repo, oid, NULL) == OBJ_COMMIT &&
>>          (c = lookup_commit(revs->repo, oid)) &&
>>          !repo_parse_commit(revs->repo, c))
>>              object = (struct object *) c;
>>      else
>>          object = parse_object(revs->repo, oid);
> I like this way better - I'll do it in the next version.

If we do _not_ have a commit-graph or if the commit-graph does not have that commit, this will have the same performance problem, right?

Should we instead create a direct dependence on the commit-graph, and try to parse the oid from the graph directly? If it succeeds, then we learn that the object is a commit, in addition to all of the parsing work. This means we could avoid oid_object_info() loading data if we succeed. We would fall back to parse_object() if it fails.

I was thinking this should be a simple API call to parse_commit_in_graph(), but that requires a struct commit filled with an oid, which is not the best idea if we don't actually know it is a commit yet.

The approach I recommend would then be more detailed:
1. Modify find_commit_in_graph() to take a struct object_id instead of a
    struct commit. This helps find the integer position in the graph. That
    position can be used in fill_commit_in_graph() to load the commit
    contents. Keep find_commit_in_graph() static as it should not be a
    public function.
2. Create a public function with prototype

struct commit *try_parse_commit_from_graph(struct repository *r, struct object_id *oid)

    that returns a commit struct fully parsed if and only if the repository
    has that oid. It can call find_commit_in_graph(), then 
lookup_commit() and
    fill_commit_in_graph() to create the commit and parse the data.
3. In replace of the snippet above, do:
     struct commit *c;
     if ((c = try_parse_commit_from_graph(revs->repo, oid))
         object = (struct object *)c;
     else
         object = parse_object(revs->repo, oid);

A similar pattern _could_ be used in parse_object(), but I don't recommend doing this pattern unless we have a reasonable suspicion that we are going to parse commits more often than other objects. (It adds an O(log(# commits)) binary search to each object.)

A final thought: consider making this "try the commit graph first, but fall back to parse_object()" a library function with a name like

     struct object *parse_probably_commit(struct repository *r, struct 
object_id *oid)

so other paths that are parsing a lot of commits (but also maybe tags) could use the logic.

Thanks! -Stolee

Previous: Jonathan TanNext: Jeff King
Message 4 of 28 in “revision: use commit graph in get_reference()”
  1. revision: use commit graph in get_reference()Jonathan Tan, Dec 4, 2018
  2. Stefan BellerDec 4, 2018
  3. Jonathan TanDec 6, 2018
  4. Derrick StoleeDec 7, 2018
  5. Jeff KingDec 5, 2018
  6. Jonathan TanDec 6, 2018
  7. Jeff KingDec 7, 2018
  8. Junio C HamanoDec 5, 2018
  9. revision: use commit graph in get_reference()Jonathan Tan, Dec 7, 2018
  10. Junio C HamanoDec 9, 2018
  11. Junio C HamanoDec 9, 2018
  12. Jeff KingDec 11, 2018
  13. Jonathan TanDec 12, 2018
  14. Jeff KingDec 13, 2018
  15. Derrick StoleeDec 13, 2018
  16. revision: use commit graph in get_reference()Jonathan Tan, Dec 13, 2018
  17. Junio C HamanoDec 14, 2018
  18. Jeff KingDec 14, 2018
  19. Regression in: [PATCH on sb/more-repo-in-api] revision: use commit graph in get_reference()SZEDER Gábor, Jan 25, 2019
  20. Stefan BellerJan 25, 2019
  21. Jonathan TanJan 25, 2019
  22. SZEDER GáborJan 25, 2019
  23. SZEDER GáborJan 25, 2019
  24. object_as_type: initialize commit-graph-related fields of 'struct commit'SZEDER Gábor, Jan 27, 2019
  25. SZEDER GáborJan 27, 2019
  26. Derrick StoleeJan 27, 2019
  27. Jonathan TanJan 28, 2019
  28. Jeff KingJan 28, 2019

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.