dovecot-1.1: Fixed dirty flag/keyword handling.
dovecot at dovecot.org
dovecot at dovecot.org
Wed Feb 27 21:51:31 EET 2008
details: http://hg.dovecot.org/dovecot-1.1/rev/4e1161bad6ec
changeset: 7299:4e1161bad6ec
user: Timo Sirainen <tss at iki.fi>
date: Wed Feb 27 21:54:04 2008 +0200
description:
Fixed dirty flag/keyword handling.
diffstat:
2 files changed, 114 insertions(+), 87 deletions(-)
src/lib-storage/index/mbox/mbox-sync-update.c | 28 ----
src/lib-storage/index/mbox/mbox-sync.c | 173 +++++++++++++++----------
diffs (275 lines):
diff -r 86af79a203d7 -r 4e1161bad6ec src/lib-storage/index/mbox/mbox-sync-update.c
--- a/src/lib-storage/index/mbox/mbox-sync-update.c Tue Feb 26 20:01:57 2008 +0200
+++ b/src/lib-storage/index/mbox/mbox-sync-update.c Wed Feb 27 21:54:04 2008 +0200
@@ -323,7 +323,8 @@ static void mbox_sync_update_xkeywords(s
return;
str = t_str_new(256);
- keywords_append(ctx->sync_ctx, str, &ctx->mail.keywords);
+ if (array_is_created(&ctx->mail.keywords))
+ keywords_append(ctx->sync_ctx, str, &ctx->mail.keywords);
str_append_c(str, '\n');
mbox_sync_update_line(ctx, ctx->hdr_pos[MBOX_HDR_X_KEYWORDS], str);
}
@@ -375,35 +376,18 @@ static void mbox_sync_update_x_uid(struc
static void mbox_sync_update_header_real(struct mbox_sync_mail_context *ctx)
{
- uint8_t old_flags;
- enum mail_index_sync_type sync_type;
-
i_assert(ctx->mail.uid != 0 || ctx->mail.pseudo);
-
- old_flags = ctx->mail.flags;
-
- index_sync_changes_apply(ctx->sync_ctx->sync_changes,
- ctx->sync_ctx->mail_keyword_pool,
- &ctx->mail.flags, &ctx->mail.keywords,
- &sync_type);
-
- if ((old_flags & XSTATUS_FLAGS_MASK) !=
- (ctx->mail.flags & XSTATUS_FLAGS_MASK))
- mbox_sync_update_xstatus(ctx);
- if ((sync_type & (MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD |
- MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE |
- MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET)) != 0)
- mbox_sync_update_xkeywords(ctx);
if (!ctx->sync_ctx->mbox->ibox.keep_recent)
ctx->mail.flags &= ~MAIL_RECENT;
- if ((old_flags & STATUS_FLAGS_MASK) !=
- (ctx->mail.flags & STATUS_FLAGS_MASK))
- mbox_sync_update_status(ctx);
+ mbox_sync_update_status(ctx);
+ mbox_sync_update_xstatus(ctx);
+ mbox_sync_update_xkeywords(ctx);
mbox_sync_update_x_imap_base(ctx);
mbox_sync_update_x_uid(ctx);
+
mbox_sync_add_missing_headers(ctx);
ctx->updated = TRUE;
}
diff -r 86af79a203d7 -r 4e1161bad6ec src/lib-storage/index/mbox/mbox-sync.c
--- a/src/lib-storage/index/mbox/mbox-sync.c Tue Feb 26 20:01:57 2008 +0200
+++ b/src/lib-storage/index/mbox/mbox-sync.c Wed Feb 27 21:54:04 2008 +0200
@@ -315,20 +315,97 @@ mbox_sync_update_md5_if_changed(struct m
}
}
+static void mbox_sync_get_dirty_flags(struct mbox_sync_mail_context *mail_ctx,
+ const struct mail_index_record *rec)
+{
+ struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx;
+ ARRAY_TYPE(keyword_indexes) idx_keywords;
+ uint8_t idx_flags, mbox_flags;
+
+ /* default to undirtying the message. it gets added back if
+ flags/keywords don't match what is in the index. */
+ mail_ctx->mail.flags &= ~MAIL_INDEX_MAIL_FLAG_DIRTY;
+
+ /* replace flags */
+ idx_flags = rec->flags & MAIL_FLAGS_NONRECENT;
+ mbox_flags = mail_ctx->mail.flags & MAIL_FLAGS_NONRECENT;
+ if (idx_flags != mbox_flags) {
+ mail_ctx->need_rewrite = TRUE;
+ mail_ctx->mail.flags = (mail_ctx->mail.flags & MAIL_RECENT) |
+ idx_flags | MAIL_INDEX_MAIL_FLAG_DIRTY;
+ }
+
+ /* replace keywords */
+ t_array_init(&idx_keywords, 32);
+ mail_index_lookup_keywords(sync_ctx->sync_view, sync_ctx->idx_seq,
+ &idx_keywords);
+ if (!index_keyword_array_cmp(&idx_keywords, &mail_ctx->mail.keywords)) {
+ mail_ctx->need_rewrite = TRUE;
+ mail_ctx->mail.flags |= MAIL_INDEX_MAIL_FLAG_DIRTY;
+
+ if (!array_is_created(&mail_ctx->mail.keywords)) {
+ p_array_init(&mail_ctx->mail.keywords,
+ sync_ctx->mail_keyword_pool,
+ array_count(&idx_keywords));
+ }
+ array_clear(&mail_ctx->mail.keywords);
+ array_append_array(&mail_ctx->mail.keywords, &idx_keywords);
+ }
+}
+
+static void mbox_sync_update_flags(struct mbox_sync_mail_context *mail_ctx,
+ const struct mail_index_record *rec)
+{
+ struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx;
+ struct mailbox *box = &sync_ctx->mbox->ibox.box;
+ struct mbox_sync_mail *mail = &mail_ctx->mail;
+ enum mail_index_sync_type sync_type;
+ ARRAY_TYPE(keyword_indexes) orig_keywords = ARRAY_INIT;
+ uint8_t flags, orig_flags;
+
+ if (rec != NULL) {
+ if ((rec->flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0) {
+ /* flags and keywords are dirty. replace the current
+ ones from the flags in index file. */
+ mbox_sync_get_dirty_flags(mail_ctx, rec);
+ }
+ }
+
+ flags = orig_flags = mail->flags & MAIL_FLAGS_NONRECENT;
+ if (array_is_created(&mail->keywords)) {
+ t_array_init(&orig_keywords, 32);
+ array_append_array(&orig_keywords, &mail->keywords);
+ }
+
+ /* apply new changes */
+ index_sync_changes_apply(sync_ctx->sync_changes,
+ sync_ctx->mail_keyword_pool,
+ &flags, &mail->keywords, &sync_type);
+ if (flags != orig_flags ||
+ !index_keyword_array_cmp(&mail->keywords, &orig_keywords)) {
+ mail_ctx->need_rewrite = TRUE;
+ mail->flags = flags | (mail->flags & MAIL_RECENT) |
+ MAIL_INDEX_MAIL_FLAG_DIRTY;
+ }
+ if (sync_type != 0 && box->v.sync_notify != NULL) {
+ box->v.sync_notify(box, rec->uid,
+ index_sync_type_convert(sync_type));
+ }
+}
+
static void mbox_sync_update_index(struct mbox_sync_mail_context *mail_ctx,
const struct mail_index_record *rec)
{
struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx;
struct mbox_sync_mail *mail = &mail_ctx->mail;
- struct mailbox *box = &sync_ctx->mbox->ibox.box;
+ ARRAY_TYPE(keyword_indexes) idx_keywords;
uint8_t mbox_flags;
- mbox_flags = mail->flags & MAIL_FLAGS_NONRECENT;
-
- if (mail_ctx->dirty)
- mbox_flags |= MAIL_INDEX_MAIL_FLAG_DIRTY;
- else if (!sync_ctx->delay_writes)
+ mbox_flags = mail->flags & ~MAIL_RECENT;
+ if (!sync_ctx->delay_writes) {
+ /* changes are written to the mbox file */
mbox_flags &= ~MAIL_INDEX_MAIL_FLAG_DIRTY;
+ }
if (rec == NULL) {
/* new message */
@@ -343,61 +420,27 @@ static void mbox_sync_update_index(struc
mail_ctx->hdr_md5_sum, NULL);
}
} else {
- /* see if we need to update flags in index file. the flags in
- sync records are automatically applied to rec->flags at the
- end of index syncing, so calculate those new flags first */
- struct mbox_sync_mail idx_mail;
- enum mail_index_sync_type sync_type;
-
- memset(&idx_mail, 0, sizeof(idx_mail));
- idx_mail.flags = rec->flags & ~MAIL_RECENT;
-
- /* get old keywords */
- t_array_init(&idx_mail.keywords, 32);
- mail_index_lookup_keywords(sync_ctx->sync_view,
- sync_ctx->idx_seq,
- &idx_mail.keywords);
- index_sync_changes_apply(sync_ctx->sync_changes,
- sync_ctx->mail_keyword_pool,
- &idx_mail.flags, &idx_mail.keywords,
- &sync_type);
- if (sync_type != 0 && box->v.sync_notify != NULL) {
- box->v.sync_notify(box, rec->uid,
- index_sync_type_convert(sync_type));
- }
-
- if ((idx_mail.flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0) {
- /* flags are dirty. ignore whatever was in the mbox,
- but update dirty flag state if needed. */
- mbox_flags &= ~MAIL_INDEX_MAIL_FLAG_DIRTY;
- mbox_flags |=
- idx_mail.flags & ~MAIL_INDEX_MAIL_FLAG_DIRTY;
- if (sync_ctx->delay_writes)
- mbox_flags |= MAIL_INDEX_MAIL_FLAG_DIRTY;
- }
-
- if ((idx_mail.flags & ~MAIL_INDEX_MAIL_FLAG_DIRTY) !=
- (mbox_flags & ~MAIL_INDEX_MAIL_FLAG_DIRTY)) {
+ if ((rec->flags & MAIL_FLAGS_NONRECENT) !=
+ (mbox_flags & MAIL_FLAGS_NONRECENT)) {
/* flags other than recent/dirty have changed */
mail_index_update_flags(sync_ctx->t, sync_ctx->idx_seq,
MODIFY_REPLACE, mbox_flags);
- } else {
- if (((idx_mail.flags ^ mbox_flags) &
- MAIL_INDEX_MAIL_FLAG_DIRTY) != 0) {
- /* dirty flag state changed */
- bool dirty = (mbox_flags &
- MAIL_INDEX_MAIL_FLAG_DIRTY) != 0;
- mail_index_update_flags(sync_ctx->t,
- sync_ctx->idx_seq,
- dirty ? MODIFY_ADD : MODIFY_REMOVE,
- (enum mail_flags)
- MAIL_INDEX_MAIL_FLAG_DIRTY);
- }
- }
-
- if ((idx_mail.flags & MAIL_INDEX_MAIL_FLAG_DIRTY) == 0 &&
- !index_keyword_array_cmp(&idx_mail.keywords,
- &mail_ctx->mail.keywords))
+ } else if (((rec->flags ^ mbox_flags) &
+ MAIL_INDEX_MAIL_FLAG_DIRTY) != 0) {
+ /* only dirty flag state changed */
+ bool dirty;
+
+ dirty = (mbox_flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0;
+ mail_index_update_flags(sync_ctx->t, sync_ctx->idx_seq,
+ dirty ? MODIFY_ADD : MODIFY_REMOVE,
+ (enum mail_flags)MAIL_INDEX_MAIL_FLAG_DIRTY);
+ }
+
+ /* see if keywords changed */
+ t_array_init(&idx_keywords, 32);
+ mail_index_lookup_keywords(sync_ctx->sync_view,
+ sync_ctx->idx_seq, &idx_keywords);
+ if (!index_keyword_array_cmp(&idx_keywords, &mail->keywords))
mbox_sync_update_index_keywords(mail_ctx);
/* see if we need to update md5 sum. */
@@ -622,8 +665,7 @@ static int mbox_sync_handle_header(struc
mail_ctx->mail.from_offset = orig_from_offset;
}
}
- } else if (mail_ctx->need_rewrite ||
- index_sync_changes_have(sync_ctx->sync_changes)) {
+ } else if (mail_ctx->need_rewrite) {
mbox_sync_update_header(mail_ctx);
if (sync_ctx->delay_writes) {
/* mark it dirty and do it later */
@@ -1056,6 +1098,9 @@ static int mbox_sync_loop(struct mbox_sy
mail_ctx->mail.idx_seq = sync_ctx->idx_seq;
if (!expunged) {
+ if (!mail_ctx->mail.pseudo) T_BEGIN {
+ mbox_sync_update_flags(mail_ctx, rec);
+ } T_END;
if (mbox_sync_handle_header(mail_ctx) < 0)
return -1;
sync_ctx->dest_first_mail = FALSE;
@@ -1064,11 +1109,9 @@ static int mbox_sync_loop(struct mbox_sy
}
if (!mail_ctx->mail.pseudo) {
- if (!expunged) {
- T_BEGIN {
- mbox_sync_update_index(mail_ctx, rec);
- } T_END;
- }
+ if (!expunged) T_BEGIN {
+ mbox_sync_update_index(mail_ctx, rec);
+ } T_END;
sync_ctx->idx_seq++;
}
More information about the dovecot-cvs
mailing list