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>

René Scharfe committed Oct 4, 2018 at 17:09 UTC 22a164651114738c723c4459140e1e5330491467
1 file changed +15 -21
fetch-pack.c
+15 -21
@@ -526,23 +526,6 @@ static void add_refs_to_oidset(struct oidset *oids, struct ref *refs)
526 oidset_insert(oids, &refs->old_oid);
527 }
528
529 -static int tip_oids_contain(struct oidset *tip_oids,
530 - struct ref *unmatched, struct ref *newlist,
531 - const struct object_id *id)
532 -{
533 - /*
534 - * Note that this only looks at the ref lists the first time it's
535 - * called. This works out in filter_refs() because even though it may
536 - * add to "newlist" between calls, the additions will always be for
537 - * oids that are already in the set.
538 - */
539 - if (!tip_oids->map.map.tablesize) {
540 - add_refs_to_oidset(tip_oids, unmatched);
541 - add_refs_to_oidset(tip_oids, newlist);
542 - }
543 - return oidset_contains(tip_oids, id);
544 -}
545 -
529 static int is_unmatched_ref(const struct ref *ref)
530 {
531 struct object_id oid;
@@ -563,6 +546,8 @@ static void filter_refs(struct fetch_pack_args *args,
546 struct ref *ref, *next;
547 struct oidset tip_oids = OIDSET_INIT;
548 int i;
549 + int strict = !(allow_unadvertised_object_request &
550 + (ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1));
551
552 i = 0;
553 for (ref = *refs; ref; ref = next) {
@@ -599,16 +584,25 @@ static void filter_refs(struct fetch_pack_args *args,
584 }
585 }
586
587 + if (strict) {
588 + for (i = 0; i < nr_sought; i++) {
589 + ref = sought[i];
590 + if (!is_unmatched_ref(ref))
591 + continue;
592 +
593 + add_refs_to_oidset(&tip_oids, unmatched);
594 + add_refs_to_oidset(&tip_oids, newlist);
595 + break;
596 + }
597 + }
598 +
599 /* Append unmatched requests to the list */
600 for (i = 0; i < nr_sought; i++) {
601 ref = sought[i];
602 if (!is_unmatched_ref(ref))
603 continue;
604
608 - if ((allow_unadvertised_object_request &
609 - (ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1)) ||
610 - tip_oids_contain(&tip_oids, unmatched, newlist,
611 - &ref->old_oid)) {
605 + if (!strict || oidset_contains(&tip_oids, &ref->old_oid)) {
606 ref->match_status = REF_MATCHED;
607 *newtail = copy_ref(ref);
608 newtail = &(*newtail)->next;