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

Re: [PATCH 3/3] commit-slab: introduce a macro to define a slab for new type

From
Jeff King <peff@peff.net>
Date
Apr 14, 2013, 18:41 UTC
Message-ID
<20130414184121.GA1621@sigill.intra.peff.net>
In-Reply-To
<1365919489-17553-4-git-send-email-gitster@pobox.com>
On Sat, Apr 13, 2013 at 11:04:49PM -0700, Junio C Hamano wrote:
Show 20 quoted lines
> Suppose you want to give one bit per existing ref and paint commits
> down to find which refs are descendants of each commit. You find
> that you have 320 refs only at runtime.
> 
> The code can declare a commit slab "struct flagbits"
> 
> 	define_commit_slab(flagbits, unsigned char);
> 	struct flagbits flags;
> 
> and initialize it by:
> 
> 	nrefs = ... count number of refs that returns say 320 ...
> 	init_flagbits_with_stride(&flags, (nrefs + 7) / 8);
> 
> so that
> 
> 	unsigned char *fp = flagbits_at(&flags, commit);
> 
> will return a pointer pointing at an array of 40 "unsigned char"s
> associated with the commit.

Thanks, I was thinking originally that we would want to break it down into "unsigned long" or something, but there is probably no real performance advantage to doing that over bytes.

I'd probably further wrap it with a flagbit_set and flagbit_tst to wrap the "figure out which byte, then which bit of that byte" logic, but that would be a wrapper around flagbits_at, anyway. It can come later.

Show 23 quoted lines
> +static elemtype *slabname## _at(struct slabname *s,			\
> +				const struct commit *c)			\
> +{									\
> +	int nth_slab, nth_slot, ix;					\
> +									\
> +	ix = c->index * s->stride;					\
> +	nth_slab = ix / s->slab_size;					\
> +	nth_slot = ix % s->slab_size;					\
> +									\
> +	if (s->slab_count <= nth_slab) {				\
> +		int i;							\
> +		s->slab = xrealloc(s->slab,				\
> +				   (nth_slab + 1) * sizeof(s->slab));	\
> +		stat_ ##slabname## realloc++;				\
> +		for (i = s->slab_count; i <= nth_slab; i++)		\
> +			s->slab[i] = NULL;				\
> +		s->slab_count = nth_slab + 1;				\
> +	}								\
> +	if (!s->slab[nth_slab])						\
> +		s->slab[nth_slab] = xcalloc(s->slab_size,		\
> +					    sizeof(**s->slab));		\
> +	return &s->slab[nth_slab][nth_slot];				\
> +}									\

We'd probably want the hot path of this (returning the actual pointer) to be inline, but not necessarily the parts about growing, which should trigger a lot less. It may make sense to split the conditional bodies out into a sub-function. And do we want to mark it with "inline"?

-Peff
Previous: Junio C HamanoNext: Junio C Hamano
Message 11 of 12 in “Using commit slab to replace indegree”
  1. 0/3 Using commit slab to replace indegreeJunio C Hamano, Apr 14, 2013
  2. 1/3 commit: allow associating auxiliary info on-demandJunio C Hamano, Apr 14, 2013
  3. Jeff KingApr 14, 2013
  4. Junio C HamanoApr 14, 2013
  5. 2/3 commit-slab: avoid large reallocJunio C Hamano, Apr 14, 2013
  6. Jeff KingApr 14, 2013
  7. Junio C HamanoApr 14, 2013
  8. Jeff KingApr 14, 2013
  9. Junio C HamanoApr 15, 2013
  10. 3/3 commit-slab: introduce a macro to define a slab for new typeJunio C Hamano, Apr 14, 2013
  11. Jeff KingApr 14, 2013
  12. Junio C HamanoApr 15, 2013

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.