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 */