@matheusbsbs / matheus-bagliano / commits / b1a01e1c07
Fork 0

fetch: Speed up fetch of large numbers of refs

When there are large numbers of refs, calling read_ref for each ref is inefficent (and infact downright slow) - so instead use for_each_ref to build up a string list of all the refs that we currently have, which significantly improves the volume. Signed-off-by: Julian Phillips <julian@quantumfyre.co.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Julian Phillips committed Oct 25, 2009 at 21:28 UTC b1a01e1c0762d117da7dac009b773f310479be12
1 file changed +14 -3
builtin-fetch.c
+14 -3
@@ -489,7 +489,8 @@ static int add_existing(const char *refname, const unsigned char *sha1,
489 int flag, void *cbdata)
490 {
491 struct string_list *list = (struct string_list *)cbdata;
492 - string_list_insert(refname, list);
492 + struct string_list_item *item = string_list_insert(refname, list);
493 + item->util = (void *)sha1;
494 return 0;
495 }
496
@@ -615,9 +616,14 @@ static void check_not_current_branch(struct ref *ref_map)
616 static int do_fetch(struct transport *transport,
617 struct refspec *refs, int ref_count)
618 {
619 + struct string_list existing_refs = { NULL, 0, 0, 0 };
620 + struct string_list_item *peer_item = NULL;
621 struct ref *ref_map;
622 struct ref *rm;
623 int autotags = (transport->remote->fetch_tags == 1);
624 +
625 + for_each_ref(add_existing, &existing_refs);
626 +
627 if (transport->remote->fetch_tags == 2 && tags != TAGS_UNSET)
628 tags = TAGS_SET;
629 if (transport->remote->fetch_tags == -1)
@@ -640,8 +646,13 @@ static int do_fetch(struct transport *transport,
646 check_not_current_branch(ref_map);
647
648 for (rm = ref_map; rm; rm = rm->next) {
643 - if (rm->peer_ref)
644 - read_ref(rm->peer_ref->name, rm->peer_ref->old_sha1);
649 + if (rm->peer_ref) {
650 + peer_item = string_list_lookup(rm->peer_ref->name,
651 + &existing_refs);
652 + if (peer_item)
653 + hashcpy(rm->peer_ref->old_sha1,
654 + peer_item->util);
655 + }
656 }
657
658 if (tags == TAGS_DEFAULT && autotags)