Mercurial > dovecot > original-hg > dovecot-2.2
changeset 17793:2171b0e47055
virtual: Recent optimizations had broken fast mailbox syncing.
We wrongly assumed that all_mails array could have been accessed using vseqs.
Broken by 8abf7eea2966
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 11 Sep 2014 18:15:04 +0300 |
parents | bbf760c25a9e |
children | ccc5701dae72 |
files | src/plugins/virtual/virtual-sync.c |
diffstat | 1 files changed, 25 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/src/plugins/virtual/virtual-sync.c Thu Sep 11 16:40:00 2014 +0300 +++ b/src/plugins/virtual/virtual-sync.c Thu Sep 11 18:15:04 2014 +0300 @@ -37,8 +37,9 @@ ARRAY(struct virtual_add_record) all_adds; - /* all messages in this sync */ - ARRAY(const struct virtual_mail_index_record) all_mails; + /* all messages in this sync, sorted by mailbox_id + (but unsorted inside it for now, since it doesn't matter) */ + ARRAY(struct virtual_sync_mail) all_mails; uint32_t all_mails_idx, all_mails_prev_mailbox_id; enum mailbox_sync_flags flags; @@ -85,7 +86,7 @@ mail_index_keywords_unref(&keywords); } -static int virtual_sync_mail_cmp(const void *p1, const void *p2) +static int virtual_sync_mail_uid_cmp(const void *p1, const void *p2) { const struct virtual_sync_mail *m1 = p1, *m2 = p2; @@ -664,9 +665,10 @@ struct virtual_backend_box *bbox, struct mail_search_result *result) { - const struct virtual_mail_index_record *vrec, *vrecs; + const struct virtual_mail_index_record *vrec; + const struct virtual_sync_mail *sync_mail, *sync_mails; const void *data; - uint32_t vseq, messages; + uint32_t i, vseq, messages; /* find the messages that currently exist in virtual index and add them to the backend mailbox's list of uids. */ @@ -674,11 +676,11 @@ if (array_is_created(&ctx->all_mails)) { i_assert(ctx->all_mails_prev_mailbox_id < bbox->mailbox_id); - vrecs = array_get(&ctx->all_mails, &messages); - for (vseq = ctx->all_mails_idx + 1; vseq <= messages; vseq++) { - vrec = &vrecs[vseq - 1]; - if (vrec->mailbox_id != bbox->mailbox_id) { - if (vrec->mailbox_id < bbox->mailbox_id) { + sync_mails = array_get(&ctx->all_mails, &messages); + for (i = ctx->all_mails_idx; i < messages; i++) { + sync_mail = &sync_mails[i]; + if (sync_mail->vrec.mailbox_id != bbox->mailbox_id) { + if (sync_mail->vrec.mailbox_id < bbox->mailbox_id) { /* stale mailbox_id, ignore */ continue; } @@ -687,10 +689,10 @@ break; } - virtual_sync_backend_add_vmsgs_results(ctx, - bbox, vrec->real_uid, result, vseq); + virtual_sync_backend_add_vmsgs_results(ctx, bbox, + sync_mail->vrec.real_uid, result, sync_mail->vseq); } - ctx->all_mails_idx = vseq - 1; + ctx->all_mails_idx = i; ctx->all_mails_prev_mailbox_id = bbox->mailbox_id; } else { /* there should be only a single backend mailbox, but in the @@ -1198,7 +1200,7 @@ vmails[vseq-1].vseq = vseq; vmails[vseq-1].vrec = *vrec; } - qsort(vmails, messages, sizeof(*vmails), virtual_sync_mail_cmp); + qsort(vmails, messages, sizeof(*vmails), virtual_sync_mail_uid_cmp); /* create real mailbox uid -> virtual uid mapping and expunge messages no longer matching the search rule */ @@ -1501,13 +1503,12 @@ } } -static int -virtual_sync_mails_mailbox_cmp(const struct virtual_mail_index_record *v1, - const struct virtual_mail_index_record *v2) +static int virtual_sync_mail_mailbox_cmp(const struct virtual_sync_mail *m1, + const struct virtual_sync_mail *m2) { - if (v1->mailbox_id < v2->mailbox_id) + if (m1->vrec.mailbox_id < m2->vrec.mailbox_id) return -1; - if (v1->mailbox_id > v2->mailbox_id) + if (m1->vrec.mailbox_id > m2->vrec.mailbox_id) return 1; return 0; } @@ -1517,6 +1518,7 @@ uint32_t messages, vseq; const void *mail_data; const struct virtual_mail_index_record *vrec; + struct virtual_sync_mail *sync_mail; messages = mail_index_view_get_messages_count(ctx->sync_view); i_array_init(&ctx->all_mails, messages); @@ -1524,9 +1526,11 @@ mail_index_lookup_ext(ctx->sync_view, vseq, ctx->mbox->virtual_ext_id, &mail_data, NULL); vrec = mail_data; - array_append(&ctx->all_mails, vrec, 1); + sync_mail = array_append_space(&ctx->all_mails); + sync_mail->vseq = vseq; + sync_mail->vrec = *vrec; } - array_sort(&ctx->all_mails, virtual_sync_mails_mailbox_cmp); + array_sort(&ctx->all_mails, virtual_sync_mail_mailbox_cmp); } static int virtual_sync_backend_boxes(struct virtual_sync_context *ctx)