Merge branch 'sb/object-store-alloc'
The conversion to pass "the_repository" and then "a_repository" throughout the object access API continues. * sb/object-store-alloc: alloc: allow arbitrary repositories for alloc functions object: allow create_object to handle arbitrary repositories object: allow grow_object_hash to handle arbitrary repositories alloc: add repository argument to alloc_commit_index alloc: add repository argument to alloc_report alloc: add repository argument to alloc_object_node alloc: add repository argument to alloc_tag_node alloc: add repository argument to alloc_commit_node alloc: add repository argument to alloc_tree_node alloc: add repository argument to alloc_blob_node object: add repository argument to grow_object_hash object: add repository argument to create_object repository: introduce parsed objects field
This commit is contained in:
65
alloc.c
65
alloc.c
@ -4,8 +4,7 @@
|
|||||||
* Copyright (C) 2006 Linus Torvalds
|
* Copyright (C) 2006 Linus Torvalds
|
||||||
*
|
*
|
||||||
* The standard malloc/free wastes too much space for objects, partly because
|
* The standard malloc/free wastes too much space for objects, partly because
|
||||||
* it maintains all the allocation infrastructure (which isn't needed, since
|
* it maintains all the allocation infrastructure, but even more because it ends
|
||||||
* we never free an object descriptor anyway), but even more because it ends
|
|
||||||
* up with maximal alignment because it doesn't know what the object alignment
|
* up with maximal alignment because it doesn't know what the object alignment
|
||||||
* for the new allocation is.
|
* for the new allocation is.
|
||||||
*/
|
*/
|
||||||
@ -15,6 +14,7 @@
|
|||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
|
#include "alloc.h"
|
||||||
|
|
||||||
#define BLOCKING 1024
|
#define BLOCKING 1024
|
||||||
|
|
||||||
@ -30,8 +30,27 @@ struct alloc_state {
|
|||||||
int count; /* total number of nodes allocated */
|
int count; /* total number of nodes allocated */
|
||||||
int nr; /* number of nodes left in current allocation */
|
int nr; /* number of nodes left in current allocation */
|
||||||
void *p; /* first free node in current allocation */
|
void *p; /* first free node in current allocation */
|
||||||
|
|
||||||
|
/* bookkeeping of allocations */
|
||||||
|
void **slabs;
|
||||||
|
int slab_nr, slab_alloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void *allocate_alloc_state(void)
|
||||||
|
{
|
||||||
|
return xcalloc(1, sizeof(struct alloc_state));
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_alloc_state(struct alloc_state *s)
|
||||||
|
{
|
||||||
|
while (s->slab_nr > 0) {
|
||||||
|
s->slab_nr--;
|
||||||
|
free(s->slabs[s->slab_nr]);
|
||||||
|
}
|
||||||
|
|
||||||
|
FREE_AND_NULL(s->slabs);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void *alloc_node(struct alloc_state *s, size_t node_size)
|
static inline void *alloc_node(struct alloc_state *s, size_t node_size)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
@ -39,60 +58,57 @@ static inline void *alloc_node(struct alloc_state *s, size_t node_size)
|
|||||||
if (!s->nr) {
|
if (!s->nr) {
|
||||||
s->nr = BLOCKING;
|
s->nr = BLOCKING;
|
||||||
s->p = xmalloc(BLOCKING * node_size);
|
s->p = xmalloc(BLOCKING * node_size);
|
||||||
|
|
||||||
|
ALLOC_GROW(s->slabs, s->slab_nr + 1, s->slab_alloc);
|
||||||
|
s->slabs[s->slab_nr++] = s->p;
|
||||||
}
|
}
|
||||||
s->nr--;
|
s->nr--;
|
||||||
s->count++;
|
s->count++;
|
||||||
ret = s->p;
|
ret = s->p;
|
||||||
s->p = (char *)s->p + node_size;
|
s->p = (char *)s->p + node_size;
|
||||||
memset(ret, 0, node_size);
|
memset(ret, 0, node_size);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct alloc_state blob_state;
|
void *alloc_blob_node(struct repository *r)
|
||||||
void *alloc_blob_node(void)
|
|
||||||
{
|
{
|
||||||
struct blob *b = alloc_node(&blob_state, sizeof(struct blob));
|
struct blob *b = alloc_node(r->parsed_objects->blob_state, sizeof(struct blob));
|
||||||
b->object.type = OBJ_BLOB;
|
b->object.type = OBJ_BLOB;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct alloc_state tree_state;
|
void *alloc_tree_node(struct repository *r)
|
||||||
void *alloc_tree_node(void)
|
|
||||||
{
|
{
|
||||||
struct tree *t = alloc_node(&tree_state, sizeof(struct tree));
|
struct tree *t = alloc_node(r->parsed_objects->tree_state, sizeof(struct tree));
|
||||||
t->object.type = OBJ_TREE;
|
t->object.type = OBJ_TREE;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct alloc_state tag_state;
|
void *alloc_tag_node(struct repository *r)
|
||||||
void *alloc_tag_node(void)
|
|
||||||
{
|
{
|
||||||
struct tag *t = alloc_node(&tag_state, sizeof(struct tag));
|
struct tag *t = alloc_node(r->parsed_objects->tag_state, sizeof(struct tag));
|
||||||
t->object.type = OBJ_TAG;
|
t->object.type = OBJ_TAG;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct alloc_state object_state;
|
void *alloc_object_node(struct repository *r)
|
||||||
void *alloc_object_node(void)
|
|
||||||
{
|
{
|
||||||
struct object *obj = alloc_node(&object_state, sizeof(union any_object));
|
struct object *obj = alloc_node(r->parsed_objects->object_state, sizeof(union any_object));
|
||||||
obj->type = OBJ_NONE;
|
obj->type = OBJ_NONE;
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct alloc_state commit_state;
|
unsigned int alloc_commit_index(struct repository *r)
|
||||||
|
|
||||||
unsigned int alloc_commit_index(void)
|
|
||||||
{
|
{
|
||||||
static unsigned int count;
|
return r->parsed_objects->commit_count++;
|
||||||
return count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *alloc_commit_node(void)
|
void *alloc_commit_node(struct repository *r)
|
||||||
{
|
{
|
||||||
struct commit *c = alloc_node(&commit_state, sizeof(struct commit));
|
struct commit *c = alloc_node(r->parsed_objects->commit_state, sizeof(struct commit));
|
||||||
c->object.type = OBJ_COMMIT;
|
c->object.type = OBJ_COMMIT;
|
||||||
c->index = alloc_commit_index();
|
c->index = alloc_commit_index(r);
|
||||||
c->graph_pos = COMMIT_NOT_FROM_GRAPH;
|
c->graph_pos = COMMIT_NOT_FROM_GRAPH;
|
||||||
c->generation = GENERATION_NUMBER_INFINITY;
|
c->generation = GENERATION_NUMBER_INFINITY;
|
||||||
return c;
|
return c;
|
||||||
@ -105,9 +121,10 @@ static void report(const char *name, unsigned int count, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define REPORT(name, type) \
|
#define REPORT(name, type) \
|
||||||
report(#name, name##_state.count, name##_state.count * sizeof(type) >> 10)
|
report(#name, r->parsed_objects->name##_state->count, \
|
||||||
|
r->parsed_objects->name##_state->count * sizeof(type) >> 10)
|
||||||
|
|
||||||
void alloc_report(void)
|
void alloc_report(struct repository *r)
|
||||||
{
|
{
|
||||||
REPORT(blob, struct blob);
|
REPORT(blob, struct blob);
|
||||||
REPORT(tree, struct tree);
|
REPORT(tree, struct tree);
|
||||||
|
19
alloc.h
Normal file
19
alloc.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef ALLOC_H
|
||||||
|
#define ALLOC_H
|
||||||
|
|
||||||
|
struct tree;
|
||||||
|
struct commit;
|
||||||
|
struct tag;
|
||||||
|
|
||||||
|
void *alloc_blob_node(struct repository *r);
|
||||||
|
void *alloc_tree_node(struct repository *r);
|
||||||
|
void *alloc_commit_node(struct repository *r);
|
||||||
|
void *alloc_tag_node(struct repository *r);
|
||||||
|
void *alloc_object_node(struct repository *r);
|
||||||
|
void alloc_report(struct repository *r);
|
||||||
|
unsigned int alloc_commit_index(struct repository *r);
|
||||||
|
|
||||||
|
void *allocate_alloc_state(void);
|
||||||
|
void clear_alloc_state(struct alloc_state *s);
|
||||||
|
|
||||||
|
#endif
|
3
blame.c
3
blame.c
@ -6,6 +6,7 @@
|
|||||||
#include "diffcore.h"
|
#include "diffcore.h"
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
#include "blame.h"
|
#include "blame.h"
|
||||||
|
#include "alloc.h"
|
||||||
#include "commit-slab.h"
|
#include "commit-slab.h"
|
||||||
|
|
||||||
define_commit_slab(blame_suspects, struct blame_origin *);
|
define_commit_slab(blame_suspects, struct blame_origin *);
|
||||||
@ -179,7 +180,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
|
|||||||
|
|
||||||
read_cache();
|
read_cache();
|
||||||
time(&now);
|
time(&now);
|
||||||
commit = alloc_commit_node();
|
commit = alloc_commit_node(the_repository);
|
||||||
commit->object.parsed = 1;
|
commit->object.parsed = 1;
|
||||||
commit->date = now;
|
commit->date = now;
|
||||||
parent_tail = &commit->parents;
|
parent_tail = &commit->parents;
|
||||||
|
5
blob.c
5
blob.c
@ -1,5 +1,7 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "blob.h"
|
#include "blob.h"
|
||||||
|
#include "repository.h"
|
||||||
|
#include "alloc.h"
|
||||||
|
|
||||||
const char *blob_type = "blob";
|
const char *blob_type = "blob";
|
||||||
|
|
||||||
@ -7,7 +9,8 @@ struct blob *lookup_blob(const struct object_id *oid)
|
|||||||
{
|
{
|
||||||
struct object *obj = lookup_object(oid->hash);
|
struct object *obj = lookup_object(oid->hash);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return create_object(oid->hash, alloc_blob_node());
|
return create_object(the_repository, oid->hash,
|
||||||
|
alloc_blob_node(the_repository));
|
||||||
return object_as_type(obj, OBJ_BLOB, 0);
|
return object_as_type(obj, OBJ_BLOB, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
9
cache.h
9
cache.h
@ -1770,15 +1770,6 @@ extern const char *excludes_file;
|
|||||||
int decode_85(char *dst, const char *line, int linelen);
|
int decode_85(char *dst, const char *line, int linelen);
|
||||||
void encode_85(char *buf, const unsigned char *data, int bytes);
|
void encode_85(char *buf, const unsigned char *data, int bytes);
|
||||||
|
|
||||||
/* alloc.c */
|
|
||||||
extern void *alloc_blob_node(void);
|
|
||||||
extern void *alloc_tree_node(void);
|
|
||||||
extern void *alloc_commit_node(void);
|
|
||||||
extern void *alloc_tag_node(void);
|
|
||||||
extern void *alloc_object_node(void);
|
|
||||||
extern void alloc_report(void);
|
|
||||||
extern unsigned int alloc_commit_index(void);
|
|
||||||
|
|
||||||
/* pkt-line.c */
|
/* pkt-line.c */
|
||||||
void packet_trace_identity(const char *prog);
|
void packet_trace_identity(const char *prog);
|
||||||
|
|
||||||
|
15
commit.c
15
commit.c
@ -7,6 +7,7 @@
|
|||||||
#include "diff.h"
|
#include "diff.h"
|
||||||
#include "revision.h"
|
#include "revision.h"
|
||||||
#include "notes.h"
|
#include "notes.h"
|
||||||
|
#include "alloc.h"
|
||||||
#include "gpg-interface.h"
|
#include "gpg-interface.h"
|
||||||
#include "mergesort.h"
|
#include "mergesort.h"
|
||||||
#include "commit-slab.h"
|
#include "commit-slab.h"
|
||||||
@ -52,7 +53,8 @@ struct commit *lookup_commit(const struct object_id *oid)
|
|||||||
{
|
{
|
||||||
struct object *obj = lookup_object(oid->hash);
|
struct object *obj = lookup_object(oid->hash);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return create_object(oid->hash, alloc_commit_node());
|
return create_object(the_repository, oid->hash,
|
||||||
|
alloc_commit_node(the_repository));
|
||||||
return object_as_type(obj, OBJ_COMMIT, 0);
|
return object_as_type(obj, OBJ_COMMIT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,6 +327,17 @@ struct object_id *get_commit_tree_oid(const struct commit *commit)
|
|||||||
return &get_commit_tree(commit)->object.oid;
|
return &get_commit_tree(commit)->object.oid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void release_commit_memory(struct commit *c)
|
||||||
|
{
|
||||||
|
c->maybe_tree = NULL;
|
||||||
|
c->index = 0;
|
||||||
|
free_commit_buffer(c);
|
||||||
|
free_commit_list(c->parents);
|
||||||
|
/* TODO: what about commit->util? */
|
||||||
|
|
||||||
|
c->object.parsed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
const void *detach_commit_buffer(struct commit *commit, unsigned long *sizep)
|
const void *detach_commit_buffer(struct commit *commit, unsigned long *sizep)
|
||||||
{
|
{
|
||||||
struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit);
|
struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit);
|
||||||
|
6
commit.h
6
commit.h
@ -119,6 +119,12 @@ void free_commit_buffer(struct commit *);
|
|||||||
struct tree *get_commit_tree(const struct commit *);
|
struct tree *get_commit_tree(const struct commit *);
|
||||||
struct object_id *get_commit_tree_oid(const struct commit *);
|
struct object_id *get_commit_tree_oid(const struct commit *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Release memory related to a commit, including the parent list and
|
||||||
|
* any cached object buffer.
|
||||||
|
*/
|
||||||
|
void release_commit_memory(struct commit *c);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disassociate any cached object buffer from the commit, but do not free it.
|
* Disassociate any cached object buffer from the commit, but do not free it.
|
||||||
* The buffer (or NULL, if none) is returned.
|
* The buffer (or NULL, if none) is returned.
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "diff.h"
|
#include "diff.h"
|
||||||
#include "diffcore.h"
|
#include "diffcore.h"
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
|
#include "alloc.h"
|
||||||
#include "unpack-trees.h"
|
#include "unpack-trees.h"
|
||||||
#include "string-list.h"
|
#include "string-list.h"
|
||||||
#include "xdiff-interface.h"
|
#include "xdiff-interface.h"
|
||||||
@ -160,7 +161,7 @@ static struct tree *shift_tree_object(struct tree *one, struct tree *two,
|
|||||||
|
|
||||||
static struct commit *make_virtual_commit(struct tree *tree, const char *comment)
|
static struct commit *make_virtual_commit(struct tree *tree, const char *comment)
|
||||||
{
|
{
|
||||||
struct commit *commit = alloc_commit_node();
|
struct commit *commit = alloc_commit_node(the_repository);
|
||||||
|
|
||||||
set_merge_remote_desc(commit, comment, (struct object *)commit);
|
set_merge_remote_desc(commit, comment, (struct object *)commit);
|
||||||
commit->maybe_tree = tree;
|
commit->maybe_tree = tree;
|
||||||
|
113
object.c
113
object.c
@ -5,20 +5,18 @@
|
|||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
|
#include "alloc.h"
|
||||||
#include "object-store.h"
|
#include "object-store.h"
|
||||||
#include "packfile.h"
|
#include "packfile.h"
|
||||||
|
|
||||||
static struct object **obj_hash;
|
|
||||||
static int nr_objs, obj_hash_size;
|
|
||||||
|
|
||||||
unsigned int get_max_object_index(void)
|
unsigned int get_max_object_index(void)
|
||||||
{
|
{
|
||||||
return obj_hash_size;
|
return the_repository->parsed_objects->obj_hash_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct object *get_indexed_object(unsigned int idx)
|
struct object *get_indexed_object(unsigned int idx)
|
||||||
{
|
{
|
||||||
return obj_hash[idx];
|
return the_repository->parsed_objects->obj_hash[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *object_type_strings[] = {
|
static const char *object_type_strings[] = {
|
||||||
@ -90,15 +88,16 @@ struct object *lookup_object(const unsigned char *sha1)
|
|||||||
unsigned int i, first;
|
unsigned int i, first;
|
||||||
struct object *obj;
|
struct object *obj;
|
||||||
|
|
||||||
if (!obj_hash)
|
if (!the_repository->parsed_objects->obj_hash)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
first = i = hash_obj(sha1, obj_hash_size);
|
first = i = hash_obj(sha1,
|
||||||
while ((obj = obj_hash[i]) != NULL) {
|
the_repository->parsed_objects->obj_hash_size);
|
||||||
|
while ((obj = the_repository->parsed_objects->obj_hash[i]) != NULL) {
|
||||||
if (!hashcmp(sha1, obj->oid.hash))
|
if (!hashcmp(sha1, obj->oid.hash))
|
||||||
break;
|
break;
|
||||||
i++;
|
i++;
|
||||||
if (i == obj_hash_size)
|
if (i == the_repository->parsed_objects->obj_hash_size)
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
if (obj && i != first) {
|
if (obj && i != first) {
|
||||||
@ -107,7 +106,8 @@ struct object *lookup_object(const unsigned char *sha1)
|
|||||||
* that we do not need to walk the hash table the next
|
* that we do not need to walk the hash table the next
|
||||||
* time we look for it.
|
* time we look for it.
|
||||||
*/
|
*/
|
||||||
SWAP(obj_hash[i], obj_hash[first]);
|
SWAP(the_repository->parsed_objects->obj_hash[i],
|
||||||
|
the_repository->parsed_objects->obj_hash[first]);
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@ -117,29 +117,30 @@ struct object *lookup_object(const unsigned char *sha1)
|
|||||||
* power of 2 (but at least 32). Copy the existing values to the new
|
* power of 2 (but at least 32). Copy the existing values to the new
|
||||||
* hash map.
|
* hash map.
|
||||||
*/
|
*/
|
||||||
static void grow_object_hash(void)
|
static void grow_object_hash(struct repository *r)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
/*
|
/*
|
||||||
* Note that this size must always be power-of-2 to match hash_obj
|
* Note that this size must always be power-of-2 to match hash_obj
|
||||||
* above.
|
* above.
|
||||||
*/
|
*/
|
||||||
int new_hash_size = obj_hash_size < 32 ? 32 : 2 * obj_hash_size;
|
int new_hash_size = r->parsed_objects->obj_hash_size < 32 ? 32 : 2 * r->parsed_objects->obj_hash_size;
|
||||||
struct object **new_hash;
|
struct object **new_hash;
|
||||||
|
|
||||||
new_hash = xcalloc(new_hash_size, sizeof(struct object *));
|
new_hash = xcalloc(new_hash_size, sizeof(struct object *));
|
||||||
for (i = 0; i < obj_hash_size; i++) {
|
for (i = 0; i < r->parsed_objects->obj_hash_size; i++) {
|
||||||
struct object *obj = obj_hash[i];
|
struct object *obj = r->parsed_objects->obj_hash[i];
|
||||||
|
|
||||||
if (!obj)
|
if (!obj)
|
||||||
continue;
|
continue;
|
||||||
insert_obj_hash(obj, new_hash, new_hash_size);
|
insert_obj_hash(obj, new_hash, new_hash_size);
|
||||||
}
|
}
|
||||||
free(obj_hash);
|
free(r->parsed_objects->obj_hash);
|
||||||
obj_hash = new_hash;
|
r->parsed_objects->obj_hash = new_hash;
|
||||||
obj_hash_size = new_hash_size;
|
r->parsed_objects->obj_hash_size = new_hash_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *create_object(const unsigned char *sha1, void *o)
|
void *create_object(struct repository *r, const unsigned char *sha1, void *o)
|
||||||
{
|
{
|
||||||
struct object *obj = o;
|
struct object *obj = o;
|
||||||
|
|
||||||
@ -147,11 +148,12 @@ void *create_object(const unsigned char *sha1, void *o)
|
|||||||
obj->flags = 0;
|
obj->flags = 0;
|
||||||
hashcpy(obj->oid.hash, sha1);
|
hashcpy(obj->oid.hash, sha1);
|
||||||
|
|
||||||
if (obj_hash_size - 1 <= nr_objs * 2)
|
if (r->parsed_objects->obj_hash_size - 1 <= r->parsed_objects->nr_objs * 2)
|
||||||
grow_object_hash();
|
grow_object_hash(r);
|
||||||
|
|
||||||
insert_obj_hash(obj, obj_hash, obj_hash_size);
|
insert_obj_hash(obj, r->parsed_objects->obj_hash,
|
||||||
nr_objs++;
|
r->parsed_objects->obj_hash_size);
|
||||||
|
r->parsed_objects->nr_objs++;
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +163,7 @@ void *object_as_type(struct object *obj, enum object_type type, int quiet)
|
|||||||
return obj;
|
return obj;
|
||||||
else if (obj->type == OBJ_NONE) {
|
else if (obj->type == OBJ_NONE) {
|
||||||
if (type == OBJ_COMMIT)
|
if (type == OBJ_COMMIT)
|
||||||
((struct commit *)obj)->index = alloc_commit_index();
|
((struct commit *)obj)->index = alloc_commit_index(the_repository);
|
||||||
obj->type = type;
|
obj->type = type;
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@ -178,7 +180,8 @@ struct object *lookup_unknown_object(const unsigned char *sha1)
|
|||||||
{
|
{
|
||||||
struct object *obj = lookup_object(sha1);
|
struct object *obj = lookup_object(sha1);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
obj = create_object(sha1, alloc_object_node());
|
obj = create_object(the_repository, sha1,
|
||||||
|
alloc_object_node(the_repository));
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,8 +434,8 @@ void clear_object_flags(unsigned flags)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i < obj_hash_size; i++) {
|
for (i=0; i < the_repository->parsed_objects->obj_hash_size; i++) {
|
||||||
struct object *obj = obj_hash[i];
|
struct object *obj = the_repository->parsed_objects->obj_hash[i];
|
||||||
if (obj)
|
if (obj)
|
||||||
obj->flags &= ~flags;
|
obj->flags &= ~flags;
|
||||||
}
|
}
|
||||||
@ -442,13 +445,27 @@ void clear_commit_marks_all(unsigned int flags)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < obj_hash_size; i++) {
|
for (i = 0; i < the_repository->parsed_objects->obj_hash_size; i++) {
|
||||||
struct object *obj = obj_hash[i];
|
struct object *obj = the_repository->parsed_objects->obj_hash[i];
|
||||||
if (obj && obj->type == OBJ_COMMIT)
|
if (obj && obj->type == OBJ_COMMIT)
|
||||||
obj->flags &= ~flags;
|
obj->flags &= ~flags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct parsed_object_pool *parsed_object_pool_new(void)
|
||||||
|
{
|
||||||
|
struct parsed_object_pool *o = xmalloc(sizeof(*o));
|
||||||
|
memset(o, 0, sizeof(*o));
|
||||||
|
|
||||||
|
o->blob_state = allocate_alloc_state();
|
||||||
|
o->tree_state = allocate_alloc_state();
|
||||||
|
o->commit_state = allocate_alloc_state();
|
||||||
|
o->tag_state = allocate_alloc_state();
|
||||||
|
o->object_state = allocate_alloc_state();
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
struct raw_object_store *raw_object_store_new(void)
|
struct raw_object_store *raw_object_store_new(void)
|
||||||
{
|
{
|
||||||
struct raw_object_store *o = xmalloc(sizeof(*o));
|
struct raw_object_store *o = xmalloc(sizeof(*o));
|
||||||
@ -491,3 +508,43 @@ void raw_object_store_clear(struct raw_object_store *o)
|
|||||||
close_all_packs(o);
|
close_all_packs(o);
|
||||||
o->packed_git = NULL;
|
o->packed_git = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void parsed_object_pool_clear(struct parsed_object_pool *o)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* As objects are allocated in slabs (see alloc.c), we do
|
||||||
|
* not need to free each object, but each slab instead.
|
||||||
|
*
|
||||||
|
* Before doing so, we need to free any additional memory
|
||||||
|
* the objects may hold.
|
||||||
|
*/
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < o->obj_hash_size; i++) {
|
||||||
|
struct object *obj = o->obj_hash[i];
|
||||||
|
|
||||||
|
if (!obj)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (obj->type == OBJ_TREE)
|
||||||
|
free_tree_buffer((struct tree*)obj);
|
||||||
|
else if (obj->type == OBJ_COMMIT)
|
||||||
|
release_commit_memory((struct commit*)obj);
|
||||||
|
else if (obj->type == OBJ_TAG)
|
||||||
|
release_tag_memory((struct tag*)obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
FREE_AND_NULL(o->obj_hash);
|
||||||
|
o->obj_hash_size = 0;
|
||||||
|
|
||||||
|
clear_alloc_state(o->blob_state);
|
||||||
|
clear_alloc_state(o->tree_state);
|
||||||
|
clear_alloc_state(o->commit_state);
|
||||||
|
clear_alloc_state(o->tag_state);
|
||||||
|
clear_alloc_state(o->object_state);
|
||||||
|
FREE_AND_NULL(o->blob_state);
|
||||||
|
FREE_AND_NULL(o->tree_state);
|
||||||
|
FREE_AND_NULL(o->commit_state);
|
||||||
|
FREE_AND_NULL(o->tag_state);
|
||||||
|
FREE_AND_NULL(o->object_state);
|
||||||
|
}
|
||||||
|
18
object.h
18
object.h
@ -1,6 +1,22 @@
|
|||||||
#ifndef OBJECT_H
|
#ifndef OBJECT_H
|
||||||
#define OBJECT_H
|
#define OBJECT_H
|
||||||
|
|
||||||
|
struct parsed_object_pool {
|
||||||
|
struct object **obj_hash;
|
||||||
|
int nr_objs, obj_hash_size;
|
||||||
|
|
||||||
|
/* TODO: migrate alloc_states to mem-pool? */
|
||||||
|
struct alloc_state *blob_state;
|
||||||
|
struct alloc_state *tree_state;
|
||||||
|
struct alloc_state *commit_state;
|
||||||
|
struct alloc_state *tag_state;
|
||||||
|
struct alloc_state *object_state;
|
||||||
|
unsigned commit_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct parsed_object_pool *parsed_object_pool_new(void);
|
||||||
|
void parsed_object_pool_clear(struct parsed_object_pool *o);
|
||||||
|
|
||||||
struct object_list {
|
struct object_list {
|
||||||
struct object *item;
|
struct object *item;
|
||||||
struct object_list *next;
|
struct object_list *next;
|
||||||
@ -85,7 +101,7 @@ extern struct object *get_indexed_object(unsigned int);
|
|||||||
*/
|
*/
|
||||||
struct object *lookup_object(const unsigned char *sha1);
|
struct object *lookup_object(const unsigned char *sha1);
|
||||||
|
|
||||||
extern void *create_object(const unsigned char *sha1, void *obj);
|
extern void *create_object(struct repository *r, const unsigned char *sha1, void *obj);
|
||||||
|
|
||||||
void *object_as_type(struct object *obj, enum object_type type, int quiet);
|
void *object_as_type(struct object *obj, enum object_type type, int quiet);
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "repository.h"
|
#include "repository.h"
|
||||||
#include "object-store.h"
|
#include "object-store.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "object.h"
|
||||||
#include "submodule-config.h"
|
#include "submodule-config.h"
|
||||||
|
|
||||||
/* The main repository */
|
/* The main repository */
|
||||||
@ -14,6 +15,8 @@ void initialize_the_repository(void)
|
|||||||
|
|
||||||
the_repo.index = &the_index;
|
the_repo.index = &the_index;
|
||||||
the_repo.objects = raw_object_store_new();
|
the_repo.objects = raw_object_store_new();
|
||||||
|
the_repo.parsed_objects = parsed_object_pool_new();
|
||||||
|
|
||||||
repo_set_hash_algo(&the_repo, GIT_HASH_SHA1);
|
repo_set_hash_algo(&the_repo, GIT_HASH_SHA1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,6 +146,7 @@ int repo_init(struct repository *repo,
|
|||||||
memset(repo, 0, sizeof(*repo));
|
memset(repo, 0, sizeof(*repo));
|
||||||
|
|
||||||
repo->objects = raw_object_store_new();
|
repo->objects = raw_object_store_new();
|
||||||
|
repo->parsed_objects = parsed_object_pool_new();
|
||||||
|
|
||||||
if (repo_init_gitdir(repo, gitdir))
|
if (repo_init_gitdir(repo, gitdir))
|
||||||
goto error;
|
goto error;
|
||||||
@ -226,6 +230,9 @@ void repo_clear(struct repository *repo)
|
|||||||
raw_object_store_clear(repo->objects);
|
raw_object_store_clear(repo->objects);
|
||||||
FREE_AND_NULL(repo->objects);
|
FREE_AND_NULL(repo->objects);
|
||||||
|
|
||||||
|
parsed_object_pool_clear(repo->parsed_objects);
|
||||||
|
FREE_AND_NULL(repo->parsed_objects);
|
||||||
|
|
||||||
if (repo->config) {
|
if (repo->config) {
|
||||||
git_configset_clear(repo->config);
|
git_configset_clear(repo->config);
|
||||||
FREE_AND_NULL(repo->config);
|
FREE_AND_NULL(repo->config);
|
||||||
|
@ -26,6 +26,15 @@ struct repository {
|
|||||||
*/
|
*/
|
||||||
struct raw_object_store *objects;
|
struct raw_object_store *objects;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All objects in this repository that have been parsed. This structure
|
||||||
|
* owns all objects it references, so users of "struct object *"
|
||||||
|
* generally do not need to free them; instead, when a repository is no
|
||||||
|
* longer used, call parsed_object_pool_clear() on this structure, which
|
||||||
|
* is called by the repositories repo_clear on its desconstruction.
|
||||||
|
*/
|
||||||
|
struct parsed_object_pool *parsed_objects;
|
||||||
|
|
||||||
/* The store in which the refs are held. */
|
/* The store in which the refs are held. */
|
||||||
struct ref_store *refs;
|
struct ref_store *refs;
|
||||||
|
|
||||||
|
12
tag.c
12
tag.c
@ -3,6 +3,7 @@
|
|||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
#include "blob.h"
|
#include "blob.h"
|
||||||
|
#include "alloc.h"
|
||||||
#include "gpg-interface.h"
|
#include "gpg-interface.h"
|
||||||
|
|
||||||
const char *tag_type = "tag";
|
const char *tag_type = "tag";
|
||||||
@ -93,7 +94,8 @@ struct tag *lookup_tag(const struct object_id *oid)
|
|||||||
{
|
{
|
||||||
struct object *obj = lookup_object(oid->hash);
|
struct object *obj = lookup_object(oid->hash);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return create_object(oid->hash, alloc_tag_node());
|
return create_object(the_repository, oid->hash,
|
||||||
|
alloc_tag_node(the_repository));
|
||||||
return object_as_type(obj, OBJ_TAG, 0);
|
return object_as_type(obj, OBJ_TAG, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +116,14 @@ static timestamp_t parse_tag_date(const char *buf, const char *tail)
|
|||||||
return parse_timestamp(dateptr, NULL, 10);
|
return parse_timestamp(dateptr, NULL, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void release_tag_memory(struct tag *t)
|
||||||
|
{
|
||||||
|
free(t->tag);
|
||||||
|
t->tagged = NULL;
|
||||||
|
t->object.parsed = 0;
|
||||||
|
t->date = 0;
|
||||||
|
}
|
||||||
|
|
||||||
int parse_tag_buffer(struct tag *item, const void *data, unsigned long size)
|
int parse_tag_buffer(struct tag *item, const void *data, unsigned long size)
|
||||||
{
|
{
|
||||||
struct object_id oid;
|
struct object_id oid;
|
||||||
|
1
tag.h
1
tag.h
@ -15,6 +15,7 @@ struct tag {
|
|||||||
extern struct tag *lookup_tag(const struct object_id *oid);
|
extern struct tag *lookup_tag(const struct object_id *oid);
|
||||||
extern int parse_tag_buffer(struct tag *item, const void *data, unsigned long size);
|
extern int parse_tag_buffer(struct tag *item, const void *data, unsigned long size);
|
||||||
extern int parse_tag(struct tag *item);
|
extern int parse_tag(struct tag *item);
|
||||||
|
extern void release_tag_memory(struct tag *t);
|
||||||
extern struct object *deref_tag(struct object *, const char *, int);
|
extern struct object *deref_tag(struct object *, const char *, int);
|
||||||
extern struct object *deref_tag_noverify(struct object *);
|
extern struct object *deref_tag_noverify(struct object *);
|
||||||
extern int gpg_verify_tag(const struct object_id *oid,
|
extern int gpg_verify_tag(const struct object_id *oid,
|
||||||
|
4
tree.c
4
tree.c
@ -5,6 +5,7 @@
|
|||||||
#include "blob.h"
|
#include "blob.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
|
#include "alloc.h"
|
||||||
#include "tree-walk.h"
|
#include "tree-walk.h"
|
||||||
|
|
||||||
const char *tree_type = "tree";
|
const char *tree_type = "tree";
|
||||||
@ -196,7 +197,8 @@ struct tree *lookup_tree(const struct object_id *oid)
|
|||||||
{
|
{
|
||||||
struct object *obj = lookup_object(oid->hash);
|
struct object *obj = lookup_object(oid->hash);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return create_object(oid->hash, alloc_tree_node());
|
return create_object(the_repository, oid->hash,
|
||||||
|
alloc_tree_node(the_repository));
|
||||||
return object_as_type(obj, OBJ_TREE, 0);
|
return object_as_type(obj, OBJ_TREE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user