Skip to content

Commit 51967f9

Browse files
author
Arijit Banerjee
committed
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. Once all direct children of a base have been dispatched, and no thread is actively retaining that base for patch_delta(), release the cached bytes. The base_data struct itself remains alive until the existing children_remaining bookkeeping says the whole subtree is done. 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.49+0.60) -> 2.69(10.52+0.28), 15.1% faster redis: 5.84(15.56+0.63) -> 4.95(14.05+0.32), 15.2% faster git.git: 11.17(38.04+1.29) -> 9.67(35.29+0.60), 13.4% faster cpython: 32.69(117.85+4.37) -> 28.60(109.25+1.91), 12.5% faster linux: 279.22(797.69+40.86) -> 236.34(723.13+19.02), 15.4% 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: 5.00s -> 4.54s, 9.2% faster redis: 8.75s -> 7.92s, 9.5% faster git.git: 25.04s -> 23.71s, 5.3% faster cpython: 56.72s -> 55.94s, 1.4% faster linux: 556.17s -> 523.83s, 5.8% 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 <arijit@effectiveailabs.com>
1 parent c69baaf commit 51967f9

1 file changed

Lines changed: 11 additions & 2 deletions

File tree

builtin/index-pack.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,12 @@ static void free_base_data(struct base_data *c)
433433
}
434434
}
435435

436+
static int base_data_has_remaining_direct_children(struct base_data *c)
437+
{
438+
return c->ref_first <= c->ref_last ||
439+
c->ofs_first <= c->ofs_last;
440+
}
441+
436442
static void prune_base_data(struct base_data *retain)
437443
{
438444
struct list_head *pos;
@@ -1201,8 +1207,12 @@ static void *threaded_second_pass(void *data)
12011207
}
12021208

12031209
work_lock();
1204-
if (parent)
1210+
if (parent) {
12051211
parent->retain_data--;
1212+
if (!parent->retain_data &&
1213+
!base_data_has_remaining_direct_children(parent))
1214+
free_base_data(parent);
1215+
}
12061216

12071217
if (child && child->data) {
12081218
/*
@@ -1212,7 +1222,6 @@ static void *threaded_second_pass(void *data)
12121222
list_add(&child->list, &work_head);
12131223
base_cache_used += child->size;
12141224
prune_base_data(NULL);
1215-
free_base_data(child);
12161225
} else if (child) {
12171226
/*
12181227
* This child does not have its own children. It may be

0 commit comments

Comments
 (0)