pack-bitmap.c: keep track of each layer's type bitmaps

Prepare for reading the type-level bitmaps from previous bitmap layers by maintaining an array for each type, where each element in that type's array corresponds to one layer's bitmap for that type. These fields will be used in a later commit to instantiate the 'struct ewah_or_iterator' for each type. Signed-off-by: Taylor Blau <me@ttaylorr.com> Acked-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Taylor Blau committed Mar 20, 2025 at 13:57 UTC e07af41139fe6d5f088dda2501ed754ef40b6399
1 file changed +53 -4
pack-bitmap.c
+53 -4
@@ -81,6 +81,23 @@ struct bitmap_index {
81 struct ewah_bitmap *blobs;
82 struct ewah_bitmap *tags;
83
84 + /*
85 + * Type index arrays when this bitmap is associated with an
86 + * incremental multi-pack index chain.
87 + *
88 + * If n is the number of unique layers in the MIDX chain, then
89 + * commits_all[n-1] is this structs 'commits' field,
90 + * commits_all[n-2] is the commits field of this bitmap's
91 + * 'base', and so on.
92 + *
93 + * When associated either with a non-incremental MIDX or a
94 + * single packfile, these arrays each contain a single element.
95 + */
96 + struct ewah_bitmap **commits_all;
97 + struct ewah_bitmap **trees_all;
98 + struct ewah_bitmap **blobs_all;
99 + struct ewah_bitmap **tags_all;
100 +
101 /* Map from object ID -> `stored_bitmap` for all the bitmapped commits */
102 kh_oid_map_t *bitmaps;
103
@@ -581,7 +598,32 @@ static int load_reverse_index(struct repository *r, struct bitmap_index *bitmap_
598 return load_pack_revindex(r, bitmap_git->pack);
599 }
600
584 -static int load_bitmap(struct repository *r, struct bitmap_index *bitmap_git)
601 +static void load_all_type_bitmaps(struct bitmap_index *bitmap_git)
602 +{
603 + struct bitmap_index *curr = bitmap_git;
604 + size_t i = bitmap_git->base_nr;
605 +
606 + ALLOC_ARRAY(bitmap_git->commits_all, bitmap_git->base_nr + 1);
607 + ALLOC_ARRAY(bitmap_git->trees_all, bitmap_git->base_nr + 1);
608 + ALLOC_ARRAY(bitmap_git->blobs_all, bitmap_git->base_nr + 1);
609 + ALLOC_ARRAY(bitmap_git->tags_all, bitmap_git->base_nr + 1);
610 +
611 + while (curr) {
612 + bitmap_git->commits_all[i] = curr->commits;
613 + bitmap_git->trees_all[i] = curr->trees;
614 + bitmap_git->blobs_all[i] = curr->blobs;
615 + bitmap_git->tags_all[i] = curr->tags;
616 +
617 + curr = curr->base;
618 + if (curr && !i)
619 + BUG("unexpected number of bitmap layers, expected %"PRIu32,
620 + bitmap_git->base_nr + 1);
621 + i -= 1;
622 + }
623 +}
624 +
625 +static int load_bitmap(struct repository *r, struct bitmap_index *bitmap_git,
626 + int recursing)
627 {
628 assert(bitmap_git->map);
629
@@ -603,10 +645,13 @@ static int load_bitmap(struct repository *r, struct bitmap_index *bitmap_git)
645 if (bitmap_git->base) {
646 if (!bitmap_is_midx(bitmap_git))
647 BUG("non-MIDX bitmap has non-NULL base bitmap index");
606 - if (load_bitmap(r, bitmap_git->base) < 0)
648 + if (load_bitmap(r, bitmap_git->base, 1) < 0)
649 goto failed;
650 }
651
652 + if (!recursing)
653 + load_all_type_bitmaps(bitmap_git);
654 +
655 return 0;
656
657 failed:
@@ -682,7 +727,7 @@ struct bitmap_index *prepare_bitmap_git(struct repository *r)
727 {
728 struct bitmap_index *bitmap_git = xcalloc(1, sizeof(*bitmap_git));
729
685 - if (!open_bitmap(r, bitmap_git) && !load_bitmap(r, bitmap_git))
730 + if (!open_bitmap(r, bitmap_git) && !load_bitmap(r, bitmap_git, 0))
731 return bitmap_git;
732
733 free_bitmap_index(bitmap_git);
@@ -2052,7 +2097,7 @@ struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,
2097 * from disk. this is the point of no return; after this the rev_list
2098 * becomes invalidated and we must perform the revwalk through bitmaps
2099 */
2055 - if (load_bitmap(revs->repo, bitmap_git) < 0)
2100 + if (load_bitmap(revs->repo, bitmap_git, 0) < 0)
2101 goto cleanup;
2102
2103 if (!use_boundary_traversal)
@@ -2985,6 +3030,10 @@ void free_bitmap_index(struct bitmap_index *b)
3030 ewah_pool_free(b->trees);
3031 ewah_pool_free(b->blobs);
3032 ewah_pool_free(b->tags);
3033 + free(b->commits_all);
3034 + free(b->trees_all);
3035 + free(b->blobs_all);
3036 + free(b->tags_all);
3037 if (b->bitmaps) {
3038 struct stored_bitmap *sb;
3039 kh_foreach_value(b->bitmaps, sb, {