Skip to content

Commit

Permalink
Eliminate calls of slow tm_tags_extract() on big arrays
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
techee committed Jul 14, 2015
1 parent 5c18b3d commit 99e222e
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 24 deletions.
4 changes: 1 addition & 3 deletions src/symbols.c
Expand Up @@ -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;

Expand All @@ -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;
}

Expand Down
56 changes: 35 additions & 21 deletions tagmanager/src/tm_workspace.c
Expand Up @@ -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;

Expand All @@ -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;
}

Expand All @@ -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;
}
Expand Down Expand Up @@ -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)
{
Expand All @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}


Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions tagmanager/src/tm_workspace.h
Expand Up @@ -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;


Expand Down

0 comments on commit 99e222e

Please sign in to comment.