From ecd04fa56e91d40b4e2946682285d1f44e763c76 Mon Sep 17 00:00:00 2001 From: Arijit Banerjee Date: Thu, 28 May 2026 14:59:28 -0700 Subject: [PATCH] index-pack: retain child bases in delta cache When resolving a delta whose result has children of its own, index-pack adds the result to work_head, accounts its data in base_cache_used, and calls prune_base_data(). It then immediately frees that same data. This bypasses the existing delta base cache policy and can force later descendants to reconstruct the queued base again. Let the existing delta_base_cache_limit pruning policy decide whether to keep or evict the data instead. This does not add a new cache or increase the cache limit. The object data is already accounted in base_cache_used before prune_base_data() runs, and the existing pruning and base cleanup paths still release it. On a quiet Ubuntu 24.04 VM with 16 vCPUs, 32 GiB RAM, and local SSD, standard p5302-pack-index.sh runs improved as follows: libgit2: 3.17(11.42+0.61) -> 2.69(10.49+0.32), 15.1% faster redis: 5.88(15.77+0.63) -> 4.98(14.08+0.39), 15.3% faster git.git: 11.22(38.31+1.29) -> 9.69(35.36+0.64), 13.6% faster cpython: 32.64(117.70+4.39) -> 28.70(109.90+1.98), 12.1% faster linux: 276.95(793.14+39.51) -> 234.75(722.33+18.01), 15.2% faster The linux p5302 number is from a single repeat; the others are from the default three repeats. End-to-end local full-clone spot checks also improved: libgit2: 4.99s -> 4.50s, 9.8% faster redis: 8.71s -> 7.90s, 9.3% faster git.git: 24.89s -> 23.57s, 5.3% faster cpython: 58.77s -> 53.84s, 8.4% faster linux: 549.21s -> 515.52s, 6.1% faster t/t5302-pack-index.sh passed, and GitGitGadget's linux-leaks CI also exercised that test under SANITIZE=leak. Signed-off-by: Arijit Banerjee --- builtin/index-pack.c | 1 - 1 file changed, 1 deletion(-) diff --git a/builtin/index-pack.c b/builtin/index-pack.c index cf0bd8280dca83..027c64b522ebb2 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1212,7 +1212,6 @@ static void *threaded_second_pass(void *data) list_add(&child->list, &work_head); base_cache_used += child->size; prune_base_data(NULL); - free_base_data(child); } else if (child) { /* * This child does not have its own children. It may be