[evolution-data-server] Add proper QRESYNC support on SELECT; use it for refresh_info
- From: David Woodhouse <dwmw2 src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Add proper QRESYNC support on SELECT; use it for refresh_info
- Date: Wed, 30 Jun 2010 08:52:55 +0000 (UTC)
commit 7dcedc3ef77ddcf4b7ca6bb1fbab7d3246edca34
Author: David Woodhouse <David Woodhouse intel com>
Date: Wed Jun 30 09:49:12 2010 +0100
Add proper QRESYNC support on SELECT; use it for refresh_info
We aren't yet correctly updating the folder's modseq every time, so we're
often asking for more than we need. That's better than asking for _less_ than
we need though -- will go over that part very carefully in separate commit(s).
We still aren't handling uidvalidity either. RSN...
camel/providers/imapx/camel-imapx-provider.c | 2 +
camel/providers/imapx/camel-imapx-server.c | 91 ++++++++++++++++++++++++--
camel/providers/imapx/camel-imapx-server.h | 2 +
camel/providers/imapx/camel-imapx-store.c | 3 +
camel/providers/imapx/camel-imapx-store.h | 1 +
5 files changed, 93 insertions(+), 6 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-provider.c b/camel/providers/imapx/camel-imapx-provider.c
index ad158b2..b400892 100644
--- a/camel/providers/imapx/camel-imapx-provider.c
+++ b/camel/providers/imapx/camel-imapx-provider.c
@@ -39,6 +39,8 @@ static gint imapx_url_equal (gconstpointer a, gconstpointer b);
CamelProviderConfEntry imapx_conf_entries[] = {
{ CAMEL_PROVIDER_CONF_SECTION_START, "mailcheck", NULL,
N_("Checking for New Mail") },
+ { CAMEL_PROVIDER_CONF_CHECKBOX, "use_qresync", NULL,
+ N_("Use _Quick Resync if the server supports it"), "1" },
{ CAMEL_PROVIDER_CONF_CHECKBOX, "use_idle", NULL,
N_("Use I_dle if the server supports it"), "1" },
{ CAMEL_PROVIDER_CONF_CHECKBOX, "check_all", NULL,
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index b8729f6..834c682 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -2380,6 +2380,66 @@ imapx_select (CamelIMAPXServer *is, CamelFolder *folder, gboolean forced, CamelE
is->state = IMAPX_INITIALISED;
ic = camel_imapx_command_new(is, "SELECT", NULL, "SELECT %f", folder);
+
+ if (is->use_qresync) {
+ CamelIMAPXSummary *isum = (CamelIMAPXSummary *)folder->summary;
+ CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *)folder;
+ gint total = camel_folder_summary_count(folder->summary);
+ const gchar *uid = "1";
+
+ if (total)
+ uid = camel_folder_summary_uid_from_index (folder->summary, 1);
+
+ if (isum->modseq && ifolder->uidvalidity_on_server) {
+ c(printf("SELECT QRESYNC %ld %ld\n", ifolder->uidvalidity_on_server, isum->modseq));
+ camel_imapx_command_add(ic, " (QRESYNC (%ld %ld %s:*", ifolder->uidvalidity_on_server, isum->modseq, uid);
+
+ if (total > 10) {
+ int i;
+ GString *seqs, *uids;
+
+ seqs = g_string_new(" ");
+ uids = g_string_new(")");
+
+ /* Include some seq/uid pairs to avoid a huge VANISHED list
+ (see RFC5162 §3.1). Work backwards exponentially from the
+ end of the mailbox, starting with the message 9 from the
+ end, then 27 from the end, then 81 from the end... */
+ i = 3;
+ do {
+ gchar buf[10];
+
+ i *= 3;
+ if (i > total)
+ i = total;
+
+ if (i != 9) { /* If not the first time */
+ g_string_prepend(seqs, ",");
+ g_string_prepend(uids, ",");
+ }
+
+ /* IMAP sequence numbers are one higher than the corresponding
+ indices in our folder summary -- they start from one, while
+ the summary starts from zero. */
+ sprintf(buf, "%d", total - i + 1);
+ g_string_prepend(seqs, buf);
+ g_string_prepend(uids, camel_folder_summary_uid_from_index(folder->summary, total - i));
+ } while (i < total);
+
+ g_string_prepend(seqs, " (");
+
+ c(printf("adding QRESYNC seq/uidset %s%s\n", seqs->str, uids->str));
+ camel_imapx_command_add(ic, seqs->str);
+ camel_imapx_command_add(ic, uids->str);
+
+ g_string_free(seqs, TRUE);
+ g_string_free(uids, TRUE);
+
+ }
+ camel_imapx_command_add(ic, "))");
+ }
+ }
+
ic->complete = imapx_command_select_done;
imapx_command_start (is, ic);
}
@@ -2870,7 +2930,8 @@ imapx_reconnect (CamelIMAPXServer *is, CamelException *ex)
if (camel_exception_is_set (ex))
goto exception;
}
- if (is->cinfo->capa & IMAPX_CAPABILITY_QRESYNC) {
+ if (((CamelIMAPXStore *)is->store)->rec_options & IMAPX_USE_QRESYNC &&
+ is->cinfo->capa & IMAPX_CAPABILITY_QRESYNC) {
ic = camel_imapx_command_new (is, "ENABLE", NULL, "ENABLE CONDSTORE QRESYNC");
imapx_command_run (is, ic);
camel_exception_xfer (ex, ic->ex);
@@ -2878,7 +2939,11 @@ imapx_reconnect (CamelIMAPXServer *is, CamelException *ex)
if (camel_exception_is_set (ex))
goto exception;
- }
+
+ is->use_qresync = TRUE;
+ } else
+ is->use_qresync = FALSE;
+
if (((CamelIMAPXStore *) is->store)->summary->namespaces == NULL) {
CamelIMAPXNamespaceList *nsl = NULL;
CamelIMAPXStoreNamespace *ns = NULL;
@@ -3631,6 +3696,7 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
const gchar *full_name;
gboolean need_rescan = FALSE;
gboolean is_selected = FALSE;
+ gboolean can_qresync = FALSE;
full_name = camel_folder_get_full_name (folder);
@@ -3663,6 +3729,9 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
if ((isum->modseq && !ifolder->modseq_on_server))
need_rescan = FALSE;
+ if (is->use_qresync && isum->modseq && ifolder->uidvalidity_on_server)
+ can_qresync = TRUE;
+
/* If we don't think there's anything to do, poke it to check */
if (!need_rescan) {
CamelIMAPXCommand *ic;
@@ -3735,14 +3804,24 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
imapx_server_fetch_new_messages (is, folder, FALSE, job->ex);
if (camel_exception_is_set (job->ex))
goto done;
+
+ /* If QRESYNC-capable we'll have got all flags changes in SELECT */
+ if (can_qresync)
+ goto done;
}
- /* Refetch flags for the entire folder */
- if (need_rescan) {
- imapx_job_scan_changes_start (is, job);
- return;
+ if (!need_rescan)
+ goto done;
+
+ if (can_qresync) {
+ /* Actually we only want to select it; no need for the NOOP */
+ camel_imapx_server_noop(is, folder, ex);
+ goto done;
}
+ imapx_job_scan_changes_start (is, job);
+ return;
+
done:
imapx_job_done (is, job);
}
diff --git a/camel/providers/imapx/camel-imapx-server.h b/camel/providers/imapx/camel-imapx-server.h
index c1a60d8..3eac3ec 100644
--- a/camel/providers/imapx/camel-imapx-server.h
+++ b/camel/providers/imapx/camel-imapx-server.h
@@ -119,6 +119,8 @@ struct _CamelIMAPXServer {
CamelIMAPXIdle *idle;
gboolean use_idle;
+ gboolean use_qresync;
+
/* used for storing eflags to syncronize duplicate get_message requests */
GHashTable *uid_eflags;
};
diff --git a/camel/providers/imapx/camel-imapx-store.c b/camel/providers/imapx/camel-imapx-store.c
index ba5fff8..367ed66 100644
--- a/camel/providers/imapx/camel-imapx-store.c
+++ b/camel/providers/imapx/camel-imapx-store.c
@@ -107,6 +107,9 @@ imapx_parse_receiving_options (CamelIMAPXStore *istore, CamelURL *url)
if (camel_url_get_param (url, "use_idle"))
istore->rec_options |= IMAPX_USE_IDLE;
+
+ if (camel_url_get_param (url, "use_qresync"))
+ istore->rec_options |= IMAPX_USE_QRESYNC;
}
static void
diff --git a/camel/providers/imapx/camel-imapx-store.h b/camel/providers/imapx/camel-imapx-store.h
index 8ae1ffe..732e6b4 100644
--- a/camel/providers/imapx/camel-imapx-store.h
+++ b/camel/providers/imapx/camel-imapx-store.h
@@ -56,6 +56,7 @@
#define IMAPX_SUBSCRIPTIONS (1 << 5)
#define IMAPX_CHECK_LSUB (1 << 6)
#define IMAPX_USE_IDLE (1 << 7)
+#define IMAPX_USE_QRESYNC (1 << 8)
G_BEGIN_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]