2 * alloc.c - specialized allocator for internal objects
4 * Copyright (C) 2006 Linus Torvalds
6 * The standard malloc/free wastes too much space for objects, partly because
7 * it maintains all the allocation infrastructure, but even more because it ends
8 * up with maximal alignment because it doesn't know what the object alignment
9 * for the new allocation is.
11 #include "git-compat-util.h"
30 int nr
; /* number of nodes left in current allocation */
31 void *p
; /* first free node in current allocation */
33 /* bookkeeping of allocations */
35 int slab_nr
, slab_alloc
;
38 struct alloc_state
*allocate_alloc_state(void)
40 return xcalloc(1, sizeof(struct alloc_state
));
43 void clear_alloc_state(struct alloc_state
*s
)
45 while (s
->slab_nr
> 0) {
47 free(s
->slabs
[s
->slab_nr
]);
50 FREE_AND_NULL(s
->slabs
);
53 static inline void *alloc_node(struct alloc_state
*s
, size_t node_size
)
59 s
->p
= xmalloc(BLOCKING
* node_size
);
61 ALLOC_GROW(s
->slabs
, s
->slab_nr
+ 1, s
->slab_alloc
);
62 s
->slabs
[s
->slab_nr
++] = s
->p
;
66 s
->p
= (char *)s
->p
+ node_size
;
67 memset(ret
, 0, node_size
);
72 void *alloc_blob_node(struct repository
*r
)
74 struct blob
*b
= alloc_node(r
->parsed_objects
->blob_state
, sizeof(struct blob
));
75 b
->object
.type
= OBJ_BLOB
;
79 void *alloc_tree_node(struct repository
*r
)
81 struct tree
*t
= alloc_node(r
->parsed_objects
->tree_state
, sizeof(struct tree
));
82 t
->object
.type
= OBJ_TREE
;
86 void *alloc_tag_node(struct repository
*r
)
88 struct tag
*t
= alloc_node(r
->parsed_objects
->tag_state
, sizeof(struct tag
));
89 t
->object
.type
= OBJ_TAG
;
93 void *alloc_object_node(struct repository
*r
)
95 struct object
*obj
= alloc_node(r
->parsed_objects
->object_state
, sizeof(union any_object
));
101 * The returned count is to be used as an index into commit slabs,
102 * that are *NOT* maintained per repository, and that is why a single
103 * global counter is used.
105 static unsigned int alloc_commit_index(void)
107 static unsigned int parsed_commits_count
;
108 return parsed_commits_count
++;
111 void init_commit_node(struct commit
*c
)
113 c
->object
.type
= OBJ_COMMIT
;
114 c
->index
= alloc_commit_index();
117 void *alloc_commit_node(struct repository
*r
)
119 struct commit
*c
= alloc_node(r
->parsed_objects
->commit_state
, sizeof(struct commit
));