[geany/geany] 99e222: Eliminate calls of slow tm_tags_extract() on big arrays

Jiří Techet git-noreply at xxxxx
Thu Feb 11 14:35:49 UTC 2016


Branch:      refs/heads/master
Author:      Jiří Techet <techet at gmail.com>
Committer:   Jiří Techet <techet at gmail.com>
Date:        Tue, 14 Jul 2015 07:44:33 UTC
Commit:      99e222ea370933ddb28f4a103b28de48b842ba2d
             https://github.com/geany/geany/commit/99e222ea370933ddb28f4a103b28de48b842ba2d

Log Message:
-----------
Eliminate calls of slow tm_tags_extract() on big arrays

Do the same with struct/class/union... member tags as we do with
typenames - extract them from the edited file and merge them with
the array containing all of them so while editing, there should
be no slowdowns because one file usually doesn't contain so many
tags. This eliminates about 2s freeze when typing "." on a linux
kernel project with 2300000 tags.

Extract typename and member tags also for global tags in case someone
creates a giant tags file - this needs to be done just once when
loading the tag files.

All the remaining tm_tags_extract() in Geany are called on
file tag array only so there shouldn't be any performance problems.


Modified Paths:
--------------
    src/symbols.c
    tagmanager/src/tm_workspace.c
    tagmanager/src/tm_workspace.h

Modified: src/symbols.c
4 lines changed, 1 insertions(+), 3 deletions(-)
===================================================================
@@ -281,7 +281,7 @@ GString *symbols_find_typenames_as_string(gint lang, gboolean global)
 	gint tag_lang;
 
 	if (global)
-		typedefs = tm_tags_extract(app->tm_workspace->global_tags, TM_GLOBAL_TYPE_MASK);
+		typedefs = app->tm_workspace->global_typename_array;
 	else
 		typedefs = app->tm_workspace->typename_array;
 
@@ -305,8 +305,6 @@ GString *symbols_find_typenames_as_string(gint lang, gboolean global)
 			}
 		}
 	}
-	if (typedefs && global)
-		g_ptr_array_free(typedefs, TRUE);
 	return s;
 }
 


Modified: tagmanager/src/tm_workspace.c
56 lines changed, 35 insertions(+), 21 deletions(-)
===================================================================
@@ -56,6 +56,10 @@ static TMTagAttrType global_tags_sort_attrs[] =
 	tm_tag_attr_type_t, tm_tag_attr_scope_t, tm_tag_attr_arglist_t, 0
 };
 
+static TMTagType TM_MEMBER_TYPE_MASK =
+	tm_tag_function_t | tm_tag_prototype_t |
+	tm_tag_member_t | tm_tag_field_t |
+	tm_tag_method_t | tm_tag_enumerator_t;
 
 static TMWorkspace *theWorkspace = NULL;
 
@@ -68,6 +72,9 @@ static gboolean tm_create_workspace(void)
 	theWorkspace->global_tags = g_ptr_array_new();
 	theWorkspace->source_files = g_ptr_array_new();
 	theWorkspace->typename_array = g_ptr_array_new();
+	theWorkspace->global_typename_array = g_ptr_array_new();
+	theWorkspace->member_array = g_ptr_array_new();
+	theWorkspace->global_member_array = g_ptr_array_new();
 	return TRUE;
 }
 
@@ -89,6 +96,9 @@ void tm_workspace_free(void)
 	tm_tags_array_free(theWorkspace->global_tags, TRUE);
 	g_ptr_array_free(theWorkspace->tags_array, TRUE);
 	g_ptr_array_free(theWorkspace->typename_array, TRUE);
+	g_ptr_array_free(theWorkspace->global_typename_array, TRUE);
+	g_ptr_array_free(theWorkspace->member_array, TRUE);
+	g_ptr_array_free(theWorkspace->global_member_array, TRUE);
 	g_free(theWorkspace);
 	theWorkspace = NULL;
 }
@@ -117,6 +127,16 @@ static void tm_workspace_merge_tags(GPtrArray **big_array, GPtrArray *small_arra
 }
 
 
+static void merge_extracted_tags(GPtrArray **dest, GPtrArray *src, TMTagType tag_types)
+{
+	GPtrArray *arr;
+
+	arr = tm_tags_extract(src, tag_types);
+	tm_workspace_merge_tags(dest, arr);
+	g_ptr_array_free(arr, TRUE);
+}
+
+
 static void update_source_file(TMSourceFile *source_file, guchar* text_buf,
 	gsize buf_size, gboolean use_buffer, gboolean update_workspace)
 {
@@ -130,21 +150,19 @@ static void update_source_file(TMSourceFile *source_file, guchar* text_buf,
 		 * workspace while they exist and can be scanned */
 		tm_tags_remove_file_tags(source_file, theWorkspace->tags_array);
 		tm_tags_remove_file_tags(source_file, theWorkspace->typename_array);
+		tm_tags_remove_file_tags(source_file, theWorkspace->member_array);
 	}
 	tm_source_file_parse(source_file, text_buf, buf_size, use_buffer);
 	tm_tags_sort(source_file->tags_array, file_tags_sort_attrs, FALSE, TRUE);
 	if (update_workspace)
 	{
-		GPtrArray *sf_typedefs;
-
 #ifdef TM_DEBUG
 		g_message("Updating workspace from source file");
 #endif
 		tm_workspace_merge_tags(&theWorkspace->tags_array, source_file->tags_array);
-		
-		sf_typedefs = tm_tags_extract(source_file->tags_array, TM_GLOBAL_TYPE_MASK);
-		tm_workspace_merge_tags(&theWorkspace->typename_array, sf_typedefs);
-		g_ptr_array_free(sf_typedefs, TRUE);
+
+		merge_extracted_tags(&(theWorkspace->typename_array), source_file->tags_array, TM_GLOBAL_TYPE_MASK);
+		merge_extracted_tags(&(theWorkspace->member_array), source_file->tags_array, TM_MEMBER_TYPE_MASK);
 	}
 #ifdef TM_DEBUG
 	else
@@ -214,6 +232,7 @@ void tm_workspace_remove_source_file(TMSourceFile *source_file)
 		{
 			tm_tags_remove_file_tags(source_file, theWorkspace->tags_array);
 			tm_tags_remove_file_tags(source_file, theWorkspace->typename_array);
+			tm_tags_remove_file_tags(source_file, theWorkspace->member_array);
 			g_ptr_array_remove_index_fast(theWorkspace->source_files, i);
 			return;
 		}
@@ -262,6 +281,7 @@ static void tm_workspace_update(void)
 
 	g_ptr_array_free(theWorkspace->typename_array, TRUE);
 	theWorkspace->typename_array = tm_tags_extract(theWorkspace->tags_array, TM_GLOBAL_TYPE_MASK);
+	theWorkspace->member_array = tm_tags_extract(theWorkspace->tags_array, TM_MEMBER_TYPE_MASK);
 }
 
 
@@ -386,6 +406,11 @@ gboolean tm_workspace_load_global_tags(const char *tags_file, gint mode)
 	g_ptr_array_free(file_tags, TRUE);
 	theWorkspace->global_tags = new_tags;
 
+	g_ptr_array_free(theWorkspace->global_typename_array, TRUE);
+	theWorkspace->global_typename_array = tm_tags_extract(new_tags, TM_GLOBAL_TYPE_MASK);
+	g_ptr_array_free(theWorkspace->global_member_array, TRUE);
+	theWorkspace->global_member_array = tm_tags_extract(new_tags, TM_MEMBER_TYPE_MASK);
+
 	return TRUE;
 }
 
@@ -939,23 +964,12 @@ tm_workspace_find_scope_members (const GPtrArray * file_tags, const char *name,
 	if (has_members)
 	{
 		GPtrArray *extracted;
-		TMTagType member_types = (tm_tag_function_t | tm_tag_prototype_t |
-									tm_tag_member_t | tm_tag_field_t |
-									tm_tag_method_t | tm_tag_enumerator_t);
 
 		/* Now get the tags from tags_array and global_tags corresponding to type_name */
-		extracted = tm_tags_extract(theWorkspace->tags_array, member_types);
-		if (extracted)
-		{
-			find_scope_members_tags(extracted, tags, type_name, lang);
-			g_ptr_array_free(extracted, TRUE);
-		}
-		extracted = tm_tags_extract(theWorkspace->global_tags, member_types);
-		if (extracted)
-		{
-			find_scope_members_tags(extracted, tags, type_name, lang);
-			g_ptr_array_free(extracted, TRUE);
-		}
+		if (theWorkspace->member_array)
+			find_scope_members_tags(theWorkspace->member_array, tags, type_name, lang);
+		if (theWorkspace->global_member_array)
+			find_scope_members_tags(theWorkspace->global_member_array, tags, type_name, lang);
 	}
 
 	g_free(type_name);


Modified: tagmanager/src/tm_workspace.h
3 lines changed, 3 insertions(+), 0 deletions(-)
===================================================================
@@ -33,6 +33,9 @@ typedef struct
 	GPtrArray *tags_array; /**< Sorted tags from all source files 
 		(just pointers to source file tags, the tag objects are owned by the source files) */
 	GPtrArray *typename_array; /* Typename tags for syntax highlighting (pointers owned by source files) */
+	GPtrArray *global_typename_array; /* Like above for global tags */
+	GPtrArray *member_array; /* Typename tags for syntax highlighting (pointers owned by source files) */
+	GPtrArray *global_member_array; /* Like above for global tags */
 } TMWorkspace;
 
 



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Commits mailing list