[evolution-kolab] KolabMailAccess: skip repeated down-sync of recently-synced folders



commit fb9292580e7ba8236cb2f4393e6bf7564cc212eb
Author: Christian Hilberg <hilberg kernelconcepts de>
Date:   Fri Sep 21 17:04:47 2012 +0200

    KolabMailAccess: skip repeated down-sync of recently-synced folders
    
    * when multiple EClients access the same Kolab folder
      (via an ESource and opening of a new view), we sync
      only once and skip syncing for subsequent accesses
      within a short timeframe
    * this speeds up initial startup and switching views,
      especially in the light of multiple active EClients,
      which we already have when just starting Evolution
      (at least, the alarm notifier service and Evo itself
      are concurrently accessing the same folders)

 src/libekolab/kolab-mail-access.c |   66 +++++++++++++++++++++++++++++++++---
 1 files changed, 60 insertions(+), 6 deletions(-)
---
diff --git a/src/libekolab/kolab-mail-access.c b/src/libekolab/kolab-mail-access.c
index a21fb54..ce2b490 100644
--- a/src/libekolab/kolab-mail-access.c
+++ b/src/libekolab/kolab-mail-access.c
@@ -29,8 +29,7 @@
 
 #include <glib/gi18n-lib.h>
 
-#include "kolab-util-backend.h"
-
+#include <libekolabutil/kolab-util-folder.h>
 #include <libekolabutil/kolab-util-glib.h>
 
 #include "kolab-mail-info-db.h"
@@ -65,6 +64,7 @@ struct _KolabMailAccessPrivate
 	GHashTable *stranstbl;
 
 	GHashTable *handles; /* foldername:uid:handle */
+	GHashTable *folder_update_timestamps;
 	GMutex big_lock;
 };
 
@@ -120,6 +120,7 @@ kolab_mail_access_init (KolabMailAccess *object)
 	priv->stranstbl = mail_access_new_strans_table ();
 
 	priv->handles = NULL;
+	priv->folder_update_timestamps = kolab_util_folder_timestamp_table_new ();
 	g_mutex_init (&(priv->big_lock));
 }
 
@@ -177,6 +178,8 @@ kolab_mail_access_finalize (GObject *object)
 		g_hash_table_destroy (priv->handles);
 	if (priv->stranstbl)
 		g_hash_table_destroy (priv->stranstbl);
+	if (priv->folder_update_timestamps)
+		kolab_util_folder_timestamp_table_free (priv->folder_update_timestamps);
 
 	g_mutex_lock (&(priv->big_lock));
 	g_mutex_unlock (&(priv->big_lock));
@@ -198,6 +201,37 @@ kolab_mail_access_class_init (KolabMailAccessClass *klass)
 }
 
 /*----------------------------------------------------------------------------*/
+
+static gboolean
+mail_access_folder_was_synced_recently (KolabMailAccess *self,
+                                        const gchar *foldername)
+{
+	KolabMailAccessPrivate *priv = NULL;
+	gint64 ts_diff = 0;
+	gboolean synced = FALSE;
+
+	g_assert (KOLAB_IS_MAIL_ACCESS (self));
+	g_return_val_if_fail (foldername != NULL, FALSE);
+
+	priv = KOLAB_MAIL_ACCESS_PRIVATE (self);
+
+	/* Check whether the folder has been updated
+	 * very recently. This situation typically occurs when
+	 * multiple EClients start simultaneously, like Evolution
+	 * and the alarm notifier, which will open the same views
+	 * (i.e., the same folders). If that is the case, we can
+	 * skip the full synchronization step for folders which
+	 * have been synced via another view shortly before.
+	 */
+	ts_diff = kolab_util_folder_timestamp_table_msec_since_update (priv->folder_update_timestamps,
+	                                                               foldername);
+	synced = ((ts_diff > 0) &&
+	          (ts_diff < KOLAB_FOLDER_UPDATE_DELAY_MICROSECS));
+
+	return synced;
+}
+
+/*----------------------------------------------------------------------------*/
 /* mailobject search/retrieve/store/delete */
 
 static gchar*
@@ -210,8 +244,8 @@ mail_access_foldername_new_from_sourcename (KolabMailAccess *self,
 	gboolean exists = FALSE;
 	GError *tmp_err = NULL;
 
-	/* sourcename may be NULL */
 	g_assert (KOLAB_IS_MAIL_ACCESS (self));
+	/* sourcename may be NULL */
 	g_return_val_if_fail (err == NULL || *err == NULL, NULL);
 
 	priv = KOLAB_MAIL_ACCESS_PRIVATE (self);
@@ -981,6 +1015,7 @@ mail_access_sync_with_server (KolabMailAccess *self,
 	KolabMailAccessPrivate *priv = NULL;
 	GList *folders_lst = NULL;
 	GList *folders_lst_ptr = NULL;
+	gboolean synced = FALSE;
 	gboolean ok = TRUE;
 	GError *tmp_err = NULL;
 
@@ -991,6 +1026,13 @@ mail_access_sync_with_server (KolabMailAccess *self,
 
 	priv = KOLAB_MAIL_ACCESS_PRIVATE (self);
 
+	if ((foldername != NULL) && full_sync) {
+		synced = mail_access_folder_was_synced_recently (self,
+		                                                 foldername);
+		if (synced)
+			return TRUE;
+	}
+	
 	/* sync folder / object info */
 	ok = kolab_mail_synchronizer_info_sync (priv->synchronizer,
 	                                        opmode,
@@ -1043,6 +1085,8 @@ mail_access_sync_with_server (KolabMailAccess *self,
 		                                             &tmp_err);
 		if (! ok)
 			break;
+		kolab_util_folder_timestamp_table_update (priv->folder_update_timestamps,
+		                                          foldername);
 		folders_lst_ptr = g_list_next (folders_lst_ptr);
 	}
 	kolab_util_glib_glist_free (folders_lst);
@@ -2139,13 +2183,14 @@ kolab_mail_access_query_changed_uids (KolabMailAccess *self,
 	KolabMailAccessPrivate *priv = NULL;
 	GList *changed_uids_lst = NULL;
 	gchar *foldername = NULL;
+	gboolean synced = FALSE;
 	gboolean ok = TRUE;
 	GError *tmp_err = NULL;
 
 	g_assert (KOLAB_IS_MAIL_ACCESS (self));
 	g_assert (sourcename != NULL);
 	/* sexp may be NULL */
-	(void)cancellable; /* FIXME */ /* cancellable may be NULL */
+	/* cancellable may be NULL */
 	g_return_val_if_fail (err == NULL || *err == NULL, NULL);
 
 	priv = KOLAB_MAIL_ACCESS_PRIVATE (self);
@@ -2163,6 +2208,13 @@ kolab_mail_access_query_changed_uids (KolabMailAccess *self,
 		goto exit;
 
 	if (priv->state->opmode > KOLAB_MAIL_ACCESS_OPMODE_OFFLINE) {
+		if (foldername != NULL) {
+			synced = mail_access_folder_was_synced_recently (self,
+			                                                 foldername);
+			if (synced)
+				goto sync_skip;
+		}
+
 		ok = kolab_mail_synchronizer_info_sync (priv->synchronizer,
 		                                        KOLAB_MAIL_ACCESS_OPMODE_ONLINE,
 		                                        foldername,
@@ -2171,6 +2223,8 @@ kolab_mail_access_query_changed_uids (KolabMailAccess *self,
 		if (! ok)
 			goto exit;
 
+	sync_skip:
+	
 		ok = mail_access_update_handles_from_infodb (self,
 		                                             foldername,
 		                                             sexp,
@@ -3257,9 +3311,9 @@ kolab_mail_access_delete_source (KolabMailAccess *self,
 }
 
 /**
- * kolab_mail_access_delete_source:
+ * kolab_mail_access_source_fbtrigger_needed:
  * @self: a #KolabMailAccess instance
- * @sourcename: the name of the source to delete
+ * @sourcename: the name of the source to check
  * @err: a #GError object (or NULL)
  *
  * Whether or not a free/busy generation trigger needs to be



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