[geany/geany-plugins] 667fa6: projectorganizer: optimize tree creation

Jiří Techet git-noreply at xxxxx
Sun May 3 21:02:30 UTC 2015


Branch:      refs/heads/master
Author:      Jiří Techet <techet at gmail.com>
Committer:   Jiří Techet <techet at gmail.com>
Date:        Sun, 03 May 2015 21:02:30 UTC
Commit:      667fa64af92957b8fc0ca641060add19dd27b19e
             https://github.com/geany/geany-plugins/commit/667fa64af92957b8fc0ca641060add19dd27b19e

Log Message:
-----------
projectorganizer: optimize tree creation

1. Use gtk_tree_store_insert_with_values() which is faster than calling
gtk_tree_store_append() and gtk_tree_store_set()

2. Avoid the use of gtk_tree_store_set() which walks all the siblings
internally.

3. Prepend values to the tree store (because it behaves as a list).

There are usually not thousands of files in a single directory to see the
effect of this optimization but knowing the lists are walked all the time
makes me nervous.


Modified Paths:
--------------
    projectorganizer/src/prjorg-sidebar.c

Modified: projectorganizer/src/prjorg-sidebar.c
139 lines changed, 68 insertions(+), 71 deletions(-)
===================================================================
@@ -861,56 +861,6 @@ static void create_branch(gint level, GSList *leaf_list, GtkTreeIter *parent,
 			file_list = g_slist_prepend(file_list, path_arr);
 	}
 
-	if (dir_list)
-	{
-		GSList *tmp_list = NULL;
-		GtkTreeIter iter;
-		gchar **path_arr = dir_list->data;
-		gchar *last_dir_name;
-		GIcon *icon_dir = g_icon_new_for_string("folder", NULL);
-
-		last_dir_name = path_arr[level];
-
-		foreach_slist (elem, dir_list)
-		{
-			gboolean dir_changed;
-
-			path_arr = (gchar **) elem->data;
-			dir_changed = g_strcmp0(last_dir_name, path_arr[level]) != 0;
-
-			if (dir_changed)
-			{
-				gtk_tree_store_append(s_file_store, &iter, parent);
-				gtk_tree_store_set(s_file_store, &iter,
-					FILEVIEW_COLUMN_ICON, icon_dir,
-					FILEVIEW_COLUMN_NAME, last_dir_name, -1);
-				if (!project)
-					gtk_tree_store_set(s_file_store, &iter, FILEVIEW_COLUMN_COLOR, &s_external_color, -1);
-				
-				create_branch(level+1, tmp_list, &iter, header_patterns, source_patterns, project);
-
-				g_slist_free(tmp_list);
-				tmp_list = NULL;
-				last_dir_name = path_arr[level];
-			}
-
-			tmp_list = g_slist_prepend(tmp_list, path_arr);
-		}
-
-		gtk_tree_store_append(s_file_store, &iter, parent);
-		gtk_tree_store_set(s_file_store, &iter,
-			FILEVIEW_COLUMN_ICON, icon_dir,
-			FILEVIEW_COLUMN_NAME, last_dir_name, -1);
-		if (!project)
-			gtk_tree_store_set(s_file_store, &iter, FILEVIEW_COLUMN_COLOR, &s_external_color, -1);
-
-		create_branch(level+1, tmp_list, &iter, header_patterns, source_patterns, project);
-
-		g_slist_free(tmp_list);
-		g_slist_free(dir_list);
-		g_object_unref(icon_dir);
-	}
-
 	foreach_slist (elem, file_list)
 	{
 		GtkTreeIter iter;
@@ -937,45 +887,87 @@ static void create_branch(gint level, GSList *leaf_list, GtkTreeIter *parent,
 			g_free(content_type);
 		}
 
-		gtk_tree_store_append(s_file_store, &iter, parent);
 		if (patterns_match(header_patterns, path_arr[level]))
 		{
 			if (! icon)
 				icon = g_icon_new_for_string("prjorg-header", NULL);
 
-			gtk_tree_store_set(s_file_store, &iter,
+			gtk_tree_store_insert_with_values(s_file_store, &iter, parent, 0,
 				FILEVIEW_COLUMN_ICON, icon,
-				FILEVIEW_COLUMN_NAME, path_arr[level], -1);
-			if (!project)
-				gtk_tree_store_set(s_file_store, &iter, FILEVIEW_COLUMN_COLOR, &s_external_color, -1);
+				FILEVIEW_COLUMN_NAME, path_arr[level],
+				FILEVIEW_COLUMN_COLOR, project ? NULL : &s_external_color, -1);
 		}
 		else if (patterns_match(source_patterns, path_arr[level]))
 		{
 			if (! icon)
 				icon = g_icon_new_for_string("prjorg-source", NULL);
 
-			gtk_tree_store_set(s_file_store, &iter,
+			gtk_tree_store_insert_with_values(s_file_store, &iter, parent, 0,
 				FILEVIEW_COLUMN_ICON, icon,
-				FILEVIEW_COLUMN_NAME, path_arr[level], -1);
-			if (!project)
-				gtk_tree_store_set(s_file_store, &iter, FILEVIEW_COLUMN_COLOR, &s_external_color, -1);
+				FILEVIEW_COLUMN_NAME, path_arr[level],
+				FILEVIEW_COLUMN_COLOR, project ? NULL : &s_external_color, -1);
 		}
 		else
 		{
 			if (! icon)
 				icon = g_icon_new_for_string("prjorg-file", NULL);
 
-			gtk_tree_store_set(s_file_store, &iter,
+			gtk_tree_store_insert_with_values(s_file_store, &iter, parent, 0,
 				FILEVIEW_COLUMN_ICON, icon,
-				FILEVIEW_COLUMN_NAME, path_arr[level], -1);
-			if (!project)
-				gtk_tree_store_set(s_file_store, &iter, FILEVIEW_COLUMN_COLOR, &s_external_color, -1);
+				FILEVIEW_COLUMN_NAME, path_arr[level],
+				FILEVIEW_COLUMN_COLOR, project ? NULL : &s_external_color, -1);
 		}
 
 		if (icon)
 			g_object_unref(icon);
 	}
 
+	if (dir_list)
+	{
+		GSList *tmp_list = NULL;
+		GtkTreeIter iter;
+		gchar **path_arr = dir_list->data;
+		gchar *last_dir_name;
+		GIcon *icon_dir = g_icon_new_for_string("folder", NULL);
+
+		last_dir_name = path_arr[level];
+
+		foreach_slist (elem, dir_list)
+		{
+			gboolean dir_changed;
+
+			path_arr = (gchar **) elem->data;
+			dir_changed = g_strcmp0(last_dir_name, path_arr[level]) != 0;
+
+			if (dir_changed)
+			{
+				gtk_tree_store_insert_with_values(s_file_store, &iter, parent, 0,
+					FILEVIEW_COLUMN_ICON, icon_dir,
+					FILEVIEW_COLUMN_NAME, last_dir_name,
+					FILEVIEW_COLUMN_COLOR, project ? NULL : &s_external_color, -1);
+
+				create_branch(level+1, tmp_list, &iter, header_patterns, source_patterns, project);
+
+				g_slist_free(tmp_list);
+				tmp_list = NULL;
+				last_dir_name = path_arr[level];
+			}
+
+			tmp_list = g_slist_prepend(tmp_list, path_arr);
+		}
+
+		gtk_tree_store_insert_with_values(s_file_store, &iter, parent, 0,
+			FILEVIEW_COLUMN_ICON, icon_dir,
+			FILEVIEW_COLUMN_NAME, last_dir_name,
+			FILEVIEW_COLUMN_COLOR, project ? NULL : &s_external_color, -1);
+
+		create_branch(level+1, tmp_list, &iter, header_patterns, source_patterns, project);
+
+		g_slist_free(tmp_list);
+		g_slist_free(dir_list);
+		g_object_unref(icon_dir);
+	}
+
 	g_slist_free(file_list);
 }
 
@@ -984,8 +976,7 @@ static void set_intro_message(const gchar *msg)
 {
 	GtkTreeIter iter;
 
-	gtk_tree_store_append(s_file_store, &iter, NULL);
-	gtk_tree_store_set(s_file_store, &iter,
+	gtk_tree_store_insert_with_values(s_file_store, &iter, NULL, -1,
 		FILEVIEW_COLUMN_NAME, msg, -1);
 
 	gtk_widget_set_sensitive(s_project_toolbar.expand, FALSE);
@@ -995,6 +986,12 @@ static void set_intro_message(const gchar *msg)
 }
 
 
+static int rev_strcmp(const char *str1, const char *str2)
+{
+	return strcmp(str2, str1);
+}
+
+
 static void load_project_root(PrjOrgRoot *root, GtkTreeIter *parent, GSList *header_patterns, GSList *source_patterns, gboolean project)
 {
 	GSList *lst = NULL;
@@ -1009,7 +1006,9 @@ static void load_project_root(PrjOrgRoot *root, GtkTreeIter *parent, GSList *hea
 		gchar *path = get_relative_path(root->base_dir, key);
 		lst = g_slist_prepend(lst, path);
 	}
-	lst = g_slist_sort(lst, (GCompareFunc) strcmp);
+	/* sort in reverse order so we can prepend nodes to the tree store -
+	 * the store behaves as a linked list and prepending is faster */
+	lst = g_slist_sort(lst, (GCompareFunc) rev_strcmp);
 
 	foreach_slist (elem, lst)
 	{
@@ -1072,12 +1071,10 @@ static void load_project(void)
 		else
 			name = g_strdup(root->base_dir);
 
-		gtk_tree_store_append(s_file_store, &iter, NULL);
-		gtk_tree_store_set(s_file_store, &iter,
+		gtk_tree_store_insert_with_values(s_file_store, &iter, NULL, -1,
 			FILEVIEW_COLUMN_ICON, icon_dir,
-			FILEVIEW_COLUMN_NAME, name, -1);
-		if (!first)
-			gtk_tree_store_set(s_file_store, &iter, FILEVIEW_COLUMN_COLOR, &s_external_color, -1);
+			FILEVIEW_COLUMN_NAME, name,
+			FILEVIEW_COLUMN_COLOR, first ? NULL : &s_external_color, -1);
 
 		load_project_root(root, &iter, header_patterns, source_patterns, first);
 



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


More information about the Plugins-Commits mailing list