commit-graph: use commit_stack

Replace a commit array implementation with commit_stack. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Dec 24, 2025 at 18:03 UTC 3e456f1d8ac409abcf1da3867c9505f48564e874
1 file changed +39 -47
commit-graph.c
+39 -47
@@ -1127,18 +1127,12 @@ struct tree *get_commit_tree_in_graph(struct repository *r, const struct commit
1127 return get_commit_tree_in_graph_one(r->objects->commit_graph, c);
1128 }
1129
1130 -struct packed_commit_list {
1131 - struct commit **list;
1132 - size_t nr;
1133 - size_t alloc;
1134 -};
1135 -
1130 struct write_commit_graph_context {
1131 struct repository *r;
1132 struct odb_source *odb_source;
1133 char *graph_name;
1134 struct oid_array oids;
1141 - struct packed_commit_list commits;
1135 + struct commit_stack commits;
1136 int num_extra_edges;
1137 int num_generation_data_overflows;
1138 unsigned long approx_nr_objects;
@@ -1180,7 +1174,7 @@ static int write_graph_chunk_fanout(struct hashfile *f,
1174 {
1175 struct write_commit_graph_context *ctx = data;
1176 int i, count = 0;
1183 - struct commit **list = ctx->commits.list;
1177 + struct commit **list = ctx->commits.items;
1178
1179 /*
1180 * Write the first-level table (the list is sorted,
@@ -1206,7 +1200,7 @@ static int write_graph_chunk_oids(struct hashfile *f,
1200 void *data)
1201 {
1202 struct write_commit_graph_context *ctx = data;
1209 - struct commit **list = ctx->commits.list;
1203 + struct commit **list = ctx->commits.items;
1204 int count;
1205 for (count = 0; count < ctx->commits.nr; count++, list++) {
1206 display_progress(ctx->progress, ++ctx->progress_cnt);
@@ -1226,8 +1220,8 @@ static int write_graph_chunk_data(struct hashfile *f,
1220 void *data)
1221 {
1222 struct write_commit_graph_context *ctx = data;
1229 - struct commit **list = ctx->commits.list;
1230 - struct commit **last = ctx->commits.list + ctx->commits.nr;
1223 + struct commit **list = ctx->commits.items;
1224 + struct commit **last = ctx->commits.items + ctx->commits.nr;
1225 uint32_t num_extra_edges = 0;
1226
1227 while (list < last) {
@@ -1249,7 +1243,7 @@ static int write_graph_chunk_data(struct hashfile *f,
1243 edge_value = GRAPH_PARENT_NONE;
1244 else {
1245 edge_value = oid_pos(&parent->item->object.oid,
1252 - ctx->commits.list,
1246 + ctx->commits.items,
1247 ctx->commits.nr,
1248 commit_to_oid);
1249
@@ -1280,7 +1274,7 @@ static int write_graph_chunk_data(struct hashfile *f,
1274 edge_value = GRAPH_EXTRA_EDGES_NEEDED | num_extra_edges;
1275 else {
1276 edge_value = oid_pos(&parent->item->object.oid,
1283 - ctx->commits.list,
1277 + ctx->commits.items,
1278 ctx->commits.nr,
1279 commit_to_oid);
1280
@@ -1332,7 +1326,7 @@ static int write_graph_chunk_generation_data(struct hashfile *f,
1326 int i, num_generation_data_overflows = 0;
1327
1328 for (i = 0; i < ctx->commits.nr; i++) {
1335 - struct commit *c = ctx->commits.list[i];
1329 + struct commit *c = ctx->commits.items[i];
1330 timestamp_t offset;
1331 repo_parse_commit(ctx->r, c);
1332 offset = commit_graph_data_at(c)->generation - c->date;
@@ -1355,7 +1349,7 @@ static int write_graph_chunk_generation_data_overflow(struct hashfile *f,
1349 struct write_commit_graph_context *ctx = data;
1350 int i;
1351 for (i = 0; i < ctx->commits.nr; i++) {
1358 - struct commit *c = ctx->commits.list[i];
1352 + struct commit *c = ctx->commits.items[i];
1353 timestamp_t offset = commit_graph_data_at(c)->generation - c->date;
1354 display_progress(ctx->progress, ++ctx->progress_cnt);
1355
@@ -1372,8 +1366,8 @@ static int write_graph_chunk_extra_edges(struct hashfile *f,
1366 void *data)
1367 {
1368 struct write_commit_graph_context *ctx = data;
1375 - struct commit **list = ctx->commits.list;
1376 - struct commit **last = ctx->commits.list + ctx->commits.nr;
1369 + struct commit **list = ctx->commits.items;
1370 + struct commit **last = ctx->commits.items + ctx->commits.nr;
1371 struct commit_list *parent;
1372
1373 while (list < last) {
@@ -1393,7 +1387,7 @@ static int write_graph_chunk_extra_edges(struct hashfile *f,
1387 /* Since num_parents > 2, this initializer is safe. */
1388 for (parent = (*list)->parents->next; parent; parent = parent->next) {
1389 int edge_value = oid_pos(&parent->item->object.oid,
1396 - ctx->commits.list,
1390 + ctx->commits.items,
1391 ctx->commits.nr,
1392 commit_to_oid);
1393
@@ -1427,8 +1421,8 @@ static int write_graph_chunk_bloom_indexes(struct hashfile *f,
1421 void *data)
1422 {
1423 struct write_commit_graph_context *ctx = data;
1430 - struct commit **list = ctx->commits.list;
1431 - struct commit **last = ctx->commits.list + ctx->commits.nr;
1424 + struct commit **list = ctx->commits.items;
1425 + struct commit **last = ctx->commits.items + ctx->commits.nr;
1426 uint32_t cur_pos = 0;
1427
1428 while (list < last) {
@@ -1463,8 +1457,8 @@ static int write_graph_chunk_bloom_data(struct hashfile *f,
1457 void *data)
1458 {
1459 struct write_commit_graph_context *ctx = data;
1466 - struct commit **list = ctx->commits.list;
1467 - struct commit **last = ctx->commits.list + ctx->commits.nr;
1460 + struct commit **list = ctx->commits.items;
1461 + struct commit **last = ctx->commits.items + ctx->commits.nr;
1462
1463 trace2_bloom_filter_settings(ctx);
1464
@@ -1585,7 +1579,7 @@ static void close_reachable(struct write_commit_graph_context *ctx)
1579
1580 struct compute_generation_info {
1581 struct repository *r;
1588 - struct packed_commit_list *commits;
1582 + struct commit_stack *commits;
1583 struct progress *progress;
1584 int progress_cnt;
1585
@@ -1622,7 +1616,7 @@ static void compute_reachable_generation_numbers(
1616 struct commit_list *list = NULL;
1617
1618 for (i = 0; i < info->commits->nr; i++) {
1625 - struct commit *c = info->commits->list[i];
1619 + struct commit *c = info->commits->items[i];
1620 timestamp_t gen;
1621 repo_parse_commit(info->r, c);
1622 gen = info->get_generation(c, info->data);
@@ -1729,7 +1723,7 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
1723
1724 if (!ctx->trust_generation_numbers) {
1725 for (i = 0; i < ctx->commits.nr; i++) {
1732 - struct commit *c = ctx->commits.list[i];
1726 + struct commit *c = ctx->commits.items[i];
1727 repo_parse_commit(ctx->r, c);
1728 commit_graph_data_at(c)->generation = GENERATION_NUMBER_ZERO;
1729 }
@@ -1738,7 +1732,7 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
1732 compute_reachable_generation_numbers(&info, 2);
1733
1734 for (i = 0; i < ctx->commits.nr; i++) {
1741 - struct commit *c = ctx->commits.list[i];
1735 + struct commit *c = ctx->commits.items[i];
1736 timestamp_t offset = commit_graph_data_at(c)->generation - c->date;
1737 if (offset > GENERATION_NUMBER_V2_OFFSET_MAX)
1738 ctx->num_generation_data_overflows++;
@@ -1760,8 +1754,8 @@ void ensure_generations_valid(struct repository *r,
1754 struct commit **commits, size_t nr)
1755 {
1756 int generation_version = get_configured_generation_version(r);
1763 - struct packed_commit_list list = {
1764 - .list = commits,
1757 + struct commit_stack list = {
1758 + .items = commits,
1759 .alloc = nr,
1760 .nr = nr,
1761 };
@@ -1804,7 +1798,7 @@ static void compute_bloom_filters(struct write_commit_graph_context *ctx)
1798 _("Computing commit changed paths Bloom filters"),
1799 ctx->commits.nr);
1800
1807 - DUP_ARRAY(sorted_commits, ctx->commits.list, ctx->commits.nr);
1801 + DUP_ARRAY(sorted_commits, ctx->commits.items, ctx->commits.nr);
1802
1803 if (ctx->order_by_pack)
1804 QSORT(sorted_commits, ctx->commits.nr, commit_pos_cmp);
@@ -1992,26 +1986,26 @@ static void copy_oids_to_commits(struct write_commit_graph_context *ctx)
1986 oid_array_sort(&ctx->oids);
1987 for (i = 0; i < ctx->oids.nr; i = oid_array_next_unique(&ctx->oids, i)) {
1988 unsigned int num_parents;
1989 + struct commit *commit;
1990
1991 display_progress(ctx->progress, i + 1);
1992
1998 - ALLOC_GROW(ctx->commits.list, ctx->commits.nr + 1, ctx->commits.alloc);
1999 - ctx->commits.list[ctx->commits.nr] = lookup_commit(ctx->r, &ctx->oids.oid[i]);
1993 + commit = lookup_commit(ctx->r, &ctx->oids.oid[i]);
1994
1995 if (ctx->split && flags != COMMIT_GRAPH_SPLIT_REPLACE &&
2002 - commit_graph_position(ctx->commits.list[ctx->commits.nr]) != COMMIT_NOT_FROM_GRAPH)
1996 + commit_graph_position(commit) != COMMIT_NOT_FROM_GRAPH)
1997 continue;
1998
1999 if (ctx->split && flags == COMMIT_GRAPH_SPLIT_REPLACE)
2006 - repo_parse_commit(ctx->r, ctx->commits.list[ctx->commits.nr]);
2000 + repo_parse_commit(ctx->r, commit);
2001 else
2008 - repo_parse_commit_no_graph(ctx->r, ctx->commits.list[ctx->commits.nr]);
2002 + repo_parse_commit_no_graph(ctx->r, commit);
2003
2010 - num_parents = commit_list_count(ctx->commits.list[ctx->commits.nr]->parents);
2004 + num_parents = commit_list_count(commit->parents);
2005 if (num_parents > 2)
2006 ctx->num_extra_edges += num_parents - 1;
2007
2014 - ctx->commits.nr++;
2008 + commit_stack_push(&ctx->commits, commit);
2009 }
2010 stop_progress(&ctx->progress);
2011 }
@@ -2330,7 +2324,7 @@ static void merge_commit_graph(struct write_commit_graph_context *ctx,
2324 oid_to_hex(&g->oid),
2325 (uintmax_t)st_add(ctx->commits.nr, g->num_commits));
2326
2333 - ALLOC_GROW(ctx->commits.list, ctx->commits.nr + g->num_commits, ctx->commits.alloc);
2327 + commit_stack_grow(&ctx->commits, g->num_commits);
2328
2329 for (i = 0; i < g->num_commits; i++) {
2330 struct object_id oid;
@@ -2343,10 +2337,8 @@ static void merge_commit_graph(struct write_commit_graph_context *ctx,
2337 /* only add commits if they still exist in the repo */
2338 result = lookup_commit_reference_gently(ctx->r, &oid, 1);
2339
2346 - if (result) {
2347 - ctx->commits.list[ctx->commits.nr] = result;
2348 - ctx->commits.nr++;
2349 - }
2340 + if (result)
2341 + commit_stack_push(&ctx->commits, result);
2342 }
2343 }
2344
@@ -2367,14 +2359,14 @@ static void sort_and_scan_merged_commits(struct write_commit_graph_context *ctx)
2359 _("Scanning merged commits"),
2360 ctx->commits.nr);
2361
2370 - QSORT(ctx->commits.list, ctx->commits.nr, commit_compare);
2362 + QSORT(ctx->commits.items, ctx->commits.nr, commit_compare);
2363
2364 ctx->num_extra_edges = 0;
2365 for (i = 0; i < ctx->commits.nr; i++) {
2366 display_progress(ctx->progress, i + 1);
2367
2376 - if (i && oideq(&ctx->commits.list[i - 1]->object.oid,
2377 - &ctx->commits.list[i]->object.oid)) {
2368 + if (i && oideq(&ctx->commits.items[i - 1]->object.oid,
2369 + &ctx->commits.items[i]->object.oid)) {
2370 /*
2371 * Silently ignore duplicates. These were likely
2372 * created due to a commit appearing in multiple
@@ -2385,10 +2377,10 @@ static void sort_and_scan_merged_commits(struct write_commit_graph_context *ctx)
2377 } else {
2378 unsigned int num_parents;
2379
2388 - ctx->commits.list[dedup_i] = ctx->commits.list[i];
2380 + ctx->commits.items[dedup_i] = ctx->commits.items[i];
2381 dedup_i++;
2382
2391 - num_parents = commit_list_count(ctx->commits.list[i]->parents);
2383 + num_parents = commit_list_count(ctx->commits.items[i]->parents);
2384 if (num_parents > 2)
2385 ctx->num_extra_edges += num_parents - 1;
2386 }
@@ -2666,7 +2658,7 @@ int write_commit_graph(struct odb_source *source,
2658 cleanup:
2659 free(ctx.graph_name);
2660 free(ctx.base_graph_name);
2669 - free(ctx.commits.list);
2661 + commit_stack_clear(&ctx.commits);
2662 oid_array_clear(&ctx.oids);
2663 clear_topo_level_slab(&topo_levels);
2664