mail-index-transaction.c revision e02e5d9fe1d86ac1aad3dc70af00b4c801f3b1f3
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (C) 2003-2004 Timo Sirainen */
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen/* Inside transaction we keep messages stored in sequences in uid fields.
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen Before they're written to transaction log the sequences are changed to
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen UIDs. This is because we're able to compress sequence ranges better. */
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainenvoid mail_index_transaction_reset(struct mail_index_transaction *t)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen struct mail_index_transaction_ext_hdr_update **ext_hdrs;
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen recs = array_get_modifiable(&t->ext_rec_updates, &count);
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi for (i = 0; i < count; i++) {
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen ext_hdrs = array_get_modifiable(&t->ext_hdr_updates, &count);
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen for (i = 0; i < count; i++)
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen struct mail_index_transaction_keyword_update *u;
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen u = array_get_modifiable(&t->keyword_updates, &count);
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen for (i = 0; i < count; i++) {
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi t->first_new_seq = mail_index_view_get_messages_count(t->view)+1;
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen memset(t->pre_hdr_mask, 0, sizeof(t->pre_hdr_mask));
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen memset(t->post_hdr_mask, 0, sizeof(t->post_hdr_mask));
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen mail_cache_transaction_rollback(t->cache_trans_ctx);
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainenstatic void mail_index_transaction_free(struct mail_index_transaction *t)
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainenmail_index_transaction_get_view(struct mail_index_transaction *t)
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainenbool mail_index_transaction_is_expunged(struct mail_index_transaction *t,
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainenvoid mail_index_transaction_ref(struct mail_index_transaction *t)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainenvoid mail_index_transaction_unref(struct mail_index_transaction **_t)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen if (--t->refcount == 0)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainenstatic int mail_index_seq_record_cmp(const void *key, const void *data)
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainenbool mail_index_seq_array_lookup(const ARRAY_TYPE(seq_array) *array,
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen unsigned int count;
202b4674243a4a4826c35ed4d089831985c47256Timo Sirainen return bsearch_insert_pos(&seq, base, count, array->arr.element_size,
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainenstatic bool mail_index_seq_array_add(ARRAY_TYPE(seq_array) *array, uint32_t seq,
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen /* records need to be 32bit aligned */
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen i_assert(array->arr.element_size == sizeof(seq) + aligned_record_size);
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen if (mail_index_seq_array_lookup(array, seq, &idx)) {
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen /* already there, update */
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen /* save the old record before overwriting it */
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen memcpy(old_record, PTR_OFFSET(p, sizeof(seq)),
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen memcpy(PTR_OFFSET(p, sizeof(seq)), record, record_size);
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainen memcpy(PTR_OFFSET(p, sizeof(seq)), record, record_size);
f6497ac81e6de57870936d538acccb75ce408fc1Timo Sirainenmail_index_buffer_convert_to_uids(struct mail_index_transaction *t,
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen for (i = 0; i < count; i++) {
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen i_assert(*seq <= view->map->hdr.messages_count);
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen rec = MAIL_INDEX_MAP_IDX(view->map, *seq - 1);
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen /* we're using only rec->uid, no need to bother locking
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen the index. */
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen /* FIXME: replace with simple assert once we
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainen figure out why this happens.. */
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainen "first_new_seq = %u, messages = %u",
a18503d5dc0751a1f9785e48438a219d95c0b9c2Timo Sirainenstatic void keyword_updates_convert_to_uids(struct mail_index_transaction *t)
a18503d5dc0751a1f9785e48438a219d95c0b9c2Timo Sirainen struct mail_index_transaction_keyword_update *updates;
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainen unsigned int i, count;
a18503d5dc0751a1f9785e48438a219d95c0b9c2Timo Sirainen updates = array_get_modifiable(&t->keyword_updates, &count);
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainen for (i = 0; i < count; i++) {
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen if (array_is_created(&updates[i].remove_seq)) {
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainenmail_index_transaction_convert_to_uids(struct mail_index_transaction *t)
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi unsigned int i, count;
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen updates = array_get_modifiable(&t->ext_rec_updates, &count);
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen for (i = 0; i < count; i++) {
f6ae9ae80a1fcf6c8f45ab759f0074caaa66c9c8Timo Sirainen mail_index_buffer_convert_to_uids(t, &updates[i],
10972f2a15f5538860fcc1d4adda227d59d2d757Timo Sirainen mail_index_buffer_convert_to_uids(t, (void *)&t->expunges, TRUE);
10972f2a15f5538860fcc1d4adda227d59d2d757Timo Sirainen mail_index_buffer_convert_to_uids(t, (void *)&t->updates, TRUE);
10972f2a15f5538860fcc1d4adda227d59d2d757Timo Sirainen mail_index_buffer_convert_to_uids(t, (void *)&t->keyword_resets, TRUE);
bb869cc24b24a8df84a43154c628785d6aee784cTimo Sirainenstatic int uid_map_cmp(const void *p1, const void *p2)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainenmail_index_update_day_headers(struct mail_index_transaction *t)
736b1800b0409ba7443d33ecb8d0fb9f8b091660Timo Sirainen sizeof(hdr.day_first_uid) / sizeof(hdr.day_first_uid[0]);
unsigned int ext_count;
unsigned int i, j, count;
for (j = 0; j < count; j++) {
for (i = 0; i < ext_count; i++) {
unsigned int i, count;
for (i = 0; i < count; i++) {
if (i == count) {
for (i = 0; i < count; i++) {
unsigned int i, count;
for (i = 0; i < count; i++) {
unsigned int i, count;
if (!t->appends_nonsorted)
for (i = 0; i < count; i++) {
for (i = 0; i < count; i++)
for (i = 0; i < count; i++)
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++) {
const struct mail_transaction_flag_update *u)
return TRUE;
return TRUE;
return FALSE;
struct mail_transaction_flag_update u,
unsigned int count;
idx++;
tmp_update = u;
move = 0;
&count);
~u.remove_flags;
~u.add_flags;
idx--;
if (mail_transaction_update_want_add(t, &u)) {
count++;
switch (modify_type) {
case MODIFY_REPLACE:
case MODIFY_ADD:
case MODIFY_REMOVE:
memset(&u, 0, sizeof(u));
switch (modify_type) {
case MODIFY_REPLACE:
case MODIFY_ADD:
case MODIFY_REMOVE:
if (mail_transaction_update_want_add(t, &u))
t->last_update_idx++;
last_update++;
if (mail_transaction_update_want_add(t, &u))
else if (t->last_update_idx > 0)
t->last_update_idx--;
first_idx = 0;
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++) {
&k->idx[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 =