]> git.ipfire.org Git - thirdparty/git.git/commitdiff
commit-graph: add a slab to store topological levels
authorAbhishek Kumar <abhishekkumar8222@gmail.com>
Sat, 16 Jan 2021 18:11:12 +0000 (18:11 +0000)
committerJunio C Hamano <gitster@pobox.com>
Tue, 19 Jan 2021 00:21:18 +0000 (16:21 -0800)
In a later commit we will introduce corrected commit date as the
generation number v2. Corrected commit dates will be stored in the new
seperate Generation Data chunk. However, to ensure backwards
compatibility with "Old" Git we need to continue to write generation
number v1 (topological levels) to the commit data chunk. Thus, we need
to compute and store both versions of generation numbers to write the
commit-graph file.

Therefore, let's introduce a commit-slab `topo_level_slab` to store
topological levels; corrected commit date will be stored in the member
`generation` of struct commit_graph_data.

The macros `GENERATION_NUMBER_INFINITY` and `GENERATION_NUMBER_ZERO`
mark commits not in the commit-graph file and commits written by a
version of Git that did not compute generation numbers respectively.
Generation numbers are computed identically for both kinds of commits.

A "slab-miss" should return `GENERATION_NUMBER_INFINITY` as the commit
is not in the commit-graph file. However, since the slab is
zero-initialized, it returns 0 (or rather `GENERATION_NUMBER_ZERO`).
Thus, we no longer need to check if the topological level of a commit is
`GENERATION_NUMBER_INFINITY`.

We will add a pointer to the slab in `struct write_commit_graph_context`
and `struct commit_graph` to populate the slab in
`fill_commit_graph_info` if the commit has a pre-computed topological
level as in case of split commit-graphs.

Signed-off-by: Abhishek Kumar <abhishekkumar8222@gmail.com>
Reviewed-by: Taylor Blau <me@ttaylorr.com>
Reviewed-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
commit-graph.c
commit-graph.h

index 123dbc7c21b481293d6a0309ec9f7f374272fcac..eb681e6cf53812785be958d08f5acc7191a14358 100644 (file)
@@ -64,6 +64,8 @@ void git_test_write_commit_graph_or_die(void)
 /* Remember to update object flag allocation in object.h */
 #define REACHABLE       (1u<<15)
 
+define_commit_slab(topo_level_slab, uint32_t);
+
 /* Keep track of the order in which commits are added to our list. */
 define_commit_slab(commit_pos, int);
 static struct commit_pos commit_pos = COMMIT_SLAB_INIT(1, commit_pos);
@@ -772,6 +774,9 @@ static void fill_commit_graph_info(struct commit *item, struct commit_graph *g,
        item->date = (timestamp_t)((date_high << 32) | date_low);
 
        graph_data->generation = get_be32(commit_data + g->hash_len + 8) >> 2;
+
+       if (g->topo_levels)
+               *topo_level_slab_at(g->topo_levels, item) = get_be32(commit_data + g->hash_len + 8) >> 2;
 }
 
 static inline void set_commit_tree(struct commit *c, struct tree *t)
@@ -960,6 +965,7 @@ struct write_commit_graph_context {
                 changed_paths:1,
                 order_by_pack:1;
 
+       struct topo_level_slab *topo_levels;
        const struct commit_graph_opts *opts;
        size_t total_bloom_filter_data_size;
        const struct bloom_filter_settings *bloom_settings;
@@ -1106,7 +1112,7 @@ static int write_graph_chunk_data(struct hashfile *f,
                else
                        packedDate[0] = 0;
 
-               packedDate[0] |= htonl(commit_graph_data_at(*list)->generation << 2);
+               packedDate[0] |= htonl(*topo_level_slab_at(ctx->topo_levels, *list) << 2);
 
                packedDate[1] = htonl((*list)->date);
                hashwrite(f, packedDate, 8);
@@ -1336,11 +1342,10 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
                                        _("Computing commit graph generation numbers"),
                                        ctx->commits.nr);
        for (i = 0; i < ctx->commits.nr; i++) {
-               uint32_t generation = commit_graph_data_at(ctx->commits.list[i])->generation;
+               uint32_t level = *topo_level_slab_at(ctx->topo_levels, ctx->commits.list[i]);
 
                display_progress(ctx->progress, i + 1);
-               if (generation != GENERATION_NUMBER_INFINITY &&
-                   generation != GENERATION_NUMBER_ZERO)
+               if (level != GENERATION_NUMBER_ZERO)
                        continue;
 
                commit_list_insert(ctx->commits.list[i], &list);
@@ -1348,29 +1353,26 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
                        struct commit *current = list->item;
                        struct commit_list *parent;
                        int all_parents_computed = 1;
-                       uint32_t max_generation = 0;
+                       uint32_t max_level = 0;
 
                        for (parent = current->parents; parent; parent = parent->next) {
-                               generation = commit_graph_data_at(parent->item)->generation;
+                               level = *topo_level_slab_at(ctx->topo_levels, parent->item);
 
-                               if (generation == GENERATION_NUMBER_INFINITY ||
-                                   generation == GENERATION_NUMBER_ZERO) {
+                               if (level == GENERATION_NUMBER_ZERO) {
                                        all_parents_computed = 0;
                                        commit_list_insert(parent->item, &list);
                                        break;
-                               } else if (generation > max_generation) {
-                                       max_generation = generation;
+                               } else if (level > max_level) {
+                                       max_level = level;
                                }
                        }
 
                        if (all_parents_computed) {
-                               struct commit_graph_data *data = commit_graph_data_at(current);
-
-                               data->generation = max_generation + 1;
                                pop_commit(&list);
 
-                               if (data->generation > GENERATION_NUMBER_MAX)
-                                       data->generation = GENERATION_NUMBER_MAX;
+                               if (max_level > GENERATION_NUMBER_MAX - 1)
+                                       max_level = GENERATION_NUMBER_MAX - 1;
+                               *topo_level_slab_at(ctx->topo_levels, current) = max_level + 1;
                        }
                }
        }
@@ -2106,6 +2108,7 @@ int write_commit_graph(struct object_directory *odb,
        int res = 0;
        int replace = 0;
        struct bloom_filter_settings bloom_settings = DEFAULT_BLOOM_FILTER_SETTINGS;
+       struct topo_level_slab topo_levels;
 
        prepare_repo_settings(the_repository);
        if (!the_repository->settings.core_commit_graph) {
@@ -2132,6 +2135,18 @@ int write_commit_graph(struct object_directory *odb,
                                                         bloom_settings.max_changed_paths);
        ctx->bloom_settings = &bloom_settings;
 
+       init_topo_level_slab(&topo_levels);
+       ctx->topo_levels = &topo_levels;
+
+       if (ctx->r->objects->commit_graph) {
+               struct commit_graph *g = ctx->r->objects->commit_graph;
+
+               while (g) {
+                       g->topo_levels = &topo_levels;
+                       g = g->base_graph;
+               }
+       }
+
        if (flags & COMMIT_GRAPH_WRITE_BLOOM_FILTERS)
                ctx->changed_paths = 1;
        if (!(flags & COMMIT_GRAPH_NO_WRITE_BLOOM_FILTERS)) {
index f8e92500c6e4bc004c9945b29d27da89319d0bd0..00f00745b79a4734185def56d9773fe814092c8e 100644 (file)
@@ -73,6 +73,7 @@ struct commit_graph {
        const unsigned char *chunk_bloom_indexes;
        const unsigned char *chunk_bloom_data;
 
+       struct topo_level_slab *topo_levels;
        struct bloom_filter_settings *bloom_filter_settings;
 };