[evolution-data-server/gnome-3-4] Bug 676403 - imapx: Syncing folder after server-side deletion of many messages is *very* slow
- From: David Woodhouse <dwmw2 src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/gnome-3-4] Bug 676403 - imapx: Syncing folder after server-side deletion of many messages is *very* slow
- Date: Mon, 21 May 2012 12:24:08 +0000 (UTC)
commit 5186c995c06fb3398688de3518d899dc149f73b8
Author: David Woodhouse <David Woodhouse intel com>
Date: Sun May 20 00:40:53 2012 +0100
Bug 676403 - imapx: Syncing folder after server-side deletion of many messages is *very* slow
Fix this by introducing a new camel_folder_change_info_remove_uids()
function, and using it for the 'vanished' code. This reduces the time taken
from about 40ms per message, to about 50Âs.
(cherry picked from commit 23a77e1d521c34e04121395ffe5df9a567c22e77)
camel/camel-folder-summary.c | 48 ++++++++++++++++++++++++++++
camel/camel-folder-summary.h | 2 +
camel/providers/imapx/camel-imapx-server.c | 24 +++++++++++++-
3 files changed, 72 insertions(+), 2 deletions(-)
---
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index 43c7c98..8dad22c 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -3232,6 +3232,54 @@ camel_folder_summary_remove_uid (CamelFolderSummary *summary,
return res;
}
+/**
+ * camel_folder_summary_remove_uids:
+ * @summary: a #CamelFolderSummary object
+ * @uids: a GList of uids
+ *
+ * Remove a specific info record from the summary, by @uid.
+ *
+ * Returns: Whether the @uid was found and removed from the @summary.
+ *
+ * Since: 3.4.3
+ **/
+gboolean
+camel_folder_summary_remove_uids (CamelFolderSummary *summary,
+ GList *uids)
+{
+ CamelStore *parent_store;
+ const gchar *full_name;
+ GList *l;
+ gboolean res = TRUE;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), FALSE);
+ g_return_val_if_fail (uids != NULL, FALSE);
+
+ camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+ for (l = g_list_first(uids); l; l = g_list_next(l)) {
+ gpointer ptr_uid = NULL, ptr_flags = NULL;
+ if (g_hash_table_lookup_extended (summary->priv->uids, l->data, &ptr_uid, &ptr_flags)) {
+ const gchar *uid_copy = camel_pstring_strdup (l->data);
+ folder_summary_update_counts_by_flags (summary, GPOINTER_TO_UINT (ptr_flags), TRUE);
+ g_hash_table_remove (summary->priv->uids, uid_copy);
+ g_hash_table_remove (summary->priv->loaded_infos, uid_copy);
+ camel_pstring_free (uid_copy);
+ }
+ }
+
+ full_name = camel_folder_get_full_name (summary->priv->folder);
+ parent_store = camel_folder_get_parent_store (summary->priv->folder);
+ if (camel_db_delete_uids (parent_store->cdb_w, full_name, uids, NULL) != 0)
+ res = FALSE;
+
+ camel_folder_summary_touch (summary);
+ camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+ return res;
+}
+
+
static struct _node *
my_list_append (struct _node **list,
struct _node *n)
diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h
index cb66520..dacacab 100644
--- a/camel/camel-folder-summary.h
+++ b/camel/camel-folder-summary.h
@@ -402,6 +402,8 @@ gboolean camel_folder_summary_remove (CamelFolderSummary *summary,
gboolean camel_folder_summary_remove_uid (CamelFolderSummary *summary,
const gchar *uid);
+gboolean camel_folder_summary_remove_uids(CamelFolderSummary *summary,
+ GList *uids);
/* remove all items */
gboolean camel_folder_summary_clear (CamelFolderSummary *summary,
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index fc5de5d..345a63e 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -1138,6 +1138,7 @@ imapx_untagged (CamelIMAPXServer *is,
}
case IMAPX_VANISHED: {
GPtrArray *uids;
+ GList *uid_list = NULL;
gboolean unsolicited = TRUE;
gint i;
guint len;
@@ -1161,11 +1162,30 @@ imapx_untagged (CamelIMAPXServer *is,
uids = imapx_parse_uids (is->stream, cancellable, error);
if (uids == NULL)
return FALSE;
+
+ if (unsolicited) {
+ CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *)is->select_folder;
+
+ if (ifolder->exists_on_server < uids->len) {
+ c(is->tagprefix, "Error: exists_on_folder %d is fewer than vanished %d\n",
+ ifolder->exists_on_server, uids->len);
+ ifolder->exists_on_server = 0;
+ } else
+ ifolder->exists_on_server -= uids->len;
+ }
+ if (is->changes == NULL)
+ is->changes = camel_folder_change_info_new ();
+
for (i = 0; i < uids->len; i++) {
gchar *uid = g_strdup_printf("%u", GPOINTER_TO_UINT(g_ptr_array_index (uids, i)));
+
c(is->tagprefix, "vanished: %s\n", uid);
- imapx_expunge_uid_from_summary (is, uid, unsolicited);
+
+ uid_list = g_list_append(uid_list, uid);
+ camel_folder_change_info_remove_uid (is->changes, uid);
}
+ camel_folder_summary_remove_uids(is->select_folder->summary, uid_list);
+ is->expunged = g_list_concat(is->expunged, uid_list);
g_ptr_array_free (uids, FALSE);
break;
}
@@ -3935,10 +3955,10 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
gchar *uid = (gchar *) l->data;
camel_folder_change_info_remove_uid (data->changes, uid);
- camel_folder_summary_remove_uid (s, uid);
}
if (removed != NULL) {
+ camel_folder_summary_remove_uids (s, removed);
camel_folder_summary_touch (s);
g_list_free_full (removed, (GDestroyNotify) g_free);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]