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