]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: Add mail_index_transaction_commit_result.changes_mask
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 8 Feb 2018 14:53:15 +0000 (16:53 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Tue, 13 Feb 2018 12:33:12 +0000 (14:33 +0200)
This can be used to determine what type of changes were committed in a
transaction.

src/lib-index/mail-index-transaction-export.c
src/lib-index/mail-index-transaction-private.h
src/lib-index/mail-index-transaction.c
src/lib-index/mail-index.h

index a3d29e807c6a832828240544a3c57680e977af30..0d59b4d35238bdbe4607aa3548d53a96cf2a10c8 100644 (file)
@@ -411,12 +411,15 @@ log_append_keyword_updates(struct mail_index_export_context *ctx)
 }
 
 void mail_index_transaction_export(struct mail_index_transaction *t,
-                                  struct mail_transaction_log_append_ctx *append_ctx)
+                                  struct mail_transaction_log_append_ctx *append_ctx,
+                                  enum mail_index_transaction_change *changes_r)
 {
        static uint8_t null4[4] = { 0, 0, 0, 0 };
        enum mail_index_fsync_mask change_mask = 0;
        struct mail_index_export_context ctx;
 
+       *changes_r = 0;
+
        i_zero(&ctx);
        ctx.trans = t;
        ctx.append_ctx = append_ctx;
@@ -435,6 +438,10 @@ void mail_index_transaction_export(struct mail_index_transaction *t,
                log_append_buffer(&ctx, log_get_hdr_update_buffer(t, TRUE),
                                  MAIL_TRANSACTION_HEADER_UPDATE);
        }
+
+       if (append_ctx->output->used > 0)
+               *changes_r |= MAIL_INDEX_TRANSACTION_CHANGE_OTHERS;
+
        if (t->attribute_updates != NULL) {
                buffer_append_c(t->attribute_updates, '\0');
                /* need to have 32bit alignment */
@@ -447,35 +454,43 @@ void mail_index_transaction_export(struct mail_index_transaction *t,
                              t->attribute_updates_suffix->data,
                              t->attribute_updates_suffix->used);
                i_assert(t->attribute_updates->used % 4 == 0);
+               *changes_r |= MAIL_INDEX_TRANSACTION_CHANGE_ATTRIBUTE;
                log_append_buffer(&ctx, t->attribute_updates,
                                  MAIL_TRANSACTION_ATTRIBUTE_UPDATE);
        }
        if (array_is_created(&t->appends)) {
                change_mask |= MAIL_INDEX_FSYNC_MASK_APPENDS;
+               *changes_r |= MAIL_INDEX_TRANSACTION_CHANGE_APPEND;
                log_append_buffer(&ctx, t->appends.arr.buffer,
                                  MAIL_TRANSACTION_APPEND);
        }
 
        if (array_is_created(&t->updates)) {
                change_mask |= MAIL_INDEX_FSYNC_MASK_FLAGS;
+               *changes_r |= MAIL_INDEX_TRANSACTION_CHANGE_FLAGS;
                log_append_flag_updates(&ctx, t);
        }
 
        if (array_is_created(&t->ext_rec_updates)) {
+               *changes_r |= MAIL_INDEX_TRANSACTION_CHANGE_OTHERS;
                log_append_ext_recs(&ctx, &t->ext_rec_updates,
                                    MAIL_TRANSACTION_EXT_REC_UPDATE);
        }
        if (array_is_created(&t->ext_rec_atomics)) {
+               *changes_r |= MAIL_INDEX_TRANSACTION_CHANGE_OTHERS;
                log_append_ext_recs(&ctx, &t->ext_rec_atomics,
                                    MAIL_TRANSACTION_EXT_ATOMIC_INC);
        }
 
        if (array_is_created(&t->keyword_updates)) {
-               if (log_append_keyword_updates(&ctx))
+               if (log_append_keyword_updates(&ctx)) {
                        change_mask |= MAIL_INDEX_FSYNC_MASK_KEYWORDS;
+                       *changes_r |= MAIL_INDEX_TRANSACTION_CHANGE_KEYWORDS;
+               }
        }
        /* keep modseq updates almost last */
        if (array_is_created(&t->modseq_updates)) {
+               *changes_r |= MAIL_INDEX_TRANSACTION_CHANGE_MODSEQ;
                log_append_buffer(&ctx, t->modseq_updates.arr.buffer,
                                  MAIL_TRANSACTION_MODSEQ_UPDATE);
        }
@@ -483,24 +498,32 @@ void mail_index_transaction_export(struct mail_index_transaction *t,
        if (array_is_created(&t->expunges)) {
                /* non-external expunges are only requests, ignore them when
                   checking fsync_mask */
-               if ((t->flags & MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL) != 0)
+               if ((t->flags & MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL) != 0) {
                        change_mask |= MAIL_INDEX_FSYNC_MASK_EXPUNGES;
+                       *changes_r |= MAIL_INDEX_TRANSACTION_CHANGE_EXPUNGE;
+               } else {
+                       *changes_r |= MAIL_INDEX_TRANSACTION_CHANGE_OTHERS;
+               }
                log_append_buffer(&ctx, t->expunges.arr.buffer,
                                  MAIL_TRANSACTION_EXPUNGE_GUID);
        }
 
        if (t->post_hdr_changed) {
+               *changes_r |= MAIL_INDEX_TRANSACTION_CHANGE_OTHERS;
                log_append_buffer(&ctx, log_get_hdr_update_buffer(t, FALSE),
                                  MAIL_TRANSACTION_HEADER_UPDATE);
        }
 
        if (t->index_deleted) {
                i_assert(!t->index_undeleted);
+               *changes_r |= MAIL_INDEX_TRANSACTION_CHANGE_OTHERS;
                mail_transaction_log_append_add(ctx.append_ctx,
                                                MAIL_TRANSACTION_INDEX_DELETED,
                                                &null4, 4);
        }
 
+       i_assert((append_ctx->output->used > 0) == (*changes_r != 0));
+
        append_ctx->index_sync_transaction = t->sync_transaction;
        append_ctx->tail_offset_changed = t->tail_offset_changed;
        append_ctx->want_fsync =
index 3ba24b18729702677dc6b32dd59af196cbf6d80a..eb438b2f2ab3d1088fbe1281cc2fde1fa915bdc6 100644 (file)
@@ -149,7 +149,8 @@ void mail_index_transaction_seq_range_to_uid(struct mail_index_transaction *t,
 void mail_index_transaction_finish_so_far(struct mail_index_transaction *t);
 void mail_index_transaction_finish(struct mail_index_transaction *t);
 void mail_index_transaction_export(struct mail_index_transaction *t,
-                                  struct mail_transaction_log_append_ctx *append_ctx);
+                                  struct mail_transaction_log_append_ctx *append_ctx,
+                                  enum mail_index_transaction_change *changes_r);
 int mail_transaction_expunge_guid_cmp(const struct mail_transaction_expunge_guid *e1,
                                      const struct mail_transaction_expunge_guid *e2);
 unsigned int
index 14f890b3c740079a9522a209c3967200d6234abe..d2ec42b83bd123ad3eaf272d8baca4fa49026be8 100644 (file)
@@ -172,7 +172,8 @@ mail_transaction_log_file_refresh(struct mail_index_transaction *t,
 
 static int
 mail_index_transaction_commit_real(struct mail_index_transaction *t,
-                                  uoff_t *commit_size_r)
+                                  uoff_t *commit_size_r,
+                                  enum mail_index_transaction_change *changes_r)
 {
        struct mail_transaction_log *log = t->view->index->log;
        struct mail_transaction_log_append_ctx *ctx;
@@ -181,6 +182,8 @@ mail_index_transaction_commit_real(struct mail_index_transaction *t,
        uoff_t log_offset1, log_offset2;
        int ret;
 
+       *changes_r = 0;
+
        if ((t->flags & MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL) != 0)
                trans_flags |= MAIL_TRANSACTION_EXTERNAL;
        if ((t->flags & MAIL_INDEX_TRANSACTION_FLAG_SYNC) != 0)
@@ -195,7 +198,7 @@ mail_index_transaction_commit_real(struct mail_index_transaction *t,
 #endif
        if (ret > 0) T_BEGIN {
                mail_index_transaction_finish(t);
-               mail_index_transaction_export(t, ctx);
+               mail_index_transaction_export(t, ctx, changes_r);
        } T_END;
 
        mail_transaction_log_get_head(log, &log_seq1, &log_offset1);
@@ -237,7 +240,8 @@ static int mail_index_transaction_commit_v(struct mail_index_transaction *t,
 
        changed = MAIL_INDEX_TRANSACTION_HAS_CHANGES(t) || t->reset;
        ret = !changed ? 0 :
-               mail_index_transaction_commit_real(t, &result_r->commit_size);
+               mail_index_transaction_commit_real(t, &result_r->commit_size,
+                                                  &result_r->changes_mask);
        mail_transaction_log_get_head(index->log, &result_r->log_file_seq,
                                      &result_r->log_file_offset);
 
index 6ced7e7ced69b3c7114bd59b8d0bf37cb46e808b..8add21b74826440b20398f623124252bf30b4228 100644 (file)
@@ -226,6 +226,17 @@ struct mail_index_view_sync_rec {
        bool hidden:1;
 };
 
+enum mail_index_transaction_change {
+       MAIL_INDEX_TRANSACTION_CHANGE_APPEND    = BIT(0),
+       MAIL_INDEX_TRANSACTION_CHANGE_EXPUNGE   = BIT(1),
+       MAIL_INDEX_TRANSACTION_CHANGE_FLAGS     = BIT(2),
+       MAIL_INDEX_TRANSACTION_CHANGE_KEYWORDS  = BIT(3),
+       MAIL_INDEX_TRANSACTION_CHANGE_MODSEQ    = BIT(4),
+       MAIL_INDEX_TRANSACTION_CHANGE_ATTRIBUTE = BIT(5),
+
+       MAIL_INDEX_TRANSACTION_CHANGE_OTHERS    = BIT(30),
+};
+
 struct mail_index_transaction_commit_result {
        /* seq/offset points to end of transaction */
        uint32_t log_file_seq;
@@ -234,6 +245,7 @@ struct mail_index_transaction_commit_result {
           all of it was written to the same file. */
        uoff_t commit_size;
 
+       enum mail_index_transaction_change changes_mask;
        unsigned int ignored_modseq_changes;
 };