Skip to content

Commit 368d19b

Browse files
derrickstoleettaylorr
authored andcommitted
commit-graph: refactor compute_topological_levels()
This patch extracts the common code used to compute topological levels and corrected committer dates into a common routine, compute_reachable_generation_numbers(). For ease of reading, it only modifies compute_topological_levels() to use this new routine, leaving compute_generation_numbers() to be modified in the next change. This new routine dispatches to call the necessary functions to get and set the generation number for a given commit through a vtable (the compute_generation_info struct). Computing the generation number itself is done in compute_generation_from_max(), which dispatches its implementation based on the generation version requested, or issuing a BUG() for unrecognized generation versions. This does not use a vtable because the logic depends only on the generation number version, not where the data is being loaded from or being stored to. This is a subtle point that will make more sense in a future change that modifies the in-memory generation values instead of just preparing values for writing to a commit-graph file. This change looks like it adds a lot of new code. However, two upcoming changes will be quite small due to the work being done in this change. Co-authored-by: Taylor Blau <[email protected]> Signed-off-by: Taylor Blau <[email protected]> Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b2c51b7 commit 368d19b

File tree

1 file changed

+83
-23
lines changed

1 file changed

+83
-23
lines changed

commit-graph.c

Lines changed: 83 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,56 +1446,116 @@ static void close_reachable(struct write_commit_graph_context *ctx)
14461446
stop_progress(&ctx->progress);
14471447
}
14481448

1449-
static void compute_topological_levels(struct write_commit_graph_context *ctx)
1449+
struct compute_generation_info {
1450+
struct repository *r;
1451+
struct packed_commit_list *commits;
1452+
struct progress *progress;
1453+
int progress_cnt;
1454+
1455+
timestamp_t (*get_generation)(struct commit *c, void *data);
1456+
void (*set_generation)(struct commit *c, timestamp_t gen, void *data);
1457+
void *data;
1458+
};
1459+
1460+
static timestamp_t compute_generation_from_max(struct commit *c,
1461+
timestamp_t max_gen,
1462+
int generation_version)
1463+
{
1464+
switch (generation_version) {
1465+
case 1: /* topological levels */
1466+
if (max_gen > GENERATION_NUMBER_V1_MAX - 1)
1467+
max_gen = GENERATION_NUMBER_V1_MAX - 1;
1468+
return max_gen + 1;
1469+
1470+
case 2: /* corrected commit date */
1471+
if (c->date && c->date > max_gen)
1472+
max_gen = c->date - 1;
1473+
return max_gen + 1;
1474+
1475+
default:
1476+
BUG("attempting unimplemented version");
1477+
}
1478+
}
1479+
1480+
static void compute_reachable_generation_numbers(
1481+
struct compute_generation_info *info,
1482+
int generation_version)
14501483
{
14511484
int i;
14521485
struct commit_list *list = NULL;
14531486

1454-
if (ctx->report_progress)
1455-
ctx->progress = start_delayed_progress(
1456-
_("Computing commit graph topological levels"),
1457-
ctx->commits.nr);
1458-
for (i = 0; i < ctx->commits.nr; i++) {
1459-
struct commit *c = ctx->commits.list[i];
1460-
uint32_t level;
1461-
1462-
repo_parse_commit(ctx->r, c);
1463-
level = *topo_level_slab_at(ctx->topo_levels, c);
1487+
for (i = 0; i < info->commits->nr; i++) {
1488+
struct commit *c = info->commits->list[i];
1489+
timestamp_t gen;
1490+
repo_parse_commit(info->r, c);
1491+
gen = info->get_generation(c, info->data);
1492+
display_progress(info->progress, info->progress_cnt + 1);
14641493

1465-
display_progress(ctx->progress, i + 1);
1466-
if (level != GENERATION_NUMBER_ZERO)
1494+
if (gen != GENERATION_NUMBER_ZERO && gen != GENERATION_NUMBER_INFINITY)
14671495
continue;
14681496

14691497
commit_list_insert(c, &list);
14701498
while (list) {
14711499
struct commit *current = list->item;
14721500
struct commit_list *parent;
14731501
int all_parents_computed = 1;
1474-
uint32_t max_level = 0;
1502+
uint32_t max_gen = 0;
14751503

14761504
for (parent = current->parents; parent; parent = parent->next) {
1477-
repo_parse_commit(ctx->r, parent->item);
1478-
level = *topo_level_slab_at(ctx->topo_levels, parent->item);
1505+
repo_parse_commit(info->r, parent->item);
1506+
gen = info->get_generation(parent->item, info->data);
14791507

1480-
if (level == GENERATION_NUMBER_ZERO) {
1508+
if (gen == GENERATION_NUMBER_ZERO) {
14811509
all_parents_computed = 0;
14821510
commit_list_insert(parent->item, &list);
14831511
break;
14841512
}
14851513

1486-
if (level > max_level)
1487-
max_level = level;
1514+
if (gen > max_gen)
1515+
max_gen = gen;
14881516
}
14891517

14901518
if (all_parents_computed) {
14911519
pop_commit(&list);
1492-
1493-
if (max_level > GENERATION_NUMBER_V1_MAX - 1)
1494-
max_level = GENERATION_NUMBER_V1_MAX - 1;
1495-
*topo_level_slab_at(ctx->topo_levels, current) = max_level + 1;
1520+
gen = compute_generation_from_max(
1521+
current, max_gen,
1522+
generation_version);
1523+
info->set_generation(current, gen, info->data);
14961524
}
14971525
}
14981526
}
1527+
}
1528+
1529+
static timestamp_t get_topo_level(struct commit *c, void *data)
1530+
{
1531+
struct write_commit_graph_context *ctx = data;
1532+
return *topo_level_slab_at(ctx->topo_levels, c);
1533+
}
1534+
1535+
static void set_topo_level(struct commit *c, timestamp_t t, void *data)
1536+
{
1537+
struct write_commit_graph_context *ctx = data;
1538+
*topo_level_slab_at(ctx->topo_levels, c) = (uint32_t)t;
1539+
}
1540+
1541+
static void compute_topological_levels(struct write_commit_graph_context *ctx)
1542+
{
1543+
struct compute_generation_info info = {
1544+
.r = ctx->r,
1545+
.commits = &ctx->commits,
1546+
.get_generation = get_topo_level,
1547+
.set_generation = set_topo_level,
1548+
.data = ctx,
1549+
};
1550+
1551+
if (ctx->report_progress)
1552+
info.progress = ctx->progress
1553+
= start_delayed_progress(
1554+
_("Computing commit graph topological levels"),
1555+
ctx->commits.nr);
1556+
1557+
compute_reachable_generation_numbers(&info, 1);
1558+
14991559
stop_progress(&ctx->progress);
15001560
}
15011561

0 commit comments

Comments
 (0)