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

index caa42f44242be9f475dc1e03bc550d415ff2f2fd..d4f6c86cf6f812fd1bc543224bacb47875c53c60 100644 (file)
@@ -16,6 +16,7 @@ libstorage_list_la_SOURCES = \
        mailbox-list-index.c \
        mailbox-list-index-iter.c \
        mailbox-list-index-status.c \
+       mailbox-list-index-sync.c \
        mailbox-list-maildir.c \
        mailbox-list-maildir-iter.c \
        mailbox-list-none.c \
diff --git a/src/lib-storage/list/mailbox-list-index-sync.c b/src/lib-storage/list/mailbox-list-index-sync.c
new file mode 100644 (file)
index 0000000..a420c26
--- /dev/null
@@ -0,0 +1,308 @@
+/* Copyright (c) 2006-2011 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "ioloop.h"
+#include "hash.h"
+#include "mail-index.h"
+#include "mailbox-list-index.h"
+
+struct mailbox_list_index_sync_context {
+       struct mailbox_list_index *ilist;
+       char sep[2];
+       uint32_t next_uid;
+
+       struct mail_index_sync_ctx *sync_ctx;
+       struct mail_index_view *view;
+       struct mail_index_transaction *trans;
+};
+
+static void
+node_add_to_index(struct mailbox_list_index_sync_context *ctx,
+                 const struct mailbox_list_index_node *node, uint32_t *seq_r)
+{
+       struct mailbox_list_index_record irec;
+       uint32_t seq;
+
+       memset(&irec, 0, sizeof(irec));
+       irec.name_id = node->name_id;
+       if (node->parent != NULL)
+               irec.parent_uid = node->parent->uid;
+
+       mail_index_append(ctx->trans, node->uid, &seq);
+       mail_index_update_flags(ctx->trans, seq, MODIFY_REPLACE,
+               (enum mail_flags)MAILBOX_LIST_INDEX_FLAG_NONEXISTENT);
+       mail_index_update_ext(ctx->trans, seq, ctx->ilist->ext_id, &irec, NULL);
+
+       *seq_r = seq;
+}
+
+static struct mailbox_list_index_node *
+mailbox_list_index_node_add(struct mailbox_list_index_sync_context *ctx,
+                           struct mailbox_list_index_node *parent,
+                           const char *name, uint32_t *seq_r)
+{
+       struct mailbox_list_index_node *node;
+       char *dup_name;
+
+       node = p_new(ctx->ilist->mailbox_pool,
+                    struct mailbox_list_index_node, 1);
+       node->flags = MAILBOX_LIST_INDEX_FLAG_NONEXISTENT |
+               MAILBOX_LIST_INDEX_FLAG_MARKED;
+       /* we don't bother doing name deduplication here, even though it would
+          be possible. */
+       node->name = dup_name = p_strdup(ctx->ilist->mailbox_pool, name);
+       node->name_id = ++ctx->ilist->highest_name_id;
+       node->uid = ctx->next_uid++;
+
+       if (parent != NULL) {
+               node->parent = parent;
+               node->next = parent->children;
+               parent->children = node;
+       } else {
+               node->next = ctx->ilist->mailbox_tree;
+               ctx->ilist->mailbox_tree = node;
+       }
+       hash_table_insert(ctx->ilist->mailbox_hash,
+                         POINTER_CAST(node->uid), node);
+       hash_table_insert(ctx->ilist->mailbox_names,
+                         POINTER_CAST(node->name_id), dup_name);
+
+       node_add_to_index(ctx, node, seq_r);
+       return node;
+}
+
+static uint32_t
+mailbox_list_index_sync_name(struct mailbox_list_index_sync_context *ctx,
+                            const char *name,
+                            enum mailbox_list_index_flags flags)
+{
+       const char *const *path;
+       struct mailbox_list_index_node *node, *parent;
+       unsigned int i;
+       uint32_t seq = 0;
+
+       path = t_strsplit(name, ctx->sep);
+       node = ctx->ilist->mailbox_tree; parent = NULL;
+       for (i = 0; path[i] != NULL; i++) {
+               node = mailbox_list_index_node_find_sibling(node, path[i]);
+               if (node == NULL)
+                       break;
+               node->flags |= MAILBOX_LIST_INDEX_FLAG_MARKED;
+               parent = node;
+               node = node->children;
+       }
+
+       node = parent;
+       if (path[i] == NULL) {
+               if (!mail_index_lookup_seq(ctx->view, node->uid, &seq))
+                       i_panic("mailbox list index: lost uid=%u", node->uid);
+       } else {
+               for (; path[i] != NULL; i++) {
+                       node = mailbox_list_index_node_add(ctx, node, path[i],
+                                                          &seq);
+               }
+       }
+
+       node->flags = flags | MAILBOX_LIST_INDEX_FLAG_MARKED;
+       return seq;
+}
+
+static void
+get_existing_name_ids(ARRAY_TYPE(uint32_t) *ids,
+                     const struct mailbox_list_index_node *node)
+{
+       for (; node != NULL; node = node->next) {
+               if ((node->flags & MAILBOX_LIST_INDEX_FLAG_MARKED) != 0) {
+                       if (node->children != NULL)
+                               get_existing_name_ids(ids, node->children);
+                       array_append(ids, &node->name_id, 1);
+               }
+       }
+}
+
+static int uint32_cmp(const uint32_t *p1, const uint32_t *p2)
+{
+       return *p1 < *p2 ? -1 :
+               (*p1 > *p2 ? 1 : 0);
+}
+
+static void
+mailbox_list_index_sync_names(struct mailbox_list_index_sync_context *ctx)
+{
+       struct mailbox_list_index *ilist = ctx->ilist;
+       ARRAY_TYPE(uint32_t) existing_name_ids;
+       buffer_t *buf;
+       const void *ext_data;
+       size_t ext_size;
+       const char *name;
+       const uint32_t *id_p;
+       uint32_t prev_id = 0;
+
+       t_array_init(&existing_name_ids, 64);
+       get_existing_name_ids(&existing_name_ids, ilist->mailbox_tree);
+       array_sort(&existing_name_ids, uint32_cmp);
+
+       buf = buffer_create_dynamic(pool_datastack_create(), 1024);
+       buffer_append_zero(buf, sizeof(struct mailbox_list_index_header));
+
+       array_foreach(&existing_name_ids, id_p) {
+               if (*id_p != prev_id) {
+                       buffer_append(buf, id_p, sizeof(*id_p));
+                       name = hash_table_lookup(ilist->mailbox_names,
+                                                POINTER_CAST(*id_p));
+                       buffer_append(buf, name, strlen(name) + 1);
+                       prev_id = *id_p;
+               }
+       }
+       buffer_append_zero(buf, sizeof(*id_p));
+
+       mail_index_get_header_ext(ctx->view, ilist->ext_id,
+                                 &ext_data, &ext_size);
+       if (nearest_power(ext_size) != nearest_power(buf->used)) {
+               mail_index_ext_resize(ctx->trans, ilist->ext_id,
+                                     nearest_power(buf->used),
+                                     sizeof(struct mailbox_list_index_record),
+                                     sizeof(uint32_t));
+       }
+       mail_index_update_header_ext(ctx->trans, ilist->ext_id,
+                                    0, buf->data, buf->used);
+}
+
+static void
+mailbox_list_index_node_unmark_recursive(struct mailbox_list_index_node *node)
+{
+       while (node != NULL) {
+               if (node->children != NULL)
+                       mailbox_list_index_node_unmark_recursive(node->children);
+
+               node->flags &= ~MAILBOX_LIST_INDEX_FLAG_MARKED;
+               node = node->next;
+       }
+}
+
+static void
+mailbox_list_index_node_unlink(struct mailbox_list_index_sync_context *sync_ctx,
+                              struct mailbox_list_index_node *node)
+{
+       struct mailbox_list_index_node **prev;
+
+       prev = node->parent == NULL ?
+               &sync_ctx->ilist->mailbox_tree :
+               &node->parent->children;
+
+       while (*prev != node)
+               prev = &(*prev)->next;
+       *prev = node->next;
+}
+
+static void
+mailbox_list_index_nodes_expunge(struct mailbox_list_index_sync_context *sync_ctx,
+                                struct mailbox_list_index_node *node)
+{
+       uint32_t seq;
+
+       while (node != NULL) {
+               if (node->children != NULL) {
+                       mailbox_list_index_nodes_expunge(sync_ctx,
+                                                        node->children);
+               }
+
+               if ((node->flags & MAILBOX_LIST_INDEX_FLAG_MARKED) == 0) {
+                       if (mail_index_lookup_seq(sync_ctx->view, node->uid,
+                                                 &seq))
+                               mail_index_expunge(sync_ctx->trans, seq);
+                       mailbox_list_index_node_unlink(sync_ctx, node);
+               }
+               node = node->next;
+       }
+}
+
+int mailbox_list_index_sync(struct mailbox_list *list)
+{
+       struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list);
+       struct mailbox_list_index_sync_context sync_ctx;
+       struct mailbox_list_iterate_context *iter;
+       const struct mail_index_header *hdr;
+       const struct mailbox_info *info;
+       const char *patterns[2];
+       enum mailbox_list_index_flags flags;
+       uint32_t seq, orig_highest_name_id;
+       int ret = 0;
+
+       mailbox_list_index_reset(ilist);
+
+       memset(&sync_ctx, 0, sizeof(sync_ctx));
+       sync_ctx.ilist = ilist;
+       sync_ctx.sep[0] = mailbox_list_get_hierarchy_sep(list);
+       if (mail_index_sync_begin(ilist->index, &sync_ctx.sync_ctx,
+                                 &sync_ctx.view, &sync_ctx.trans,
+                                 MAIL_INDEX_SYNC_FLAG_AVOID_FLAG_UPDATES) < 0)
+               return -1;
+
+       if (mailbox_list_index_read(ilist, sync_ctx.view, TRUE) < 0) {
+               mail_index_sync_rollback(&sync_ctx.sync_ctx);
+               return -1;
+       }
+       orig_highest_name_id = ilist->highest_name_id;
+
+       hdr = mail_index_get_header(sync_ctx.view);
+       sync_ctx.next_uid = hdr->next_uid;
+
+       if (hdr->uid_validity == 0) {
+               uint32_t uid_validity = ioloop_time;
+
+               mail_index_update_header(sync_ctx.trans,
+                       offsetof(struct mail_index_header, uid_validity),
+                       &uid_validity, sizeof(uid_validity), TRUE);
+       }
+
+       mailbox_list_index_node_unmark_recursive(ilist->mailbox_tree);
+
+       patterns[0] = "*"; patterns[1] = NULL;
+       iter = ilist->module_ctx.super.iter_init(list, patterns, 0);
+       while ((info = ilist->module_ctx.super.iter_next(iter)) != NULL) {
+               flags = 0;
+               if ((info->flags & MAILBOX_NONEXISTENT) != 0)
+                       flags |= MAILBOX_LIST_INDEX_FLAG_NONEXISTENT;
+               if ((info->flags & MAILBOX_NOSELECT) != 0)
+                       flags |= MAILBOX_LIST_INDEX_FLAG_NOSELECT;
+               if ((info->flags & MAILBOX_NOINFERIORS) != 0)
+                       flags |= MAILBOX_LIST_INDEX_FLAG_NOINFERIORS;
+
+               T_BEGIN {
+                       const char *name =
+                               mailbox_list_get_storage_name(info->ns->list,
+                                                             info->name);
+                       seq = mailbox_list_index_sync_name(&sync_ctx,
+                                                          name, flags);
+               } T_END;
+
+               mail_index_update_flags(sync_ctx.trans, seq,
+                                       MODIFY_REPLACE, (enum mail_flags)flags);
+       }
+       if (ilist->module_ctx.super.iter_deinit(iter) < 0)
+               ret = -1;
+
+       if (ret < 0) {
+               mail_index_sync_rollback(&sync_ctx.sync_ctx);
+               return -1;
+       }
+
+       mailbox_list_index_nodes_expunge(&sync_ctx, ilist->mailbox_tree);
+
+       if (orig_highest_name_id != ilist->highest_name_id) {
+               /* new names added */
+               T_BEGIN {
+                       mailbox_list_index_sync_names(&sync_ctx);
+               } T_END;
+       } else {
+               struct mailbox_list_index_header new_hdr;
+
+               new_hdr.refresh_flag = 0;
+               mail_index_update_header_ext(sync_ctx.trans, ilist->ext_id,
+                       offsetof(struct mailbox_list_index_header, refresh_flag),
+                       &new_hdr.refresh_flag, sizeof(new_hdr.refresh_flag));
+       }
+
+       return mail_index_sync_commit(&sync_ctx.sync_ctx);
+}
index 1c4f7266ed14d2083d96d01c288f37e319edd2fa..7ab7d6ee67b6aec20437023d3a63d35b2d316440 100644 (file)
@@ -1,30 +1,15 @@
 /* Copyright (c) 2006-2011 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
-#include "ioloop.h"
 #include "hash.h"
 #include "mail-index.h"
-#include "mail-storage.h"
 #include "mail-storage-hooks.h"
 #include "mailbox-list-index.h"
 
-struct mailbox_list_index_sync_context {
-       struct mailbox_list_index *ilist;
-       char sep[2];
-       uint32_t next_uid;
-
-       struct mail_index_sync_ctx *sync_ctx;
-       struct mail_index_view *view;
-       struct mail_index_transaction *trans;
-};
-
 struct mailbox_list_index_module mailbox_list_index_module =
        MODULE_CONTEXT_INIT(&mailbox_list_module_register);
 
-static int mailbox_list_index_read(struct mailbox_list_index *ilist,
-                                  struct mail_index_view *view, bool force);
-
-static void mailbox_list_index_reset(struct mailbox_list_index *ilist)
+void mailbox_list_index_reset(struct mailbox_list_index *ilist)
 {
        hash_table_clear(ilist->mailbox_names, FALSE);
        hash_table_clear(ilist->mailbox_hash, FALSE);
@@ -35,8 +20,9 @@ static void mailbox_list_index_reset(struct mailbox_list_index *ilist)
        ilist->sync_log_file_offset = 0;
 }
 
-static struct mailbox_list_index_node *
-node_find_sibling(struct mailbox_list_index_node *node, const char *name)
+struct mailbox_list_index_node *
+mailbox_list_index_node_find_sibling(struct mailbox_list_index_node *node,
+                                    const char *name)
 {
        while (node != NULL) {
                if (strcmp(node->name, name) == 0)
@@ -46,325 +32,40 @@ node_find_sibling(struct mailbox_list_index_node *node, const char *name)
        return NULL;
 }
 
-static void
-node_add_to_index(struct mailbox_list_index_sync_context *ctx,
-                 struct mailbox_list_index_node *node,
-                 uint32_t *name_id_r, uint32_t *seq_r)
-{
-       struct mailbox_list_index_record irec;
-       uint32_t seq;
-
-       memset(&irec, 0, sizeof(irec));
-       irec.name_id = node->name_id;
-       if (node->parent != NULL)
-               irec.parent_uid = node->parent->uid;
-
-       mail_index_append(ctx->trans, node->uid, &seq);
-       mail_index_update_flags(ctx->trans, seq, MODIFY_REPLACE,
-               (enum mail_flags)MAILBOX_LIST_INDEX_FLAG_NONEXISTENT);
-       mail_index_update_ext(ctx->trans, seq, ctx->ilist->ext_id, &irec, NULL);
-
-       *name_id_r = irec.name_id;
-       *seq_r = seq;
-}
-
 static struct mailbox_list_index_node *
-mailbox_list_index_node_add(struct mailbox_list_index_sync_context *ctx,
-                           struct mailbox_list_index_node *parent,
-                           const char *name, uint32_t *seq_r)
+mailbox_list_index_lookup_real(struct mailbox_list *list, const char *name)
 {
+       struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list);
        struct mailbox_list_index_node *node;
-       uint32_t name_id;
-       char *dup_name;
-
-       node = p_new(ctx->ilist->mailbox_pool,
-                    struct mailbox_list_index_node, 1);
-       node->flags = MAILBOX_LIST_INDEX_FLAG_NONEXISTENT |
-               MAILBOX_LIST_INDEX_FLAG_MARKED;
-       node->name = dup_name = p_strdup(ctx->ilist->mailbox_pool, name);
-       node->name_id = ++ctx->ilist->highest_name_id;
-       node->uid = ctx->next_uid++;
-
-       if (parent != NULL) {
-               node->parent = parent;
-               node->next = parent->children;
-               parent->children = node;
-       } else {
-               node->next = ctx->ilist->mailbox_tree;
-               ctx->ilist->mailbox_tree = node;
-       }
+       const char *const *path;
+       unsigned int i;
+       char sep[2];
+
+       (void)mailbox_list_index_refresh(list);
 
-       node_add_to_index(ctx, node, &name_id, seq_r);
-       hash_table_insert(ctx->ilist->mailbox_hash,
-                         POINTER_CAST(node->uid), node);
-       hash_table_insert(ctx->ilist->mailbox_names,
-                         POINTER_CAST(name_id), dup_name);
+       sep[0] = mailbox_list_get_hierarchy_sep(list); sep[1] = '\0';
+       path = t_strsplit(name, sep);
+       node = ilist->mailbox_tree;
+       for (i = 0;; i++) {
+               node = mailbox_list_index_node_find_sibling(node, path[i]);
+               if (node == NULL || path[i+1] == NULL)
+                       break;
+               node = node->children;
+       }
        return node;
 }
 
 struct mailbox_list_index_node *
 mailbox_list_index_lookup(struct mailbox_list *list, const char *name)
 {
-       struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list);
        struct mailbox_list_index_node *node;
 
-       (void)mailbox_list_index_refresh(list);
-
        T_BEGIN {
-               const char *const *path;
-               unsigned int i;
-               char sep[2];
-
-               sep[0] = mailbox_list_get_hierarchy_sep(list); sep[1] = '\0';
-               path = t_strsplit(name, sep);
-               node = ilist->mailbox_tree;
-               for (i = 0;; i++) {
-                       node = node_find_sibling(node, path[i]);
-                       if (node == NULL || path[i+1] == NULL)
-                               break;
-                       node = node->children;
-               }
+               node = mailbox_list_index_lookup_real(list, name);
        } T_END;
-
        return node;
 }
 
-static uint32_t
-mailbox_list_index_sync_name(struct mailbox_list_index_sync_context *ctx,
-                            const char *name,
-                            enum mailbox_list_index_flags flags)
-{
-       const char *const *path;
-       struct mailbox_list_index_node *node, *parent;
-       unsigned int i;
-       uint32_t seq = 0;
-
-       path = t_strsplit(name, ctx->sep);
-       node = ctx->ilist->mailbox_tree; parent = NULL;
-       for (i = 0; path[i] != NULL; i++) {
-               node = node_find_sibling(node, path[i]);
-               if (node == NULL)
-                       break;
-               node->flags |= MAILBOX_LIST_INDEX_FLAG_MARKED;
-               parent = node;
-               node = node->children;
-       }
-
-       node = parent;
-       if (path[i] == NULL) {
-               if (!mail_index_lookup_seq(ctx->view, node->uid, &seq))
-                       i_panic("mailbox list index: lost uid=%u", node->uid);
-       } else {
-               for (; path[i] != NULL; i++) {
-                       node = mailbox_list_index_node_add(ctx, node, path[i],
-                                                          &seq);
-               }
-       }
-
-       node->flags = flags | MAILBOX_LIST_INDEX_FLAG_MARKED;
-       return seq;
-}
-
-static void
-get_existing_name_ids(ARRAY_TYPE(uint32_t) *ids,
-                     const struct mailbox_list_index_node *node)
-{
-       for (; node != NULL; node = node->next) {
-               if ((node->flags & MAILBOX_LIST_INDEX_FLAG_MARKED) != 0) {
-                       if (node->children != NULL)
-                               get_existing_name_ids(ids, node->children);
-                       array_append(ids, &node->name_id, 1);
-               }
-       }
-}
-
-static int uint32_cmp(const uint32_t *p1, const uint32_t *p2)
-{
-       return *p1 < *p2 ? -1 :
-               (*p1 > *p2 ? 1 : 0);
-}
-
-static void
-mailbox_list_index_sync_names(struct mailbox_list_index_sync_context *ctx)
-{
-       struct mailbox_list_index *ilist = ctx->ilist;
-       ARRAY_TYPE(uint32_t) existing_name_ids;
-       buffer_t *buf;
-       const void *ext_data;
-       size_t ext_size;
-       const char *name;
-       const uint32_t *id_p;
-       uint32_t prev_id = 0;
-
-       t_array_init(&existing_name_ids, 64);
-       get_existing_name_ids(&existing_name_ids, ilist->mailbox_tree);
-       array_sort(&existing_name_ids, uint32_cmp);
-
-       buf = buffer_create_dynamic(pool_datastack_create(), 1024);
-       buffer_append_zero(buf, sizeof(struct mailbox_list_index_header));
-
-       array_foreach(&existing_name_ids, id_p) {
-               if (*id_p != prev_id) {
-                       buffer_append(buf, id_p, sizeof(*id_p));
-                       name = hash_table_lookup(ilist->mailbox_names,
-                                                POINTER_CAST(*id_p));
-                       buffer_append(buf, name, strlen(name) + 1);
-                       prev_id = *id_p;
-               }
-       }
-       buffer_append_zero(buf, sizeof(*id_p));
-
-       mail_index_get_header_ext(ctx->view, ilist->ext_id,
-                                 &ext_data, &ext_size);
-       if (nearest_power(ext_size) != nearest_power(buf->used)) {
-               mail_index_ext_resize(ctx->trans, ilist->ext_id,
-                                     nearest_power(buf->used),
-                                     sizeof(struct mailbox_list_index_record),
-                                     sizeof(uint32_t));
-       }
-       mail_index_update_header_ext(ctx->trans, ilist->ext_id,
-                                    0, buf->data, buf->used);
-}
-
-static void
-mailbox_list_index_node_unmark_recursive(struct mailbox_list_index_node *node)
-{
-       while (node != NULL) {
-               if (node->children != NULL)
-                       mailbox_list_index_node_unmark_recursive(node->children);
-
-               node->flags &= ~MAILBOX_LIST_INDEX_FLAG_MARKED;
-               node = node->next;
-       }
-}
-
-static void
-mailbox_list_index_node_unlink(struct mailbox_list_index_sync_context *sync_ctx,
-                              struct mailbox_list_index_node *node)
-{
-       struct mailbox_list_index_node **prev;
-
-       prev = node->parent == NULL ?
-               &sync_ctx->ilist->mailbox_tree :
-               &node->parent->children;
-
-       while (*prev != node)
-               prev = &(*prev)->next;
-       *prev = node->next;
-}
-
-static void
-mailbox_list_index_nodes_expunge(struct mailbox_list_index_sync_context *sync_ctx,
-                                struct mailbox_list_index_node *node)
-{
-       uint32_t seq;
-
-       while (node != NULL) {
-               if (node->children != NULL) {
-                       mailbox_list_index_nodes_expunge(sync_ctx,
-                                                        node->children);
-               }
-
-               if ((node->flags & MAILBOX_LIST_INDEX_FLAG_MARKED) == 0) {
-                       if (mail_index_lookup_seq(sync_ctx->view, node->uid,
-                                                 &seq))
-                               mail_index_expunge(sync_ctx->trans, seq);
-                       mailbox_list_index_node_unlink(sync_ctx, node);
-               }
-               node = node->next;
-       }
-}
-
-static int mailbox_list_index_sync(struct mailbox_list *list)
-{
-       struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list);
-       struct mailbox_list_index_sync_context sync_ctx;
-       struct mailbox_list_iterate_context *iter;
-       const struct mail_index_header *hdr;
-       const struct mailbox_info *info;
-       const char *patterns[2];
-       enum mailbox_list_index_flags flags;
-       uint32_t seq, orig_highest_name_id;
-       int ret = 0;
-
-       mailbox_list_index_reset(ilist);
-
-       memset(&sync_ctx, 0, sizeof(sync_ctx));
-       sync_ctx.ilist = ilist;
-       sync_ctx.sep[0] = mailbox_list_get_hierarchy_sep(list);
-       if (mail_index_sync_begin(ilist->index, &sync_ctx.sync_ctx,
-                                 &sync_ctx.view, &sync_ctx.trans,
-                                 MAIL_INDEX_SYNC_FLAG_AVOID_FLAG_UPDATES) < 0)
-               return -1;
-
-       if (mailbox_list_index_read(ilist, sync_ctx.view, TRUE) < 0) {
-               mail_index_sync_rollback(&sync_ctx.sync_ctx);
-               return -1;
-       }
-       orig_highest_name_id = ilist->highest_name_id;
-
-       hdr = mail_index_get_header(sync_ctx.view);
-       sync_ctx.next_uid = hdr->next_uid;
-
-       if (hdr->uid_validity == 0) {
-               uint32_t uid_validity = ioloop_time;
-
-               mail_index_update_header(sync_ctx.trans,
-                       offsetof(struct mail_index_header, uid_validity),
-                       &uid_validity, sizeof(uid_validity), TRUE);
-       }
-
-       mailbox_list_index_node_unmark_recursive(ilist->mailbox_tree);
-
-       patterns[0] = "*"; patterns[1] = NULL;
-       iter = ilist->module_ctx.super.iter_init(list, patterns, 0);
-       while ((info = ilist->module_ctx.super.iter_next(iter)) != NULL) {
-               flags = 0;
-               if ((info->flags & MAILBOX_NONEXISTENT) != 0)
-                       flags |= MAILBOX_LIST_INDEX_FLAG_NONEXISTENT;
-               if ((info->flags & MAILBOX_NOSELECT) != 0)
-                       flags |= MAILBOX_LIST_INDEX_FLAG_NOSELECT;
-               if ((info->flags & MAILBOX_NOINFERIORS) != 0)
-                       flags |= MAILBOX_LIST_INDEX_FLAG_NOINFERIORS;
-
-               T_BEGIN {
-                       const char *name =
-                               mailbox_list_get_storage_name(info->ns->list,
-                                                             info->name);
-                       seq = mailbox_list_index_sync_name(&sync_ctx,
-                                                          name, flags);
-               } T_END;
-
-               mail_index_update_flags(sync_ctx.trans, seq,
-                                       MODIFY_REPLACE, (enum mail_flags)flags);
-       }
-       if (ilist->module_ctx.super.iter_deinit(iter) < 0)
-               ret = -1;
-
-       if (ret < 0) {
-               mail_index_sync_rollback(&sync_ctx.sync_ctx);
-               return -1;
-       }
-
-       mailbox_list_index_nodes_expunge(&sync_ctx, ilist->mailbox_tree);
-
-       if (orig_highest_name_id != ilist->highest_name_id) {
-               /* new names added */
-               T_BEGIN {
-                       mailbox_list_index_sync_names(&sync_ctx);
-               } T_END;
-       } else {
-               struct mailbox_list_index_header new_hdr;
-
-               new_hdr.refresh_flag = 0;
-               mail_index_update_header_ext(sync_ctx.trans, ilist->ext_id,
-                       offsetof(struct mailbox_list_index_header, refresh_flag),
-                       &new_hdr.refresh_flag, sizeof(new_hdr.refresh_flag));
-       }
-
-       return mail_index_sync_commit(&sync_ctx.sync_ctx);
-}
-
 static int mailbox_list_index_parse_header(struct mailbox_list_index *ilist,
                                           struct mail_index_view *view)
 {
@@ -457,8 +158,8 @@ static int mailbox_list_index_parse_records(struct mailbox_list_index *ilist,
        return 0;
 }
 
-static int mailbox_list_index_read(struct mailbox_list_index *ilist,
-                                  struct mail_index_view *view, bool force)
+int mailbox_list_index_read(struct mailbox_list_index *ilist,
+                           struct mail_index_view *view, bool force)
 {
        const struct mail_index_header *hdr;
        int ret;
index aac0fbab4b46c3a1ef1db7f4e9082dd7a9929f66..35ca37493c20faebce3580de10ee75b3b3e57d53 100644 (file)
@@ -9,6 +9,9 @@
 #define INDEX_LIST_CONTEXT(obj) \
        MODULE_CONTEXT(obj, mailbox_list_index_module)
 
+struct mail_index_view;
+struct mailbox;
+
 /* stored in mail_index_record.flags: */
 enum mailbox_list_index_flags {
        MAILBOX_LIST_INDEX_FLAG_NONEXISTENT = MAIL_DELETED,
@@ -102,6 +105,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_index_node *
+mailbox_list_index_node_find_sibling(struct mailbox_list_index_node *node,
+                                    const char *name);
+void mailbox_list_index_reset(struct mailbox_list_index *ilist);
+int mailbox_list_index_read(struct mailbox_list_index *ilist,
+                           struct mail_index_view *view, bool force);
+int mailbox_list_index_sync(struct mailbox_list *list);
+
 struct mailbox_list_iterate_context *
 mailbox_list_index_iter_init(struct mailbox_list *list,
                             const char *const *patterns,