Hi,

Jonathan Tan wrote:

> Thanks, peff. I've incorporated your suggestions - I don't feel very
> strongly about this, but I guess it's worthwhile to avoid the quadratic
> behavior if we can.
>
> Also incorporated Jonathan Nieder's suggestion about the placement of
> the last line. The relevant function is also factored out (following
> peff's suggestion).

Thanks.  The structure still seems more complicated than it needs to
be.  More details below.

[...]
> +++ b/fetch-pack.c
[...]
> @@ -592,13 +593,22 @@ static void mark_recent_complete_commits(struct 
> fetch_pack_args *args,
>       }
>  }
>  
> +static void add_refs_to_oidset(struct oidset *oids, const struct ref *refs)
> +{
> +     for (; refs; refs = refs->next)
> +             oidset_insert(oids, &refs->old_oid);

Makes sense.

[...]
>       /* Append unmatched requests to the list */
>       for (i = 0; i < nr_sought; i++) {
>               unsigned char sha1[20];
> +             int can_append = 0;
>  
>               ref = sought[i];
>               if (ref->match_status != REF_NOT_MATCHED)
> @@ -649,6 +661,21 @@ static void filter_refs(struct fetch_pack_args *args,
>  
>               if ((allow_unadvertised_object_request &
>                   (ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1))) {
> +                     can_append = 1;
> +             } else {
> +                     if (!tip_oids_initialized) {
> +                             /*
> +                              * Check all refs, including those already
> +                              * matched
> +                              */
> +                             add_refs_to_oidset(&tip_oids, unmatched);
> +                             add_refs_to_oidset(&tip_oids, newlist);
> +                             tip_oids_initialized = 1;
> +                     }
> +                     can_append = oidset_contains(&tip_oids, &ref->old_oid);
> +             }
> +
> +             if (can_append) {

This structure could be simplified by putting the lazy-initializing
tip_oids lookup in a separate function.  For example:

        int tip_oids_contain(struct oidset *tip_oids,
                struct ref *unmatched, struct ref *newlist,
                const struct oid *id)
        {
                if (oidset_is_empty(tip_oids)) {
                        add_refs_to_oidset(tip_oids, unmatched);
                        add_refs_to_oidset(tip_oids, newlist);
                }
                return oidset_contains(tip_oids, id);
        }

That way, the caller could be kept simple (eliminating can_append
and the repeated if).

Thanks,
Jonathan

Reply via email to