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"
16 #include "repository.h"
31 int nr
; /* number of nodes left in current allocation */
32 void *p
; /* first free node in current allocation */
34 /* bookkeeping of allocations */
36 int slab_nr
, slab_alloc
;
39 struct alloc_state
*allocate_alloc_state(void)
41 return xcalloc(1, sizeof(struct alloc_state
));
44 void clear_alloc_state(struct alloc_state
*s
)
46 while (s
->slab_nr
> 0) {
48 free(s
->slabs
[s
->slab_nr
]);
51 FREE_AND_NULL(s
->slabs
);
54 static inline void *alloc_node(struct alloc_state
*s
, size_t node_size
)
60 s
->p
= xmalloc(BLOCKING
* node_size
);
62 ALLOC_GROW(s
->slabs
, s
->slab_nr
+ 1, s
->slab_alloc
);
63 s
->slabs
[s
->slab_nr
++] = s
->p
;
67 s
->p
= (char *)s
->p
+ node_size
;
68 memset(ret
, 0, node_size
);
73 void *alloc_blob_node(struct repository
*r
)
75 struct blob
*b
= alloc_node(r
->parsed_objects
->blob_state
, sizeof(struct blob
));
76 b
->object
.type
= OBJ_BLOB
;
80 void *alloc_tree_node(struct repository
*r
)
82 struct tree
*t
= alloc_node(r
->parsed_objects
->tree_state
, sizeof(struct tree
));
83 t
->object
.type
= OBJ_TREE
;
87 void *alloc_tag_node(struct repository
*r
)
89 struct tag
*t
= alloc_node(r
->parsed_objects
->tag_state
, sizeof(struct tag
));
90 t
->object
.type
= OBJ_TAG
;
94 void *alloc_object_node(struct repository
*r
)
96 struct object
*obj
= alloc_node(r
->parsed_objects
->object_state
, sizeof(union any_object
));
102 * The returned count is to be used as an index into commit slabs,
103 * that are *NOT* maintained per repository, and that is why a single
104 * global counter is used.
106 static unsigned int alloc_commit_index(void)
108 static unsigned int parsed_commits_count
;
109 return parsed_commits_count
++;
112 void init_commit_node(struct commit
*c
)
114 c
->object
.type
= OBJ_COMMIT
;
115 c
->index
= alloc_commit_index();
118 void *alloc_commit_node(struct repository
*r
)
120 struct commit
*c
= alloc_node(r
->parsed_objects
->commit_state
, sizeof(struct commit
));