Skip to content

Commit

Permalink
Merge branch 'sb/object-store-alloc'
Browse files Browse the repository at this point in the history
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
  • Loading branch information
gitster committed Jun 25, 2018
2 parents fa82bb7 + 14ba97f commit 1102405
Show file tree
Hide file tree
Showing 15 changed files with 221 additions and 68 deletions.
65 changes: 41 additions & 24 deletions alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
* Copyright (C) 2006 Linus Torvalds
*
* The standard malloc/free wastes too much space for objects, partly because
* it maintains all the allocation infrastructure (which isn't needed, since
* we never free an object descriptor anyway), but even more because it ends
* it maintains all the allocation infrastructure, but even more because it ends
* up with maximal alignment because it doesn't know what the object alignment
* for the new allocation is.
*/
Expand All @@ -15,6 +14,7 @@
#include "tree.h"
#include "commit.h"
#include "tag.h"
#include "alloc.h"

#define BLOCKING 1024

Expand All @@ -30,69 +30,85 @@ struct alloc_state {
int count; /* total number of nodes allocated */
int nr; /* number of nodes left 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)
{
void *ret;

if (!s->nr) {
s->nr = BLOCKING;
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->count++;
ret = s->p;
s->p = (char *)s->p + node_size;
memset(ret, 0, node_size);

return ret;
}

static struct alloc_state blob_state;
void *alloc_blob_node(void)
void *alloc_blob_node(struct repository *r)
{
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;
return b;
}

static struct alloc_state tree_state;
void *alloc_tree_node(void)
void *alloc_tree_node(struct repository *r)
{
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;
return t;
}

static struct alloc_state tag_state;
void *alloc_tag_node(void)
void *alloc_tag_node(struct repository *r)
{
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;
return t;
}

static struct alloc_state object_state;
void *alloc_object_node(void)
void *alloc_object_node(struct repository *r)
{
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;
return obj;
}

static struct alloc_state commit_state;

unsigned int alloc_commit_index(void)
unsigned int alloc_commit_index(struct repository *r)
{
static unsigned int count;
return count++;
return r->parsed_objects->commit_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->index = alloc_commit_index();
c->index = alloc_commit_index(r);
c->graph_pos = COMMIT_NOT_FROM_GRAPH;
c->generation = GENERATION_NUMBER_INFINITY;
return c;
Expand All @@ -105,9 +121,10 @@ static void report(const char *name, unsigned int count, size_t size)
}

#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(tree, struct tree);
Expand Down
19 changes: 19 additions & 0 deletions alloc.h
Original file line number Diff line number Diff line change
@@ -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 changes: 2 additions & 1 deletion blame.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "diffcore.h"
#include "tag.h"
#include "blame.h"
#include "alloc.h"
#include "commit-slab.h"

define_commit_slab(blame_suspects, struct blame_origin *);
Expand Down Expand Up @@ -179,7 +180,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,

read_cache();
time(&now);
commit = alloc_commit_node();
commit = alloc_commit_node(the_repository);
commit->object.parsed = 1;
commit->date = now;
parent_tail = &commit->parents;
Expand Down
5 changes: 4 additions & 1 deletion blob.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
#include "cache.h"
#include "blob.h"
#include "repository.h"
#include "alloc.h"

const char *blob_type = "blob";

struct blob *lookup_blob(const struct object_id *oid)
{
struct object *obj = lookup_object(oid->hash);
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);
}

Expand Down
9 changes: 0 additions & 9 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -1770,15 +1770,6 @@ extern const char *excludes_file;
int decode_85(char *dst, const char *line, int linelen);
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 */
void packet_trace_identity(const char *prog);

Expand Down
15 changes: 14 additions & 1 deletion commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "diff.h"
#include "revision.h"
#include "notes.h"
#include "alloc.h"
#include "gpg-interface.h"
#include "mergesort.h"
#include "commit-slab.h"
Expand Down Expand Up @@ -52,7 +53,8 @@ struct commit *lookup_commit(const struct object_id *oid)
{
struct object *obj = lookup_object(oid->hash);
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);
}

Expand Down Expand Up @@ -325,6 +327,17 @@ struct object_id *get_commit_tree_oid(const struct commit *commit)
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)
{
struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit);
Expand Down
6 changes: 6 additions & 0 deletions commit.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ void free_commit_buffer(struct commit *);
struct tree *get_commit_tree(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.
* The buffer (or NULL, if none) is returned.
Expand Down
3 changes: 2 additions & 1 deletion merge-recursive.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "diff.h"
#include "diffcore.h"
#include "tag.h"
#include "alloc.h"
#include "unpack-trees.h"
#include "string-list.h"
#include "xdiff-interface.h"
Expand Down Expand Up @@ -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)
{
struct commit *commit = alloc_commit_node();
struct commit *commit = alloc_commit_node(the_repository);

set_merge_remote_desc(commit, comment, (struct object *)commit);
commit->maybe_tree = tree;
Expand Down
Loading

0 comments on commit 1102405

Please sign in to comment.