From d4706609e70c9569acbef2c0d8e7fda5ab3cfa4e Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Thu, 8 Feb 2018 16:53:15 +0200 Subject: [PATCH] lib-index: Add mail_index_transaction_commit_result.changes_mask This can be used to determine what type of changes were committed in a transaction. --- src/lib-index/mail-index-transaction-export.c | 29 +++++++++++++++++-- .../mail-index-transaction-private.h | 3 +- src/lib-index/mail-index-transaction.c | 10 +++++-- src/lib-index/mail-index.h | 12 ++++++++ 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/lib-index/mail-index-transaction-export.c b/src/lib-index/mail-index-transaction-export.c index a3d29e807c..0d59b4d352 100644 --- a/src/lib-index/mail-index-transaction-export.c +++ b/src/lib-index/mail-index-transaction-export.c @@ -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 = diff --git a/src/lib-index/mail-index-transaction-private.h b/src/lib-index/mail-index-transaction-private.h index 3ba24b1872..eb438b2f2a 100644 --- a/src/lib-index/mail-index-transaction-private.h +++ b/src/lib-index/mail-index-transaction-private.h @@ -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 diff --git a/src/lib-index/mail-index-transaction.c b/src/lib-index/mail-index-transaction.c index 14f890b3c7..d2ec42b83b 100644 --- a/src/lib-index/mail-index-transaction.c +++ b/src/lib-index/mail-index-transaction.c @@ -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); diff --git a/src/lib-index/mail-index.h b/src/lib-index/mail-index.h index 6ced7e7ced..8add21b748 100644 --- a/src/lib-index/mail-index.h +++ b/src/lib-index/mail-index.h @@ -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; }; -- 2.47.3