dovecot-2.2: imapc: Cache LIST replies for a while to be able to...

dovecot at dovecot.org dovecot at dovecot.org
Fri Mar 21 15:53:39 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/d9ebebdb931b
changeset: 17168:d9ebebdb931b
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Mar 21 17:52:50 2014 +0200
description:
imapc: Cache LIST replies for a while to be able to immediately ask for mailbox flags/existence.
Besides giving better performance, this will fix bugs in some servers where
LISTing a single mailbox doesn't necessarily return it. (In this case a
mailbox named "in" wasn't returned, but I think Dovecot has had bugs related
to this also.)

diffstat:

 src/lib-storage/index/imapc/imapc-list.c |  18 ++++++------------
 src/lib-storage/index/imapc/imapc-list.h |   7 +++++++
 src/lib-storage/index/imapc/imapc-sync.c |   8 ++++++++
 3 files changed, 21 insertions(+), 12 deletions(-)

diffs (98 lines):

diff -r 8fe564dd4018 -r d9ebebdb931b src/lib-storage/index/imapc/imapc-list.c
--- a/src/lib-storage/index/imapc/imapc-list.c	Thu Mar 20 17:07:32 2014 +0200
+++ b/src/lib-storage/index/imapc/imapc-list.c	Fri Mar 21 17:52:50 2014 +0200
@@ -1,6 +1,7 @@
 /* Copyright (c) 2011-2014 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "ioloop.h"
 #include "str.h"
 #include "imap-arg.h"
 #include "imap-match.h"
@@ -565,6 +566,8 @@
 
 	if (ctx.ret == 0) {
 		list->refreshed_mailboxes = TRUE;
+		list->refreshed_mailboxes_recently = TRUE;
+		list->last_refreshed_mailboxes = ioloop_time;
 		imapc_list_delete_unused_indexes(list);
 	}
 	return ctx.ret;
@@ -867,23 +870,14 @@
 				 enum mailbox_info_flags *flags_r)
 {
 	struct imapc_mailbox_list *list = (struct imapc_mailbox_list *)_list;
-	struct imapc_command *cmd;
-	struct imapc_simple_context sctx;
 	struct mailbox_node *node;
 	const char *vname;
 
 	vname = mailbox_list_get_vname(_list, name);
-	if (!list->refreshed_mailboxes) {
-		node = mailbox_tree_lookup(list->mailboxes, vname);
-		if (node != NULL)
-			node->flags |= MAILBOX_NONEXISTENT;
-
-		/* refresh the mailbox flags */
-		cmd = imapc_list_simple_context_init(&sctx, list);
-		imapc_command_sendf(cmd, "LIST \"\" %s", name);
-		imapc_simple_run(&sctx);
-		if (sctx.ret < 0)
+	if (!list->refreshed_mailboxes_recently) {
+		if (imapc_list_refresh(list) < 0)
 			return -1;
+		i_assert(list->refreshed_mailboxes_recently);
 	}
 
 	node = mailbox_tree_lookup(list->mailboxes, vname);
diff -r 8fe564dd4018 -r d9ebebdb931b src/lib-storage/index/imapc/imapc-list.h
--- a/src/lib-storage/index/imapc/imapc-list.h	Thu Mar 20 17:07:32 2014 +0200
+++ b/src/lib-storage/index/imapc/imapc-list.h	Fri Mar 21 17:52:50 2014 +0200
@@ -15,11 +15,18 @@
 
 	struct mailbox_tree_context *mailboxes, *tmp_subscriptions;
 	char root_sep;
+	time_t last_refreshed_mailboxes;
 
 	unsigned int iter_count;
 
+	/* mailboxes/subscriptions are fully refreshed only during
+	   mailbox list iteration. */
 	unsigned int refreshed_subscriptions:1;
 	unsigned int refreshed_mailboxes:1;
+	/* mailbox list's "recently refreshed" state is reset by syncing a
+	   mailbox. mainly we use this to cache mailboxes' existence to avoid
+	   issuing a LIST command every time. */
+	unsigned int refreshed_mailboxes_recently:1;
 	unsigned int index_list_failed:1;
 	unsigned int root_sep_pending:1;
 };
diff -r 8fe564dd4018 -r d9ebebdb931b src/lib-storage/index/imapc/imapc-sync.c
--- a/src/lib-storage/index/imapc/imapc-sync.c	Thu Mar 20 17:07:32 2014 +0200
+++ b/src/lib-storage/index/imapc/imapc-sync.c	Fri Mar 21 17:52:50 2014 +0200
@@ -7,6 +7,7 @@
 #include "index-sync-private.h"
 #include "imapc-client.h"
 #include "imapc-msgmap.h"
+#include "imapc-list.h"
 #include "imapc-storage.h"
 #include "imapc-sync.h"
 
@@ -448,10 +449,17 @@
 imapc_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
 {
 	struct imapc_mailbox *mbox = (struct imapc_mailbox *)box;
+	struct imapc_mailbox_list *list = mbox->storage->client->_list;
 	enum imapc_capability capabilities;
 	bool changes;
 	int ret = 0;
 
+	if (list != NULL) {
+		if (!list->refreshed_mailboxes &&
+		    list->last_refreshed_mailboxes < ioloop_time)
+			list->refreshed_mailboxes_recently = FALSE;
+	}
+
 	if (!box->opened) {
 		if (mailbox_open(box) < 0)
 			ret = -1;


More information about the dovecot-cvs mailing list