git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 06/11] submodule.c: sort changed_submodule_names before searching it

From
Junio C Hamano <gitster@pobox.com>
Date
Sep 6, 2018, 18:03 UTC
Message-ID
<xmqqbm9a1p1p.fsf@gitster-ct.c.googlers.com>
In-Reply-To
<20180904230149.180332-7-sbeller@google.com>
Stefan Beller <sbeller@google.com> writes:
> Instead of sorting it after we created an unsorted list, we could insert
> correctly into the list.

It is unclear what problem you are solving, especially with subjunctive "could" there. We are creating an unsorted list and then sorting it and you see it as a problem because it is just as easy and efficient to do the insertion sort while building up the list? (don't react and answer without reading all the way to the end; I think I know what is going on).

> As the unsorted append is in order of cache entry
> names, this is already sorted if names were equal to paths for submodules.

That may be a statement of a fact, but it is unclear how that fact relates to what the code is doing before this patch, or what the code updated by this patch is doing.

> As submodule names are often the same as their path, the input is sorted
> pretty well already, so let's just do the sort afterwards.

It is unclear what (performance?) trade-off this senttence is trying to make. It sounds as if it is claiming this:

	We can string_list_insert() to maintain sorted-ness of the
	list as we find new items, or we can string_list_append() to
	build an unsorted list and sort it at the end just once.
	To pick which one is more appropriate, we notice the fact
	that we discover new items more or less in the already
	sorted order.  That makes "append then sort" more
	appropriate.
But is that reasoning sensible?  

I'd imagine that append-then-sort would always be more efficient than insert-at-the-right-place-as-we-go, and the reason why we sometimes would need to do the latter is when we need to look up elements in the middle of building the list (e.g. we may want to de-dup, which requires us to look up a name from the ones we collected so far).

And in this application, calculate_changed_submodule_paths() discover paths by calling collect_changed_submodules() which finds a mapping <submodule name, oid of commits> into a list sorted by submodule name, and then goes through that list and builds a list of submodules paths (which could be different from submodule names) by appending. Only after this list is fully built, get_next_submodule() gets called, so making the latter use string_list_lookup() that assumes a sorted list is safe if we built the list by append-then-sort (iow, sortedness while building the list does not matter).

Having analysed all that, I find it somewhat iffy that _append() is used there in the calculate_changed_submodule_paths() function. It would cause the resulting changed_submodule_names list to hold the same name twice (or more), but I do not know if that would pose a problem to the consumer of the list. Using "accumulate then sort before calling look-up" would not change it as string_list_sort() would not dedup, so I do not think this patch would introduce a new problem, though.

Show 26 quoted lines
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  submodule.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/submodule.c b/submodule.c
> index 8345d423fda..8bee455137a 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -1255,7 +1255,7 @@ static int get_next_submodule(struct child_process *cp,
>  		default:
>  		case RECURSE_SUBMODULES_DEFAULT:
>  		case RECURSE_SUBMODULES_ON_DEMAND:
> -			if (!submodule || !unsorted_string_list_lookup(
> +			if (!submodule || !string_list_lookup(
>  					&changed_submodule_names,
>  					submodule->name))
>  				continue;
> @@ -1349,6 +1349,7 @@ int fetch_populated_submodules(struct repository *r,
>  	/* default value, "--submodule-prefix" and its value are added later */
>  
>  	calculate_changed_submodule_paths();
> +	string_list_sort(&changed_submodule_names);
>  	run_processes_parallel(max_parallel_jobs,
>  			       get_next_submodule,
>  			       fetch_start_failure,
Previous: Stefan BellerNext: Stefan Beller
Message 31 of 39 in “fetch: make sure submodule oids are fetched”
  1. 00/11 fetch: make sure submodule oids are fetchedStefan Beller, Sep 4, 2018
  2. 01/11 string_list: print_string_list to use trace_printfStefan Beller, Sep 4, 2018
  3. Junio C HamanoSep 6, 2018
  4. Jeff KingSep 6, 2018
  5. Stefan BellerSep 6, 2018
  6. Jeff KingSep 7, 2018
  7. Junio C HamanoSep 7, 2018
  8. Stefan BellerSep 7, 2018
  9. 1/2 trace: add trace_print_string_list_keyStefan Beller, Sep 10, 2018
  10. 2/2 string-list: remove unused function print_string_listStefan Beller, Sep 10, 2018
  11. Junio C HamanoSep 10, 2018
  12. Stefan BellerSep 10, 2018
  13. Junio C HamanoSep 11, 2018
  14. Stefan BellerSep 11, 2018
  15. Jeff KingSep 11, 2018
  16. string-list: remove unused function print_string_listStefan Beller, Sep 11, 2018
  17. Junio C HamanoSep 11, 2018
  18. Junio C HamanoSep 11, 2018
  19. Stefan BellerSep 11, 2018
  20. Junio C HamanoSep 11, 2018
  21. 02/11 string-list.h: add string_list_{pop, last} functionsStefan Beller, Sep 4, 2018
  22. Junio C HamanoSep 6, 2018
  23. Stefan BellerSep 6, 2018
  24. 03/11 sha1-array: provide oid_array_filterStefan Beller, Sep 4, 2018
  25. Junio C HamanoSep 6, 2018
  26. 04/11 submodule.c: convert submodule_move_head new argument to object idStefan Beller, Sep 4, 2018
  27. Junio C HamanoSep 6, 2018
  28. 05/11 submodule.c: fix indentationStefan Beller, Sep 4, 2018
  29. Junio C HamanoSep 6, 2018
  30. 06/11 submodule.c: sort changed_submodule_names before searching itStefan Beller, Sep 4, 2018
  31. Junio C HamanoSep 6, 2018
  32. Stefan BellerSep 11, 2018
  33. 07/11 submodule: move global changed_submodule_names into fetch submodule structStefan Beller, Sep 4, 2018
  34. Junio C HamanoSep 6, 2018
  35. 08/11 submodule.c: do not copy around submodule listStefan Beller, Sep 4, 2018
  36. Junio C HamanoSep 6, 2018
  37. 09/11 submodule: fetch in submodules git directory instead of in worktreeStefan Beller, Sep 4, 2018
  38. 10/11 fetch: retry fetching submodules if sha1 were not fetchedStefan Beller, Sep 4, 2018
  39. 11/11 builtin/fetch: check for submodule updates for non branch fetchesStefan Beller, Sep 4, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.