[evolution-data-server] Bug 785212 - Quit with a large vFolder causes load of each message info
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug 785212 - Quit with a large vFolder causes load of each message info
- Date: Mon, 24 Jul 2017 17:27:45 +0000 (UTC)
commit 666be62ac02049116dc9169b2d2d9fdca221ee42
Author: Milan Crha <mcrha redhat com>
Date: Mon Jul 24 19:26:18 2017 +0200
Bug 785212 - Quit with a large vFolder causes load of each message info
src/camel/camel-folder-summary.c | 26 ++++++++++++++++++++++
src/camel/camel-folder-summary.h | 5 +++-
src/camel/camel-vee-folder.c | 5 ++++
src/camel/camel-vee-message-info.c | 41 +++++++++++++++++++++++++++++++++++-
src/camel/camel-vee-store.c | 14 ++++++++---
src/camel/camel-vee-summary.c | 31 +++++++++++++++++++++++++++
6 files changed, 116 insertions(+), 6 deletions(-)
---
diff --git a/src/camel/camel-folder-summary.c b/src/camel/camel-folder-summary.c
index 4286bda..3194538 100644
--- a/src/camel/camel-folder-summary.c
+++ b/src/camel/camel-folder-summary.c
@@ -143,6 +143,13 @@ enum {
PROP_VISIBLE_COUNT
};
+enum {
+ PREPARE_FETCH_ALL,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
G_DEFINE_TYPE (CamelFolderSummary, camel_folder_summary, G_TYPE_OBJECT)
/* Private function */
@@ -737,6 +744,23 @@ camel_folder_summary_class_init (CamelFolderSummaryClass *class)
"How many visible (not deleted and not junk) infos is saved in a summary",
0, G_MAXUINT32,
0, G_PARAM_READABLE));
+
+ /**
+ * CamelFolderSummary::prepare-fetch-all
+ * @summary: the #CamelFolderSummary which emitted the signal
+ *
+ * Emitted on call to camel_folder_summary_prepare_fetch_all().
+ *
+ * Since: 3.26
+ **/
+ signals[PREPARE_FETCH_ALL] = g_signal_new (
+ "changed",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CamelFolderSummaryClass, prepare_fetch_all),
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0,
+ G_TYPE_NONE);
}
static void
@@ -1743,6 +1767,8 @@ camel_folder_summary_prepare_fetch_all (CamelFolderSummary *summary,
loaded = cfs_cache_size (summary);
known = camel_folder_summary_count (summary);
+ g_signal_emit (summary, signals[PREPARE_FETCH_ALL], 0);
+
if (known - loaded > 50) {
camel_folder_summary_lock (summary);
cfs_reload_from_db (summary, error);
diff --git a/src/camel/camel-folder-summary.h b/src/camel/camel-folder-summary.h
index 8fb53bb..bb0cea7 100644
--- a/src/camel/camel-folder-summary.h
+++ b/src/camel/camel-folder-summary.h
@@ -120,8 +120,11 @@ struct _CamelFolderSummaryClass {
gchar * (*next_uid_string)
(CamelFolderSummary *summary);
+ void (* prepare_fetch_all)
+ (CamelFolderSummary *summary);
+
/* Padding for future expansion */
- gpointer reserved[20];
+ gpointer reserved[19];
};
GType camel_folder_summary_get_type (void);
diff --git a/src/camel/camel-vee-folder.c b/src/camel/camel-vee-folder.c
index 2555b14..47c8ca2 100644
--- a/src/camel/camel-vee-folder.c
+++ b/src/camel/camel-vee-folder.c
@@ -39,6 +39,8 @@
#define d(x)
#define dd(x) (camel_debug ("vfolder")?(x):0)
+extern gint camel_application_is_exiting;
+
typedef struct _FolderChangedData FolderChangedData;
#define CAMEL_VEE_FOLDER_GET_PRIVATE(obj) \
@@ -1092,6 +1094,9 @@ vee_folder_remove_folder (CamelVeeFolder *vfolder,
CamelFolder *v_folder;
GHashTable *uids;
+ if (camel_application_is_exiting)
+ return;
+
v_folder = CAMEL_FOLDER (vfolder);
changes = camel_folder_change_info_new ();
diff --git a/src/camel/camel-vee-message-info.c b/src/camel/camel-vee-message-info.c
index 4ec2aea..d932cfa 100644
--- a/src/camel/camel-vee-message-info.c
+++ b/src/camel/camel-vee-message-info.c
@@ -136,10 +136,49 @@ vee_message_info_notify_mi_changed (CamelFolder *folder,
return result; \
} G_STMT_END
+static gboolean
+vee_message_info_read_flags_from_orig_summary (const CamelMessageInfo *mi,
+ guint32 *out_flags)
+{
+ CamelVeeMessageInfo *vmi;
+ const gchar *uid;
+
+ g_return_val_if_fail (CAMEL_IS_VEE_MESSAGE_INFO (mi), FALSE);
+ g_return_val_if_fail (out_flags != NULL, FALSE);
+
+ vmi = CAMEL_VEE_MESSAGE_INFO (mi);
+ g_return_val_if_fail (vmi->priv->orig_summary != NULL, FALSE);
+
+ uid = camel_message_info_pooldup_uid (mi);
+ g_return_val_if_fail (uid != NULL, FALSE);
+
+ if (!uid[0] || !uid[1] || !uid[2] || !uid[3] || !uid[4] ||
+ !uid[5] || !uid[6] || !uid[7] || !uid[8]) {
+ camel_pstring_free (uid);
+ g_warn_if_reached ();
+ return FALSE;
+ }
+
+ /* Flags can be read from summary, without a need to load the message info and
+ it is also required when adding to the summary, thus this should help when
+ populating summary of any vFolder. */
+ *out_flags = camel_folder_summary_get_info_flags (vmi->priv->orig_summary, uid + 8);
+
+ camel_pstring_free (uid);
+
+ return *out_flags != (~0);
+}
+
static guint32
vee_message_info_get_flags (const CamelMessageInfo *mi)
{
- vee_call_from_parent_mi (0, guint32, camel_message_info_get_flags, (orig_mi), FALSE);
+ guint32 flags = 0;
+
+ if (vee_message_info_read_flags_from_orig_summary (mi, &flags)) {
+ return flags;
+ } else {
+ vee_call_from_parent_mi (0, guint32, camel_message_info_get_flags, (orig_mi), FALSE);
+ }
}
static gboolean
diff --git a/src/camel/camel-vee-store.c b/src/camel/camel-vee-store.c
index 2b72e86..3b47ce8 100644
--- a/src/camel/camel-vee-store.c
+++ b/src/camel/camel-vee-store.c
@@ -47,6 +47,8 @@
#define CHANGE_DELETE (1)
#define CHANGE_NOSELECT (2)
+extern gint camel_application_is_exiting;
+
/* The custom property ID is a CamelArg artifact.
* It still identifies the property in state files. */
enum {
@@ -711,7 +713,8 @@ camel_vee_store_note_subfolder_used (CamelVeeStore *vstore,
/* only real folders can be part of the unmatched folder */
if (CAMEL_IS_VEE_FOLDER (subfolder) ||
- used_by == vstore->priv->unmatched_folder)
+ used_by == vstore->priv->unmatched_folder ||
+ camel_application_is_exiting)
return;
g_mutex_lock (&vstore->priv->sf_counts_mutex);
@@ -795,7 +798,8 @@ camel_vee_store_note_subfolder_unused (CamelVeeStore *vstore,
/* only real folders can be part of the unmatched folder */
if (CAMEL_IS_VEE_FOLDER (subfolder) ||
- unused_by == vstore->priv->unmatched_folder)
+ unused_by == vstore->priv->unmatched_folder ||
+ camel_application_is_exiting)
return;
g_mutex_lock (&vstore->priv->sf_counts_mutex);
@@ -850,7 +854,8 @@ camel_vee_store_note_vuid_used (CamelVeeStore *vstore,
g_return_if_fail (mi_data != NULL);
/* these notifications are ignored from Unmatched folder */
- if (used_by == vstore->priv->unmatched_folder)
+ if (used_by == vstore->priv->unmatched_folder ||
+ camel_application_is_exiting)
return;
/* unmatched folder holds only real folders */
@@ -912,7 +917,8 @@ camel_vee_store_note_vuid_unused (CamelVeeStore *vstore,
g_return_if_fail (mi_data != NULL);
/* these notifications are ignored from Unmatched folder */
- if (unused_by == vstore->priv->unmatched_folder)
+ if (unused_by == vstore->priv->unmatched_folder ||
+ camel_application_is_exiting)
return;
/* unmatched folder holds only real folders */
diff --git a/src/camel/camel-vee-summary.c b/src/camel/camel-vee-summary.c
index 2b51c26..e89ee48 100644
--- a/src/camel/camel-vee-summary.c
+++ b/src/camel/camel-vee-summary.c
@@ -88,6 +88,36 @@ message_info_from_uid (CamelFolderSummary *s,
}
static void
+vee_summary_prepare_fetch_all (CamelFolderSummary *summary)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+ CamelVeeSummary *vee_summary;
+
+ g_return_if_fail (CAMEL_IS_VEE_SUMMARY (summary));
+
+ camel_folder_summary_lock (summary);
+
+ vee_summary = CAMEL_VEE_SUMMARY (summary);
+
+ g_hash_table_iter_init (&iter, vee_summary->priv->vuids_by_subfolder);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ CamelFolder *subfolder = key;
+ GHashTable *vuids = value;
+
+ if (subfolder && vuids && g_hash_table_size (vuids) > 50) {
+ CamelFolderSummary *subsummary;
+
+ subsummary = camel_folder_get_folder_summary (subfolder);
+ if (subsummary)
+ camel_folder_summary_prepare_fetch_all (subsummary, NULL);
+ }
+ }
+
+ camel_folder_summary_unlock (summary);
+}
+
+static void
vee_summary_finalize (GObject *object)
{
CamelVeeSummaryPrivate *priv;
@@ -114,6 +144,7 @@ camel_vee_summary_class_init (CamelVeeSummaryClass *class)
folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (class);
folder_summary_class->message_info_type = CAMEL_TYPE_VEE_MESSAGE_INFO;
folder_summary_class->message_info_from_uid = message_info_from_uid;
+ folder_summary_class->prepare_fetch_all = vee_summary_prepare_fetch_all;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]