Re: [PATCH v5] fetch-pack.c: use oidset to check existence of loose object
- From
Junio C Hamano <gitster@pobox.com>
- Date
- Mar 13, 2018, 19:04 UTC
- Message-ID
- <xmqq7eqf3ign.fsf@gitster-ct.c.googlers.com>
- In-Reply-To
- <20180310124643.82666-1-tikuta@chromium.org>
Takuto Ikuta <tikuta@chromium.org> writes:
Show 21 quoted lines
> +struct loose_object_iter {
> + struct oidset *loose_object_set;
> + struct ref *refs;
> +};
> +
> +/*
> + * If the number of refs is not larger than the number of loose objects,
> + * this function stops inserting and returns false.
> + */
> +static int add_loose_objects_to_set(const struct object_id *oid,
> + const char *path,
> + void *data)
> +{
> + struct loose_object_iter *iter = data;
> + oidset_insert(iter->loose_object_set, oid);
> + if (iter->refs == NULL)
> + return 1;
> +
> + iter->refs = iter->refs->next;
> + return 0;
> +}That's clever. By traversing the refs list as you iterate over the loose objects, you do not do any unnecessary work ;-)
Thanks for working on this.
Show 35 quoted lines
> @@ -719,16 +741,31 @@ static int everything_local(struct fetch_pack_args *args,
> int retval;
> int old_save_commit_buffer = save_commit_buffer;
> timestamp_t cutoff = 0;
> + struct oidset loose_oid_set = OIDSET_INIT;
> + int use_oidset = 0;
> + struct loose_object_iter iter = {&loose_oid_set, *refs};
> +
> + /* Enumerate all loose objects or know refs are not so many. */
> + use_oidset = !for_each_loose_object(add_loose_objects_to_set,
> + &iter, 0);
>
> save_commit_buffer = 0;
>
> for (ref = *refs; ref; ref = ref->next) {
> struct object *o;
> + unsigned int flags = OBJECT_INFO_QUICK;
>
> - if (!has_object_file_with_flags(&ref->old_oid,
> - OBJECT_INFO_QUICK))
> - continue;
> + if (use_oidset &&
> + !oidset_contains(&loose_oid_set, &ref->old_oid)) {
> + /*
> + * I know this does not exist in the loose form,
> + * so check if it exists in a non-loose form.
> + */
> + flags |= OBJECT_INFO_IGNORE_LOOSE;
> + }
>
> + if (!has_object_file_with_flags(&ref->old_oid, flags))
> + continue;
> o = parse_object(&ref->old_oid);
> if (!o)
> continue;