commit-slab.h: code split

The struct declaration and implementation macros are moved to commit-slab-hdr.h and commit-slab-impl.h respectively. This right now is not needed for current users but if we make a public commit-slab type, we may want to avoid including the slab implementation in a header file which gets replicated in every c file that includes it. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed May 19, 2018 at 07:28 UTC a9f1f1f9f8b2873c43d6100717eb776ea288ed9e
3 files changed +127 -109
commit-slab-decl.h new
+30
@@ -0,0 +1,30 @@
1 +#ifndef COMMIT_SLAB_HDR_H
2 +#define COMMIT_SLAB_HDR_H
3 +
4 +/* allocate ~512kB at once, allowing for malloc overhead */
5 +#ifndef COMMIT_SLAB_SIZE
6 +#define COMMIT_SLAB_SIZE (512*1024-32)
7 +#endif
8 +
9 +#define declare_commit_slab(slabname, elemtype) \
10 + \
11 +struct slabname { \
12 + unsigned slab_size; \
13 + unsigned stride; \
14 + unsigned slab_count; \
15 + elemtype **slab; \
16 +}
17 +
18 +/*
19 + * Statically initialize a commit slab named "var". Note that this
20 + * evaluates "stride" multiple times! Example:
21 + *
22 + * struct indegree indegrees = COMMIT_SLAB_INIT(1, indegrees);
23 + *
24 + */
25 +#define COMMIT_SLAB_INIT(stride, var) { \
26 + COMMIT_SLAB_SIZE / sizeof(**((var).slab)) / (stride), \
27 + (stride), 0, NULL \
28 +}
29 +
30 +#endif /* COMMIT_SLAB_HDR_H */
commit-slab-impl.h new
+91
@@ -0,0 +1,91 @@
1 +#ifndef COMMIT_SLAB_IMPL_H
2 +#define COMMIT_SLAB_IMPL_H
3 +
4 +#define MAYBE_UNUSED __attribute__((__unused__))
5 +
6 +#define implement_commit_slab(slabname, elemtype) \
7 + \
8 +static int stat_ ##slabname## realloc; \
9 + \
10 +static MAYBE_UNUSED void init_ ##slabname## _with_stride(struct slabname *s, \
11 + unsigned stride) \
12 +{ \
13 + unsigned int elem_size; \
14 + if (!stride) \
15 + stride = 1; \
16 + s->stride = stride; \
17 + elem_size = sizeof(elemtype) * stride; \
18 + s->slab_size = COMMIT_SLAB_SIZE / elem_size; \
19 + s->slab_count = 0; \
20 + s->slab = NULL; \
21 +} \
22 + \
23 +static MAYBE_UNUSED void init_ ##slabname(struct slabname *s) \
24 +{ \
25 + init_ ##slabname## _with_stride(s, 1); \
26 +} \
27 + \
28 +static MAYBE_UNUSED void clear_ ##slabname(struct slabname *s) \
29 +{ \
30 + unsigned int i; \
31 + for (i = 0; i < s->slab_count; i++) \
32 + free(s->slab[i]); \
33 + s->slab_count = 0; \
34 + FREE_AND_NULL(s->slab); \
35 +} \
36 + \
37 +static MAYBE_UNUSED elemtype *slabname## _at_peek(struct slabname *s, \
38 + const struct commit *c, \
39 + int add_if_missing) \
40 +{ \
41 + unsigned int nth_slab, nth_slot; \
42 + \
43 + nth_slab = c->index / s->slab_size; \
44 + nth_slot = c->index % s->slab_size; \
45 + \
46 + if (s->slab_count <= nth_slab) { \
47 + unsigned int i; \
48 + if (!add_if_missing) \
49 + return NULL; \
50 + REALLOC_ARRAY(s->slab, nth_slab + 1); \
51 + stat_ ##slabname## realloc++; \
52 + for (i = s->slab_count; i <= nth_slab; i++) \
53 + s->slab[i] = NULL; \
54 + s->slab_count = nth_slab + 1; \
55 + } \
56 + if (!s->slab[nth_slab]) { \
57 + if (!add_if_missing) \
58 + return NULL; \
59 + s->slab[nth_slab] = xcalloc(s->slab_size, \
60 + sizeof(**s->slab) * s->stride); \
61 + } \
62 + return &s->slab[nth_slab][nth_slot * s->stride]; \
63 +} \
64 + \
65 +static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s, \
66 + const struct commit *c) \
67 +{ \
68 + return slabname##_at_peek(s, c, 1); \
69 +} \
70 + \
71 +static MAYBE_UNUSED elemtype *slabname## _peek(struct slabname *s, \
72 + const struct commit *c) \
73 +{ \
74 + return slabname##_at_peek(s, c, 0); \
75 +} \
76 + \
77 +struct slabname
78 +
79 +/*
80 + * Note that this redundant forward declaration is required
81 + * to allow a terminating semicolon, which makes instantiations look
82 + * like function declarations. I.e., the expansion of
83 + *
84 + * implement_commit_slab(indegree, int);
85 + *
86 + * ends in 'struct indegree;'. This would otherwise
87 + * be a syntax error according (at least) to ISO C. It's hard to
88 + * catch because GCC silently parses it by default.
89 + */
90 +
91 +#endif /* COMMIT_SLAB_IMPL_H */
commit-slab.h
+6 -109
@@ -1,6 +1,9 @@
1 #ifndef COMMIT_SLAB_H
2 #define COMMIT_SLAB_H
3
4 +#include "commit-slab-decl.h"
5 +#include "commit-slab-impl.h"
6 +
7 /*
8 * define_commit_slab(slabname, elemtype) creates boilerplate code to define
9 * a new struct (struct slabname) that is used to associate a piece of data
@@ -41,114 +44,8 @@
44 * leaking memory.
45 */
46
44 -/* allocate ~512kB at once, allowing for malloc overhead */
45 -#ifndef COMMIT_SLAB_SIZE
46 -#define COMMIT_SLAB_SIZE (512*1024-32)
47 -#endif
48 -
49 -#define MAYBE_UNUSED __attribute__((__unused__))
50 -
51 -#define define_commit_slab(slabname, elemtype) \
52 - \
53 -struct slabname { \
54 - unsigned slab_size; \
55 - unsigned stride; \
56 - unsigned slab_count; \
57 - elemtype **slab; \
58 -}; \
59 -static int stat_ ##slabname## realloc; \
60 - \
61 -static MAYBE_UNUSED void init_ ##slabname## _with_stride(struct slabname *s, \
62 - unsigned stride) \
63 -{ \
64 - unsigned int elem_size; \
65 - if (!stride) \
66 - stride = 1; \
67 - s->stride = stride; \
68 - elem_size = sizeof(elemtype) * stride; \
69 - s->slab_size = COMMIT_SLAB_SIZE / elem_size; \
70 - s->slab_count = 0; \
71 - s->slab = NULL; \
72 -} \
73 - \
74 -static MAYBE_UNUSED void init_ ##slabname(struct slabname *s) \
75 -{ \
76 - init_ ##slabname## _with_stride(s, 1); \
77 -} \
78 - \
79 -static MAYBE_UNUSED void clear_ ##slabname(struct slabname *s) \
80 -{ \
81 - unsigned int i; \
82 - for (i = 0; i < s->slab_count; i++) \
83 - free(s->slab[i]); \
84 - s->slab_count = 0; \
85 - FREE_AND_NULL(s->slab); \
86 -} \
87 - \
88 -static MAYBE_UNUSED elemtype *slabname## _at_peek(struct slabname *s, \
89 - const struct commit *c, \
90 - int add_if_missing) \
91 -{ \
92 - unsigned int nth_slab, nth_slot; \
93 - \
94 - nth_slab = c->index / s->slab_size; \
95 - nth_slot = c->index % s->slab_size; \
96 - \
97 - if (s->slab_count <= nth_slab) { \
98 - unsigned int i; \
99 - if (!add_if_missing) \
100 - return NULL; \
101 - REALLOC_ARRAY(s->slab, nth_slab + 1); \
102 - stat_ ##slabname## realloc++; \
103 - for (i = s->slab_count; i <= nth_slab; i++) \
104 - s->slab[i] = NULL; \
105 - s->slab_count = nth_slab + 1; \
106 - } \
107 - if (!s->slab[nth_slab]) { \
108 - if (!add_if_missing) \
109 - return NULL; \
110 - s->slab[nth_slab] = xcalloc(s->slab_size, \
111 - sizeof(**s->slab) * s->stride); \
112 - } \
113 - return &s->slab[nth_slab][nth_slot * s->stride]; \
114 -} \
115 - \
116 -static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s, \
117 - const struct commit *c) \
118 -{ \
119 - return slabname##_at_peek(s, c, 1); \
120 -} \
121 - \
122 -static MAYBE_UNUSED elemtype *slabname## _peek(struct slabname *s, \
123 - const struct commit *c) \
124 -{ \
125 - return slabname##_at_peek(s, c, 0); \
126 -} \
127 - \
128 -struct slabname
129 -
130 -/*
131 - * Note that this redundant forward declaration is required
132 - * to allow a terminating semicolon, which makes instantiations look
133 - * like function declarations. I.e., the expansion of
134 - *
135 - * define_commit_slab(indegree, int);
136 - *
137 - * ends in 'struct indegree;'. This would otherwise
138 - * be a syntax error according (at least) to ISO C. It's hard to
139 - * catch because GCC silently parses it by default.
140 - */
141 -
142 -/*
143 - * Statically initialize a commit slab named "var". Note that this
144 - * evaluates "stride" multiple times! Example:
145 - *
146 - * struct indegree indegrees = COMMIT_SLAB_INIT(1, indegrees);
147 - *
148 - */
149 -#define COMMIT_SLAB_INIT(stride, var) { \
150 - COMMIT_SLAB_SIZE / sizeof(**((var).slab)) / (stride), \
151 - (stride), 0, NULL \
152 -}
47 +#define define_commit_slab(slabname, elemtype) \
48 + declare_commit_slab(slabname, elemtype); \
49 + implement_commit_slab(slabname, elemtype)
50
51 #endif /* COMMIT_SLAB_H */