[geany/geany] 712cdd: Merge global tags in order rather than resorting the whole array

Nick Treleaven git-noreply at xxxxx
Thu Jul 26 00:04:04 UTC 2012


Branch:      refs/heads/document-messages
Author:      Nick Treleaven <nick.treleaven at btinternet.com>
Committer:   Nick Treleaven <nick.treleaven at btinternet.com>
Date:        Fri, 20 Apr 2012 12:13:16
Commit:      712cdd6aa0005f65bd77b15c34cd29067864628d
             https://github.com/geany/geany/commit/712cdd6aa0005f65bd77b15c34cd29067864628d

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).



More information about the Commits mailing list