From: Johannes Schindelin <Johannes.Schindelin@gmx.de>
To: Junio C Hamano <gitster@pobox.com>
Cc: Eyvind Bernhardsen <eyvind-git-list@orakel.ntnu.no>,
Nicolas Pitre <nico@cam.org>,
Nguyen Thai Ngoc Duy <pclouds@gmail.com>, Jan Hudec <bulb@ucw.cz>,
git@vger.kernel.org
Subject: [PATCH 1/3] Introduce release_all_objects()
Date: Sun, 2 Dec 2007 02:54:27 +0000 (GMT) [thread overview]
Message-ID: <Pine.LNX.4.64.0712020254120.27959@racer.site> (raw)
In-Reply-To: <Pine.LNX.4.64.0712020146240.27959@racer.site>
The new function release_all_objects() can be used to flush the object
cache. This will be needed for the upcoming change in execv_git_cmd(),
which should call the builtin functions directly instead of calling
execvp().
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
Guess how surprised I was when "free(commit);" would work the
first time, but not the second...
ATM I use an ugly way to cope with the static "nr" variables
in alloc.c: I just do not free() the last block.
It might be a better idea to refactor the (quite ugly) code in
alloc.c to have global structures a la
#define BLOCKING 1024
struct object_block {
size_t struct_size;
int nr;
/* first (uint32_t *) is pointer to previous block */
void *block;
};
static void *alloc_node(struct object_block *block)
{
if (!block || block->nr >= BLOCKING) {
void *next = xmalloc(sizeof(void *)
+ BLOCKING * block->struct_size);
*(void **)next = block->block;
block->block = next;
block->nr = 0;
}
return block->block + sizeof(void *)
+ block->struct_size * block->nr++;
}
static void release_nodes(struct object_block *block)
{
while (block->block) {
void *previous = *(void **)block->block;
free(block->block);
block->block = previous;
}
block->nr = 0; /* not strictly necessary */
}
#define DEFINE_ALLOCATOR(type) \
static object_block type##s = { sizeof(struct type) }; \
struct type *alloc_##type##_node(void) \
{ \
return alloc_node(&type##s); \
}
DEFINE_ALLOCATOR(object)
DEFINE_ALLOCATOR(blob)
DEFINE_ALLOCATOR(tree)
DEFINE_ALLOCATOR(commit)
DEFINE_ALLOCATOR(tag)
but I am waaay too tired to brush this up, test it and submit it
(hint, hint).
alloc.c | 31 ++++++++++++++++++++++++++++++-
blob.c | 3 +++
blob.h | 1 +
cache.h | 6 ++++++
commit.c | 8 ++++++++
commit.h | 2 ++
object.c | 24 ++++++++++++++++++++++++
object.h | 2 ++
tag.c | 8 ++++++++
tag.h | 2 ++
tree.c | 6 ++++++
tree.h | 1 +
12 files changed, 93 insertions(+), 1 deletions(-)
diff --git a/alloc.c b/alloc.c
index 216c23a..8c5e5e0 100644
--- a/alloc.c
+++ b/alloc.c
@@ -20,6 +20,7 @@
#define DEFINE_ALLOCATOR(name, type) \
static unsigned int name##_allocs; \
+static void *last_alloced_##name; \
void *alloc_##name##_node(void) \
{ \
static int nr; \
@@ -28,13 +29,32 @@ void *alloc_##name##_node(void) \
\
if (!nr) { \
nr = BLOCKING; \
- block = xmalloc(BLOCKING * sizeof(type)); \
+ struct { \
+ void *previous; \
+ type block[BLOCKING]; \
+ } *buf = xmalloc(sizeof(*buf)); \
+ buf->previous = last_alloced_##name; \
+ last_alloced_##name = buf; \
+ block = buf->block; \
} \
nr--; \
name##_allocs++; \
ret = block++; \
memset(ret, 0, sizeof(type)); \
return ret; \
+} \
+ \
+void release_all_##name##_nodes(void) \
+{ \
+ void *buf = last_alloced_##name; \
+ if (!buf) \
+ return; \
+ buf = *(void **)buf; \
+ while (buf) { \
+ void *next = *(void **)buf; \
+ free(buf); \
+ buf = next; \
+ } \
}
union any_object {
@@ -74,3 +94,12 @@ void alloc_report(void)
REPORT(commit);
REPORT(tag);
}
+
+void release_all_nodes(void)
+{
+ release_all_blob_nodes();
+ release_all_tree_nodes();
+ release_all_commit_nodes();
+ release_all_tag_nodes();
+ release_all_object_nodes();
+}
diff --git a/blob.c b/blob.c
index bd7d078..63756e6 100644
--- a/blob.c
+++ b/blob.c
@@ -18,6 +18,9 @@ struct blob *lookup_blob(const unsigned char *sha1)
return (struct blob *) obj;
}
+void release_blob(struct blob *blob) {
+}
+
int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size)
{
item->object.parsed = 1;
diff --git a/blob.h b/blob.h
index ea5d9e9..7560671 100644
--- a/blob.h
+++ b/blob.h
@@ -10,6 +10,7 @@ struct blob {
};
struct blob *lookup_blob(const unsigned char *sha1);
+void release_blob(struct blob *blob);
int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size);
diff --git a/cache.h b/cache.h
index 4e59646..cc50f1c 100644
--- a/cache.h
+++ b/cache.h
@@ -613,6 +613,12 @@ 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 release_all_blob_nodes(void);
+extern void release_all_tree_nodes(void);
+extern void release_all_commit_nodes(void);
+extern void release_all_tag_nodes(void);
+extern void release_all_object_nodes(void);
+extern void release_all_nodes(void);
extern void alloc_report(void);
/* trace.c */
diff --git a/commit.c b/commit.c
index f074811..59c2236 100644
--- a/commit.c
+++ b/commit.c
@@ -48,6 +48,14 @@ struct commit *lookup_commit(const unsigned char *sha1)
return check_commit(obj, sha1, 0);
}
+void release_commit(struct commit *commit)
+{
+ if (commit->parents)
+ free_commit_list(commit->parents);
+ if (commit->buffer)
+ free(commit->buffer);
+}
+
static unsigned long parse_commit_date(const char *buf)
{
unsigned long date;
diff --git a/commit.h b/commit.h
index 10e2b5d..363b9fb 100644
--- a/commit.h
+++ b/commit.h
@@ -21,6 +21,7 @@ struct commit {
char *buffer;
};
+
extern int save_commit_buffer;
extern const char *commit_type;
@@ -35,6 +36,7 @@ struct commit *lookup_commit(const unsigned char *sha1);
struct commit *lookup_commit_reference(const unsigned char *sha1);
struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
int quiet);
+void release_commit(struct commit *commit);
int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size);
diff --git a/object.c b/object.c
index 16793d9..f217122 100644
--- a/object.c
+++ b/object.c
@@ -192,6 +192,30 @@ struct object *parse_object(const unsigned char *sha1)
return NULL;
}
+void release_all_objects(void)
+{
+ int i;
+ for (i = 0; i < obj_hash_size; i++)
+ if (obj_hash[i]) {
+ switch (obj_hash[i]->type) {
+ case OBJ_BLOB:
+ release_blob((struct blob *)obj_hash[i]);
+ break;
+ case OBJ_COMMIT:
+ release_commit((struct commit *)obj_hash[i]);
+ break;
+ /*case OBJ_TREE:
+ release_tree((struct tree *)obj_hash[i]);
+ break;
+ case OBJ_TAG:
+ release_tag((struct tag *)obj_hash[i]);
+ break;*/
+ }
+ obj_hash[i] = NULL;
+ }
+ release_all_nodes();
+}
+
struct object_list *object_list_insert(struct object *item,
struct object_list **list_p)
{
diff --git a/object.h b/object.h
index 397bbfa..ad6184c 100644
--- a/object.h
+++ b/object.h
@@ -44,6 +44,8 @@ extern unsigned int get_max_object_index(void);
extern struct object *get_indexed_object(unsigned int);
extern struct object_refs *lookup_object_refs(struct object *);
+extern void release_all_objects(void);
+
/** Internal only **/
struct object *lookup_object(const unsigned char *sha1);
diff --git a/tag.c b/tag.c
index f62bcdd..8bc6840 100644
--- a/tag.c
+++ b/tag.c
@@ -33,6 +33,14 @@ struct tag *lookup_tag(const unsigned char *sha1)
return (struct tag *) obj;
}
+void release_tag(struct tag *tag)
+{
+ if (tag->tag)
+ free(tag->tag);
+ if (tag->signature)
+ free(tag->signature);
+}
+
int parse_tag_buffer(struct tag *item, void *data, unsigned long size)
{
int typelen, taglen;
diff --git a/tag.h b/tag.h
index 7a0cb00..fbc6048 100644
--- a/tag.h
+++ b/tag.h
@@ -12,6 +12,8 @@ struct tag {
char *signature; /* not actually implemented */
};
+void release_tag(struct tag *tag);
+
extern struct tag *lookup_tag(const unsigned char *sha1);
extern int parse_tag_buffer(struct tag *item, void *data, unsigned long size);
extern int parse_tag(struct tag *item);
diff --git a/tree.c b/tree.c
index 8c0819f..ee99bc6 100644
--- a/tree.c
+++ b/tree.c
@@ -202,6 +202,12 @@ struct tree *lookup_tree(const unsigned char *sha1)
return (struct tree *) obj;
}
+void release_tree(struct tree *tree)
+{
+ if (tree->buffer)
+ free(tree->buffer);
+}
+
/*
* NOTE! Tree refs to external git repositories
* (ie gitlinks) do not count as real references.
diff --git a/tree.h b/tree.h
index dd25c53..f8372a2 100644
--- a/tree.h
+++ b/tree.h
@@ -12,6 +12,7 @@ struct tree {
};
struct tree *lookup_tree(const unsigned char *sha1);
+void release_tree(struct tree *tree);
int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size);
--
1.5.3.6.2112.ge2263
next prev parent reply other threads:[~2007-12-02 2:55 UTC|newest]
Thread overview: 92+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-11-27 15:02 [PATCH RFC] Move all dashed form git commands to libexecdir Nguyễn Thái Ngọc Duy
2007-11-27 15:12 ` Johannes Schindelin
2007-11-27 15:25 ` Nicolas Pitre
2007-11-27 16:04 ` [PATCH] " Nguyễn Thái Ngoc Duy
2007-11-27 16:18 ` Johannes Schindelin
2007-11-28 0:07 ` Jan Hudec
2007-11-28 1:13 ` Junio C Hamano
2007-11-28 8:18 ` Jan Hudec
2007-11-28 8:36 ` Nguyen Thai Ngoc Duy
2007-11-28 23:14 ` Junio C Hamano
2007-11-28 23:40 ` Johannes Schindelin
2007-11-28 23:48 ` Junio C Hamano
2007-11-29 0:01 ` Johannes Schindelin
2007-11-29 0:59 ` A Large Angry SCM
2007-11-29 1:02 ` Junio C Hamano
2007-11-29 3:17 ` Nguyen Thai Ngoc Duy
2007-11-29 14:09 ` Nicolas Pitre
2007-11-29 22:36 ` Junio C Hamano
2007-11-30 7:32 ` Wincent Colaiuta
2007-11-30 11:28 ` Eyvind Bernhardsen
2007-11-30 12:08 ` [PATCH] transport.c: call dash-less form of receive-pack and upload-pack on remote Johannes Schindelin
2007-12-01 2:36 ` Junio C Hamano
2007-12-01 10:17 ` Johannes Schindelin
2007-12-01 19:30 ` Junio C Hamano
2007-12-01 23:03 ` Johannes Schindelin
2007-12-01 23:15 ` Johannes Schindelin
2007-12-02 1:57 ` Junio C Hamano
2007-12-02 2:52 ` [PATCH 0/3] Call builtin functions directly, was " Johannes Schindelin
2007-12-02 2:54 ` Johannes Schindelin [this message]
2007-12-02 2:54 ` [PATCH 2/3] Include the objects needed for the builtin functions into libgit.a Johannes Schindelin
2007-12-02 2:55 ` [PATCH 3/3] Introduce execv_git_builtin() and use it Johannes Schindelin
2007-12-02 3:04 ` Johannes Schindelin
2007-12-02 3:16 ` [REPLACEMENT PATCH " Johannes Schindelin
2007-12-02 5:19 ` [PATCH 0/3] Call builtin functions directly, was Re: [PATCH] transport.c: call dash-less form of receive-pack and upload-pack on remote Junio C Hamano
2007-12-02 11:35 ` Johannes Schindelin
2007-11-30 12:19 ` [PATCH] Move all dashed form git commands to libexecdir Nguyen Thai Ngoc Duy
2007-11-30 13:35 ` Johannes Schindelin
2007-11-29 15:08 ` Jeff King
2007-11-29 20:05 ` Nguyen Thai Ngoc Duy
2007-11-29 21:14 ` Jeff King
2007-11-29 22:19 ` Johannes Schindelin
2007-11-29 23:14 ` Jeff King
2007-11-29 23:30 ` Linus Torvalds
2007-11-30 0:13 ` Junio C Hamano
2007-11-30 0:35 ` Jeff King
2007-11-30 0:49 ` Junio C Hamano
2007-11-30 0:58 ` Jeff King
2007-11-30 1:13 ` Nicolas Pitre
2007-11-30 1:17 ` Jeff King
2007-11-30 5:42 ` Steffen Prohaska
2007-11-30 7:18 ` Andreas Ericsson
2007-11-30 15:09 ` Jeff King
2007-11-30 20:01 ` Junio C Hamano
2007-11-30 21:25 ` Jeff King
2007-11-30 23:10 ` Johannes Schindelin
2007-12-02 15:02 ` Wincent Colaiuta
2007-12-02 16:39 ` Johannes Schindelin
2007-12-02 16:56 ` Pascal Obry
2007-12-02 17:23 ` Johannes Schindelin
2007-12-01 2:37 ` Junio C Hamano
2007-12-01 4:17 ` Jeff King
2007-11-30 2:29 ` Linus Torvalds
2007-11-30 2:55 ` Nicolas Pitre
2007-11-30 5:51 ` Steffen Prohaska
2007-11-30 15:12 ` Jeff King
2007-11-30 15:28 ` Santi Béjar
2007-11-30 15:29 ` Jeff King
2007-11-30 15:50 ` Linus Torvalds
2007-11-30 16:22 ` Jeff King
2007-11-30 18:28 ` Johannes Schindelin
2007-11-30 18:37 ` Jeff King
2007-11-30 23:05 ` Johannes Schindelin
2007-11-30 23:21 ` Jeff King
2007-11-30 23:38 ` Johannes Schindelin
[not found] ` <fcaeb9bf0711302234l32460a1fqbf9825fc8055f99d@mail.gmail.com>
2007-12-01 19:32 ` Junio C Hamano
2007-12-01 21:26 ` Jeff King
2007-12-02 5:50 ` Nguyen Thai Ngoc Duy
2007-11-30 0:52 ` Nicolas Pitre
2007-11-30 1:00 ` Jeff King
2007-11-30 1:19 ` Nicolas Pitre
2007-11-30 1:25 ` Jeff King
2007-11-30 1:33 ` Nicolas Pitre
2007-11-30 1:53 ` Jeff King
2007-11-30 2:23 ` A Large Angry SCM
2007-11-30 0:40 ` Nguyen Thai Ngoc Duy
2007-11-30 0:51 ` A Large Angry SCM
2007-11-30 0:54 ` Johannes Schindelin
2007-11-30 2:03 ` A Large Angry SCM
2007-11-30 1:01 ` Nicolas Pitre
2007-11-30 2:17 ` A Large Angry SCM
2007-11-30 2:27 ` Nicolas Pitre
2007-11-29 0:14 ` Jakub Narebski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.64.0712020254120.27959@racer.site \
--to=johannes.schindelin@gmx.de \
--cc=bulb@ucw.cz \
--cc=eyvind-git-list@orakel.ntnu.no \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=nico@cam.org \
--cc=pclouds@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).