]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
mailbox list indexes: Moved iteration code to separate file.
authorTimo Sirainen <tss@iki.fi>
Sun, 2 Oct 2011 14:18:31 +0000 (17:18 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 2 Oct 2011 14:18:31 +0000 (17:18 +0300)
src/lib-storage/list/Makefile.am
src/lib-storage/list/mailbox-list-index-iter.c [new file with mode: 0644]
src/lib-storage/list/mailbox-list-index.c
src/lib-storage/list/mailbox-list-index.h

index 61b7ca07c4ff6f6da97ba5720a1596007d4d9031..caa42f44242be9f475dc1e03bc550d415ff2f2fd 100644 (file)
@@ -14,6 +14,7 @@ libstorage_list_la_SOURCES = \
        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 --git a/src/lib-storage/list/mailbox-list-index-iter.c b/src/lib-storage/list/mailbox-list-index-iter.c
new file mode 100644 (file)
index 0000000..8a13dd5
--- /dev/null
@@ -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;
+}
index 567d9af51f87cdfffe99dbb9f4680bacac8aa123..1c4f7266ed14d2083d96d01c288f37e319edd2fa 100644 (file)
@@ -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 @@ void mailbox_list_index_refresh_later(struct mailbox_list *list)
        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;
-       }
-}
-
-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;
-}
-
-static 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;
-}
-
-static 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;
-}
-
 static void mailbox_list_index_deinit(struct mailbox_list *list)
 {
        struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list);
index 3694f22aa3aff143efeba38cabcc581a218667a9..aac0fbab4b46c3a1ef1db7f4e9082dd7a9929f66 100644 (file)
@@ -102,6 +102,14 @@ mailbox_list_index_lookup(struct mailbox_list *list, const char *name);
 int mailbox_list_index_refresh(struct mailbox_list *list);
 void mailbox_list_index_refresh_later(struct mailbox_list *list);
 
+struct mailbox_list_iterate_context *
+mailbox_list_index_iter_init(struct mailbox_list *list,
+                            const char *const *patterns,
+                            enum mailbox_list_iter_flags flags);
+const struct mailbox_info *
+mailbox_list_index_iter_next(struct mailbox_list_iterate_context *ctx);
+int mailbox_list_index_iter_deinit(struct mailbox_list_iterate_context *ctx);
+
 void mailbox_list_index_status_set_info_flags(struct mailbox *box, uint32_t uid,
                                              enum mailbox_info_flags *flags);