{"thread":{"id":"20837","subject":"[PATCH] pack-objects: free preferred base memory after usage","startedAt":"2009-09-04T01:54:03Z","lastAt":"2009-09-04T01:54:03Z","messageCount":1,"participants":["Nicolas Pitre"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"122375","messageId":"alpine.LFD.2.00.0909032139010.6044@xanadu.home","threadId":"20837","inReplyTo":null,"subject":"[PATCH] pack-objects: free preferred base memory after usage","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2009-09-04T01:54:03Z","receivedAt":"2009-09-04T01:54:03Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"When adding objects for preferred delta base, the content from tree \nobjects leading to given paths is kept in a cache. This has the \npotential to grow significantly, especially with large directories as \nthe whole tree object content is loaded in memory, even if in practice \nthe number of those objects is limited to the 256 cache entries plus the \n$window root tree objects.  Still, that can't hurt freeing that up after \nobject enumeration is done, and before more memory is needed for delta \nsearch.\n\nSigned-off-by: Nicolas Pitre <nico@cam.org>\n\ndiff --git a/builtin-pack-objects.c b/builtin-pack-objects.c\nindex 1ff2ce6..ae7ce0f 100644\n--- a/builtin-pack-objects.c\n+++ b/builtin-pack-objects.c\n@@ -1008,6 +1008,33 @@ static void add_preferred_base(unsigned char *sha1)\n \tit->pcache.tree_size = size;\n }\n \n+static void cleanup_preferred_base(void)\n+{\n+\tstruct pbase_tree *it;\n+\tunsigned i;\n+\t\n+\tit = pbase_tree;\n+\tpbase_tree = NULL;\n+\twhile (it) {\n+\t\tstruct pbase_tree *this = it;\n+\t\tit = this->next;\n+\t\tfree(this->pcache.tree_data);\n+\t\tfree(this);\n+\t}\n+\t\n+\tfor (i = 0; i < ARRAY_SIZE(pbase_tree_cache); i++) {\n+\t\tif (!pbase_tree_cache[i])\n+\t\t\tcontinue;\n+\t\tfree(pbase_tree_cache[i]->tree_data);\n+\t\tfree(pbase_tree_cache[i]);\n+\t\tpbase_tree_cache[i] = NULL;\n+\t}\n+\n+\tfree(done_pbase_paths);\n+\tdone_pbase_paths = NULL;\n+\tdone_pbase_paths_num = done_pbase_paths_alloc = 0;\n+}\n+\n static void check_object(struct object_entry *entry)\n {\n \tif (entry->in_pack) {\n@@ -2312,6 +2339,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)\n \t\trp_av[rp_ac] = NULL;\n \t\tget_object_list(rp_ac, rp_av);\n \t}\n+\tcleanup_preferred_base();\n \tif (include_tag && nr_result)\n \t\tfor_each_ref(add_ref_tag, NULL);\n \tstop_progress(&progress_state);\n"}]}