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
}