changeset 2317:0cf316c77b1b HEAD

Recent flags should be fully working now with maildir.
author Timo Sirainen <tss@iki.fi>
date Mon, 12 Jul 2004 00:04:46 +0300
parents 1c1ed4494aa4
children 4e925eb04b10
files src/lib-storage/index/index-mail.c src/lib-storage/index/index-status.c src/lib-storage/index/index-storage.h src/lib-storage/index/index-sync.c src/lib-storage/index/maildir/maildir-mail.c src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/maildir/maildir-uidlist.h src/lib-storage/index/mbox/mbox-storage.c
diffstat 8 files changed, 135 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/index-mail.c	Sat Jul 10 20:24:08 2004 +0300
+++ b/src/lib-storage/index/index-mail.c	Mon Jul 12 00:04:46 2004 +0300
@@ -133,6 +133,9 @@
 	struct index_mail_data *data = &mail->data;
 
 	data->flags.flags = data->rec->flags & MAIL_FLAGS_MASK;
+	if (index_mailbox_is_recent(mail->ibox, data->seq))
+		data->flags.flags |= MAIL_RECENT;
+
 	/*FIXME:data->flags.keywords =
 		mail_keywords_list_get(mail->ibox->index->keywords);
 	data->flags.keywords_count = MAIL_KEYWORDS_COUNT;*/
--- a/src/lib-storage/index/index-status.c	Sat Jul 10 20:24:08 2004 +0300
+++ b/src/lib-storage/index/index-status.c	Mon Jul 12 00:04:46 2004 +0300
@@ -41,6 +41,7 @@
 		return -1;
 	if ((items & STATUS_MESSAGE_COUNTS) != 0) {
 		status->messages = hdr->messages_count;
+		status->recent = ibox->synced_recent_count;
 		status->unseen = hdr->messages_count - hdr->seen_messages_count;
 		status->uidvalidity = hdr->uid_validity;
 		status->uidnext = hdr->next_uid;
@@ -55,11 +56,6 @@
 		}
 	}
 
-	if ((items & STATUS_RECENT) != 0) {
-		i_assert(ibox->last_recent_count_initialized);
-		status->recent = ibox->last_recent_count;
-	}
-
 	/*FIXME:if (items & STATUS_KEYWORDS)
 		get_keywords(ibox, status);*/
 
--- a/src/lib-storage/index/index-storage.h	Sat Jul 10 20:24:08 2004 +0300
+++ b/src/lib-storage/index/index-storage.h	Mon Jul 12 00:04:46 2004 +0300
@@ -60,9 +60,8 @@
 	struct mail_cache *cache;
 	struct mail *mail_interface;
 
-	uint32_t (*get_recent_count)(struct index_mailbox *ibox);
 	void (*mail_deinit)(struct index_mail *mail);
-	unsigned int last_recent_count;
+	int (*is_recent)(struct index_mailbox *ibox, uint32_t uid);
 
 	struct timeout *autosync_to;
 	struct index_autosync_file *autosync_files;
@@ -77,6 +76,10 @@
 	uint32_t commit_log_file_seq;
 	uoff_t commit_log_file_offset;
 
+	buffer_t *recent_flags;
+	uint32_t recent_flags_start_seq, recent_flags_count;
+	unsigned int synced_recent_count;
+
 	/* mbox: */
 	int mbox_fd;
 	struct istream *mbox_stream, *mbox_file_stream;
@@ -100,11 +103,11 @@
 
 	unsigned int readonly:1;
 	unsigned int keep_recent:1;
+	unsigned int recent_flags_synced:1;
 	unsigned int sent_diskspace_warning:1;
 	unsigned int sent_readonly_flags_warning:1;
 	unsigned int autosync_pending:1;
 	unsigned int mail_read_mmaped:1;
-	unsigned int last_recent_count_initialized:1;
 	unsigned int syncing_commit:1;
 };
 
@@ -152,6 +155,9 @@
 			       const char *keywords[],
 			       unsigned int keywords_count);
 
+void index_mailbox_set_recent(struct index_mailbox *ibox, uint32_t seq);
+int index_mailbox_is_recent(struct index_mailbox *ibox, uint32_t seq);
+
 unsigned int index_storage_get_recent_count(struct mail_index_view *view);
 
 void index_mailbox_check_add(struct index_mailbox *ibox,
--- a/src/lib-storage/index/index-sync.c	Sat Jul 10 20:24:08 2004 +0300
+++ b/src/lib-storage/index/index-sync.c	Mon Jul 12 00:04:46 2004 +0300
@@ -1,8 +1,102 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "lib.h"
+#include "buffer.h"
 #include "index-storage.h"
 
+void index_mailbox_set_recent(struct index_mailbox *ibox, uint32_t seq)
+{
+	unsigned char *p;
+	static char flag;
+
+	if (ibox->recent_flags_start_seq == 0) {
+		ibox->recent_flags =
+			buffer_create_dynamic(default_pool, 128, (size_t)-1);
+		ibox->recent_flags_start_seq = seq;
+	} else if (seq < ibox->recent_flags_start_seq) {
+		buffer_copy(ibox->recent_flags,
+			    ibox->recent_flags_start_seq - seq,
+			    ibox->recent_flags, 0, (size_t)-1);
+		ibox->recent_flags_start_seq = seq;
+	}
+
+	flag = TRUE;
+	p = buffer_get_space_unsafe(ibox->recent_flags,
+				    seq - ibox->recent_flags_start_seq, 1);
+	if (*p == 0) {
+		ibox->recent_flags_count++;
+		*p = 1;
+	}
+}
+
+int index_mailbox_is_recent(struct index_mailbox *ibox, uint32_t seq)
+{
+	const unsigned char *data;
+	size_t size;
+	uint32_t idx;
+
+	if (seq < ibox->recent_flags_start_seq ||
+	    ibox->recent_flags_start_seq == 0)
+		return FALSE;
+
+	idx = seq - ibox->recent_flags_start_seq;
+	data = buffer_get_data(ibox->recent_flags, &size);
+	return idx < size ? data[idx] : FALSE;
+}
+
+static void index_mailbox_expunge_recent(struct index_mailbox *ibox,
+					 uint32_t seq1, uint32_t seq2)
+{
+	const unsigned char *data;
+	size_t size;
+	uint32_t i, idx, count;
+
+	if (seq2 < ibox->recent_flags_start_seq ||
+	    ibox->recent_flags_start_seq == 0)
+		return;
+
+	if (seq1 < ibox->recent_flags_start_seq)
+		seq1 = ibox->recent_flags_start_seq;
+
+	idx = seq1 - ibox->recent_flags_start_seq;
+	count = seq2 - seq1 + 1;
+
+	data = buffer_get_data(ibox->recent_flags, &size);
+	if (idx > size)
+		return;
+	if (idx + count > size)
+		count = size - idx;
+
+	for (i = 0; i < count; i++) {
+		if (data[idx+i])
+			ibox->recent_flags_count--;
+	}
+
+	buffer_copy(ibox->recent_flags, idx,
+		    ibox->recent_flags, idx + count, (size_t)-1);
+	buffer_set_used_size(ibox->recent_flags, size - count);
+
+}
+
+static int index_mailbox_update_recent(struct index_mailbox *ibox,
+				       uint32_t seq1, uint32_t seq2)
+{
+	const struct mail_index_record *rec;
+
+	for (; seq1 <= seq2; seq1++) {
+		if (mail_index_lookup(ibox->view, seq1, &rec) < 0) {
+			mail_storage_set_index_error(ibox);
+			return -1;
+		}
+
+		if ((rec->flags & MAIL_RECENT) != 0 ||
+		    ibox->is_recent(ibox, rec->uid))
+                        index_mailbox_set_recent(ibox, seq1);
+	}
+
+	return 0;
+}
+
 int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags)
 {
 	struct index_mailbox *ibox = (struct index_mailbox *)box;
@@ -16,7 +110,7 @@
 	void *sc_context;
 	enum mail_index_sync_type sync_mask;
 	uint32_t seq, seq1, seq2;
-	uint32_t messages_count, last_messages_count, recent_count;
+	uint32_t messages_count, last_messages_count;
 	int ret;
 
 	sync_mask = MAIL_INDEX_SYNC_MASK_ALL;
@@ -28,11 +122,12 @@
 		return -1;
 	}
 
-	if (!ibox->last_recent_count_initialized) {
-                ibox->last_recent_count_initialized = TRUE;
-		ibox->last_recent_count = ibox->get_recent_count(ibox);
+	last_messages_count = mail_index_view_get_message_count(ibox->view);
+
+	if (!ibox->recent_flags_synced) {
+		ibox->recent_flags_synced = TRUE;
+                index_mailbox_update_recent(ibox, 1, last_messages_count);
 	}
-	last_messages_count = mail_index_view_get_message_count(ibox->view);
 
 	if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) != 0) {
 		expunges_count = 0;
@@ -76,6 +171,8 @@
 					break;
 				}
 				full_flags.flags = rec->flags; // FIXME
+				if (index_mailbox_is_recent(ibox, seq))
+					full_flags.flags |= MAIL_RECENT;
 				sc->update_flags(&ibox->box, seq,
 						 &full_flags, sc_context);
 			}
@@ -92,6 +189,7 @@
 		messages_count = mail_index_view_get_message_count(ibox->view);
 		for (i = expunges_count*2; i > 0; i -= 2) {
 			seq = expunges[i-1];
+			index_mailbox_expunge_recent(ibox, expunges[i-2], seq);
 			if (seq > messages_count)
 				seq = messages_count;
 			for (; seq >= expunges[i-2]; seq--) {
@@ -105,17 +203,16 @@
 
 	messages_count = mail_index_view_get_message_count(ibox->view);
 	if (messages_count != last_messages_count) {
+		index_mailbox_update_recent(ibox, last_messages_count+1,
+					    messages_count);
 		sc->message_count_changed(&ibox->box, messages_count,
 					  sc_context);
-		recent_count = ibox->get_recent_count(ibox);
-	} else if (expunges_count != 0)
-		recent_count = ibox->get_recent_count(ibox);
-	else
-		recent_count = ibox->last_recent_count;
+	}
 
-	if (recent_count != ibox->last_recent_count) {
-		ibox->last_recent_count = recent_count;
-		sc->recent_count_changed(&ibox->box, recent_count, sc_context);
+	if (ibox->recent_flags_count != ibox->synced_recent_count) {
+                ibox->synced_recent_count = ibox->recent_flags_count;
+		sc->recent_count_changed(&ibox->box, ibox->synced_recent_count,
+					 sc_context);
 	}
 
 	mail_index_view_unlock(ibox->view);
--- a/src/lib-storage/index/maildir/maildir-mail.c	Sat Jul 10 20:24:08 2004 +0300
+++ b/src/lib-storage/index/maildir/maildir-mail.c	Mon Jul 12 00:04:46 2004 +0300
@@ -64,18 +64,6 @@
 	}
 }
 
-static const struct mail_full_flags *maildir_mail_get_flags(struct mail *_mail)
-{
-	struct index_mail *mail = (struct index_mail *)_mail;
-	struct index_mail_data *data = &mail->data;
-
-	(void)index_mail_get_flags(_mail);
-
-	if (maildir_uidlist_is_recent(mail->ibox->uidlist, _mail->uid))
-		data->flags.flags |= MAIL_RECENT;
-	return &data->flags;
-}
-
 static time_t maildir_mail_get_received_date(struct mail *_mail)
 {
 	struct index_mail *mail = (struct index_mail *) _mail;
@@ -180,7 +168,7 @@
 struct mail maildir_mail = {
 	0, 0, 0, 0, 0, 0,
 
-	maildir_mail_get_flags,
+	index_mail_get_flags,
 	index_mail_get_parts,
 	maildir_mail_get_received_date,
 	index_mail_get_date,
--- a/src/lib-storage/index/maildir/maildir-storage.c	Sat Jul 10 20:24:08 2004 +0300
+++ b/src/lib-storage/index/maildir/maildir-storage.c	Mon Jul 12 00:04:46 2004 +0300
@@ -401,9 +401,9 @@
 	return 0;
 }
 
-static uint32_t maildir_get_recent_count(struct index_mailbox *ibox)
+static int maildir_is_recent(struct index_mailbox *ibox, uint32_t uid)
 {
-	return maildir_uidlist_get_recent_count(ibox->uidlist);
+	return maildir_uidlist_is_recent(ibox->uidlist, uid);
 }
 
 static struct mailbox *
@@ -429,9 +429,9 @@
 	ibox->path = i_strdup(path);
 	ibox->control_dir = i_strdup(control_dir);
 
-	ibox->get_recent_count = maildir_get_recent_count;
 	ibox->mail_interface = &maildir_mail;
 	ibox->uidlist = maildir_uidlist_init(ibox);
+	ibox->is_recent = maildir_is_recent;
 
 	/* for shared mailboxes get the create mode from the
 	   permissions of dovecot-shared file */
--- a/src/lib-storage/index/maildir/maildir-uidlist.h	Sat Jul 10 20:24:08 2004 +0300
+++ b/src/lib-storage/index/maildir/maildir-uidlist.h	Mon Jul 12 00:04:46 2004 +0300
@@ -1,4 +1,4 @@
-#ifndef __MAILDIR_UIDLIST_H
+#ifndef __MAILDIR_UIDLI3ST_H
 #define __MAILDIR_UIDLIST_H
 
 #define MAILDIR_UIDLIST_NAME "dovecot-uidlist"
--- a/src/lib-storage/index/mbox/mbox-storage.c	Sat Jul 10 20:24:08 2004 +0300
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Mon Jul 12 00:04:46 2004 +0300
@@ -407,11 +407,6 @@
 	return t_strconcat(storage->dir, "/", name, NULL);
 }
 
-static uint32_t mbox_get_recent_count(struct index_mailbox *ibox)
-{
-	return 0; // FIXME
-}
-
 static void mbox_mail_deinit(struct index_mail *mail)
 {
 	if (mail->ibox->mbox_mail_lock_id != 0) {
@@ -420,6 +415,12 @@
 	}
 }
 
+static int mbox_mail_is_recent(struct index_mailbox *ibox __attr_unused__,
+			       uint32_t uid __attr_unused__)
+{
+	return FALSE;
+}
+
 static struct mailbox *
 mbox_open(struct index_storage *storage, const char *name,
 	  enum mailbox_open_flags flags)
@@ -456,8 +457,8 @@
 	ibox->mbox_lock_type = F_UNLCK;
 	ibox->mbox_extra_idx = mbox_extra_idx;
 
-	ibox->get_recent_count = mbox_get_recent_count;
 	ibox->mail_deinit = mbox_mail_deinit;
+	ibox->is_recent = mbox_mail_is_recent;
 	ibox->mail_interface = &mbox_mail;
 
 	if (access(path, R_OK|W_OK) < 0) {