dovecot: If a message was expunged but is still visible in a vie...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Jan 6 11:59:24 EET 2008
details: http://hg.dovecot.org/dovecot/rev/26dbad6c08f3
changeset: 7130:26dbad6c08f3
user: Timo Sirainen <tss at iki.fi>
date: Sun Jan 06 11:59:21 2008 +0200
description:
If a message was expunged but is still visible in a view, its flags/keywords
might have been updated if an uid range included the expunged message.
diffstat:
4 files changed, 100 insertions(+), 32 deletions(-)
src/lib-index/mail-index-sync-keywords.c | 41 +++++++----------
src/lib-index/mail-index-sync-private.h | 11 ++++
src/lib-index/mail-index-sync-update.c | 70 +++++++++++++++++++++++++++---
src/lib-index/mail-index-view-sync.c | 10 +++-
diffs (258 lines):
diff -r 0c1859ca8ee9 -r 26dbad6c08f3 src/lib-index/mail-index-sync-keywords.c
--- a/src/lib-index/mail-index-sync-keywords.c Sun Jan 06 11:24:04 2008 +0200
+++ b/src/lib-index/mail-index-sync-keywords.c Sun Jan 06 11:59:21 2008 +0200
@@ -191,22 +191,18 @@ keywords_header_add(struct mail_index_sy
i_assert(*keyword_idx_r / CHAR_BIT < ext->record_size);
}
-static int
+static void
keywords_update_records(struct mail_index_sync_map_ctx *ctx,
const struct mail_index_ext *ext,
unsigned int keyword_idx, enum modify_type type,
- uint32_t uid1, uint32_t uid2)
+ uint32_t seq1, uint32_t seq2)
{
struct mail_index_view *view = ctx->view;
struct mail_index_record *rec;
unsigned char *data, data_mask;
unsigned int data_offset;
- uint32_t seq1, seq2;
i_assert(keyword_idx != (unsigned int)-1);
-
- if (!mail_index_lookup_seq_range(view, uid1, uid2, &seq1, &seq2))
- return 1;
mail_index_sync_write_seq_update(ctx, seq1, seq2);
@@ -237,7 +233,6 @@ keywords_update_records(struct mail_inde
default:
i_unreached();
}
- return 1;
}
int mail_index_sync_keywords(struct mail_index_sync_map_ctx *ctx,
@@ -248,9 +243,10 @@ int mail_index_sync_keywords(struct mail
const char *keyword_name;
const struct mail_index_ext *ext;
const uint32_t *uid, *end;
+ struct sync_uid_range_iter iter;
+ uint32_t seq1, seq2;
uint32_t seqset_offset, ext_map_idx;
unsigned int keyword_idx;
- int ret;
seqset_offset = sizeof(*rec) + rec->name_size;
if ((seqset_offset % 4) != 0)
@@ -293,12 +289,11 @@ int mail_index_sync_keywords(struct mail
}
while (uid+2 <= end) {
- ret = keywords_update_records(ctx, ext, keyword_idx,
- rec->modify_type,
- uid[0], uid[1]);
- if (ret <= 0)
- return ret;
-
+ sync_uid_range_iter_init(&iter, ctx, uid[0], uid[1]);
+ while (sync_uid_range_iter_next(&iter, &seq1, &seq2)) {
+ keywords_update_records(ctx, ext, keyword_idx,
+ rec->modify_type, seq1, seq2);
+ }
uid += 2;
}
@@ -314,6 +309,7 @@ mail_index_sync_keywords_reset(struct ma
struct mail_index_record *rec;
const struct mail_index_ext *ext;
const struct mail_transaction_keyword_reset *end;
+ struct sync_uid_range_iter iter;
uint32_t ext_map_idx, seq1, seq2;
if (!mail_index_map_lookup_ext(map, "keywords", &ext_map_idx)) {
@@ -324,15 +320,14 @@ mail_index_sync_keywords_reset(struct ma
ext = array_idx(&map->extensions, ext_map_idx);
end = CONST_PTR_OFFSET(r, hdr->size);
for (; r != end; r++) {
- if (!mail_index_lookup_seq_range(ctx->view, r->uid1, r->uid2,
- &seq1, &seq2))
- continue;
-
- mail_index_sync_write_seq_update(ctx, seq1, seq2);
- for (seq1--; seq1 < seq2; seq1++) {
- rec = MAIL_INDEX_MAP_IDX(map, seq1);
- memset(PTR_OFFSET(rec, ext->record_offset),
- 0, ext->record_size);
+ sync_uid_range_iter_init(&iter, ctx, r->uid1, r->uid2);
+ while (sync_uid_range_iter_next(&iter, &seq1, &seq2)) {
+ mail_index_sync_write_seq_update(ctx, seq1, seq2);
+ for (seq1--; seq1 < seq2; seq1++) {
+ rec = MAIL_INDEX_MAP_IDX(map, seq1);
+ memset(PTR_OFFSET(rec, ext->record_offset),
+ 0, ext->record_size);
+ }
}
}
return 1;
diff -r 0c1859ca8ee9 -r 26dbad6c08f3 src/lib-index/mail-index-sync-private.h
--- a/src/lib-index/mail-index-sync-private.h Sun Jan 06 11:24:04 2008 +0200
+++ b/src/lib-index/mail-index-sync-private.h Sun Jan 06 11:59:21 2008 +0200
@@ -7,6 +7,11 @@ struct uid_range {
uint32_t uid1, uid2;
};
ARRAY_DEFINE_TYPE(uid_range, struct uid_range);
+
+struct sync_uid_range_iter {
+ struct mail_index_sync_map_ctx *ctx;
+ uint32_t seq1, seq2;
+};
struct mail_index_sync_list {
const ARRAY_TYPE(uid_range) *array;
@@ -52,6 +57,12 @@ int mail_index_sync_map(struct mail_inde
int mail_index_sync_map(struct mail_index_map **map,
enum mail_index_sync_handler_type type, bool force);
+void sync_uid_range_iter_init(struct sync_uid_range_iter *iter,
+ struct mail_index_sync_map_ctx *ctx,
+ uint32_t uid1, uint32_t uid2);
+bool sync_uid_range_iter_next(struct sync_uid_range_iter *iter,
+ uint32_t *seq1_r, uint32_t *seq2_r);
+
int mail_index_sync_record(struct mail_index_sync_map_ctx *ctx,
const struct mail_transaction_header *hdr,
const void *data);
diff -r 0c1859ca8ee9 -r 26dbad6c08f3 src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c Sun Jan 06 11:24:04 2008 +0200
+++ b/src/lib-index/mail-index-sync-update.c Sun Jan 06 11:59:21 2008 +0200
@@ -86,6 +86,55 @@ mail_index_sync_get_atomic_map(struct ma
mail_index_record_map_move_to_private(ctx->view->map);
ctx->view->map->write_atomic = TRUE;
return ctx->view->map;
+}
+
+void sync_uid_range_iter_init(struct sync_uid_range_iter *iter,
+ struct mail_index_sync_map_ctx *ctx,
+ uint32_t uid1, uint32_t uid2)
+{
+ memset(iter, 0, sizeof(*iter));
+ iter->ctx = ctx;
+ if (!mail_index_lookup_seq_range(ctx->view, uid1, uid2,
+ &iter->seq1, &iter->seq2))
+ iter->seq1 = 1;
+}
+
+bool sync_uid_range_iter_next(struct sync_uid_range_iter *iter,
+ uint32_t *seq1_r, uint32_t *seq2_r)
+{
+ struct mail_index_view *view;
+ uint32_t seq;
+
+ if (iter->seq1 > iter->seq2)
+ return FALSE;
+
+ if (iter->ctx->type != MAIL_INDEX_SYNC_HANDLER_VIEW) {
+ *seq1_r = iter->seq1;
+ *seq2_r = iter->seq2;
+ iter->seq1 = iter->seq2 + 1;
+ return TRUE;
+ }
+ view = iter->ctx->view;
+
+ /* with views we have to drop expunged messages from the range.
+ first skip over any expunged messages from the beginning of the
+ range. */
+ for (seq = iter->seq1; seq <= iter->seq2; seq++) {
+ if (!mail_index_is_expunged(view, seq))
+ break;
+ }
+ if (seq > iter->seq2)
+ return FALSE;
+ *seq1_r = seq;
+
+ /* go forward until we find the first expunged message */
+ for (seq++; seq <= iter->seq2; seq++) {
+ if (mail_index_is_expunged(view, seq))
+ break;
+ }
+ *seq2_r = seq - 1;
+ iter->seq1 = seq;
+ return TRUE;
}
static int
@@ -338,16 +387,14 @@ static int sync_append(const struct mail
return 1;
}
-static int sync_flag_update(const struct mail_transaction_flag_update *u,
- struct mail_index_sync_map_ctx *ctx)
+static void sync_flag_update_range(struct mail_index_sync_map_ctx *ctx,
+ const struct mail_transaction_flag_update *u,
+ uint32_t seq1, uint32_t seq2)
{
struct mail_index_view *view = ctx->view;
struct mail_index_record *rec;
uint8_t flag_mask, old_flags;
- uint32_t idx, seq1, seq2;
-
- if (!mail_index_lookup_seq_range(view, u->uid1, u->uid2, &seq1, &seq2))
- return 1;
+ uint32_t idx;
mail_index_sync_write_seq_update(ctx, seq1, seq2);
@@ -377,6 +424,17 @@ static int sync_flag_update(const struct
rec->flags, TRUE);
}
}
+}
+
+static int sync_flag_update(const struct mail_transaction_flag_update *u,
+ struct mail_index_sync_map_ctx *ctx)
+{
+ struct sync_uid_range_iter iter;
+ uint32_t seq1, seq2;
+
+ sync_uid_range_iter_init(&iter, ctx, u->uid1, u->uid2);
+ while (sync_uid_range_iter_next(&iter, &seq1, &seq2))
+ sync_flag_update_range(ctx, u, seq1, seq2);
return 1;
}
diff -r 0c1859ca8ee9 -r 26dbad6c08f3 src/lib-index/mail-index-view-sync.c
--- a/src/lib-index/mail-index-view-sync.c Sun Jan 06 11:24:04 2008 +0200
+++ b/src/lib-index/mail-index-view-sync.c Sun Jan 06 11:59:21 2008 +0200
@@ -309,8 +309,6 @@ int mail_index_view_sync_begin(struct ma
ctx->expunges = expunges;
ctx->finish_min_msg_count = reset || quick_sync ? 0 :
view->map->hdr.messages_count - expunge_count;
- mail_index_sync_map_init(&ctx->sync_map_ctx, view,
- MAIL_INDEX_SYNC_HANDLER_VIEW);
if (reset && view->map->hdr.messages_count > 0 &&
(flags & MAIL_INDEX_VIEW_SYNC_FLAG_FIX_INCONSISTENT) == 0) {
@@ -358,6 +356,11 @@ int mail_index_view_sync_begin(struct ma
} else {
map = view->map;
}
+ }
+
+ if (ctx->sync_map_update) {
+ mail_index_sync_map_init(&ctx->sync_map_ctx, view,
+ MAIL_INDEX_SYNC_HANDLER_VIEW);
}
#ifdef DEBUG
@@ -686,7 +689,8 @@ int mail_index_view_sync_commit(struct m
view->map->hdr.log_file_tail_offset = 0;
}
- mail_index_sync_map_deinit(&ctx->sync_map_ctx);
+ if (ctx->sync_map_update)
+ mail_index_sync_map_deinit(&ctx->sync_map_ctx);
mail_index_view_sync_clean_log_syncs(ctx->view);
#ifdef DEBUG
More information about the dovecot-cvs
mailing list