fetch-pack: load tip_oids eagerly iff needed

tip_oids_contain() lazily loads refs into an oidset at its first call.
It abuses the internal (sub)member .map.tablesize of that oidset to
check if it has done that already.

Determine if the oidset needs to be populated upfront and then do that
instead.  This duplicates a loop, but simplifies the existing one by
separating concerns between the two.

Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
René Scharfe 2018-10-04 17:09:39 +02:00 committed by Junio C Hamano
parent bf73282c0b
commit 22a1646511

View File

@ -526,23 +526,6 @@ static void add_refs_to_oidset(struct oidset *oids, struct ref *refs)
oidset_insert(oids, &refs->old_oid);
}
static int tip_oids_contain(struct oidset *tip_oids,
struct ref *unmatched, struct ref *newlist,
const struct object_id *id)
{
/*
* Note that this only looks at the ref lists the first time it's
* called. This works out in filter_refs() because even though it may
* add to "newlist" between calls, the additions will always be for
* oids that are already in the set.
*/
if (!tip_oids->map.map.tablesize) {
add_refs_to_oidset(tip_oids, unmatched);
add_refs_to_oidset(tip_oids, newlist);
}
return oidset_contains(tip_oids, id);
}
static int is_unmatched_ref(const struct ref *ref)
{
struct object_id oid;
@ -563,6 +546,8 @@ static void filter_refs(struct fetch_pack_args *args,
struct ref *ref, *next;
struct oidset tip_oids = OIDSET_INIT;
int i;
int strict = !(allow_unadvertised_object_request &
(ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1));
i = 0;
for (ref = *refs; ref; ref = next) {
@ -599,16 +584,25 @@ static void filter_refs(struct fetch_pack_args *args,
}
}
if (strict) {
for (i = 0; i < nr_sought; i++) {
ref = sought[i];
if (!is_unmatched_ref(ref))
continue;
add_refs_to_oidset(&tip_oids, unmatched);
add_refs_to_oidset(&tip_oids, newlist);
break;
}
}
/* Append unmatched requests to the list */
for (i = 0; i < nr_sought; i++) {
ref = sought[i];
if (!is_unmatched_ref(ref))
continue;
if ((allow_unadvertised_object_request &
(ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1)) ||
tip_oids_contain(&tip_oids, unmatched, newlist,
&ref->old_oid)) {
if (!strict || oidset_contains(&tip_oids, &ref->old_oid)) {
ref->match_status = REF_MATCHED;
*newtail = copy_ref(ref);
newtail = &(*newtail)->next;