dovecot: Don't cache all headers just because they're listed in ...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Nov 22 07:56:43 EET 2007
details: http://hg.dovecot.org/dovecot/rev/efec8836586a
changeset: 6840:efec8836586a
user: Timo Sirainen <tss at iki.fi>
date: Thu Nov 22 07:46:25 2007 +0200
description:
Don't cache all headers just because they're listed in cache file. First
check if we actually want to cache them.
diffstat:
2 files changed, 48 insertions(+), 53 deletions(-)
src/lib-storage/index/index-mail-headers.c | 96 ++++++++++++----------------
src/lib-storage/index/index-mail.h | 5 +
diffs (184 lines):
diff -r af74d2e6f3c5 -r efec8836586a src/lib-storage/index/index-mail-headers.c
--- a/src/lib-storage/index/index-mail-headers.c Thu Nov 22 06:32:59 2007 +0200
+++ b/src/lib-storage/index/index-mail-headers.c Thu Nov 22 07:46:25 2007 +0200
@@ -70,16 +70,13 @@ static void index_mail_parse_header_fini
until lines[i] weren't found */
while (match_idx < lines[i].field_idx &&
match_idx < match_count) {
- /* if match[] doesn't have header_match_value,
- it belongs to some older header parsing and we
- just want to ignore it. */
- i_assert(match[match_idx] !=
- mail->header_match_value + 1);
- if (match[match_idx] == mail->header_match_value &&
- mail_cache_field_exists(mail->trans->cache_view,
- mail->data.seq,
- match_idx) == 0) {
+ if (HEADER_MATCH_USABLE(mail, match[match_idx]) &&
+ mail_cache_field_can_add(mail->trans->cache_trans,
+ mail->data.seq,
+ match_idx)) {
/* this header doesn't exist. remember that. */
+ i_assert((match[match_idx] &
+ HEADER_MATCH_FLAG_FOUND) == 0);
index_mail_cache_add_idx(mail, match_idx,
NULL, 0);
}
@@ -93,7 +90,9 @@ static void index_mail_parse_header_fini
match_idx++;
}
- if (!lines[i].cache) {
+ if (!mail_cache_field_can_add(mail->trans->cache_trans,
+ mail->data.seq,
+ lines[i].field_idx)) {
/* header is already cached */
j = i + 1;
continue;
@@ -135,10 +134,13 @@ static void index_mail_parse_header_fini
}
for (; match_idx < match_count; match_idx++) {
- if (match[match_idx] == mail->header_match_value &&
- mail_cache_field_exists(mail->trans->cache_view,
- mail->data.seq, match_idx) == 0) {
+ if (HEADER_MATCH_USABLE(mail, match[match_idx]) &&
+ mail_cache_field_can_add(mail->trans->cache_trans,
+ mail->data.seq,
+ match_idx)) {
/* this header doesn't exist. remember that. */
+ i_assert((match[match_idx] &
+ HEADER_MATCH_FLAG_FOUND) == 0);
index_mail_cache_add_idx(mail, match_idx, NULL, 0);
}
}
@@ -180,17 +182,20 @@ void index_mail_parse_header_init(struct
i_array_init(&mail->header_lines, 32);
i_array_init(&mail->header_match, 32);
i_array_init(&mail->header_match_lines, 32);
+ mail->header_match_value = HEADER_MATCH_SKIP_COUNT;
} else {
buffer_set_used_size(mail->header_data, 0);
array_clear(&mail->header_lines);
array_clear(&mail->header_match_lines);
- }
-
- mail->header_match_value += 2;
- if (mail->header_match_value == 0) {
- /* wrapped, we'll have to clear the buffer */
- array_clear(&mail->header_match);
- mail->header_match_value = 2;
+
+ mail->header_match_value += HEADER_MATCH_SKIP_COUNT;
+ i_assert((mail->header_match_value &
+ (HEADER_MATCH_SKIP_COUNT-1)) == 0);
+ if (mail->header_match_value == 0) {
+ /* wrapped, we'll have to clear the buffer */
+ array_clear(&mail->header_match);
+ mail->header_match_value = HEADER_MATCH_SKIP_COUNT;
+ }
}
if (headers != NULL) {
@@ -222,11 +227,14 @@ void index_mail_parse_header_init(struct
mail_cache_register_get_list(mail->ibox->cache,
pool_datastack_create(), &count);
for (i = 0; i < count; i++) {
- if (strncasecmp(all_cache_fields[i].name, "hdr.", 4) == 0) {
- array_idx_set(&mail->header_match,
- all_cache_fields[i].idx,
- &mail->header_match_value);
- }
+ if (strncasecmp(all_cache_fields[i].name, "hdr.", 4) != 0)
+ continue;
+ if (!mail_cache_field_want_add(mail->trans->cache_trans,
+ mail->data.seq, i))
+ continue;
+
+ array_idx_set(&mail->header_match, all_cache_fields[i].idx,
+ &mail->header_match_value);
}
t_pop();
}
@@ -288,34 +296,23 @@ void index_mail_parse_header(struct mess
t_pop();
}
field_idx = data->parse_line.field_idx;
-
- if (field_idx == (unsigned int)-1) {
- /* we don't want this field */
+ match = array_get_modifiable(&mail->header_match, &count);
+ if (field_idx >= count ||
+ !HEADER_MATCH_USABLE(mail, match[field_idx])) {
+ /* we don't want this header. */
return;
}
if (!hdr->continued) {
- data->parse_line.cache =
- mail_cache_field_want_add(mail->trans->cache_trans,
- data->seq, field_idx);
- }
-
- match = array_get_modifiable(&mail->header_match, &count);
- if (field_idx < count && match[field_idx] == mail->header_match_value) {
- /* first header */
- match[field_idx]++;
- } else if (!data->parse_line.cache &&
- (field_idx >= count ||
- (match[field_idx] & ~1) != mail->header_match_value)) {
- /* we don't need to do anything with this header */
- return;
- }
-
- if (!hdr->continued) {
+ /* beginning of a line. add the header name. */
data->parse_line.start_pos = str_len(mail->header_data);
data->parse_line.line_num = data->parse_line_num;
str_append(mail->header_data, hdr->name);
str_append_n(mail->header_data, hdr->middle, hdr->middle_len);
+
+ /* remember that we saw this header so we don't add it to
+ cache as nonexisting. */
+ match[field_idx] |= HEADER_MATCH_FLAG_FOUND;
}
str_append_n(mail->header_data, hdr->value, hdr->value_len);
if (!hdr->no_newline)
@@ -488,13 +485,8 @@ static int index_mail_header_is_parsed(s
unsigned int count;
match = array_get(&mail->header_match, &count);
- if (field_idx >= count)
- return -1;
-
- if (match[field_idx] == mail->header_match_value)
- return 0;
- else if (match[field_idx] == mail->header_match_value + 1)
- return 1;
+ if (field_idx < count && HEADER_MATCH_USABLE(mail, match[field_idx]))
+ return (match[field_idx] & HEADER_MATCH_FLAG_FOUND) != 0;
return -1;
}
diff -r af74d2e6f3c5 -r efec8836586a src/lib-storage/index/index-mail.h
--- a/src/lib-storage/index/index-mail.h Thu Nov 22 06:32:59 2007 +0200
+++ b/src/lib-storage/index/index-mail.h Thu Nov 22 07:46:25 2007 +0200
@@ -62,7 +62,6 @@ 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;
@@ -120,6 +119,10 @@ struct index_mail {
uint32_t header_seq;
string_t *header_data;
ARRAY_DEFINE(header_lines, struct index_mail_line);
+#define HEADER_MATCH_FLAG_FOUND 1
+#define HEADER_MATCH_SKIP_COUNT 2
+#define HEADER_MATCH_USABLE(mail, num) \
+ ((num & ~1) == (mail)->header_match_value)
ARRAY_DEFINE(header_match, uint8_t);
ARRAY_DEFINE(header_match_lines, unsigned int);
uint8_t header_match_value;
More information about the dovecot-cvs
mailing list