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