From 90944c77b0c304de28d26297687c12383d76ef39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Techet?= Date: Wed, 5 Nov 2014 20:21:33 +0100 Subject: [PATCH] Unify tag sorting and simplify tag comparison function Use the same (or compatible) sorting criteria everywhere. Add tm_tag_attr_line_t to sort options so even after merging file tags into workspace tags, the same tags defined at different lines are preserved and not removed as duplicates. Sort type before scope because it's cheaper to compare (string vs int comparison). For some reason, the above changes make the sorting performance worse. Simplify the tag comparison function a bit and reorder the case statements in the switch to match the sort order. This (again not sure why), makes the performance like before. --- tagmanager/src/tm_tag.c | 32 +++++++++++---------------- tagmanager/src/tm_workspace.c | 41 ++++++++++++++++++++++------------- 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/tagmanager/src/tm_tag.c b/tagmanager/src/tm_tag.c index 3d1ed64ee1..a617544ee6 100644 --- a/tagmanager/src/tm_tag.c +++ b/tagmanager/src/tm_tag.c @@ -695,7 +695,7 @@ static gint tm_tag_compare(gconstpointer ptr1, gconstpointer ptr2, gpointer user return strcmp(FALLBACK(t1->name, ""), FALLBACK(t2->name, "")); } - for (sort_attr = sort_options->sort_attrs; *sort_attr != tm_tag_attr_none_t; ++ sort_attr) + for (sort_attr = sort_options->sort_attrs; returnval == 0 && *sort_attr != tm_tag_attr_none_t; ++ sort_attr) { switch (*sort_attr) { @@ -704,36 +704,30 @@ static gint tm_tag_compare(gconstpointer ptr1, gconstpointer ptr2, gpointer user returnval = strncmp(FALLBACK(t1->name, ""), FALLBACK(t2->name, ""), strlen(FALLBACK(t1->name, ""))); else returnval = strcmp(FALLBACK(t1->name, ""), FALLBACK(t2->name, "")); - if (0 != returnval) - return returnval; - break; - case tm_tag_attr_type_t: - if (0 != (returnval = (t1->type - t2->type))) - return returnval; break; case tm_tag_attr_file_t: - if (0 != (returnval = (t1->file - t2->file))) - return returnval; + returnval = t1->file - t2->file; + break; + case tm_tag_attr_line_t: + returnval = t1->line - t2->line; + break; + case tm_tag_attr_type_t: + returnval = t1->type - t2->type; break; case tm_tag_attr_scope_t: - if (0 != (returnval = strcmp(FALLBACK(t1->scope, ""), FALLBACK(t2->scope, "")))) - return returnval; + returnval = strcmp(FALLBACK(t1->scope, ""), FALLBACK(t2->scope, "")); break; case tm_tag_attr_arglist_t: - if (0 != (returnval = strcmp(FALLBACK(t1->arglist, ""), FALLBACK(t2->arglist, "")))) + returnval = strcmp(FALLBACK(t1->arglist, ""), FALLBACK(t2->arglist, "")); + if (returnval != 0) { int line_diff = (t1->line - t2->line); - return line_diff ? line_diff : returnval; + returnval = line_diff ? line_diff : returnval; } break; case tm_tag_attr_vartype_t: - if (0 != (returnval = strcmp(FALLBACK(t1->var_type, ""), FALLBACK(t2->var_type, "")))) - return returnval; - break; - case tm_tag_attr_line_t: - if (0 != (returnval = (t1->line - t2->line))) - return returnval; + returnval = strcmp(FALLBACK(t1->var_type, ""), FALLBACK(t2->var_type, "")); break; } } diff --git a/tagmanager/src/tm_workspace.c b/tagmanager/src/tm_workspace.c index 1272d2b713..c82ef2c339 100644 --- a/tagmanager/src/tm_workspace.c +++ b/tagmanager/src/tm_workspace.c @@ -33,6 +33,29 @@ #include "tm_workspace.h" #include "tm_tag.h" + +/* when changing, always keep the three sort criteria below in sync */ +static TMTagAttrType workspace_tags_sort_attrs[] = +{ + tm_tag_attr_name_t, tm_tag_attr_file_t, tm_tag_attr_line_t, + tm_tag_attr_type_t, tm_tag_attr_scope_t, tm_tag_attr_arglist_t, 0 +}; + +/* for file tags the file is always identical, don't use for sorting */ +static TMTagAttrType file_tags_sort_attrs[] = +{ + tm_tag_attr_name_t, tm_tag_attr_line_t, + tm_tag_attr_type_t, tm_tag_attr_scope_t, tm_tag_attr_arglist_t, 0 +}; + +/* global tags don't have file/line information */ +static TMTagAttrType global_tags_sort_attrs[] = +{ + tm_tag_attr_name_t, + tm_tag_attr_type_t, tm_tag_attr_scope_t, tm_tag_attr_arglist_t, 0 +}; + + static TMWorkspace *theWorkspace = NULL; @@ -86,10 +109,7 @@ const TMWorkspace *tm_get_workspace(void) static void tm_workspace_merge_tags(GPtrArray **big_array, GPtrArray *small_array) { - TMTagAttrType sort_attrs[] = { tm_tag_attr_name_t, tm_tag_attr_file_t, - tm_tag_attr_scope_t, tm_tag_attr_type_t, tm_tag_attr_arglist_t, 0}; - - GPtrArray *new_tags = tm_tags_merge(*big_array, small_array, sort_attrs, FALSE); + GPtrArray *new_tags = tm_tags_merge(*big_array, small_array, workspace_tags_sort_attrs, FALSE); /* tags owned by TMSourceFile - free just the pointer array */ g_ptr_array_free(*big_array, TRUE); *big_array = new_tags; @@ -111,7 +131,7 @@ static void update_source_file(TMSourceFile *source_file, guchar* text_buf, tm_tags_remove_file_tags(source_file, theWorkspace->typename_array); } tm_source_file_parse(source_file, text_buf, buf_size, use_buffer); - tm_tags_sort(source_file->tags_array, NULL, FALSE, TRUE); + tm_tags_sort(source_file->tags_array, file_tags_sort_attrs, FALSE, TRUE); if (update_workspace) { GPtrArray *sf_typedefs; @@ -210,8 +230,6 @@ static void tm_workspace_update(void) { guint i, j; TMSourceFile *source_file; - TMTagAttrType sort_attrs[] = { tm_tag_attr_name_t, tm_tag_attr_file_t - , tm_tag_attr_scope_t, tm_tag_attr_type_t, tm_tag_attr_arglist_t, 0}; #ifdef TM_DEBUG g_message("Recreating workspace tags array"); @@ -240,7 +258,7 @@ static void tm_workspace_update(void) #ifdef TM_DEBUG g_message("Total: %d tags", theWorkspace->tags_array->len); #endif - tm_tags_sort(theWorkspace->tags_array, sort_attrs, TRUE, FALSE); + tm_tags_sort(theWorkspace->tags_array, workspace_tags_sort_attrs, TRUE, FALSE); theWorkspace->typename_array = tm_tags_extract(theWorkspace->tags_array, TM_GLOBAL_TYPE_MASK); } @@ -296,13 +314,6 @@ void tm_workspace_remove_source_files(GPtrArray *source_files) } -static TMTagAttrType global_tags_sort_attrs[] = -{ - tm_tag_attr_name_t, tm_tag_attr_scope_t, - tm_tag_attr_type_t, tm_tag_attr_arglist_t, 0 -}; - - /* Loads the global tag list from the specified file. The global tag list should have been first created using tm_workspace_create_global_tags(). @param tags_file The file containing global tags.