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.
This commit is contained in:
Jiří Techet 2014-11-05 20:21:33 +01:00
parent 29000cf104
commit 90944c77b0
2 changed files with 39 additions and 34 deletions

View File

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

View File

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