mail-index-transaction-finish.c revision 4860b8746b3b7846a9fe65b8c2907ba8aebd422f
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2003-2013 Dovecot authors, see the included COPYING file */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint mail_transaction_expunge_guid_cmp(const struct mail_transaction_expunge_guid *e1,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_transaction_expunge_guid *e2)
369a1084c500a9df7448ffa9409ce32e42060bc2Timo Sirainenvoid mail_index_transaction_sort_expunges(struct mail_index_transaction *t)
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen array_sort(&t->expunges, mail_transaction_expunge_guid_cmp);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenext_reset_update_atomic(struct mail_index_transaction *t,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!mail_index_map_get_ext_idx(t->view->index->map, ext_id, &idx)) {
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen /* new extension */
db5164c9a1129af0cfb11fc18d88da361a8011fbTimo Sirainen map_ext = array_idx(&t->view->index->map->extensions, idx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* ignore this extension update */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen array_idx_set(&t->ext_reset_ids, ext_id, &reset_id);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen /* reseting existing data is optional */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen reset = array_idx_modifiable(&t->ext_resets, ext_id);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainentransaction_update_atomic_reset_ids(struct mail_index_transaction *t)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen expected_reset_ids = array_get(&t->ext_reset_atomic, &count);
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainenstatic unsigned int
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainenmail_transaction_drop_range(struct mail_index_transaction *t,
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen unsigned int i, keep_count;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen /* evereything is kept */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen /* add back all the updates we want to keep */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen for (i = 0; i < keep_count; i++, update_idx++) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen array_insert(&t->updates, update_idx, &update, 1);
db87d16551d1081ada01f787ea21aa3ed1402c31Timo Sirainenmail_index_transaction_finish_flag_updates(struct mail_index_transaction *t)
c8adec8db635f5efb13b9879a5f3fb523abdc969Timo Sirainen const struct mail_index_flag_update *updates, *u;
c8adec8db635f5efb13b9879a5f3fb523abdc969Timo Sirainen unsigned int i, count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!t->drop_unnecessary_flag_updates || !array_is_created(&t->updates))
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen for (i = 0; i < count; ) {
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen /* first get the list of changes to drop */
2d39dc1a453546892109b35c0d9770369011a13dTimo Sirainen if ((rec->flags & u->add_flags) != u->add_flags ||
c8adec8db635f5efb13b9879a5f3fb523abdc969Timo Sirainen /* keep this change */
d6a1fa1d65c6d1996937802c2482c0f14dd821a7Timo Sirainen i = mail_transaction_drop_range(t, updates[i], i, &keeps);
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainenmail_index_transaction_check_conflicts(struct mail_index_transaction *t)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (t->max_modseq == mail_index_modseq_get_highest(t->view)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* no conflicts possible */
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen /* no flag updates */
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen for (seq = t->min_flagupdate_seq; seq <= t->max_flagupdate_seq; seq++) {
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen if (mail_index_modseq_lookup(t->view, seq) > t->max_modseq) {
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen ret1 = mail_index_cancel_flag_updates(t, seq);
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen ret2 = mail_index_cancel_keyword_updates(t, seq);
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen seq_range_array_add_with_init(t->conflict_seqs,
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenmail_index_transaction_get_uid(struct mail_index_transaction *t, uint32_t seq)
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen i_assert(seq <= t->view->map->hdr.messages_count);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen rec = MAIL_INDEX_MAP_IDX(t->view->map, seq - 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_index_convert_to_uids(struct mail_index_transaction *t,
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen unsigned int i, count;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen for (i = 0; i < count; i++) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *seq = mail_index_transaction_get_uid(t, *seq);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenget_nonexpunged_uid2(struct mail_index_transaction *t,
db87d16551d1081ada01f787ea21aa3ed1402c31Timo Sirainen while (mail_index_transaction_get_uid(t, seq1) == uid1 + 1) {
eac3948d67eff8623d51aeaea9eca582f3aec677Timo Sirainenmail_index_convert_to_uid_ranges(struct mail_index_transaction *t,
48136ae5a0eb49daa44e343553f3688a500307e2Timo Sirainen unsigned int i, count;
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainen for (i = 0; i < count; i++) {
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainen uid1 = mail_index_transaction_get_uid(t, range->seq1);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen uid2 = mail_index_transaction_get_uid(t, range->seq2);
d6a1fa1d65c6d1996937802c2482c0f14dd821a7Timo Sirainen if (uid2 - uid1 == range->seq2 - range->seq1) {
d6a1fa1d65c6d1996937802c2482c0f14dd821a7Timo Sirainen /* simple conversion */
b92813e2f96d4b28f989528ed5dd6115da7d9bdbTimo Sirainen /* remove expunged UIDs */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen memcpy(new_range, range, array->arr.element_size);
db5164c9a1129af0cfb11fc18d88da361a8011fbTimo Sirainen new_range->seq2 = get_nonexpunged_uid2(t, uid1,
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen /* continue the range without the inserted seqs */
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen range->seq1 += new_range->seq2 - new_range->seq1 + 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void keyword_updates_convert_to_uids(struct mail_index_transaction *t)
aa0647f2debf0d48d504a321186f66c85596aaf4Timo Sirainen struct mail_index_transaction_keyword_update *update;
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainen array_foreach_modifiable(&t->keyword_updates, update) {
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainen mail_index_convert_to_uid_ranges(t, &update->add_seq);
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainen mail_index_convert_to_uid_ranges(t, &update->remove_seq);
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainenstatic void expunges_convert_to_uids(struct mail_index_transaction *t)
768b7f5783c8de119d7386321e5d0c72d5c2d9f6Timo Sirainen struct mail_transaction_expunge_guid *expunges;
89caf81340a4da959ef18c5f9b9c99824a53066bTimo Sirainen expunges = array_get_modifiable(&t->expunges, &count);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen /* convert uids and drop duplicates */
d9de52132072d80b8c268094b879c0ef5a108db3Timo Sirainen expunges[0].uid = mail_index_transaction_get_uid(t, expunges[0].uid);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_transaction_get_uid(t, expunges[src].uid);
685393de106e55b61f754d420e378d05bd462ebbTimo Sirainen if (expunges[dest-1].uid != expunges[dest].uid) {
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen memcpy(expunges[dest].guid_128, expunges[src].guid_128,
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainenmail_index_transaction_convert_to_uids(struct mail_index_transaction *t)
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen array_foreach_modifiable(&t->ext_rec_updates, update)
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen array_foreach_modifiable(&t->ext_rec_atomics, update)
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen mail_index_convert_to_uids(t, (void *)&t->modseq_updates);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen mail_index_convert_to_uid_ranges(t, (void *)&t->updates);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenvoid mail_index_transaction_finish(struct mail_index_transaction *t)
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen mail_index_transaction_finish_flag_updates(t);
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen /* finally convert all sequences to UIDs before we write them,
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen but after we've checked and removed conflicts */
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen /* and kind of ugly way to update highest modseq */