#ifndef COMMIT_SLAB_IMPL_H
#define COMMIT_SLAB_IMPL_H

#define implement_static_commit_slab(slabname, elemtype) \
	implement_commit_slab(slabname, elemtype, MAYBE_UNUSED static)

#define implement_shared_commit_slab(slabname, elemtype) \
	implement_commit_slab(slabname, elemtype, )

#define implement_commit_slab(slabname, elemtype, scope)		\
									\
scope void init_ ##slabname## _with_stride(struct slabname *s,		\
						   unsigned stride)	\
{									\
	unsigned int elem_size;						\
	if (!stride)							\
		stride = 1;						\
	s->stride = stride;						\
	elem_size = sizeof(elemtype) * stride;				\
	s->slab_size = COMMIT_SLAB_SIZE / elem_size;			\
	s->slab_count = 0;						\
	s->slab = NULL;							\
}									\
									\
scope void init_ ##slabname(struct slabname *s)				\
{									\
	init_ ##slabname## _with_stride(s, 1);				\
}									\
									\
scope void clear_ ##slabname(struct slabname *s)			\
{									\
	unsigned int i;							\
	for (i = 0; i < s->slab_count; i++)				\
		free(s->slab[i]);					\
	s->slab_count = 0;						\
	FREE_AND_NULL(s->slab);						\
}									\
									\
scope void deep_clear_ ##slabname(struct slabname *s, void (*free_fn)(elemtype *)) \
{									\
	unsigned int i;							\
	for (i = 0; i < s->slab_count; i++) {				\
		unsigned int j;						\
		if (!s->slab[i])					\
			continue;					\
		for (j = 0; j < s->slab_size; j++)			\
			free_fn(&s->slab[i][j * s->stride]);		\
	}								\
	clear_ ##slabname(s);						\
}									\
									\
scope elemtype *slabname## _at_peek(struct slabname *s,			\
						  const struct commit *c, \
						  int add_if_missing)   \
{									\
	unsigned int nth_slab, nth_slot;				\
									\
	nth_slab = c->index / s->slab_size;				\
	nth_slot = c->index % s->slab_size;				\
									\
	if (s->slab_count <= nth_slab) {				\
		unsigned int i;						\
		if (!add_if_missing)					\
			return NULL;					\
		REALLOC_ARRAY(s->slab, nth_slab + 1);			\
		for (i = s->slab_count; i <= nth_slab; i++)		\
			s->slab[i] = NULL;				\
		s->slab_count = nth_slab + 1;				\
	}								\
	if (!s->slab[nth_slab]) {					\
		if (!add_if_missing)					\
			return NULL;					\
		s->slab[nth_slab] = xcalloc(s->slab_size,		\
					    sizeof(**s->slab) * s->stride);		\
	}								\
	return &s->slab[nth_slab][nth_slot * s->stride];		\
}									\
									\
scope elemtype *slabname## _at(struct slabname *s,			\
					     const struct commit *c)	\
{									\
	return slabname##_at_peek(s, c, 1);				\
}									\
									\
scope elemtype *slabname## _peek(struct slabname *s,			\
					     const struct commit *c)	\
{									\
	return slabname##_at_peek(s, c, 0);				\
}									\
									\
struct slabname

/*
 * Note that this redundant forward declaration is required
 * to allow a terminating semicolon, which makes instantiations look
 * like function declarations.  I.e., the expansion of
 *
 *    implement_commit_slab(indegree, int, static);
 *
 * ends in 'struct indegree;'.  This would otherwise
 * be a syntax error according (at least) to ISO C.  It's hard to
 * catch because GCC silently parses it by default.
 */

#endif	/* COMMIT_SLAB_IMPL_H */
