Mercurial > dovecot > core-2.2
changeset 4688:764bd841e0ae HEAD
Try to avoid sending duplicate/useless flag updates.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 15 Oct 2006 20:56:09 +0300 |
parents | c8b565e87966 |
children | 80023f898ddd |
files | src/lib-index/mail-index-view-sync.c src/lib-index/mail-index.h src/lib-storage/index/index-sync.c |
diffstat | 3 files changed, 100 insertions(+), 44 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-index-view-sync.c Sun Oct 15 20:44:32 2006 +0300 +++ b/src/lib-index/mail-index-view-sync.c Sun Oct 15 20:56:09 2006 +0300 @@ -12,7 +12,7 @@ struct mail_index_view *view; enum mail_transaction_type visible_sync_mask; struct mail_index_sync_map_ctx sync_map_ctx; - ARRAY_TYPE(uid_range) expunges; + ARRAY_TYPE(seq_range) expunges; const struct mail_transaction_header *hdr; const void *data; @@ -24,11 +24,12 @@ }; static void -mail_transaction_log_sort_expunges(ARRAY_TYPE(uid_range) *expunges, - const struct uid_range *src, size_t src_size) +mail_transaction_log_sort_expunges(ARRAY_TYPE(seq_range) *expunges, + const struct seq_range *src, size_t src_size) { - const struct uid_range *src_end; - struct uid_range *dest, new_exp; + /* Note that all the sequences are actually still UIDs at this point */ + const struct seq_range *src_end; + struct seq_range *dest, new_exp; unsigned int first, i, dest_count; i_assert(src_size % sizeof(*src) == 0); @@ -43,28 +44,28 @@ src_end = CONST_PTR_OFFSET(src, src_size); for (i = 0; src != src_end; src++) { /* src[] must be sorted. */ - i_assert(src+1 == src_end || src->uid2 < src[1].uid1); - i_assert(src->uid1 <= src->uid2); + i_assert(src+1 == src_end || src->seq2 < src[1].seq1); + i_assert(src->seq1 <= src->seq2); for (; i < dest_count; i++) { - if (src->uid1 < dest[i].uid1) + if (src->seq1 < dest[i].seq1) break; } new_exp = *src; first = i; - while (i < dest_count && src->uid2 >= dest[i].uid1-1) { + while (i < dest_count && src->seq2 >= dest[i].seq1-1) { /* we can/must merge with next record */ - if (new_exp.uid2 < dest[i].uid2) - new_exp.uid2 = dest[i].uid2; + if (new_exp.seq2 < dest[i].seq2) + new_exp.seq2 = dest[i].seq2; i++; } - if (first > 0 && new_exp.uid1 <= dest[first-1].uid2+1) { + if (first > 0 && new_exp.seq1 <= dest[first-1].seq2+1) { /* continue previous record */ - if (dest[first-1].uid2 < new_exp.uid2) - dest[first-1].uid2 = new_exp.uid2; + if (dest[first-1].seq2 < new_exp.seq2) + dest[first-1].seq2 = new_exp.seq2; } else if (i == first) { array_insert(expunges, i, &new_exp, 1); i++; first++; @@ -112,10 +113,10 @@ static int view_sync_get_expunges(struct mail_index_view *view, - ARRAY_TYPE(uid_range) *expunges_r) + ARRAY_TYPE(seq_range) *expunges_r) { const struct mail_transaction_header *hdr; - struct uid_range *src, *src_end, *dest; + struct seq_range *src, *src_end, *dest; const void *data; unsigned int count; int ret; @@ -135,17 +136,17 @@ return -1; } - /* convert to sequences */ + /* convert UIDs to sequences */ src = dest = array_get_modifiable(expunges_r, &count); src_end = src + count; for (; src != src_end; src++) { - ret = mail_index_lookup_uid_range(view, src->uid1, - src->uid2, - &dest->uid1, - &dest->uid2); + ret = mail_index_lookup_uid_range(view, src->seq1, + src->seq2, + &dest->seq1, + &dest->seq2); i_assert(ret == 0); - if (dest->uid1 == 0) + if (dest->seq1 == 0) count--; else dest++; @@ -195,7 +196,7 @@ struct mail_index_view_sync_ctx *ctx; struct mail_index_map *map; enum mail_transaction_type log_get_mask, visible_mask; - ARRAY_TYPE(uid_range) expunges = ARRAY_INIT; + ARRAY_TYPE(seq_range) expunges = ARRAY_INIT; /* We must sync flags as long as view is mmap()ed, as the flags may have already changed under us. */ @@ -511,14 +512,10 @@ return 1; } -const uint32_t * -mail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx, - unsigned int *count_r) +void mail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx, + const ARRAY_TYPE(seq_range) **expunges_r) { - const struct uid_range *data; - - data = array_get(&ctx->expunges, count_r); - return (const uint32_t *)data; + *expunges_r = &ctx->expunges; } static void
--- a/src/lib-index/mail-index.h Sun Oct 15 20:44:32 2006 +0300 +++ b/src/lib-index/mail-index.h Sun Oct 15 20:56:09 2006 +0300 @@ -2,6 +2,7 @@ #define __MAIL_INDEX_H #include "mail-types.h" +#include "seq-range-array.h" #define MAIL_INDEX_MAJOR_VERSION 7 #define MAIL_INDEX_MINOR_VERSION 0 @@ -266,9 +267,9 @@ /* Returns -1 if error, 0 if sync is finished, 1 if record was filled. */ int mail_index_view_sync_next(struct mail_index_view_sync_ctx *ctx, struct mail_index_view_sync_rec *sync_rec); -const uint32_t * +void mail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx, - unsigned int *count_r); + const ARRAY_TYPE(seq_range) **expunges_r); void mail_index_view_sync_end(struct mail_index_view_sync_ctx **ctx); /* Returns the index header. */
--- a/src/lib-storage/index/index-sync.c Sun Oct 15 20:44:32 2006 +0300 +++ b/src/lib-storage/index/index-sync.c Sun Oct 15 20:56:09 2006 +0300 @@ -1,6 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" +#include "seq-range-array.h" #include "array.h" #include "buffer.h" #include "index-storage.h" @@ -11,9 +12,11 @@ struct mail_index_view_sync_ctx *sync_ctx; uint32_t messages_count; - const uint32_t *expunges; - unsigned int expunges_count; - int failed; + const ARRAY_TYPE(seq_range) *expunges; + unsigned int expunge_pos; + uint32_t last_seq1, last_seq2; + + bool failed; }; void index_mailbox_set_recent(struct index_mailbox *ibox, uint32_t seq) @@ -163,13 +166,62 @@ } if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) == 0) { - ctx->expunges = - mail_index_view_sync_get_expunges(ctx->sync_ctx, - &ctx->expunges_count); + mail_index_view_sync_get_expunges(ctx->sync_ctx, + &ctx->expunges); + ctx->expunge_pos = array_count(ctx->expunges); } return &ctx->ctx; } +static bool sync_rec_check_skips(struct index_mailbox_sync_context *ctx, + struct mailbox_sync_rec *sync_rec) +{ + uint32_t seq, new_seq1, new_seq2; + + if (sync_rec->seq1 >= ctx->last_seq1 && + sync_rec->seq1 <= ctx->last_seq2) + new_seq1 = ctx->last_seq2 + 1; + else + new_seq1 = sync_rec->seq1; + if (sync_rec->seq2 >= ctx->last_seq1 && + sync_rec->seq2 <= ctx->last_seq2) + new_seq2 = ctx->last_seq1 - 1; + else + new_seq2 = sync_rec->seq2; + + if (new_seq1 > new_seq2) + return FALSE; + + ctx->last_seq1 = sync_rec->seq1; + ctx->last_seq2 = sync_rec->seq2; + + sync_rec->seq1 = new_seq1; + sync_rec->seq2 = new_seq2; + + /* FIXME: we're only skipping messages from the beginning and from + the end. we should skip also the middle ones. This takes care of + the most common repeats though. */ + if (ctx->expunges != NULL) { + /* skip expunged messages from the beginning and the end */ + for (seq = sync_rec->seq1; seq <= sync_rec->seq2; seq++) { + if (!seq_range_exists(ctx->expunges, seq)) + break; + } + if (seq > sync_rec->seq2) { + /* everything skipped */ + return FALSE; + } + sync_rec->seq1 = seq; + + for (seq = sync_rec->seq2; seq >= sync_rec->seq1; seq--) { + if (!seq_range_exists(ctx->expunges, seq)) + break; + } + sync_rec->seq2 = seq; + } + return TRUE; +} + int index_mailbox_sync_next(struct mailbox_sync_context *_ctx, struct mailbox_sync_rec *sync_rec_r) { @@ -205,6 +257,9 @@ if (sync_rec_r->seq1 == 0) break; + if (!sync_rec_check_skips(ctx, sync_rec_r)) + break; + sync_rec_r->type = sync.type == MAIL_INDEX_SYNC_TYPE_FLAGS ? MAILBOX_SYNC_TYPE_FLAGS : @@ -213,19 +268,22 @@ } } - if (ret == 0 && ctx->expunges_count > 0) { - /* expunges[] is a sorted array of sequences. it's easiest for + if (ret == 0 && ctx->expunge_pos > 0) { + /* expunges is a sorted array of sequences. it's easiest for us to print them from end to beginning. */ - sync_rec_r->seq1 = ctx->expunges[ctx->expunges_count*2-2]; - sync_rec_r->seq2 = ctx->expunges[ctx->expunges_count*2-1]; + const struct seq_range *range; + + ctx->expunge_pos--; + range = array_idx(ctx->expunges, ctx->expunge_pos); + + sync_rec_r->seq1 = range->seq1; + sync_rec_r->seq2 = range->seq2; index_mailbox_expunge_recent(ctx->ibox, sync_rec_r->seq1, sync_rec_r->seq2); if (sync_rec_r->seq2 > ctx->messages_count) sync_rec_r->seq2 = ctx->messages_count; - ctx->messages_count -= sync_rec_r->seq2 - sync_rec_r->seq1 + 1; - ctx->expunges_count--; sync_rec_r->type = MAILBOX_SYNC_TYPE_EXPUNGE; return 1;