Hi there,

The imap_rescan function of the default IMAP provider of Evolution will
in case at the front of the IMAP Mailbox items got expunged, more or
less start marking all of the locally cached summary info as invalid.

(note. summary in this context means the envelope information of each
item that we have cached locally in a file called "summary" and that,
when loaded, loads into a integer-based index. The sequence number on
the IMAP server minus one must correspond to that index for each item)

As a result will the entire summary be re-retrieved. This is one of the
many reasons why Evolution's IMAP feels slow for the users: they removed
something and suddenly the next operation takes a very long time. That's
the summary being re-retrieved ... sometimes.

Luckily wont most people delete old items, so it wont occur often for
most people's IMAP operations. Nevertheless it can occur.

I figured it's a bit too-aggressive about this (it = the code). It can
also assume that only a few items got removed, keep how many got
removed, and shift the table's indexes according to the amount of
removed items.

If then we still see a significant mismatch, we can still nonetheless
mark as invalid, remove and perform a re-retrieval of the summary.

I do this in Tinymail's camel-lite code, and now ported it to upstream
camel in the patch that I attached. I have not tested this porting and
note that I do quite a lot of things different in Tinymail (it supports
condstore, which is heavily related to this code).

But for code review this might be interesting to post to you guys, so
here it goes ...

Philip Van Hoof, freelance software developer
home: me at pvanhoof dot be 
gnome: pvanhoof at gnome dot org 
Index: camel-imap-folder.c
--- camel-imap-folder.c	(revision 8395)
+++ camel-imap-folder.c	(working copy)
@@ -664,6 +664,7 @@
 	GArray *removed;
 	gboolean ok;
 	CamelFolderChangeInfo *changes = NULL;
+	gint tr = 0;
 	imap_folder->need_rescan = FALSE;
@@ -732,16 +733,17 @@
 	 * from the summary.
 	removed = g_array_new (FALSE, FALSE, sizeof (int));
-	for (i = 0; i < summary_len && new[i].uid; i++) {
-		info = camel_folder_summary_index (folder->summary, i);
+	for (i = 0; i + tr < summary_len && new[i].uid; i++) {
+		info = camel_folder_summary_index (folder->summary, i + tr);
 		iinfo = (CamelImapMessageInfo *)info;
 		if (strcmp (camel_message_info_uid (info), new[i].uid) != 0) {
+			tr++;
 			seq = i + 1;
 			g_array_append_val (removed, seq);
-			summary_len--;
+			/* summary_len--; */
@@ -762,6 +764,7 @@
 		g_free (new[i].uid);
+		new[i].uid = NULL;
 	if (changes) {
@@ -772,6 +775,7 @@
 	seq = i + 1;
 	/* Free remaining memory. */
+	i = 0;
 	while (i < summary_len && new[i].uid)
 		g_free (new[i++].uid);
 	g_free (new);
Evolution-hackers mailing list

Reply via email to