dovecot-2.0: Maildir: Allow specifying recent flags for saved me...

dovecot at dovecot.org dovecot at dovecot.org
Thu Aug 6 03:30:51 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/64ab55223d69
changeset: 9728:64ab55223d69
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Aug 05 20:15:47 2009 -0400
description:
Maildir: Allow specifying recent flags for saved messages.

diffstat:

1 file changed, 57 insertions(+), 18 deletions(-)
src/lib-storage/index/maildir/maildir-save.c |   75 +++++++++++++++++++-------

diffs (126 lines):

diff -r b7af600f0c62 -r 64ab55223d69 src/lib-storage/index/maildir/maildir-save.c
--- a/src/lib-storage/index/maildir/maildir-save.c	Wed Aug 05 20:14:05 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-save.c	Wed Aug 05 20:15:47 2009 -0400
@@ -57,7 +57,7 @@ struct maildir_save_context {
 
 	struct istream *input;
 	int fd;
-	uint32_t first_seq, seq;
+	uint32_t first_seq, seq, last_nonrecent_uid;
 
 	unsigned int have_keywords:1;
 	unsigned int locked:1;
@@ -140,10 +140,14 @@ maildir_save_add(struct mail_save_contex
 	struct istream *input;
 	unsigned int keyword_count;
 
-	/* allow caller to specify recent flag only when we're syncing
-	   messages (uid specified). */
+	/* allow caller to specify recent flag only when uid is specified
+	   (we're replicating, converting, etc.). */
 	if (_ctx->uid == 0)
 		_ctx->flags |= MAIL_RECENT;
+	else if ((_ctx->flags & MAIL_RECENT) == 0 &&
+		 ctx->last_nonrecent_uid < _ctx->uid)
+		ctx->last_nonrecent_uid = _ctx->uid;
+
 
 	/* now, we want to be able to rollback the whole append session,
 	   so we'll just store the name of this temp file and move it later
@@ -174,7 +178,7 @@ maildir_save_add(struct mail_save_contex
 	/* insert into index */
 	mail_index_append(ctx->trans, _ctx->uid, &ctx->seq);
 	mail_index_update_flags(ctx->trans, ctx->seq,
-				MODIFY_REPLACE, _ctx->flags);
+				MODIFY_REPLACE, _ctx->flags & ~MAIL_RECENT);
 	if (_ctx->keywords != NULL) {
 		mail_index_update_keywords(ctx->trans, ctx->seq,
 					   MODIFY_REPLACE, _ctx->keywords);
@@ -634,14 +638,46 @@ static int maildir_transaction_fsync_dir
 	return 0;
 }
 
+static int seq_range_cmp(const struct seq_range *r1, const struct seq_range *r2)
+{
+	if (r1->seq1 < r2->seq2)
+		return -1;
+	else if (r1->seq1 > r2->seq2)
+		return 1;
+	else
+		return 0;
+}
+
+static uint32_t
+maildir_save_set_recent_flags(struct maildir_save_context *ctx)
+{
+	struct maildir_mailbox *mbox = ctx->mbox;
+	ARRAY_TYPE(seq_range) saved_sorted_uids;
+	const struct seq_range *uids;
+	unsigned int i, count;
+	uint32_t uid;
+
+	t_array_init(&saved_sorted_uids,
+		     array_count(&ctx->ctx.transaction->changes->saved_uids));
+	array_append_array(&saved_sorted_uids,
+			   &ctx->ctx.transaction->changes->saved_uids);
+	array_sort(&saved_sorted_uids, seq_range_cmp);
+
+	uids = array_get(&saved_sorted_uids, &count);
+	i_assert(count > 0);
+	for (i = 0; i < count; i++) {
+		for (uid = uids[i].seq1; uid <= uids[i].seq2; uid++)
+			index_mailbox_set_recent_uid(&mbox->ibox, uid);
+	}
+	return uids[count-1].seq2;
+}
+
 static int
 maildir_save_sync_index(struct maildir_save_context *ctx)
 {
 	struct mailbox_transaction_context *_t = ctx->ctx.transaction;
 	struct maildir_mailbox *mbox = ctx->mbox;
-	const struct seq_range *uids;
-	uint32_t uid, first_uid, next_uid;
-	unsigned int i, count;
+	uint32_t first_uid, next_uid, first_recent_uid;
 	int ret;
 
 	/* we'll need to keep the lock past the sync deinit */
@@ -673,23 +709,26 @@ maildir_save_sync_index(struct maildir_s
 	i_assert(ctx->files_count == seq_range_count(&_t->changes->saved_uids));
 
 	/* these mails are all recent in our session */
-	next_uid = first_uid;
-	uids = array_get(&_t->changes->saved_uids, &count);
-	for (i = 0; i < count; i++) {
-		if (next_uid < uids[i].seq2)
-			next_uid = uids[i].seq2;
-		for (uid = uids[i].seq1; uid <= uids[i].seq2; uid++)
-			index_mailbox_set_recent_uid(&mbox->ibox, uid);
-	}
-
-	if ((mbox->ibox.box.flags & MAILBOX_FLAG_KEEP_RECENT) == 0) {
+	T_BEGIN {
+		next_uid = maildir_save_set_recent_flags(ctx);
+	} T_END;
+
+	if ((mbox->ibox.box.flags & MAILBOX_FLAG_KEEP_RECENT) == 0)
+		first_recent_uid = next_uid;
+	else if (ctx->last_nonrecent_uid != 0)
+		first_recent_uid = ctx->last_nonrecent_uid + 1;
+	else
+		first_recent_uid = 0;
+
+	if (first_recent_uid != 0) {
 		/* maildir_sync_index() dropped recent flags from
 		   existing messages. we'll still need to drop recent
 		   flags from these newly added messages. */
 		mail_index_update_header(ctx->trans,
 					 offsetof(struct mail_index_header,
 						  first_recent_uid),
-					 &next_uid, sizeof(next_uid), FALSE);
+					 &first_recent_uid,
+					 sizeof(first_recent_uid), FALSE);
 	}
 	return 0;
 }


More information about the dovecot-cvs mailing list