midx: use chunk-format API in write_midx_internal()

The chunk-format API allows writing the table of contents and all chunks using the anonymous 'struct chunkfile' type. We only need to convert our local chunk logic to this API for the multi-pack-index writes to share that logic with the commit-graph file writes. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Feb 18, 2021 at 14:07 UTC 63a8f0e9b9d9ce636738094391619c35856f7665
1 file changed +20 -86
midx.c
+20 -86
@@ -11,6 +11,7 @@
11 #include "trace2.h"
12 #include "run-command.h"
13 #include "repository.h"
14 +#include "chunk-format.h"
15
16 #define MIDX_SIGNATURE 0x4d494458 /* "MIDX" */
17 #define MIDX_VERSION 1
@@ -21,7 +22,6 @@
22 #define MIDX_HEADER_SIZE 12
23 #define MIDX_MIN_SIZE (MIDX_HEADER_SIZE + the_hash_algo->rawsz)
24
24 -#define MIDX_MAX_CHUNKS 5
25 #define MIDX_CHUNK_ALIGNMENT 4
26 #define MIDX_CHUNKID_PACKNAMES 0x504e414d /* "PNAM" */
27 #define MIDX_CHUNKID_OIDFANOUT 0x4f494446 /* "OIDF" */
@@ -799,18 +799,15 @@ static int write_midx_large_offsets(struct hashfile *f,
799 static int write_midx_internal(const char *object_dir, struct multi_pack_index *m,
800 struct string_list *packs_to_drop, unsigned flags)
801 {
802 - unsigned char cur_chunk, num_chunks = 0;
802 char *midx_name;
803 uint32_t i;
804 struct hashfile *f = NULL;
805 struct lock_file lk;
806 struct write_midx_context ctx = { 0 };
808 - uint64_t header_size = 0;
809 - uint32_t chunk_ids[MIDX_MAX_CHUNKS + 1];
810 - uint64_t chunk_offsets[MIDX_MAX_CHUNKS + 1];
807 int pack_name_concat_len = 0;
808 int dropped_packs = 0;
809 int result = 0;
810 + struct chunkfile *cf;
811
812 midx_name = get_midx_filename(object_dir);
813 if (safe_create_leading_directories(midx_name))
@@ -923,98 +920,35 @@ static int write_midx_internal(const char *object_dir, struct multi_pack_index *
920 if (ctx.m)
921 close_midx(ctx.m);
922
926 - cur_chunk = 0;
927 - num_chunks = ctx.large_offsets_needed ? 5 : 4;
928 -
923 if (ctx.nr - dropped_packs == 0) {
924 error(_("no pack files to index."));
925 result = 1;
926 goto cleanup;
927 }
928
935 - header_size = write_midx_header(f, num_chunks, ctx.nr - dropped_packs);
936 -
937 - chunk_ids[cur_chunk] = MIDX_CHUNKID_PACKNAMES;
938 - chunk_offsets[cur_chunk] = header_size + (num_chunks + 1) * MIDX_CHUNKLOOKUP_WIDTH;
939 -
940 - cur_chunk++;
941 - chunk_ids[cur_chunk] = MIDX_CHUNKID_OIDFANOUT;
942 - chunk_offsets[cur_chunk] = chunk_offsets[cur_chunk - 1] + pack_name_concat_len;
943 -
944 - cur_chunk++;
945 - chunk_ids[cur_chunk] = MIDX_CHUNKID_OIDLOOKUP;
946 - chunk_offsets[cur_chunk] = chunk_offsets[cur_chunk - 1] + MIDX_CHUNK_FANOUT_SIZE;
947 -
948 - cur_chunk++;
949 - chunk_ids[cur_chunk] = MIDX_CHUNKID_OBJECTOFFSETS;
950 - chunk_offsets[cur_chunk] = chunk_offsets[cur_chunk - 1] + ctx.entries_nr * the_hash_algo->rawsz;
951 -
952 - cur_chunk++;
953 - chunk_offsets[cur_chunk] = chunk_offsets[cur_chunk - 1] + ctx.entries_nr * MIDX_CHUNK_OFFSET_WIDTH;
954 - if (ctx.large_offsets_needed) {
955 - chunk_ids[cur_chunk] = MIDX_CHUNKID_LARGEOFFSETS;
956 -
957 - cur_chunk++;
958 - chunk_offsets[cur_chunk] = chunk_offsets[cur_chunk - 1] +
959 - ctx.num_large_offsets * MIDX_CHUNK_LARGE_OFFSET_WIDTH;
960 - }
961 -
962 - chunk_ids[cur_chunk] = 0;
963 -
964 - for (i = 0; i <= num_chunks; i++) {
965 - if (i && chunk_offsets[i] < chunk_offsets[i - 1])
966 - BUG("incorrect chunk offsets: %"PRIu64" before %"PRIu64,
967 - chunk_offsets[i - 1],
968 - chunk_offsets[i]);
969 -
970 - if (chunk_offsets[i] % MIDX_CHUNK_ALIGNMENT)
971 - BUG("chunk offset %"PRIu64" is not properly aligned",
972 - chunk_offsets[i]);
973 -
974 - hashwrite_be32(f, chunk_ids[i]);
975 - hashwrite_be64(f, chunk_offsets[i]);
976 - }
977 -
978 - for (i = 0; i < num_chunks; i++) {
979 - if (f->total + f->offset != chunk_offsets[i])
980 - BUG("incorrect chunk offset (%"PRIu64" != %"PRIu64") for chunk id %"PRIx32,
981 - chunk_offsets[i],
982 - f->total + f->offset,
983 - chunk_ids[i]);
929 + cf = init_chunkfile(f);
930
985 - switch (chunk_ids[i]) {
986 - case MIDX_CHUNKID_PACKNAMES:
987 - write_midx_pack_names(f, &ctx);
988 - break;
931 + add_chunk(cf, MIDX_CHUNKID_PACKNAMES, pack_name_concat_len,
932 + write_midx_pack_names);
933 + add_chunk(cf, MIDX_CHUNKID_OIDFANOUT, MIDX_CHUNK_FANOUT_SIZE,
934 + write_midx_oid_fanout);
935 + add_chunk(cf, MIDX_CHUNKID_OIDLOOKUP,
936 + ctx.entries_nr * the_hash_algo->rawsz,
937 + write_midx_oid_lookup);
938 + add_chunk(cf, MIDX_CHUNKID_OBJECTOFFSETS,
939 + ctx.entries_nr * MIDX_CHUNK_OFFSET_WIDTH,
940 + write_midx_object_offsets);
941
990 - case MIDX_CHUNKID_OIDFANOUT:
991 - write_midx_oid_fanout(f, &ctx);
992 - break;
993 -
994 - case MIDX_CHUNKID_OIDLOOKUP:
995 - write_midx_oid_lookup(f, &ctx);
996 - break;
997 -
998 - case MIDX_CHUNKID_OBJECTOFFSETS:
999 - write_midx_object_offsets(f, &ctx);
1000 - break;
1001 -
1002 - case MIDX_CHUNKID_LARGEOFFSETS:
1003 - write_midx_large_offsets(f, &ctx);
1004 - break;
1005 -
1006 - default:
1007 - BUG("trying to write unknown chunk id %"PRIx32,
1008 - chunk_ids[i]);
1009 - }
1010 - }
942 + if (ctx.large_offsets_needed)
943 + add_chunk(cf, MIDX_CHUNKID_LARGEOFFSETS,
944 + ctx.num_large_offsets * MIDX_CHUNK_LARGE_OFFSET_WIDTH,
945 + write_midx_large_offsets);
946
1012 - if (hashfile_total(f) != chunk_offsets[num_chunks])
1013 - BUG("incorrect final offset %"PRIu64" != %"PRIu64,
1014 - hashfile_total(f),
1015 - chunk_offsets[num_chunks]);
947 + write_midx_header(f, get_num_chunks(cf), ctx.nr - dropped_packs);
948 + write_chunkfile(cf, &ctx);
949
950 finalize_hashfile(f, NULL, CSUM_FSYNC | CSUM_HASH_IN_STREAM);
951 + free_chunkfile(cf);
952 commit_lock_file(&lk);
953
954 cleanup: