Skip to content

Commit 2692c2f

Browse files
derrickstoleegitster
authored andcommitted
commit-graph: use chunk-format read API
Instead of parsing the table of contents directly, use the chunk-format API methods read_table_of_contents() and pair_chunk(). While the current implementation loses the duplicate-chunk detection, that will be added in a future change. Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5f0879f commit 2692c2f

File tree

2 files changed

+55
-106
lines changed

2 files changed

+55
-106
lines changed

commit-graph.c

Lines changed: 54 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,7 @@ void git_test_write_commit_graph_or_die(void)
5959

6060
#define GRAPH_HEADER_SIZE 8
6161
#define GRAPH_FANOUT_SIZE (4 * 256)
62-
#define GRAPH_CHUNKLOOKUP_WIDTH 12
63-
#define GRAPH_MIN_SIZE (GRAPH_HEADER_SIZE + 4 * GRAPH_CHUNKLOOKUP_WIDTH \
62+
#define GRAPH_MIN_SIZE (GRAPH_HEADER_SIZE + 4 * CHUNK_TOC_ENTRY_SIZE \
6463
+ GRAPH_FANOUT_SIZE + the_hash_algo->rawsz)
6564

6665
#define CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW (1ULL << 31)
@@ -298,15 +297,43 @@ static int verify_commit_graph_lite(struct commit_graph *g)
298297
return 0;
299298
}
300299

300+
static int graph_read_oid_lookup(const unsigned char *chunk_start,
301+
size_t chunk_size, void *data)
302+
{
303+
struct commit_graph *g = data;
304+
g->chunk_oid_lookup = chunk_start;
305+
g->num_commits = chunk_size / g->hash_len;
306+
return 0;
307+
}
308+
309+
static int graph_read_bloom_data(const unsigned char *chunk_start,
310+
size_t chunk_size, void *data)
311+
{
312+
struct commit_graph *g = data;
313+
uint32_t hash_version;
314+
g->chunk_bloom_data = chunk_start;
315+
hash_version = get_be32(chunk_start);
316+
317+
if (hash_version != 1)
318+
return 0;
319+
320+
g->bloom_filter_settings = xmalloc(sizeof(struct bloom_filter_settings));
321+
g->bloom_filter_settings->hash_version = hash_version;
322+
g->bloom_filter_settings->num_hashes = get_be32(chunk_start + 4);
323+
g->bloom_filter_settings->bits_per_entry = get_be32(chunk_start + 8);
324+
g->bloom_filter_settings->max_changed_paths = DEFAULT_BLOOM_MAX_CHANGES;
325+
326+
return 0;
327+
}
328+
301329
struct commit_graph *parse_commit_graph(struct repository *r,
302330
void *graph_map, size_t graph_size)
303331
{
304-
const unsigned char *data, *chunk_lookup;
305-
uint32_t i;
332+
const unsigned char *data;
306333
struct commit_graph *graph;
307-
uint64_t next_chunk_offset;
308334
uint32_t graph_signature;
309335
unsigned char graph_version, hash_version;
336+
struct chunkfile *cf = NULL;
310337

311338
if (!graph_map)
312339
return NULL;
@@ -347,116 +374,36 @@ struct commit_graph *parse_commit_graph(struct repository *r,
347374
graph->data_len = graph_size;
348375

349376
if (graph_size < GRAPH_HEADER_SIZE +
350-
(graph->num_chunks + 1) * GRAPH_CHUNKLOOKUP_WIDTH +
377+
(graph->num_chunks + 1) * CHUNK_TOC_ENTRY_SIZE +
351378
GRAPH_FANOUT_SIZE + the_hash_algo->rawsz) {
352379
error(_("commit-graph file is too small to hold %u chunks"),
353380
graph->num_chunks);
354381
free(graph);
355382
return NULL;
356383
}
357384

358-
chunk_lookup = data + 8;
359-
next_chunk_offset = get_be64(chunk_lookup + 4);
360-
for (i = 0; i < graph->num_chunks; i++) {
361-
uint32_t chunk_id;
362-
uint64_t chunk_offset = next_chunk_offset;
363-
int chunk_repeated = 0;
364-
365-
chunk_id = get_be32(chunk_lookup + 0);
366-
367-
chunk_lookup += GRAPH_CHUNKLOOKUP_WIDTH;
368-
next_chunk_offset = get_be64(chunk_lookup + 4);
369-
370-
if (chunk_offset > graph_size - the_hash_algo->rawsz) {
371-
error(_("commit-graph improper chunk offset %08x%08x"), (uint32_t)(chunk_offset >> 32),
372-
(uint32_t)chunk_offset);
373-
goto free_and_return;
374-
}
375-
376-
switch (chunk_id) {
377-
case GRAPH_CHUNKID_OIDFANOUT:
378-
if (graph->chunk_oid_fanout)
379-
chunk_repeated = 1;
380-
else
381-
graph->chunk_oid_fanout = (uint32_t*)(data + chunk_offset);
382-
break;
383-
384-
case GRAPH_CHUNKID_OIDLOOKUP:
385-
if (graph->chunk_oid_lookup)
386-
chunk_repeated = 1;
387-
else {
388-
graph->chunk_oid_lookup = data + chunk_offset;
389-
graph->num_commits = (next_chunk_offset - chunk_offset)
390-
/ graph->hash_len;
391-
}
392-
break;
385+
cf = init_chunkfile(NULL);
393386

394-
case GRAPH_CHUNKID_DATA:
395-
if (graph->chunk_commit_data)
396-
chunk_repeated = 1;
397-
else
398-
graph->chunk_commit_data = data + chunk_offset;
399-
break;
400-
401-
case GRAPH_CHUNKID_GENERATION_DATA:
402-
if (graph->chunk_generation_data)
403-
chunk_repeated = 1;
404-
else
405-
graph->chunk_generation_data = data + chunk_offset;
406-
break;
407-
408-
case GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW:
409-
if (graph->chunk_generation_data_overflow)
410-
chunk_repeated = 1;
411-
else
412-
graph->chunk_generation_data_overflow = data + chunk_offset;
413-
break;
414-
415-
case GRAPH_CHUNKID_EXTRAEDGES:
416-
if (graph->chunk_extra_edges)
417-
chunk_repeated = 1;
418-
else
419-
graph->chunk_extra_edges = data + chunk_offset;
420-
break;
421-
422-
case GRAPH_CHUNKID_BASE:
423-
if (graph->chunk_base_graphs)
424-
chunk_repeated = 1;
425-
else
426-
graph->chunk_base_graphs = data + chunk_offset;
427-
break;
428-
429-
case GRAPH_CHUNKID_BLOOMINDEXES:
430-
if (graph->chunk_bloom_indexes)
431-
chunk_repeated = 1;
432-
else if (r->settings.commit_graph_read_changed_paths)
433-
graph->chunk_bloom_indexes = data + chunk_offset;
434-
break;
435-
436-
case GRAPH_CHUNKID_BLOOMDATA:
437-
if (graph->chunk_bloom_data)
438-
chunk_repeated = 1;
439-
else if (r->settings.commit_graph_read_changed_paths) {
440-
uint32_t hash_version;
441-
graph->chunk_bloom_data = data + chunk_offset;
442-
hash_version = get_be32(data + chunk_offset);
443-
444-
if (hash_version != 1)
445-
break;
387+
if (read_table_of_contents(cf, graph->data, graph_size,
388+
GRAPH_HEADER_SIZE, graph->num_chunks))
389+
goto free_and_return;
446390

447-
graph->bloom_filter_settings = xmalloc(sizeof(struct bloom_filter_settings));
448-
graph->bloom_filter_settings->hash_version = hash_version;
449-
graph->bloom_filter_settings->num_hashes = get_be32(data + chunk_offset + 4);
450-
graph->bloom_filter_settings->bits_per_entry = get_be32(data + chunk_offset + 8);
451-
graph->bloom_filter_settings->max_changed_paths = DEFAULT_BLOOM_MAX_CHANGES;
452-
}
453-
break;
454-
}
391+
pair_chunk(cf, GRAPH_CHUNKID_OIDFANOUT,
392+
(const unsigned char **)&graph->chunk_oid_fanout);
393+
read_chunk(cf, GRAPH_CHUNKID_OIDLOOKUP, graph_read_oid_lookup, graph);
394+
pair_chunk(cf, GRAPH_CHUNKID_DATA, &graph->chunk_commit_data);
395+
pair_chunk(cf, GRAPH_CHUNKID_EXTRAEDGES, &graph->chunk_extra_edges);
396+
pair_chunk(cf, GRAPH_CHUNKID_BASE, &graph->chunk_base_graphs);
397+
pair_chunk(cf, GRAPH_CHUNKID_GENERATION_DATA,
398+
&graph->chunk_generation_data);
399+
pair_chunk(cf, GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW,
400+
&graph->chunk_generation_data_overflow);
455401

456-
if (chunk_repeated) {
457-
error(_("commit-graph chunk id %08x appears multiple times"), chunk_id);
458-
goto free_and_return;
459-
}
402+
if (r->settings.commit_graph_read_changed_paths) {
403+
pair_chunk(cf, GRAPH_CHUNKID_BLOOMINDEXES,
404+
&graph->chunk_bloom_indexes);
405+
read_chunk(cf, GRAPH_CHUNKID_BLOOMDATA,
406+
graph_read_bloom_data, graph);
460407
}
461408

462409
if (graph->chunk_bloom_indexes && graph->chunk_bloom_data) {
@@ -473,9 +420,11 @@ struct commit_graph *parse_commit_graph(struct repository *r,
473420
if (verify_commit_graph_lite(graph))
474421
goto free_and_return;
475422

423+
free_chunkfile(cf);
476424
return graph;
477425

478426
free_and_return:
427+
free_chunkfile(cf);
479428
free(graph->bloom_filter_settings);
480429
free(graph);
481430
return NULL;

t/t5318-commit-graph.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ test_expect_success 'detect bad hash version' '
564564

565565
test_expect_success 'detect low chunk count' '
566566
corrupt_graph_and_verify $GRAPH_BYTE_CHUNK_COUNT "\01" \
567-
"missing the .* chunk"
567+
"final chunk has non-zero id"
568568
'
569569

570570
test_expect_success 'detect missing OID fanout chunk' '

0 commit comments

Comments
 (0)