dovecot-2.1: mailbox list indexes: Moved iteration code to separ...

dovecot at dovecot.org dovecot at dovecot.org
Sun Oct 2 17:10:13 EEST 2011


details:   http://hg.dovecot.org/dovecot-2.1/rev/cd7b56e965d2
changeset: 13587:cd7b56e965d2
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Oct 02 17:18:31 2011 +0300
description:
mailbox list indexes: Moved iteration code to separate file.

diffstat:

 src/lib-storage/list/Makefile.am               |    1 +
 src/lib-storage/list/mailbox-list-index-iter.c |  172 +++++++++++++++++++++++++
 src/lib-storage/list/mailbox-list-index.c      |  169 ------------------------
 src/lib-storage/list/mailbox-list-index.h      |    8 +
 4 files changed, 181 insertions(+), 169 deletions(-)

diffs (truncated from 395 to 300 lines):

diff -r 8800d0429b7c -r cd7b56e965d2 src/lib-storage/list/Makefile.am
--- a/src/lib-storage/list/Makefile.am	Sun Oct 02 17:12:58 2011 +0300
+++ b/src/lib-storage/list/Makefile.am	Sun Oct 02 17:18:31 2011 +0300
@@ -14,6 +14,7 @@
 	mailbox-list-fs-flags.c \
 	mailbox-list-fs-iter.c \
 	mailbox-list-index.c \
+	mailbox-list-index-iter.c \
 	mailbox-list-index-status.c \
 	mailbox-list-maildir.c \
 	mailbox-list-maildir-iter.c \
diff -r 8800d0429b7c -r cd7b56e965d2 src/lib-storage/list/mailbox-list-index-iter.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/list/mailbox-list-index-iter.c	Sun Oct 02 17:18:31 2011 +0300
@@ -0,0 +1,172 @@
+/* Copyright (c) 2006-2011 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "str.h"
+#include "imap-match.h"
+#include "mail-storage.h"
+#include "mailbox-list-subscriptions.h"
+#include "mailbox-list-index.h"
+
+struct mailbox_list_iterate_context *
+mailbox_list_index_iter_init(struct mailbox_list *list,
+			     const char *const *patterns,
+			     enum mailbox_list_iter_flags flags)
+{
+	struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list);
+	struct mailbox_list_index_iterate_context *ctx;
+	char ns_sep = mail_namespace_get_sep(list->ns);
+
+	ctx = i_new(struct mailbox_list_index_iterate_context, 1);
+	ctx->ctx.list = list;
+	ctx->ctx.flags = flags;
+	ctx->ctx.glob = imap_match_init_multiple(default_pool, patterns,
+						 TRUE, ns_sep);
+	array_create(&ctx->ctx.module_contexts, default_pool, sizeof(void *), 5);
+	ctx->sep = ns_sep;
+
+	if (mailbox_list_index_refresh(ctx->ctx.list) < 0) {
+		/* no indexing */
+		ctx->backend_ctx = ilist->module_ctx.super.
+			iter_init(list, patterns, flags);
+	} else {
+		/* listing mailboxes from index */
+		ctx->info.ns = list->ns;
+		ctx->path = str_new(default_pool, 128);
+		ctx->next_node = ilist->mailbox_tree;
+		ilist->iter_refcount++;
+	}
+	return &ctx->ctx;
+}
+
+static void
+mailbox_list_index_update_info(struct mailbox_list_index_iterate_context *ctx)
+{
+	struct mailbox_list_index_node *node = ctx->next_node;
+	struct mailbox *box;
+
+	str_truncate(ctx->path, ctx->parent_len);
+	if (str_len(ctx->path) > 0)
+		str_append_c(ctx->path, ctx->sep);
+	str_append(ctx->path, node->name);
+
+	ctx->info.name = str_c(ctx->path);
+	ctx->info.flags = 0;
+	if ((node->flags & MAILBOX_LIST_INDEX_FLAG_NONEXISTENT) != 0)
+		ctx->info.flags |= MAILBOX_NONEXISTENT;
+	else if ((node->flags & MAILBOX_LIST_INDEX_FLAG_NOSELECT) != 0)
+		ctx->info.flags |= MAILBOX_NOSELECT;
+	if ((node->flags & MAILBOX_LIST_INDEX_FLAG_NOINFERIORS) != 0)
+		ctx->info.flags |= MAILBOX_NOINFERIORS;
+	ctx->info.flags |= node->children != NULL ?
+		MAILBOX_CHILDREN : MAILBOX_NOCHILDREN;
+
+	if ((ctx->ctx.flags & (MAILBOX_LIST_ITER_SELECT_SUBSCRIBED |
+			       MAILBOX_LIST_ITER_RETURN_SUBSCRIBED)) != 0) {
+		mailbox_list_set_subscription_flags(ctx->ctx.list,
+						    ctx->info.name,
+						    &ctx->info.flags);
+	}
+
+	box = mailbox_alloc(ctx->ctx.list, ctx->info.name, 0);
+	mailbox_list_index_status_set_info_flags(box, node->uid,
+						 &ctx->info.flags);
+	mailbox_free(&box);
+}
+
+static void
+mailbox_list_index_update_next(struct mailbox_list_index_iterate_context *ctx,
+			       bool follow_children)
+{
+	struct mailbox_list_index_node *node = ctx->next_node;
+
+	if (node->children != NULL && follow_children) {
+		ctx->parent_len = str_len(ctx->path);
+		ctx->next_node = node->children;
+	} else {
+		while (node->next == NULL) {
+			node = node->parent;
+			if (node != NULL) {
+				ctx->parent_len -= strlen(node->name);
+				if (node->parent != NULL)
+					ctx->parent_len--;
+			}
+			if (node == NULL) {
+				/* last one */
+				ctx->next_node = NULL;
+				return;
+			}
+		}
+		ctx->next_node = node->next;
+	}
+}
+
+static bool
+iter_subscriptions_ok(struct mailbox_list_index_iterate_context *ctx)
+{
+	if ((ctx->ctx.flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) == 0)
+		return TRUE;
+
+	if ((ctx->info.flags & MAILBOX_SUBSCRIBED) != 0)
+		return TRUE;
+
+	if ((ctx->ctx.flags & MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH) != 0 &&
+	    (ctx->info.flags & MAILBOX_CHILD_SUBSCRIBED) != 0)
+		return TRUE;
+	return FALSE;
+}
+
+const struct mailbox_info *
+mailbox_list_index_iter_next(struct mailbox_list_iterate_context *_ctx)
+{
+	struct mailbox_list_index_iterate_context *ctx =
+		(struct mailbox_list_index_iterate_context *)_ctx;
+	struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(_ctx->list);
+	bool follow_children;
+	enum imap_match_result match;
+
+	if (ctx->backend_ctx != NULL) {
+		/* index isn't being used */
+		return ilist->module_ctx.super.iter_next(ctx->backend_ctx);
+	}
+
+	/* listing mailboxes from index */
+	while (ctx->next_node != NULL) {
+		mailbox_list_index_update_info(ctx);
+		match = imap_match(_ctx->glob, ctx->info.name);
+
+		follow_children = (match & (IMAP_MATCH_YES |
+					    IMAP_MATCH_CHILDREN)) != 0;
+		if (match == IMAP_MATCH_YES && iter_subscriptions_ok(ctx)) {
+			mailbox_list_index_update_next(ctx, TRUE);
+			return &ctx->info;
+		} else if ((_ctx->flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0 &&
+			   (ctx->info.flags & MAILBOX_CHILD_SUBSCRIBED) == 0) {
+			/* listing only subscriptions, but there are no
+			   subscribed children. */
+			follow_children = FALSE;
+		}
+		mailbox_list_index_update_next(ctx, follow_children);
+	}
+	return NULL;
+}
+
+int mailbox_list_index_iter_deinit(struct mailbox_list_iterate_context *_ctx)
+{
+	struct mailbox_list_index_iterate_context *ctx =
+		(struct mailbox_list_index_iterate_context *)_ctx;
+	struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(_ctx->list);
+	int ret = ctx->failed ? -1 : 0;
+
+	if (ctx->backend_ctx != NULL)
+		ret = ilist->module_ctx.super.iter_deinit(ctx->backend_ctx);
+	else {
+		i_assert(ilist->iter_refcount > 0);
+		ilist->iter_refcount--;
+		str_free(&ctx->path);
+	}
+
+	imap_match_deinit(&ctx->ctx.glob);
+	array_free(&ctx->ctx.module_contexts);
+	i_free(ctx);
+	return ret;
+}
diff -r 8800d0429b7c -r cd7b56e965d2 src/lib-storage/list/mailbox-list-index.c
--- a/src/lib-storage/list/mailbox-list-index.c	Sun Oct 02 17:12:58 2011 +0300
+++ b/src/lib-storage/list/mailbox-list-index.c	Sun Oct 02 17:18:31 2011 +0300
@@ -2,13 +2,10 @@
 
 #include "lib.h"
 #include "ioloop.h"
-#include "str.h"
 #include "hash.h"
-#include "imap-match.h"
 #include "mail-index.h"
 #include "mail-storage.h"
 #include "mail-storage-hooks.h"
-#include "mailbox-list-subscriptions.h"
 #include "mailbox-list-index.h"
 
 struct mailbox_list_index_sync_context {
@@ -551,172 +548,6 @@
 	mail_index_view_close(&view);
 }
 
-static struct mailbox_list_iterate_context *
-mailbox_list_index_iter_init(struct mailbox_list *list,
-			     const char *const *patterns,
-			     enum mailbox_list_iter_flags flags)
-{
-	struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list);
-	struct mailbox_list_index_iterate_context *ctx;
-	char ns_sep = mail_namespace_get_sep(list->ns);
-
-	ctx = i_new(struct mailbox_list_index_iterate_context, 1);
-	ctx->ctx.list = list;
-	ctx->ctx.flags = flags;
-	ctx->ctx.glob = imap_match_init_multiple(default_pool, patterns,
-						 TRUE, ns_sep);
-	array_create(&ctx->ctx.module_contexts, default_pool, sizeof(void *), 5);
-	ctx->sep = ns_sep;
-
-	if (mailbox_list_index_refresh(ctx->ctx.list) < 0) {
-		/* no indexing */
-		mail_index_mark_corrupted(ilist->index);
-		ctx->backend_ctx = ilist->module_ctx.super.
-			iter_init(list, patterns, flags);
-	} else {
-		/* listing mailboxes from index */
-		ctx->info.ns = list->ns;
-		ctx->path = str_new(default_pool, 128);
-		ctx->next_node = ilist->mailbox_tree;
-		ilist->iter_refcount++;
-	}
-	return &ctx->ctx;
-}
-
-static void
-mailbox_list_index_update_info(struct mailbox_list_index_iterate_context *ctx)
-{
-	struct mailbox_list_index_node *node = ctx->next_node;
-	struct mailbox *box;
-
-	str_truncate(ctx->path, ctx->parent_len);
-	if (str_len(ctx->path) > 0)
-		str_append_c(ctx->path, ctx->sep);
-	str_append(ctx->path, node->name);
-
-	ctx->info.name = str_c(ctx->path);
-	ctx->info.flags = 0;
-	if ((node->flags & MAILBOX_LIST_INDEX_FLAG_NONEXISTENT) != 0)
-		ctx->info.flags |= MAILBOX_NONEXISTENT;
-	else if ((node->flags & MAILBOX_LIST_INDEX_FLAG_NOSELECT) != 0)
-		ctx->info.flags |= MAILBOX_NOSELECT;
-	if ((node->flags & MAILBOX_LIST_INDEX_FLAG_NOINFERIORS) != 0)
-		ctx->info.flags |= MAILBOX_NOINFERIORS;
-	ctx->info.flags |= node->children != NULL ?
-		MAILBOX_CHILDREN : MAILBOX_NOCHILDREN;
-
-	if ((ctx->ctx.flags & (MAILBOX_LIST_ITER_SELECT_SUBSCRIBED |
-			       MAILBOX_LIST_ITER_RETURN_SUBSCRIBED)) != 0) {
-		mailbox_list_set_subscription_flags(ctx->ctx.list,
-						    ctx->info.name,
-						    &ctx->info.flags);
-	}
-
-	box = mailbox_alloc(ctx->ctx.list, ctx->info.name, 0);
-	mailbox_list_index_status_set_info_flags(box, node->uid,
-						 &ctx->info.flags);
-	mailbox_free(&box);
-}
-
-static void
-mailbox_list_index_update_next(struct mailbox_list_index_iterate_context *ctx,
-			       bool follow_children)
-{
-	struct mailbox_list_index_node *node = ctx->next_node;
-
-	if (node->children != NULL && follow_children) {
-		ctx->parent_len = str_len(ctx->path);
-		ctx->next_node = node->children;
-	} else {
-		while (node->next == NULL) {
-			node = node->parent;
-			if (node != NULL) {
-				ctx->parent_len -= strlen(node->name);
-				if (node->parent != NULL)
-					ctx->parent_len--;
-			}
-			if (node == NULL) {
-				/* last one */
-				ctx->next_node = NULL;
-				return;
-			}
-		}
-		ctx->next_node = node->next;
-	}


More information about the dovecot-cvs mailing list