Web lists-archives.com

[PATCH 149/194] commit: allow commit buffer functions to handle arbitrary repositories




Signed-off-by: Stefan Beller <sbeller@xxxxxxxxxx>
---
 builtin/index-pack.c |  2 +-
 commit.c             | 33 ++++++++++++++++++++++-----------
 commit.h             | 17 ++++++++---------
 object.h             |  6 +++++-
 repository.c         |  6 ++++++
 5 files changed, 42 insertions(+), 22 deletions(-)

diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index f78e9d2e65..b2b6021ad3 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -870,7 +870,7 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
 			}
 			if (obj->type == OBJ_COMMIT) {
 				struct commit *commit = (struct commit *) obj;
-				if (detach_commit_buffer(commit, NULL) != data)
+				if (detach_commit_buffer(the_repository, commit, NULL) != data)
 					die("BUG: parse_object_buffer transmogrified our buffer");
 			}
 			obj->flags |= FLAG_CHECKED;
diff --git a/commit.c b/commit.c
index 8ef8619dec..a5e570f057 100644
--- a/commit.c
+++ b/commit.c
@@ -248,18 +248,29 @@ struct commit_buffer {
 	unsigned long size;
 };
 define_commit_slab(buffer_slab, struct commit_buffer);
-static struct buffer_slab buffer_slab = COMMIT_SLAB_INIT(1, buffer_slab);
+struct buffer_slab the_repository_buffer_slab = COMMIT_SLAB_INIT(1, the_repository_buffer_slab);
 
-void set_commit_buffer_the_repository(struct commit *commit, void *buffer, unsigned long size)
+void alloc_buffer_slab(struct repository *r)
 {
-	struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
+	r->parsed_objects.buffer_slab = xcalloc(1, sizeof(struct buffer_slab));
+	init_buffer_slab(r->parsed_objects.buffer_slab);
+}
+
+void free_commit_slab(struct repository *r)
+{
+	free(r->parsed_objects.buffer_slab);
+}
+
+void set_commit_buffer(struct repository *r, struct commit *commit, void *buffer, unsigned long size)
+{
+	struct commit_buffer *v = buffer_slab_at(r->parsed_objects.buffer_slab, commit);
 	v->buffer = buffer;
 	v->size = size;
 }
 
-const void *get_cached_commit_buffer_the_repository(const struct commit *commit, unsigned long *sizep)
+const void *get_cached_commit_buffer(struct repository *r, const struct commit *commit, unsigned long *sizep)
 {
-	struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit);
+	struct commit_buffer *v = buffer_slab_peek(r->parsed_objects.buffer_slab, commit);
 	if (!v) {
 		if (sizep)
 			*sizep = 0;
@@ -290,25 +301,25 @@ const void *get_commit_buffer(const struct commit *commit, unsigned long *sizep)
 	return ret;
 }
 
-void unuse_commit_buffer_the_repository(const struct commit *commit, const void *buffer)
+void unuse_commit_buffer(struct repository *r, const struct commit *commit, const void *buffer)
 {
-	struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit);
+	struct commit_buffer *v = buffer_slab_peek(r->parsed_objects.buffer_slab, commit);
 	if (!(v && v->buffer == buffer))
 		free((void *)buffer);
 }
 
-void free_commit_buffer_the_repository(struct commit *commit)
+void free_commit_buffer(struct repository *r, struct commit *commit)
 {
-	struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit);
+	struct commit_buffer *v = buffer_slab_peek(r->parsed_objects.buffer_slab, commit);
 	if (v) {
 		FREE_AND_NULL(v->buffer);
 		v->size = 0;
 	}
 }
 
-const void *detach_commit_buffer(struct commit *commit, unsigned long *sizep)
+const void *detach_commit_buffer(struct repository *r, struct commit *commit, unsigned long *sizep)
 {
-	struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit);
+	struct commit_buffer *v = buffer_slab_peek(r->parsed_objects.buffer_slab, commit);
 	void *ret;
 
 	if (!v) {
diff --git a/commit.h b/commit.h
index 8892989b1d..0d3ccd7279 100644
--- a/commit.h
+++ b/commit.h
@@ -75,19 +75,20 @@ static inline int parse_commit_the_repository(struct commit *item)
 }
 void parse_commit_or_die(struct commit *item);
 
+extern void alloc_buffer_slab(struct repository *r);
+extern void free_commit_slab(struct repository *r);
+
 /*
  * Associate an object buffer with the commit. The ownership of the
  * memory is handed over to the commit, and must be free()-able.
  */
-#define set_commit_buffer(r, c, b, s) set_commit_buffer_##r(c, b, s)
-void set_commit_buffer_the_repository(struct commit *, void *buffer, unsigned long size);
+void set_commit_buffer(struct repository *r, struct commit *, void *buffer, unsigned long size);
 
 /*
  * Get any cached object buffer associated with the commit. Returns NULL
  * if none. The resulting memory should not be freed.
  */
-#define get_cached_commit_buffer(r, c, s) get_cached_commit_buffer_##r(c, s)
-const void *get_cached_commit_buffer_the_repository(const struct commit *, unsigned long *size);
+const void *get_cached_commit_buffer(struct repository *r, const struct commit *, unsigned long *size);
 
 /*
  * Get the commit's object contents, either from cache or by reading the object
@@ -102,20 +103,18 @@ const void *get_commit_buffer(const struct commit *, unsigned long *size);
  * from an earlier call to get_commit_buffer.  The buffer may or may not be
  * freed by this call; callers should not access the memory afterwards.
  */
-#define unuse_commit_buffer(r, c, b) unuse_commit_buffer_##r(c, b)
-void unuse_commit_buffer_the_repository(const struct commit *, const void *buffer);
+void unuse_commit_buffer(struct repository *r, const struct commit *, const void *buffer);
 
 /*
  * Free any cached object buffer associated with the commit.
  */
-#define free_commit_buffer(r, c) free_commit_buffer_##r(c)
-void free_commit_buffer_the_repository(struct commit *);
+void free_commit_buffer(struct repository *r, struct commit *);
 
 /*
  * Disassociate any cached object buffer from the commit, but do not free it.
  * The buffer (or NULL, if none) is returned.
  */
-const void *detach_commit_buffer(struct commit *, unsigned long *sizep);
+const void *detach_commit_buffer(struct repository *r, struct commit *, unsigned long *sizep);
 
 /* Find beginning and length of commit subject. */
 int find_commit_subject(const char *commit_buffer, const char **subject);
diff --git a/object.h b/object.h
index 513f5eaef4..65b5326e0f 100644
--- a/object.h
+++ b/object.h
@@ -5,6 +5,8 @@ struct object_parser {
 	struct object **obj_hash;
 	int nr_objs, obj_hash_size;
 
+	struct buffer_slab *buffer_slab;
+
 	/* parent substitutions from .git/info/grafts and .git/shallow */
 	struct commit_graft **grafts;
 	int grafts_alloc, grafts_nr;
@@ -17,12 +19,14 @@ struct object_parser {
 	unsigned commit_count;
 };
 
+extern struct buffer_slab the_repository_buffer_slab;
 extern struct alloc_state the_repository_blob_state;
 extern struct alloc_state the_repository_tree_state;
 extern struct alloc_state the_repository_commit_state;
 extern struct alloc_state the_repository_tag_state;
 extern struct alloc_state the_repository_object_state;
-#define OBJECT_PARSER_INIT { NULL, 0, 0, NULL, 0, 0, \
+#define OBJECT_PARSER_INIT { NULL, 0, 0, &the_repository_buffer_slab, \
+	NULL, 0, 0, \
 	&the_repository_blob_state, \
 	&the_repository_tree_state, \
 	&the_repository_commit_state, \
diff --git a/repository.c b/repository.c
index f76f0ddd37..0cf019bb9b 100644
--- a/repository.c
+++ b/repository.c
@@ -2,6 +2,7 @@
 #include "repository.h"
 #include "object-store.h"
 #include "config.h"
+#include "commit.h"
 #include "submodule-config.h"
 
 /* The main repository */
@@ -187,6 +188,8 @@ int repo_init(struct repository *repo, const char *gitdir, const char *worktree)
 	ALLOC_GROW(open_repos, open_repos_nr + 1, open_repos_alloc);
 	open_repos[open_repos_nr++] = repo;
 
+	alloc_buffer_slab(repo);
+
 	return 0;
 
 error:
@@ -249,6 +252,9 @@ int repo_submodule_init(struct repository *submodule,
 void repo_free(struct repository *repo)
 {
 	int i;
+
+	free_commit_slab(repo);
+
 	for (i = 0; i < open_repos_nr; i++) {
 		if (open_repos[i] != repo)
 			continue;
-- 
2.15.1.433.g936d1b9894.dirty