]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Stop parsing cached headers when we've got everything.
authorTimo Sirainen <tss@iki.fi>
Mon, 8 Sep 2003 02:24:29 +0000 (05:24 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 8 Sep 2003 02:24:29 +0000 (05:24 +0300)
--HG--
branch : HEAD

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

index 2ef79c875b8d651a0f39e0bd78331ccef7c151f8..1220d33129b4b65cc55d9cf0010c4da7f279466c 100644 (file)
@@ -240,10 +240,15 @@ void index_mail_parse_header_init(struct index_mail *mail,
        data = buffer_get_modifyable_data(mail->data.headers, &size);
        size /= sizeof(struct cached_header *);
 
+       mail->data.parsing_count = 0;
        if (headers == NULL) {
                /* parsing all headers */
-               for (i = 0; i < size; i++)
-                       data[i]->parsing = TRUE;
+               for (i = 0; i < size; i++) {
+                       if (!data[i]->fully_saved) {
+                               data[i]->parsing = TRUE;
+                               mail->data.parsing_count++;
+                       }
+               }
        } else {
                t_push();
                headers = sort_array(headers);
@@ -251,7 +256,10 @@ void index_mail_parse_header_init(struct index_mail *mail,
                        cmp = strcasecmp(*headers, data[i]->name);
                        if (cmp <= 0) {
                                if (cmp == 0) {
-                                       data[i]->parsing = TRUE;
+                                       if (!data[i]->fully_saved) {
+                                               data[i]->parsing = TRUE;
+                                               mail->data.parsing_count++;
+                                       }
                                        i++;
                                }
                                headers++;
@@ -261,12 +269,17 @@ void index_mail_parse_header_init(struct index_mail *mail,
                }
                t_pop();
        }
+
+       if (mail->data.save_sent_date || mail->data.save_envelope) {
+               /* parse the whole header */
+               mail->data.parsing_count = -1;
+       }
 }
 
-void index_mail_parse_header(struct message_part *part,
-                            struct message_header_line *hdr, void *context)
+int index_mail_parse_header(struct message_part *part,
+                           struct message_header_line *hdr,
+                           struct index_mail *mail)
 {
-       struct index_mail *mail = context;
        struct index_mail_data *data = &mail->data;
        struct cached_header *cached_hdr;
        int timezone;
@@ -275,7 +288,7 @@ void index_mail_parse_header(struct message_part *part,
                imap_bodystructure_parse_header(mail->pool, part, hdr);
 
        if (part != NULL && part->parent != NULL)
-               return;
+               return FALSE;
 
        if (data->save_envelope) {
                imap_envelope_parse_header(mail->pool,
@@ -306,7 +319,7 @@ void index_mail_parse_header(struct message_part *part,
                }
 
                cached_headers_mark_fully_saved(mail);
-               return;
+               return TRUE;
        }
 
        if (data->save_sent_date && strcasecmp(hdr->name, "Date") == 0) {
@@ -341,14 +354,32 @@ void index_mail_parse_header(struct message_part *part,
                                     hdr->value, hdr->value_len);
                        if (!hdr->no_newline)
                                str_append(data->header_data, "\n");
+                       if (!hdr->continues) {
+                               cached_hdr->fully_saved = TRUE;
+                               data->parsing_count--;
+                       }
                } else {
                        /* it's already in header_data. */
-                       if (cached_hdr->value_idx == 0) {
-                               cached_hdr->value_idx =
-                                       data->header_stream->v_offset;
-                       }
+                       i_assert(cached_hdr->value_idx == 0);
+                       cached_hdr->value_idx = data->header_stream->v_offset;
+
+                       cached_hdr->fully_saved = TRUE;
+                       data->parsing_count--;
                }
+
+               if (data->parsing_count == 0)
+                       return FALSE;
        }
+       return TRUE;
+}
+
+static void index_mail_parse_header_cb(struct message_part *part,
+                                      struct message_header_line *hdr,
+                                      void *context)
+{
+       struct index_mail *mail = context;
+
+       (void)index_mail_parse_header(part, hdr, mail);
 }
 
 static int index_mail_can_cache_headers(struct index_mail *mail)
@@ -421,8 +452,17 @@ static int parse_cached_headers(struct index_mail *mail, int idx)
        }
 
        index_mail_parse_header_init(mail, idx_headers);
-       message_parse_header(NULL, istream, NULL,
-                            index_mail_parse_header, mail);
+
+       struct message_header_parser_ctx *hdr_ctx;
+       struct message_header_line *hdr;
+
+       hdr_ctx = message_parse_header_init(istream, NULL);
+       while ((hdr = message_parse_header_next(hdr_ctx)) != NULL) {
+               if (!index_mail_parse_header(NULL, hdr, mail))
+                       break;
+       }
+       message_parse_header_deinit(hdr_ctx);
+       index_mail_parse_header(NULL, NULL, mail);
 
        data->header_stream = NULL;
        i_stream_unref(istream);
@@ -504,12 +544,12 @@ int index_mail_parse_headers(struct index_mail *mail)
 
        if (data->parts != NULL || data->parser_ctx != NULL) {
                message_parse_header(data->parts, data->stream, &data->hdr_size,
-                                    index_mail_parse_header, mail);
+                                    index_mail_parse_header_cb, mail);
        } else {
                data->parser_ctx =
                        message_parser_init(mail->pool, data->stream);
                message_parser_parse_header(data->parser_ctx, &data->hdr_size,
-                                           index_mail_parse_header, mail);
+                                           index_mail_parse_header_cb, mail);
        }
        data->hdr_size_set = TRUE;
 
index aa294ebb3507d30a6cd6dd9e55fdb93d72de41f2..133aa7d7005021a1a2a2fd9338524877de7d94af 100644 (file)
@@ -31,6 +31,7 @@ struct index_mail_data {
        struct istream *stream;
        struct message_size hdr_size, body_size;
        struct message_parser_ctx *parser_ctx;
+       int parsing_count;
 
        unsigned int parse_header:1;
        unsigned int bodystructure_header_want:1;
@@ -69,8 +70,9 @@ void index_mail_deinit(struct index_mail *mail);
 
 void index_mail_parse_header_init(struct index_mail *mail,
                                  const char *const headers[]);
-void index_mail_parse_header(struct message_part *part,
-                            struct message_header_line *hdr, void *context);
+int index_mail_parse_header(struct message_part *part,
+                           struct message_header_line *hdr,
+                           struct index_mail *mail);
 
 int index_mail_cache_transaction_begin(struct index_mail *mail);
 void index_mail_cache_add(struct index_mail *mail, enum mail_cache_field field,
index 410df572c9d7c57113f1c5c932772dd7e3dcb01a..d33752b6ef147d514c874392a74566a051169317 100644 (file)
@@ -482,7 +482,7 @@ static void search_header(struct message_part *part,
        if (hdr->eoh)
                return;
 
-       index_mail_parse_header(part, hdr, ctx->index_context->mail);
+       index_mail_parse_header(part, hdr, &ctx->index_context->imail);
 
        if (ctx->custom_header || strcasecmp(hdr->name, "Date") == 0) {
                ctx->hdr = hdr;