commit-slab-impl.hon commit commit: add repository argument to lookup_commit_reference (2122f67)
   1#ifndef COMMIT_SLAB_IMPL_H
   2#define COMMIT_SLAB_IMPL_H
   3
   4#define MAYBE_UNUSED __attribute__((__unused__))
   5
   6#define implement_static_commit_slab(slabname, elemtype) \
   7        implement_commit_slab(slabname, elemtype, static MAYBE_UNUSED)
   8
   9#define implement_shared_commit_slab(slabname, elemtype) \
  10        implement_commit_slab(slabname, elemtype, )
  11
  12#define implement_commit_slab(slabname, elemtype, scope)                \
  13                                                                        \
  14static int stat_ ##slabname## realloc;                                  \
  15                                                                        \
  16scope void init_ ##slabname## _with_stride(struct slabname *s,          \
  17                                                   unsigned stride)     \
  18{                                                                       \
  19        unsigned int elem_size;                                         \
  20        if (!stride)                                                    \
  21                stride = 1;                                             \
  22        s->stride = stride;                                             \
  23        elem_size = sizeof(elemtype) * stride;                          \
  24        s->slab_size = COMMIT_SLAB_SIZE / elem_size;                    \
  25        s->slab_count = 0;                                              \
  26        s->slab = NULL;                                                 \
  27}                                                                       \
  28                                                                        \
  29scope void init_ ##slabname(struct slabname *s)                         \
  30{                                                                       \
  31        init_ ##slabname## _with_stride(s, 1);                          \
  32}                                                                       \
  33                                                                        \
  34scope void clear_ ##slabname(struct slabname *s)                        \
  35{                                                                       \
  36        unsigned int i;                                                 \
  37        for (i = 0; i < s->slab_count; i++)                             \
  38                free(s->slab[i]);                                       \
  39        s->slab_count = 0;                                              \
  40        FREE_AND_NULL(s->slab);                                         \
  41}                                                                       \
  42                                                                        \
  43scope elemtype *slabname## _at_peek(struct slabname *s,                 \
  44                                                  const struct commit *c, \
  45                                                  int add_if_missing)   \
  46{                                                                       \
  47        unsigned int nth_slab, nth_slot;                                \
  48                                                                        \
  49        nth_slab = c->index / s->slab_size;                             \
  50        nth_slot = c->index % s->slab_size;                             \
  51                                                                        \
  52        if (s->slab_count <= nth_slab) {                                \
  53                unsigned int i;                                         \
  54                if (!add_if_missing)                                    \
  55                        return NULL;                                    \
  56                REALLOC_ARRAY(s->slab, nth_slab + 1);                   \
  57                stat_ ##slabname## realloc++;                           \
  58                for (i = s->slab_count; i <= nth_slab; i++)             \
  59                        s->slab[i] = NULL;                              \
  60                s->slab_count = nth_slab + 1;                           \
  61        }                                                               \
  62        if (!s->slab[nth_slab]) {                                       \
  63                if (!add_if_missing)                                    \
  64                        return NULL;                                    \
  65                s->slab[nth_slab] = xcalloc(s->slab_size,               \
  66                                            sizeof(**s->slab) * s->stride);             \
  67        }                                                               \
  68        return &s->slab[nth_slab][nth_slot * s->stride];                \
  69}                                                                       \
  70                                                                        \
  71scope elemtype *slabname## _at(struct slabname *s,                      \
  72                                             const struct commit *c)    \
  73{                                                                       \
  74        return slabname##_at_peek(s, c, 1);                             \
  75}                                                                       \
  76                                                                        \
  77scope elemtype *slabname## _peek(struct slabname *s,                    \
  78                                             const struct commit *c)    \
  79{                                                                       \
  80        return slabname##_at_peek(s, c, 0);                             \
  81}                                                                       \
  82                                                                        \
  83struct slabname
  84
  85/*
  86 * Note that this redundant forward declaration is required
  87 * to allow a terminating semicolon, which makes instantiations look
  88 * like function declarations.  I.e., the expansion of
  89 *
  90 *    implement_commit_slab(indegree, int, static);
  91 *
  92 * ends in 'struct indegree;'.  This would otherwise
  93 * be a syntax error according (at least) to ISO C.  It's hard to
  94 * catch because GCC silently parses it by default.
  95 */
  96
  97#endif  /* COMMIT_SLAB_IMPL_H */