Re: Speed improvement when changing file permissions?



hi,

that's what my patch did. It probably does not apply cleanly anymore...

Mathieu

On Thu, 2004-03-11 at 09:29, Alexander Larsson wrote:
> On Thu, 2004-03-11 at 06:05, Ryan McDougall wrote:
> > Hi,
> > 	I recently had some strange permissions on a bunch of music files. I
> > thought I would fix them by selecting them all, and setting the correct
> > permissions via nautilus. Un-selecting partially selected check boxes,
> > selecting un-selected boxes, etc., is a *very* slow procedure (approx 30
> > seconds per click). Doing a similar operation via command line took only
> > a second.
> > 
> > 	I was wondering if the operation could be sped up by buffering change
> > requests by maintaining a mask of composite changes and only applying
> > after a timeout, or upon the dialogue being closed. Do usability or
> > other pitfalls lie that way?
> 
> I'm sure its possible, with a bit of care taken. Anyone want to try? (We
> should probably use a timeout, not wait until the dialog is closed, as
> that is what instant apply should do)
> 
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
>  Alexander Larsson                                            Red Hat, Inc 
>                    alexl redhat com    alla lysator liu se 
> He's a scrappy pirate card sharp moving from town to town, helping folk in 
> trouble. She's a blind gypsy cab driver living homeless in New York's sewers. 
> They fight crime! 
-- 
Mathieu Lacage <mathieu gnu org>
? patch
? stamp-h1
? src/patch
? src/file-manager/patch
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/nautilus/ChangeLog,v
retrieving revision 1.5926
diff -u -r1.5926 ChangeLog
--- ChangeLog	12 Sep 2003 08:45:51 -0000	1.5926
+++ ChangeLog	15 Sep 2003 08:21:07 -0000
@@ -1,3 +1,26 @@
+2003-09-15  Mathieu Lacage  <mathieu gnome org>
+
+	Improve performance of the properties window when changing the 
+	properties of a lot of files at the same time. Now, the operations
+	complete much faster and the UI is not frozen anymore when the operations
+	take place.
+	
+	* src/file-manager/fm-properties-window.c: 
+	(remove_from_dialog): disconnect file_changed_cb callback,
+	(properties_window_update): take a list of changed files as input
+	and not a single changed file. This is the core of the optimization, 
+	(update_contents_callback): ensure the list of changed files does not 
+	contain duplicates, invoke properties_window_update on them,
+	(schedule_window_timeout_update): scheudle a timeout for later completion
+	of UI update,
+	(attach_directory_contents_value_field): connect schedule_window_timeout_update
+	on updated_deep_count_in_progress signal,
+	(permission_button_toggled): remove a useless empty line, 
+	(file_changed_cb): insert changed file in list of changed files and
+	schedule a timeout for later update,
+	(create_properties_window): connect file_changed_cb callback, 
+	(real_destroy): make sure to destroy changed file list
+
 2003-09-11 Mathieu Lacage <mathieu gnome org>
 
 	* src/file-manager/fm-properties-window.c: add a wait cursor during
Index: src/file-manager/fm-properties-window.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-properties-window.c,v
retrieving revision 1.178
diff -u -r1.178 fm-properties-window.c
--- src/file-manager/fm-properties-window.c	12 Sep 2003 08:45:53 -0000	1.178
+++ src/file-manager/fm-properties-window.c	15 Sep 2003 08:21:09 -0000
@@ -100,7 +100,7 @@
 
 	GtkLabel *directory_contents_title_field;
 	GtkLabel *directory_contents_value_field;
-	guint update_directory_contents_timeout_id;
+	guint update_contents_timeout_id;
 
 	GList *directory_contents_widgets;
 	int directory_contents_row;
@@ -125,6 +125,8 @@
 	GnomeVFSFileSize total_size;
 
 	guint long_operation_underway;
+
+ 	GList *changed_files;
 };
 
 enum {
@@ -176,16 +178,18 @@
 	{ "x-special/gnome-reset-background", 0, TARGET_RESET_BACKGROUND }
 };
 
-#define DIRECTORY_CONTENTS_UPDATE_INTERVAL	200 /* milliseconds */
+#define CONTENTS_UPDATE_INTERVAL	200 /* milliseconds */
 #define STANDARD_EMBLEM_HEIGHT			52
 #define EMBLEM_LABEL_SPACING			2
 
+static void directory_contents_value_field_update (FMPropertiesWindow *window);
+static void file_changed_cb (NautilusFile *file, gpointer user_data);
 static void permission_button_update (FMPropertiesWindow *window,
 				      GtkToggleButton *button);
 static void value_field_update (FMPropertiesWindow *window,
 				GtkLabel *field);
 static void properties_window_update (FMPropertiesWindow *window, 
-				      NautilusFile *changed_file);
+				      GList *files);
 
 static void is_directory_ready_callback (NautilusFile *file,
 					 gpointer data);
@@ -970,10 +974,10 @@
 	g_hash_table_remove (window->details->initial_permissions, target_file);
 
 	g_signal_handlers_disconnect_by_func (original_file,
-					      G_CALLBACK (properties_window_update),
+					      G_CALLBACK (file_changed_cb),
 					      window);
 	g_signal_handlers_disconnect_by_func (target_file,
-					      G_CALLBACK (properties_window_update),
+					      G_CALLBACK (file_changed_cb),
 					      window);
 
 	nautilus_file_monitor_remove (original_file, window);
@@ -1014,26 +1018,45 @@
 
 static void
 properties_window_update (FMPropertiesWindow *window, 
-			  NautilusFile *changed_file)
+			  GList *files)
 {
 	GList *l;
 	GList *mime_list;
-
-	if (changed_file && nautilus_file_is_gone (changed_file)) {
-		remove_from_dialog (window, changed_file);
-		changed_file = NULL;
-		
-                /* Remove the file from the property dialog */
-		if (window->details->original_files == NULL) {
-			gtk_widget_destroy (GTK_WIDGET (window));
-			return;
+	GList *tmp;
+	NautilusFile *changed_file;
+	gboolean dirty_original = FALSE;
+	gboolean dirty_target = FALSE;
+
+	if (files == NULL) {
+		dirty_original = TRUE;
+		dirty_target = TRUE;
+	}
+
+	for (tmp = files; tmp != NULL; tmp = tmp->next) {
+		changed_file = NAUTILUS_FILE (tmp->data);
+
+		if (changed_file && nautilus_file_is_gone (changed_file)) {
+			remove_from_dialog (window, changed_file);
+			changed_file = NULL;
+			
+			/* Remove the file from the property dialog */
+			if (window->details->original_files == NULL) {
+				gtk_widget_destroy (GTK_WIDGET (window));
+				return;
+			}
+		}		
+		if (!changed_file 
+		    || g_list_find (window->details->original_files, changed_file)) {
+			dirty_original = TRUE;
+		}
+		if (!changed_file 
+		    || g_list_find (window->details->target_files, changed_file)) {
+			dirty_target = TRUE;
 		}
-
 	}
 
-	if (!changed_file 
-	    || g_list_find (window->details->original_files, changed_file)) {
 		
+	if (dirty_original) {
 		update_properties_window_title (window);
 		update_properties_window_icon (GTK_IMAGE (window->details->icon_image));
 
@@ -1047,8 +1070,7 @@
 		 * value, value_field_updates should be added here */
 	}
 
-	if (!changed_file 
-	    || g_list_find (window->details->target_files, changed_file)) {
+	if (dirty_target) {
 		for (l = window->details->permission_buttons; l != NULL; l = l->next) {
 			permission_button_update (window, GTK_TOGGLE_BUTTON (l->data));
 		}
@@ -1070,6 +1092,8 @@
 		eel_g_list_free_deep (window->details->mime_list);
 		window->details->mime_list = mime_list;
 	}
+
+	directory_contents_value_field_update (window);
 }
 
 static gboolean
@@ -1783,27 +1807,44 @@
 }
 
 static gboolean
-update_directory_contents_callback (gpointer data)
+update_contents_callback (gpointer data)
 {
 	FMPropertiesWindow *window;
 
 	window = FM_PROPERTIES_WINDOW (data);
 
-	window->details->update_directory_contents_timeout_id = 0;
+	window->details->update_contents_timeout_id = 0;
+
+	{
+		GList *tmp, *unique;
+		unique = 0;
+		for (tmp = window->details->changed_files; tmp != NULL; tmp = tmp->next) {
+			if (g_list_find (unique, tmp->data)) {
+				nautilus_file_unref (NAUTILUS_FILE (tmp->data));
+				continue;
+			}
+			unique = g_list_prepend (unique, tmp->data);
+		}
+		g_list_free (window->details->changed_files);
+		window->details->changed_files = NULL;
+		properties_window_update (window, unique);
+		nautilus_file_list_free (unique);
+	}
+
 	directory_contents_value_field_update (window);
 
 	return FALSE;
 }
 
 static void
-schedule_directory_contents_update (FMPropertiesWindow *window)
+schedule_window_timeout_update (FMPropertiesWindow *window)
 {
 	g_assert (FM_IS_PROPERTIES_WINDOW (window));
 
-	if (window->details->update_directory_contents_timeout_id == 0) {
-		window->details->update_directory_contents_timeout_id
-			= g_timeout_add (DIRECTORY_CONTENTS_UPDATE_INTERVAL,
-					 update_directory_contents_callback,
+	if (window->details->update_contents_timeout_id == 0) {
+		window->details->update_contents_timeout_id
+			= g_timeout_add (CONTENTS_UPDATE_INTERVAL,
+					 update_contents_callback,
 					 window);
 	}
 }
@@ -1834,7 +1875,7 @@
 		
 		g_signal_connect_object (file,
 					 "updated_deep_count_in_progress",
-					 G_CALLBACK (schedule_directory_contents_update),
+					 G_CALLBACK (schedule_window_timeout_update),
 					 window, G_CONNECT_SWAPPED);
 	}
 	
@@ -2546,7 +2587,6 @@
 				 permission_change_callback,
 				 window);
 		}
-		
 	}
 	
 	for (l = files_off; l != NULL; l = l->next) {
@@ -3308,6 +3348,17 @@
 	}
 }
 
+static void
+file_changed_cb (NautilusFile *file, gpointer user_data)
+{
+	FMPropertiesWindow *window = FM_PROPERTIES_WINDOW (user_data);
+
+	nautilus_file_ref (file);
+	window->details->changed_files = g_list_prepend (window->details->changed_files, file);
+
+	schedule_window_timeout_update (window);
+}
+
 static FMPropertiesWindow *
 create_properties_window (StartupData *startup_data)
 {
@@ -3368,17 +3419,17 @@
 	for (l = window->details->target_files; l != NULL; l = l->next) {
 		g_signal_connect_object (NAUTILUS_FILE (l->data),
 					 "changed",
-					 G_CALLBACK (properties_window_update),
+					 G_CALLBACK (file_changed_cb),
 					 G_OBJECT (window),
-					 G_CONNECT_SWAPPED);
+					 0);
 	}
 
 	for (l = window->details->original_files; l != NULL; l = l->next) {
 		g_signal_connect_object (NAUTILUS_FILE (l->data),
 					 "changed",
-					 G_CALLBACK (properties_window_update),
+					 G_CALLBACK (file_changed_cb),
 					 G_OBJECT (window),
-					 G_CONNECT_SWAPPED);
+					 0);
 	}
 
 	/* Create box for notebook and button box. */
@@ -3674,6 +3725,9 @@
 	nautilus_file_list_free (window->details->target_files);
 	window->details->target_files = NULL;
 
+	nautilus_file_list_free (window->details->changed_files);
+	window->details->changed_files = NULL;
+
 	window->details->name_field = NULL;
 	
 	g_list_free (window->details->directory_contents_widgets);
@@ -3701,9 +3755,9 @@
 	g_list_free (window->details->value_fields);
 	window->details->value_fields = NULL;
 
-	if (window->details->update_directory_contents_timeout_id != 0) {
-		g_source_remove (window->details->update_directory_contents_timeout_id);
-		window->details->update_directory_contents_timeout_id = 0;
+	if (window->details->update_contents_timeout_id != 0) {
+		g_source_remove (window->details->update_contents_timeout_id);
+		window->details->update_contents_timeout_id = 0;
 	}
 	GTK_OBJECT_CLASS (parent_class)->destroy (object);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]