git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Derrick Stolee <stolee@gmail.com>
To: Christian Couder <christian.couder@gmail.com>, git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>, "Jeff King" <peff@peff.net>,
	"Ben Peart" <Ben.Peart@microsoft.com>,
	"Jonathan Tan" <jonathantanmy@google.com>,
	"Jonathan Nieder" <jrnieder@gmail.com>,
	"Nguyen Thai Ngoc Duy" <pclouds@gmail.com>,
	"Mike Hommey" <mh@glandium.org>,
	"Lars Schneider" <larsxschneider@gmail.com>,
	"Eric Wong" <e@80x24.org>,
	"Christian Couder" <chriscool@tuxfamily.org>,
	"Jeff Hostetler" <jeffhost@microsoft.com>,
	"Eric Sunshine" <sunshine@sunshineco.com>,
	"Beat Bolli" <dev+git@drbeat.li>,
	"SZEDER Gábor" <szeder.dev@gmail.com>,
	"Ramsay Jones" <ramsay@ramsayjones.plus.com>
Subject: Re: [PATCH v5 04/16] promisor-remote: implement promisor_remote_get_direct()
Date: Thu, 30 May 2019 13:21:51 -0400	[thread overview]
Message-ID: <b4d69d2b-dc0d-fffb-2909-c54060fe9cd1@gmail.com> (raw)
In-Reply-To: <20190409161116.30256-5-chriscool@tuxfamily.org>

On 4/9/2019 12:11 PM, Christian Couder wrote:
> From: Christian Couder <christian.couder@gmail.com>
> 
> This is implemented for now by calling fetch_objects(). It fetches
> from all the promisor remotes.

Hi Christian,

Sorry for jumping on the thread late, but I noticed some peculiarities
when looking at the test coverage report.

> +static int remove_fetched_oids(struct object_id **oids, int oid_nr, int to_free)

This method does not seem to be covered by the test suite at all.
Is this scenario difficult to set up for a test?

> +{
> +	int i, missing_nr = 0;
> +	int *missing = xcalloc(oid_nr, sizeof(*missing));
> +	struct object_id *old_oids = *oids;
> +	struct object_id *new_oids;
> +	int old_fetch_if_missing = fetch_if_missing;
> +
> +	fetch_if_missing = 0;

This global 'fetch_if_missing' swap seems very fragile. I'm guessing you are using
it to prevent a loop when calling oid_object_info_extended() below. Can you instead
pass a flag to the method that disables the fetch_if_missing behavior?

> +
> +	for (i = 0; i < oid_nr; i++)
> +		if (oid_object_info_extended(the_repository, &old_oids[i], NULL, 0)) {

A use of "the_repository" this deep in new code is asking for a refactor later to remove it.
Please try to pass a "struct repository *r" through your methods so we minimize references
to the_repository (and the amount of work required to remove them later).

> +			missing[i] = 1;
> +			missing_nr++;
> +		}
> +
> +	fetch_if_missing = old_fetch_if_missing;
> +
> +	if (missing_nr) {
> +		int j = 0;
> +		new_oids = xcalloc(missing_nr, sizeof(*new_oids));
> +		for (i = 0; i < oid_nr; i++)
> +			if (missing[i])
> +				oidcpy(&new_oids[j++], &old_oids[i]);
> +		*oids = new_oids;
> +		if (to_free)
> +			free(old_oids);
> +	}
> +
> +	free(missing);
> +
> +	return missing_nr;
> +}
> +
> +int promisor_remote_get_direct(const struct object_id *oids, int oid_nr)
> +{
> +	struct promisor_remote *r;
> +	struct object_id *missing_oids = (struct object_id *)oids;
> +	int missing_nr = oid_nr;

Note that for this method, "missing_nr" actually means "number of oids still in the list".

> +	int to_free = 0;
> +	int res = -1;
> +
> +	promisor_remote_init();
> +
> +	for (r = promisors; r; r = r->next) {
> +		if (fetch_objects(r->name, missing_oids, missing_nr) < 0) {

This block hits if we have any missing objects. This is not currently hit by the test
suite.

> +			if (missing_nr == 1)
> +				continue;

But we skip the call below if there is exactly one object in the list, as it must be the one
missing object. So, to be interesting we need to try fetching multiple objects.

> +			missing_nr = remove_fetched_oids(&missing_oids, missing_nr, to_free);

Here is the one call, and after this assignment "missing_nr" does mean the number of missing objects.
However, I do think this could be clarified by using remaining_nr and remaining_oids.

> +			if (missing_nr) {
> +				to_free = 1;
> +				continue;
> +			}

Now this block took a bit to grok. You use to_free in the if(to_free) free(missing_oids); below.
But it also changes the behavior of remove_fetched_oids(). This means that the first time
remove_fetched_oids() will preserve the list (because it is the input list) but all later
calls will free the newly-created intermediate list. This checks out.

What is confusing to me: is there any reason that missing_nr would be zero in this situation?
I guess if the fetch_objects() failed to find some objects, but we ended up having them locally
in a new call to oid_object_info_extended(). That's a fringe case that is worth guarding against
but I wouldn't worry about testing.

> +		}
> +		res = 0;
> +		break;
> +	}
> +
> +	if (to_free)
> +		free(missing_oids);
> +
> +	return res;
> +}

While the test coverage report brought this patch to my attention, it does seem correct.
I still think a test exposing this method would be good, especially one that requires
a fetch_objects() call to multiple remotes to really exercise the details of remove_fetched_oids().

Thanks,
-Stolee


  reply	other threads:[~2019-05-30 17:21 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-09 16:11 [PATCH v5 00/16] Many promisor remotes Christian Couder
2019-04-09 16:11 ` [PATCH v5 01/16] t0410: remove pipes after git commands Christian Couder
2019-04-09 16:11 ` [PATCH v5 02/16] fetch-object: make functions return an error code Christian Couder
2019-04-09 16:11 ` [PATCH v5 03/16] Add initial support for many promisor remotes Christian Couder
2019-04-09 16:11 ` [PATCH v5 04/16] promisor-remote: implement promisor_remote_get_direct() Christian Couder
2019-05-30 17:21   ` Derrick Stolee [this message]
2019-05-30 20:46     ` Johannes Schindelin
2019-05-30 20:54       ` Derrick Stolee
2019-05-31 11:35         ` Johannes Schindelin
2019-05-31 16:14         ` Junio C Hamano
2019-05-31  5:10     ` Christian Couder
2019-06-25 13:50       ` Christian Couder
2019-04-09 16:11 ` [PATCH v5 05/16] promisor-remote: add promisor_remote_reinit() Christian Couder
2019-04-09 16:11 ` [PATCH v5 06/16] promisor-remote: use repository_format_partial_clone Christian Couder
2019-04-09 16:11 ` [PATCH v5 07/16] Use promisor_remote_get_direct() and has_promisor_remote() Christian Couder
2019-04-09 16:11 ` [PATCH v5 08/16] diff: use promisor-remote.h instead of fetch-object.h Christian Couder
2019-04-09 16:11 ` [PATCH v5 09/16] promisor-remote: parse remote.*.partialclonefilter Christian Couder
2019-04-09 16:11 ` [PATCH v5 10/16] builtin/fetch: remove unique promisor remote limitation Christian Couder
2019-04-09 16:11 ` [PATCH v5 11/16] t0410: test fetching from many promisor remotes Christian Couder
2019-04-09 16:11 ` [PATCH v5 12/16] partial-clone: add multiple remotes in the doc Christian Couder
2019-04-09 16:11 ` [PATCH v5 13/16] remote: add promisor and partial clone config to " Christian Couder
2019-04-09 16:11 ` [PATCH v5 14/16] Remove fetch-object.{c,h} in favor of promisor-remote.{c,h} Christian Couder
2019-04-09 16:11 ` [PATCH v5 15/16] Move repository_format_partial_clone to promisor-remote.c Christian Couder
2019-04-09 16:11 ` [PATCH v5 16/16] Move core_partial_clone_filter_default " Christian Couder
2019-04-15  9:27 ` [PATCH v5 00/16] Many promisor remotes Junio C Hamano
2019-04-15 10:30   ` Junio C Hamano
2019-04-15 10:39     ` Christian Couder
2019-04-15 10:37   ` Christian Couder

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b4d69d2b-dc0d-fffb-2909-c54060fe9cd1@gmail.com \
    --to=stolee@gmail.com \
    --cc=Ben.Peart@microsoft.com \
    --cc=chriscool@tuxfamily.org \
    --cc=christian.couder@gmail.com \
    --cc=dev+git@drbeat.li \
    --cc=e@80x24.org \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jeffhost@microsoft.com \
    --cc=jonathantanmy@google.com \
    --cc=jrnieder@gmail.com \
    --cc=larsxschneider@gmail.com \
    --cc=mh@glandium.org \
    --cc=pclouds@gmail.com \
    --cc=peff@peff.net \
    --cc=ramsay@ramsayjones.plus.com \
    --cc=sunshine@sunshineco.com \
    --cc=szeder.dev@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).