[dovecot-cvs] dovecot/src/lib-storage/index index-mail.c, 1.80,
1.81 index-mail.h, 1.33, 1.34
cras at dovecot.org
cras at dovecot.org
Sun Jul 3 17:18:30 EEST 2005
Update of /var/lib/cvs/dovecot/src/lib-storage/index
In directory talvi:/tmp/cvs-serv1597/index
Modified Files:
index-mail.c index-mail.h
Log Message:
Added MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII to compress simple BODY and
BODYSTRUCTURE replies into a single flag + message parts. Also did other
cleanups.
Index: index-mail.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/index-mail.c,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -d -r1.80 -r1.81
--- index-mail.c 3 Jul 2005 13:07:50 -0000 1.80
+++ index-mail.c 3 Jul 2005 14:18:28 -0000 1.81
@@ -14,12 +14,6 @@
#include "index-storage.h"
#include "index-mail.h"
-struct fetch_cache_map {
- enum mail_fetch_field fetch_field;
- enum index_cache_field cache_field;
- enum index_mail_access_part part;
-};
-
struct mail_cache_field global_cache_fields[MAIL_CACHE_FIELD_COUNT] = {
{ "flags", 0, MAIL_CACHE_FIELD_BITMASK, sizeof(uint32_t), 0 },
{ "date.sent", 0, MAIL_CACHE_FIELD_FIXED_SIZE,
@@ -36,23 +30,9 @@
{ "mime.parts", 0, MAIL_CACHE_FIELD_VARIABLE_SIZE, 0, 0 }
};
-static const struct fetch_cache_map fetch_cache_map[] = {
- { MAIL_FETCH_DATE, MAIL_CACHE_SENT_DATE, PARSE_HDR },
-
- { MAIL_FETCH_MESSAGE_PARTS,
- MAIL_CACHE_MESSAGEPART, PARSE_HDR | PARSE_BODY },
- { MAIL_FETCH_VIRTUAL_SIZE,
- MAIL_CACHE_VIRTUAL_FULL_SIZE, READ_HDR | READ_BODY },
-
- { MAIL_FETCH_IMAP_BODYSTRUCTURE,
- MAIL_CACHE_IMAP_BODYSTRUCTURE, PARSE_HDR | PARSE_BODY },
-
- { 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)
+static int get_cached_parts(struct index_mail *mail)
{
struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
struct message_part *part;
@@ -65,7 +45,7 @@
mail->data.seq,
cache_fields[MAIL_CACHE_MESSAGEPART].idx) <= 0) {
t_pop();
- return NULL;
+ return FALSE;
}
part = message_part_deserialize(mail->data_pool,
@@ -75,7 +55,7 @@
if (part == NULL) {
mail_cache_set_corrupted(mail->ibox->cache,
"Corrupted cached message_part data (%s)", error);
- return NULL;
+ return FALSE;
}
/* we know the NULs now, update them */
@@ -87,7 +67,8 @@
mail->mail.mail.has_no_nuls = TRUE;
}
- return part;
+ mail->data.parts = part;
+ return TRUE;
}
const char *index_mail_get_cached_string(struct index_mail *mail,
@@ -223,8 +204,7 @@
if (data->parts != NULL)
return data->parts;
- data->parts = get_cached_parts(mail);
- if (data->parts != NULL)
+ if (get_cached_parts(mail))
return data->parts;
if (data->parser_ctx == NULL) {
@@ -294,7 +274,7 @@
struct index_mail_data *data = &mail->data;
if (data->parts == NULL)
- data->parts = get_cached_parts(mail);
+ get_cached_parts(mail);
if (data->parts != NULL) {
data->hdr_size_set = TRUE;
@@ -393,10 +373,21 @@
data->parts = message_parser_deinit(data->parser_ctx);
data->parser_ctx = NULL;
+ if (data->parsed_bodystructure &&
+ imap_bodystructure_is_plain_7bit(data->parts)) {
+ data->cache_flags |= MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII;
+ /* we need message_parts cached to be able to
+ actually use it in BODY/BODYSTRUCTURE reply */
+ need_parts = TRUE;
+ }
+
data->body_size = data->parts->body_size;
data->body_size_set = TRUE;
- cache_flags = 0;
+ cache_flags = data->cache_flags & ~(MAIL_CACHE_FLAG_BINARY_HEADER |
+ MAIL_CACHE_FLAG_BINARY_BODY |
+ MAIL_CACHE_FLAG_HAS_NULS |
+ MAIL_CACHE_FLAG_HAS_NO_NULS);
if (!mail->mail.mail.has_nuls && !mail->mail.mail.has_no_nuls) {
/* we know the NULs now, update them */
if ((data->parts->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0) {
@@ -418,7 +409,8 @@
if (data->body_size.virtual_size == data->body_size.physical_size)
cache_flags |= MAIL_CACHE_FLAG_BINARY_BODY;
- if ((cache_flags & ~data->cache_flags) != 0) {
+ if (cache_flags != data->cache_flags) {
+ data->cache_flags = cache_flags;
mail_cache_add(mail->trans->cache_trans, mail->data.seq,
cache_fields[MAIL_CACHE_FLAGS].idx,
&cache_flags, sizeof(cache_flags));
@@ -443,6 +435,7 @@
cache_fields[MAIL_CACHE_MESSAGEPART].idx,
buf_data, buf_size);
t_pop();
+ data->messageparts_saved_to_cache = TRUE;
}
}
@@ -504,6 +497,7 @@
enum mail_cache_decision_type dec;
string_t *str;
int bodystructure_cached = FALSE;
+ int plain_bodystructure = FALSE;
if (!data->parsed_bodystructure) {
if (data->save_bodystructure_header ||
@@ -529,6 +523,15 @@
}
}
+ if ((data->cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) != 0) {
+ if (data->messageparts_saved_to_cache ||
+ mail_cache_field_exists(mail->trans->cache_view, data->seq,
+ cache_fields[MAIL_CACHE_MESSAGEPART].idx) > 0) {
+ /* cached it as flag + message_parts */
+ plain_bodystructure = TRUE;
+ }
+ }
+
dec = mail_cache_field_get_decision(mail->ibox->cache,
cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx);
if (field == MAIL_CACHE_IMAP_BODYSTRUCTURE ||
@@ -539,8 +542,9 @@
imap_bodystructure_write(data->parts, str, TRUE);
data->bodystructure = str_c(str);
- if (dec !=
- (MAIL_CACHE_DECISION_NO | MAIL_CACHE_DECISION_FORCED)) {
+ if (!plain_bodystructure &&
+ dec != (MAIL_CACHE_DECISION_NO |
+ MAIL_CACHE_DECISION_FORCED)) {
mail_cache_add(mail->trans->cache_trans, data->seq,
cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx,
str_c(str), str_len(str)+1);
@@ -558,8 +562,9 @@
imap_bodystructure_write(data->parts, str, FALSE);
data->body = str_c(str);
- if (!bodystructure_cached && dec !=
- (MAIL_CACHE_DECISION_NO | MAIL_CACHE_DECISION_FORCED)) {
+ if (!bodystructure_cached && !plain_bodystructure &&
+ dec != (MAIL_CACHE_DECISION_NO |
+ MAIL_CACHE_DECISION_FORCED)) {
mail_cache_add(mail->trans->cache_trans, data->seq,
cache_fields[MAIL_CACHE_IMAP_BODY].idx,
str_c(str), str_len(str)+1);
@@ -567,6 +572,17 @@
}
}
+static void
+index_mail_get_plain_bodystructure(struct index_mail *mail, string_t *str,
+ int extended)
+{
+ str_printfa(str, IMAP_BODY_PLAIN_7BIT_ASCII" %"PRIuUOFF_T" %u",
+ mail->data.parts->body_size.virtual_size,
+ mail->data.parts->body_size.lines);
+ if (extended)
+ str_append(str, " NIL NIL NIL");
+}
+
const char *index_mail_get_special(struct mail *_mail,
enum mail_fetch_field field)
{
@@ -585,12 +601,20 @@
if (data->body != NULL)
return data->body;
- /* 1) get BODY if it exists
- 2) get it using BODYSTRUCTURE if it exists
- 3) parse body structure, and save BODY/BODYSTRUCTURE
+ /* 1) use plain-7bit-ascii flag if it exists
+ 2) get BODY if it exists
+ 3) get it using BODYSTRUCTURE if it exists
+ 4) parse body structure, and save BODY/BODYSTRUCTURE
depending on what we want cached */
str = str_new(mail->data_pool, 128);
+ if ((mail->data.cache_flags &
+ MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) != 0 &&
+ get_cached_parts(mail)) {
+ index_mail_get_plain_bodystructure(mail, str, FALSE);
+ return str_c(str);
+ }
+
if (mail_cache_lookup_field(mail->trans->cache_view, str,
mail->data.seq, body_cache_field) > 0) {
data->body = str_c(str);
@@ -628,6 +652,13 @@
return data->bodystructure;
str = str_new(mail->data_pool, 128);
+ if ((mail->data.cache_flags &
+ MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) != 0 &&
+ get_cached_parts(mail)) {
+ index_mail_get_plain_bodystructure(mail, str, TRUE);
+ return str_c(str);
+ }
+
if (mail_cache_lookup_field(mail->trans->cache_view, str,
mail->data.seq,
bodystructure_cache_field) > 0) {
@@ -710,8 +741,8 @@
struct index_mail *mail = (struct index_mail *)_mail;
struct index_mail_data *data = &mail->data;
struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
+ struct mail_cache_view *cache_view = mail->trans->cache_view;
const struct mail_index_record *rec;
- unsigned int i;
if (mail_index_lookup(mail->trans->trans_view, seq, &rec) < 0) {
mail_storage_set_index_error(mail->ibox);
@@ -744,20 +775,22 @@
/* see if wanted_fields can tell us if we need to read/parse
header/body */
- for (i = 0; fetch_cache_map[i].part != 0; i++) {
- const struct fetch_cache_map *map = &fetch_cache_map[i];
+ if ((mail->wanted_fields & MAIL_FETCH_MESSAGE_PARTS) != 0) {
+ unsigned int cache_field =
+ cache_fields[MAIL_FETCH_MESSAGE_PARTS].idx;
- if ((mail->wanted_fields & map->fetch_field) != 0) {
- unsigned int cache_field =
- cache_fields[map->cache_field].idx;
+ if (mail_cache_field_exists(cache_view, seq, cache_field) == 0)
+ data->access_part |= PARSE_HDR | PARSE_BODY;
+ }
- if (mail_cache_field_exists(mail->trans->cache_view,
- seq, cache_field) == 0)
- data->access_part |= map->part;
- }
+ if ((mail->wanted_fields & MAIL_FETCH_VIRTUAL_SIZE) != 0) {
+ unsigned int cache_field =
+ cache_fields[MAIL_FETCH_VIRTUAL_SIZE].idx;
+
+ if (mail_cache_field_exists(cache_view, seq, cache_field) == 0)
+ data->access_part |= READ_HDR | READ_BODY;
}
- /* handle the special cases */
if ((mail->wanted_fields & MAIL_FETCH_IMAP_ENVELOPE) != 0 &&
(data->access_part & PARSE_HDR) == 0) {
/* don't waste time doing full checks for all required
@@ -769,37 +802,55 @@
unsigned int cache_field2 =
cache_fields[MAIL_CACHE_IMAP_ENVELOPE].idx;
- if (mail_cache_field_exists(mail->trans->cache_view,
- seq, cache_field1) == 0 &&
- mail_cache_field_exists(mail->trans->cache_view,
- seq, cache_field2) == 0)
+ if (mail_cache_field_exists(cache_view, seq,
+ cache_field1) == 0 &&
+ mail_cache_field_exists(cache_view, seq,
+ cache_field2) == 0)
data->access_part |= PARSE_HDR;
}
if ((mail->wanted_fields & MAIL_FETCH_IMAP_BODY) != 0 &&
- ((data->access_part & PARSE_HDR) == 0 ||
- (data->access_part & PARSE_BODY) == 0)) {
+ (data->cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) == 0) {
/* we need either imap.body or imap.bodystructure */
unsigned int cache_field1 =
cache_fields[MAIL_CACHE_IMAP_BODY].idx;
unsigned int cache_field2 =
cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
- if (mail_cache_field_exists(mail->trans->cache_view,
+ if (mail_cache_field_exists(cache_view,
seq, cache_field1) == 0 &&
- mail_cache_field_exists(mail->trans->cache_view,
+ mail_cache_field_exists(cache_view,
seq, cache_field2) == 0)
data->access_part |= PARSE_HDR | PARSE_BODY;
+ else {
+ data->save_bodystructure_header = TRUE;
+ data->save_bodystructure_body = TRUE;
+ }
}
- if ((mail->wanted_fields & (MAIL_FETCH_IMAP_BODY |
- MAIL_FETCH_IMAP_BODYSTRUCTURE)) != 0) {
- data->save_bodystructure_header = TRUE;
- data->save_bodystructure_body = TRUE;
+ if ((mail->wanted_fields & MAIL_FETCH_IMAP_BODYSTRUCTURE) != 0 &&
+ (data->cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) == 0) {
+ unsigned int cache_field =
+ cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
+
+ if (mail_cache_field_exists(cache_view, seq, cache_field) == 0)
+ data->access_part |= PARSE_HDR | PARSE_BODY;
+ else {
+ data->save_bodystructure_header = TRUE;
+ data->save_bodystructure_body = TRUE;
+ }
}
- if ((mail->wanted_fields & MAIL_FETCH_DATE) != 0)
- data->save_sent_date = TRUE;
+ if ((mail->wanted_fields & MAIL_FETCH_DATE) != 0) {
+ unsigned int cache_field =
+ cache_fields[MAIL_CACHE_SENT_DATE].idx;
+
+ if (mail_cache_field_exists(cache_view, seq,
+ cache_field) == 0) {
+ data->access_part |= PARSE_HDR;
+ data->save_sent_date = TRUE;
+ }
+ }
if ((mail->wanted_fields & MAIL_FETCH_IMAP_ENVELOPE) != 0)
data->save_envelope = TRUE;
Index: index-mail.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/index-mail.h,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- index-mail.h 3 Jul 2005 13:07:50 -0000 1.33
+++ index-mail.h 3 Jul 2005 14:18:28 -0000 1.34
@@ -23,6 +23,9 @@
};
extern struct mail_cache_field global_cache_fields[MAIL_CACHE_FIELD_COUNT];
+#define IMAP_BODY_PLAIN_7BIT_ASCII \
+ "\"text\" \"plain\" (\"charset\" \"us-ascii\") NIL NIL \"7bit\""
+
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
@@ -34,7 +37,11 @@
/* Mail header or body is known to contain NUL characters. */
MAIL_CACHE_FLAG_HAS_NULS = 0x0004,
/* Mail header or body is known to not contain NUL characters. */
- MAIL_CACHE_FLAG_HAS_NO_NULS = 0x0008
+ MAIL_CACHE_FLAG_HAS_NO_NULS = 0x0008,
+
+ /* BODY is IMAP_BODY_PLAIN_7BIT_ASCII and rest of BODYSTRUCTURE
+ fields are NIL */
+ MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII = 0x0010
};
enum index_mail_access_part {
@@ -89,6 +96,7 @@
unsigned int parsed_bodystructure:1;
unsigned int hdr_size_set:1;
unsigned int body_size_set:1;
+ unsigned int messageparts_saved_to_cache:1;
};
struct index_mail {
More information about the dovecot-cvs
mailing list