mail-index-transaction-finish.c revision bed3fcccce6a15dfd7491e82df10acd5f5c0bc9b
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina/* Copyright (c) 2003-2009 Dovecot authors, see the included COPYING file */
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina#include "lib.h"
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina#include "array.h"
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina#include "mail-index-private.h"
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina#include "mail-index-modseq.h"
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina#include "mail-index-transaction-private.h"
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinastatic void
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinaext_reset_update_atomic(struct mail_index_transaction *t,
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina uint32_t ext_id, uint32_t expected_reset_id)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina{
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina const struct mail_index_ext *map_ext;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina struct mail_transaction_ext_reset *reset;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina uint32_t idx, reset_id;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (!mail_index_map_get_ext_idx(t->view->index->map, ext_id, &idx)) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina /* new extension */
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina reset_id = 1;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina } else {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina map_ext = array_idx(&t->view->index->map->extensions, idx);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina reset_id = map_ext->reset_id + 1;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (reset_id != expected_reset_id) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina /* ignore this extension update */
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina mail_index_ext_set_reset_id(t, ext_id, 0);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
d2633d922eeed68f92be4248b9172b928c189920Jakub Hrozek if (reset_id == 0)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina reset_id++;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina array_idx_set(&t->ext_reset_ids, ext_id, &reset_id);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina /* reseting existing data is optional */
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (array_is_created(&t->ext_resets)) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev reset = array_idx_modifiable(&t->ext_resets, ext_id);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (reset->new_reset_id == (uint32_t)-1)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina reset->new_reset_id = reset_id;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina}
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinastatic void
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinatransaction_update_atomic_reset_ids(struct mail_index_transaction *t)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina{
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina const uint32_t *expected_reset_ids;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina unsigned int ext_id, count;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (!array_is_created(&t->ext_reset_atomic))
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina expected_reset_ids = array_get(&t->ext_reset_atomic, &count);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina for (ext_id = 0; ext_id < count; ext_id++) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (expected_reset_ids[ext_id] != 0) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev ext_reset_update_atomic(t, ext_id,
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina expected_reset_ids[ext_id]);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina}
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
d2633d922eeed68f92be4248b9172b928c189920Jakub Hrozekstatic unsigned int
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinamail_transaction_drop_range(struct mail_index_transaction *t,
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina struct mail_transaction_flag_update update,
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina unsigned int update_idx,
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina ARRAY_TYPE(seq_range) *keeps)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina{
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina const struct seq_range *keep_range;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina unsigned int i, keep_count;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina keep_range = array_get(keeps, &keep_count);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (keep_count == 1 &&
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina update.uid1 == keep_range[0].seq1 &&
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina update.uid2 == keep_range[0].seq2) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina /* evereything is kept */
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return update_idx + 1;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina array_delete(&t->updates, update_idx, 1);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina /* add back all the updates we want to keep */
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina for (i = 0; i < keep_count; i++, update_idx++) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina update.uid1 = keep_range[i].seq1;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina update.uid2 = keep_range[i].seq2;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina array_insert(&t->updates, update_idx, &update, 1);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return update_idx;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina}
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinastatic void
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinamail_index_transaction_finish_flag_updates(struct mail_index_transaction *t)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina{
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina const struct mail_transaction_flag_update *updates, *u;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina const struct mail_index_record *rec;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina unsigned int i, count;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina ARRAY_TYPE(seq_range) keeps;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina uint32_t seq;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (!t->drop_unnecessary_flag_updates)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina t_array_init(&keeps, 64);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina updates = array_get(&t->updates, &count);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina for (i = 0; i < count; ) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina /* first get the list of changes to drop */
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina u = &updates[i];
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina array_clear(&keeps);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina for (seq = u->uid1; seq <= u->uid2; seq++) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina rec = mail_index_lookup(t->view, seq);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if ((rec->flags & u->add_flags) != u->add_flags ||
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina (rec->flags & u->remove_flags) != 0) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina /* keep this change */
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina seq_range_array_add(&keeps, 0, seq);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina i = mail_transaction_drop_range(t, updates[i], i, &keeps);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina updates = array_get(&t->updates, &count);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (array_count(&t->updates) == 0)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina array_free(&t->updates);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina}
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venevstatic bool
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venevmail_index_update_cancel_array(ARRAY_TYPE(seq_range) *array, uint32_t seq)
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev{
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (array_is_created(array)) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (seq_range_array_remove(array, seq)) {
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (array_count(array) == 0)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina array_free(array);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return TRUE;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return FALSE;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina}
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinastatic bool
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinamail_index_update_cancel(struct mail_index_transaction *t, uint32_t seq)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina{
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina struct mail_index_transaction_keyword_update *kw;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina struct mail_transaction_flag_update *updates, tmp_update;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina unsigned int i, count;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina bool ret, have_kw_changes = FALSE;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina ret = mail_index_update_cancel_array(&t->keyword_resets, seq);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (array_is_created(&t->keyword_updates)) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina kw = array_get_modifiable(&t->keyword_updates, &count);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina for (i = 0; i < count; i++) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (mail_index_update_cancel_array(&kw[i].add_seq, seq))
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina ret = TRUE;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (mail_index_update_cancel_array(&kw[i].remove_seq,
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina seq))
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina ret = TRUE;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (array_is_created(&kw[i].add_seq) ||
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina array_is_created(&kw[i].remove_seq))
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina have_kw_changes = TRUE;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (!have_kw_changes)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina array_free(&t->keyword_updates);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (!array_is_created(&t->updates))
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return ret;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina updates = array_get_modifiable(&t->updates, &count);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina i = mail_index_transaction_get_flag_update_pos(t, 0, count, seq);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (i < count && updates[i].uid1 <= seq && updates[i].uid2 >= seq) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina /* exists */
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina ret = TRUE;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (updates[i].uid1 == seq && updates[i].uid2 == seq) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (count > 1)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina array_delete(&t->updates, i, 1);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina else
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina array_free(&t->updates);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina } else if (updates[i].uid1 == seq)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina updates[i].uid1++;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina else if (updates[i].uid2 == seq)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina updates[i].uid2--;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina else {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina /* need to split it in two */
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina tmp_update = updates[i];
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina tmp_update.uid1 = seq+1;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina updates[i].uid2 = seq-1;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina array_insert(&t->updates, i + 1, &tmp_update, 1);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return ret;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina}
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinastatic void
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinamail_index_transaction_check_conflicts(struct mail_index_transaction *t)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina{
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina uint32_t seq;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina i_assert(t->max_modseq != 0);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina i_assert(t->conflict_seqs != NULL);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (t->max_modseq == mail_index_modseq_get_highest(t->view)) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina /* no conflicts possible */
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (t->min_flagupdate_seq == 0) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina /* no flag updates */
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina for (seq = t->min_flagupdate_seq; seq <= t->max_flagupdate_seq; seq++) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (mail_index_modseq_lookup(t->view, seq) > t->max_modseq) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (mail_index_update_cancel(t, seq))
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina seq_range_array_add(t->conflict_seqs, 0, seq);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
383840c0c9c440710352076f844a64745121d251Pavel Březina mail_index_transaction_set_log_updates(t);
383840c0c9c440710352076f844a64745121d251Pavel Březina}
383840c0c9c440710352076f844a64745121d251Pavel Březina
383840c0c9c440710352076f844a64745121d251Pavel Březinastatic uint32_t
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinamail_index_transaction_get_uid(struct mail_index_transaction *t, uint32_t seq)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina{
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina const struct mail_index_record *rec;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina i_assert(seq > 0);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (seq >= t->first_new_seq)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina rec = mail_index_transaction_lookup(t, seq);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina else {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina i_assert(seq <= t->view->map->hdr.messages_count);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina rec = MAIL_INDEX_MAP_IDX(t->view->map, seq - 1);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina i_assert(rec->uid != 0);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return rec->uid;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina}
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinastatic void
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinamail_index_convert_to_uids(struct mail_index_transaction *t,
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina ARRAY_TYPE(seq_array) *array)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina{
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev uint32_t *seq;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina unsigned int i, count;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (!array_is_created(array))
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina count = array_count(array);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina for (i = 0; i < count; i++) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina seq = array_idx_modifiable(array, i);
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev *seq = mail_index_transaction_get_uid(t, *seq);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina}
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinastatic uint32_t
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinaget_nonexpunged_uid2(struct mail_index_transaction *t,
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina uint32_t uid1, uint32_t seq1)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina{
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina seq1++;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina while (mail_index_transaction_get_uid(t, seq1) == uid1 + 1) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina seq1++;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina uid1++;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return uid1;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina}
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinastatic void
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinamail_index_convert_to_uid_ranges(struct mail_index_transaction *t,
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina ARRAY_TYPE(seq_range) *array)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina{
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina struct seq_range *range, *new_range;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina unsigned int i, count;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina uint32_t uid1, uid2;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (!array_is_created(array))
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina count = array_count(array);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina for (i = 0; i < count; i++) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina range = array_idx_modifiable(array, i);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina uid1 = mail_index_transaction_get_uid(t, range->seq1);
4dd38025efda88f123eac672f87d3cda12f050c8Jakub Hrozek uid2 = mail_index_transaction_get_uid(t, range->seq2);
4dd38025efda88f123eac672f87d3cda12f050c8Jakub Hrozek if (uid2 - uid1 == range->seq2 - range->seq1) {
4dd38025efda88f123eac672f87d3cda12f050c8Jakub Hrozek /* simple conversion */
4dd38025efda88f123eac672f87d3cda12f050c8Jakub Hrozek range->seq1 = uid1;
4dd38025efda88f123eac672f87d3cda12f050c8Jakub Hrozek range->seq2 = uid2;
4dd38025efda88f123eac672f87d3cda12f050c8Jakub Hrozek } else {
4dd38025efda88f123eac672f87d3cda12f050c8Jakub Hrozek /* remove expunged UIDs */
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina new_range = array_insert_space(array, i);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina range = array_idx_modifiable(array, i + 1);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina count++;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina memcpy(new_range, range, array->arr.element_size);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina new_range->seq1 = uid1;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina new_range->seq2 = get_nonexpunged_uid2(t, uid1,
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina range->seq1);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina /* continue the range without the inserted seqs */
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina range->seq1 += new_range->seq2 - new_range->seq1 + 1;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina}
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinastatic void keyword_updates_convert_to_uids(struct mail_index_transaction *t)
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev{
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev struct mail_index_transaction_keyword_update *updates;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev unsigned int i, count;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev if (!array_is_created(&t->keyword_updates))
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev return;
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev
60a715a0dd79873d2d2607eab8fdfaf0ffd2e7d3Hristo Venev updates = array_get_modifiable(&t->keyword_updates, &count);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina for (i = 0; i < count; i++) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina mail_index_convert_to_uid_ranges(t, &updates[i].add_seq);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina mail_index_convert_to_uid_ranges(t, &updates[i].remove_seq);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina}
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinastatic void
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinamail_index_transaction_convert_to_uids(struct mail_index_transaction *t)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina{
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina ARRAY_TYPE(seq_array) *updates;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina unsigned int i, count;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (array_is_created(&t->ext_rec_updates)) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina updates = array_get_modifiable(&t->ext_rec_updates, &count);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina for (i = 0; i < count; i++)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina mail_index_convert_to_uids(t, (void *)&updates[i]);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (array_is_created(&t->ext_rec_atomics)) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina updates = array_get_modifiable(&t->ext_rec_atomics, &count);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina for (i = 0; i < count; i++)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina mail_index_convert_to_uids(t, (void *)&updates[i]);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina keyword_updates_convert_to_uids(t);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
383840c0c9c440710352076f844a64745121d251Pavel Březina mail_index_convert_to_uid_ranges(t, &t->expunges);
383840c0c9c440710352076f844a64745121d251Pavel Březina mail_index_convert_to_uid_ranges(t, (void *)&t->updates);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina mail_index_convert_to_uid_ranges(t, &t->keyword_resets);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina}
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březinaint mail_index_transaction_finish(struct mail_index_transaction *t)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina{
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina mail_index_transaction_sort_appends(t);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina mail_index_transaction_finish_flag_updates(t);
383840c0c9c440710352076f844a64745121d251Pavel Březina
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (array_is_created(&t->ext_reset_atomic) || t->max_modseq != 0) {
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (mail_index_map(t->view->index,
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina MAIL_INDEX_SYNC_HANDLER_HEAD) <= 0)
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return -1;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina }
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (array_is_created(&t->ext_reset_atomic))
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina transaction_update_atomic_reset_ids(t);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina if (t->max_modseq != 0)
383840c0c9c440710352076f844a64745121d251Pavel Březina mail_index_transaction_check_conflicts(t);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina /* finally convert all sequences to UIDs before we write them,
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina but after we've checked and removed conflicts */
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina mail_index_transaction_convert_to_uids(t);
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina return 0;
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina}
ce35bb272d25926b8fa0f9450c8b74064f25c816Pavel Březina