[dovecot-cvs] dovecot/src/lib-storage/index index-mail-headers.c,
1.26, 1.27 index-mail.c, 1.43, 1.44 index-mail.h, 1.17,
1.18 index-search.c, 1.91, 1.92 index-storage.c, 1.57,
1.58 index-storage.h, 1.73, 1.74
cras at dovecot.org
cras at dovecot.org
Sun Jul 18 05:25:10 EEST 2004
Update of /home/cvs/dovecot/src/lib-storage/index
In directory talvi:/tmp/cvs-serv3398/lib-storage/index
Modified Files:
index-mail-headers.c index-mail.c index-mail.h index-search.c
index-storage.c index-storage.h
Log Message:
Header caching redesigned. New design allows caching decisions per field, so
they can be divided to temporary/permanent. Cached headers are now always
returned in original order, old code didn't guarantee it. Some other caching
changes. (still missing code to store changes in caching decisions)
Index: index-mail-headers.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail-headers.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- index-mail-headers.c 9 Jul 2004 00:10:37 -0000 1.26
+++ index-mail-headers.c 18 Jul 2004 02:25:07 -0000 1.27
@@ -1,45 +1,12 @@
/* Copyright (C) 2003 Timo Sirainen */
-/*
- Headers are stored in 1-4 pieces. There's a list of header names that each
- piece contains, so if piece doesn't actually contain some listed header,
- it's known not to exist in the mail at all.
-
- Header name lists are stored in sorted order, so we can use binary
- searching.
-
- We have to be able to do 3 things:
[...1085 lines suppressed...]
+
+ /* @UNSAFE */
+ for (i = 0; i < size; i++) {
+ ctx->idx[i] = fields[i].idx;
+ ctx->name[i] = p_strdup(pool, sorted_headers[i]);
+ }
}
- data->header_save = FALSE;
+
+ t_pop();
+ return &ctx->ctx;
+}
+
+void index_header_lookup_deinit(struct mailbox_header_lookup_ctx *_ctx)
+{
+ struct index_header_lookup_ctx *ctx =
+ (struct index_header_lookup_ctx *)_ctx;
+
+ pool_unref(ctx->pool);
}
Index: index-mail.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- index-mail.c 11 Jul 2004 21:04:46 -0000 1.43
+++ index-mail.c 18 Jul 2004 02:25:07 -0000 1.44
@@ -13,6 +13,22 @@
#include "index-storage.h"
#include "index-mail.h"
+struct mail_cache_field cache_fields[MAIL_CACHE_FIELD_COUNT] = {
+ { "index.flags", 0, MAIL_CACHE_FIELD_BITMASK,
+ sizeof(uint32_t), 0, 0, 0 },
+ { "date.sent", 0, MAIL_CACHE_FIELD_FIXED_SIZE,
+ sizeof(struct mail_sent_date), 0, 0, 0 },
+ { "date.received", 0, MAIL_CACHE_FIELD_FIXED_SIZE,
+ sizeof(time_t), 0, 0, 0 },
+ { "size.virtual", 0, MAIL_CACHE_FIELD_FIXED_SIZE,
+ sizeof(uoff_t), 0, 0, 0 },
+ { "imap.body", 0, MAIL_CACHE_FIELD_STRING, 0, 0, 0, 0 },
+ { "imap.bodystructure", 0, MAIL_CACHE_FIELD_STRING, 0, 0, 0, 0 },
+ { "imap.envelope", 0, MAIL_CACHE_FIELD_STRING, 0, 0, 0, 0 },
+ { "mime.parts", 0, MAIL_CACHE_FIELD_VARIABLE_SIZE, 0, 0, 0, 0 },
+ { "mail.uid", 0, MAIL_CACHE_FIELD_STRING, 0, 0, 0, 0 }
+};
+
static void index_mail_parse_body(struct index_mail *mail, int need_parts);
static struct message_part *get_cached_parts(struct index_mail *mail)
@@ -25,8 +41,8 @@
part_buf = buffer_create_dynamic(pool_datastack_create(),
128, (size_t)-1);
if (mail_cache_lookup_field(mail->trans->cache_view, part_buf,
- mail->data.seq,
- MAIL_CACHE_MESSAGEPART) <= 0) {
+ mail->data.seq,
+ cache_fields[MAIL_CACHE_MESSAGEPART].idx) <= 0) {
t_pop();
return NULL;
}
@@ -56,13 +72,14 @@
}
const char *index_mail_get_cached_string(struct index_mail *mail,
- enum mail_cache_field field)
+ enum index_cache_field field)
{
string_t *str;
str = str_new(mail->pool, 32);
- if (mail_cache_lookup_string_field(mail->trans->cache_view, str,
- mail->data.seq, field) <= 0) {
+ if (mail_cache_lookup_field(mail->trans->cache_view, str,
+ mail->data.seq,
+ cache_fields[field].idx) <= 0) {
p_free(mail->pool, str);
return NULL;
}
@@ -71,7 +88,7 @@
}
static int index_mail_get_fixed_field(struct index_mail *mail,
- enum mail_cache_field field,
+ enum index_cache_field field,
void *data, size_t data_size)
{
buffer_t *buf;
@@ -80,7 +97,8 @@
t_push();
buf = buffer_create_data(pool_datastack_create(), data, data_size);
if (mail_cache_lookup_field(mail->trans->cache_view, buf,
- mail->data.seq, field) <= 0) {
+ mail->data.seq,
+ cache_fields[field].idx) <= 0) {
ret = FALSE;
} else {
i_assert(buffer_get_used_size(buf) == data_size);
@@ -92,11 +110,12 @@
}
uoff_t index_mail_get_cached_uoff_t(struct index_mail *mail,
- enum mail_cache_field field)
+ enum index_cache_field field)
{
uoff_t uoff;
- if (!index_mail_get_fixed_field(mail, field, &uoff, sizeof(uoff)))
+ if (!index_mail_get_fixed_field(mail, cache_fields[field].idx,
+ &uoff, sizeof(uoff)))
uoff = (uoff_t)-1;
return uoff;
@@ -207,7 +226,8 @@
}
data->sent_date.timezone = tz;
mail_cache_add(mail->trans->cache_trans, mail->data.seq,
- MAIL_CACHE_SENT_DATE, &data->sent_date,
+ cache_fields[MAIL_CACHE_SENT_DATE].idx,
+ &data->sent_date,
sizeof(data->sent_date));
}
}
@@ -258,9 +278,9 @@
return data->size;
}
-static void parse_bodystructure_header(struct message_part *part,
- struct message_header_line *hdr,
- void *context)
+static void parse_bodystructure_part_header(struct message_part *part,
+ struct message_header_line *hdr,
+ void *context)
{
pool_t pool = context;
@@ -281,11 +301,12 @@
i_stream_seek(data->stream, data->hdr_size.physical_size);
- if (data->bodystructure_header_parsed) {
+ if (data->save_bodystructure_body) {
/* bodystructure header is parsed, we want the body's mime
headers too */
+ i_assert(!data->save_bodystructure_header);
message_parser_parse_body(data->parser_ctx,
- parse_bodystructure_header,
+ parse_bodystructure_part_header,
NULL, mail->pool);
} else {
message_parser_parse_body(data->parser_ctx, NULL, NULL, NULL);
@@ -307,7 +328,7 @@
}
/* update cache_flags */
- cache_flags =
+ /*FIXME:cache_flags =
mail_cache_get_record_flags(mail->trans->cache_view,
mail->data.seq);
if (mail->mail.has_nuls)
@@ -317,16 +338,16 @@
(void)mail_cache_update_record_flags(mail->trans->cache_view,
mail->data.seq,
- cache_flags);
+ cache_flags);*/
}
/* see if we want to cache the message part */
if (mail_cache_field_exists(mail->trans->cache_view, mail->data.seq,
- MAIL_CACHE_MESSAGEPART) != 0)
+ cache_fields[MAIL_CACHE_MESSAGEPART].idx) != 0)
return;
decision = mail_cache_field_get_decision(mail->ibox->cache,
- MAIL_CACHE_MESSAGEPART);
+ cache_fields[MAIL_CACHE_MESSAGEPART].idx);
if (decision != (MAIL_CACHE_DECISION_NO | MAIL_CACHE_DECISION_FORCED) &&
(decision != MAIL_CACHE_DECISION_NO || need_parts ||
(mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) != 0)) {
@@ -337,7 +358,8 @@
buf_data = buffer_get_data(buffer, &buf_size);
mail_cache_add(mail->trans->cache_trans, mail->data.seq,
- MAIL_CACHE_MESSAGEPART, buf_data, buf_size);
+ cache_fields[MAIL_CACHE_MESSAGEPART].idx,
+ buf_data, buf_size);
t_pop();
}
}
@@ -378,15 +400,17 @@
}
static void index_mail_parse_bodystructure(struct index_mail *mail,
- enum mail_cache_field field)
+ enum index_cache_field field)
{
struct index_mail_data *data = &mail->data;
enum mail_cache_decision_type dec;
string_t *str;
int bodystructure_cached = FALSE;
- if (!data->bodystructure_header_parsed) {
- data->bodystructure_header_want = TRUE;
+ if (data->save_bodystructure_header || !data->save_bodystructure_body) {
+ /* we haven't parsed the header yet */
+ data->save_bodystructure_header = TRUE;
+ data->save_bodystructure_body = TRUE;
if (!index_mail_parse_headers(mail))
return;
}
@@ -394,18 +418,18 @@
if (data->parts != NULL) {
i_assert(data->parts->next == NULL);
message_parse_from_parts(data->parts->children, data->stream,
- parse_bodystructure_header,
+ parse_bodystructure_part_header,
mail->pool);
} else {
index_mail_parse_body(mail, FALSE);
}
dec = mail_cache_field_get_decision(mail->ibox->cache,
- MAIL_CACHE_BODYSTRUCTURE);
+ cache_fields[MAIL_CACHE_BODYSTRUCTURE].idx);
if (field == MAIL_CACHE_BODYSTRUCTURE ||
((dec & ~MAIL_CACHE_DECISION_FORCED) != MAIL_CACHE_DECISION_NO &&
mail_cache_field_exists(mail->trans->cache_view, data->seq,
- MAIL_CACHE_BODYSTRUCTURE)) == 0) {
+ cache_fields[MAIL_CACHE_BODYSTRUCTURE].idx) == 0)) {
str = str_new(mail->pool, 128);
imap_bodystructure_write(data->parts, str, TRUE);
data->bodystructure = str_c(str);
@@ -413,17 +437,18 @@
if (dec !=
(MAIL_CACHE_DECISION_NO | MAIL_CACHE_DECISION_FORCED)) {
mail_cache_add(mail->trans->cache_trans, data->seq,
- MAIL_CACHE_BODYSTRUCTURE,
- str_c(str), str_len(str)+1);
+ cache_fields[MAIL_CACHE_BODYSTRUCTURE].idx,
+ str_c(str), str_len(str)+1);
bodystructure_cached = TRUE;
}
}
- dec = mail_cache_field_get_decision(mail->ibox->cache, MAIL_CACHE_BODY);
+ dec = mail_cache_field_get_decision(mail->ibox->cache,
+ cache_fields[MAIL_CACHE_BODY].idx);
if (field == MAIL_CACHE_BODY ||
((dec & ~MAIL_CACHE_DECISION_FORCED) != MAIL_CACHE_DECISION_NO &&
mail_cache_field_exists(mail->trans->cache_view, data->seq,
- MAIL_CACHE_BODY)) == 0) {
+ cache_fields[MAIL_CACHE_BODY].idx) == 0)) {
str = str_new(mail->pool, 128);
imap_bodystructure_write(data->parts, str, FALSE);
data->body = str_c(str);
@@ -431,7 +456,7 @@
if (!bodystructure_cached && dec !=
(MAIL_CACHE_DECISION_NO | MAIL_CACHE_DECISION_FORCED)) {
mail_cache_add(mail->trans->cache_trans, data->seq,
- MAIL_CACHE_BODY,
+ cache_fields[MAIL_CACHE_BODY].idx,
str_c(str), str_len(str)+1);
}
}
@@ -455,16 +480,16 @@
depending on what we want cached */
str = str_new(mail->pool, 128);
- if (mail_cache_lookup_string_field(mail->trans->cache_view,
- str, mail->data.seq,
- MAIL_CACHE_BODY) > 0) {
+ if (mail_cache_lookup_field(mail->trans->cache_view, str,
+ mail->data.seq,
+ cache_fields[MAIL_CACHE_BODY].idx) > 0) {
data->body = str_c(str);
return data->body;
}
- if (mail_cache_lookup_string_field(mail->trans->cache_view,
- str, mail->data.seq,
- MAIL_CACHE_BODYSTRUCTURE) > 0) {
- data->bodystructure = str_c(str);
+ if (mail_cache_lookup_field(mail->trans->cache_view, str,
+ mail->data.seq,
+ cache_fields[MAIL_CACHE_BODYSTRUCTURE].idx) > 0) {
+ data->bodystructure = p_strdup(mail->pool, str_c(str));
str_truncate(str, 0);
if (imap_body_parse_from_bodystructure(
@@ -474,10 +499,10 @@
}
/* broken, continue.. */
- data->bodystructure = NULL;
mail_cache_set_corrupted(mail->ibox->cache,
"Corrupted BODYSTRUCTURE for mail %u",
mail->mail.uid);
+ data->bodystructure = NULL;
}
p_free(mail->pool, str);
@@ -488,9 +513,9 @@
return data->bodystructure;
str = str_new(mail->pool, 128);
- if (mail_cache_lookup_string_field(mail->trans->cache_view,
- str, mail->data.seq,
- MAIL_CACHE_BODYSTRUCTURE) > 0) {
+ if (mail_cache_lookup_field(mail->trans->cache_view, str,
+ mail->data.seq,
+ cache_fields[MAIL_CACHE_BODYSTRUCTURE].idx) > 0) {
data->bodystructure = str_c(str);
return data->bodystructure;
}
@@ -499,11 +524,8 @@
index_mail_parse_bodystructure(mail, MAIL_CACHE_BODYSTRUCTURE);
return data->bodystructure;
case MAIL_FETCH_IMAP_ENVELOPE:
- if (data->envelope != NULL)
- return data->envelope;
-
- data->save_envelope = TRUE;
- (void)_mail->get_header(_mail, "Date");
+ if (data->envelope == NULL)
+ index_mail_headers_get_envelope(mail);
return data->envelope;
case MAIL_FETCH_FROM_ENVELOPE:
return NULL;
@@ -523,8 +545,10 @@
void index_mail_init(struct index_transaction_context *t,
struct index_mail *mail,
enum mail_fetch_field wanted_fields,
- const char *const wanted_headers[])
+ struct mailbox_header_lookup_ctx *_wanted_headers)
{
+ struct index_header_lookup_ctx *wanted_headers =
+ (struct index_header_lookup_ctx *)_wanted_headers;
const struct mail_index_header *hdr;
int ret;
@@ -541,16 +565,14 @@
mail->trans = t;
mail->wanted_fields = wanted_fields;
mail->wanted_headers = wanted_headers;
-
- index_mail_headers_init(mail);
}
static void index_mail_close(struct index_mail *mail)
{
if (mail->data.stream != NULL)
i_stream_unref(mail->data.stream);
-
- index_mail_headers_close(mail);
+ if (mail->data.filter_stream != NULL)
+ i_stream_unref(mail->data.filter_stream);
}
int index_mail_next(struct index_mail *mail, uint32_t seq)
@@ -564,13 +586,12 @@
return -1;
}
- t_push();
-
index_mail_close(mail);
+
memset(data, 0, sizeof(*data));
p_clear(mail->pool);
- cache_flags = mail_cache_get_record_flags(mail->trans->cache_view, seq);
+ cache_flags = 0;//FIXME:mail_cache_get_record_flags(mail->trans->cache_view, seq);
mail->mail.seq = seq;
mail->mail.uid = rec->uid;
@@ -583,6 +604,8 @@
data->size = (uoff_t)-1;
data->received_date = data->sent_date.time = (time_t)-1;
+ t_push();
+
/* if some wanted fields are cached, get them */
if (mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS)
data->parts = get_cached_parts(mail);
@@ -611,20 +634,20 @@
data->parts = get_cached_parts(mail);
data->open_mail = TRUE;
data->parse_header = data->parts == NULL;
- data->bodystructure_header_want = TRUE;
+ data->save_bodystructure_header = TRUE;
+ data->save_bodystructure_body = TRUE;
} else if ((mail->wanted_fields & MAIL_FETCH_IMAP_BODY) &&
data->body == NULL && data->bodystructure == NULL) {
if (data->parts == NULL)
data->parts = get_cached_parts(mail);
data->open_mail = TRUE;
data->parse_header = data->parts == NULL;
- data->bodystructure_header_want = TRUE;
+ data->save_bodystructure_header = TRUE;
+ data->save_bodystructure_body = TRUE;
} else if (mail->wanted_fields & (MAIL_FETCH_STREAM_HEADER |
MAIL_FETCH_STREAM_BODY))
data->open_mail = TRUE;
- index_mail_headers_init_next(mail);
-
if ((mail->wanted_fields & MAIL_FETCH_DATE) &&
data->sent_date.time == (time_t)-1)
data->save_sent_date = TRUE;
@@ -641,9 +664,14 @@
if (mail->ibox->mail_deinit != NULL)
mail->ibox->mail_deinit(mail);
- t_push();
index_mail_close(mail);
- t_pop();
+
+ if (mail->header_data != NULL)
+ buffer_free(mail->header_data);
+ if (mail->header_lines != NULL)
+ buffer_free(mail->header_lines);
+ if (mail->header_match != NULL)
+ buffer_free(mail->header_match);
pool_unref(mail->pool);
memset(mail, 0, sizeof(*mail));
Index: index-mail.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- index-mail.h 9 Jul 2004 00:10:38 -0000 1.17
+++ index-mail.h 18 Jul 2004 02:25:07 -0000 1.18
@@ -5,6 +5,50 @@
#include "mail-cache.h"
#include "mail-storage-private.h"
+enum index_cache_field {
+ /* fixed size fields */
+ MAIL_CACHE_INDEX_FLAGS = 0,
+ MAIL_CACHE_SENT_DATE,
+ MAIL_CACHE_RECEIVED_DATE,
+ MAIL_CACHE_VIRTUAL_FULL_SIZE,
+
+ /* variable sized field */
+ MAIL_CACHE_BODY,
+ MAIL_CACHE_BODYSTRUCTURE,
+ MAIL_CACHE_ENVELOPE,
+ MAIL_CACHE_MESSAGEPART,
+ MAIL_CACHE_UID_STRING,
+
+ MAIL_CACHE_FIELD_COUNT
+};
+extern struct mail_cache_field cache_fields[MAIL_CACHE_FIELD_COUNT];
+
+enum mail_cache_record_flag {
+ /* If binary flags are set, it's not checked whether mail is
+ missing CRs. So this flag may be set as an optimization for
+ regular non-binary mails as well if it's known that it contains
+ valid CR+LF line breaks. */
+ MAIL_INDEX_FLAG_BINARY_HEADER = 0x0001,
+ MAIL_INDEX_FLAG_BINARY_BODY = 0x0002,
+
+ /* Mail header or body is known to contain NUL characters. */
+ MAIL_INDEX_FLAG_HAS_NULS = 0x0004,
+ /* Mail header or body is known to not contain NUL characters. */
+ MAIL_INDEX_FLAG_HAS_NO_NULS = 0x0008
+};
+
+struct mail_sent_date {
+ time_t time;
+ int32_t timezone;
+};
+
+struct index_mail_line {
+ unsigned int field_idx;
+ uint32_t start_pos, end_pos;
+ uint32_t line_num;
+ unsigned int cache:1;
+};
+
struct message_header_line;
struct index_mail_data {
@@ -13,13 +57,8 @@
uoff_t size;
struct mail_sent_date sent_date;
-
- buffer_t *headers;
- string_t *header_data;
- int header_data_cached, header_data_cached_contiguous;
- size_t header_data_uncached_offset;
- struct istream *header_stream;
- int header_save_idx;
+ struct index_mail_line parse_line;
+ uint32_t parse_line_num;
struct message_part *parts;
const char *envelope, *body, *bodystructure, *uid_string;
@@ -28,24 +67,20 @@
uint32_t seq;
const struct mail_index_record *rec;
- struct istream *stream;
+ struct istream *stream, *filter_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;
- unsigned int bodystructure_header_parse:1;
- unsigned int bodystructure_header_parsed:1;
unsigned int save_envelope:1;
unsigned int save_sent_date:1;
+ unsigned int save_bodystructure_header:1;
+ unsigned int save_bodystructure_body:1;
unsigned int hdr_size_set:1;
unsigned int body_size_set:1;
- unsigned int deleted:1;
- unsigned int header_data_cached_partial:1;
- unsigned int header_fully_parsed:1;
- unsigned int header_save:1;
unsigned int open_mail:1;
+ unsigned int deleted:1;
};
struct index_mail {
@@ -55,37 +90,37 @@
pool_t pool;
struct index_mailbox *ibox;
struct index_transaction_context *trans;
- unsigned int expunge_counter;
- buffer_t *header_buf;
uint32_t uid_validity;
enum mail_fetch_field wanted_fields;
- const char *const *wanted_headers;
- int wanted_headers_idx;
+ struct index_header_lookup_ctx *wanted_headers;
+
+ /* per-mail variables, here for performance reasons: */
+ string_t *header_data;
+ buffer_t *header_lines;
+ buffer_t *header_match;
+ uint8_t header_match_value;
};
void index_mail_init(struct index_transaction_context *t,
struct index_mail *mail,
enum mail_fetch_field wanted_fields,
- const char *const wanted_headers[]);
+ struct mailbox_header_lookup_ctx *wanted_headers);
int index_mail_next(struct index_mail *mail, uint32_t seq);
void index_mail_deinit(struct index_mail *mail);
void index_mail_parse_header_init(struct index_mail *mail,
- const char *const headers[]);
+ struct mailbox_header_lookup_ctx *headers);
int index_mail_parse_header(struct message_part *part,
struct message_header_line *hdr,
struct index_mail *mail);
-
int index_mail_parse_headers(struct index_mail *mail);
-
-void index_mail_headers_init(struct index_mail *mail);
-void index_mail_headers_init_next(struct index_mail *mail);
-void index_mail_headers_close(struct index_mail *mail);
+void index_mail_headers_get_envelope(struct index_mail *mail);
const char *index_mail_get_header(struct mail *_mail, const char *field);
-struct istream *index_mail_get_headers(struct mail *_mail,
- const char *const minimum_fields[]);
+struct istream *
+index_mail_get_headers(struct mail *_mail,
+ struct mailbox_header_lookup_ctx *headers);
const struct mail_full_flags *index_mail_get_flags(struct mail *_mail);
const struct message_part *index_mail_get_parts(struct mail *_mail);
@@ -104,9 +139,9 @@
int index_mail_expunge(struct mail *mail);
const char *index_mail_get_cached_string(struct index_mail *mail,
- enum mail_cache_field field);
+ enum index_cache_field field);
uoff_t index_mail_get_cached_uoff_t(struct index_mail *mail,
- enum mail_cache_field field);
+ enum index_cache_field field);
uoff_t index_mail_get_cached_virtual_size(struct index_mail *mail);
time_t index_mail_get_cached_received_date(struct index_mail *mail);
Index: index-search.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-search.c,v
retrieving revision 1.91
retrieving revision 1.92
diff -u -d -r1.91 -r1.92
--- index-search.c 8 Jul 2004 20:26:16 -0000 1.91
+++ index-search.c 18 Jul 2004 02:25:07 -0000 1.92
@@ -444,7 +444,7 @@
if (hdr->eoh)
return;
- index_mail_parse_header(part, hdr, &ctx->index_context->imail);
+ index_mail_parse_header(NULL, hdr, &ctx->index_context->imail);
if (ctx->custom_header || strcasecmp(hdr->name, "Date") == 0) {
ctx->hdr = hdr;
@@ -482,6 +482,7 @@
struct index_search_context *ctx)
{
struct istream *input;
+ struct mailbox_header_lookup_ctx *headers_ctx;
const char *const *headers;
int have_headers, have_body;
@@ -496,20 +497,33 @@
if (have_body)
headers = NULL;
- input = headers == NULL ?
- ctx->mail->get_stream(ctx->mail, NULL, NULL) :
- ctx->mail->get_headers(ctx->mail, headers);
- if (input == NULL)
- return FALSE;
+ if (headers == NULL) {
+ headers_ctx = NULL;
+ input = ctx->mail->get_stream(ctx->mail, NULL, NULL);
+ if (input == NULL)
+ return FALSE;
+ } else {
+ /* FIXME: do this once in init */
+ headers_ctx =
+ mailbox_header_lookup_init(&ctx->ibox->box,
+ headers);
+ input = ctx->mail->get_headers(ctx->mail, headers_ctx);
+ if (input == NULL) {
+ mailbox_header_lookup_deinit(headers_ctx);
+ return FALSE;
+ }
+ }
memset(&hdr_ctx, 0, sizeof(hdr_ctx));
hdr_ctx.index_context = ctx;
hdr_ctx.custom_header = TRUE;
hdr_ctx.args = args;
- index_mail_parse_header_init(&ctx->imail, headers);
+ index_mail_parse_header_init(&ctx->imail, headers_ctx);
message_parse_header(NULL, input, NULL,
search_header, &hdr_ctx);
+ if (headers_ctx != NULL)
+ mailbox_header_lookup_deinit(headers_ctx);
} else {
struct message_size hdr_size;
@@ -720,7 +734,7 @@
const char *charset, struct mail_search_arg *args,
const enum mail_sort_type *sort_program,
enum mail_fetch_field wanted_fields,
- const char *const wanted_headers[])
+ struct mailbox_header_lookup_ctx *wanted_headers)
{
struct index_transaction_context *t =
(struct index_transaction_context *)_t;
Index: index-storage.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-storage.c,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -d -r1.57 -r1.58
--- index-storage.c 11 Jul 2004 21:09:31 -0000 1.57
+++ index-storage.c 18 Jul 2004 02:25:07 -0000 1.58
@@ -11,6 +11,8 @@
#include <unistd.h>
#include <sys/stat.h>
+#define DEFAULT_NEVER_CACHE_FIELDS "imap.envelope"
+
/* How many seconds to keep index opened for reuse after it's been closed */
#define INDEX_CACHE_TIMEOUT 10
/* How many closed indexes to keep */
@@ -173,28 +175,9 @@
destroy_unrefed(TRUE);
}
-static void set_cache_fields(const char *fields,
- enum mail_cache_decision_type dest[32],
- enum mail_cache_decision_type dec)
+static void set_cache_decisions(const char *fields,
+ enum mail_cache_decision_type dec)
{
- static enum mail_cache_field field_enums[] = {
- MAIL_CACHE_SENT_DATE,
- MAIL_CACHE_RECEIVED_DATE,
- MAIL_CACHE_VIRTUAL_FULL_SIZE,
- MAIL_CACHE_BODY,
- MAIL_CACHE_BODYSTRUCTURE,
- MAIL_CACHE_MESSAGEPART
- };
- static const char *field_names[] = {
- "sent_date",
- "received_date",
- "virtual_size",
- "body",
- "bodystructure",
- "messagepart",
- NULL
- };
-
const char *const *arr;
int i;
@@ -202,33 +185,34 @@
return;
for (arr = t_strsplit_spaces(fields, " ,"); *arr != NULL; arr++) {
- for (i = 0; field_names[i] != NULL; i++) {
- if (strcasecmp(field_names[i], *arr) == 0) {
- dest[field_enums[i]] = dec;
+ for (i = 0; i < MAIL_CACHE_FIELD_COUNT; i++) {
+ if (strcasecmp(cache_fields[i].name, *arr) == 0) {
+ cache_fields[i].decision = dec;
break;
}
}
- if (field_names[i] == NULL) {
+ if (i == MAIL_CACHE_FIELD_COUNT) {
i_error("Invalid cache field name '%s', ignoring ",
*arr);
}
}
}
-static const enum mail_cache_decision_type *get_default_cache_decisions(void)
+static void index_cache_register_defaults(struct mail_cache *cache)
{
- static enum mail_cache_decision_type dec[32];
- static int dec_set = FALSE;
+ const char *never_env;
- if (dec_set)
- return dec;
+ never_env = getenv("MAIL_NEVER_CACHE_FIELDS");
+ if (never_env == NULL)
+ never_env = DEFAULT_NEVER_CACHE_FIELDS;
- memset(dec, 0, sizeof(dec));
- set_cache_fields(getenv("MAIL_CACHE_FIELDS"), dec,
- MAIL_CACHE_DECISION_TEMP);
- set_cache_fields(getenv("MAIL_NEVER_CACHE_FIELDS"), dec,
- MAIL_CACHE_DECISION_NO | MAIL_CACHE_DECISION_FORCED);
- return dec;
+ set_cache_decisions(getenv("MAIL_CACHE_FIELDS"),
+ MAIL_CACHE_DECISION_TEMP);
+ set_cache_decisions(never_env, MAIL_CACHE_DECISION_NO |
+ MAIL_CACHE_DECISION_FORCED);
+
+ mail_cache_register_fields(cache, cache_fields,
+ MAIL_CACHE_FIELD_COUNT);
}
void index_storage_lock_notify(struct index_mailbox *ibox,
@@ -327,8 +311,7 @@
break;
ibox->cache = mail_index_get_cache(index);
- mail_cache_set_defaults(ibox->cache,
- get_default_cache_decisions());
+ index_cache_register_defaults(ibox->cache);
ibox->view = mail_index_view_open(index);
return ibox;
} while (0);
Index: index-storage.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-storage.h,v
retrieving revision 1.73
retrieving revision 1.74
diff -u -d -r1.73 -r1.74
--- index-storage.h 12 Jul 2004 11:35:51 -0000 1.73
+++ index-storage.h 18 Jul 2004 02:25:07 -0000 1.74
@@ -181,6 +181,10 @@
int index_storage_get_uids(struct mailbox *box, uint32_t uid1, uint32_t uid2,
uint32_t *seq1_r, uint32_t *seq2_r);
+struct mailbox_header_lookup_ctx *
+index_header_lookup_init(struct mailbox *box, const char *const headers[]);
+void index_header_lookup_deinit(struct mailbox_header_lookup_ctx *ctx);
+
int index_storage_search_get_sorting(struct mailbox *box,
enum mail_sort_type *sort_program);
struct mail_search_context *
@@ -188,7 +192,7 @@
const char *charset, struct mail_search_arg *args,
const enum mail_sort_type *sort_program,
enum mail_fetch_field wanted_fields,
- const char *const wanted_headers[]);
+ struct mailbox_header_lookup_ctx *wanted_headers);
int index_storage_search_deinit(struct mail_search_context *ctx);
struct mail *index_storage_search_next(struct mail_search_context *ctx);
More information about the dovecot-cvs
mailing list