Mercurial > dovecot > core-2.2
changeset 12873:b47f17b173f5
lib-storage: Search code cleanup.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 31 Mar 2011 09:48:37 +0300 |
parents | b131b89f5e20 |
children | 0461e23ae57c |
files | src/lib-storage/index/index-search.c src/lib-storage/index/index-sort.c src/lib-storage/index/index-sort.h |
diffstat | 3 files changed, 69 insertions(+), 55 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/index-search.c Thu Mar 31 09:23:22 2011 +0300 +++ b/src/lib-storage/index/index-search.c Thu Mar 31 09:48:37 2011 +0300 @@ -1068,6 +1068,7 @@ struct mailbox_header_lookup_ctx *wanted_headers) { struct mailbox_status status; + struct index_mail *imail; ctx->mail_ctx.transaction = t; ctx->box = t->box; @@ -1078,9 +1079,6 @@ if (gettimeofday(&ctx->last_nonblock_timeval, NULL) < 0) i_fatal("gettimeofday() failed: %m"); - ctx->mail = mail_alloc(t, wanted_fields, wanted_headers); - ((struct index_mail *)ctx->mail)->search_mail = TRUE; - mailbox_get_open_status(t->box, STATUS_MESSAGES, &status); ctx->mail_ctx.progress_max = status.messages; @@ -1102,6 +1100,13 @@ &ctx->extra_wanted_headers); } + ctx->mail = mail_alloc(t, wanted_fields, wanted_headers); + imail = (struct index_mail *)ctx->mail; + imail->search_mail = TRUE; + imail->mail.stats_track = TRUE; + imail->mail.extra_wanted_fields = ctx->extra_wanted_fields; + imail->mail.extra_wanted_headers = ctx->extra_wanted_headers; + search_get_seqset(ctx, status.messages, args->args); (void)mail_search_args_foreach(args->args, search_init_arg, ctx); @@ -1354,43 +1359,25 @@ return ret; } -bool index_storage_search_next_nonblock(struct mail_search_context *_ctx, - struct mail **mail_r, bool *tryagain_r) +static int search_more(struct index_search_context *ctx, + struct mail *mail) { - struct index_search_context *ctx = (struct index_search_context *)_ctx; + struct mail_search_context *_ctx = &ctx->mail_ctx; struct mailbox *box = _ctx->transaction->box; - struct mail *mail = ctx->mail; struct mail_private *mail_private = (struct mail_private *)mail; unsigned long long cost1, cost2; - bool old_stats_track, match = FALSE; - - *mail_r = mail; - *tryagain_r = FALSE; - - if (ctx->sorted) { - /* everything searched at this point already. just returning - matches from sort list */ - if (!index_sort_list_next(ctx->mail_ctx.sort_program, mail)) - return FALSE; - return TRUE; - } + bool match = FALSE; if (search_would_block(ctx)) { /* this lookup is useful when a large number of messages match */ - *tryagain_r = TRUE; - return FALSE; + return 0; } - mail_private->extra_wanted_fields = ctx->extra_wanted_fields; - mail_private->extra_wanted_headers = ctx->extra_wanted_headers; - if (ioloop_time - ctx->last_notify.tv_sec >= SEARCH_NOTIFY_INTERVAL_SECS) index_storage_search_notify(box, ctx); - old_stats_track = mail_private->stats_track; - mail_private->stats_track = TRUE; cost1 = search_mail_get_cost(mail_private); while (box->v.search_next_update_seq(_ctx)) { mail_set_seq(mail, _ctx->seq); @@ -1398,51 +1385,78 @@ T_BEGIN { match = search_match_next(ctx); + } T_END; + ctx->imail = NULL; - if (mail->expunged) - _ctx->seen_lost_data = TRUE; + if (mail->expunged) + _ctx->seen_lost_data = TRUE; - if (!match && - search_has_static_nonmatches(_ctx->args->args)) { - /* if there are saved search results remember - that this message never matches */ - mailbox_search_results_never(_ctx, mail->uid); - } - } T_END; + if (!match && search_has_static_nonmatches(_ctx->args->args)) { + /* if there are saved search results remember + that this message never matches */ + mailbox_search_results_never(_ctx, mail->uid); + } + cost2 = search_mail_get_cost(mail_private); ctx->cost += cost2 - cost1; cost1 = cost2; mail_search_args_reset(_ctx->args->args, FALSE); - if (match) { - if (_ctx->sort_program == NULL) - break; + if (match) + return 1; + if (search_would_block(ctx)) + return 0; + } + return -1; +} - index_sort_list_add(_ctx->sort_program, mail); - } - match = FALSE; +bool index_storage_search_next_nonblock(struct mail_search_context *_ctx, + struct mail **mail_r, bool *tryagain_r) +{ + struct index_search_context *ctx = (struct index_search_context *)_ctx; + struct mail *mail = ctx->mail; + uint32_t seq; + int ret; - if (search_would_block(ctx)) { + *tryagain_r = FALSE; + + if (_ctx->sort_program == NULL) { + ret = search_more(ctx, mail); + if (ret == 0) { *tryagain_r = TRUE; - break; + return FALSE; } + if (ret < 0) + return FALSE; + *mail_r = mail; + return TRUE; } - ctx->imail = NULL; - mail_private->stats_track = old_stats_track; - mail_private->extra_wanted_fields = 0; - mail_private->extra_wanted_headers = NULL; + + if (!ctx->sorted) { + while ((ret = search_more(ctx, mail)) > 0) + index_sort_list_add(_ctx->sort_program, mail); - if (!match && _ctx->sort_program != NULL && - !*tryagain_r && !ctx->failed) { + if (ret == 0) { + *tryagain_r = TRUE; + return FALSE; + } /* finished searching the messages. now sort them and start returning the messages. */ ctx->sorted = TRUE; index_sort_list_finish(_ctx->sort_program); - return index_storage_search_next_nonblock(_ctx, mail_r, - tryagain_r); + if (ctx->failed) + return FALSE; } - return !ctx->failed && match; + + /* everything searched at this point already. just returning + matches from sort list */ + if (!index_sort_list_next(_ctx->sort_program, &seq)) + return FALSE; + + mail_set_seq(mail, seq); + *mail_r = mail; + return TRUE; } bool index_storage_search_next_update_seq(struct mail_search_context *_ctx)
--- a/src/lib-storage/index/index-sort.c Thu Mar 31 09:23:22 2011 +0300 +++ b/src/lib-storage/index/index-sort.c Thu Mar 31 09:48:37 2011 +0300 @@ -203,7 +203,7 @@ } bool index_sort_list_next(struct mail_search_sort_program *program, - struct mail *mail) + uint32_t *seq_r) { const uint32_t *seqp; @@ -211,7 +211,7 @@ return FALSE; seqp = array_idx(&program->seqs, program->iter_idx++); - mail_set_seq(mail, *seqp); + *seq_r = *seqp; return TRUE; }
--- a/src/lib-storage/index/index-sort.h Thu Mar 31 09:23:22 2011 +0300 +++ b/src/lib-storage/index/index-sort.h Thu Mar 31 09:48:37 2011 +0300 @@ -13,6 +13,6 @@ void index_sort_list_finish(struct mail_search_sort_program *program); bool index_sort_list_next(struct mail_search_sort_program *program, - struct mail *mail); + uint32_t *seq_r); #endif