pack-bitmap: move some initialization to `bitmap_writer_init()`

The pack-bitmap-writer machinery uses a oidmap (backed by khash.h) to map from commits selected for bitmaps (by OID) to a bitmapped_commit structure (containing the bitmap itself, among other things like its XOR offset, etc.) This map was initialized at the end of `bitmap_writer_build()`. New entries are added in `pack-bitmap-write.c::store_selected()`, which is called by the bitmap_builder machinery (which is responsible for traversing history and generating the actual bitmaps). Reorganize when this field is initialized and when entries are added to it so that we can quickly determine whether a commit is a candidate for pseudo-merge selection, or not (since it was already selected to receive a bitmap, and thus storing it in a pseudo-merge would be redundant). The changes are as follows: - Introduce a new `bitmap_writer_init()` function which initializes the `writer.bitmaps` field (instead of waiting until the end of `bitmap_writer_build()`). - Add map entries in `push_bitmapped_commit()` (which is called via `bitmap_writer_select_commits()`) with OID keys and NULL values to track whether or not we *expect* to write a bitmap for some given commit. - Validate that a NULL entry is found matching the given key when we store a selected bitmap. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Taylor Blau committed May 23, 2024 at 17:26 UTC 4722e06edcbb57142387081684b41eda2a6cf635
4 files changed +22 -9
builtin/pack-objects.c
+2 -1
@@ -1340,7 +1340,8 @@ static void write_pack_file(void)
1340 hash_to_hex(hash));
1341
1342 if (write_bitmap_index) {
1343 - bitmap_writer_init(&bitmap_writer);
1343 + bitmap_writer_init(&bitmap_writer,
1344 + the_repository);
1345 bitmap_writer_set_checksum(&bitmap_writer, hash);
1346 bitmap_writer_build_type_index(&bitmap_writer,
1347 &to_pack, written_list, nr_written);
midx-write.c
+1 -1
@@ -820,7 +820,7 @@ static int write_midx_bitmap(const char *midx_name,
820 for (i = 0; i < pdata->nr_objects; i++)
821 index[i] = &pdata->objects[i].idx;
822
823 - bitmap_writer_init(&writer);
823 + bitmap_writer_init(&writer, the_repository);
824 bitmap_writer_show_progress(&writer, flags & MIDX_PROGRESS);
825 bitmap_writer_build_type_index(&writer, pdata, index,
826 pdata->nr_objects);
pack-bitmap-write.c
+18 -6
@@ -27,9 +27,12 @@ struct bitmapped_commit {
27 uint32_t commit_pos;
28 };
29
30 -void bitmap_writer_init(struct bitmap_writer *writer)
30 +void bitmap_writer_init(struct bitmap_writer *writer, struct repository *r)
31 {
32 memset(writer, 0, sizeof(struct bitmap_writer));
33 + if (writer->bitmaps)
34 + BUG("bitmap writer already initialized");
35 + writer->bitmaps = kh_init_oid_map();
36 }
37
38 void bitmap_writer_free(struct bitmap_writer *writer)
@@ -128,11 +131,21 @@ void bitmap_writer_build_type_index(struct bitmap_writer *writer,
131 static inline void push_bitmapped_commit(struct bitmap_writer *writer,
132 struct commit *commit)
133 {
134 + int hash_ret;
135 + khiter_t hash_pos;
136 +
137 if (writer->selected_nr >= writer->selected_alloc) {
138 writer->selected_alloc = (writer->selected_alloc + 32) * 2;
139 REALLOC_ARRAY(writer->selected, writer->selected_alloc);
140 }
141
142 + hash_pos = kh_put_oid_map(writer->bitmaps, commit->object.oid,
143 + &hash_ret);
144 + if (!hash_ret)
145 + die(_("duplicate entry when writing bitmap index: %s"),
146 + oid_to_hex(&commit->object.oid));
147 + kh_value(writer->bitmaps, hash_pos) = NULL;
148 +
149 writer->selected[writer->selected_nr].commit = commit;
150 writer->selected[writer->selected_nr].bitmap = NULL;
151 writer->selected[writer->selected_nr].write_as = NULL;
@@ -483,14 +496,14 @@ static void store_selected(struct bitmap_writer *writer,
496 {
497 struct bitmapped_commit *stored = &writer->selected[ent->idx];
498 khiter_t hash_pos;
486 - int hash_ret;
499
500 stored->bitmap = bitmap_to_ewah(ent->bitmap);
501
490 - hash_pos = kh_put_oid_map(writer->bitmaps, commit->object.oid, &hash_ret);
491 - if (hash_ret == 0)
492 - die("Duplicate entry when writing index: %s",
502 + hash_pos = kh_get_oid_map(writer->bitmaps, commit->object.oid);
503 + if (hash_pos == kh_end(writer->bitmaps))
504 + die(_("attempted to store non-selected commit: '%s'"),
505 oid_to_hex(&commit->object.oid));
506 +
507 kh_value(writer->bitmaps, hash_pos) = stored;
508 }
509
@@ -506,7 +519,6 @@ int bitmap_writer_build(struct bitmap_writer *writer,
519 uint32_t *mapping;
520 int closed = 1; /* until proven otherwise */
521
509 - writer->bitmaps = kh_init_oid_map();
522 writer->to_pack = to_pack;
523
524 if (writer->show_progress)
pack-bitmap.h
+1 -1
@@ -114,7 +114,7 @@ struct bitmap_writer {
114 unsigned char pack_checksum[GIT_MAX_RAWSZ];
115 };
116
117 -void bitmap_writer_init(struct bitmap_writer *writer);
117 +void bitmap_writer_init(struct bitmap_writer *writer, struct repository *r);
118 void bitmap_writer_show_progress(struct bitmap_writer *writer, int show);
119 void bitmap_writer_set_checksum(struct bitmap_writer *writer,
120 const unsigned char *sha1);