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 <me@ttaylorr.com> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
b2c51b7590
commit
368d19b0b7
106
commit-graph.c
106
commit-graph.c
@ -1446,24 +1446,52 @@ static void close_reachable(struct write_commit_graph_context *ctx)
|
||||
stop_progress(&ctx->progress);
|
||||
}
|
||||
|
||||
static void compute_topological_levels(struct write_commit_graph_context *ctx)
|
||||
struct compute_generation_info {
|
||||
struct repository *r;
|
||||
struct packed_commit_list *commits;
|
||||
struct progress *progress;
|
||||
int progress_cnt;
|
||||
|
||||
timestamp_t (*get_generation)(struct commit *c, void *data);
|
||||
void (*set_generation)(struct commit *c, timestamp_t gen, void *data);
|
||||
void *data;
|
||||
};
|
||||
|
||||
static timestamp_t compute_generation_from_max(struct commit *c,
|
||||
timestamp_t max_gen,
|
||||
int generation_version)
|
||||
{
|
||||
switch (generation_version) {
|
||||
case 1: /* topological levels */
|
||||
if (max_gen > GENERATION_NUMBER_V1_MAX - 1)
|
||||
max_gen = GENERATION_NUMBER_V1_MAX - 1;
|
||||
return max_gen + 1;
|
||||
|
||||
case 2: /* corrected commit date */
|
||||
if (c->date && c->date > max_gen)
|
||||
max_gen = c->date - 1;
|
||||
return max_gen + 1;
|
||||
|
||||
default:
|
||||
BUG("attempting unimplemented version");
|
||||
}
|
||||
}
|
||||
|
||||
static void compute_reachable_generation_numbers(
|
||||
struct compute_generation_info *info,
|
||||
int generation_version)
|
||||
{
|
||||
int i;
|
||||
struct commit_list *list = NULL;
|
||||
|
||||
if (ctx->report_progress)
|
||||
ctx->progress = start_delayed_progress(
|
||||
_("Computing commit graph topological levels"),
|
||||
ctx->commits.nr);
|
||||
for (i = 0; i < ctx->commits.nr; i++) {
|
||||
struct commit *c = ctx->commits.list[i];
|
||||
uint32_t level;
|
||||
for (i = 0; i < info->commits->nr; i++) {
|
||||
struct commit *c = info->commits->list[i];
|
||||
timestamp_t gen;
|
||||
repo_parse_commit(info->r, c);
|
||||
gen = info->get_generation(c, info->data);
|
||||
display_progress(info->progress, info->progress_cnt + 1);
|
||||
|
||||
repo_parse_commit(ctx->r, c);
|
||||
level = *topo_level_slab_at(ctx->topo_levels, c);
|
||||
|
||||
display_progress(ctx->progress, i + 1);
|
||||
if (level != GENERATION_NUMBER_ZERO)
|
||||
if (gen != GENERATION_NUMBER_ZERO && gen != GENERATION_NUMBER_INFINITY)
|
||||
continue;
|
||||
|
||||
commit_list_insert(c, &list);
|
||||
@ -1471,31 +1499,63 @@ static void compute_topological_levels(struct write_commit_graph_context *ctx)
|
||||
struct commit *current = list->item;
|
||||
struct commit_list *parent;
|
||||
int all_parents_computed = 1;
|
||||
uint32_t max_level = 0;
|
||||
uint32_t max_gen = 0;
|
||||
|
||||
for (parent = current->parents; parent; parent = parent->next) {
|
||||
repo_parse_commit(ctx->r, parent->item);
|
||||
level = *topo_level_slab_at(ctx->topo_levels, parent->item);
|
||||
repo_parse_commit(info->r, parent->item);
|
||||
gen = info->get_generation(parent->item, info->data);
|
||||
|
||||
if (level == GENERATION_NUMBER_ZERO) {
|
||||
if (gen == GENERATION_NUMBER_ZERO) {
|
||||
all_parents_computed = 0;
|
||||
commit_list_insert(parent->item, &list);
|
||||
break;
|
||||
}
|
||||
|
||||
if (level > max_level)
|
||||
max_level = level;
|
||||
if (gen > max_gen)
|
||||
max_gen = gen;
|
||||
}
|
||||
|
||||
if (all_parents_computed) {
|
||||
pop_commit(&list);
|
||||
|
||||
if (max_level > GENERATION_NUMBER_V1_MAX - 1)
|
||||
max_level = GENERATION_NUMBER_V1_MAX - 1;
|
||||
*topo_level_slab_at(ctx->topo_levels, current) = max_level + 1;
|
||||
gen = compute_generation_from_max(
|
||||
current, max_gen,
|
||||
generation_version);
|
||||
info->set_generation(current, gen, info->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static timestamp_t get_topo_level(struct commit *c, void *data)
|
||||
{
|
||||
struct write_commit_graph_context *ctx = data;
|
||||
return *topo_level_slab_at(ctx->topo_levels, c);
|
||||
}
|
||||
|
||||
static void set_topo_level(struct commit *c, timestamp_t t, void *data)
|
||||
{
|
||||
struct write_commit_graph_context *ctx = data;
|
||||
*topo_level_slab_at(ctx->topo_levels, c) = (uint32_t)t;
|
||||
}
|
||||
|
||||
static void compute_topological_levels(struct write_commit_graph_context *ctx)
|
||||
{
|
||||
struct compute_generation_info info = {
|
||||
.r = ctx->r,
|
||||
.commits = &ctx->commits,
|
||||
.get_generation = get_topo_level,
|
||||
.set_generation = set_topo_level,
|
||||
.data = ctx,
|
||||
};
|
||||
|
||||
if (ctx->report_progress)
|
||||
info.progress = ctx->progress
|
||||
= start_delayed_progress(
|
||||
_("Computing commit graph topological levels"),
|
||||
ctx->commits.nr);
|
||||
|
||||
compute_reachable_generation_numbers(&info, 1);
|
||||
|
||||
stop_progress(&ctx->progress);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user