[gthumb] make gth_folder_tree_set_children() faster for big file lists
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] make gth_folder_tree_set_children() faster for big file lists
- Date: Fri, 23 Apr 2010 23:13:44 +0000 (UTC)
commit 32699f912fd7fef7f4f5e4bd774176776c7fc139
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sat Apr 24 01:10:25 2010 +0200
make gth_folder_tree_set_children() faster for big file lists
[bug #611115]
gthumb/gth-browser.c | 7 +-
gthumb/gth-folder-tree.c | 186 +++++++++++++++++++++++++++++----------------
2 files changed, 125 insertions(+), 68 deletions(-)
---
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index 452d66c..cae915a 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -1336,6 +1336,7 @@ load_data_continue (LoadData *load_data,
GthBrowser *browser = load_data->browser;
GList *files;
GFile *loaded_folder;
+ gboolean loaded_requested_folder;
GtkTreePath *path;
GthTest *filter;
@@ -1351,11 +1352,13 @@ load_data_continue (LoadData *load_data,
loaded_folder = (GFile *) load_data->current->data;
gth_folder_tree_set_children (GTH_FOLDER_TREE (browser->priv->folder_tree), loaded_folder, files);
+
+ loaded_requested_folder = g_file_equal (loaded_folder, load_data->requested_folder->file);
path = gth_folder_tree_get_path (GTH_FOLDER_TREE (browser->priv->folder_tree), loaded_folder);
- if ((path != NULL) && ! g_file_equal (loaded_folder, load_data->requested_folder->file))
+ if ((path != NULL) && ! loaded_requested_folder)
gth_folder_tree_expand_row (GTH_FOLDER_TREE (browser->priv->folder_tree), path, FALSE);
- if (! g_file_equal (loaded_folder, load_data->requested_folder->file)) {
+ if (! loaded_requested_folder) {
gtk_tree_path_free (path);
_g_object_list_unref (files);
diff --git a/gthumb/gth-folder-tree.c b/gthumb/gth-folder-tree.c
index fe77c5a..c19f7ee 100644
--- a/gthumb/gth-folder-tree.c
+++ b/gthumb/gth-folder-tree.c
@@ -599,6 +599,40 @@ gth_folder_tree_get_iter (GthFolderTree *folder_tree,
static gboolean
+_gth_folder_tree_get_child (GthFolderTree *folder_tree,
+ GFile *file,
+ GtkTreeIter *file_iter,
+ GtkTreeIter *parent)
+{
+ GtkTreeModel *tree_model = GTK_TREE_MODEL (folder_tree->priv->tree_store);
+ GtkTreeIter iter;
+
+ if (! gtk_tree_model_iter_children (tree_model, &iter, parent))
+ return FALSE;
+
+ do {
+ GthFileData *test_file_data;
+ EntryType file_entry_type;
+
+ gtk_tree_model_get (tree_model, &iter,
+ COLUMN_FILE_DATA, &test_file_data,
+ COLUMN_TYPE, &file_entry_type,
+ -1);
+ if ((file_entry_type == ENTRY_TYPE_FILE) && (test_file_data != NULL) && g_file_equal (file, test_file_data->file)) {
+ _g_object_unref (test_file_data);
+ *file_iter = iter;
+ return TRUE;
+ }
+
+ _g_object_unref (test_file_data);
+ }
+ while (gtk_tree_model_iter_next (tree_model, &iter));
+
+ return FALSE;
+}
+
+
+static gboolean
_gth_folder_tree_child_type_present (GthFolderTree *folder_tree,
GtkTreeIter *parent,
EntryType entry_type)
@@ -626,12 +660,13 @@ _gth_folder_tree_child_type_present (GthFolderTree *folder_tree,
static void
_gth_folder_tree_add_loading_item (GthFolderTree *folder_tree,
- GtkTreeIter *parent)
+ GtkTreeIter *parent,
+ gboolean forced)
{
char *sort_key;
GtkTreeIter iter;
- if (_gth_folder_tree_child_type_present (folder_tree, parent, ENTRY_TYPE_LOADING))
+ if (! forced && _gth_folder_tree_child_type_present (folder_tree, parent, ENTRY_TYPE_LOADING))
return;
sort_key = g_utf8_collate_key_for_filename (LOADING_URI, -1);
@@ -651,12 +686,13 @@ _gth_folder_tree_add_loading_item (GthFolderTree *folder_tree,
static void
_gth_folder_tree_add_empty_item (GthFolderTree *folder_tree,
- GtkTreeIter *parent)
+ GtkTreeIter *parent,
+ gboolean forced)
{
char *sort_key;
GtkTreeIter iter;
- if (_gth_folder_tree_child_type_present (folder_tree, parent, ENTRY_TYPE_EMPTY))
+ if (! forced && _gth_folder_tree_child_type_present (folder_tree, parent, ENTRY_TYPE_EMPTY))
return;
sort_key = g_utf8_collate_key_for_filename (EMPTY_URI, -1);
@@ -754,8 +790,8 @@ _gth_folder_tree_add_file (GthFolderTree *folder_tree,
COLUMN_WEIGHT, PANGO_WEIGHT_NORMAL,
-1);
- if (! _gth_folder_tree_iter_has_no_child (folder_tree, &iter))
- _gth_folder_tree_add_loading_item (folder_tree, &iter);
+ if (! g_file_info_get_attribute_boolean (fd->info, "gthumb::no-child"))
+ _gth_folder_tree_add_loading_item (folder_tree, &iter, TRUE);
return TRUE;
}
@@ -937,6 +973,7 @@ emit_fake_motion_notify_event (GthFolderTree *folder_tree)
}
+G_GNUC_UNUSED
static GList *
_gth_folder_tree_get_children (GthFolderTree *folder_tree,
GtkTreeIter *parent)
@@ -994,15 +1031,17 @@ _gth_folder_tree_remove_child_type (GthFolderTree *folder_tree,
void
gth_folder_tree_set_children (GthFolderTree *folder_tree,
- GFile *parent,
- GList *files)
+ GFile *parent,
+ GList *files)
{
- GtkTreeIter parent_iter;
- GtkTreeIter *p_parent_iter;
- gboolean is_empty;
- GList *old_files;
- GList *scan;
- GtkTreeIter iter;
+ GtkTreeIter parent_iter;
+ GtkTreeIter *p_parent_iter;
+ gboolean is_empty;
+ GHashTable *file_hash;
+ GList *scan;
+ GList *old_files;
+ GtkTreeModel *tree_model;
+ GtkTreeIter iter;
if (g_file_equal (parent, folder_tree->priv->root))
p_parent_iter = NULL;
@@ -1014,37 +1053,84 @@ gth_folder_tree_set_children (GthFolderTree *folder_tree,
if (_gth_folder_tree_iter_has_no_child (folder_tree, p_parent_iter))
return;
+ tree_model = GTK_TREE_MODEL (folder_tree->priv->tree_store);
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (tree_model), GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, 0);
+
is_empty = TRUE;
- _gth_folder_tree_add_empty_item (folder_tree, p_parent_iter);
- _gth_folder_tree_remove_child_type (folder_tree, p_parent_iter, ENTRY_TYPE_LOADING);
+ _gth_folder_tree_add_empty_item (folder_tree, p_parent_iter, FALSE);
- /* delete the children not present in the new file list */
+ /* delete the children not present in the new file list, update the
+ * already existing files */
- old_files = _gth_folder_tree_get_children (folder_tree, p_parent_iter);
- for (scan = old_files; scan; scan = scan->next) {
+ file_hash = g_hash_table_new (g_file_hash, (GEqualFunc) g_file_equal);
+ for (scan = files; scan; scan = scan->next) {
GthFileData *file_data = scan->data;
+ g_hash_table_insert (file_hash, file_data->file, GINT_TO_POINTER (1));
+ }
- if (! gth_file_data_list_find_file (files, file_data->file)
- && gth_folder_tree_get_iter (folder_tree, file_data->file, &iter, p_parent_iter))
- {
- gtk_tree_store_remove (folder_tree->priv->tree_store, &iter);
+ old_files = NULL;
+ if (gtk_tree_model_iter_children (tree_model, &iter, p_parent_iter)) {
+ gboolean valid = TRUE;
+
+ do {
+ GthFileData *file_data;
+ EntryType file_type;
+
+ gtk_tree_model_get (tree_model, &iter,
+ COLUMN_FILE_DATA, &file_data,
+ COLUMN_TYPE, &file_type,
+ -1);
+
+ if (file_type == ENTRY_TYPE_LOADING) {
+ valid = gtk_tree_store_remove (folder_tree->priv->tree_store, &iter);
+ }
+ else if (file_type == ENTRY_TYPE_FILE) {
+ /* save the old files list to compute the new files list below */
+ old_files = g_list_prepend (old_files, g_object_ref (file_data));
+
+ if (g_hash_table_lookup (file_hash, file_data->file)) {
+ /* file_data is already present in the list, just update it */
+ if (_gth_folder_tree_set_file_data (folder_tree, &iter, file_data))
+ is_empty = FALSE;
+ valid = gtk_tree_model_iter_next (tree_model, &iter);
+ }
+ else {
+ /* file_data is not present anymore, remove it from the tree */
+ valid = gtk_tree_store_remove (folder_tree->priv->tree_store, &iter);
+ }
+ }
+ else
+ valid = gtk_tree_model_iter_next (tree_model, &iter);
+
+ _g_object_unref (file_data);
}
+ while (valid);
}
- _g_object_list_unref (old_files);
- /* add or update the new files */
+ g_hash_table_unref (file_hash);
+
+ /* add the new files */
+
+ file_hash = g_hash_table_new (g_file_hash, (GEqualFunc) g_file_equal);
+ for (scan = old_files; scan; scan = scan->next) {
+ GthFileData *file_data = scan->data;
+ g_hash_table_insert (file_hash, file_data->file, GINT_TO_POINTER (1));
+ }
for (scan = files; scan; scan = scan->next) {
GthFileData *file_data = scan->data;
- if (gth_folder_tree_get_iter (folder_tree, file_data->file, &iter, p_parent_iter)) {
- if (_gth_folder_tree_set_file_data (folder_tree, &iter, file_data))
+ if (! g_hash_table_lookup (file_hash, file_data->file)) {
+ if (_gth_folder_tree_add_file (folder_tree, p_parent_iter, file_data))
is_empty = FALSE;
}
- else if (_gth_folder_tree_add_file (folder_tree, p_parent_iter, file_data))
- is_empty = FALSE;
}
+ _g_object_list_unref (old_files);
+ g_hash_table_unref (file_hash);
+
+ /**/
+
if (! is_empty)
_gth_folder_tree_remove_child_type (folder_tree, p_parent_iter, ENTRY_TYPE_EMPTY);
@@ -1053,6 +1139,8 @@ gth_folder_tree_set_children (GthFolderTree *folder_tree,
COLUMN_LOADED, TRUE,
-1);
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (folder_tree->priv->tree_store), COLUMN_NAME, GTK_SORT_ASCENDING);
+
emit_fake_motion_notify_event (folder_tree);
}
@@ -1073,7 +1161,7 @@ gth_folder_tree_loading_children (GthFolderTree *folder_tree,
else
return;
- _gth_folder_tree_add_loading_item (folder_tree, p_parent_iter);
+ _gth_folder_tree_add_loading_item (folder_tree, p_parent_iter, FALSE);
/* remove anything but the loading item */
gtk_tree_model_iter_children (GTK_TREE_MODEL (folder_tree->priv->tree_store), &iter, p_parent_iter);
@@ -1157,40 +1245,6 @@ gth_folder_tree_add_children (GthFolderTree *folder_tree,
}
-static gboolean
-_gth_folder_tree_get_child (GthFolderTree *folder_tree,
- GFile *file,
- GtkTreeIter *file_iter,
- GtkTreeIter *parent)
-{
- GtkTreeModel *tree_model = GTK_TREE_MODEL (folder_tree->priv->tree_store);
- GtkTreeIter iter;
-
- if (! gtk_tree_model_iter_children (tree_model, &iter, parent))
- return FALSE;
-
- do {
- GthFileData *test_file_data;
- EntryType file_entry_type;
-
- gtk_tree_model_get (tree_model, &iter,
- COLUMN_FILE_DATA, &test_file_data,
- COLUMN_TYPE, &file_entry_type,
- -1);
- if ((file_entry_type == ENTRY_TYPE_FILE) && (test_file_data != NULL) && g_file_equal (file, test_file_data->file)) {
- _g_object_unref (test_file_data);
- *file_iter = iter;
- return TRUE;
- }
-
- _g_object_unref (test_file_data);
- }
- while (gtk_tree_model_iter_next (tree_model, &iter));
-
- return FALSE;
-}
-
-
void
gth_folder_tree_update_children (GthFolderTree *folder_tree,
GFile *parent,
@@ -1251,13 +1305,13 @@ gth_folder_tree_delete_children (GthFolderTree *folder_tree,
return;
/* add the empty item first to not allow the folder to collapse. */
- _gth_folder_tree_add_empty_item (folder_tree, p_parent_iter);
+ _gth_folder_tree_add_empty_item (folder_tree, p_parent_iter, TRUE);
for (scan = files; scan; scan = scan->next) {
GFile *file = scan->data;
GtkTreeIter iter;
- if (gth_folder_tree_get_iter (folder_tree, file, &iter, p_parent_iter))
+ if (_gth_folder_tree_get_child (folder_tree, file, &iter, p_parent_iter))
gtk_tree_store_remove (folder_tree->priv->tree_store, &iter);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]