file-roller r2639 - in trunk: . src



Author: paobac
Date: Tue Mar 31 17:06:54 2009
New Revision: 2639
URL: http://svn.gnome.org/viewvc/file-roller?rev=2639&view=rev

Log:
2009-03-31  Paolo Bacchilega  <paobac svn gnome org>

	* src/file-utils.h: 
	* src/file-utils.c: 
	
	added a parent_folder argument to get_temp_work_dir
	
	* src/fr-archive.c (fr_archive_extract_to_local): 
	
	create the temp dir in the destination folder to make the mv 
	operation faster.

	* src/fr-command-unstuff.c: 
	* src/fr-command-jar.c: 
	* src/fr-window.c: 
	* src/fr-command-cfile.c: 
	
	updated calls to get_temp_work_dir

	* src/glib-utils.h: 
	* src/glib-utils.c: 
	* src/fr-window.c: 
	* src/fr-command.c: 
	* src/fr-archive.c: 
	* src/file-data.h: 
	* src/file-data.c: 
	
	sort the files array after getting the list and search a path using 
	a binary search to speed up the operation.
	
	Fixes bug #577389 â File roller hangs and leaks memory when file is 
	dragged / dropped from archive


Modified:
   trunk/ChangeLog
   trunk/configure.ac
   trunk/src/file-data.c
   trunk/src/file-data.h
   trunk/src/file-utils.c
   trunk/src/file-utils.h
   trunk/src/fr-archive.c
   trunk/src/fr-command-cfile.c
   trunk/src/fr-command-jar.c
   trunk/src/fr-command-unstuff.c
   trunk/src/fr-command.c
   trunk/src/fr-window.c
   trunk/src/glib-utils.c
   trunk/src/glib-utils.h

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Tue Mar 31 17:06:54 2009
@@ -2,7 +2,7 @@
 
 AC_PREREQ(2.61)
 
-AC_INIT(file-roller, 2.26.0, [http://bugzilla.gnome.org/enter_bug.cgi?product=file-roller])
+AC_INIT(file-roller, 2.26.1, [http://bugzilla.gnome.org/enter_bug.cgi?product=file-roller])
 AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
 
 AC_CONFIG_SRCDIR([config.h.in])

Modified: trunk/src/file-data.c
==============================================================================
--- trunk/src/file-data.c	(original)
+++ trunk/src/file-data.c	Tue Mar 31 17:06:54 2009
@@ -114,3 +114,39 @@
 {
 	return fdata->dir || fdata->list_dir;
 }
+
+
+int
+file_data_compare_by_path (gconstpointer a,
+			   gconstpointer b)
+{
+	FileData *data_a = *((FileData **) a);
+	FileData *data_b = *((FileData **) b);
+	
+	return strcmp (data_a->full_path, data_b->full_path);
+}
+
+
+int
+find_path_in_file_data_array (GPtrArray  *array,
+			      const char *path)
+{
+	int       l, r, p, cmp = -1;
+	FileData *fd;
+			
+	l = 0;
+	r = array->len;
+	while (l < r) {
+		p = l + ((r - l) / 2);
+		fd = (FileData *) g_ptr_array_index (array, p);
+		cmp = strcmp (path, fd->original_path);
+		if (cmp == 0)
+			return p; 
+		else if (cmp < 0)
+			r = p;
+		else 
+			l = p + 1;
+	}
+	
+	return -1;
+}

Modified: trunk/src/file-data.h
==============================================================================
--- trunk/src/file-data.h	(original)
+++ trunk/src/file-data.h	Tue Mar 31 17:06:54 2009
@@ -62,4 +62,9 @@
 void            file_data_update_content_type (FileData *fdata);
 gboolean        file_data_is_dir              (FileData *fdata);
 
+int  file_data_compare_by_path                (gconstpointer a, 
+				               gconstpointer b);
+int  find_path_in_file_data_array             (GPtrArray   *array,
+				               const char *path);
+
 #endif /* FILE_DATA_H */

Modified: trunk/src/file-utils.c
==============================================================================
--- trunk/src/file-utils.c	(original)
+++ trunk/src/file-utils.c	Tue Mar 31 17:06:54 2009
@@ -907,7 +907,7 @@
 
 
 char *
-get_temp_work_dir (void)
+get_temp_work_dir (const char *parent_folder)
 {
 	guint64  max_size = 0;
 	char    *best_folder = NULL;
@@ -915,23 +915,27 @@
 	char    *template;
 	char    *result = NULL;
 
-	/* find the folder with more free space. */
-
-	for (i = 0; try_folder[i] != NULL; i++) {
-		char    *folder;
-		guint64  size;
-
-		folder = ith_temp_folder_to_try (i);
-		size = get_dest_free_space (folder);
-		if (max_size < size) {
-			max_size = size;
-			g_free (best_folder);
-			best_folder = folder;
+	if (parent_folder == NULL) { 	
+		/* find the folder with more free space. */
+	
+		for (i = 0; try_folder[i] != NULL; i++) {
+			char    *folder;
+			guint64  size;
+	
+			folder = ith_temp_folder_to_try (i);
+			size = get_dest_free_space (folder);
+			if (max_size < size) {
+				max_size = size;
+				g_free (best_folder);
+				best_folder = folder;
+			}
+			else
+				g_free (folder);
 		}
-		else
-			g_free (folder);
-	}
-
+	}	
+	else 
+		best_folder = g_strdup (parent_folder);
+		
 	if (best_folder == NULL)
 		return NULL;
 	

Modified: trunk/src/file-utils.h
==============================================================================
--- trunk/src/file-utils.h	(original)
+++ trunk/src/file-utils.h	Tue Mar 31 17:06:54 2009
@@ -80,7 +80,7 @@
 guint64             get_dest_free_space          (const char  *path);
 gboolean            remove_directory             (const char  *uri);
 gboolean            remove_local_directory       (const char  *directory);
-char *              get_temp_work_dir            (void);
+char *              get_temp_work_dir            (const char  *parent_folder);
 gboolean            is_temp_work_dir             (const char *dir);
 gboolean            is_temp_dir                  (const char *dir);
 

Modified: trunk/src/fr-archive.c
==============================================================================
--- trunk/src/fr-archive.c	(original)
+++ trunk/src/fr-archive.c	Tue Mar 31 17:06:54 2009
@@ -394,7 +394,7 @@
 	char  *temp_dir;
 	GFile *local_copy = NULL;
 
-	temp_dir = get_temp_work_dir ();
+	temp_dir = get_temp_work_dir (NULL);
 	if (temp_dir != NULL) {
 		char  *archive_name;
 		char  *local_path;
@@ -1355,7 +1355,7 @@
 	debug (DEBUG_INFO, "base_dir: %s\n", base_dir);
 	debug (DEBUG_INFO, "dest_dir: %s\n", dest_dir);
 
-	temp_dir = get_temp_work_dir ();
+	temp_dir = get_temp_work_dir (NULL);
 	tmp = remove_level_from_path (dest_dir);
 	parent_dir =  g_build_filename (temp_dir, tmp, NULL);
 	g_free (tmp);
@@ -1383,13 +1383,11 @@
 
 	g_return_val_if_fail (path != NULL, NULL);
 
-	for (i = 0; i < archive->command->files->len; i++) {
-		FileData *fdata = g_ptr_array_index (archive->command->files, i);
-		if (strcmp (path, fdata->original_path) == 0)
-			return fdata;
-	}
-
-	return NULL;
+	i = find_path_in_file_data_array (archive->command->files, path);
+	if (i >= 0)
+		return (FileData *) g_ptr_array_index (archive->command->files, i);
+	else
+		return NULL;
 }
 
 
@@ -1476,7 +1474,7 @@
 
 	if (error != NULL)
 		*error = NULL;
-	*list_dir = get_temp_work_dir ();
+	*list_dir = get_temp_work_dir (NULL);
 	*list_filename = g_build_filename (*list_dir, "file-list", NULL);
 	list_file = g_file_new_for_path (*list_filename);
 	ostream = g_file_create (list_file, G_FILE_CREATE_PRIVATE, NULL, error);
@@ -1906,7 +1904,7 @@
 fr_archive_get_temp_work_dir (FrArchive *archive)
 {
 	fr_archive_remove_temp_work_dir (archive);
-	archive->priv->temp_dir = get_temp_work_dir ();
+	archive->priv->temp_dir = get_temp_work_dir (NULL);
 	return archive->priv->temp_dir;
 }
 
@@ -2752,7 +2750,7 @@
 			new_path = g_strdup (file_name_from_path (path));
 		else
 			new_path = g_strdup (path);
-		debug (DEBUG_INFO, "%s, %s --> %s\n", base_dir, path, new_path);
+		/*debug (DEBUG_INFO, "%s, %s --> %s\n", base_dir, path, new_path);*/
 		return new_path;
 	}
 
@@ -2771,7 +2769,7 @@
 		new_path = g_strndup (path, name_len);
 	}
 
-	debug (DEBUG_INFO, "%s, %s --> %s\n", base_dir, path, new_path);
+	/*debug (DEBUG_INFO, "%s, %s --> %s\n", base_dir, path, new_path);*/
 
 	return new_path;
 }
@@ -2850,23 +2848,24 @@
 
 
 static GList*
-remove_files_contained_in_this_dir (GList      *file_list,
-				    const char *dirname,
-				    gboolean   *changed)
+remove_files_contained_in_this_dir (GList *file_list,
+				    GList *dir_pointer)
 {
+	char  *dirname = dir_pointer->data;
+	int    dirname_l = strlen (dirname);
 	GList *scan;
-
-	*changed = FALSE;
-
-	for (scan = file_list; scan; /* empty */) {
+	
+	for (scan = dir_pointer->next; scan; /* empty */) {
 		char *filename = scan->data;
 
+		if (strncmp (dirname, filename, dirname_l) != 0)
+			break;
+
 		if (path_in_path (dirname, filename)) {
 			GList *next = scan->next;
 
 			file_list = g_list_remove_link (file_list, scan);
 			g_list_free (scan);
-			*changed = TRUE;
 
 			scan = next;
 		}
@@ -2936,15 +2935,8 @@
 			created_filtered_list = TRUE;
 			filtered = g_list_copy (file_list);
 			filtered = g_list_sort (filtered, (GCompareFunc) strcmp);
-			for (scan = filtered; scan; /* empty */) {
-				gboolean changed = FALSE;
-
-				filtered = remove_files_contained_in_this_dir (filtered, scan->data, &changed);
-				if (changed)
-					scan = filtered;
-				else
-					scan = scan->next;
-			}
+			for (scan = filtered; scan; scan = scan->next) 
+				filtered = remove_files_contained_in_this_dir (filtered, scan);
 		}
 		else
 			filtered = file_list;
@@ -3015,7 +3007,7 @@
 		else
 			sprintf (dest_filename, "%s/%s", destination, filename);
 
-		debug (DEBUG_INFO, "-> %s\n", dest_filename);
+		/*debug (DEBUG_INFO, "-> %s\n", dest_filename);*/
 
 		/**/
 
@@ -3045,7 +3037,7 @@
 	if (move_to_dest_dir) {
 		char *temp_dir;
 
-		temp_dir = get_temp_work_dir ();
+		temp_dir = get_temp_work_dir (destination);
 		extract_from_archive (archive,
 				      filtered,
 				      temp_dir,
@@ -3108,7 +3100,7 @@
 
 	archive->priv->remote_extraction = ! uri_is_local (destination);
 	if (archive->priv->remote_extraction) {
- 		archive->priv->temp_extraction_dir = get_temp_work_dir ();
+ 		archive->priv->temp_extraction_dir = get_temp_work_dir (NULL);
 		fr_archive_extract_to_local (archive,
 				  	     file_list,
 				  	     archive->priv->temp_extraction_dir,

Modified: trunk/src/fr-command-cfile.c
==============================================================================
--- trunk/src/fr-command-cfile.c	(original)
+++ trunk/src/fr-command-cfile.c	Tue Mar 31 17:06:54 2009
@@ -211,7 +211,7 @@
 
 	/* copy file to the temp dir */
 
-	temp_dir = get_temp_work_dir ();
+	temp_dir = get_temp_work_dir (NULL);
 	filename = file_list->data;
 	temp_file = g_strconcat (temp_dir, "/", filename, NULL);
 
@@ -326,7 +326,7 @@
 
 	/* copy file to the temp dir, remove the already existing file first */
 
-	temp_dir = get_temp_work_dir ();
+	temp_dir = get_temp_work_dir (NULL);
 	temp_file = g_strconcat (temp_dir,
 				 "/",
 				 file_name_from_path (comm->filename),

Modified: trunk/src/fr-command-jar.c
==============================================================================
--- trunk/src/fr-command-jar.c	(original)
+++ trunk/src/fr-command-jar.c	Tue Mar 31 17:06:54 2009
@@ -87,7 +87,7 @@
 		g_free (path);
 	}
 
-	tmp_dir = get_temp_work_dir ();
+	tmp_dir = get_temp_work_dir (NULL);
 	for (scan = jardata_list; scan ; scan = scan->next) {
 		JarData *jdata = scan->data;
 		char    *pack_path;

Modified: trunk/src/fr-command-unstuff.c
==============================================================================
--- trunk/src/fr-command-unstuff.c	(original)
+++ trunk/src/fr-command-unstuff.c	Tue Mar 31 17:06:54 2009
@@ -202,7 +202,7 @@
 	fr_process_add_arg (comm->process, "--trace");
 
 	/* Actually unpack everything in a temporary directory */
-	path = get_temp_work_dir ();
+	path = get_temp_work_dir (NULL);
 	path_dots = unstuff_is_shit_with_filenames (path);
 	g_free (path);
 

Modified: trunk/src/fr-command.c
==============================================================================
--- trunk/src/fr-command.c	(original)
+++ trunk/src/fr-command.c	Tue Mar 31 17:06:54 2009
@@ -218,14 +218,21 @@
 	if (process->error.type != FR_PROC_ERROR_NONE)
 		fr_command_handle_error (comm, &process->error);
 
-	if (comm->process->restart)
+	if (comm->process->restart) {
 		fr_process_start (comm->process);
-	else
-		g_signal_emit (G_OBJECT (comm),
-			       fr_command_signals[DONE],
-			       0,
-			       comm->action,
-			       &process->error);
+		return;
+	}
+	
+	if (comm->action == FR_ACTION_LISTING_CONTENT) {
+		/* order the list by name to speed up search */
+		g_ptr_array_sort (comm->files, file_data_compare_by_path);
+	}
+	
+	g_signal_emit (G_OBJECT (comm),
+		       fr_command_signals[DONE],
+		       0,
+		       comm->action,
+		       &process->error);
 }
 
 

Modified: trunk/src/fr-window.c
==============================================================================
--- trunk/src/fr-window.c	(original)
+++ trunk/src/fr-window.c	Tue Mar 31 17:06:54 2009
@@ -1041,17 +1041,6 @@
 }
 
 
-static gint
-sort_by_full_path (gconstpointer  ptr1,
-	           gconstpointer  ptr2)
-{
-	const FileData *fdata1 = *((FileData **) ptr1);
-	const FileData *fdata2 = *((FileData **) ptr2);
-
-	return strcmp (fdata1->full_path, fdata2->full_path);
-}
-
-
 static guint64
 get_dir_size (FrWindow   *window,
 	      const char *current_dir,
@@ -1096,34 +1085,35 @@
 }
 
 
-static void
+static gboolean
 compute_file_list_name (FrWindow   *window,
 			FileData   *fdata,
 			const char *current_dir,
 			int         current_dir_len,
-			GHashTable *names_hash)
+			GHashTable *names_hash,
+			gboolean   *different_name)
 {
 	register char *scan, *end;
 
-	g_free (fdata->list_name);
-	fdata->list_name = NULL;
-	fdata->list_dir = FALSE;
+	*different_name = FALSE;
 
 	if (! file_data_respects_filter (window, fdata))
-		return;
+		return FALSE;
 
 	if (window->priv->list_mode == FR_WINDOW_LIST_MODE_FLAT) {
 		fdata->list_name = g_strdup (fdata->name);
 		if (fdata->dir)
 			fdata->dir_size = 0;
-		return;
+		return FALSE;
 	}
 
-	if (strncmp (fdata->full_path, current_dir, current_dir_len) != 0)
-		return;
+	if (strncmp (fdata->full_path, current_dir, current_dir_len) != 0) {
+		*different_name = TRUE;
+		return FALSE;
+	}
 
 	if (strlen (fdata->full_path) == current_dir_len)
-		return;
+		return FALSE;
 
 	scan = fdata->full_path + current_dir_len;
 	end = strchr (scan, '/');
@@ -1141,7 +1131,7 @@
 		/* avoid to insert duplicated folders */
 		if (g_hash_table_lookup (names_hash, dir_name) != NULL) {
 			g_free (dir_name);
-			return;
+			return FALSE;
 		}
 		g_hash_table_insert (names_hash, dir_name, GINT_TO_POINTER (1));
 
@@ -1150,6 +1140,8 @@
 		fdata->list_name = dir_name;
 		fdata->dir_size = get_dir_size (window, current_dir, dir_name);
 	}
+	
+	return TRUE;
 }
 
 
@@ -1161,6 +1153,9 @@
 	int         current_dir_len;
 	GHashTable *names_hash;
 	int         i;
+	gboolean    visible_list_started = FALSE;
+	gboolean    visible_list_completed = FALSE;
+	gboolean    different_name;
 
 	current_dir = fr_window_get_current_location (window);
 	current_dir_len = strlen (current_dir);
@@ -1168,7 +1163,24 @@
 
 	for (i = 0; i < files->len; i++) {
 		FileData *fdata = g_ptr_array_index (files, i);
-		compute_file_list_name (window, fdata, current_dir, current_dir_len, names_hash);
+
+		g_free (fdata->list_name);
+		fdata->list_name = NULL;
+		fdata->list_dir = FALSE;
+		
+		/* the files array is sorted by path, when the visible list
+		 * is started and we find a path that doesn't match the 
+		 * current_dir path, the following files can't match 
+		 * the current_dir path. */
+		
+		if (visible_list_completed)
+			continue;
+		
+		if (compute_file_list_name (window, fdata, current_dir, current_dir_len, names_hash, &different_name)) {
+			visible_list_started = TRUE;
+		}
+		else if (visible_list_started && different_name) 
+			visible_list_completed = TRUE;
 	}
 
 	g_hash_table_destroy (names_hash);
@@ -1925,7 +1937,6 @@
 		}
 		g_free (current_dir);
 
-		g_ptr_array_sort (window->archive->command->files, sort_by_full_path);
 		fr_window_compute_list_names (window, window->archive->command->files);
 		files = fr_window_get_current_dir_list (window);
 		free_files = TRUE;
@@ -6182,7 +6193,7 @@
 			  window);
 
 	window->priv->convert_data.converting = TRUE;
-	window->priv->convert_data.temp_dir = get_temp_work_dir ();
+	window->priv->convert_data.temp_dir = get_temp_work_dir (NULL);
 
 	fr_process_clear (window->archive->process);
 	fr_archive_extract_to_local (window->archive,
@@ -7074,7 +7085,7 @@
 
 	fr_process_clear (archive->process);
 
-	tmp_dir = get_temp_work_dir ();
+	tmp_dir = get_temp_work_dir (NULL);
 
 	if (is_dir)
 		file_list = get_dir_list_from_path (window, rdata->path_to_rename);
@@ -7638,7 +7649,7 @@
 
 	current_dir_relative = data->current_dir + 1;
 
-	data->tmp_dir = get_temp_work_dir ();
+	data->tmp_dir = get_temp_work_dir (NULL);
 	created_dirs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 	for (scan = data->files; scan; scan = scan->next) {
 		const char *old_name = (char*) scan->data;
@@ -7838,7 +7849,7 @@
 	odata->file_list = path_list_dup (file_list);
 	odata->ask_application = ask_application;
 	odata->cdata = g_new0 (CommandData, 1);
-	odata->cdata->temp_dir = get_temp_work_dir ();
+	odata->cdata->temp_dir = get_temp_work_dir (NULL);
 	odata->cdata->file_list = NULL;
 	for (scan = file_list; scan; scan = scan->next) {
 		char *file = scan->data;

Modified: trunk/src/glib-utils.c
==============================================================================
--- trunk/src/glib-utils.c	(original)
+++ trunk/src/glib-utils.c	Tue Mar 31 17:06:54 2009
@@ -583,6 +583,30 @@
 }
 
 
+int
+g_ptr_array_binary_search (GPtrArray    *array,
+			   gpointer      value,
+			   GCompareFunc  func)
+{
+	int l, r, p, cmp = -1;
+		
+	l = 0;
+	r = array->len;
+	while (l < r) {
+		p = l + ((r - l) / 2);
+		cmp = func(value, &g_ptr_array_index (array, p));
+		if (cmp == 0)
+			return p; 
+		else if (cmp < 0)
+			r = p;
+		else 
+			l = p + 1;
+	}
+	
+	return -1;
+}
+
+
 GHashTable *static_strings = NULL;
 
 

Modified: trunk/src/glib-utils.h
==============================================================================
--- trunk/src/glib-utils.h	(original)
+++ trunk/src/glib-utils.h	Tue Mar 31 17:06:54 2009
@@ -64,6 +64,9 @@
                        				  GFunc        func,
                        				  gpointer     user_data);
 void                g_ptr_array_reverse          (GPtrArray   *array);
+int                 g_ptr_array_binary_search    (GPtrArray   *array,
+						  gpointer     value,
+						  GCompareFunc func);
 const char *        get_static_string            (const char  *s);
 char*               g_uri_display_basename       (const char  *uri);
 



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