Mercurial > dovecot > original-hg > dovecot-1.2
changeset 7133:e0115302e68e HEAD
When converting sequence ranges to UID ranges, don't try to optimize the UID
ranges by letting them contain expunged UIDs. This makes the transactions
somewhat larger if UID range has holes, but it properly fixes problems with
updating flags for expunged messages.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 07 Jan 2008 07:37:12 +0200 |
parents | a1d1f7c9671e |
children | 9c2b65bfe604 |
files | src/lib-index/mail-index-transaction.c |
diffstat | 1 files changed, 75 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-index-transaction.c Mon Jan 07 07:34:08 2008 +0200 +++ b/src/lib-index/mail-index-transaction.c Mon Jan 07 07:37:12 2008 +0200 @@ -196,44 +196,87 @@ } } -static void -mail_index_buffer_convert_to_uids(struct mail_index_transaction *t, - ARRAY_TYPE(seq_array) *array, bool range) +static uint32_t +mail_index_transaction_get_uid(struct mail_index_transaction *t, uint32_t seq) { - struct mail_index_view *view = t->view; const struct mail_index_record *rec; + + i_assert(seq > 0); + + if (seq >= t->first_new_seq) + rec = mail_index_transaction_lookup(t, seq); + else { + i_assert(seq <= t->view->map->hdr.messages_count); + rec = MAIL_INDEX_MAP_IDX(t->view->map, seq - 1); + } + i_assert(rec->uid != 0); + return rec->uid; +} + +static void +mail_index_convert_to_uids(struct mail_index_transaction *t, + ARRAY_TYPE(seq_array) *array) +{ uint32_t *seq; - unsigned int i, j, count, range_count; + unsigned int i, count; if (!array_is_created(array)) return; count = array_count(array); - range_count = range ? 1 : 0; for (i = 0; i < count; i++) { seq = array_idx_modifiable(array, i); + *seq = mail_index_transaction_get_uid(t, *seq); + } +} - for (j = 0; j <= range_count; j++, seq++) { - i_assert(*seq > 0); +static uint32_t +get_nonexpunged_uid2(struct mail_index_transaction *t, + uint32_t uid1, uint32_t seq1) +{ + seq1++; - if (*seq >= t->first_new_seq) - rec = mail_index_transaction_lookup(t, *seq); - else { - i_assert(*seq <= view->map->hdr.messages_count); - rec = MAIL_INDEX_MAP_IDX(view->map, *seq - 1); - } + while (mail_index_transaction_get_uid(t, seq1) == uid1 + 1) { + seq1++; + uid1++; + } + return uid1; +} + +static void +mail_index_convert_to_uid_ranges(struct mail_index_transaction *t, + ARRAY_TYPE(seq_range) *array) +{ + struct seq_range *range, *new_range; + unsigned int i, count; + uint32_t uid1, uid2; - /* we're using only rec->uid, no need to bother locking - the index. */ - if (rec->uid == 0) { - /* FIXME: replace with simple assert once we - figure out why this happens.. */ - i_panic("seq = %u, rec->uid = %u, " - "first_new_seq = %u, messages = %u", - *seq, rec->uid, t->first_new_seq, - view->map->hdr.messages_count); - } - *seq = rec->uid; + if (!array_is_created(array)) + return; + + count = array_count(array); + for (i = 0; i < count; i++) { + range = array_idx_modifiable(array, i); + + uid1 = mail_index_transaction_get_uid(t, range->seq1); + uid2 = mail_index_transaction_get_uid(t, range->seq2); + if (uid2 - uid1 == range->seq2 - range->seq1) { + /* simple conversion */ + range->seq1 = uid1; + range->seq2 = uid2; + } else { + /* remove expunged UIDs */ + new_range = array_insert_space(array, i); + range = array_idx_modifiable(array, i + 1); + count++; + + memcpy(new_range, range, array->arr.element_size); + new_range->seq1 = uid1; + new_range->seq2 = get_nonexpunged_uid2(t, uid1, + range->seq1); + + /* continue the range without the inserted seqs */ + range->seq1 += new_range->seq2 - new_range->seq1 + 1; } } } @@ -248,14 +291,8 @@ updates = array_get_modifiable(&t->keyword_updates, &count); for (i = 0; i < count; i++) { - if (array_is_created(&updates[i].add_seq)) { - mail_index_buffer_convert_to_uids(t, - (void *)&updates[i].add_seq, TRUE); - } - if (array_is_created(&updates[i].remove_seq)) { - mail_index_buffer_convert_to_uids(t, - (void *)&updates[i].remove_seq, TRUE); - } + mail_index_convert_to_uid_ranges(t, &updates[i].add_seq); + mail_index_convert_to_uid_ranges(t, &updates[i].remove_seq); } } @@ -267,19 +304,15 @@ if (array_is_created(&t->ext_rec_updates)) { updates = array_get_modifiable(&t->ext_rec_updates, &count); - for (i = 0; i < count; i++) { - if (!array_is_created(&updates[i])) - continue; - mail_index_buffer_convert_to_uids(t, &updates[i], - FALSE); - } + for (i = 0; i < count; i++) + mail_index_convert_to_uids(t, (void *)&updates[i]); } keyword_updates_convert_to_uids(t); - mail_index_buffer_convert_to_uids(t, (void *)&t->expunges, TRUE); - mail_index_buffer_convert_to_uids(t, (void *)&t->updates, TRUE); - mail_index_buffer_convert_to_uids(t, (void *)&t->keyword_resets, TRUE); + mail_index_convert_to_uid_ranges(t, &t->expunges); + mail_index_convert_to_uid_ranges(t, (void *)&t->updates); + mail_index_convert_to_uid_ranges(t, &t->keyword_resets); return 0; }