From: Timo Sirainen Date: Fri, 5 Dec 2014 03:50:19 +0000 (+0200) Subject: lib-storage: Mail prefetching was still not working right. X-Git-Tag: 2.2.16.rc1~178 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=823af4a2cc4e2ce90d12f9ec362160546aa4c4b8;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Mail prefetching was still not working right. I wonder if it ever actually worked (except for SEARCH TEXT). --- diff --git a/src/lib-storage/index/index-mail.c b/src/lib-storage/index/index-mail.c index 431584a1f7..2636be3514 100644 --- a/src/lib-storage/index/index-mail.c +++ b/src/lib-storage/index/index-mail.c @@ -1435,14 +1435,12 @@ static void check_envelope(struct index_mail *mail) mail->data.save_envelope = TRUE; } -void index_mail_update_access_parts(struct mail *_mail) +void index_mail_update_access_parts_pre(struct mail *_mail) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; const struct mail_cache_field *cache_fields = mail->ibox->cache_fields; struct mail_cache_view *cache_view = _mail->transaction->cache_view; - const struct mail_index_header *hdr; - struct istream *input; if ((data->wanted_fields & (MAIL_FETCH_NUL_STATE | MAIL_FETCH_IMAP_BODY | @@ -1522,21 +1520,35 @@ void index_mail_update_access_parts(struct mail *_mail) data->save_sent_date = TRUE; } } - if ((data->wanted_fields & (MAIL_FETCH_STREAM_HEADER | MAIL_FETCH_STREAM_BODY)) != 0) { - /* open stream immediately to set expunged flag if - it's already lost */ if ((data->wanted_fields & MAIL_FETCH_STREAM_HEADER) != 0) data->access_part |= READ_HDR; if ((data->wanted_fields & MAIL_FETCH_STREAM_BODY) != 0) data->access_part |= READ_BODY; + } +} + +void index_mail_update_access_parts_post(struct mail *_mail) +{ + struct index_mail *mail = (struct index_mail *)_mail; + struct index_mail_data *data = &mail->data; + const struct mail_index_header *hdr; + struct istream *input; + + /* when mail_prefetch_count>1, at this point we've started the + prefetching to all the mails and we're now starting to access the + first mail. */ + + if (data->access_part != 0) { + /* open stream immediately to set expunged flag if + it's already lost */ /* open the stream only if we didn't get here from mailbox_save_init() */ hdr = mail_index_get_header(_mail->transaction->view); if (!_mail->saving && _mail->uid < hdr->next_uid) { - if ((data->access_part & READ_BODY) != 0) + if ((data->access_part & (READ_BODY | PARSE_BODY)) != 0) (void)mail_get_stream(_mail, NULL, NULL, &input); else (void)mail_get_hdr_stream(_mail, NULL, &input); @@ -1569,11 +1581,13 @@ void index_mail_set_seq(struct mail *_mail, uint32_t seq, bool saving) return; } - if (!mail->search_mail) - index_mail_update_access_parts(_mail); - else { - /* searching code will call the index_mail_update_access_parts() - after we know the mail is actually wanted to be fetched. */ + if (!mail->search_mail) { + index_mail_update_access_parts_pre(_mail); + index_mail_update_access_parts_post(_mail); + } else { + /* searching code will call the + index_mail_update_access_parts_*() after we know the mail is + actually wanted to be fetched. */ } mail->data.initialized = TRUE; } @@ -1665,7 +1679,8 @@ void index_mail_add_temp_wanted_fields(struct mail *_mail, mailbox_header_lookup_init(_mail->box, array_idx(&names, 0)); } - index_mail_update_access_parts(_mail); + index_mail_update_access_parts_pre(_mail); + index_mail_update_access_parts_post(_mail); } void index_mail_set_uid_cache_updates(struct mail *_mail, bool set) diff --git a/src/lib-storage/index/index-mail.h b/src/lib-storage/index/index-mail.h index a2f535b7ab..b7fd4439df 100644 --- a/src/lib-storage/index/index-mail.h +++ b/src/lib-storage/index/index-mail.h @@ -171,7 +171,8 @@ bool index_mail_prefetch(struct mail *mail); void index_mail_add_temp_wanted_fields(struct mail *mail, enum mail_fetch_field fields, struct mailbox_header_lookup_ctx *headers); -void index_mail_update_access_parts(struct mail *mail); +void index_mail_update_access_parts_pre(struct mail *mail); +void index_mail_update_access_parts_post(struct mail *_mail); void index_mail_close(struct mail *mail); void index_mail_close_streams(struct index_mail *mail); void index_mail_free(struct mail *mail); diff --git a/src/lib-storage/index/index-search.c b/src/lib-storage/index/index-search.c index 18f0e5faaa..d9f43b3422 100644 --- a/src/lib-storage/index/index-search.c +++ b/src/lib-storage/index/index-search.c @@ -1556,7 +1556,7 @@ static int search_more_with_mail(struct index_search_context *ctx, if searching would want fewer access_parts than the fetching part, but that's probably not a big problem usually. */ - index_mail_update_access_parts(mail); + index_mail_update_access_parts_pre(mail); ret = 1; break; } @@ -1651,6 +1651,7 @@ static int search_more_with_prefetching(struct index_search_context *ctx, array_delete(&ctx->mails, 0, 1); array_append(&ctx->mails, mail_r, 1); } + index_mail_update_access_parts_post(*mail_r); return 1; } @@ -1731,13 +1732,14 @@ bool index_storage_search_next_nonblock(struct mail_search_context *_ctx, } /* everything searched at this point already. just returning - matches from sort list */ + matches from sort list. FIXME: we could do prefetching here also. */ if (!index_sort_list_next(_ctx->sort_program, &seq)) return FALSE; mailp = array_idx(&ctx->mails, 0); mail_set_seq(*mailp, seq); - index_mail_update_access_parts(*mailp); + index_mail_update_access_parts_pre(*mailp); + index_mail_update_access_parts_post(*mailp); *mail_r = *mailp; return TRUE; }