1 #ifndef MAIL_INDEX_TRANSACTION_PRIVATE_H
2 #define MAIL_INDEX_TRANSACTION_PRIVATE_H
3 
4 #include "seq-range-array.h"
5 #include "mail-transaction-log.h"
6 
7 ARRAY_DEFINE_TYPE(seq_array_array, ARRAY_TYPE(seq_array));
8 
9 struct mail_index_transaction_keyword_update {
10 	ARRAY_TYPE(seq_range) add_seq;
11 	ARRAY_TYPE(seq_range) remove_seq;
12 };
13 
14 struct mail_index_transaction_ext_hdr_update {
15 	size_t alloc_size;
16 	/* mask is in bytes, not bits */
17 	unsigned char *mask;
18 	unsigned char *data;
19 };
20 
21 struct mail_index_transaction_vfuncs {
22 	void (*reset)(struct mail_index_transaction *t);
23 	int (*commit)(struct mail_index_transaction *t,
24 		      struct mail_index_transaction_commit_result *result_r);
25 	void (*rollback)(struct mail_index_transaction *t);
26 };
27 
28 union mail_index_transaction_module_context {
29 	struct mail_index_transaction_vfuncs super;
30 	struct mail_index_module_register *reg;
31 };
32 
33 struct mail_index_flag_update {
34 	uint32_t uid1, uid2;
35 	uint16_t add_flags;
36 	uint16_t remove_flags;
37 };
38 
39 struct mail_index_transaction {
40 	struct mail_index_transaction *prev, *next;
41 	int refcount;
42 
43 	enum mail_index_transaction_flags flags;
44 	struct mail_index_transaction_vfuncs v, *vlast;
45 	struct mail_index_view *view;
46 	struct mail_index_view *latest_view;
47 
48 	/* NOTE: If you add anything new, remember to update
49 	   mail_index_transaction_reset_v() to reset it. */
50         ARRAY(struct mail_index_record) appends;
51 	uint32_t first_new_seq, last_new_seq;
52 	uint32_t highest_append_uid;
53 	/* lowest/highest sequence that updates flags/keywords */
54 	uint32_t min_flagupdate_seq, max_flagupdate_seq;
55 
56 	ARRAY(struct mail_transaction_modseq_update) modseq_updates;
57 	ARRAY(struct mail_transaction_expunge_guid) expunges;
58 	ARRAY(struct mail_index_flag_update) updates;
59 	size_t last_update_idx;
60 
61 	unsigned char pre_hdr_change[sizeof(struct mail_index_header)];
62 	unsigned char pre_hdr_mask[sizeof(struct mail_index_header)];
63 	unsigned char post_hdr_change[sizeof(struct mail_index_header)];
64 	unsigned char post_hdr_mask[sizeof(struct mail_index_header)];
65 
66 	ARRAY(struct mail_index_transaction_ext_hdr_update) ext_hdr_updates;
67 	ARRAY_TYPE(seq_array_array) ext_rec_updates;
68 	ARRAY_TYPE(seq_array_array) ext_rec_atomics;
69 	ARRAY(struct mail_transaction_ext_intro) ext_resizes;
70 	ARRAY(struct mail_transaction_ext_reset) ext_resets;
71 	ARRAY(uint32_t) ext_reset_ids;
72 	ARRAY(uint32_t) ext_reset_atomic;
73 
74 	ARRAY(struct mail_index_transaction_keyword_update) keyword_updates;
75 	buffer_t *attribute_updates; /* [+-][ps]key\0.. */
76 	buffer_t *attribute_updates_suffix; /* <timestamp>[<value len>].. */
77 
78 	uint64_t min_highest_modseq;
79 	uint64_t max_modseq;
80 	ARRAY_TYPE(seq_range) *conflict_seqs;
81 
82 	/* Module-specific contexts. */
83 	ARRAY(union mail_index_transaction_module_context *) module_contexts;
84 
85 	bool no_appends:1;
86 
87 	bool sync_transaction:1;
88 	bool appends_nonsorted:1;
89 	bool expunges_nonsorted:1;
90 	bool drop_unnecessary_flag_updates:1;
91 	bool pre_hdr_changed:1;
92 	bool post_hdr_changed:1;
93 	bool reset:1;
94 	bool index_deleted:1;
95 	bool index_undeleted:1;
96 	bool commit_deleted_index:1;
97 	bool tail_offset_changed:1;
98 	/* non-extension updates. flag updates don't change this because
99 	   they may be added and removed, so be sure to check that the updates
100 	   array is non-empty also. */
101 	bool log_updates:1;
102 	/* extension updates */
103 	bool log_ext_updates:1;
104 };
105 
106 #define MAIL_INDEX_TRANSACTION_HAS_CHANGES(t) \
107 	((t)->log_updates || (t)->log_ext_updates || \
108 	 (array_is_created(&(t)->updates) && array_count(&(t)->updates) > 0) || \
109 	 (t)->index_deleted || (t)->index_undeleted)
110 
111 typedef void hook_mail_index_transaction_created_t(struct mail_index_transaction *t);
112 
113 void mail_index_transaction_hook_register(hook_mail_index_transaction_created_t *hook);
114 void mail_index_transaction_hook_unregister(hook_mail_index_transaction_created_t *hook);
115 
116 struct mail_index_record *
117 mail_index_transaction_lookup(struct mail_index_transaction *t, uint32_t seq);
118 
119 void mail_index_transaction_ref(struct mail_index_transaction *t);
120 void mail_index_transaction_unref(struct mail_index_transaction **t);
121 void mail_index_transaction_reset_v(struct mail_index_transaction *t);
122 
123 void mail_index_transaction_sort_appends(struct mail_index_transaction *t);
124 void mail_index_transaction_sort_expunges(struct mail_index_transaction *t);
125 uint32_t mail_index_transaction_get_next_uid(struct mail_index_transaction *t);
126 void mail_index_transaction_set_log_updates(struct mail_index_transaction *t);
127 void mail_index_update_day_headers(struct mail_index_transaction *t, time_t day_stamp);
128 
129 unsigned int
130 mail_index_transaction_get_flag_update_pos(struct mail_index_transaction *t,
131 					   unsigned int left_idx,
132 					   unsigned int right_idx,
133 					   uint32_t seq);
134 void mail_index_transaction_lookup_latest_keywords(struct mail_index_transaction *t,
135 						   uint32_t seq,
136 						   ARRAY_TYPE(keyword_indexes) *keywords);
137 
138 bool mail_index_cancel_flag_updates(struct mail_index_transaction *t,
139 				    uint32_t seq);
140 bool mail_index_cancel_keyword_updates(struct mail_index_transaction *t,
141 				       uint32_t seq);
142 
143 /* As input the array's each element starts with struct seq_range where
144    uid1..uid2 are actually sequences within the transaction view. This function
145    changes the sequences into UIDs. If the transaction has any appends, they
146    must have already been assigned UIDs. */
147 void mail_index_transaction_seq_range_to_uid(struct mail_index_transaction *t,
148 					     ARRAY_TYPE(seq_range) *array);
149 void mail_index_transaction_finish_so_far(struct mail_index_transaction *t);
150 void mail_index_transaction_finish(struct mail_index_transaction *t);
151 void mail_index_transaction_export(struct mail_index_transaction *t,
152 				   struct mail_transaction_log_append_ctx *append_ctx,
153 				   enum mail_index_transaction_change *changes_r);
154 int mail_transaction_expunge_guid_cmp(const struct mail_transaction_expunge_guid *e1,
155 				      const struct mail_transaction_expunge_guid *e2);
156 unsigned int
157 mail_index_transaction_get_flag_update_pos(struct mail_index_transaction *t,
158 					   unsigned int left_idx,
159 					   unsigned int right_idx,
160 					   uint32_t seq);
161 
162 void mail_index_ext_using_reset_id(struct mail_index_transaction *t,
163 				   uint32_t ext_id, uint32_t reset_id);
164 
165 #endif
166