Browse Source

commit-graph: compute generation numbers

While preparing commits to be written into a commit-graph file, compute
the generation numbers using a depth-first strategy.

The only commits that are walked in this depth-first search are those
without a precomputed generation number. Thus, computation time will be
relative to the number of new commits to the commit-graph file.

If a computed generation number would exceed GENERATION_NUMBER_MAX, then
use GENERATION_NUMBER_MAX instead.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Derrick Stolee 7 years ago committed by Junio C Hamano
parent
commit
3258c66332
  1. 43
      commit-graph.c

43
commit-graph.c

@ -439,6 +439,8 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len, @@ -439,6 +439,8 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
else
packedDate[0] = 0;

packedDate[0] |= htonl((*list)->generation << 2);

packedDate[1] = htonl((*list)->date);
hashwrite(f, packedDate, 8);

@ -571,6 +573,45 @@ static void close_reachable(struct packed_oid_list *oids) @@ -571,6 +573,45 @@ static void close_reachable(struct packed_oid_list *oids)
}
}

static void compute_generation_numbers(struct packed_commit_list* commits)
{
int i;
struct commit_list *list = NULL;

for (i = 0; i < commits->nr; i++) {
if (commits->list[i]->generation != GENERATION_NUMBER_INFINITY &&
commits->list[i]->generation != GENERATION_NUMBER_ZERO)
continue;

commit_list_insert(commits->list[i], &list);
while (list) {
struct commit *current = list->item;
struct commit_list *parent;
int all_parents_computed = 1;
uint32_t max_generation = 0;

for (parent = current->parents; parent; parent = parent->next) {
if (parent->item->generation == GENERATION_NUMBER_INFINITY ||
parent->item->generation == GENERATION_NUMBER_ZERO) {
all_parents_computed = 0;
commit_list_insert(parent->item, &list);
break;
} else if (parent->item->generation > max_generation) {
max_generation = parent->item->generation;
}
}

if (all_parents_computed) {
current->generation = max_generation + 1;
pop_commit(&list);

if (current->generation > GENERATION_NUMBER_MAX)
current->generation = GENERATION_NUMBER_MAX;
}
}
}
}

void write_commit_graph(const char *obj_dir,
const char **pack_indexes,
int nr_packs,
@ -694,6 +735,8 @@ void write_commit_graph(const char *obj_dir, @@ -694,6 +735,8 @@ void write_commit_graph(const char *obj_dir,
if (commits.nr >= GRAPH_PARENT_MISSING)
die(_("too many commits to write graph"));

compute_generation_numbers(&commits);

graph_name = get_commit_graph_filename(obj_dir);
fd = hold_lock_file_for_update(&lk, graph_name, 0);


Loading…
Cancel
Save