1 /* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
2
3 #include "lib.h"
4 #include "mail-storage-private.h"
5 #include "mailbox-recent-flags.h"
6
mailbox_recent_flags_set_uid(struct mailbox * box,uint32_t uid)7 void mailbox_recent_flags_set_uid(struct mailbox *box, uint32_t uid)
8 {
9 if (uid <= box->recent_flags_prev_uid) {
10 if (seq_range_exists(&box->recent_flags, uid))
11 return;
12
13 mailbox_set_critical(box, "Recent flags state corrupted");
14 array_clear(&box->recent_flags);
15 box->recent_flags_count = 0;
16 }
17 mailbox_recent_flags_set_uid_forced(box, uid);
18 }
19
mailbox_recent_flags_set_uid_forced(struct mailbox * box,uint32_t uid)20 void mailbox_recent_flags_set_uid_forced(struct mailbox *box, uint32_t uid)
21 {
22 box->recent_flags_prev_uid = uid;
23
24 if (!mailbox_recent_flags_have_uid(box, uid)) {
25 seq_range_array_add_with_init(&box->recent_flags, 64, uid);
26 box->recent_flags_count++;
27 }
28 }
29
mailbox_recent_flags_set_seqs(struct mailbox * box,struct mail_index_view * view,uint32_t seq1,uint32_t seq2)30 void mailbox_recent_flags_set_seqs(struct mailbox *box,
31 struct mail_index_view *view,
32 uint32_t seq1, uint32_t seq2)
33 {
34 uint32_t uid;
35
36 for (; seq1 <= seq2; seq1++) {
37 mail_index_lookup_uid(view, seq1, &uid);
38 mailbox_recent_flags_set_uid(box, uid);
39 }
40 }
41
mailbox_recent_flags_have_uid(struct mailbox * box,uint32_t uid)42 bool mailbox_recent_flags_have_uid(struct mailbox *box, uint32_t uid)
43 {
44 return array_is_created(&box->recent_flags) &&
45 seq_range_exists(&box->recent_flags, uid);
46 }
47
mailbox_recent_flags_reset(struct mailbox * box)48 void mailbox_recent_flags_reset(struct mailbox *box)
49 {
50 if (array_is_created(&box->recent_flags))
51 array_clear(&box->recent_flags);
52 box->recent_flags_count = 0;
53 box->recent_flags_prev_uid = 0;
54 }
55
mailbox_recent_flags_count(struct mailbox * box)56 unsigned int mailbox_recent_flags_count(struct mailbox *box)
57 {
58 const struct mail_index_header *hdr;
59 const struct seq_range *range;
60 unsigned int i, count, recent_count;
61
62 if (!array_is_created(&box->recent_flags))
63 return 0;
64
65 hdr = mail_index_get_header(box->view);
66 recent_count = box->recent_flags_count;
67 range = array_get(&box->recent_flags, &count);
68 for (i = count; i > 0; ) {
69 i--;
70 if (range[i].seq2 < hdr->next_uid)
71 break;
72
73 if (range[i].seq1 >= hdr->next_uid) {
74 /* completely invisible to this view */
75 recent_count -= range[i].seq2 - range[i].seq1 + 1;
76 } else {
77 /* partially invisible */
78 recent_count -= range[i].seq2 - hdr->next_uid + 1;
79 break;
80 }
81 }
82 return recent_count;
83 }
84
mailbox_recent_flags_expunge_seqs(struct mailbox * box,uint32_t seq1,uint32_t seq2)85 void mailbox_recent_flags_expunge_seqs(struct mailbox *box,
86 uint32_t seq1, uint32_t seq2)
87 {
88 uint32_t uid;
89
90 if (!array_is_created(&box->recent_flags))
91 return;
92
93 for (; seq1 <= seq2; seq1++) {
94 mail_index_lookup_uid(box->view, seq1, &uid);
95 if (seq_range_array_remove(&box->recent_flags, uid))
96 box->recent_flags_count--;
97 }
98 }
99
mailbox_recent_flags_expunge_uid(struct mailbox * box,uint32_t uid)100 void mailbox_recent_flags_expunge_uid(struct mailbox *box, uint32_t uid)
101 {
102 if (array_is_created(&box->recent_flags)) {
103 if (seq_range_array_remove(&box->recent_flags, uid))
104 box->recent_flags_count--;
105 }
106 }
107