summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRazvan Chitu <razvan.ch95@gmail.com>2016-05-05 15:33:20 +0300
committerCarlos Soriano <csoriano@gnome.org>2016-07-28 14:46:42 +0200
commita49d600b5a2c2bc6a8e330f4876df48e53cf6556 (patch)
treeb69004967b53dc7a114051593f2183fe198a8ad5
parent26a3ab4cd56c557df64993b604c6d3e53606a875 (diff)
downloadnautilus-a49d600b5a2c2bc6a8e330f4876df48e53cf6556.tar.gz
file-undo-operations: use queue for storing sources and destinations
When copying, moving or linking files, original sources and their destinations are stored in an information structure used for undoing the operation. The sources and destinations were appended at the end of a list. Due to append taking linear time, these file operations would have a resulting quadratic complexity depending on the number of files. When operating on thousands of files, this would lead to a significant decrease in speed. In order to fix this, the sources and destinations are stored in a queue that allows appending in constant time. https://bugzilla.gnome.org/show_bug.cgi?id=757747
-rw-r--r--libnautilus-private/nautilus-file-undo-operations.c69
1 files changed, 43 insertions, 26 deletions
diff --git a/libnautilus-private/nautilus-file-undo-operations.c b/libnautilus-private/nautilus-file-undo-operations.c
index 9e96b35ed..01f27f343 100644
--- a/libnautilus-private/nautilus-file-undo-operations.c
+++ b/libnautilus-private/nautilus-file-undo-operations.c
@@ -322,8 +322,8 @@ G_DEFINE_TYPE (NautilusFileUndoInfoExt, nautilus_file_undo_info_ext, NAUTILUS_TY
struct _NautilusFileUndoInfoExtDetails {
GFile *src_dir;
GFile *dest_dir;
- GList *sources; /* Relative to src_dir */
- GList *destinations; /* Relative to dest_dir */
+ GQueue *sources; /* Relative to src_dir */
+ GQueue *destinations; /* Relative to dest_dir */
};
static char *
@@ -332,7 +332,7 @@ ext_get_first_target_short_name (NautilusFileUndoInfoExt *self)
GList *targets_first;
char *file_name = NULL;
- targets_first = g_list_first (self->priv->destinations);
+ targets_first = g_queue_peek_head_link (self->priv->destinations);
if (targets_first != NULL &&
targets_first->data != NULL) {
@@ -471,35 +471,47 @@ static void
ext_create_link_redo_func (NautilusFileUndoInfoExt *self,
GtkWindow *parent_window)
{
- nautilus_file_operations_link (self->priv->sources, NULL,
- self->priv->dest_dir, parent_window,
- file_undo_info_transfer_callback, self);
+ nautilus_file_operations_link (g_queue_peek_head_link (self->priv->sources),
+ NULL,
+ self->priv->dest_dir,
+ parent_window,
+ file_undo_info_transfer_callback,
+ self);
}
static void
ext_duplicate_redo_func (NautilusFileUndoInfoExt *self,
GtkWindow *parent_window)
{
- nautilus_file_operations_duplicate (self->priv->sources, NULL, parent_window,
- file_undo_info_transfer_callback, self);
+ nautilus_file_operations_duplicate (g_queue_peek_head_link (self->priv->sources),
+ NULL,
+ parent_window,
+ file_undo_info_transfer_callback,
+ self);
}
static void
ext_copy_redo_func (NautilusFileUndoInfoExt *self,
GtkWindow *parent_window)
{
- nautilus_file_operations_copy (self->priv->sources, NULL,
- self->priv->dest_dir, parent_window,
- file_undo_info_transfer_callback, self);
+ nautilus_file_operations_copy (g_queue_peek_head_link (self->priv->sources),
+ NULL,
+ self->priv->dest_dir,
+ parent_window,
+ file_undo_info_transfer_callback,
+ self);
}
static void
ext_move_restore_redo_func (NautilusFileUndoInfoExt *self,
GtkWindow *parent_window)
{
- nautilus_file_operations_move (self->priv->sources, NULL,
- self->priv->dest_dir, parent_window,
- file_undo_info_transfer_callback, self);
+ nautilus_file_operations_move (g_queue_peek_head_link (self->priv->sources),
+ NULL,
+ self->priv->dest_dir,
+ parent_window,
+ file_undo_info_transfer_callback,
+ self);
}
static void
@@ -527,8 +539,10 @@ static void
ext_restore_undo_func (NautilusFileUndoInfoExt *self,
GtkWindow *parent_window)
{
- nautilus_file_operations_trash_or_delete (self->priv->destinations, parent_window,
- file_undo_info_delete_callback, self);
+ nautilus_file_operations_trash_or_delete (g_queue_peek_head_link (self->priv->destinations),
+ parent_window,
+ file_undo_info_delete_callback,
+ self);
}
@@ -536,9 +550,12 @@ static void
ext_move_undo_func (NautilusFileUndoInfoExt *self,
GtkWindow *parent_window)
{
- nautilus_file_operations_move (self->priv->destinations, NULL,
- self->priv->src_dir, parent_window,
- file_undo_info_transfer_callback, self);
+ nautilus_file_operations_move (g_queue_peek_head_link (self->priv->destinations),
+ NULL,
+ self->priv->src_dir,
+ parent_window,
+ file_undo_info_transfer_callback,
+ self);
}
static void
@@ -547,7 +564,7 @@ ext_copy_duplicate_undo_func (NautilusFileUndoInfoExt *self,
{
GList *files;
- files = g_list_copy (self->priv->destinations);
+ files = g_list_copy (g_queue_peek_head_link (self->priv->destinations));
files = g_list_reverse (files); /* Deleting must be done in reverse */
nautilus_file_operations_delete (files, parent_window,
@@ -589,11 +606,11 @@ nautilus_file_undo_info_ext_finalize (GObject *obj)
NautilusFileUndoInfoExt *self = NAUTILUS_FILE_UNDO_INFO_EXT (obj);
if (self->priv->sources) {
- g_list_free_full (self->priv->sources, g_object_unref);
+ g_queue_free_full (self->priv->sources, g_object_unref);
}
if (self->priv->destinations) {
- g_list_free_full (self->priv->destinations, g_object_unref);
+ g_queue_free_full (self->priv->destinations, g_object_unref);
}
g_clear_object (&self->priv->src_dir);
@@ -632,6 +649,8 @@ nautilus_file_undo_info_ext_new (NautilusFileUndoOp op_type,
retval->priv->src_dir = g_object_ref (src_dir);
retval->priv->dest_dir = g_object_ref (target_dir);
+ retval->priv->sources = g_queue_new ();
+ retval->priv->destinations = g_queue_new ();
return NAUTILUS_FILE_UNDO_INFO (retval);
}
@@ -641,10 +660,8 @@ nautilus_file_undo_info_ext_add_origin_target_pair (NautilusFileUndoInfoExt *sel
GFile *origin,
GFile *target)
{
- self->priv->sources =
- g_list_append (self->priv->sources, g_object_ref (origin));
- self->priv->destinations =
- g_list_append (self->priv->destinations, g_object_ref (target));
+ g_queue_push_tail (self->priv->sources, g_object_ref (origin));
+ g_queue_push_tail (self->priv->destinations, g_object_ref (target));
}
/* create new file/folder */