summaryrefslogtreecommitdiffstats
path: root/src/lib-storage/mailbox-recent-flags.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib-storage/mailbox-recent-flags.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/lib-storage/mailbox-recent-flags.c b/src/lib-storage/mailbox-recent-flags.c
new file mode 100644
index 0000000..5129809
--- /dev/null
+++ b/src/lib-storage/mailbox-recent-flags.c
@@ -0,0 +1,106 @@
+/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "mail-storage-private.h"
+#include "mailbox-recent-flags.h"
+
+void mailbox_recent_flags_set_uid(struct mailbox *box, uint32_t uid)
+{
+ if (uid <= box->recent_flags_prev_uid) {
+ if (seq_range_exists(&box->recent_flags, uid))
+ return;
+
+ mailbox_set_critical(box, "Recent flags state corrupted");
+ array_clear(&box->recent_flags);
+ box->recent_flags_count = 0;
+ }
+ mailbox_recent_flags_set_uid_forced(box, uid);
+}
+
+void mailbox_recent_flags_set_uid_forced(struct mailbox *box, uint32_t uid)
+{
+ box->recent_flags_prev_uid = uid;
+
+ if (!mailbox_recent_flags_have_uid(box, uid)) {
+ seq_range_array_add_with_init(&box->recent_flags, 64, uid);
+ box->recent_flags_count++;
+ }
+}
+
+void mailbox_recent_flags_set_seqs(struct mailbox *box,
+ struct mail_index_view *view,
+ uint32_t seq1, uint32_t seq2)
+{
+ uint32_t uid;
+
+ for (; seq1 <= seq2; seq1++) {
+ mail_index_lookup_uid(view, seq1, &uid);
+ mailbox_recent_flags_set_uid(box, uid);
+ }
+}
+
+bool mailbox_recent_flags_have_uid(struct mailbox *box, uint32_t uid)
+{
+ return array_is_created(&box->recent_flags) &&
+ seq_range_exists(&box->recent_flags, uid);
+}
+
+void mailbox_recent_flags_reset(struct mailbox *box)
+{
+ if (array_is_created(&box->recent_flags))
+ array_clear(&box->recent_flags);
+ box->recent_flags_count = 0;
+ box->recent_flags_prev_uid = 0;
+}
+
+unsigned int mailbox_recent_flags_count(struct mailbox *box)
+{
+ const struct mail_index_header *hdr;
+ const struct seq_range *range;
+ unsigned int i, count, recent_count;
+
+ if (!array_is_created(&box->recent_flags))
+ return 0;
+
+ hdr = mail_index_get_header(box->view);
+ recent_count = box->recent_flags_count;
+ range = array_get(&box->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;
+}
+
+void mailbox_recent_flags_expunge_seqs(struct mailbox *box,
+ uint32_t seq1, uint32_t seq2)
+{
+ uint32_t uid;
+
+ if (!array_is_created(&box->recent_flags))
+ return;
+
+ for (; seq1 <= seq2; seq1++) {
+ mail_index_lookup_uid(box->view, seq1, &uid);
+ if (seq_range_array_remove(&box->recent_flags, uid))
+ box->recent_flags_count--;
+ }
+}
+
+void mailbox_recent_flags_expunge_uid(struct mailbox *box, uint32_t uid)
+{
+ if (array_is_created(&box->recent_flags)) {
+ if (seq_range_array_remove(&box->recent_flags, uid))
+ box->recent_flags_count--;
+ }
+}