[evolution-ews] Bug #655806 - Folder deletion is very slow
- From: Fabiano Fidêncio <ffidencio src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews] Bug #655806 - Folder deletion is very slow
- Date: Mon, 10 Feb 2014 19:22:02 +0000 (UTC)
commit 0e01d38c071c81c3d8f2ef0f3698b58d2dfd9b76
Author: Fabiano Fidêncio <fidencio redhat com>
Date: Mon Feb 3 18:13:55 2014 +0100
Bug #655806 - Folder deletion is very slow
src/camel/camel-ews-store.c | 141 +++++++++++++++++++++++++++++++++++++++----
1 files changed, 129 insertions(+), 12 deletions(-)
---
diff --git a/src/camel/camel-ews-store.c b/src/camel/camel-ews-store.c
index 8f34b3b..6979b76 100644
--- a/src/camel/camel-ews-store.c
+++ b/src/camel/camel-ews-store.c
@@ -282,6 +282,8 @@ ews_store_initable_init (GInitable *initable,
store->flags |= CAMEL_STORE_USE_CACHE_DIR;
ews_migrate_to_user_cache_dir (service);
+ store->flags |= CAMEL_STORE_CAN_DELETE_FOLDERS_AT_ONCE;
+
/* Chain up to parent interface's init() method. */
if (!parent_initable_interface->init (initable, cancellable, error))
return FALSE;
@@ -2561,21 +2563,86 @@ ews_create_folder_sync (CamelStore *store,
}
static gboolean
+ews_update_store_delete_recursive (CamelEwsStore *ews_store,
+ CamelFolderInfo *folder_info,
+ GError **error)
+{
+ gboolean success = TRUE;
+
+ while (folder_info != NULL) {
+ gchar *fid;
+
+ if (folder_info->child != NULL) {
+ success = ews_update_store_delete_recursive (ews_store, folder_info->child, error);
+
+ if (!success)
+ break;
+ }
+
+ fid = camel_ews_store_summary_get_folder_id_from_name (ews_store->summary,
folder_info->full_name);
+ success = camel_ews_store_summary_remove_folder (ews_store->summary, fid, error);
+ g_free (fid);
+
+ if (!success)
+ break;
+
+ folder_info = folder_info->next;
+ }
+
+ return success;
+}
+
+static void
+ews_update_store_move_recursive (CamelEwsStore *ews_store,
+ CamelFolderInfo *folder_info)
+{
+ while (folder_info != NULL) {
+ if (folder_info->child != NULL)
+ ews_update_store_move_recursive (ews_store, folder_info->child);
+
+ camel_store_folder_created (CAMEL_STORE (ews_store), folder_info);
+ camel_subscribable_folder_subscribed (CAMEL_SUBSCRIBABLE (ews_store), folder_info);
+
+ folder_info = folder_info->next;
+ }
+}
+
+static gboolean
ews_delete_folder_sync (CamelStore *store,
const gchar *folder_name,
GCancellable *cancellable,
GError **error)
{
CamelEwsStore *ews_store = CAMEL_EWS_STORE (store);
- CamelEwsStoreSummary *ews_summary = ews_store->summary;
gchar *fid;
- CamelFolderInfo *fi = NULL;
+ gchar *trash_fid;
+ gchar *trash_name;
+ CamelFolderInfo *folder_info;
+ CamelFolderInfo *to_update;
gboolean success;
+ gboolean is_under_trash_folder;
GError *local_error = NULL;
+ folder_info = camel_store_get_folder_info_sync (
+ store, folder_name,
+ CAMEL_STORE_FOLDER_INFO_RECURSIVE |
+ CAMEL_STORE_FOLDER_INFO_SUBSCRIBED,
+ cancellable, &local_error);
+
+ if (folder_info == NULL) {
+ g_propagate_error (error, local_error);
+
+ return FALSE;
+ }
+
+ to_update = folder_info;
+
fid = camel_ews_store_summary_get_folder_id_from_name (
- ews_summary, folder_name);
+ ews_store->summary, folder_name);
+
if (!fid) {
+ camel_folder_info_free (folder_info);
+
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
_("Folder does not exist"));
@@ -2584,6 +2651,7 @@ ews_delete_folder_sync (CamelStore *store,
if (g_str_equal (fid, EWS_FOREIGN_FOLDER_ROOT_ID)) {
g_free (fid);
+ camel_folder_info_free (folder_info);
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
@@ -2594,6 +2662,7 @@ ews_delete_folder_sync (CamelStore *store,
if (g_str_equal (fid, EWS_PUBLIC_FOLDER_ROOT_ID)) {
g_free (fid);
+ camel_folder_info_free (folder_info);
g_set_error (
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
@@ -2602,8 +2671,28 @@ ews_delete_folder_sync (CamelStore *store,
return FALSE;
}
- if (!camel_ews_store_connected (ews_store, cancellable, error)) {
+ trash_fid = camel_ews_store_summary_get_folder_id_from_folder_type (ews_store->summary,
CAMEL_FOLDER_TYPE_TRASH);
+ trash_name = camel_ews_store_summary_get_folder_full_name (ews_store->summary, trash_fid,
&local_error);
+ if (!trash_name) {
+ g_free (trash_fid);
+ g_free (fid);
+ camel_folder_info_free (folder_info);
+
+ g_propagate_error (error, local_error);
+ return FALSE;
+ }
+
+ is_under_trash_folder = g_str_has_prefix (folder_name, trash_name);
+
+ g_free (trash_name);
+
+ if (!camel_ews_store_connected (ews_store, cancellable, &local_error)) {
+ g_free (trash_fid);
g_free (fid);
+ camel_folder_info_free (folder_info);
+
+ g_propagate_error (error, local_error);
+
return FALSE;
}
@@ -2620,31 +2709,59 @@ ews_delete_folder_sync (CamelStore *store,
success = e_ews_connection_delete_folder_sync (
connection,
EWS_PRIORITY_MEDIUM,
- fid, FALSE, "HardDelete",
+ fid, FALSE, is_under_trash_folder ? "HardDelete" : "MoveToDeletedItems",
cancellable, &local_error);
g_object_unref (connection);
}
if (!success) {
+ g_free (trash_fid);
+ g_free (fid);
+ camel_folder_info_free (folder_info);
+
camel_ews_store_maybe_disconnect (ews_store, local_error);
g_propagate_error (error, local_error);
- g_free (fid);
+
return FALSE;
}
- fi = camel_ews_utils_build_folder_info (ews_store, fid);
- camel_ews_store_summary_remove_folder (ews_summary, fid, error);
+ if (is_under_trash_folder) {
+ success = ews_update_store_delete_recursive (ews_store, to_update, &local_error);
- camel_subscribable_folder_unsubscribed (CAMEL_SUBSCRIBABLE (ews_store), fi);
- camel_store_folder_deleted (store, fi);
- camel_folder_info_free (fi);
+ if (!success) {
+ g_free (trash_fid);
+ g_free (fid);
+ camel_folder_info_free (folder_info);
- g_free (fid);
+ g_propagate_error (error, local_error);
+ return FALSE;
+ }
+ } else {
+ camel_ews_store_summary_set_parent_folder_id (ews_store->summary, fid, trash_fid);
+ }
+
+ camel_subscribable_folder_unsubscribed (CAMEL_SUBSCRIBABLE (ews_store), folder_info);
+ camel_store_folder_deleted (CAMEL_STORE (ews_store), folder_info);
+
+ camel_folder_info_free (folder_info);
+
+ if (!is_under_trash_folder) {
+ camel_ews_store_summary_rebuild_hashes (ews_store->summary);
+
+ folder_info = camel_ews_utils_build_folder_info (ews_store, fid);
+
+ to_update = folder_info;
+ ews_update_store_move_recursive (ews_store, to_update);
+ camel_folder_info_free (folder_info);
+ }
camel_ews_store_ensure_virtual_folders (ews_store);
camel_ews_store_summary_save (ews_store->summary, NULL);
+ g_free (trash_fid);
+ g_free (fid);
+
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]