Takuto Ikuta <[email protected]> writes:
> +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.
> @@ -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;