mail-index-transaction.c revision 46726d2abcfffdd13cf9dbdb0acb11b2c01c0549
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Inside transaction we keep messages stored in sequences in uid fields.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen Before they're written to transaction log the sequences are changed to
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen UIDs. This is because we're able to compress sequence ranges better. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_transaction_reset(struct mail_index_transaction *t)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_transaction_ext_hdr_update **ext_hdrs;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen recs = array_get_modifiable(&t->ext_rec_updates, &count);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (i = 0; i < count; i++) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ext_hdrs = array_get_modifiable(&t->ext_hdr_updates, &count);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (i = 0; i < count; i++)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_transaction_keyword_update *u;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen u = array_get_modifiable(&t->keyword_updates, &count);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (i = 0; i < count; i++) {
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen t->first_new_seq = mail_index_view_get_messages_count(t->view)+1;
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen memset(t->pre_hdr_mask, 0, sizeof(t->pre_hdr_mask));
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen memset(t->post_hdr_mask, 0, sizeof(t->post_hdr_mask));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_cache_transaction_rollback(t->cache_trans_ctx);
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainenstatic void mail_index_transaction_free(struct mail_index_transaction *t)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_index_transaction_get_view(struct mail_index_transaction *t)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenbool mail_index_transaction_is_expunged(struct mail_index_transaction *t,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_transaction_ref(struct mail_index_transaction *t)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_transaction_unref(struct mail_index_transaction **_t)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (--t->refcount == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenbool mail_index_seq_array_lookup(const ARRAY_TYPE(seq_array) *array,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* we're probably appending it, check */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic bool mail_index_seq_array_add(ARRAY_TYPE(seq_array) *array, uint32_t seq,
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen /* records need to be 32bit aligned */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(array->arr.element_size == sizeof(seq) + aligned_record_size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_seq_array_lookup(array, seq, &idx)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* already there, update */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* save the old record before overwriting it */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen memcpy(old_record, PTR_OFFSET(p, sizeof(seq)),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen memcpy(PTR_OFFSET(p, sizeof(seq)), record, record_size);
return FALSE;
for (i = 0; i < count; i++) {
unsigned int i, count;
for (i = 0; i < count; i++) {
unsigned int i, count;
for (i = 0; i < count; i++) {
FALSE);
struct uid_map {
const int max_days =
int i, days;
if (!t->appends_nonsorted)
for (i = 0; i < count; i++) {
for (i = 0; i < count; i++)
for (i = 0; i < count; i++)
ext_rec_array_count = 0;
for (j = 0; j < ext_rec_array_count; j++) {
unsigned int ext_count;
for (i = 0; i < ext_count; i++) {
(t->first_new_seq +
return next_uid;
int ret;
if (mail_index_transaction_convert_to_uids(t) < 0)
return ret;
t->v.rollback(t);
struct mail_index_record *
if (t->last_new_seq != 0)
if (uid != 0) {
if (!t->appends_nonsorted &&
unsigned int i, count;
for (i = 0; i < count; i++) {
for (; i < count; i++) {
struct mail_transaction_flag_update u,
unsigned int count;
idx++;
tmp_update = u;
move = 0;
~u.remove_flags;
~u.add_flags;
idx--;
switch (modify_type) {
case MODIFY_REPLACE:
case MODIFY_ADD:
case MODIFY_REMOVE:
unsigned int count;
memset(&u, 0, sizeof(u));
switch (modify_type) {
case MODIFY_REPLACE:
case MODIFY_ADD:
case MODIFY_REMOVE:
t->last_update_idx++;
last_update++;
count);
bool prepend)
if (prepend) {
unsigned int i, count;
for (i = 0; i < count; i++) {
return TRUE;
for (i = 0; i < count; i++) {
return TRUE;
for (i = 0; i < count; i++) {
if (ids[i] != 0)
return TRUE;
for (i = 0; i < count; i++) {
return TRUE;
return FALSE;
unsigned int count;
count = 0;
old_data_r)) {
struct mail_keywords *
const char *const keywords[])
struct mail_keywords *k;
unsigned int i, count;
if (count == 0) {
for (i = 0; i < count; i++) {
struct mail_keywords *
struct mail_keywords *k;
unsigned int count;
if (count == 0) {
struct mail_index_transaction_keyword_update *u;
unsigned int i, ku_count;
switch (modify_type) {
case MODIFY_ADD:
case MODIFY_REMOVE:
case MODIFY_REPLACE:
&ku_count);
for (i = 0; i < ku_count; i++) {
struct mail_index_transaction *
struct mail_index_transaction *t;
t->v = trans_vfuncs;
t->first_new_seq =