Re: [PATCH v4 03/10] commit-graph: compute generation numbers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Derrick Stolee <dstolee@xxxxxxxxxxxxx> writes:

> @@ -439,6 +439,9 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
>  		else
>  			packedDate[0] = 0;
>  
> +		if ((*list)->generation != GENERATION_NUMBER_INFINITY)
> +			packedDate[0] |= htonl((*list)->generation << 2);
> +
>  		packedDate[1] = htonl((*list)->date);
>  		hashwrite(f, packedDate, 8);

The ones that have infinity are written as zero here.  The code that
reads the generation field off of a file in fill_commit_graph_info()
and fill_commit_in_graph() both leave such a record in file as-is,
so the reader of what we write out will think it is _ZERO, not _INF.

Not that it matters, as it seems that most of the code being added
by this series treat _ZERO and _INF more or less interchangeably.
But it does raise another question, i.e. do we need both _ZERO and
_INF, or is it sufficient to have just a single _UNKNOWN?

> @@ -571,6 +574,46 @@ static void close_reachable(struct packed_oid_list *oids)
>  	}
>  }
>  
> +static void compute_generation_numbers(struct commit** commits,
> +				       int nr_commits)
> +{
> +	int i;
> +	struct commit_list *list = NULL;
> +
> +	for (i = 0; i < nr_commits; i++) {
> +		if (commits[i]->generation != GENERATION_NUMBER_INFINITY &&
> +		    commits[i]->generation != GENERATION_NUMBER_ZERO)
> +			continue;
> +
> +		commit_list_insert(commits[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 we haven't computed all parents' generations yet,
current->generation is undefined (or at least "left as
initialized"), so it does not make much sense to attempt to clip it
at _MAX at this point.  At leat not yet.

IOW, shouldn't the following two lines be inside the "we now know
genno of all parents, so we can compute genno for commit" block
above?

> +			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 +737,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.list, commits.nr);
> +
>  	graph_name = get_commit_graph_filename(obj_dir);
>  	fd = hold_lock_file_for_update(&lk, graph_name, 0);



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux