]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Moved setting "wanted fields/headers" fields for sort program from imap...
authorTimo Sirainen <tss@iki.fi>
Mon, 31 Jan 2011 00:13:06 +0000 (02:13 +0200)
committerTimo Sirainen <tss@iki.fi>
Mon, 31 Jan 2011 00:13:06 +0000 (02:13 +0200)
Also separate between fields that are actually wanted to be fetched from the
fields that sorting wants to temporarily use.

src/imap/imap-search.c
src/lib-storage/index/index-mail-headers.c
src/lib-storage/index/index-search-private.h
src/lib-storage/index/index-search.c
src/lib-storage/index/index-sort.c
src/lib-storage/mail-storage-private.h

index 35c76e938a785077dc2c8cfb92779fb323a5bfa7..4bf93ffc045ff7e4b04d057232c2bec7c6288d86 100644 (file)
@@ -474,55 +474,11 @@ int cmd_search_parse_return_if_found(struct imap_search_context *ctx,
        return 1;
 }
 
-static void wanted_fields_get(struct mailbox *box,
-                             const enum mail_sort_type *sort_program,
-                             enum mail_fetch_field *wanted_fields_r,
-                             struct mailbox_header_lookup_ctx **headers_ctx_r)
-{
-       const char *headers[2];
-
-       *wanted_fields_r = 0;
-       *headers_ctx_r = NULL;
-
-       if (sort_program == NULL)
-               return;
-
-       headers[0] = headers[1] = NULL;
-       switch (sort_program[0] & MAIL_SORT_MASK) {
-       case MAIL_SORT_ARRIVAL:
-               *wanted_fields_r = MAIL_FETCH_RECEIVED_DATE;
-               break;
-       case MAIL_SORT_CC:
-               headers[0] = "Cc";
-               break;
-       case MAIL_SORT_DATE:
-               *wanted_fields_r = MAIL_FETCH_DATE;
-               break;
-       case MAIL_SORT_FROM:
-               headers[0] = "From";
-               break;
-       case MAIL_SORT_SIZE:
-               *wanted_fields_r = MAIL_FETCH_VIRTUAL_SIZE;
-               break;
-       case MAIL_SORT_SUBJECT:
-               headers[0] = "Subject";
-               break;
-       case MAIL_SORT_TO:
-               headers[0] = "To";
-               break;
-       }
-
-       if (headers[0] != NULL)
-               *headers_ctx_r = mailbox_header_lookup_init(box, headers);
-}
-
 bool imap_search_start(struct imap_search_context *ctx,
                       struct mail_search_args *sargs,
                       const enum mail_sort_type *sort_program)
 {
        struct client_command_context *cmd = ctx->cmd;
-       enum mail_fetch_field wanted_fields;
-       struct mailbox_header_lookup_ctx *wanted_headers;
 
        imap_search_args_check(ctx, sargs->args);
 
@@ -532,13 +488,10 @@ bool imap_search_start(struct imap_search_context *ctx,
        }
 
        ctx->box = cmd->client->mailbox;
-       wanted_fields_get(ctx->box, sort_program,
-                         &wanted_fields, &wanted_headers);
-
        ctx->trans = mailbox_transaction_begin(ctx->box, 0);
        ctx->sargs = sargs;
        ctx->search_ctx = mailbox_search_init(ctx->trans, sargs, sort_program);
-       ctx->mail = mail_alloc(ctx->trans, wanted_fields, wanted_headers);
+       ctx->mail = mail_alloc(ctx->trans, 0, NULL);
        ctx->sorting = sort_program != NULL;
        (void)gettimeofday(&ctx->start_time, NULL);
        i_array_init(&ctx->result, 128);
index 15e33082ce325e6f58c2e7a22bb5c93f66300c59..db56e3a323c4b4af3d829cff6ef781be30f7f5a7 100644 (file)
@@ -152,6 +152,7 @@ get_header_field_idx(struct mailbox *box, const char *field,
 bool index_mail_want_parse_headers(struct index_mail *mail)
 {
        if (mail->wanted_headers != NULL ||
+           mail->mail.extra_wanted_headers != NULL ||
            mail->data.save_bodystructure_header)
                return TRUE;
 
@@ -224,6 +225,13 @@ void index_mail_parse_header_init(struct index_mail *mail,
                                      &mail->header_match_value);
                }
        }
+       if (mail->mail.extra_wanted_headers != NULL) {
+               headers = mail->mail.extra_wanted_headers;
+               for (i = 0; i < headers->count; i++) {
+                       array_idx_set(&mail->header_match, headers->idx[i],
+                                     &mail->header_match_value);
+               }
+       }
 
        /* register also all the other headers that exist in cache file */
        T_BEGIN {
index 8a3691584d7d39886e1b9d87ae3d4c6fb4ab1c98..c7af18f90bcf17de8d71aa67463e24dc0ee296d9 100644 (file)
@@ -8,6 +8,9 @@ struct index_search_context {
        struct mail_index_view *view;
        struct mailbox *box;
 
+       enum mail_fetch_field extra_wanted_fields;
+       struct mailbox_header_lookup_ctx *extra_wanted_headers;
+
        uint32_t seq1, seq2;
        struct mail *mail;
        struct index_mail *imail;
index b50e6e06f01c5ca9df795790d22ef8bc59be650f..89ecd2b88ddd261e64ac9ecc6435e6eba19b7de1 100644 (file)
@@ -1040,6 +1040,46 @@ static int search_build_inthreads(struct index_search_context *ctx,
        return ret;
 }
 
+static void
+wanted_sort_fields_get(struct mailbox *box,
+                      const enum mail_sort_type *sort_program,
+                      enum mail_fetch_field *wanted_fields_r,
+                      struct mailbox_header_lookup_ctx **headers_ctx_r)
+{
+       const char *headers[2];
+
+       *wanted_fields_r = 0;
+       *headers_ctx_r = NULL;
+
+       headers[0] = headers[1] = NULL;
+       switch (sort_program[0] & MAIL_SORT_MASK) {
+       case MAIL_SORT_ARRIVAL:
+               *wanted_fields_r = MAIL_FETCH_RECEIVED_DATE;
+               break;
+       case MAIL_SORT_CC:
+               headers[0] = "Cc";
+               break;
+       case MAIL_SORT_DATE:
+               *wanted_fields_r = MAIL_FETCH_DATE;
+               break;
+       case MAIL_SORT_FROM:
+               headers[0] = "From";
+               break;
+       case MAIL_SORT_SIZE:
+               *wanted_fields_r = MAIL_FETCH_VIRTUAL_SIZE;
+               break;
+       case MAIL_SORT_SUBJECT:
+               headers[0] = "Subject";
+               break;
+       case MAIL_SORT_TO:
+               headers[0] = "To";
+               break;
+       }
+
+       if (headers[0] != NULL)
+               *headers_ctx_r = mailbox_header_lookup_init(box, headers);
+}
+
 void index_storage_search_init_context(struct index_search_context *ctx,
                                       struct mailbox_transaction_context *t,
                                       struct mail_search_args *args,
@@ -1071,6 +1111,12 @@ void index_storage_search_init_context(struct index_search_context *ctx,
                        ctx->failed = TRUE;
        }
 
+       if (sort_program != NULL) {
+               wanted_sort_fields_get(ctx->box, sort_program,
+                                      &ctx->extra_wanted_fields,
+                                      &ctx->extra_wanted_headers);
+       }
+
        search_get_seqset(ctx, status.messages, args->args);
        (void)mail_search_args_foreach(args->args, search_init_arg, ctx);
 
@@ -1117,6 +1163,8 @@ int index_storage_search_deinit(struct mail_search_context *_ctx)
        (void)mail_search_args_foreach(ctx->mail_ctx.args->args,
                                       search_arg_deinit, NULL);
 
+       if (ctx->extra_wanted_headers != NULL)
+               mailbox_header_lookup_unref(&ctx->extra_wanted_headers);
        if (ctx->mail_ctx.sort_program != NULL)
                index_sort_program_deinit(&ctx->mail_ctx.sort_program);
        if (ctx->thread_ctx != NULL)
@@ -1347,6 +1395,8 @@ bool index_storage_search_next_nonblock(struct mail_search_context *_ctx,
        }
 
        ctx->mail = mail;
+       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)
@@ -1396,6 +1446,8 @@ bool index_storage_search_next_nonblock(struct mail_search_context *_ctx,
        ctx->mail = NULL;
        ctx->imail = NULL;
        mail_private->stats_track = old_stats_track;
+       mail_private->extra_wanted_fields = 0;
+       mail_private->extra_wanted_headers = NULL;
 
        if (!match && _ctx->sort_program != NULL &&
            !*tryagain_r && !ctx->failed) {
index a2514a41fdd88c368958dc679cd38aaab5417530..b70d84427f789f78635110b295a0b409ade7caaa 100644 (file)
@@ -108,7 +108,9 @@ void index_sort_list_add(struct mail_search_sort_program *program,
 {
        i_assert(mail->transaction == program->t);
 
-       program->sort_list_add(program, mail);
+       T_BEGIN {
+               program->sort_list_add(program, mail);
+       } T_END;
 }
 
 static int sort_node_date_cmp(const struct mail_sort_node_date *n1,
index 305dd649a8a7b6b97b2ee98a27ce7bed4d7871c9..ed326ce7f3dbe67a0f2c80ea970251ed8e19b56a 100644 (file)
@@ -319,6 +319,12 @@ struct mail_private {
        pool_t pool;
        ARRAY_DEFINE(module_contexts, union mail_module_context *);
 
+       /* temporary extra wanted fields/headers that should be looked up
+          automatically if possible. for example sort_program fields during
+          search. */
+       enum mail_fetch_field extra_wanted_fields;
+       struct mailbox_header_lookup_ctx *extra_wanted_headers;
+
        /* these statistics are never reset by mail-storage API: */
 
        unsigned long stats_open_lookup_count;