Takuto Ikuta <tik...@chromium.org> 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;

Reply via email to