dovecot-2.0: dbox, maildir: When copying messages, copy the cach...

dovecot at dovecot.org dovecot at dovecot.org
Wed Oct 20 18:07:11 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/8ccf177754b3
changeset: 12318:8ccf177754b3
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Oct 20 16:07:03 2010 +0100
description:
dbox, maildir: When copying messages, copy the cached fields also.
Copy only fields whose caching decision is not "no" in the destination mailbox.

diffstat:

 src/lib-storage/index/dbox-multi/mdbox-save.c   |   1 +
 src/lib-storage/index/dbox-single/sdbox-copy.c  |   2 +
 src/lib-storage/index/index-storage.c           |  55 +++++++++++++++++++++++++++
 src/lib-storage/index/index-storage.h           |   2 +
 src/lib-storage/index/maildir/maildir-copy.c    |   2 +-
 src/lib-storage/index/maildir/maildir-save.c    |  10 +++--
 src/lib-storage/index/maildir/maildir-storage.h |   3 +-
 7 files changed, 69 insertions(+), 6 deletions(-)

diffs (156 lines):

diff -r 8a6cdefd829a -r 8ccf177754b3 src/lib-storage/index/dbox-multi/mdbox-save.c
--- a/src/lib-storage/index/dbox-multi/mdbox-save.c	Wed Oct 20 16:03:13 2010 +0100
+++ b/src/lib-storage/index/dbox-multi/mdbox-save.c	Wed Oct 20 16:07:03 2010 +0100
@@ -434,6 +434,7 @@
 		mail_index_update_ext(ctx->ctx.trans, ctx->ctx.seq,
 				      ctx->mbox->guid_ext_id, data, NULL);
 	}
+	index_copy_cache_fields(_ctx, mail, ctx->ctx.seq);
 
 	save_mail = array_append_space(&ctx->mails);
 	save_mail->seq = ctx->ctx.seq;
diff -r 8a6cdefd829a -r 8ccf177754b3 src/lib-storage/index/dbox-single/sdbox-copy.c
--- a/src/lib-storage/index/dbox-single/sdbox-copy.c	Wed Oct 20 16:03:13 2010 +0100
+++ b/src/lib-storage/index/dbox-single/sdbox-copy.c	Wed Oct 20 16:07:03 2010 +0100
@@ -127,6 +127,8 @@
 	}
 
 	dbox_save_add_to_index(ctx);
+	index_copy_cache_fields(_ctx, mail, ctx->seq);
+
 	sdbox_save_add_file(_ctx, dest_file);
 	if (_ctx->dest_mail != NULL) {
 		mail_set_seq(_ctx->dest_mail, ctx->seq);
diff -r 8a6cdefd829a -r 8ccf177754b3 src/lib-storage/index/index-storage.c
--- a/src/lib-storage/index/index-storage.c	Wed Oct 20 16:03:13 2010 +0100
+++ b/src/lib-storage/index/index-storage.c	Wed Oct 20 16:07:03 2010 +0100
@@ -600,3 +600,58 @@
 	i_free_and_null(ctx->pop3_uidl);
 	index_attachment_save_free(ctx);
 }
+
+static void
+mail_copy_cache_field(struct mail_save_context *ctx, struct mail *src_mail,
+		      uint32_t dest_seq, const char *name, buffer_t *buf)
+{
+	struct mailbox_transaction_context *dest_trans = ctx->transaction;
+	struct index_transaction_context *dest_itrans =
+		(struct index_transaction_context *)dest_trans;
+	struct index_transaction_context *src_itrans =
+		(struct index_transaction_context *)src_mail->transaction;
+	const struct mail_cache_field *dest_field;
+	unsigned int src_field_idx, dest_field_idx;
+
+	src_field_idx = mail_cache_register_lookup(src_mail->box->cache, name);
+	i_assert(src_field_idx != -1U);
+
+	dest_field_idx = mail_cache_register_lookup(dest_trans->box->cache, name);
+	if (dest_field_idx == -1U) {
+		/* unknown field */
+		return;
+	}
+	dest_field = mail_cache_register_get_field(dest_trans->box->cache,
+						   dest_field_idx);
+	if ((dest_field->decision &
+	     ~MAIL_CACHE_DECISION_FORCED) == MAIL_CACHE_DECISION_NO) {
+		/* field not wanted in destination mailbox */
+		return;
+	}
+
+	buffer_set_used_size(buf, 0);
+	if (mail_cache_lookup_field(src_itrans->cache_view, buf,
+				    src_mail->seq, src_field_idx) > 0) {
+		mail_cache_add(dest_itrans->cache_trans, dest_seq,
+			       dest_field_idx, buf->data, buf->used);
+	}
+}
+
+void index_copy_cache_fields(struct mail_save_context *ctx,
+			     struct mail *src_mail, uint32_t dest_seq)
+{
+	T_BEGIN {
+		struct mailbox_status src_status;
+		const char *const *namep;
+		buffer_t *buf;
+
+		index_storage_get_status(src_mail->box, STATUS_CACHE_FIELDS,
+					 &src_status);
+
+		buf = buffer_create_dynamic(pool_datastack_create(), 1024);
+		array_foreach(src_status.cache_fields, namep) {
+			mail_copy_cache_field(ctx, src_mail, dest_seq,
+					      *namep, buf);
+		}
+	} T_END;
+}
diff -r 8a6cdefd829a -r 8ccf177754b3 src/lib-storage/index/index-storage.h
--- a/src/lib-storage/index/index-storage.h	Wed Oct 20 16:03:13 2010 +0100
+++ b/src/lib-storage/index/index-storage.h	Wed Oct 20 16:07:03 2010 +0100
@@ -166,6 +166,8 @@
 			     struct mail_transaction_commit_changes *changes_r);
 void index_transaction_rollback(struct mailbox_transaction_context *t);
 void index_save_context_free(struct mail_save_context *ctx);
+void index_copy_cache_fields(struct mail_save_context *ctx,
+			     struct mail *src_mail, uint32_t dest_seq);
 
 bool index_keyword_array_cmp(const ARRAY_TYPE(keyword_indexes) *k1,
 			     const ARRAY_TYPE(keyword_indexes) *k2);
diff -r 8a6cdefd829a -r 8ccf177754b3 src/lib-storage/index/maildir/maildir-copy.c
--- a/src/lib-storage/index/maildir/maildir-copy.c	Wed Oct 20 16:03:13 2010 +0100
+++ b/src/lib-storage/index/maildir/maildir-copy.c	Wed Oct 20 16:07:03 2010 +0100
@@ -104,7 +104,7 @@
 	}
 
 	/* hardlinked to tmp/, treat as normal copied mail */
-	mf = maildir_save_add(ctx, dest_fname);
+	mf = maildir_save_add(ctx, dest_fname, mail);
 	if (mail_get_special(mail, MAIL_FETCH_GUID, &guid) == 0) {
 		if (*guid != '\0')
 			maildir_save_set_dest_basename(ctx, mf, guid);
diff -r 8a6cdefd829a -r 8ccf177754b3 src/lib-storage/index/maildir/maildir-save.c
--- a/src/lib-storage/index/maildir/maildir-save.c	Wed Oct 20 16:03:13 2010 +0100
+++ b/src/lib-storage/index/maildir/maildir-save.c	Wed Oct 20 16:07:03 2010 +0100
@@ -140,7 +140,8 @@
 }
 
 struct maildir_filename *
-maildir_save_add(struct mail_save_context *_ctx, const char *tmp_fname)
+maildir_save_add(struct mail_save_context *_ctx, const char *tmp_fname,
+		 struct mail *src_mail)
 {
 	struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx;
 	struct maildir_filename *mf;
@@ -212,8 +213,9 @@
 	_ctx->dest_mail->saving = TRUE;
 
 	if (ctx->input == NULL) {
-		/* FIXME: copying with hardlinking. we could copy the
-		   cached data directly */
+		/* copying with hardlinking. */
+		i_assert(src_mail != NULL);
+		index_copy_cache_fields(_ctx, src_mail, ctx->seq);
 		ctx->cur_dest_mail = NULL;
 	} else {
 		input = index_mail_cache_parse_init(_ctx->dest_mail,
@@ -404,7 +406,7 @@
 				ctx->input = i_stream_create_crlf(input);
 			else
 				ctx->input = i_stream_create_lf(input);
-			mf = maildir_save_add(_ctx, fname);
+			mf = maildir_save_add(_ctx, fname, NULL);
 			if (_ctx->guid != NULL) {
 				maildir_save_set_dest_basename(_ctx, mf,
 							       _ctx->guid);
diff -r 8a6cdefd829a -r 8ccf177754b3 src/lib-storage/index/maildir/maildir-storage.h
--- a/src/lib-storage/index/maildir/maildir-storage.h	Wed Oct 20 16:03:13 2010 +0100
+++ b/src/lib-storage/index/maildir/maildir-storage.h	Wed Oct 20 16:07:03 2010 +0100
@@ -120,7 +120,8 @@
 void maildir_save_cancel(struct mail_save_context *ctx);
 
 struct maildir_filename *
-maildir_save_add(struct mail_save_context *_ctx, const char *tmp_fname);
+maildir_save_add(struct mail_save_context *_ctx, const char *tmp_fname,
+		 struct mail *src_mail);
 void maildir_save_set_dest_basename(struct mail_save_context *ctx,
 				    struct maildir_filename *mf,
 				    const char *basename);


More information about the dovecot-cvs mailing list