summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2009-09-03 21:54:03 -0400
committerJunio C Hamano <gitster@pobox.com>2009-09-05 22:27:08 -0700
commit0ef95f72f878184fbce8d7c855ab4346c081abed (patch)
treef012fc2a4ad51f09436a5259c7b0ffe39feb9316
parent6523078b96cd39f681e6fa11135049808591fb95 (diff)
downloadgit-0ef95f72f878184fbce8d7c855ab4346c081abed.tar.gz
pack-objects: free preferred base memory after usage
When adding objects for preferred delta base, the content from tree objects leading to given paths is kept in a cache. This has the potential to grow significantly, especially with large directories as the whole tree object content is loaded in memory, even if in practice the number of those objects is limited to the 256 cache entries plus the $window root tree objects. Still, that can't hurt freeing that up after object enumeration is done, and before more memory is needed for delta search. Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin-pack-objects.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 941cc2d73c..b44fa0e06a 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -1012,6 +1012,33 @@ static void add_preferred_base(unsigned char *sha1)
it->pcache.tree_size = size;
}
+static void cleanup_preferred_base(void)
+{
+ struct pbase_tree *it;
+ unsigned i;
+
+ it = pbase_tree;
+ pbase_tree = NULL;
+ while (it) {
+ struct pbase_tree *this = it;
+ it = this->next;
+ free(this->pcache.tree_data);
+ free(this);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(pbase_tree_cache); i++) {
+ if (!pbase_tree_cache[i])
+ continue;
+ free(pbase_tree_cache[i]->tree_data);
+ free(pbase_tree_cache[i]);
+ pbase_tree_cache[i] = NULL;
+ }
+
+ free(done_pbase_paths);
+ done_pbase_paths = NULL;
+ done_pbase_paths_num = done_pbase_paths_alloc = 0;
+}
+
static void check_object(struct object_entry *entry)
{
if (entry->in_pack) {
@@ -2308,6 +2335,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
rp_av[rp_ac] = NULL;
get_object_list(rp_ac, rp_av);
}
+ cleanup_preferred_base();
if (include_tag && nr_result)
for_each_ref(add_ref_tag, NULL);
stop_progress(&progress_state);