ref_remove_duplicates(): avoid redundant bisection

The old code called string_list_lookup(), and if that failed called string_list_insert(), thus doing the bisection search through the string list twice in the latter code path. Instead, just call string_list_insert() right away. If an entry for that peer reference name already existed, then its util pointer is always non-NULL. Of course this doesn't change the fact that the repeated string_list_insert() calls make the function scale like O(N^2) if the input reference list is not already approximately sorted. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Michael Haggerty committed Oct 30, 2013 at 06:33 UTC 09ea1f8e0e85dd65307b29219ef1f5a3958eb918
1 file changed +6 -6
remote.c
+6 -6
@@ -750,13 +750,15 @@ void ref_remove_duplicates(struct ref *ref_map)
750 struct string_list refs = STRING_LIST_INIT_NODUP;
751 struct string_list_item *item = NULL;
752 struct ref *prev = NULL, *next = NULL;
753 +
754 for (; ref_map; prev = ref_map, ref_map = next) {
755 next = ref_map->next;
756 if (!ref_map->peer_ref)
757 continue;
758
758 - item = string_list_lookup(&refs, ref_map->peer_ref->name);
759 - if (item) {
759 + item = string_list_insert(&refs, ref_map->peer_ref->name);
760 + if (item->util) {
761 + /* Entry already existed */
762 if (strcmp(((struct ref *)item->util)->name,
763 ref_map->name))
764 die("%s tracks both %s and %s",
@@ -767,11 +769,9 @@ void ref_remove_duplicates(struct ref *ref_map)
769 free(ref_map->peer_ref);
770 free(ref_map);
771 ref_map = prev; /* skip this; we freed it */
770 - continue;
772 + } else {
773 + item->util = ref_map;
774 }
772 -
773 - item = string_list_insert(&refs, ref_map->peer_ref->name);
774 - item->util = ref_map;
775 }
776 string_list_clear(&refs, 0);
777 }