combine_notes_cat_sort_uniq(): sort and dedup lines all at once

Instead of reading lines one by one and insertion-sorting them into a string_list, read all of the lines, sort them, then remove duplicates. Aside from being less code, this reduces the complexity from O(N^2) to O(N lg N) in the total number of lines. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Acked-by: Johan Herland <johan@herland.net> Signed-off-by: Jeff King <peff@peff.net>

Michael Haggerty committed Nov 4, 2012 at 08:07 UTC 131352433621e89b2e8c58d8327b1d55bf0bc8d0
1 file changed +16 -22
notes.c
+16 -22
@@ -848,15 +848,16 @@ int combine_notes_ignore(unsigned char *cur_sha1,
848 return 0;
849 }
850
851 -static int string_list_add_note_lines(struct string_list *sort_uniq_list,
851 +/*
852 + * Add the lines from the named object to list, with trailing
853 + * newlines removed.
854 + */
855 +static int string_list_add_note_lines(struct string_list *list,
856 const unsigned char *sha1)
857 {
858 char *data;
859 unsigned long len;
860 enum object_type t;
857 - struct strbuf buf = STRBUF_INIT;
858 - struct strbuf **lines = NULL;
859 - int i, list_index;
861
862 if (is_null_sha1(sha1))
863 return 0;
@@ -868,24 +869,14 @@ static int string_list_add_note_lines(struct string_list *sort_uniq_list,
869 return t != OBJ_BLOB || !data;
870 }
871
871 - strbuf_attach(&buf, data, len, len + 1);
872 - lines = strbuf_split(&buf, '\n');
873 -
874 - for (i = 0; lines[i]; i++) {
875 - if (lines[i]->buf[lines[i]->len - 1] == '\n')
876 - strbuf_setlen(lines[i], lines[i]->len - 1);
877 - if (!lines[i]->len)
878 - continue; /* skip empty lines */
879 - list_index = string_list_find_insert_index(sort_uniq_list,
880 - lines[i]->buf, 0);
881 - if (list_index < 0)
882 - continue; /* skip duplicate lines */
883 - string_list_insert_at_index(sort_uniq_list, list_index,
884 - lines[i]->buf);
885 - }
886 -
887 - strbuf_list_free(lines);
888 - strbuf_release(&buf);
872 + /*
873 + * If the last line of the file is EOL-terminated, this will
874 + * add an empty string to the list. But it will be removed
875 + * later, along with any empty strings that came from empty
876 + * lines within the file.
877 + */
878 + string_list_split(list, data, '\n', -1);
879 + free(data);
880 return 0;
881 }
882
@@ -910,6 +901,9 @@ int combine_notes_cat_sort_uniq(unsigned char *cur_sha1,
901 goto out;
902 if (string_list_add_note_lines(&sort_uniq_list, new_sha1))
903 goto out;
904 + string_list_remove_empty_items(&sort_uniq_list, 0);
905 + sort_string_list(&sort_uniq_list);
906 + string_list_remove_duplicates(&sort_uniq_list, 0);
907
908 /* create a new blob object from sort_uniq_list */
909 if (for_each_string_list(&sort_uniq_list,