mail-index-sync.c revision 4f22fc1d063d48ed368b4cb124b44183bc27773c
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher/* Copyright (C) 2003-2004 Timo Sirainen */
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher#include "lib.h"
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher#include "buffer.h"
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher#include "mail-index-view-private.h"
2cb6f28b3a12bb714bf14494d31eb6b6fff64b8bJakub Hrozek#include "mail-index-sync-private.h"
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher#include "mail-transaction-log.h"
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher#include "mail-transaction-util.h"
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher#include <stdlib.h>
7465d6a1ef6e83825dba3a4dc4dda7271671aba0Jakub Hrozek
ad805face83ba7d67b1cf2067a1982c7e63d1060Jakub Hrozekstatic void mail_index_sync_sort_flags(struct mail_index_sync_ctx *ctx)
ad805face83ba7d67b1cf2067a1982c7e63d1060Jakub Hrozek{
a7797068c4deb6ce2bdbcda27c45ff1bbb4a8e78Jakub Hrozek const struct mail_transaction_flag_update *src, *src_end;
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher const struct mail_transaction_flag_update *dest;
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher struct mail_transaction_flag_update new_update;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher struct mail_transaction_expunge_traverse_ctx *exp_ctx;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher uint32_t last;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher size_t i, dest_count;
7a14e8f66c0e932fe2954d792614a3b61d444bd1Jakub Hrozek
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozek src = ctx->data;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher src_end = PTR_OFFSET(src, ctx->hdr->size);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher dest = buffer_get_data(ctx->updates_buf, &dest_count);
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek dest_count /= sizeof(*dest);
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek exp_ctx = mail_transaction_expunge_traverse_init(ctx->expunges_buf);
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek for (i = 0; src != src_end; src++) {
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek new_update = *src;
261cdde02b40aa8dabb3d69e43586a5a220647e9Jakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek /* find seq1 */
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek new_update.seq1 +=
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek mail_transaction_expunge_traverse_to(exp_ctx,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher src->seq1);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher /* find seq2 */
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher new_update.seq2 +=
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher mail_transaction_expunge_traverse_to(exp_ctx,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher src->seq2);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher /* insert it into buffer, split it in multiple parts if needed
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher to make sure the ordering stays the same */
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek for (; i < dest_count; i++) {
261cdde02b40aa8dabb3d69e43586a5a220647e9Jakub Hrozek if (dest[i].seq1 <= new_update.seq1)
261cdde02b40aa8dabb3d69e43586a5a220647e9Jakub Hrozek continue;
261cdde02b40aa8dabb3d69e43586a5a220647e9Jakub Hrozek
261cdde02b40aa8dabb3d69e43586a5a220647e9Jakub Hrozek if (dest[i].seq1 > new_update.seq2)
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek break;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher /* partial */
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher last = new_update.seq2;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher new_update.seq2 = dest[i].seq1-1;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher buffer_insert(ctx->updates_buf, i * sizeof(new_update),
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher &new_update, sizeof(new_update));
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher dest = buffer_get_data(ctx->updates_buf, NULL);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher dest_count++;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher new_update.seq1 = new_update.seq2+1;
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher new_update.seq2 = last;
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher }
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher buffer_insert(ctx->updates_buf, i * sizeof(new_update),
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher &new_update, sizeof(new_update));
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher dest = buffer_get_data(ctx->updates_buf, NULL);
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher dest_count++;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher }
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher mail_transaction_expunge_traverse_deinit(exp_ctx);
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek}
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozekstatic void mail_index_sync_sort_transaction(struct mail_index_sync_ctx *ctx)
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek{
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek switch (ctx->hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek case MAIL_TRANSACTION_EXPUNGE:
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek if (buffer_get_used_size(ctx->expunges_buf) == 0) {
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek buffer_append(ctx->expunges_buf, ctx->data,
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek ctx->hdr->size);
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek } else {
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek mail_transaction_log_sort_expunges(ctx->expunges_buf,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher ctx->data,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher ctx->hdr->size);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher }
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher break;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher case MAIL_TRANSACTION_FLAG_UPDATE:
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher if (buffer_get_used_size(ctx->expunges_buf) == 0 &&
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher buffer_get_used_size(ctx->updates_buf) == 0) {
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher buffer_append(ctx->updates_buf, ctx->data,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher ctx->hdr->size);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher } else {
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher mail_index_sync_sort_flags(ctx);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher }
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher break;
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek case MAIL_TRANSACTION_APPEND:
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher buffer_append(ctx->appends_buf, ctx->data, ctx->hdr->size);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher ctx->sync_appends = TRUE;
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek break;
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek }
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher}
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagherstatic int mail_index_sync_read_and_sort(struct mail_index_sync_ctx *ctx,
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher int external)
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher{
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher enum mail_transaction_type flag;
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher size_t size;
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher int ret;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher flag = external ? MAIL_TRANSACTION_EXTERNAL : 0;
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher while ((ret = mail_transaction_log_view_next(ctx->view->log_view,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher &ctx->hdr,
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher &ctx->data, NULL)) > 0) {
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher if ((ctx->hdr->type & MAIL_TRANSACTION_EXTERNAL) == flag)
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher mail_index_sync_sort_transaction(ctx);
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher }
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher ctx->expunges = buffer_get_data(ctx->expunges_buf, &size);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher ctx->expunges_count = size / sizeof(*ctx->expunges);
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher ctx->updates = buffer_get_data(ctx->updates_buf, &size);
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher ctx->updates_count = size / sizeof(*ctx->updates);
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher return ret;
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher}
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagherstatic int mail_index_need_lock(struct mail_index *index,
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher uint32_t log_file_seq, uoff_t log_file_offset)
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher{
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher if (index->hdr->log_file_seq > log_file_seq ||
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher (index->hdr->log_file_seq == log_file_seq &&
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher index->hdr->log_file_offset >= log_file_offset)) {
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher /* already synced */
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher return 0;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher }
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher return 1;
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher}
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagherint mail_index_sync_begin(struct mail_index *index,
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher struct mail_index_sync_ctx **ctx_r,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher struct mail_index_view **view_r,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher uint32_t log_file_seq, uoff_t log_file_offset)
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher{
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher struct mail_index_sync_ctx *ctx;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher uint32_t seq;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher uoff_t offset;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher unsigned int lock_id;
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek if (mail_transaction_log_sync_lock(index->log, &seq, &offset) < 0)
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek return -1;
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek if (mail_index_lock_shared(index, TRUE, &lock_id) < 0) {
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher mail_transaction_log_sync_unlock(index->log);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher return -1;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher }
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek if (mail_index_map(index, FALSE) <= 0) {
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek mail_transaction_log_sync_unlock(index->log);
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek mail_index_unlock(index, lock_id);
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek return -1;
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek }
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher if (!mail_index_need_lock(index, log_file_seq, log_file_offset)) {
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher mail_index_unlock(index, lock_id);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher mail_transaction_log_sync_unlock(index->log);
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek return 0;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher }
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher ctx = i_new(struct mail_index_sync_ctx, 1);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher ctx->index = index;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher ctx->lock_id = lock_id;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher ctx->view = mail_index_view_open(index);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher ctx->view->external = TRUE;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher if (mail_transaction_log_view_set(ctx->view->log_view,
531661c7bb54eb71853977a64cb30f80c20b963eJakub Hrozek index->hdr->log_file_seq,
be5cc3c013ece0c957f2f8c28a217052227dfd07Jakub Hrozek index->hdr->log_file_offset,
be5cc3c013ece0c957f2f8c28a217052227dfd07Jakub Hrozek seq, offset,
be5cc3c013ece0c957f2f8c28a217052227dfd07Jakub Hrozek MAIL_TRANSACTION_TYPE_MASK) < 0) {
be5cc3c013ece0c957f2f8c28a217052227dfd07Jakub Hrozek mail_index_sync_end(ctx, 0, 0);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher return -1;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher }
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher /* we need to have all the transactions sorted to optimize
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher caller's mailbox access patterns */
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher ctx->expunges_buf = buffer_create_dynamic(default_pool,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher 1024, (size_t)-1);
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher ctx->updates_buf = buffer_create_dynamic(default_pool,
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher 1024, (size_t)-1);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher ctx->appends_buf = buffer_create_dynamic(default_pool,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher 1024, (size_t)-1);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher if (mail_index_sync_read_and_sort(ctx, FALSE) < 0) {
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher mail_index_sync_end(ctx, 0, 0);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher return -1;
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher }
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher *ctx_r = ctx;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher *view_r = ctx->view;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher return 1;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher}
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallaghervoid
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallaghermail_index_sync_get_expunge(struct mail_index_sync_rec *rec,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher const struct mail_transaction_expunge *exp)
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher{
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher rec->type = MAIL_INDEX_SYNC_TYPE_EXPUNGE;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher rec->seq1 = exp->seq1;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher rec->seq2 = exp->seq2;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher}
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallaghervoid
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallaghermail_index_sync_get_update(struct mail_index_sync_rec *rec,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher const struct mail_transaction_flag_update *update)
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher{
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher rec->type = MAIL_INDEX_SYNC_TYPE_FLAGS;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher rec->seq1 = update->seq1;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher rec->seq2 = update->seq2;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher rec->add_flags = update->add_flags;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher memcpy(rec->add_keywords, update->add_keywords,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher sizeof(rec->add_keywords));
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher rec->remove_flags = update->remove_flags;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher memcpy(rec->remove_keywords, update->remove_keywords,
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher sizeof(rec->remove_keywords));
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher}
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagherstatic int mail_index_sync_rec_check(struct mail_index_view *view,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher struct mail_index_sync_rec *rec)
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher{
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher uint32_t message_count;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher switch (rec->type) {
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher case MAIL_INDEX_SYNC_TYPE_EXPUNGE:
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek case MAIL_INDEX_SYNC_TYPE_FLAGS:
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek if (rec->seq1 > rec->seq2 || rec->seq1 == 0) {
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek mail_transaction_log_view_set_corrupted(view->log_view,
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek "Broken sequence: %u..%u (type 0x%x)",
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek rec->seq1, rec->seq2, rec->type);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek return FALSE;
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek }
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek message_count = mail_index_view_get_message_count(view);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek if (rec->seq2 > message_count) {
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek mail_transaction_log_view_set_corrupted(view->log_view,
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek "Sequence out of range: %u > %u (type 0x%x)",
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek rec->seq2, message_count, rec->type);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek return FALSE;
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek }
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek break;
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek case MAIL_INDEX_SYNC_TYPE_APPEND:
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek break;
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek }
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek return TRUE;
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek}
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozekint mail_index_sync_next(struct mail_index_sync_ctx *ctx,
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek struct mail_index_sync_rec *sync_rec)
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek{
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek const struct mail_transaction_expunge *next_exp;
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek const struct mail_transaction_flag_update *next_update;
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek next_exp = ctx->expunge_idx == ctx->expunges_count ? NULL :
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek &ctx->expunges[ctx->expunge_idx];
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek next_update = ctx->update_idx == ctx->updates_count ? NULL :
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek &ctx->updates[ctx->update_idx];
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek // FIXME: return dirty flagged records as flag updates
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek /* the ugliness here is to avoid returning overlapping expunge
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek and update areas. For example:
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek updates[] = A { 1, 7 }, B { 1, 3 }
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek expunges[] = { 5, 6 }
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek will make us return
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek update A: 1, 4
a7797068c4deb6ce2bdbcda27c45ff1bbb4a8e78Jakub Hrozek update B: 1, 3
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek expunge : 5, 6
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek update A: 7, 7
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek */
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek while (next_update != NULL &&
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek (next_exp == NULL || next_update->seq1 < next_exp->seq1)) {
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek if (next_update->seq2 >= ctx->next_seq) {
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek mail_index_sync_get_update(sync_rec, next_update);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek if (next_exp != NULL &&
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek next_exp->seq1 <= next_update->seq2) {
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek /* it's overlapping.. */
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek sync_rec->seq2 = next_exp->seq1-1;
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek }
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek if (sync_rec->seq1 < ctx->next_seq)
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek sync_rec->seq1 = ctx->next_seq;
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek i_assert(sync_rec->seq1 <= sync_rec->seq2);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek ctx->update_idx++;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek return mail_index_sync_rec_check(ctx->view, sync_rec);
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek }
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek if (++ctx->update_idx == ctx->updates_count)
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek break;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek next_update++;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek }
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek if (next_exp != NULL) {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek /* a few sanity checks here, we really don't ever want to
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek accidentally expunge a message. If sequence and UID matches,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek it's quite unlikely this expunge was caused by some bug. */
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek uint32_t uid1, uid2;
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek mail_index_sync_get_expunge(sync_rec, next_exp);
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek if (mail_index_sync_rec_check(ctx->view, sync_rec) < 0)
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek return -1;
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek if (mail_index_lookup_uid(ctx->view, next_exp->seq1, &uid1) < 0)
481ec0e1eb0058195732cb320845b41f6f4d43ebJakub Hrozek return -1;
481ec0e1eb0058195732cb320845b41f6f4d43ebJakub Hrozek if (mail_index_lookup_uid(ctx->view, next_exp->seq2, &uid2) < 0)
481ec0e1eb0058195732cb320845b41f6f4d43ebJakub Hrozek return -1;
481ec0e1eb0058195732cb320845b41f6f4d43ebJakub Hrozek if (next_exp->uid1 != uid1 || next_exp->uid2 != uid2) {
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek mail_transaction_log_view_set_corrupted(
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek ctx->view->log_view, "Expunge range %u..%u: "
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek "UIDs %u..%u doesn't match real UIDs %u..%u",
7465d6a1ef6e83825dba3a4dc4dda7271671aba0Jakub Hrozek next_exp->seq1, next_exp->seq2,
7465d6a1ef6e83825dba3a4dc4dda7271671aba0Jakub Hrozek next_exp->uid1, next_exp->uid2, uid1, uid2);
7465d6a1ef6e83825dba3a4dc4dda7271671aba0Jakub Hrozek return -1;
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek }
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek ctx->expunge_idx++;
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek /* scan updates again from the beginning */
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek ctx->update_idx = 0;
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek ctx->next_seq = next_exp->seq2;
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek return 1;
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek }
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek if (ctx->sync_appends) {
481ec0e1eb0058195732cb320845b41f6f4d43ebJakub Hrozek ctx->sync_appends = FALSE;
481ec0e1eb0058195732cb320845b41f6f4d43ebJakub Hrozek sync_rec->type = MAIL_INDEX_SYNC_TYPE_APPEND;
481ec0e1eb0058195732cb320845b41f6f4d43ebJakub Hrozek sync_rec->seq1 = ctx->index->map->records_count+1;
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek sync_rec->seq2 = sync_rec->seq1-1 +
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek buffer_get_used_size(ctx->appends_buf) /
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek sizeof(struct mail_index_record);
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek sync_rec->appends = buffer_get_data(ctx->appends_buf, NULL);
7465d6a1ef6e83825dba3a4dc4dda7271671aba0Jakub Hrozek return 1;
7465d6a1ef6e83825dba3a4dc4dda7271671aba0Jakub Hrozek }
7465d6a1ef6e83825dba3a4dc4dda7271671aba0Jakub Hrozek
7465d6a1ef6e83825dba3a4dc4dda7271671aba0Jakub Hrozek return 0;
4c9419d98b89a6161a3dde11f9f80be39d12e72aJakub Hrozek}
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozekint mail_index_sync_have_more(struct mail_index_sync_ctx *ctx)
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek{
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek return (ctx->update_idx != ctx->updates_count) ||
7465d6a1ef6e83825dba3a4dc4dda7271671aba0Jakub Hrozek (ctx->expunge_idx != ctx->expunges_count) ||
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek ctx->sync_appends;
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek}
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozekint mail_index_sync_set_dirty(struct mail_index_sync_ctx *ctx, uint32_t seq)
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek{
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek if (ctx->dirty_lock_id == 0) {
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek if (mail_index_lock_exclusive(ctx->index,
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek &ctx->dirty_lock_id) < 0)
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek return -1;
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek }
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek i_assert(seq <= ctx->view->map->records_count);
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek ctx->view->map->records[seq-1].flags |= MAIL_INDEX_MAIL_FLAG_DIRTY;
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek ctx->have_dirty = TRUE;
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek return 0;
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek}
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozekint mail_index_sync_end(struct mail_index_sync_ctx *ctx,
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek uint32_t sync_stamp, uint64_t sync_size)
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek{
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek const struct mail_index_header *hdr;
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek uint32_t seq;
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek uoff_t offset;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek int ret = 0;
7465d6a1ef6e83825dba3a4dc4dda7271671aba0Jakub Hrozek
7465d6a1ef6e83825dba3a4dc4dda7271671aba0Jakub Hrozek if (mail_transaction_log_view_is_corrupted(ctx->view->log_view))
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek ret = -1;
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek mail_transaction_log_get_head(ctx->index->log, &seq, &offset);
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek if (ret == 0) {
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher hdr = ctx->index->hdr;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher mail_transaction_log_view_unset(ctx->view->log_view);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher if (mail_transaction_log_view_set(ctx->view->log_view,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher hdr->log_file_seq, hdr->log_file_offset,
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek seq, offset, MAIL_TRANSACTION_TYPE_MASK) < 0)
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher ret = -1;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher }
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher if (ret == 0) {
7465d6a1ef6e83825dba3a4dc4dda7271671aba0Jakub Hrozek mail_index_sync_read_and_sort(ctx, TRUE);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher if (mail_index_sync_update_index(ctx, sync_stamp,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher sync_size) < 0)
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher ret = -1;
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek }
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher if (ctx->dirty_lock_id == 0)
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher mail_index_unlock(ctx->index, ctx->dirty_lock_id);
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek mail_index_unlock(ctx->index, ctx->lock_id);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher mail_transaction_log_sync_unlock(ctx->index->log);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher mail_index_view_close(ctx->view);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher if (ctx->expunges_buf != NULL)
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher buffer_free(ctx->expunges_buf);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher if (ctx->updates_buf != NULL)
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher buffer_free(ctx->updates_buf);
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher if (ctx->appends_buf != NULL)
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek buffer_free(ctx->appends_buf);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher i_free(ctx);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher return ret;
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher}
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozekvoid mail_index_sync_flags_apply(const struct mail_index_sync_rec *sync_rec,
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher uint8_t *flags, keywords_mask_t keywords)
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozek{
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozek int i;
7465d6a1ef6e83825dba3a4dc4dda7271671aba0Jakub Hrozek
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozek i_assert(sync_rec->type == MAIL_INDEX_SYNC_TYPE_FLAGS);
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher
6b0f9cd2ee601121cb7fe1d9ad8ebce782aa8f39Stephen Gallagher *flags = (*flags & ~sync_rec->remove_flags) | sync_rec->add_flags;
1008001f34abb42df75f840db17f14a83f0c21d4Stephen Gallagher for (i = 0; i < INDEX_KEYWORDS_BYTE_COUNT; i++) {
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek keywords[i] = (keywords[i] & ~sync_rec->remove_keywords[i]) |
056302a92862fda16351d7192600746746f38e5dStephen Gallagher sync_rec->add_keywords[i];
e59e09b5010f262228bbdeb92a79b733bf5854b3Stephen Gallagher }
e59e09b5010f262228bbdeb92a79b733bf5854b3Stephen Gallagher}
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher