]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Recent flags should be fully working now with maildir.
authorTimo Sirainen <tss@iki.fi>
Sun, 11 Jul 2004 21:04:46 +0000 (00:04 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 11 Jul 2004 21:04:46 +0000 (00:04 +0300)
--HG--
branch : HEAD

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

index 5713aad62a6c3b6a4add192aa7294a2c960f6c35..c5ef65f8672b7a0b889292c9b784a9a643ed5f92 100644 (file)
@@ -133,6 +133,9 @@ const struct mail_full_flags *index_mail_get_flags(struct mail *_mail)
        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;*/
index 62645f29211ed7f5ec59e347533869d85c53e497..e9d7f8632b9c038fdc07b1460fb9c00d34dcc79f 100644 (file)
@@ -41,6 +41,7 @@ int index_storage_get_status(struct mailbox *box,
                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 @@ int index_storage_get_status(struct mailbox *box,
                }
        }
 
-       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);*/
 
index 6f262d961da35769813886d09cace13eeab95e83..3e4602384d1fe7916defe043bcb0cd103c9e931e 100644 (file)
@@ -60,9 +60,8 @@ struct index_mailbox {
        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 @@ struct index_mailbox {
        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 @@ struct index_mailbox {
 
        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 @@ int index_mailbox_fix_keywords(struct index_mailbox *ibox,
                               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,
index f345f1cd79768f12d15c57ae86d4e0f586340e3c..fdb9efa228709e0309f59e8983cfc5e623bcad6f 100644 (file)
@@ -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 @@ int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags)
        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,12 +122,13 @@ int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags)
                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);
+       }
+
        if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) != 0) {
                expunges_count = 0;
                expunges = NULL;
@@ -76,6 +171,8 @@ int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags)
                                        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 @@ int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags)
                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 @@ int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags)
 
        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);
index a33252699ae5c120aebb04ea475c918a86f8db97..c9b6f9aa9d0cafb0df3d839479a6b1aee3b85ac3 100644 (file)
@@ -64,18 +64,6 @@ maildir_open_mail(struct index_mailbox *ibox, uint32_t uid, int *deleted)
        }
 }
 
-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 @@ static struct istream *maildir_mail_get_stream(struct mail *_mail,
 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,
index 58cfa4c31246807b12cd0711dc628559545a3144..4cb1c0e921fa3a42c8cb5fd481909aafcfb3e484 100644 (file)
@@ -401,9 +401,9 @@ static int verify_inbox(struct index_storage *storage)
        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 @@ maildir_open(struct index_storage *storage, const char *name,
        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 */
index 8381ef09ab4da234839776110ac001950c592dcc..8bd58c00e77b87c1ea0c675ba3576c72edcc673c 100644 (file)
@@ -1,4 +1,4 @@
-#ifndef __MAILDIR_UIDLIST_H
+#ifndef __MAILDIR_UIDLI3ST_H
 #define __MAILDIR_UIDLIST_H
 
 #define MAILDIR_UIDLIST_NAME "dovecot-uidlist"
index f0fc8582f970610a450aae14c8db0e6aa411ccf2..c8a1adacddae13861b47c6e33d840b8432a4c570 100644 (file)
@@ -407,11 +407,6 @@ mbox_get_path(struct index_storage *storage, const char *name)
        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 void mbox_mail_deinit(struct index_mail *mail)
        }
 }
 
+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 @@ mbox_open(struct index_storage *storage, const char *name,
        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) {