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