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);
|
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;
|
int i;
|
||||||
struct commit_list *list = NULL;
|
struct commit_list *list = NULL;
|
||||||
|
|
||||||
if (ctx->report_progress)
|
for (i = 0; i < info->commits->nr; i++) {
|
||||||
ctx->progress = start_delayed_progress(
|
struct commit *c = info->commits->list[i];
|
||||||
_("Computing commit graph topological levels"),
|
timestamp_t gen;
|
||||||
ctx->commits.nr);
|
repo_parse_commit(info->r, c);
|
||||||
for (i = 0; i < ctx->commits.nr; i++) {
|
gen = info->get_generation(c, info->data);
|
||||||
struct commit *c = ctx->commits.list[i];
|
display_progress(info->progress, info->progress_cnt + 1);
|
||||||
uint32_t level;
|
|
||||||
|
|
||||||
repo_parse_commit(ctx->r, c);
|
if (gen != GENERATION_NUMBER_ZERO && gen != GENERATION_NUMBER_INFINITY)
|
||||||
level = *topo_level_slab_at(ctx->topo_levels, c);
|
|
||||||
|
|
||||||
display_progress(ctx->progress, i + 1);
|
|
||||||
if (level != GENERATION_NUMBER_ZERO)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
commit_list_insert(c, &list);
|
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 *current = list->item;
|
||||||
struct commit_list *parent;
|
struct commit_list *parent;
|
||||||
int all_parents_computed = 1;
|
int all_parents_computed = 1;
|
||||||
uint32_t max_level = 0;
|
uint32_t max_gen = 0;
|
||||||
|
|
||||||
for (parent = current->parents; parent; parent = parent->next) {
|
for (parent = current->parents; parent; parent = parent->next) {
|
||||||
repo_parse_commit(ctx->r, parent->item);
|
repo_parse_commit(info->r, parent->item);
|
||||||
level = *topo_level_slab_at(ctx->topo_levels, parent->item);
|
gen = info->get_generation(parent->item, info->data);
|
||||||
|
|
||||||
if (level == GENERATION_NUMBER_ZERO) {
|
if (gen == GENERATION_NUMBER_ZERO) {
|
||||||
all_parents_computed = 0;
|
all_parents_computed = 0;
|
||||||
commit_list_insert(parent->item, &list);
|
commit_list_insert(parent->item, &list);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (level > max_level)
|
if (gen > max_gen)
|
||||||
max_level = level;
|
max_gen = gen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (all_parents_computed) {
|
if (all_parents_computed) {
|
||||||
pop_commit(&list);
|
pop_commit(&list);
|
||||||
|
gen = compute_generation_from_max(
|
||||||
if (max_level > GENERATION_NUMBER_V1_MAX - 1)
|
current, max_gen,
|
||||||
max_level = GENERATION_NUMBER_V1_MAX - 1;
|
generation_version);
|
||||||
*topo_level_slab_at(ctx->topo_levels, current) = max_level + 1;
|
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);
|
stop_progress(&ctx->progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user