dovecot: Cache received date, sent date, save date and physical ...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Aug 11 14:37:43 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/0ee2b0691f3e
changeset: 6265:0ee2b0691f3e
user: Timo Sirainen <tss at iki.fi>
date: Sat Aug 11 14:35:36 2007 +0300
description:
Cache received date, sent date, save date and physical size when saving
mails if they're wanted.
diffstat:
6 files changed, 171 insertions(+), 81 deletions(-)
src/lib-storage/index/cydir/cydir-save.c | 38 +++++---
src/lib-storage/index/index-mail-headers.c | 4
src/lib-storage/index/index-mail.c | 121 +++++++++++++++++++-------
src/lib-storage/index/index-mail.h | 2
src/lib-storage/index/maildir/maildir-save.c | 83 ++++++++++-------
src/lib-storage/index/mbox/mbox-save.c | 4
diffs (truncated from 444 to 300 lines):
diff -r 10acca6dd37d -r 0ee2b0691f3e src/lib-storage/index/cydir/cydir-save.c
--- a/src/lib-storage/index/cydir/cydir-save.c Sat Aug 11 14:27:40 2007 +0300
+++ b/src/lib-storage/index/cydir/cydir-save.c Sat Aug 11 14:35:36 2007 +0300
@@ -29,6 +29,7 @@ struct cydir_save_context {
struct istream *input;
struct ostream *output;
struct mail *mail, *cur_dest_mail;
+ time_t cur_received_date;
int fd;
unsigned int failed:1;
@@ -89,18 +90,6 @@ int cydir_save_init(struct mailbox_trans
ctx->output = o_stream_create_crlf(output);
o_stream_unref(&output);
o_stream_cork(ctx->output);
-
- if (received_date != (time_t)-1) {
- struct utimbuf ut;
-
- ut.actime = ioloop_time;
- ut.modtime = received_date;
- if (utime(path, &ut) < 0) {
- mail_storage_set_critical(_t->box->storage,
- "utime(%s) failed: %m", path);
- /* ignore this error anyway */
- }
- }
} else {
mail_storage_set_critical(_t->box->storage,
"open(%s) failed: %m", path);
@@ -130,6 +119,7 @@ int cydir_save_init(struct mailbox_trans
ctx->cur_dest_mail = dest_mail;
ctx->input = index_mail_cache_parse_init(dest_mail, input);
+ ctx->cur_received_date = received_date;
*ctx_r = &ctx->ctx;
return ctx->failed ? -1 : 0;
@@ -167,6 +157,7 @@ int cydir_save_finish(struct mail_save_c
struct cydir_save_context *ctx = (struct cydir_save_context *)_ctx;
struct mail_storage *storage = &ctx->mbox->storage->storage;
const char *path = cydir_get_save_path(ctx, ctx->mail_count);
+ struct stat st;
ctx->finished = TRUE;
@@ -180,6 +171,26 @@ int cydir_save_finish(struct mail_save_c
if (fsync(ctx->fd) < 0) {
mail_storage_set_critical(storage,
"fsync(%s) failed: %m", path);
+ ctx->failed = TRUE;
+ }
+ }
+
+ if (ctx->cur_received_date == (time_t)-1) {
+ if (fstat(ctx->fd, &st) == 0)
+ ctx->cur_received_date = st.st_mtime;
+ else {
+ mail_storage_set_critical(storage,
+ "fstat(%s) failed: %m", path);
+ ctx->failed = TRUE;
+ }
+ } else {
+ struct utimbuf ut;
+
+ ut.actime = ioloop_time;
+ ut.modtime = ctx->cur_received_date;
+ if (utime(path, &ut) < 0) {
+ mail_storage_set_critical(storage,
+ "utime(%s) failed: %m", path);
ctx->failed = TRUE;
}
}
@@ -201,7 +212,8 @@ int cydir_save_finish(struct mail_save_c
}
}
- index_mail_cache_parse_deinit(ctx->cur_dest_mail);
+ index_mail_cache_parse_deinit(ctx->cur_dest_mail,
+ ctx->cur_received_date);
i_stream_unref(&ctx->input);
return ctx->failed ? -1 : 0;
diff -r 10acca6dd37d -r 0ee2b0691f3e src/lib-storage/index/index-mail-headers.c
--- a/src/lib-storage/index/index-mail-headers.c Sat Aug 11 14:27:40 2007 +0300
+++ b/src/lib-storage/index/index-mail-headers.c Sat Aug 11 14:35:36 2007 +0300
@@ -341,8 +341,8 @@ index_mail_parse_header_cb(struct messag
index_mail_parse_header(mail->data.parts, hdr, mail);
}
-struct istream *index_mail_cache_parse_init(struct mail *_mail,
- struct istream *input)
+struct istream *
+index_mail_cache_parse_init(struct mail *_mail, struct istream *input)
{
struct index_mail *mail = (struct index_mail *)_mail;
struct tee_istream *tee;
diff -r 10acca6dd37d -r 0ee2b0691f3e src/lib-storage/index/index-mail.c
--- a/src/lib-storage/index/index-mail.c Sat Aug 11 14:27:40 2007 +0300
+++ b/src/lib-storage/index/index-mail.c Sat Aug 11 14:35:36 2007 +0300
@@ -3,6 +3,7 @@
#include "lib.h"
#include "array.h"
#include "buffer.h"
+#include "ioloop.h"
#include "istream.h"
#include "hex-binary.h"
#include "str.h"
@@ -225,11 +226,33 @@ time_t index_mail_get_save_date(struct m
return data->save_date;
}
+static void index_mail_cache_sent_date(struct index_mail *mail)
+{
+ struct index_mail_data *data = &mail->data;
+ const char *str;
+ time_t t;
+ int tz;
+
+ if (data->sent_date.time != (uint32_t)-1)
+ return;
+
+ str = mail_get_first_header(&mail->mail.mail, "Date");
+ if (str == NULL || !message_date_parse((const unsigned char *)str,
+ strlen(str), &t, &tz)) {
+ /* 0 = not found / invalid */
+ t = 0;
+ tz = 0;
+ }
+ data->sent_date.time = t;
+ data->sent_date.timezone = tz;
+ index_mail_cache_add(mail, MAIL_CACHE_SENT_DATE,
+ &data->sent_date, sizeof(data->sent_date));
+}
+
time_t index_mail_get_date(struct mail *_mail, int *timezone)
{
struct index_mail *mail = (struct index_mail *) _mail;
struct index_mail_data *data = &mail->data;
- const char *str;
if (data->sent_date.time != (uint32_t)-1) {
if (timezone != NULL)
@@ -241,24 +264,7 @@ time_t index_mail_get_date(struct mail *
&data->sent_date,
sizeof(data->sent_date));
- if (data->sent_date.time == (uint32_t)-1) {
- time_t t;
- int tz;
-
- str = mail_get_first_header(_mail, "Date");
- if (str == NULL ||
- !message_date_parse((const unsigned char *)str,
- strlen(str), &t, &tz)) {
- /* 0 = not found / invalid */
- t = 0;
- tz = 0;
- }
- data->sent_date.time = t;
- data->sent_date.timezone = tz;
- index_mail_cache_add(mail, MAIL_CACHE_SENT_DATE,
- &data->sent_date, sizeof(data->sent_date));
- }
-
+ index_mail_cache_sent_date(mail);
if (timezone != NULL)
*timezone = data->sent_date.timezone;
return data->sent_date.time;
@@ -561,17 +567,27 @@ index_mail_body_parsed_cache_bodystructu
}
}
-static void
-index_mail_body_parsed_cache_virtual_size(struct index_mail *mail)
-{
- unsigned int cache_field =
- mail->ibox->cache_fields[MAIL_CACHE_VIRTUAL_FULL_SIZE].idx;
-
- if (mail_cache_field_want_add(mail->trans->cache_trans,
- mail->data.seq, cache_field)) {
- index_mail_cache_add(mail, MAIL_CACHE_VIRTUAL_FULL_SIZE,
- &mail->data.virtual_size,
- sizeof(mail->data.virtual_size));
+static void index_mail_body_parsed_cache_sizes(struct index_mail *mail)
+{
+ static enum index_cache_field date_fields[] = {
+ MAIL_CACHE_VIRTUAL_FULL_SIZE,
+ MAIL_CACHE_PHYSICAL_FULL_SIZE
+ };
+ uoff_t sizes[N_ELEMENTS(date_fields)];
+ unsigned int i, cache_field;
+
+ sizes[0] = mail->data.virtual_size;
+ sizes[1] = mail->data.physical_size;
+
+ for (i = 0; i < N_ELEMENTS(date_fields); i++) {
+ cache_field = mail->ibox->cache_fields[date_fields[i]].idx;
+
+ i_assert(sizes[i] != (uoff_t)-1);
+ if (mail_cache_field_want_add(mail->trans->cache_trans,
+ mail->data.seq, cache_field)) {
+ index_mail_cache_add(mail, date_fields[i],
+ &sizes[i], sizeof(sizes[i]));
+ }
}
}
@@ -592,7 +608,7 @@ static void index_mail_parse_body_finish
index_mail_body_parsed_cache_flags(mail);
index_mail_body_parsed_cache_message_parts(mail);
index_mail_body_parsed_cache_bodystructure(mail, field);
- index_mail_body_parsed_cache_virtual_size(mail);
+ index_mail_body_parsed_cache_sizes(mail);
}
static void index_mail_parse_body(struct index_mail *mail,
@@ -1095,13 +1111,54 @@ void index_mail_cache_parse_continue(str
}
}
-void index_mail_cache_parse_deinit(struct mail *_mail)
+static void index_mail_cache_dates(struct index_mail *mail)
+{
+ static enum index_cache_field date_fields[] = {
+ MAIL_CACHE_RECEIVED_DATE,
+ MAIL_CACHE_SAVE_DATE
+ };
+ time_t dates[N_ELEMENTS(date_fields)];
+ unsigned int i, cache_field;
+ uint32_t t;
+
+ dates[0] = mail->data.received_date;
+ dates[1] = mail->data.save_date;
+
+ for (i = 0; i < N_ELEMENTS(date_fields); i++) {
+ cache_field = mail->ibox->cache_fields[date_fields[i]].idx;
+
+ i_assert(dates[i] != (time_t)-1);
+ if (mail_cache_field_want_add(mail->trans->cache_trans,
+ mail->data.seq, cache_field)) {
+ t = dates[i];
+ index_mail_cache_add(mail, date_fields[i],
+ &t, sizeof(t));
+ }
+ }
+
+ cache_field = mail->ibox->cache_fields[MAIL_CACHE_SENT_DATE].idx;
+ if (mail_cache_field_want_add(mail->trans->cache_trans,
+ mail->data.seq, cache_field))
+ index_mail_cache_sent_date(mail);
+}
+
+void index_mail_cache_parse_deinit(struct mail *_mail, time_t received_date)
{
struct index_mail *mail = (struct index_mail *)_mail;
+
+ if (mail->data.received_date == (time_t)-1)
+ mail->data.received_date = received_date;
+ if (mail->data.save_date == (time_t)-1) {
+ /* this save_date may not be exactly the same as what we get
+ in future, but then again neither mbox nor maildir
+ guarantees it anyway. */
+ mail->data.save_date = ioloop_time;
+ }
mail->data.save_bodystructure_body = FALSE;
mail->data.parsed_bodystructure = TRUE;
index_mail_parse_body_finish(mail, 0, TRUE);
+ index_mail_cache_dates(mail);
}
int index_mail_update_flags(struct mail *mail, enum modify_type modify_type,
diff -r 10acca6dd37d -r 0ee2b0691f3e src/lib-storage/index/index-mail.h
--- a/src/lib-storage/index/index-mail.h Sat Aug 11 14:27:40 2007 +0300
+++ b/src/lib-storage/index/index-mail.h Sat Aug 11 14:35:36 2007 +0300
@@ -187,6 +187,6 @@ struct istream *index_mail_cache_parse_i
struct istream *index_mail_cache_parse_init(struct mail *mail,
struct istream *input);
void index_mail_cache_parse_continue(struct mail *mail);
-void index_mail_cache_parse_deinit(struct mail *mail);
+void index_mail_cache_parse_deinit(struct mail *mail, time_t received_date);
#endif
diff -r 10acca6dd37d -r 0ee2b0691f3e src/lib-storage/index/maildir/maildir-save.c
--- a/src/lib-storage/index/maildir/maildir-save.c Sat Aug 11 14:27:40 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-save.c Sat Aug 11 14:35:36 2007 +0300
@@ -427,21 +427,11 @@ int maildir_save_finish(struct mail_save
int maildir_save_finish(struct mail_save_context *_ctx)
{
struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx;
+ struct mail_storage *storage = &ctx->mbox->storage->storage;
struct utimbuf buf;
+ struct stat st;
const char *path;
int output_errno;
-
- if (o_stream_flush(ctx->output) < 0) {
- mail_storage_set_critical(&ctx->mbox->storage->storage,
- "o_stream_flush(%s/%s) failed: %m",
More information about the dovecot-cvs
mailing list