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: