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

Re: [PATCH 6/6] Retain caches of submodule refs

From
Heiko Voigt <hvoigt@hvoigt.net>
Date
Aug 24, 2011, 20:05 UTC
Message-ID
<20110824200520.GE45292@book.hvoigt.net>
In-Reply-To
<4E54B394.2070006@alum.mit.edu>
On Wed, Aug 24, 2011 at 10:17:24AM +0200, Michael Haggerty wrote:
Show 40 quoted lines
> On 08/13/2011 02:54 PM, Heiko Voigt wrote:
> > On Sat, Aug 13, 2011 at 12:36:29AM +0200, Michael Haggerty wrote:
> >> diff --git a/refs.c b/refs.c
> >> index 8d1055d..f02cf94 100644
> >> --- a/refs.c
> >> +++ b/refs.c
> > 
> > ...
> > 
> >> @@ -205,23 +208,28 @@ struct cached_refs *create_cached_refs(const char *submodule)
> >>   */
> >>  static struct cached_refs *get_cached_refs(const char *submodule)
> >>  {
> >> -	if (! submodule) {
> >> -		if (!cached_refs)
> >> -			cached_refs = create_cached_refs(submodule);
> >> -		return cached_refs;
> >> -	} else {
> >> -		if (!submodule_refs)
> >> -			submodule_refs = create_cached_refs(submodule);
> >> -		else
> >> -			/* For now, don't reuse the refs cache for submodules. */
> >> -			clear_cached_refs(submodule_refs);
> >> -		return submodule_refs;
> >> +	struct cached_refs *refs = cached_refs;
> >> +	if (! submodule)
> >> +		submodule = "";
> > 
> > Maybe instead of searching for the main refs store a pointer to them
> > locally so you can immediately return here. That will keep the
> > performance when requesting the main refs the same.
> 
> I am assuming that the number of submodules will be small compared to
> the number of refs in a typical submodule.  Therefore, given that the
> refs are stored in a big linked list and that the only thing that can
> realistically be done with the list is to iterate through it, the cost
> of finding the reference cache for a specific (sub-)module should be
> negligible compared to the cost of the iteration over refs in the cache.
>  Treating the main module like the other submodules makes the code
> simpler, so I would prefer to leave it this way.

I just thought I mention it since it is a change and you are already special casing the main module with this if(!submodule) but you are probably right and in most cases (many refs and few submodules) this change is negligible.

Show 22 quoted lines
> If iteration over refs ever becomes a bottleneck, then optimization of
> the storage of refs within a (sub-)module would be a bigger win than
> special-casing the main module.  And that is what I would like to work
> towards.
> 
> > If I see it correctly you are always prepending to the linked list 
> 
> This is true.
> 
> >                                                                    and
> > in case many submodules get cached this could slow down the iteration
> > over the refs of the main repository.
> 
> Is this a realistic concern?  Remember that the extra search over
> submodules only occurs once for each scan through the list of references.
> 
> I wrote an additional patch that moves the least-recently accessed
> module to the front of the list.  But I doubt that the savings justify
> the 10-odd extra lines of code, so I kept it to myself.  Please note
> that this approach gives pessimal performance (2x slower) if the
> submodules are iterated over repeatedly.  If you would like me to add
> this patch to the patch series, please let me know.
No I don't think this is necessary.
Show 11 quoted lines
> Long-term, it would be better to implement a "struct submodule" and use
> it to hold submodule-specific data like the ref cache.  Then users could
> hold on to the "struct submodule *" and pass it, rather than the
> submodule name, to the functions that need it.  But this goes beyond the
> scope of what I want to change now, especially since I have no
> experience even working with submodules.
> 
> Summary: I hope I have convinced you that the extra overhead is
> negligible and does not justify additional code.  But if you insist on
> more emphasis on performance (or obviously if you have numbers to back
> up your concerns) then I would be willing to put more work into it.

Yes I am also fine with the current state. I do not have a strong opinion about this. This already adds enough improvements of the submodule ref caching which looks a lot nicer than before.

Cheers Heiko
Previous: Michael HaggertyNext: Junio C Hamano
Message 13 of 54 in “Retain caches of submodule refs”
  1. 0/6 Retain caches of submodule refsMichael Haggerty, Aug 12, 2011
  2. 1/6 Extract a function clear_cached_refs()Michael Haggerty, Aug 12, 2011
  3. 2/6 Access reference caches only through new function get_cached_refs().Michael Haggerty, Aug 12, 2011
  4. Junio C HamanoAug 14, 2011
  5. Michael HaggertyAug 23, 2011
  6. 3/6 Change the signature of read_packed_refs()Michael Haggerty, Aug 12, 2011
  7. 4/6 Allocate cached_refs objects dynamicallyMichael Haggerty, Aug 12, 2011
  8. Junio C HamanoAug 14, 2011
  9. 5/6 Store the submodule name in struct cached_refs.Michael Haggerty, Aug 12, 2011
  10. 6/6 Retain caches of submodule refsMichael Haggerty, Aug 12, 2011
  11. Heiko VoigtAug 13, 2011
  12. Michael HaggertyAug 24, 2011
  13. Heiko VoigtAug 24, 2011
  14. Junio C HamanoAug 16, 2011
  15. Michael HaggertyAug 24, 2011
  16. Michael HaggertyOct 9, 2011
  17. Junio C HamanoOct 9, 2011
  18. 0/2 Provide API to invalidate refs cacheMichael Haggerty, Oct 10, 2011
  19. 1/2 invalidate_cached_refs(): take the submodule as parameterMichael Haggerty, Oct 10, 2011
  20. 2/2 invalidate_cached_refs(): expose this function in refs APIMichael Haggerty, Oct 10, 2011
  21. 0/7 Provide API to invalidate refs cacheMichael Haggerty, Oct 10, 2011
  22. 1/7 invalidate_ref_cache(): rename function from invalidate_cached_refs()Michael Haggerty, Oct 10, 2011
  23. Junio C HamanoOct 11, 2011
  24. Michael HaggertyOct 11, 2011
  25. 2/7 invalidate_ref_cache(): take the submodule as parameterMichael Haggerty, Oct 10, 2011
  26. 3/7 invalidate_ref_cache(): expose this function in refs APIMichael Haggerty, Oct 10, 2011
  27. 4/7 clear_cached_refs(): rename parameterMichael Haggerty, Oct 10, 2011
  28. 5/7 clear_cached_refs(): extract two new functionsMichael Haggerty, Oct 10, 2011
  29. 6/7 write_ref_sha1(): only invalidate the loose ref cacheMichael Haggerty, Oct 10, 2011
  30. 7/7 clear_cached_refs(): inline functionMichael Haggerty, Oct 10, 2011
  31. Junio C HamanoOct 11, 2011
  32. Michael HaggertyOct 11, 2011
  33. Julian PhillipsOct 11, 2011
  34. Junio C HamanoOct 11, 2011
  35. 0/7 Provide API to invalidate refs cacheMichael Haggerty, Oct 12, 2011
  36. 1/7 invalidate_ref_cache(): rename function from invalidate_cached_refs()Michael Haggerty, Oct 12, 2011
  37. Junio C HamanoOct 12, 2011
  38. Michael HaggertyOct 12, 2011
  39. 2/7 invalidate_ref_cache(): take the submodule as parameterMichael Haggerty, Oct 12, 2011
  40. Junio C HamanoOct 12, 2011
  41. Michael HaggertyOct 12, 2011
  42. Junio C HamanoOct 17, 2011
  43. Michael HaggertyNov 3, 2011
  44. Junio C HamanoNov 3, 2011
  45. 3/7 invalidate_ref_cache(): expose this function in refs APIMichael Haggerty, Oct 12, 2011
  46. 4/7 clear_cached_refs(): rename parameterMichael Haggerty, Oct 12, 2011
  47. 5/7 clear_cached_refs(): extract two new functionsMichael Haggerty, Oct 12, 2011
  48. 6/7 write_ref_sha1(): only invalidate the loose ref cacheMichael Haggerty, Oct 12, 2011
  49. 7/7 clear_cached_refs(): inline functionMichael Haggerty, Oct 12, 2011
  50. Junio C HamanoOct 12, 2011
  51. Heiko VoigtOct 10, 2011
  52. Michael HaggertyOct 11, 2011
  53. Heiko VoigtOct 11, 2011
  54. Heiko VoigtAug 13, 2011

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.