pack-objects: move 'layer' into 'struct packing_data'

This reduces the size of 'struct object_entry' from 88 bytes to 80 and therefore makes packing objects more efficient. For example on a Linux repo with 12M objects, `git pack-objects --all` needs extra 96MB memory even if the layer feature is not used. Helped-by: Jeff King <peff@peff.net> Helped-by: Duy Nguyen <pclouds@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Christian Couder committed Aug 16, 2018 at 08:13 UTC fe0ac2fb7f8e87d37ef83dcee2d93901d58d8277
4 files changed +28 -6
builtin/pack-objects.c
+2 -2
@@ -611,7 +611,7 @@ static inline void add_to_write_order(struct object_entry **wo,
611 unsigned int *endp,
612 struct object_entry *e)
613 {
614 - if (e->filled || e->layer != write_layer)
614 + if (e->filled || oe_layer(&to_pack, e) != write_layer)
615 return;
616 wo[(*endp)++] = e;
617 e->filled = 1;
@@ -714,7 +714,7 @@ static void compute_layer_order(struct object_entry **wo, unsigned int *wo_end)
714 * Finally all the rest in really tight order
715 */
716 for (i = last_untagged; i < to_pack.nr_objects; i++) {
717 - if (!objects[i].filled && objects[i].layer == write_layer)
717 + if (!objects[i].filled && oe_layer(&to_pack, &objects[i]) == write_layer)
718 add_family_to_write_order(wo, wo_end, &objects[i]);
719 }
720 }
delta-islands.c
+2 -2
@@ -488,13 +488,13 @@ int compute_pack_layers(struct packing_data *to_pack)
488 struct object_entry *entry = &to_pack->objects[i];
489 khiter_t pos = kh_get_sha1(island_marks, entry->idx.oid.hash);
490
491 - entry->layer = 1;
491 + oe_set_layer(to_pack, entry, 1);
492
493 if (pos < kh_end(island_marks)) {
494 struct island_bitmap *bitmap = kh_value(island_marks, pos);
495
496 if (island_bitmap_get(bitmap, island_counter_core))
497 - entry->layer = 0;
497 + oe_set_layer(to_pack, entry, 0);
498 }
499 }
500
pack-objects.c
+6
@@ -163,6 +163,9 @@ struct object_entry *packlist_alloc(struct packing_data *pdata,
163
164 if (pdata->tree_depth)
165 REALLOC_ARRAY(pdata->tree_depth, pdata->nr_alloc);
166 +
167 + if (pdata->layer)
168 + REALLOC_ARRAY(pdata->layer, pdata->nr_alloc);
169 }
170
171 new_entry = pdata->objects + pdata->nr_objects++;
@@ -181,5 +184,8 @@ struct object_entry *packlist_alloc(struct packing_data *pdata,
184 if (pdata->tree_depth)
185 pdata->tree_depth[pdata->nr_objects - 1] = 0;
186
187 + if (pdata->layer)
188 + pdata->layer[pdata->nr_objects - 1] = 0;
189 +
190 return new_entry;
191 }
pack-objects.h
+18 -2
@@ -101,8 +101,6 @@ struct object_entry {
101 unsigned no_try_delta:1;
102 unsigned in_pack_type:TYPE_BITS; /* could be delta */
103
104 - unsigned char layer;
105 -
104 unsigned preferred_base:1; /*
105 * we do not pack this, but is available
106 * to be used as the base object to delta
@@ -147,6 +145,7 @@ struct packing_data {
145
146 /* delta islands */
147 unsigned int *tree_depth;
148 + unsigned char *layer;
149 };
150
151 void prepare_packing_data(struct packing_data *pdata);
@@ -369,4 +368,21 @@ static inline void oe_set_tree_depth(struct packing_data *pack,
368 pack->tree_depth[e - pack->objects] = tree_depth;
369 }
370
371 +static inline unsigned char oe_layer(struct packing_data *pack,
372 + struct object_entry *e)
373 +{
374 + if (!pack->layer)
375 + return 0;
376 + return pack->layer[e - pack->objects];
377 +}
378 +
379 +static inline void oe_set_layer(struct packing_data *pack,
380 + struct object_entry *e,
381 + unsigned char layer)
382 +{
383 + if (!pack->layer)
384 + ALLOC_ARRAY(pack->layer, pack->nr_objects);
385 + pack->layer[e - pack->objects] = layer;
386 +}
387 +
388 #endif