mail-index-transaction-finish.c revision d97f939b1c09e9f90b01b6f81bfb1c05da990148
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen/* Copyright (c) 2003-2017 Dovecot authors, see the included COPYING file */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "lib.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "array.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "ioloop.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "mail-index-private.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "mail-index-modseq.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "mail-index-transaction-private.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenint mail_transaction_expunge_guid_cmp(const struct mail_transaction_expunge_guid *e1,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen const struct mail_transaction_expunge_guid *e2)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (e1->uid < e2->uid)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return -1;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen else if (e1->uid > e2->uid)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return 1;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen else
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return 0;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenvoid mail_index_transaction_sort_expunges(struct mail_index_transaction *t)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (!t->expunges_nonsorted)
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen return;
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen array_sort(&t->expunges, mail_transaction_expunge_guid_cmp);
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen t->expunges_nonsorted = FALSE;
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic void
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenext_reset_update_atomic(struct mail_index_transaction *t,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen uint32_t ext_id, uint32_t expected_reset_id)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen const struct mail_index_ext *map_ext;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen struct mail_transaction_ext_reset *reset;
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen uint32_t idx, reset_id;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (!mail_index_map_get_ext_idx(t->view->index->map, ext_id, &idx)) {
3d4450c252790b03bb5ce054987ac91110f1ff62Timo Sirainen /* new extension */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen reset_id = 1;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen } else {
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen map_ext = array_idx(&t->view->index->map->extensions, idx);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen reset_id = map_ext->reset_id + 1;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen }
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (reset_id != expected_reset_id) {
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen /* ignore this extension update */
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen mail_index_ext_set_reset_id(t, ext_id, 0);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen return;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen }
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (reset_id == 0)
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen reset_id++;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen array_idx_set(&t->ext_reset_ids, ext_id, &reset_id);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen /* reseting existing data is optional */
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen if (array_is_created(&t->ext_resets)) {
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen reset = array_idx_modifiable(&t->ext_resets, ext_id);
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen if (reset->new_reset_id == (uint32_t)-1)
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen reset->new_reset_id = reset_id;
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic void
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainentransaction_update_atomic_reset_ids(struct mail_index_transaction *t)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen const uint32_t *expected_reset_ids;
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen unsigned int ext_id, count;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen if (!array_is_created(&t->ext_reset_atomic))
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen return;
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen expected_reset_ids = array_get(&t->ext_reset_atomic, &count);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen for (ext_id = 0; ext_id < count; ext_id++) {
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen if (expected_reset_ids[ext_id] != 0) {
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen ext_reset_update_atomic(t, ext_id,
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen expected_reset_ids[ext_id]);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic unsigned int
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenmail_transaction_drop_range(struct mail_index_transaction *t,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct mail_index_flag_update update,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen unsigned int update_idx,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ARRAY_TYPE(seq_range) *keeps)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen const struct seq_range *keep_range;
3fb1c1f0375ec0a2b00be90b5d61fbc8374e9b90Timo Sirainen unsigned int i, keep_count;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen keep_range = array_get(keeps, &keep_count);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (keep_count == 1 &&
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen update.uid1 == keep_range[0].seq1 &&
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen update.uid2 == keep_range[0].seq2) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* evereything is kept */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return update_idx + 1;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen array_delete(&t->updates, update_idx, 1);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* add back all the updates we want to keep */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen for (i = 0; i < keep_count; i++, update_idx++) {
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen update.uid1 = keep_range[i].seq1;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen update.uid2 = keep_range[i].seq2;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen array_insert(&t->updates, update_idx, &update, 1);
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen }
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen return update_idx;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen}
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainenstatic void
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainenmail_index_transaction_finish_flag_updates(struct mail_index_transaction *t)
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen{
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen const struct mail_index_flag_update *updates, *u;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen const struct mail_index_record *rec;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen unsigned int i, count;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen ARRAY_TYPE(seq_range) keeps;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen uint32_t seq;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen if (!t->drop_unnecessary_flag_updates || !array_is_created(&t->updates))
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen return;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen t_array_init(&keeps, 64);
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen updates = array_get(&t->updates, &count);
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen for (i = 0; i < count; ) {
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen /* first get the list of changes to drop */
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen u = &updates[i];
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen array_clear(&keeps);
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen for (seq = u->uid1; seq <= u->uid2; seq++) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen rec = mail_index_lookup(t->view, seq);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if ((rec->flags & u->add_flags) != u->add_flags ||
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen (rec->flags & u->remove_flags) != 0) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* keep this change */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen seq_range_array_add(&keeps, seq);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen i = mail_transaction_drop_range(t, updates[i], i, &keeps);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen updates = array_get(&t->updates, &count);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (array_count(&t->updates) == 0)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen array_free(&t->updates);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainenstatic void
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenmail_index_transaction_check_conflicts(struct mail_index_transaction *t)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen uint32_t seq;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen bool ret1, ret2;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen i_assert(t->max_modseq != 0);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen i_assert(t->conflict_seqs != NULL);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (t->max_modseq == mail_index_modseq_get_highest(t->view)) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* no conflicts possible */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (t->min_flagupdate_seq == 0) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* no flag updates */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen for (seq = t->min_flagupdate_seq; seq <= t->max_flagupdate_seq; seq++) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (mail_index_modseq_lookup(t->view, seq) > t->max_modseq) {
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen ret1 = mail_index_cancel_flag_updates(t, seq);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ret2 = mail_index_cancel_keyword_updates(t, seq);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (ret1 || ret2) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen seq_range_array_add_with_init(t->conflict_seqs,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen 16, seq);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen mail_index_transaction_set_log_updates(t);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic uint32_t
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenmail_index_transaction_get_uid(struct mail_index_transaction *t, uint32_t seq)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen const struct mail_index_record *rec;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen i_assert(seq > 0);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (seq >= t->first_new_seq)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen rec = mail_index_transaction_lookup(t, seq);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen else {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen i_assert(seq <= t->view->map->hdr.messages_count);
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen rec = MAIL_INDEX_REC_AT_SEQ(t->view->map, seq);
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen }
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen i_assert(rec->uid != 0);
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen return rec->uid;
c63544d7d2580c680b07f9569e87e9cebee383d5Timo Sirainen}
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainenstatic void
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainenmail_index_convert_to_uids(struct mail_index_transaction *t,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ARRAY_TYPE(seq_array) *array)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen uint32_t *seq;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen unsigned int i, count;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (!array_is_created(array))
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen return;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen count = array_count(array);
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen for (i = 0; i < count; i++) {
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen seq = array_idx_modifiable(array, i);
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen *seq = mail_index_transaction_get_uid(t, *seq);
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen }
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen}
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstatic uint32_t
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenget_nonexpunged_uid2(struct mail_index_transaction *t,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen uint32_t uid1, uint32_t seq1)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen seq1++;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen while (mail_index_transaction_get_uid(t, seq1) == uid1 + 1) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen seq1++;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen uid1++;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return uid1;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenvoid mail_index_transaction_seq_range_to_uid(struct mail_index_transaction *t,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ARRAY_TYPE(seq_range) *array)
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen{
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen struct seq_range *range, *new_range;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen unsigned int i, count;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen uint32_t uid1, uid2, prev_uid = 0;
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (!array_is_created(array))
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen return;
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen count = array_count(array);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen for (i = 0; i < count; i++) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen range = array_idx_modifiable(array, i);
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen uid1 = mail_index_transaction_get_uid(t, range->seq1);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen uid2 = mail_index_transaction_get_uid(t, range->seq2);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen i_assert(uid1 > prev_uid);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (uid2 - uid1 == range->seq2 - range->seq1) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* simple conversion */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen range->seq1 = uid1;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen range->seq2 = uid2;
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen prev_uid = uid2;
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen } else {
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen /* remove expunged UIDs */
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen new_range = array_insert_space(array, i);
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen range = array_idx_modifiable(array, i + 1);
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen count++;
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen memcpy(new_range, range, array->arr.element_size);
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen new_range->seq1 = uid1;
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen new_range->seq2 = get_nonexpunged_uid2(t, uid1,
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen range->seq1);
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen i_assert(new_range->seq2 < uid2);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen /* continue the range without the inserted seqs */
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen range->seq1 += new_range->seq2 - new_range->seq1 + 1;
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen prev_uid = new_range->seq2;
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen}
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenstatic void keyword_updates_convert_to_uids(struct mail_index_transaction *t)
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen{
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen struct mail_index_transaction_keyword_update *update;
7c311effa7150d364232e6f2d0a1fa623dbb8d95Timo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (!array_is_created(&t->keyword_updates))
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen return;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen array_foreach_modifiable(&t->keyword_updates, update) {
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen mail_index_transaction_seq_range_to_uid(t, &update->add_seq);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen mail_index_transaction_seq_range_to_uid(t, &update->remove_seq);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen }
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen}
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenstatic void expunges_convert_to_uids(struct mail_index_transaction *t)
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen{
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen struct mail_transaction_expunge_guid *expunges;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen unsigned int src, dest, count;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (!array_is_created(&t->expunges))
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen mail_index_transaction_sort_expunges(t);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen expunges = array_get_modifiable(&t->expunges, &count);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (count == 0)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen /* convert uids and drop duplicates */
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen expunges[0].uid = mail_index_transaction_get_uid(t, expunges[0].uid);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen for (src = dest = 1; src < count; src++) {
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen expunges[dest].uid =
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen mail_index_transaction_get_uid(t, expunges[src].uid);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (expunges[dest-1].uid != expunges[dest].uid) {
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (dest != src) {
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen memcpy(expunges[dest].guid_128, expunges[src].guid_128,
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen sizeof(expunges[dest].guid_128));
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen }
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen dest++;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen array_delete(&t->expunges, dest, count-dest);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen}
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenstatic void
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenmail_index_transaction_convert_to_uids(struct mail_index_transaction *t)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen ARRAY_TYPE(seq_array) *update;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (array_is_created(&t->ext_rec_updates)) {
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen array_foreach_modifiable(&t->ext_rec_updates, update)
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen mail_index_convert_to_uids(t, update);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen }
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (array_is_created(&t->ext_rec_atomics)) {
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen array_foreach_modifiable(&t->ext_rec_atomics, update)
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen mail_index_convert_to_uids(t, update);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen }
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen keyword_updates_convert_to_uids(t);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen expunges_convert_to_uids(t);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen mail_index_convert_to_uids(t, (void *)&t->modseq_updates);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen mail_index_transaction_seq_range_to_uid(t, (void *)&t->updates);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen}
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenvoid mail_index_transaction_finish_so_far(struct mail_index_transaction *t)
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen{
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (array_is_created(&t->appends))
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen mail_index_transaction_sort_appends(t);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen mail_index_transaction_finish_flag_updates(t);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (t->max_modseq != 0)
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen mail_index_transaction_check_conflicts(t);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen}
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenvoid mail_index_transaction_finish(struct mail_index_transaction *t)
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen{
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen mail_index_transaction_finish_so_far(t);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (array_is_created(&t->appends))
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen mail_index_update_day_headers(t, ioloop_time);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (array_is_created(&t->ext_reset_atomic))
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen transaction_update_atomic_reset_ids(t);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen /* finally convert all sequences to UIDs before we write them,
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen but after we've checked and removed conflicts */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen mail_index_transaction_convert_to_uids(t);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen /* and kind of ugly way to update highest modseq */
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (t->min_highest_modseq != 0)
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen mail_index_update_modseq(t, 0, t->min_highest_modseq);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen}
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen