mail-index-sync.c revision 5238fe9419d071cfbee6f3ff8f2411541e95537d
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (C) 2003-2004 Timo Sirainen */
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainenstatic void mail_index_sync_add_expunge(struct mail_index_sync_ctx *ctx)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen const struct mail_transaction_expunge *e = ctx->data;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen for (i = 0; i < size; i++) {
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen for (uid = e[i].uid1; uid <= e[i].uid2; uid++)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainenstatic void mail_index_sync_add_flag_update(struct mail_index_sync_ctx *ctx)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen const struct mail_transaction_flag_update *u = ctx->data;
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen for (i = 0; i < size; i++) {
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (u[i].add_flags != 0) {
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (u[i].remove_flags != 0) {
62c05ba0290a0bf9c2b0ab4ce117f9a736907c21Timo Sirainenstatic void mail_index_sync_add_keyword_update(struct mail_index_sync_ctx *ctx)
62c05ba0290a0bf9c2b0ab4ce117f9a736907c21Timo Sirainen const struct mail_transaction_keyword_update *u = ctx->data;
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen keyword_names[0] = t_strndup(u + 1, u->name_size);
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen keywords = mail_index_keywords_create(ctx->trans, keyword_names);
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen size = (ctx->hdr->size - uidset_offset) / sizeof(uint32_t);
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen /* FIXME: mail_index_update_keywords_range() */
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen for (uid = uids[i]; uid <= uids[i+1]; uid++) {
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainenstatic void mail_index_sync_add_keyword_reset(struct mail_index_sync_ctx *ctx)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen const struct mail_transaction_keyword_reset *u = ctx->data;
ef4661aec4031e24944175ab914dc60942a2b68aTimo Sirainen keywords = mail_index_keywords_create(ctx->trans, NULL);
ef4661aec4031e24944175ab914dc60942a2b68aTimo Sirainen for (i = 0; i < size; i++) {
ef4661aec4031e24944175ab914dc60942a2b68aTimo Sirainen for (uid = u[i].uid1; uid <= u[i].uid2; uid++) {
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainenstatic void mail_index_sync_add_append(struct mail_index_sync_ctx *ctx)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen const struct mail_index_record *rec = ctx->data;
62c05ba0290a0bf9c2b0ab4ce117f9a736907c21Timo Sirainen if (ctx->append_uid_first == 0 || rec->uid < ctx->append_uid_first)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen rec = CONST_PTR_OFFSET(ctx->data, ctx->hdr->size - sizeof(*rec));
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainenstatic void mail_index_sync_add_transaction(struct mail_index_sync_ctx *ctx)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen switch (ctx->hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainenstatic int mail_index_sync_add_dirty_updates(struct mail_index_sync_ctx *ctx)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen messages_count = mail_index_view_get_messages_count(ctx->view);
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (mail_index_lookup(ctx->view, seq, &rec) < 0)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if ((rec->flags & MAIL_INDEX_MAIL_FLAG_DIRTY) == 0)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainenstatic int mail_index_sync_add_recent_updates(struct mail_index_sync_ctx *ctx)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen messages_count = mail_index_view_get_messages_count(ctx->view);
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (mail_index_lookup(ctx->view, seq, &rec) < 0)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen /* no recent messages, drop the sync_recent flag so we
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen don't scan through the message again */
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainenmail_index_sync_read_and_sort(struct mail_index_sync_ctx *ctx,
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen const struct mail_index_transaction_keyword_update *keyword_updates;
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen unsigned int i, keyword_count;
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if ((ctx->view->map->hdr.flags & MAIL_INDEX_HDR_FLAG_HAVE_DIRTY) &&
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen /* show dirty flags as flag updates */
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (mail_index_sync_add_dirty_updates(ctx) < 0)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (mail_index_sync_add_recent_updates(ctx) < 0)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen /* read all transactions from log into a transaction in memory */
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen while ((ret = mail_transaction_log_view_next(ctx->view->log_view,
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if ((ctx->hdr->type & MAIL_TRANSACTION_EXTERNAL) != 0)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen /* create an array containing all expunge, flag and keyword update
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen arrays so we can easily go through all of the changes. */
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen keyword_count = !array_is_created(&ctx->trans->keyword_updates) ? 0 :
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen struct mail_index_sync_list, keyword_count + 2);
7f74811b78f8915e73dffc88bb49009e98b6846dTimo Sirainen if (array_is_created(&ctx->trans->expunges)) {
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen synclist = array_append_space(&ctx->sync_list);
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen synclist = array_append_space(&ctx->sync_list);
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen /* we must return resets before keyword additions or they get lost */
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (array_is_created(&ctx->trans->keyword_resets)) {
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen synclist = array_append_space(&ctx->sync_list);
7f74811b78f8915e73dffc88bb49009e98b6846dTimo Sirainen synclist->array = &ctx->trans->keyword_resets;
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen array_get(&ctx->trans->keyword_updates, NULL);
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen for (i = 0; i < keyword_count; i++) {
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (array_is_created(&keyword_updates[i].add_seq)) {
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen synclist = array_append_space(&ctx->sync_list);
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen synclist->array = &keyword_updates[i].add_seq;
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (array_is_created(&keyword_updates[i].remove_seq)) {
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen synclist = array_append_space(&ctx->sync_list);
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen synclist->array = &keyword_updates[i].remove_seq;
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainenstatic int mail_index_need_lock(struct mail_index *index, int sync_recent,
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen uint32_t log_file_seq, uoff_t log_file_offset)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (sync_recent && index->hdr->recent_messages_count > 0)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (index->hdr->log_file_seq > log_file_seq ||
2c0f1cb7a0564d48ec43c7315ea46ea38d2abd19Timo Sirainen index->hdr->log_file_int_offset >= log_file_offset &&
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen index->hdr->log_file_ext_offset >= log_file_offset)) {
2c0f1cb7a0564d48ec43c7315ea46ea38d2abd19Timo Sirainen /* already synced */
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen return mail_cache_need_compress(index->cache);
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainenstatic int mail_index_sync_commit_external(struct mail_index_sync_ctx *ctx,
7f74811b78f8915e73dffc88bb49009e98b6846dTimo Sirainen while ((ret = mail_transaction_log_view_next(ctx->view->log_view,
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if ((ctx->hdr->type & MAIL_TRANSACTION_EXTERNAL) != 0)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (mail_transaction_log_view_set(ctx->view->log_view,
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (mail_index_sync_update_index(ctx, TRUE) < 0)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen (index)->sync_log_file_seq == (index)->hdr->log_file_seq && \
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen (index)->sync_log_file_offset == (index)->hdr->log_file_ext_offset)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainenint mail_index_sync_begin(struct mail_index *index,
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen uint32_t log_file_seq, uoff_t log_file_offset,
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen unsigned int lock_id = 0;
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (mail_transaction_log_sync_lock(index->log, &seq, &offset) < 0)
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (!index->mmap_disable || !MAIL_INDEX_IS_SYNCS_SAME(index) ||
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen /* make sure we have the latest file mapped */
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (mail_index_lock_shared(index, TRUE, &lock_id) < 0) {
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen /* with mmap_disable the force parameter has somewhat special
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen meaning, it syncs exactly to the log seq/offset in index
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen file's header. */
12983e9d3b4ebdfb1e14f197c153304b3af44b59Timo Sirainen if (mail_index_map(index, index->mmap_disable) <= 0) {
MAIL_TRANSACTION_TYPE_MASK) < 0) {
MAIL_TRANSACTION_TYPE_MASK) < 0) {
return FALSE;
return TRUE;
for (i = 0; i < count; i++) {
next_i = i;
if (i == count) {
i = next_i;
&sync_list[i]);
unsigned int i, count;
return TRUE;
for (i = 0; i < count; i++) {
return TRUE;
return FALSE;
unsigned int i, count;
for (i = 0; i < count; i++)
int ret = 0;
return ret;
const unsigned int *keyword_indexes;
unsigned int i, count;
for (i = 0; i < count; i++) {
return FALSE;
return TRUE;
for (i = 0; i < count; i++) {
return TRUE;
return FALSE;
return FALSE;
return TRUE;
i_unreached();
return FALSE;