pack-bitmap.c: read pseudo-merge extension

Now that the scaffolding for reading the pseudo-merge extension has been laid, teach the pack-bitmap machinery to read the pseudo-merge extension when present. Note that pseudo-merges themselves are not yet used during traversal, this step will be taken by a future commit. In the meantime, read the table and initialize the pseudo_merge_map structure introduced by a previous commit. When the pseudo-merge extension is present, `load_bitmap_header()` performs basic sanity checks to make sure that the table is well-formed. 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 7c0fae88442824cfb4a3160d61a00c54287d56a7
1 file changed +39
pack-bitmap.c
+39
@@ -20,6 +20,7 @@
20 #include "list-objects-filter-options.h"
21 #include "midx.h"
22 #include "config.h"
23 +#include "pseudo-merge.h"
24
25 /*
26 * An entry on the bitmap index, representing the bitmap for a given
@@ -86,6 +87,9 @@ struct bitmap_index {
87 */
88 unsigned char *table_lookup;
89
90 + /* This contains the pseudo-merge cache within 'map' (if found). */
91 + struct pseudo_merge_map pseudo_merges;
92 +
93 /*
94 * Extended index.
95 *
@@ -205,6 +209,41 @@ static int load_bitmap_header(struct bitmap_index *index)
209 index->table_lookup = (void *)(index_end - table_size);
210 index_end -= table_size;
211 }
212 +
213 + if (flags & BITMAP_OPT_PSEUDO_MERGES) {
214 + unsigned char *pseudo_merge_ofs;
215 + size_t table_size;
216 + uint32_t i;
217 +
218 + if (sizeof(table_size) > index_end - index->map - header_size)
219 + return error(_("corrupted bitmap index file (too short to fit pseudo-merge table header)"));
220 +
221 + table_size = get_be64(index_end - 8);
222 + if (table_size > index_end - index->map - header_size)
223 + return error(_("corrupted bitmap index file (too short to fit pseudo-merge table)"));
224 +
225 + if (git_env_bool("GIT_TEST_USE_PSEUDO_MERGES", 1)) {
226 + const unsigned char *ext = (index_end - table_size);
227 +
228 + index->pseudo_merges.map = index->map;
229 + index->pseudo_merges.map_size = index->map_size;
230 + index->pseudo_merges.commits = ext + get_be64(index_end - 16);
231 + index->pseudo_merges.commits_nr = get_be32(index_end - 20);
232 + index->pseudo_merges.nr = get_be32(index_end - 24);
233 +
234 + CALLOC_ARRAY(index->pseudo_merges.v,
235 + index->pseudo_merges.nr);
236 +
237 + pseudo_merge_ofs = index_end - 24 -
238 + (index->pseudo_merges.nr * sizeof(uint64_t));
239 + for (i = 0; i < index->pseudo_merges.nr; i++) {
240 + index->pseudo_merges.v[i].at = get_be64(pseudo_merge_ofs);
241 + pseudo_merge_ofs += sizeof(uint64_t);
242 + }
243 + }
244 +
245 + index_end -= table_size;
246 + }
247 }
248
249 index->entry_count = ntohl(header->entry_count);