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

Re: cleaner/better zlib sources?

From
Shawn O. Pearce <spearce@spearce.org>
Date
Mar 17, 2007, 05:19 UTC
Message-ID
<20070317051921.GA5731@spearce.org>
In-Reply-To
<alpine.LFD.0.83.0703162257560.18328@xanadu.home>
Nicolas Pitre <nico@cam.org> wrote:
Show 9 quoted lines
> On Fri, 16 Mar 2007, Linus Torvalds wrote:
> > I also didn't worry about it, because I felt that if it became a problem, 
> > it would be easy to just add a cache of base objects (we probably do *not* 
> > want to keep the whole unpacked object info in memory all the time just 
> > because of memory pressure issues, so "cache of base objects" is better). 
> > However, the "pack file + offset" thing makes it harder to do, since we 
> > now don't even have the SHA1 of the base object before we unpack it.
> > 
> > But I guess we could just index this by a <packfile, offset> tuple.
...
> Then it would only be a matter of coming up with a clever cache 
> eviction algorithm.

Yes. Linus above seems to imply (at least to me) that we wouldn't want to cache the original object requested by read_sha1_file(), as its not the delta base. But given our packing rules, we should be (in general anyway) first asking for the most recent revision of a file, which is stored whole, then for an older revision, which will be a delta of the more recent revision we just saw.

Hence we probably would want to cache an object.  Well, at least
anything that had been packed as a delta.  Caching a deflated
OBJ_BLOB may not be worth it.
 
Show 5 quoted lines
> > Anyway, I bet that this is a much bigger issue than the pack format 
> > itself (and is largely independent).
> 
> Well, I think the pack format issue is significant too.  But because 
> those are independent issues the gain in performance will be additive.
I'm torn there.

There's two places that we do lots of unpacks of objects where we run into this difficult case of unpacking the same base object many times: git-blame and a rev-list with a path limiter.

Now the git-blame case is obvious: we are constantly unpacking various revisions of the same file, and these are probably delta'd against each other, so the unpacking gets really brutal after a while. A blob cache here would probably *really* help out git-blame.

What's slightly less obvious about git-blame is we are probably also traversing the different versions of the same trees over and over, as we resolve the path to the correct blob in each commit we traverse. So again here we are hitting lots of the same trees multiple times.

That last part about git-blame also obviously applies to the rev-list with a path limiter.

But most other operations don't seem like they would benefit from a base object cache; actually they might slow down from having such a cache present!

Commits tend not to delta well; if they delta it is a very rare occurrance. So we aren't getting huge unpacking benefits there by caching them. Scratch any benefit of the cache for any sort of rev-list operation that doesn't require tree access.

As for the other common operations (diff, read-tree, checkout-index, merge-recursive): I don't think these will benefit from a cache either. Their data access patterns are pretty spread out over the tree. With the exception of rename detection we hit everything only once. After touching a path, we tend to not go back to it. So unless we are really lucky and one blob acts as a base object for many others at different paths (possible, but I suspect not very likely) its not worth caching the base.

If we do hit something twice, its probably because we are doing two distinct passes over the data. In this case the passes are probably because we either don't want to hold all of the data in memory (too big of a set for some projects) or because we tried one algorithm, failed, and are now trying a different one (internal read-tree in merge-recursive).

Caching in merge-recursive may help, but just making the dirty cache (index) that resulted from the internal read-tree available for the remainder of the merge-recursive process might be faster; especially if we only have one base and don't need to recursively merge multiple bases.

So where does that leave us? The only places I see a base object cache really helping is in git-blame for blob access, repeated tree access (git-blame and path limiting), and maybe we could do better with the common cases in merge-recursive by being smarter with the cache.

But with pack v4 I don't think I need a tree object cache. With a 6 byte fixed record format, a strict ordering requirement, a finite delta depth within a packfile, a stricter tree-specific delta encoder, and a minor API change to tree-walk.h, I think we can unpack the delta at the same time that we are walking the tree. No upfront unpack required. Hence no reason to cache.

So yea, a base object cache may help us today. It will most definately help in git-blame. But I doubt it will help with trees in pack v4, and I think it will just hurt in most cases. So maybe it should be local to git-blame only.

-- 
Shawn.
Previous: Nicolas PitreNext: Linus Torvalds
Message 17 of 79 in “cleaner/better zlib sources?”
  1. Linus TorvaldsMar 16, 2007
  2. Shawn O. PearceMar 16, 2007
  3. Jeff GarzikMar 16, 2007
  4. Matt MackallMar 16, 2007
  5. Linus TorvaldsMar 16, 2007
  6. Linus TorvaldsMar 16, 2007
  7. Davide LibenziMar 16, 2007
  8. Linus TorvaldsMar 16, 2007
  9. Davide LibenziMar 16, 2007
  10. Linus TorvaldsMar 16, 2007
  11. Davide LibenziMar 16, 2007
  12. Linus TorvaldsMar 16, 2007
  13. Davide LibenziMar 16, 2007
  14. Linus TorvaldsMar 17, 2007
  15. Linus TorvaldsMar 17, 2007
  16. Nicolas PitreMar 17, 2007
  17. Shawn O. PearceMar 17, 2007
  18. Linus TorvaldsMar 17, 2007
  19. Linus TorvaldsMar 17, 2007
  20. 1/2 Make trivial wrapper functions around delta base generation and freeingLinus Torvalds, Mar 17, 2007
  21. 2/2 Implement a simple delta_base cacheLinus Torvalds, Mar 17, 2007
  22. Linus TorvaldsMar 17, 2007
  23. Junio C HamanoMar 17, 2007
  24. Linus TorvaldsMar 17, 2007
  25. Linus TorvaldsMar 17, 2007
  26. Nicolas PitreMar 18, 2007
  27. Junio C HamanoMar 18, 2007
  28. Junio C HamanoMar 17, 2007
  29. Linus TorvaldsMar 17, 2007
  30. Jon SmirlMar 17, 2007
  31. Morten WelinderMar 18, 2007
  32. Linus TorvaldsMar 18, 2007
  33. Nicolas PitreMar 18, 2007
  34. Linus TorvaldsMar 18, 2007
  35. Nicolas PitreMar 18, 2007
  36. Linus TorvaldsMar 18, 2007
  37. Nicolas PitreMar 18, 2007
  38. Linus TorvaldsMar 18, 2007
  39. Julian PhillipsMar 18, 2007
  40. Linus TorvaldsMar 18, 2007
  41. Robin RosenbergMar 18, 2007
  42. Linus TorvaldsMar 18, 2007
  43. Robin RosenbergMar 18, 2007
  44. Shawn O. PearceMar 18, 2007
  45. David BrodskyMar 19, 2007
  46. Robin RosenbergMar 20, 2007
  47. David BrodskyMar 20, 2007
  48. Linus TorvaldsMar 21, 2007
  49. Nicolas PitreMar 21, 2007
  50. 3/2 Avoid unnecessary strlen() callsLinus Torvalds, Mar 18, 2007
  51. Junio C HamanoMar 18, 2007
  52. Linus TorvaldsMar 18, 2007
  53. Linus TorvaldsMar 18, 2007
  54. Shawn O. PearceMar 18, 2007
  55. Linus TorvaldsMar 18, 2007
  56. Johannes SchindelinMar 20, 2007
  57. Shawn O. PearceMar 20, 2007
  58. Shawn O. PearceMar 20, 2007
  59. Linus TorvaldsMar 20, 2007
  60. Shawn O. PearceMar 20, 2007
  61. Linus TorvaldsMar 20, 2007
  62. Junio C HamanoMar 20, 2007
  63. Junio C HamanoMar 20, 2007
  64. Linus TorvaldsMar 20, 2007
  65. Shawn O. PearceMar 20, 2007
  66. Linus TorvaldsMar 20, 2007
  67. Linus TorvaldsMar 18, 2007
  68. Avi KivityMar 18, 2007
  69. Linus TorvaldsMar 17, 2007
  70. Jeff GarzikMar 16, 2007
  71. Matt MackallMar 16, 2007
  72. Linus TorvaldsMar 16, 2007
  73. Nicolas PitreMar 16, 2007
  74. Shawn O. PearceMar 16, 2007
  75. Nicolas PitreMar 16, 2007
  76. Linus TorvaldsMar 16, 2007
  77. Nicolas PitreMar 16, 2007
  78. Davide LibenziMar 16, 2007
  79. Davide LibenziMar 16, 2007

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.