]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
View sync returns now also hidden records, but they're marked as such.
authorTimo Sirainen <tss@iki.fi>
Sat, 15 Mar 2008 06:45:04 +0000 (08:45 +0200)
committerTimo Sirainen <tss@iki.fi>
Sat, 15 Mar 2008 06:45:04 +0000 (08:45 +0200)
Mailbox syncing returns hidden records as modseq changes.

--HG--
branch : HEAD

src/lib-index/mail-index-view-sync.c
src/lib-index/mail-index.h
src/lib-storage/index/index-sync.c

index 21d3223b6321b93b367d4f1ccb730a4c7b897e7c..7709a41fc9dd5abaa008e9890df55539beca0ab4 100644 (file)
@@ -27,6 +27,7 @@ struct mail_index_view_sync_ctx {
        unsigned int sync_map_update:1;
        unsigned int skipped_expunges:1;
        unsigned int last_read:1;
+       unsigned int hidden:1;
 };
 
 static int
@@ -447,7 +448,7 @@ mail_index_view_sync_get_next_transaction(struct mail_index_view_sync_ctx *ctx)
        int ret;
        bool synced_to_map;
 
-       for (;;) {
+       do {
                /* Get the next transaction from log. */
                ret = mail_transaction_log_view_next(log_view, &ctx->hdr,
                                                     &ctx->data);
@@ -461,43 +462,34 @@ mail_index_view_sync_get_next_transaction(struct mail_index_view_sync_ctx *ctx)
                }
 
                hdr = ctx->hdr;
-               if (!mail_index_view_sync_want(ctx, hdr)) {
-                       /* This is a visible record that we don't want to
-                          sync. */
-                       continue;
-               }
-
-               mail_transaction_log_view_get_prev_pos(log_view, &seq, &offset);
-
-               /* If we started from a map that we didn't create ourself,
-                  some of the transactions may already be synced. at the end
-                  of this view sync we'll update file_seq=0 so that this check
-                  always becomes FALSE for subsequent syncs. */
-               synced_to_map = view->map->hdr.log_file_seq != 0 &&
-                       LOG_IS_BEFORE(seq, offset,
-                                     view->map->hdr.log_file_seq,
-                                     view->map->hdr.log_file_head_offset);
-
-               /* Apply transaction to view's mapping if needed (meaning we
-                  didn't just re-map the view to head mapping). */
-               if (ctx->sync_map_update && !synced_to_map) {
-                       i_assert((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0 ||
-                                (hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0);
-
-                       T_BEGIN {
-                               ret = mail_index_sync_record(&ctx->sync_map_ctx,
-                                                            hdr, ctx->data);
-                       } T_END;
-                       if (ret < 0)
-                               return -1;
-               }
-
-               /* skip changes committed by hidden transactions (eg. in IMAP
-                  store +flags.silent command) */
-               if (view_sync_is_hidden(view, seq, offset))
-                       continue;
-               break;
+               /* skip records we've already synced */
+       } while (!mail_index_view_sync_want(ctx, hdr));
+
+       mail_transaction_log_view_get_prev_pos(log_view, &seq, &offset);
+
+       /* If we started from a map that we didn't create ourself,
+          some of the transactions may already be synced. at the end
+          of this view sync we'll update file_seq=0 so that this check
+          always becomes FALSE for subsequent syncs. */
+       synced_to_map = view->map->hdr.log_file_seq != 0 &&
+               LOG_IS_BEFORE(seq, offset, view->map->hdr.log_file_seq,
+                             view->map->hdr.log_file_head_offset);
+
+       /* Apply transaction to view's mapping if needed (meaning we
+          didn't just re-map the view to head mapping). */
+       if (ctx->sync_map_update && !synced_to_map) {
+               i_assert((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0 ||
+                        (hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0);
+
+               T_BEGIN {
+                       ret = mail_index_sync_record(&ctx->sync_map_ctx,
+                                                    hdr, ctx->data);
+               } T_END;
+               if (ret < 0)
+                       return -1;
        }
+
+       ctx->hidden = view_sync_is_hidden(view, seq, offset);
        return 1;
 }
 
@@ -597,6 +589,8 @@ mail_index_view_sync_get_rec(struct mail_index_view_sync_ctx *ctx,
                ctx->hdr = NULL;
                return FALSE;
        }
+
+       rec->hidden = ctx->hidden;
        return TRUE;
 }
 
index aa176e97814c531963118c6fb6f511e59077a5d6..909d3cc7c04e13460e24b8d6ecef0f9ee402e4ea 100644 (file)
@@ -103,8 +103,8 @@ struct mail_keywords {
 };
 
 enum mail_index_transaction_flags {
-       /* If transaction is marked as hidden, the changes won't be listed
-          when the view is synchronized. */
+       /* If transaction is marked as hidden, the changes are marked with
+          hidden=TRUE when the view is synchronized. */
        MAIL_INDEX_TRANSACTION_FLAG_HIDE                = 0x01,
        /* External transactions describe changes to mailbox that have already
           happened. */
@@ -162,6 +162,9 @@ struct mail_index_view_sync_rec {
        /* keyword appends and removes are packed into one and same
           MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD */
        enum mail_index_sync_type type;
+
+       /* TRUE if this was a hidden transaction. */
+       unsigned int hidden:1;
 };
 
 struct mail_index;
index bb0302d58cca54c14a9eaee877a471e92716907b..4db29b4ab6eae5b73c1f2fa35a3ccea8ebdd748c 100644 (file)
@@ -14,8 +14,9 @@ struct index_mailbox_sync_context {
        uint32_t messages_count;
 
        ARRAY_TYPE(seq_range) flag_updates;
+       ARRAY_TYPE(seq_range) modseq_updates;
        const ARRAY_TYPE(seq_range) *expunges;
-       unsigned int flag_update_pos, expunge_pos;
+       unsigned int flag_update_idx, modseq_update_idx, expunge_pos;
 
        bool failed;
 };
@@ -113,6 +114,8 @@ static void index_view_sync_recs_get(struct index_mailbox_sync_context *ctx)
        uint32_t seq1, seq2;
 
        i_array_init(&ctx->flag_updates, 128);
+       if ((ctx->ibox->box.enabled_features & MAILBOX_FEATURE_CONDSTORE) != 0)
+               i_array_init(&ctx->modseq_updates, 32);
        while (mail_index_view_sync_next(ctx->sync_ctx, &sync)) {
                switch (sync.type) {
                case MAIL_INDEX_SYNC_TYPE_APPEND:
@@ -125,20 +128,35 @@ static void index_view_sync_recs_get(struct index_mailbox_sync_context *ctx)
                case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD:
                case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE:
                case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET:
-                       if (mail_index_lookup_seq_range(ctx->ibox->view,
+                       if (!mail_index_lookup_seq_range(ctx->ibox->view,
                                                        sync.uid1, sync.uid2,
-                                                       &seq1, &seq2)) {
+                                                        &seq1, &seq2))
+                               break;
+
+                       if (!sync.hidden) {
                                seq_range_array_add_range(&ctx->flag_updates,
                                                          seq1, seq2);
+                       } else if (array_is_created(&ctx->modseq_updates)) {
+                               seq_range_array_add_range(&ctx->modseq_updates,
+                                                         seq1, seq2);
                        }
                        break;
                }
        }
 
-       /* remove expunged messages from flag updates */
+       /* remove expunged messages from flag/modseq updates */
        if (ctx->expunges != NULL) {
                seq_range_array_remove_seq_range(&ctx->flag_updates,
                                                 ctx->expunges);
+               if (array_is_created(&ctx->modseq_updates)) {
+                       seq_range_array_remove_seq_range(&ctx->modseq_updates,
+                                                        ctx->expunges);
+               }
+       }
+       /* remove flag updates from modseq updates */
+       if (array_is_created(&ctx->modseq_updates)) {
+               seq_range_array_remove_seq_range(&ctx->modseq_updates,
+                                                &ctx->flag_updates);
        }
 }
 
@@ -215,20 +233,30 @@ bool index_mailbox_sync_next(struct mailbox_sync_context *_ctx,
 {
        struct index_mailbox_sync_context *ctx =
                (struct index_mailbox_sync_context *)_ctx;
-       const struct seq_range *flag_updates;
+       const struct seq_range *range;
        unsigned int count;
 
        if (ctx->failed)
                return FALSE;
 
-       flag_updates = array_get(&ctx->flag_updates, &count);
-       if (ctx->flag_update_pos < count) {
+       range = array_get(&ctx->flag_updates, &count);
+       if (ctx->flag_update_idx < count) {
                sync_rec_r->type = MAILBOX_SYNC_TYPE_FLAGS;
-               sync_rec_r->seq1 = flag_updates[ctx->flag_update_pos].seq1;
-               sync_rec_r->seq2 = flag_updates[ctx->flag_update_pos].seq2;
-               ctx->flag_update_pos++;
+               sync_rec_r->seq1 = range[ctx->flag_update_idx].seq1;
+               sync_rec_r->seq2 = range[ctx->flag_update_idx].seq2;
+               ctx->flag_update_idx++;
                return 1;
        }
+       if (array_is_created(&ctx->modseq_updates)) {
+               range = array_get(&ctx->modseq_updates, &count);
+               if (ctx->modseq_update_idx < count) {
+                       sync_rec_r->type = MAILBOX_SYNC_TYPE_MODSEQ;
+                       sync_rec_r->seq1 = range[ctx->modseq_update_idx].seq1;
+                       sync_rec_r->seq2 = range[ctx->modseq_update_idx].seq2;
+                       ctx->modseq_update_idx++;
+                       return 1;
+               }
+       }
 
        return index_mailbox_sync_next_expunge(ctx, sync_rec_r);
 }
@@ -336,6 +364,8 @@ int index_mailbox_sync_deinit(struct mailbox_sync_context *_ctx,
 
        if (array_is_created(&ctx->flag_updates))
                array_free(&ctx->flag_updates);
+       if (array_is_created(&ctx->modseq_updates))
+               array_free(&ctx->modseq_updates);
        i_free(ctx);
        return ret;
 }