]>
git.ipfire.org Git - thirdparty/git.git/blob - alloc.c
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.
30 int count
; /* total number of nodes allocated */
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
;
68 s
->p
= (char *)s
->p
+ node_size
;
69 memset(ret
, 0, node_size
);
74 void *alloc_blob_node(struct repository
*r
)
76 struct blob
*b
= alloc_node(r
->parsed_objects
->blob_state
, sizeof(struct blob
));
77 b
->object
.type
= OBJ_BLOB
;
81 void *alloc_tree_node(struct repository
*r
)
83 struct tree
*t
= alloc_node(r
->parsed_objects
->tree_state
, sizeof(struct tree
));
84 t
->object
.type
= OBJ_TREE
;
88 void *alloc_tag_node(struct repository
*r
)
90 struct tag
*t
= alloc_node(r
->parsed_objects
->tag_state
, sizeof(struct tag
));
91 t
->object
.type
= OBJ_TAG
;
95 void *alloc_object_node(struct repository
*r
)
97 struct object
*obj
= alloc_node(r
->parsed_objects
->object_state
, sizeof(union any_object
));
103 * The returned count is to be used as an index into commit slabs,
104 * that are *NOT* maintained per repository, and that is why a single
105 * global counter is used.
107 static unsigned int alloc_commit_index(void)
109 static unsigned int parsed_commits_count
;
110 return parsed_commits_count
++;
113 void init_commit_node(struct commit
*c
)
115 c
->object
.type
= OBJ_COMMIT
;
116 c
->index
= alloc_commit_index();
119 void *alloc_commit_node(struct repository
*r
)
121 struct commit
*c
= alloc_node(r
->parsed_objects
->commit_state
, sizeof(struct commit
));
126 static void report(const char *name
, unsigned int count
, size_t size
)
128 fprintf(stderr
, "%10s: %8u (%"PRIuMAX
" kB)\n",
129 name
, count
, (uintmax_t) size
);
132 #define REPORT(name, type) \
133 report(#name, r->parsed_objects->name##_state->count, \
134 r->parsed_objects->name##_state->count * sizeof(type) >> 10)
136 void alloc_report(struct repository
*r
)
138 REPORT(blob
, struct blob
);
139 REPORT(tree
, struct tree
);
140 REPORT(commit
, struct commit
);
141 REPORT(tag
, struct tag
);
142 REPORT(object
, union any_object
);