Re: [PATCH v3 05/11] commit-graph: return 64-bit generation number
- From
Jakub Narębski <jnareb@gmail.com>
- Date
- Aug 21, 2020, 13:14 UTC
- Message-ID
- <85d03km98l.fsf@gmail.com>
- In-Reply-To
- <6be759a9542114e4de41422efa18491085e19682.1597509583.git.gitgitgadget@gmail.com>
"Abhishek Kumar via GitGitGadget" <gitgitgadget@gmail.com> writes:
> From: Abhishek Kumar <abhishekkumar8222@gmail.com> > > In a preparatory step, let's return timestamp_t values from > commit_graph_generation(), use timestamp_t for local variables
All right, this is all good.
> and define GENERATION_NUMBER_INFINITY as (2 ^ 63 - 1) instead.
This needs more detailed examination. There are two similar constants, GENERATION_NUMBER_INFINITY and GENERATION_NUMBER_MAX. The former is used for newest commits outside the commit-graph, while the latter is maximum number that commits in the commit-graph can have (because of the storage limitations). We therefore need GENERATION_NUMBER_INFINITY to be larger than GENERATION_NUMBER_MAX, and it is (and was).
The GENERATION_NUMBER_INFINITY is because of the above requirement traditionally taken as maximum value that can be represented in the data type used to store commit's generation number _in memory_, but it can be less. For timestamp_t the maximum value that can be represented is (2 ^ 63 - 1).
All right then.
>
The commit message says nothing about the new symbolic constant GENERATION_NUMBER_V1_INFINITY, though.
I'm not sure it is even needed (see comments below).
Show 10 quoted lines
> Signed-off-by: Abhishek Kumar <abhishekkumar8222@gmail.com> > --- > commit-graph.c | 18 +++++++++--------- > commit-graph.h | 4 ++-- > commit-reach.c | 32 ++++++++++++++++---------------- > commit-reach.h | 2 +- > commit.h | 3 ++- > revision.c | 10 +++++----- > upload-pack.c | 2 +- > 7 files changed, 36 insertions(+), 35 deletions(-)
I hope that changing the type returned by commit_graph_generation() and stored in 'generation' field of `struct commit_graph_data` would mean that the compiler or at least the linter would catch all the places that need updating the type.
Just in case, I have performed a simple code search and it agrees with the above list (one search result missing, in commit.c, was handled by previous patch).
Show 36 quoted lines
>
> diff --git a/commit-graph.c b/commit-graph.c
> index fb6e2bf18f..7f9f858577 100644
> --- a/commit-graph.c
> +++ b/commit-graph.c
> @@ -99,7 +99,7 @@ uint32_t commit_graph_position(const struct commit *c)
> return data ? data->graph_pos : COMMIT_NOT_FROM_GRAPH;
> }
>
> -uint32_t commit_graph_generation(const struct commit *c)
> +timestamp_t commit_graph_generation(const struct commit *c)
> {
> struct commit_graph_data *data =
> commit_graph_data_slab_peek(&commit_graph_data_slab, c);
> @@ -115,8 +115,8 @@ uint32_t commit_graph_generation(const struct commit *c)
> int compare_commits_by_gen(const void *_a, const void *_b)
> {
> const struct commit *a = _a, *b = _b;
> - const uint32_t generation_a = commit_graph_generation(a);
> - const uint32_t generation_b = commit_graph_generation(b);
> + const timestamp_t generation_a = commit_graph_generation(a);
> + const timestamp_t generation_b = commit_graph_generation(b);
>
> /* older commits first */
> if (generation_a < generation_b)
> @@ -159,8 +159,8 @@ static int commit_gen_cmp(const void *va, const void *vb)
> const struct commit *a = *(const struct commit **)va;
> const struct commit *b = *(const struct commit **)vb;
>
> - uint32_t generation_a = commit_graph_data_at(a)->generation;
> - uint32_t generation_b = commit_graph_data_at(b)->generation;
> + const timestamp_t generation_a = commit_graph_data_at(a)->generation;
> + const timestamp_t generation_b = commit_graph_data_at(b)->generation;
> /* lower generation commits first */
> if (generation_a < generation_b)
> return -1;All right.
> @@ -1338,7 +1338,7 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx) > uint32_t generation = commit_graph_data_at(ctx->commits.list[i])->generation;
Shouldn't this be
- uint32_t generation = commit_graph_data_at(ctx->commits.list[i])->generation; + timestamp_t generation = commit_graph_data_at(ctx->commits.list[i])->generation;
> > display_progress(ctx->progress, i + 1); > - if (generation != GENERATION_NUMBER_INFINITY && > + if (generation != GENERATION_NUMBER_V1_INFINITY &&
Then there would be no need for this change, isn't it?
Show 9 quoted lines
> generation != GENERATION_NUMBER_ZERO)
> continue;
>
> @@ -1352,7 +1352,7 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
> for (parent = current->parents; parent; parent = parent->next) {
> generation = commit_graph_data_at(parent->item)->generation;
>
> - if (generation == GENERATION_NUMBER_INFINITY ||
> + if (generation == GENERATION_NUMBER_V1_INFINITY ||And this one either.
Show 11 quoted lines
> generation == GENERATION_NUMBER_ZERO) {
> all_parents_computed = 0;
> commit_list_insert(parent->item, &list);
> @@ -2355,8 +2355,8 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
> for (i = 0; i < g->num_commits; i++) {
> struct commit *graph_commit, *odb_commit;
> struct commit_list *graph_parents, *odb_parents;
> - uint32_t max_generation = 0;
> - uint32_t generation;
> + timestamp_t max_generation = 0;
> + timestamp_t generation;All right.
Show 14 quoted lines
>
> display_progress(progress, i + 1);
> hashcpy(cur_oid.hash, g->chunk_oid_lookup + g->hash_len * i);
> diff --git a/commit-graph.h b/commit-graph.h
> index 701e3d41aa..430bc830bb 100644
> --- a/commit-graph.h
> +++ b/commit-graph.h
> @@ -138,13 +138,13 @@ void disable_commit_graph(struct repository *r);
>
> struct commit_graph_data {
> uint32_t graph_pos;
> - uint32_t generation;
> + timestamp_t generation;
> };All right; this is the main part of this change.
Show 7 quoted lines
> > /* > * Commits should be parsed before accessing generation, graph positions. > */ > -uint32_t commit_graph_generation(const struct commit *); > +timestamp_t commit_graph_generation(const struct commit *); > uint32_t commit_graph_position(const struct commit *);
As is this one.
Show 21 quoted lines
>
> int compare_commits_by_gen(const void *_a, const void *_b);
> diff --git a/commit-reach.c b/commit-reach.c
> index c83cc291e7..470bc80139 100644
> --- a/commit-reach.c
> +++ b/commit-reach.c
> @@ -32,12 +32,12 @@ static int queue_has_nonstale(struct prio_queue *queue)
> static struct commit_list *paint_down_to_common(struct repository *r,
> struct commit *one, int n,
> struct commit **twos,
> - int min_generation)
> + timestamp_t min_generation)
> {
> struct prio_queue queue = { compare_commits_by_gen_then_commit_date };
> struct commit_list *result = NULL;
> int i;
> - uint32_t last_gen = GENERATION_NUMBER_INFINITY;
> + timestamp_t last_gen = GENERATION_NUMBER_INFINITY;
>
> if (!min_generation)
> queue.compare = compare_commits_by_commit_date;All right.
Show 13 quoted lines
> @@ -58,10 +58,10 @@ static struct commit_list *paint_down_to_common(struct repository *r,
> struct commit *commit = prio_queue_get(&queue);
> struct commit_list *parents;
> int flags;
> - uint32_t generation = commit_graph_generation(commit);
> + timestamp_t generation = commit_graph_generation(commit);
>
> if (min_generation && generation > last_gen)
> - BUG("bad generation skip %8x > %8x at %s",
> + BUG("bad generation skip %"PRItime" > %"PRItime" at %s",
> generation, last_gen,
> oid_to_hex(&commit->object.oid));
> last_gen = generation;All right.
Show 15 quoted lines
> @@ -177,12 +177,12 @@ static int remove_redundant(struct repository *r, struct commit **array, int cnt
> repo_parse_commit(r, array[i]);
> for (i = 0; i < cnt; i++) {
> struct commit_list *common;
> - uint32_t min_generation = commit_graph_generation(array[i]);
> + timestamp_t min_generation = commit_graph_generation(array[i]);
>
> if (redundant[i])
> continue;
> for (j = filled = 0; j < cnt; j++) {
> - uint32_t curr_generation;
> + timestamp_t curr_generation;
> if (i == j || redundant[j])
> continue;
> filled_index[filled] = j;All right.
Show 9 quoted lines
> @@ -321,7 +321,7 @@ int repo_in_merge_bases_many(struct repository *r, struct commit *commit,
> {
> struct commit_list *bases;
> int ret = 0, i;
> - uint32_t generation, min_generation = GENERATION_NUMBER_INFINITY;
> + timestamp_t generation, min_generation = GENERATION_NUMBER_INFINITY;
>
> if (repo_parse_commit(r, commit))
> return ret;All right,
Show 6 quoted lines
> @@ -470,7 +470,7 @@ static int in_commit_list(const struct commit_list *want, struct commit *c) > static enum contains_result contains_test(struct commit *candidate, > const struct commit_list *want, > struct contains_cache *cache, > - uint32_t cutoff) > + timestamp_t cutoff)
All right.
(Sidenote: this one I have missed in my simple search.)
Show 17 quoted lines
> {
> enum contains_result *cached = contains_cache_at(cache, candidate);
>
> @@ -506,11 +506,11 @@ static enum contains_result contains_tag_algo(struct commit *candidate,
> {
> struct contains_stack contains_stack = { 0, 0, NULL };
> enum contains_result result;
> - uint32_t cutoff = GENERATION_NUMBER_INFINITY;
> + timestamp_t cutoff = GENERATION_NUMBER_INFINITY;
> const struct commit_list *p;
>
> for (p = want; p; p = p->next) {
> - uint32_t generation;
> + timestamp_t generation;
> struct commit *c = p->item;
> load_commit_graph_info(the_repository, c);
> generation = commit_graph_generation(c);All right.
Show 34 quoted lines
> @@ -565,7 +565,7 @@ int can_all_from_reach_with_flag(struct object_array *from,
> unsigned int with_flag,
> unsigned int assign_flag,
> time_t min_commit_date,
> - uint32_t min_generation)
> + timestamp_t min_generation)
> {
> struct commit **list = NULL;
> int i;
> @@ -666,13 +666,13 @@ int can_all_from_reach(struct commit_list *from, struct commit_list *to,
> time_t min_commit_date = cutoff_by_min_date ? from->item->date : 0;
> struct commit_list *from_iter = from, *to_iter = to;
> int result;
> - uint32_t min_generation = GENERATION_NUMBER_INFINITY;
> + timestamp_t min_generation = GENERATION_NUMBER_INFINITY;
>
> while (from_iter) {
> add_object_array(&from_iter->item->object, NULL, &from_objs);
>
> if (!parse_commit(from_iter->item)) {
> - uint32_t generation;
> + timestamp_t generation;
> if (from_iter->item->date < min_commit_date)
> min_commit_date = from_iter->item->date;
>
> @@ -686,7 +686,7 @@ int can_all_from_reach(struct commit_list *from, struct commit_list *to,
>
> while (to_iter) {
> if (!parse_commit(to_iter->item)) {
> - uint32_t generation;
> + timestamp_t generation;
> if (to_iter->item->date < min_commit_date)
> min_commit_date = to_iter->item->date;
>All right.
Show 16 quoted lines
> @@ -726,13 +726,13 @@ struct commit_list *get_reachable_subset(struct commit **from, int nr_from,
> struct commit_list *found_commits = NULL;
> struct commit **to_last = to + nr_to;
> struct commit **from_last = from + nr_from;
> - uint32_t min_generation = GENERATION_NUMBER_INFINITY;
> + timestamp_t min_generation = GENERATION_NUMBER_INFINITY;
> int num_to_find = 0;
>
> struct prio_queue queue = { compare_commits_by_gen_then_commit_date };
>
> for (item = to; item < to_last; item++) {
> - uint32_t generation;
> + timestamp_t generation;
> struct commit *c = *item;
>
> parse_commit(c);All right.
Show 13 quoted lines
> diff --git a/commit-reach.h b/commit-reach.h > index b49ad71a31..148b56fea5 100644 > --- a/commit-reach.h > +++ b/commit-reach.h > @@ -87,7 +87,7 @@ int can_all_from_reach_with_flag(struct object_array *from, > unsigned int with_flag, > unsigned int assign_flag, > time_t min_commit_date, > - uint32_t min_generation); > + timestamp_t min_generation); > int can_all_from_reach(struct commit_list *from, struct commit_list *to, > int commit_date_cutoff); >
All right.
Show 14 quoted lines
> diff --git a/commit.h b/commit.h > index e901538909..bc0732a4fe 100644 > --- a/commit.h > +++ b/commit.h > @@ -11,7 +11,8 @@ > #include "commit-slab.h" > > #define COMMIT_NOT_FROM_GRAPH 0xFFFFFFFF > -#define GENERATION_NUMBER_INFINITY 0xFFFFFFFF > +#define GENERATION_NUMBER_INFINITY ((1ULL << 63) - 1) > +#define GENERATION_NUMBER_V1_INFINITY 0xFFFFFFFF > #define GENERATION_NUMBER_MAX 0x3FFFFFFF > #define GENERATION_NUMBER_ZERO 0 >
Why do we even need GENERATION_NUMBER_V1_INFINITY? It is about marking out-of-graph commits, and it is about in-memory storage.
We would need separate GENERATION_NUMBER_V1_MAX and GENERATION_NUMBER_V2_MAX because of different _on-disk_ storage, or in other words file format limitations. But that is for the future commit.
Show 13 quoted lines
> diff --git a/revision.c b/revision.c
> index ecf757c327..411852468b 100644
> --- a/revision.c
> +++ b/revision.c
> @@ -3290,7 +3290,7 @@ define_commit_slab(indegree_slab, int);
> define_commit_slab(author_date_slab, timestamp_t);
>
> struct topo_walk_info {
> - uint32_t min_generation;
> + timestamp_t min_generation;
> struct prio_queue explore_queue;
> struct prio_queue indegree_queue;
> struct prio_queue topo_queue;All right.
Show 9 quoted lines
> @@ -3336,7 +3336,7 @@ static void explore_walk_step(struct rev_info *revs)
> }
>
> static void explore_to_depth(struct rev_info *revs,
> - uint32_t gen_cutoff)
> + timestamp_t gen_cutoff)
> {
> struct topo_walk_info *info = revs->topo_walk_info;
> struct commit *c;All right.
Show 18 quoted lines
> @@ -3379,7 +3379,7 @@ static void indegree_walk_step(struct rev_info *revs)
> }
>
> static void compute_indegrees_to_depth(struct rev_info *revs,
> - uint32_t gen_cutoff)
> + timestamp_t gen_cutoff)
> {
> struct topo_walk_info *info = revs->topo_walk_info;
> struct commit *c;
> @@ -3437,7 +3437,7 @@ static void init_topo_walk(struct rev_info *revs)
> info->min_generation = GENERATION_NUMBER_INFINITY;
> for (list = revs->commits; list; list = list->next) {
> struct commit *c = list->item;
> - uint32_t generation;
> + timestamp_t generation;
>
> if (parse_commit_gently(c, 1))
> continue;All right.
Show 9 quoted lines
> @@ -3498,7 +3498,7 @@ static void expand_topo_walk(struct rev_info *revs, struct commit *commit)
> for (p = commit->parents; p; p = p->next) {
> struct commit *parent = p->item;
> int *pi;
> - uint32_t generation;
> + timestamp_t generation;
>
> if (parent->object.flags & UNINTERESTING)
> continue;All right.
Show 13 quoted lines
> diff --git a/upload-pack.c b/upload-pack.c
> index 80ad9a38d8..bcb8b5dfda 100644
> --- a/upload-pack.c
> +++ b/upload-pack.c
> @@ -497,7 +497,7 @@ static int got_oid(struct upload_pack_data *data,
>
> static int ok_to_give_up(struct upload_pack_data *data)
> {
> - uint32_t min_generation = GENERATION_NUMBER_ZERO;
> + timestamp_t min_generation = GENERATION_NUMBER_ZERO;
>
> if (!data->have_obj.nr)
> return 0;All right.
Best,
-- Jakub Narębski