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

Re: [PATCH v4] unpack-trees: avoid duplicate ODB lookups during checkout

From
Jeff King <peff@peff.net>
Date
Apr 14, 2017, 19:52 UTC
Message-ID
<20170414195219.qmc4w46t7t6brlp4@sigill.intra.peff.net>
In-Reply-To
<20170414192554.26683-2-git@jeffhostetler.com>
On Fri, Apr 14, 2017 at 07:25:54PM +0000, git@jeffhostetler.com wrote:
Show 15 quoted lines
>  	for (i = 0; i < n; i++, dirmask >>= 1) {
> -		const unsigned char *sha1 = NULL;
> -		if (dirmask & 1)
> -			sha1 = names[i].oid->hash;
> -		buf[i] = fill_tree_descriptor(t+i, sha1);
> +		if (i > 0 && are_same_oid(&names[i], &names[i - 1]))
> +			t[i] = t[i - 1];
> +		else if (i > 1 && are_same_oid(&names[i], &names[i - 2]))
> +			t[i] = t[i - 2];
> +		else {
> +			const unsigned char *sha1 = NULL;
> +			if (dirmask & 1)
> +				sha1 = names[i].oid->hash;
> +			buf[nr_buf++] = fill_tree_descriptor(t+i, sha1);
> +		}
This looks fine to me.

Just musing (and I do not think we need to go further than your patch), we're slowly walking towards an actual object-content cache. The "buf" array is now essentially a cache of all oids we've loaded, but it doesn't know its sha1s. So we could actually encapsulate all of the caching:

  struct object_cache {
	  int nr_entries;
	  struct object_cache_entry {
		  struct object_id oid;
		  void *data;
	  } cache[MAX_UNPACK_TREES];
  };

and then ask it "have you seen oid X" rather than playing games with looking at "i - 1". Of course it would have to do a linear search, so the next step is to replace its array with a hashmap.

And now suddenly we have a reusable object-content cache that you could use like:

  struct object_cache = {0};
  for (...) {
    /* maybe reads fresh, or maybe gets it from the cache */
    void *data = read_object_data_cached(&oid, &cache);
  }
  /* operation done, release the cache */
  clear_object_cache(&cache);

which would work anywhere you expect to load N objects and see some overlap.

Of course it would be nicer still if this all just happened automatically behind the scenes of read_object_data(). But it would have to keep an _extra_ copy of each object, since the caller expects to be able to free it. We'd probably have to return instead a struct with buffer/size in it along with a reference counter.

I don't think any of that is worth it unless there are spots where we really expect there to be a lot of cases where we hit the same objects in rapid succession. I don't think there should be, though. Our usual "caching" mechanism is to create a "struct object", which is enough to perform most operations (and has a much smaller memory footprint).

So again, just musing. I think your patch is fine as-is.
-Peff
Previous: git@jeffhostetler.comNext: Jeff Hostetler
Message 3 of 4 in “unpack-trees: avoid duplicate ODB lookups during checkout”
  1. unpack-trees: avoid duplicate ODB lookups during checkoutgit@jeffhostetler.com, Apr 14, 2017
  2. unpack-trees: avoid duplicate ODB lookups during checkoutgit@jeffhostetler.com, Apr 14, 2017
  3. Jeff KingApr 14, 2017
  4. Jeff HostetlerApr 14, 2017

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.