Skip to content

Commit a9f1f1f

Browse files
pcloudsgitster
authored andcommitted
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 <[email protected]>
1 parent ccdcbd5 commit a9f1f1f

File tree

3 files changed

+127
-109
lines changed

3 files changed

+127
-109
lines changed

commit-slab-decl.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 6 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#ifndef COMMIT_SLAB_H
22
#define COMMIT_SLAB_H
33

4+
#include "commit-slab-decl.h"
5+
#include "commit-slab-impl.h"
6+
47
/*
58
* define_commit_slab(slabname, elemtype) creates boilerplate code to define
69
* a new struct (struct slabname) that is used to associate a piece of data
@@ -41,114 +44,8 @@
4144
* leaking memory.
4245
*/
4346

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)
15350

15451
#endif /* COMMIT_SLAB_H */

0 commit comments

Comments
 (0)