Branch: refs/heads/master Author: Nick Treleaven nick.treleaven@btinternet.com Committer: Nick Treleaven nick.treleaven@btinternet.com Date: Fri, 20 Apr 2012 12:13:16 Commit: 712cdd6aa0005f65bd77b15c34cd29067864628d https://github.com/geany/geany/commit/712cdd6aa0005f65bd77b15c34cd2906786462...
Log Message: ----------- Merge global tags in order rather than resorting the whole array
This is much faster than resorting, especially when there are many global tags files loaded.
Modified Paths: -------------- tagmanager/include/tm_tag.h tagmanager/tm_tag.c tagmanager/tm_workspace.c
Modified: tagmanager/include/tm_tag.h 3 files changed, 3 insertions(+), 0 deletions(-) =================================================================== @@ -225,6 +225,9 @@ */ int tm_tag_compare(const void *ptr1, const void *ptr2);
+gboolean tm_tags_merge(GPtrArray *tags_array, gsize orig_len, + TMTagAttrType *sort_attributes, gboolean dedup); + /*! Sort an array of tags on the specified attribuites using the inbuilt comparison function.
Modified: tagmanager/tm_tag.c 45 files changed, 45 insertions(+), 0 deletions(-) =================================================================== @@ -569,6 +569,51 @@ gboolean tm_tags_custom_dedup(GPtrArray *tags_array, TMTagCompareFunc compare_fu return TRUE; }
+/* Sorts newly-added tags and merges them in order with existing tags. + * This is much faster than resorting the whole array. + * Note: Having the caller append to the existing array should be faster + * than creating a new array which would likely get resized more than once. + * tags_array: array with new (perhaps unsorted) tags appended. + * orig_len: number of existing tags. */ +gboolean tm_tags_merge(GPtrArray *tags_array, gsize orig_len, + TMTagAttrType *sort_attributes, gboolean dedup) +{ + TMTag **copy, **a, **b; + gsize copy_len, i; + + if ((!tags_array) || (!tags_array->len) || orig_len >= tags_array->len) + return TRUE; + if (!orig_len) + return tm_tags_sort(tags_array, sort_attributes, dedup); + copy_len = tags_array->len - orig_len; + copy = g_memdup(tags_array->pdata + orig_len, copy_len * sizeof(gpointer)); + s_sort_attrs = sort_attributes; + s_partial = FALSE; + /* enforce copy sorted with same attributes for merge */ + qsort(copy, copy_len, sizeof(gpointer), tm_tag_compare); + a = tags_array->pdata + orig_len - 1; + b = copy + copy_len - 1; + for (i = tags_array->len - 1;; i--) + { + gint cmp = tm_tag_compare(a, b); + + tags_array->pdata[i] = (cmp >= 0) ? *a-- : *b--; + if (a < tags_array->pdata) + { + memcpy(tags_array->pdata, copy, b - copy); + break; + } + if (b < copy) + break; /* remaining elements of 'a' are in place already */ + g_assert(i != 0); + } + s_sort_attrs = NULL; + g_free(copy); + if (dedup) + tm_tags_dedup(tags_array, sort_attributes); + return TRUE; +} + gboolean tm_tags_sort(GPtrArray *tags_array, TMTagAttrType *sort_attributes, gboolean dedup) { if ((!tags_array) || (!tags_array->len))
Modified: tagmanager/tm_workspace.c 8 files changed, 4 insertions(+), 4 deletions(-) =================================================================== @@ -142,6 +142,7 @@ gboolean tm_workspace_remove_object(TMWorkObject *w, gboolean do_free, gboolean
gboolean tm_workspace_load_global_tags(const char *tags_file, gint mode) { + gsize orig_len; guchar buf[BUFSIZ]; FILE *fp; TMTag *tag; @@ -153,6 +154,7 @@ gboolean tm_workspace_load_global_tags(const char *tags_file, gint mode) return FALSE; if (NULL == theWorkspace->global_tags) theWorkspace->global_tags = g_ptr_array_new(); + orig_len = theWorkspace->global_tags->len; if ((NULL == fgets((gchar*) buf, BUFSIZ, fp)) || ('\0' == *buf)) { fclose(fp); @@ -182,10 +184,8 @@ gboolean tm_workspace_load_global_tags(const char *tags_file, gint mode) g_ptr_array_add(theWorkspace->global_tags, tag); fclose(fp);
- /* resort the whole array, because tm_tags_find expects a sorted array and it is not sorted - * when c99.tags, php.tags and latex.tags are loaded at the same time */ - tm_tags_sort(theWorkspace->global_tags, global_tags_sort_attrs, TRUE); - + /* reorder the whole array, because tm_tags_find expects a sorted array */ + tm_tags_merge(theWorkspace->global_tags, orig_len, global_tags_sort_attrs, TRUE); return TRUE; }
@@ Diff output truncated at 100000 characters. @@
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: TBD).