[evolution-data-server/evolution-data-server-3-12] [IMAPx] Do not open each folder on LIST/LSUB responses



commit ef1357e239a696f620720e21a8ddd81d91924690
Author: Milan Crha <mcrha redhat com>
Date:   Thu Apr 10 09:34:36 2014 +0200

    [IMAPx] Do not open each folder on LIST/LSUB responses
    
    It has sever performance issues, especially with large folders,
    which load (part of) the folder summary into memory too.

 camel/providers/imapx/camel-imapx-conn-manager.c |   27 ++++++++++++++++++
 camel/providers/imapx/camel-imapx-conn-manager.h |    4 +++
 camel/providers/imapx/camel-imapx-folder.c       |   18 +++++++++++-
 camel/providers/imapx/camel-imapx-store.c        |   32 +++++++++++----------
 camel/providers/imapx/camel-imapx-store.h        |    4 +++
 5 files changed, 68 insertions(+), 17 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-conn-manager.c 
b/camel/providers/imapx/camel-imapx-conn-manager.c
index aeb64d3..d7d37d2 100644
--- a/camel/providers/imapx/camel-imapx-conn-manager.c
+++ b/camel/providers/imapx/camel-imapx-conn-manager.c
@@ -897,6 +897,33 @@ camel_imapx_conn_manager_update_con_info (CamelIMAPXConnManager *con_man,
        connection_info_unref (cinfo);
 }
 
+CamelIMAPXMailbox *
+camel_imapx_conn_manager_ref_mailbox (CamelIMAPXConnManager *con_man,
+                                     const gchar *mailbox_name)
+{
+       CamelIMAPXMailbox *mailbox = NULL;
+       GList *iter;
+
+       g_return_val_if_fail (CAMEL_IS_IMAPX_CONN_MANAGER (con_man), NULL);
+       g_return_val_if_fail (mailbox_name != NULL, NULL);
+
+       CON_READ_LOCK (con_man);
+
+       for (iter = con_man->priv->connections; iter != NULL; iter = g_list_next (iter)) {
+               ConnectionInfo *candidate = iter->data;
+
+               if (candidate->is) {
+                       mailbox = camel_imapx_server_ref_mailbox (candidate->is, mailbox_name);
+                       if (mailbox)
+                               break;
+               }
+       }
+
+       CON_READ_UNLOCK (con_man);
+
+       return mailbox;
+}
+
 void
 camel_imapx_conn_manager_close_connections (CamelIMAPXConnManager *con_man)
 {
diff --git a/camel/providers/imapx/camel-imapx-conn-manager.h 
b/camel/providers/imapx/camel-imapx-conn-manager.h
index 5ebfd71..43c7894 100644
--- a/camel/providers/imapx/camel-imapx-conn-manager.h
+++ b/camel/providers/imapx/camel-imapx-conn-manager.h
@@ -88,6 +88,10 @@ void         camel_imapx_conn_manager_update_con_info
                                                (CamelIMAPXConnManager *con_man,
                                                 CamelIMAPXServer *server,
                                                 const gchar *folder_name);
+CamelIMAPXMailbox *
+               camel_imapx_conn_manager_ref_mailbox
+                                               (CamelIMAPXConnManager *con_man,
+                                                const gchar *mailbox_name);
 
 G_END_DECLS
 
diff --git a/camel/providers/imapx/camel-imapx-folder.c b/camel/providers/imapx/camel-imapx-folder.c
index e5962f5..6fe1021 100644
--- a/camel/providers/imapx/camel-imapx-folder.c
+++ b/camel/providers/imapx/camel-imapx-folder.c
@@ -1447,11 +1447,20 @@ void
 camel_imapx_folder_set_mailbox (CamelIMAPXFolder *folder,
                                 CamelIMAPXMailbox *mailbox)
 {
+       CamelIMAPXSummary *imapx_summary;
+       guint32 uidvalidity;
+
        g_return_if_fail (CAMEL_IS_IMAPX_FOLDER (folder));
        g_return_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox));
 
        g_weak_ref_set (&folder->priv->mailbox, mailbox);
 
+       imapx_summary = CAMEL_IMAPX_SUMMARY (CAMEL_FOLDER (folder)->summary);
+       uidvalidity = camel_imapx_mailbox_get_uidvalidity (mailbox);
+
+       if (uidvalidity > 0 && uidvalidity != imapx_summary->validity)
+               camel_imapx_folder_invalidate_local_cache (folder, uidvalidity);
+
        g_object_notify (G_OBJECT (folder), "mailbox");
 }
 
@@ -1519,10 +1528,15 @@ camel_imapx_folder_list_mailbox (CamelIMAPXFolder *folder,
 
        camel_store_summary_info_unref (imapx_store->summary, store_info);
 
-       /* See if the CamelIMAPXServer already has the mailbox. */
+       /* See if the CamelIMAPXStore already has the mailbox. */
 
-       server = camel_imapx_store_ref_server (imapx_store, NULL, FALSE, cancellable, error);
+       mailbox = camel_imapx_store_ref_mailbox (imapx_store, mailbox_name);
+       if (mailbox != NULL) {
+               camel_imapx_folder_set_mailbox (folder, mailbox);
+               goto exit;
+       }
 
+       server = camel_imapx_store_ref_server (imapx_store, NULL, FALSE, cancellable, error);
        if (server == NULL)
                goto exit;
 
diff --git a/camel/providers/imapx/camel-imapx-store.c b/camel/providers/imapx/camel-imapx-store.c
index eaf3603..b69ed0f 100644
--- a/camel/providers/imapx/camel-imapx-store.c
+++ b/camel/providers/imapx/camel-imapx-store.c
@@ -529,23 +529,18 @@ imapx_store_process_mailbox_attributes (CamelIMAPXStore *store,
 }
 
 static void
-imapx_store_process_mailbox_status (CamelIMAPXStore *store,
+imapx_store_process_mailbox_status (CamelIMAPXStore *imapx_store,
                                     CamelIMAPXMailbox *mailbox)
 {
-       CamelFolder *folder = NULL;
+       CamelStore *store;
+       CamelFolder *folder;
        gchar *folder_path;
-       GError *local_error = NULL;
 
        folder_path = camel_imapx_mailbox_dup_folder_path (mailbox);
+       store = CAMEL_STORE (imapx_store);
 
-       folder = camel_store_get_folder_sync (
-               CAMEL_STORE (store), folder_path, 0, NULL, &local_error);
-
-       /* Sanity check. */
-       g_return_if_fail (
-               ((folder != NULL) && (local_error == NULL)) ||
-               ((folder == NULL) && (local_error != NULL)));
-
+       /* Update only already opened folders */
+       folder = camel_object_bag_reserve (store->folders, folder_path);
        if (folder != NULL) {
                CamelIMAPXFolder *imapx_folder;
                CamelIMAPXSummary *imapx_summary;
@@ -562,10 +557,7 @@ imapx_store_process_mailbox_status (CamelIMAPXStore *store,
 
                g_object_unref (folder);
        } else {
-               g_warning (
-                       "%s: Failed to get folder '%s': %s",
-                       G_STRFUNC, folder_path, local_error->message);
-               g_error_free (local_error);
+               camel_object_bag_abort (store->folders, folder_path);
        }
 
        g_free (folder_path);
@@ -2535,6 +2527,16 @@ camel_imapx_store_folder_op_done (CamelIMAPXStore *store,
                store->priv->con_man, server, folder_name);
 }
 
+CamelIMAPXMailbox *
+camel_imapx_store_ref_mailbox (CamelIMAPXStore *imapx_store,
+                              const gchar *mailbox_name)
+{
+       g_return_val_if_fail (CAMEL_IS_IMAPX_STORE (imapx_store), NULL);
+       g_return_val_if_fail (mailbox_name != NULL, NULL);
+
+       return camel_imapx_conn_manager_ref_mailbox (imapx_store->priv->con_man, mailbox_name);
+}
+
 CamelFolderQuotaInfo *
 camel_imapx_store_dup_quota_info (CamelIMAPXStore *store,
                                   const gchar *quota_root_name)
diff --git a/camel/providers/imapx/camel-imapx-store.h b/camel/providers/imapx/camel-imapx-store.h
index 0da0b16..8ef34ba 100644
--- a/camel/providers/imapx/camel-imapx-store.h
+++ b/camel/providers/imapx/camel-imapx-store.h
@@ -76,6 +76,10 @@ void         camel_imapx_store_folder_op_done
                                                (CamelIMAPXStore *store,
                                                 CamelIMAPXServer *server,
                                                 const gchar *folder_name);
+CamelIMAPXMailbox *
+               camel_imapx_store_ref_mailbox   (CamelIMAPXStore *imapx_store,
+                                                const gchar *mailbox_name);
+
 CamelFolderQuotaInfo *
                camel_imapx_store_dup_quota_info
                                                (CamelIMAPXStore *store,


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