mail-index-transaction-finish.c revision bed3fcccce6a15dfd7491e82df10acd5f5c0bc9b
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2003-2009 Dovecot authors, see the included COPYING file */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "lib.h"
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen#include "array.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mail-index-private.h"
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen#include "mail-index-modseq.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mail-index-transaction-private.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
abf015c9682f0f723db87a7c97bc284ef814818fTimo Sirainenstatic void
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainenext_reset_update_atomic(struct mail_index_transaction *t,
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen uint32_t ext_id, uint32_t expected_reset_id)
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen{
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen const struct mail_index_ext *map_ext;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_transaction_ext_reset *reset;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen uint32_t idx, reset_id;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (!mail_index_map_get_ext_idx(t->view->index->map, ext_id, &idx)) {
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen /* new extension */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen reset_id = 1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen } else {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen map_ext = array_idx(&t->view->index->map->extensions, idx);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen reset_id = map_ext->reset_id + 1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (reset_id != expected_reset_id) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* ignore this extension update */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_index_ext_set_reset_id(t, ext_id, 0);
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen return;
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen }
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen if (reset_id == 0)
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen reset_id++;
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen array_idx_set(&t->ext_reset_ids, ext_id, &reset_id);
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen /* reseting existing data is optional */
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen if (array_is_created(&t->ext_resets)) {
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen reset = array_idx_modifiable(&t->ext_resets, ext_id);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen if (reset->new_reset_id == (uint32_t)-1)
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen reset->new_reset_id = reset_id;
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen}
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenstatic void
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainentransaction_update_atomic_reset_ids(struct mail_index_transaction *t)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen{
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen const uint32_t *expected_reset_ids;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen unsigned int ext_id, count;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (!array_is_created(&t->ext_reset_atomic))
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen return;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen expected_reset_ids = array_get(&t->ext_reset_atomic, &count);
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen for (ext_id = 0; ext_id < count; ext_id++) {
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen if (expected_reset_ids[ext_id] != 0) {
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen ext_reset_update_atomic(t, ext_id,
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen expected_reset_ids[ext_id]);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainenstatic unsigned int
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainenmail_transaction_drop_range(struct mail_index_transaction *t,
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen struct mail_transaction_flag_update update,
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen unsigned int update_idx,
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen ARRAY_TYPE(seq_range) *keeps)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen{
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainen const struct seq_range *keep_range;
49fd8c950e3da2ed32506e617a4b1480a07f874fTimo Sirainen unsigned int i, keep_count;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen keep_range = array_get(keeps, &keep_count);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (keep_count == 1 &&
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen update.uid1 == keep_range[0].seq1 &&
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen update.uid2 == keep_range[0].seq2) {
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen /* evereything is kept */
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen return update_idx + 1;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen }
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen array_delete(&t->updates, update_idx, 1);
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen /* add back all the updates we want to keep */
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen for (i = 0; i < keep_count; i++, update_idx++) {
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen update.uid1 = keep_range[i].seq1;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen update.uid2 = keep_range[i].seq2;
e438c85a6b0f77889e25913bbbba808d6078282dStephan Bosch array_insert(&t->updates, update_idx, &update, 1);
e438c85a6b0f77889e25913bbbba808d6078282dStephan Bosch }
5a9912dcadfd467c5ea54bdc3331eef359f0b1c5Timo Sirainen return update_idx;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen}
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen
38f227941bcf673e0e523c1ac7267bca9cbcd2c4Timo Sirainenstatic void
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmail_index_transaction_finish_flag_updates(struct mail_index_transaction *t)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen{
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen const struct mail_transaction_flag_update *updates, *u;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen const struct mail_index_record *rec;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen unsigned int i, count;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen ARRAY_TYPE(seq_range) keeps;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen uint32_t seq;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (!t->drop_unnecessary_flag_updates)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen return;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen t_array_init(&keeps, 64);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen updates = array_get(&t->updates, &count);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen for (i = 0; i < count; ) {
2eb2cf8eeb763bd5ca9b6848dce32f0303e88ec1Timo Sirainen /* first get the list of changes to drop */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen u = &updates[i];
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen array_clear(&keeps);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen for (seq = u->uid1; seq <= u->uid2; seq++) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rec = mail_index_lookup(t->view, seq);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if ((rec->flags & u->add_flags) != u->add_flags ||
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen (rec->flags & u->remove_flags) != 0) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen /* keep this change */
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen seq_range_array_add(&keeps, 0, seq);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen i = mail_transaction_drop_range(t, updates[i], i, &keeps);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen updates = array_get(&t->updates, &count);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (array_count(&t->updates) == 0)
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen array_free(&t->updates);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic bool
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmail_index_update_cancel_array(ARRAY_TYPE(seq_range) *array, uint32_t seq)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (array_is_created(array)) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (seq_range_array_remove(array, seq)) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (array_count(array) == 0)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen array_free(array);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen return TRUE;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen }
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen return FALSE;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen}
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenstatic bool
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenmail_index_update_cancel(struct mail_index_transaction *t, uint32_t seq)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen{
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen struct mail_index_transaction_keyword_update *kw;
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen struct mail_transaction_flag_update *updates, tmp_update;
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen unsigned int i, count;
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen bool ret, have_kw_changes = FALSE;
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen ret = mail_index_update_cancel_array(&t->keyword_resets, seq);
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen if (array_is_created(&t->keyword_updates)) {
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen kw = array_get_modifiable(&t->keyword_updates, &count);
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen for (i = 0; i < count; i++) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (mail_index_update_cancel_array(&kw[i].add_seq, seq))
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen ret = TRUE;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (mail_index_update_cancel_array(&kw[i].remove_seq,
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen seq))
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen ret = TRUE;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (array_is_created(&kw[i].add_seq) ||
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen array_is_created(&kw[i].remove_seq))
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen have_kw_changes = TRUE;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (!have_kw_changes)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen array_free(&t->keyword_updates);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (!array_is_created(&t->updates))
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen return ret;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen updates = array_get_modifiable(&t->updates, &count);
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen i = mail_index_transaction_get_flag_update_pos(t, 0, count, seq);
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen if (i < count && updates[i].uid1 <= seq && updates[i].uid2 >= seq) {
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen /* exists */
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen ret = TRUE;
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen if (updates[i].uid1 == seq && updates[i].uid2 == seq) {
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen if (count > 1)
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen array_delete(&t->updates, i, 1);
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen else
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen array_free(&t->updates);
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen } else if (updates[i].uid1 == seq)
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen updates[i].uid1++;
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen else if (updates[i].uid2 == seq)
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen updates[i].uid2--;
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen else {
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen /* need to split it in two */
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen tmp_update = updates[i];
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen tmp_update.uid1 = seq+1;
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen updates[i].uid2 = seq-1;
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen array_insert(&t->updates, i + 1, &tmp_update, 1);
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen }
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen }
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen return ret;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen}
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenstatic void
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenmail_index_transaction_check_conflicts(struct mail_index_transaction *t)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen{
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen uint32_t seq;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_assert(t->max_modseq != 0);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_assert(t->conflict_seqs != NULL);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (t->max_modseq == mail_index_modseq_get_highest(t->view)) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* no conflicts possible */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (t->min_flagupdate_seq == 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* no flag updates */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen for (seq = t->min_flagupdate_seq; seq <= t->max_flagupdate_seq; seq++) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (mail_index_modseq_lookup(t->view, seq) > t->max_modseq) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (mail_index_update_cancel(t, seq))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen seq_range_array_add(t->conflict_seqs, 0, seq);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_index_transaction_set_log_updates(t);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic uint32_t
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenmail_index_transaction_get_uid(struct mail_index_transaction *t, uint32_t seq)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const struct mail_index_record *rec;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_assert(seq > 0);
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen if (seq >= t->first_new_seq)
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen rec = mail_index_transaction_lookup(t, seq);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen else {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_assert(seq <= t->view->map->hdr.messages_count);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rec = MAIL_INDEX_MAP_IDX(t->view->map, seq - 1);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_assert(rec->uid != 0);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return rec->uid;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainenstatic void
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenmail_index_convert_to_uids(struct mail_index_transaction *t,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ARRAY_TYPE(seq_array) *array)
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen{
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen uint32_t *seq;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen unsigned int i, count;
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (!array_is_created(array))
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen return;
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen count = array_count(array);
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen for (i = 0; i < count; i++) {
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen seq = array_idx_modifiable(array, i);
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen *seq = mail_index_transaction_get_uid(t, *seq);
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen }
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen}
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainenstatic uint32_t
e30b9e07f9657c35ca09ac36d57d60cbe2ebbc66Timo Sirainenget_nonexpunged_uid2(struct mail_index_transaction *t,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen uint32_t uid1, uint32_t seq1)
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen{
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen seq1++;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen while (mail_index_transaction_get_uid(t, seq1) == uid1 + 1) {
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen seq1++;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen uid1++;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen return uid1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
e438c85a6b0f77889e25913bbbba808d6078282dStephan Boschstatic void
e438c85a6b0f77889e25913bbbba808d6078282dStephan Boschmail_index_convert_to_uid_ranges(struct mail_index_transaction *t,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ARRAY_TYPE(seq_range) *array)
4c261fb48e6e36570a0841aa51ca483024d6a0a6Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct seq_range *range, *new_range;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen unsigned int i, count;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen uint32_t uid1, uid2;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen if (!array_is_created(array))
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen return;
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen count = array_count(array);
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen for (i = 0; i < count; i++) {
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen range = array_idx_modifiable(array, i);
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen uid1 = mail_index_transaction_get_uid(t, range->seq1);
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen uid2 = mail_index_transaction_get_uid(t, range->seq2);
ab90f702ceedb7ba445a9a592be0b213b27cbafaStephan Bosch if (uid2 - uid1 == range->seq2 - range->seq1) {
ab90f702ceedb7ba445a9a592be0b213b27cbafaStephan Bosch /* simple conversion */
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen range->seq1 = uid1;
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen range->seq2 = uid2;
5a9912dcadfd467c5ea54bdc3331eef359f0b1c5Timo Sirainen } else {
5a9912dcadfd467c5ea54bdc3331eef359f0b1c5Timo Sirainen /* remove expunged UIDs */
5a9912dcadfd467c5ea54bdc3331eef359f0b1c5Timo Sirainen new_range = array_insert_space(array, i);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen range = array_idx_modifiable(array, i + 1);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen count++;
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen
4c261fb48e6e36570a0841aa51ca483024d6a0a6Timo Sirainen memcpy(new_range, range, array->arr.element_size);
4c261fb48e6e36570a0841aa51ca483024d6a0a6Timo Sirainen new_range->seq1 = uid1;
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen new_range->seq2 = get_nonexpunged_uid2(t, uid1,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen range->seq1);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* continue the range without the inserted seqs */
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen range->seq1 += new_range->seq2 - new_range->seq1 + 1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic void keyword_updates_convert_to_uids(struct mail_index_transaction *t)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen{
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen struct mail_index_transaction_keyword_update *updates;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen unsigned int i, count;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (!array_is_created(&t->keyword_updates))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return;
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen updates = array_get_modifiable(&t->keyword_updates, &count);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen for (i = 0; i < count; i++) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_index_convert_to_uid_ranges(t, &updates[i].add_seq);
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen mail_index_convert_to_uid_ranges(t, &updates[i].remove_seq);
b9dc21a94401638c00e40b695998875e1563ce77Timo Sirainen }
b9dc21a94401638c00e40b695998875e1563ce77Timo Sirainen}
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainenstatic void
27ca6cb0548c6478005c77d04be641356ec7d83cTimo Sirainenmail_index_transaction_convert_to_uids(struct mail_index_transaction *t)
27ca6cb0548c6478005c77d04be641356ec7d83cTimo Sirainen{
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen ARRAY_TYPE(seq_array) *updates;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen unsigned int i, count;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (array_is_created(&t->ext_rec_updates)) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen updates = array_get_modifiable(&t->ext_rec_updates, &count);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen for (i = 0; i < count; i++)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen mail_index_convert_to_uids(t, (void *)&updates[i]);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (array_is_created(&t->ext_rec_atomics)) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen updates = array_get_modifiable(&t->ext_rec_atomics, &count);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen for (i = 0; i < count; i++)
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen mail_index_convert_to_uids(t, (void *)&updates[i]);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen }
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen keyword_updates_convert_to_uids(t);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen mail_index_convert_to_uid_ranges(t, &t->expunges);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen mail_index_convert_to_uid_ranges(t, (void *)&t->updates);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_index_convert_to_uid_ranges(t, &t->keyword_resets);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainenint mail_index_transaction_finish(struct mail_index_transaction *t)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen mail_index_transaction_sort_appends(t);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_index_transaction_finish_flag_updates(t);
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen if (array_is_created(&t->ext_reset_atomic) || t->max_modseq != 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (mail_index_map(t->view->index,
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen MAIL_INDEX_SYNC_HANDLER_HEAD) <= 0)
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen return -1;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (array_is_created(&t->ext_reset_atomic))
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen transaction_update_atomic_reset_ids(t);
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen if (t->max_modseq != 0)
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen mail_index_transaction_check_conflicts(t);
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen /* finally convert all sequences to UIDs before we write them,
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen but after we've checked and removed conflicts */
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen mail_index_transaction_convert_to_uids(t);
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen return 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen