dovecot: Fixes to recent handling. Now it should work properly.

dovecot at dovecot.org dovecot at dovecot.org
Tue Jul 17 20:39:35 EEST 2007


details:   http://hg.dovecot.org/dovecot/rev/cadb5b7cd919
changeset: 6038:cadb5b7cd919
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Jul 16 10:21:56 2007 +0300
description:
Fixes to recent handling. Now it should work properly.

diffstat:

7 files changed, 71 insertions(+), 67 deletions(-)
src/lib-storage/index/index-mail.c                 |    2 
src/lib-storage/index/index-status.c               |    8 +-
src/lib-storage/index/index-storage.h              |    1 
src/lib-storage/index/index-sync.c                 |   41 +++++++++--
src/lib-storage/index/maildir/maildir-sync-index.c |   73 ++++++--------------
src/lib-storage/index/mbox/mbox-sync-private.h     |    2 
src/lib-storage/index/mbox/mbox-sync.c             |   11 +--

diffs (truncated from 305 to 300 lines):

diff -r d911d943438e -r cadb5b7cd919 src/lib-storage/index/index-mail.c
--- a/src/lib-storage/index/index-mail.c	Mon Jul 16 09:48:02 2007 +0300
+++ b/src/lib-storage/index/index-mail.c	Mon Jul 16 10:21:56 2007 +0300
@@ -116,7 +116,7 @@ enum mail_flags index_mail_get_flags(str
 	struct index_mail_data *data = &mail->data;
 
 	data->flags = data->rec->flags & MAIL_FLAGS_NONRECENT;
-	if (index_mailbox_is_recent(mail->ibox, data->seq))
+	if (index_mailbox_is_recent(mail->ibox, _mail->uid))
 		data->flags |= MAIL_RECENT;
 
 	return data->flags;
diff -r d911d943438e -r cadb5b7cd919 src/lib-storage/index/index-status.c
--- a/src/lib-storage/index/index-status.c	Mon Jul 16 09:48:02 2007 +0300
+++ b/src/lib-storage/index/index-status.c	Mon Jul 16 10:21:56 2007 +0300
@@ -14,9 +14,11 @@ int index_storage_get_status_locked(stru
 	/* we can get most of the status items without any trouble */
 	hdr = mail_index_get_header(ibox->view);
 	status_r->messages = hdr->messages_count;
-	status_r->recent = ibox->recent_flags_count;
-	status_r->unseen =
-		hdr->messages_count - hdr->seen_messages_count;
+	if ((items & STATUS_RECENT) != 0) {
+		status_r->recent = index_mailbox_get_recent_count(ibox);
+		i_assert(status_r->recent <= status_r->messages);
+	}
+	status_r->unseen = hdr->messages_count - hdr->seen_messages_count;
 	status_r->uidvalidity = hdr->uid_validity;
 	status_r->uidnext = hdr->next_uid;
 
diff -r d911d943438e -r cadb5b7cd919 src/lib-storage/index/index-storage.h
--- a/src/lib-storage/index/index-storage.h	Mon Jul 16 09:48:02 2007 +0300
+++ b/src/lib-storage/index/index-storage.h	Mon Jul 16 10:21:56 2007 +0300
@@ -119,6 +119,7 @@ void index_mailbox_set_recent_seq(struct
 				  struct mail_index_view *view,
 				  uint32_t seq1, uint32_t seq2);
 bool index_mailbox_is_recent(struct index_mailbox *ibox, uint32_t uid);
+unsigned int index_mailbox_get_recent_count(struct index_mailbox *ibox);
 
 void index_mailbox_check_add(struct index_mailbox *ibox,
 			     const char *path);
diff -r d911d943438e -r cadb5b7cd919 src/lib-storage/index/index-sync.c
--- a/src/lib-storage/index/index-sync.c	Mon Jul 16 09:48:02 2007 +0300
+++ b/src/lib-storage/index/index-sync.c	Mon Jul 16 10:21:56 2007 +0300
@@ -49,6 +49,35 @@ bool index_mailbox_is_recent(struct inde
 {
 	return array_is_created(&ibox->recent_flags) &&
 		seq_range_exists(&ibox->recent_flags, uid);
+}
+
+unsigned int index_mailbox_get_recent_count(struct index_mailbox *ibox)
+{
+	const struct mail_index_header *hdr;
+	const struct seq_range *range;
+	unsigned int i, count, recent_count;
+
+	if (!array_is_created(&ibox->recent_flags))
+		return 0;
+
+	hdr = mail_index_get_header(ibox->view);
+	recent_count = ibox->recent_flags_count;
+	range = array_get(&ibox->recent_flags, &count);
+	for (i = count; i > 0; ) {
+		i--;
+		if (range[i].seq2 < hdr->next_uid)
+			break;
+
+		if (range[i].seq1 >= hdr->next_uid) {
+			/* completely invisible to this view */
+			recent_count -= range[i].seq2 - range[i].seq1 + 1;
+		} else {
+			/* partially invisible */
+			recent_count -= range[i].seq2 - hdr->next_uid + 1;
+			break;
+		}
+	}
+	return recent_count;
 }
 
 static void index_mailbox_expunge_recent(struct index_mailbox *ibox,
@@ -200,8 +229,12 @@ int index_mailbox_sync_next(struct mailb
 			return 1;
 		}
 	}
-
-	if (ret == 0 && ctx->expunge_pos > 0) {
+	if (ret < 0) {
+		mail_storage_set_index_error(ctx->ibox);
+		return -1;
+	}
+
+	if (ctx->expunge_pos > 0) {
 		/* expunges is a sorted array of sequences. it's easiest for
 		   us to print them from end to beginning. */
 		const struct seq_range *range;
@@ -222,9 +255,7 @@ int index_mailbox_sync_next(struct mailb
 		return 1;
 	}
 
-	if (ret < 0)
-		mail_storage_set_index_error(ctx->ibox);
-	return ret;
+	return 0;
 }
 
 int index_mailbox_sync_deinit(struct mailbox_sync_context *_ctx,
diff -r d911d943438e -r cadb5b7cd919 src/lib-storage/index/maildir/maildir-sync-index.c
--- a/src/lib-storage/index/maildir/maildir-sync-index.c	Mon Jul 16 09:48:02 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-sync-index.c	Mon Jul 16 10:21:56 2007 +0300
@@ -27,7 +27,7 @@ struct maildir_index_sync_context {
 	enum mail_flags flags;
 	ARRAY_TYPE(keyword_indexes) keywords;
 
-	uint32_t seq, uid, last_nonrecent_seq, last_nonrecent_uid;
+	uint32_t seq, uid;
 
 	bool changed;
 };
@@ -184,46 +184,6 @@ int maildir_sync_index_begin(struct mail
 	return 0;
 }
 
-static int maildir_sync_recent_state(struct maildir_index_sync_context *ctx)
-{
-	const struct mail_index_header *hdr;
-	uint32_t seq1, seq2, first_recent_uid;
-
-	/* see what index thinks is the lowest recent sequence */
-	hdr = mail_index_get_header(ctx->view);
-	if (mail_index_lookup_uid_range(ctx->view, hdr->first_recent_uid,
-					hdr->next_uid, &seq1, &seq2) < 0) {
-		mail_storage_set_index_error(&ctx->mbox->ibox);
-		return -1;
-	}
-
-	if (seq1 == 0 && hdr->first_recent_uid >= ctx->last_nonrecent_uid + 1) {
-		/* nothing new */
-		return 0;
-	}
-
-	if (ctx->last_nonrecent_seq >= seq1) {
-		/* we've seen newer non-recent messages. */
-		seq1 = ctx->last_nonrecent_seq + 1;
-	}
-
-	if (seq2 < ctx->seq)
-		seq2 = ctx->seq - 1;
-
-	if (seq1 <= seq2) {
-		index_mailbox_set_recent_seq(&ctx->mbox->ibox, ctx->view,
-					     seq1, seq2);
-	}
-
-	if (ctx->mbox->ibox.keep_recent &&
-	    hdr->first_recent_uid < ctx->last_nonrecent_uid + 1) {
-		first_recent_uid = ctx->last_nonrecent_uid + 1;
-		mail_index_update_header(ctx->trans,
-			offsetof(struct mail_index_header, first_recent_uid),
-			&first_recent_uid, sizeof(first_recent_uid), FALSE);
-	}
-	return 0;
-}
 int maildir_sync_index_finish(struct maildir_index_sync_context **_ctx,
 			      bool failed, bool cancel)
 {
@@ -236,8 +196,6 @@ int maildir_sync_index_finish(struct mai
 	if (ret < 0 || cancel)
 		mail_index_sync_rollback(&ctx->sync_ctx);
 	else {
-		maildir_sync_recent_state(ctx);
-
 		/* Set syncing_commit=TRUE so that if any sync callbacks try
 		   to access mails which got lost (eg. expunge callback trying
 		   to open the file which was just unlinked) we don't try to
@@ -296,10 +254,10 @@ int maildir_sync_index(struct maildir_in
         enum maildir_uidlist_rec_flag uflags;
 	const char *filename;
 	ARRAY_TYPE(keyword_indexes) idx_keywords;
-	uint32_t uid_validity, next_uid, hdr_next_uid;
+	uint32_t uid_validity, next_uid, hdr_next_uid, last_nonrecent_uid;
 	unsigned int changes = 0;
 	int ret = 0;
-	bool expunged, full_rescan = FALSE;
+	bool recent, expunged, full_rescan = FALSE;
 
 	i_assert(!mbox->syncing_commit);
 	i_assert(maildir_uidlist_is_locked(mbox->uidlist));
@@ -323,7 +281,7 @@ int maildir_sync_index(struct maildir_in
 	hdr_next_uid = hdr->next_uid;
 
 	mbox->syncing_commit = TRUE;
-	seq = prev_uid = 0;
+	seq = prev_uid = last_nonrecent_uid = 0;
 	t_array_init(&ctx->keywords, MAILDIR_MAX_KEYWORDS);
 	t_array_init(&idx_keywords, MAILDIR_MAX_KEYWORDS);
 	iter = maildir_uidlist_iter_init(mbox->uidlist);
@@ -343,10 +301,10 @@ int maildir_sync_index(struct maildir_in
 		ctx->uid = uid;
 
 		if ((uflags & MAILDIR_UIDLIST_REC_FLAG_RECENT) == 0 &&
-		    (uflags & MAILDIR_UIDLIST_REC_FLAG_NONSYNCED) == 0) {
-			ctx->last_nonrecent_seq = seq;
-			ctx->last_nonrecent_uid = uid;
-		}
+		    (uflags & MAILDIR_UIDLIST_REC_FLAG_NONSYNCED) == 0)
+			last_nonrecent_uid = uid;
+		recent = (uflags & MAILDIR_UIDLIST_REC_FLAG_RECENT) != 0 &&
+			uid >= hdr->first_recent_uid;
 
 		if (seq > hdr->messages_count) {
 			if (uid < hdr_next_uid) {
@@ -360,7 +318,6 @@ int maildir_sync_index(struct maildir_in
 			mail_index_append(trans, uid, &seq);
 			mail_index_update_flags(trans, seq, MODIFY_REPLACE,
 						ctx->flags);
-
 			if (array_count(&ctx->keywords) > 0) {
 				struct mail_keywords *kw;
 
@@ -370,6 +327,8 @@ int maildir_sync_index(struct maildir_in
 							   MODIFY_REPLACE, kw);
 				mail_index_keywords_free(&kw);
 			}
+			if (recent)
+				index_mailbox_set_recent_uid(&mbox->ibox, uid);
 			continue;
 		}
 
@@ -409,6 +368,9 @@ int maildir_sync_index(struct maildir_in
 			continue;
 		}
 
+		if (recent)
+			index_mailbox_set_recent_uid(&mbox->ibox, uid);
+
 		/* the private flags are stored only in indexes, keep them */
 		ctx->flags |= rec->flags & mbox->private_flags_mask;
 
@@ -499,5 +461,14 @@ int maildir_sync_index(struct maildir_in
 			offsetof(struct mail_index_header, next_uid),
 			&next_uid, sizeof(next_uid), FALSE);
 	}
+
+	if (ctx->mbox->ibox.keep_recent &&
+	    hdr->first_recent_uid < last_nonrecent_uid + 1) {
+		uint32_t first_recent_uid = last_nonrecent_uid + 1;
+
+		mail_index_update_header(ctx->trans,
+			offsetof(struct mail_index_header, first_recent_uid),
+			&first_recent_uid, sizeof(first_recent_uid), FALSE);
+	}
 	return ret < 0 ? -1 : (full_rescan ? 0 : 1);
 }
diff -r d911d943438e -r cadb5b7cd919 src/lib-storage/index/mbox/mbox-sync-private.h
--- a/src/lib-storage/index/mbox/mbox-sync-private.h	Mon Jul 16 09:48:02 2007 +0300
+++ b/src/lib-storage/index/mbox/mbox-sync-private.h	Mon Jul 16 10:21:56 2007 +0300
@@ -131,7 +131,7 @@ struct mbox_sync_context {
 
 	uint32_t prev_msg_uid, next_uid, idx_next_uid;
 	uint32_t seq, idx_seq, need_space_seq;
-	uint32_t last_nonrecent_idx_seq, last_nonrecent_uid;
+	uint32_t last_nonrecent_uid;
 	off_t expunged_space, space_diff;
 
 	unsigned int dest_first_mail:1;
diff -r d911d943438e -r cadb5b7cd919 src/lib-storage/index/mbox/mbox-sync.c
--- a/src/lib-storage/index/mbox/mbox-sync.c	Mon Jul 16 09:48:02 2007 +0300
+++ b/src/lib-storage/index/mbox/mbox-sync.c	Mon Jul 16 10:21:56 2007 +0300
@@ -446,10 +446,10 @@ static int mbox_sync_update_index(struct
 		}
 	}
 
-	if (!mail_ctx->recent) {
-		sync_ctx->last_nonrecent_idx_seq = sync_ctx->idx_seq;
+	if (!mail_ctx->recent)
 		sync_ctx->last_nonrecent_uid = mail->uid;
-	}
+	else
+		index_mailbox_set_recent_uid(&sync_ctx->mbox->ibox, mail->uid);
 
 	/* update from_offsets, but not if we're going to rewrite this message.
 	   rewriting would just move it anyway. */
@@ -1432,6 +1432,7 @@ static int mbox_sync_update_index_header
 
 static int mbox_sync_recent_state(struct mbox_sync_context *sync_ctx)
 {
+#if 0
 	uint32_t seq1, seq2;
 
 	/* see what index thinks is the lowest recent sequence */
@@ -1453,13 +1454,11 @@ static int mbox_sync_recent_state(struct
 		seq1 = sync_ctx->last_nonrecent_idx_seq + 1;
 	}
 
-	if (seq2 < sync_ctx->idx_seq)
-		seq2 = sync_ctx->idx_seq - 1;
-
 	if (seq1 <= seq2) {
 		index_mailbox_set_recent_seq(&sync_ctx->mbox->ibox,
 					     sync_ctx->sync_view, seq1, seq2);


More information about the dovecot-cvs mailing list