@matheusbsbs / matheus-bagliano / commits / a7f7e84a49
Fork 0

index-pack: remove redundant child field

This is refactoring 1 of 2 to simplify struct base_data. In index-pack, each thread maintains a doubly-linked list of the delta chain that it is currently processing (the "base" and "child" pointers in struct base_data). When a thread exceeds the delta base cache limit and needs to reclaim memory, it uses the "child" pointers to traverse the lineage, reclaiming the memory of the eldest delta bases first. A subsequent patch will perform memory reclaiming in a different way and will thus no longer need the "child" pointer. Because the "child" pointer is redundant even now, remove it so that the aforementioned subsequent patch will be clearer. In the meantime, reclaim memory in the reverse order of the "base" pointers. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Tan committed Aug 24, 2020 at 12:16 UTC a7f7e84a496d194ceeeba9827d17c4c206932d2b
1 file changed +22 -19
builtin/index-pack.c
+22 -19
@@ -34,7 +34,6 @@ struct object_stat {
34
35 struct base_data {
36 struct base_data *base;
37 - struct base_data *child;
37 struct object_entry *obj;
38 void *data;
39 unsigned long size;
@@ -44,7 +43,6 @@ struct base_data {
43
44 struct thread_local {
45 pthread_t thread;
47 - struct base_data *base_cache;
46 size_t base_cache_used;
47 int pack_fd;
48 };
@@ -380,27 +378,37 @@ static void free_base_data(struct base_data *c)
378 }
379 }
380
383 -static void prune_base_data(struct base_data *retain)
381 +static void prune_base_data(struct base_data *youngest_child)
382 {
383 struct base_data *b;
384 struct thread_local *data = get_thread_data();
387 - for (b = data->base_cache;
388 - data->base_cache_used > delta_base_cache_limit && b;
389 - b = b->child) {
390 - if (b->data && b != retain)
391 - free_base_data(b);
385 + struct base_data **ancestry = NULL;
386 + size_t nr = 0, alloc = 0;
387 + ssize_t i;
388 +
389 + if (data->base_cache_used <= delta_base_cache_limit)
390 + return;
391 +
392 + /*
393 + * Free all ancestors of youngest_child until we have enough space,
394 + * starting with the oldest. (We cannot free youngest_child itself.)
395 + */
396 + for (b = youngest_child->base; b != NULL; b = b->base) {
397 + ALLOC_GROW(ancestry, nr + 1, alloc);
398 + ancestry[nr++] = b;
399 }
400 + for (i = nr - 1;
401 + i >= 0 && data->base_cache_used > delta_base_cache_limit;
402 + i--) {
403 + if (ancestry[i]->data)
404 + free_base_data(ancestry[i]);
405 + }
406 + free(ancestry);
407 }
408
409 static void link_base_data(struct base_data *base, struct base_data *c)
410 {
397 - if (base)
398 - base->child = c;
399 - else
400 - get_thread_data()->base_cache = c;
401 -
411 c->base = base;
403 - c->child = NULL;
412 if (c->data)
413 get_thread_data()->base_cache_used += c->size;
414 prune_base_data(c);
@@ -408,11 +416,6 @@ static void link_base_data(struct base_data *base, struct base_data *c)
416
417 static void unlink_base_data(struct base_data *c)
418 {
411 - struct base_data *base = c->base;
412 - if (base)
413 - base->child = NULL;
414 - else
415 - get_thread_data()->base_cache = NULL;
419 free_base_data(c);
420 }
421