Mercurial > dovecot > core-2.2
changeset 4244:b9a7a9592f43 HEAD
Index header's seen/recent/deleted counters weren't always correct after
syncing a view. This caused some problems with recent SEARCH optimizations,
eg. EXPUNGE not always working.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 03 May 2006 01:06:32 +0300 |
parents | 07c10799434e |
children | be915546ce49 |
files | src/lib-index/mail-index-private.h src/lib-index/mail-index-sync-private.h src/lib-index/mail-index-sync-update.c src/lib-index/mail-index-view-private.h src/lib-index/mail-index-view-sync.c src/lib-index/mail-index-view.c |
diffstat | 6 files changed, 67 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-index-private.h Wed May 03 01:05:09 2006 +0300 +++ b/src/lib-index/mail-index-private.h Wed May 03 01:06:32 2006 +0300 @@ -246,6 +246,7 @@ uint32_t ext_id, uint32_t *idx_r); const struct mail_index_ext * mail_index_view_get_ext(struct mail_index_view *view, uint32_t ext_id); +void mail_index_view_recalc_counters(struct mail_index_view *view); int mail_index_map_parse_keywords(struct mail_index *index, struct mail_index_map *map);
--- a/src/lib-index/mail-index-sync-private.h Wed May 03 01:05:09 2006 +0300 +++ b/src/lib-index/mail-index-sync-private.h Wed May 03 01:06:32 2006 +0300 @@ -52,6 +52,7 @@ unsigned int expunge_handlers_used:1; unsigned int cur_ext_ignore:1; unsigned int keywords_read:1; + unsigned int unreliable_flags:1; }; extern struct mail_transaction_map_functions mail_index_map_sync_funcs;
--- a/src/lib-index/mail-index-sync-update.c Wed May 03 01:05:09 2006 +0300 +++ b/src/lib-index/mail-index-sync-update.c Wed May 03 01:06:32 2006 +0300 @@ -82,6 +82,29 @@ } } +void mail_index_view_recalc_counters(struct mail_index_view *view) +{ + struct mail_index_map *map = view->map; + const struct mail_index_record *rec; + unsigned int i; + + map->hdr.recent_messages_count = 0; + map->hdr.seen_messages_count = 0; + map->hdr.deleted_messages_count = 0; + + for (i = 0; i < view->hdr.messages_count; i++) { + rec = MAIL_INDEX_MAP_IDX(map, i); + mail_index_header_update_counts(view->index, &map->hdr, + 0, rec->flags); + } + + view->hdr.recent_messages_count = map->hdr.recent_messages_count; + view->hdr.seen_messages_count = map->hdr.seen_messages_count; + view->hdr.deleted_messages_count = map->hdr.deleted_messages_count; + + view->broken_counters = FALSE; +} + static void mail_index_header_update_lowwaters(struct mail_index_header *hdr, const struct mail_index_record *rec) @@ -149,10 +172,14 @@ expunge_handlers_count = 0; } - for (seq = seq1; seq <= seq2; seq++) { - rec = MAIL_INDEX_MAP_IDX(map, seq-1); - mail_index_header_update_counts(view->index, &map->hdr, - rec->flags, 0); + if (ctx->unreliable_flags) + view->broken_counters = TRUE; + else { + for (seq = seq1; seq <= seq2; seq++) { + rec = MAIL_INDEX_MAP_IDX(map, seq-1); + mail_index_header_update_counts(view->index, &map->hdr, + rec->flags, 0); + } } for (i = 0; i < expunge_handlers_count; i++) { @@ -264,15 +291,27 @@ flag_mask = ~u->remove_flags; - for (idx = seq1-1; idx < seq2; idx++) { - rec = MAIL_INDEX_MAP_IDX(view->map, idx); + if (ctx->unreliable_flags && + ((u->add_flags | u->remove_flags) & + (MAIL_SEEN | MAIL_DELETED | MAIL_RECENT)) != 0) { + view->broken_counters = TRUE; + for (idx = seq1-1; idx < seq2; idx++) { + rec = MAIL_INDEX_MAP_IDX(view->map, idx); + rec->flags = (rec->flags & flag_mask) | u->add_flags; - old_flags = rec->flags; - rec->flags = (rec->flags & flag_mask) | u->add_flags; + mail_index_header_update_lowwaters(hdr, rec); + } + } else { + for (idx = seq1-1; idx < seq2; idx++) { + rec = MAIL_INDEX_MAP_IDX(view->map, idx); - mail_index_header_update_counts(view->index, hdr, - old_flags, rec->flags); - mail_index_header_update_lowwaters(hdr, rec); + old_flags = rec->flags; + rec->flags = (rec->flags & flag_mask) | u->add_flags; + + mail_index_header_update_counts(view->index, hdr, + old_flags, rec->flags); + mail_index_header_update_lowwaters(hdr, rec); + } } return 1; }
--- a/src/lib-index/mail-index-view-private.h Wed May 03 01:05:09 2006 +0300 +++ b/src/lib-index/mail-index-view-private.h Wed May 03 01:06:32 2006 +0300 @@ -54,6 +54,7 @@ unsigned int inconsistent:1; unsigned int syncing:1; + unsigned int broken_counters:1; }; void mail_index_view_clone(struct mail_index_view *dest,
--- a/src/lib-index/mail-index-view-sync.c Wed May 03 01:05:09 2006 +0300 +++ b/src/lib-index/mail-index-view-sync.c Wed May 03 01:06:32 2006 +0300 @@ -254,6 +254,9 @@ view->sync_new_map = view->index->map; view->sync_new_map->refcount++; + /* since we're syncing everything, the counters get fixed */ + view->broken_counters = FALSE; + /* keep the old mapping without expunges until we're fully synced */ } else { @@ -270,6 +273,14 @@ /* Using non-head mapping. We have to apply transactions to it to get latest changes into it. */ ctx->sync_map_update = TRUE; + /* Unless map was synced at the exact same position as + view, the message flags can't be reliably used to + update flag counters. */ + ctx->sync_map_ctx.unreliable_flags = + !(view->map->hdr.log_file_seq == + view->log_file_seq && + view->map->hdr.log_file_int_offset == + view->log_file_offset); /* Copy only the mails that we see currently, since we're going to append the new ones when we see
--- a/src/lib-index/mail-index-view.c Wed May 03 01:05:09 2006 +0300 +++ b/src/lib-index/mail-index-view.c Wed May 03 01:06:32 2006 +0300 @@ -19,6 +19,7 @@ dest->map = src->map; dest->map->refcount++; dest->hdr = src->hdr; + dest->broken_counters = src->broken_counters; dest->log_file_seq = src->log_file_seq; dest->log_file_offset = src->log_file_offset; @@ -174,6 +175,8 @@ static const struct mail_index_header * _view_get_header(struct mail_index_view *view) { + if (view->broken_counters) + mail_index_view_recalc_counters(view); return &view->hdr; }