dovecot: mail_index_transaction_sort_appends() fixed to work wit...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Sep 1 00:36:06 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/f2815306ccda
changeset: 6336:f2815306ccda
user: Timo Sirainen <tss at iki.fi>
date: Fri Aug 31 23:41:03 2007 +0300
description:
mail_index_transaction_sort_appends() fixed to work with keywords (dbox-only
problem)
diffstat:
1 file changed, 112 insertions(+), 45 deletions(-)
src/lib-index/mail-index-transaction.c | 157 ++++++++++++++++++++++----------
diffs (186 lines):
diff -r a1c587d3d633 -r f2815306ccda src/lib-index/mail-index-transaction.c
--- a/src/lib-index/mail-index-transaction.c Fri Aug 31 22:58:25 2007 +0300
+++ b/src/lib-index/mail-index-transaction.c Fri Aug 31 23:41:03 2007 +0300
@@ -330,13 +330,115 @@ mail_index_update_day_headers(struct mai
hdr.day_first_uid, sizeof(hdr.day_first_uid), FALSE);
}
+static void
+mail_index_transaction_sort_appends_ext(struct mail_index_transaction *t,
+ const uint32_t *old_to_newseq_map)
+{
+ ARRAY_TYPE(seq_array) *ext_rec_arrays;
+ ARRAY_TYPE(seq_array) *old_array;
+ ARRAY_TYPE(seq_array) new_array;
+ unsigned int ext_count;
+ const uint32_t *ext_rec;
+ uint32_t seq;
+ unsigned int i, j, count;
+
+ if (!array_is_created(&t->ext_rec_updates))
+ return;
+
+ ext_rec_arrays = array_get_modifiable(&t->ext_rec_updates, &count);
+ for (j = 0; j < count; j++) {
+ old_array = &ext_rec_arrays[j];
+ if (!array_is_created(old_array))
+ continue;
+
+ ext_count = array_count(old_array);
+ array_create(&new_array, default_pool,
+ old_array->arr.element_size, ext_count);
+ for (i = 0; i < ext_count; i++) {
+ ext_rec = array_idx(old_array, i);
+
+ seq = *ext_rec < t->first_new_seq ? *ext_rec :
+ old_to_newseq_map[*ext_rec - t->first_new_seq];
+ mail_index_seq_array_add(&new_array, seq, ext_rec+1,
+ old_array->arr.element_size -
+ sizeof(*ext_rec), NULL);
+ }
+ array_free(old_array);
+ ext_rec_arrays[j] = new_array;
+ }
+}
+
+static void
+sort_appends_seq_range(struct mail_index_transaction *t,
+ ARRAY_TYPE(seq_range) *array,
+ const uint32_t *old_to_newseq_map)
+{
+ struct seq_range *range, temp_range;
+ ARRAY_TYPE(seq_range) old_seqs;
+ uint32_t idx, idx1, idx2;
+ unsigned int i, count;
+
+ range = array_get_modifiable(array, &count);
+ for (i = 0; i < count; i++) {
+ if (range[i].seq2 >= t->first_new_seq)
+ break;
+ }
+ if (i == count) {
+ /* nothing to do */
+ return;
+ }
+
+ i_array_init(&old_seqs, count - i);
+ if (range[i].seq1 < t->first_new_seq) {
+ temp_range.seq1 = t->first_new_seq;
+ temp_range.seq2 = range[i].seq2;
+ array_append(&old_seqs, &temp_range, 1);
+ range[i].seq2 = t->first_new_seq - 1;
+ i++;
+ }
+ array_append(&old_seqs, &range[i], count - i);
+ array_delete(array, i, count - i);
+
+ range = array_get_modifiable(&old_seqs, &count);
+ for (i = 0; i < count; i++) {
+ idx1 = range[i].seq1 - t->first_new_seq;
+ idx2 = range[i].seq2 - t->first_new_seq;
+ for (idx = idx1; idx <= idx2; idx++)
+ seq_range_array_add(array, 0, old_to_newseq_map[idx]);
+ }
+ array_free(&old_seqs);
+}
+
+static void
+mail_index_transaction_sort_appends_keywords(struct mail_index_transaction *t,
+ const uint32_t *old_to_newseq_map)
+{
+ struct mail_index_transaction_keyword_update *updates;
+ unsigned int i, count;
+
+ /* fix the order in keywords */
+ if (!array_is_created(&t->keyword_updates))
+ return;
+
+ updates = array_get_modifiable(&t->keyword_updates, &count);
+ for (i = 0; i < count; i++) {
+ if (array_is_created(&updates->add_seq)) {
+ sort_appends_seq_range(t, &updates[i].add_seq,
+ old_to_newseq_map);
+ }
+ if (array_is_created(&updates->remove_seq)) {
+ sort_appends_seq_range(t, &updates[i].remove_seq,
+ old_to_newseq_map);
+ }
+ }
+}
+
void mail_index_transaction_sort_appends(struct mail_index_transaction *t)
{
struct mail_index_record *recs, *sorted_recs;
struct uid_map *new_uid_map;
- ARRAY_TYPE(seq_array) *ext_rec_arrays;
- uint32_t *old_to_new_map;
- unsigned int i, j, count, ext_rec_array_count;
+ uint32_t *old_to_newseq_map;
+ unsigned int i, count;
if (!t->appends_nonsorted)
return;
@@ -351,10 +453,6 @@ void mail_index_transaction_sort_appends
/* now sort the UID map */
qsort(new_uid_map, count, sizeof(*new_uid_map), uid_map_cmp);
-
- old_to_new_map = i_new(uint32_t, count);
- for (i = 0; i < count; i++)
- old_to_new_map[new_uid_map[i].idx] = i;
/* sort mail records */
sorted_recs = i_new(struct mail_index_record, count);
@@ -364,45 +462,14 @@ void mail_index_transaction_sort_appends
sizeof(*sorted_recs) * count);
i_free(sorted_recs);
- /* fix the order in extensions */
- if (!array_is_created(&t->ext_rec_updates)) {
- ext_rec_arrays = NULL;
- ext_rec_array_count = 0;
- } else {
- ext_rec_arrays = array_get_modifiable(&t->ext_rec_updates,
- &ext_rec_array_count);
- }
- for (j = 0; j < ext_rec_array_count; j++) {
- ARRAY_TYPE(seq_array) *old_array = &ext_rec_arrays[j];
- ARRAY_TYPE(seq_array) new_array;
- unsigned int ext_count;
- const uint32_t *ext_rec;
- uint32_t seq;
-
- if (!array_is_created(old_array))
- continue;
-
- ext_count = array_count(old_array);
- array_create(&new_array, default_pool,
- old_array->arr.element_size, ext_count);
- for (i = 0; i < ext_count; i++) {
- ext_rec = array_idx(old_array, i);
-
- seq = *ext_rec < t->first_new_seq ? *ext_rec :
- (t->first_new_seq +
- old_to_new_map[*ext_rec - t->first_new_seq]);
- mail_index_seq_array_add(&new_array, seq, ext_rec+1,
- old_array->arr.element_size -
- sizeof(*ext_rec), NULL);
- }
- array_free(old_array);
- ext_rec_arrays[j] = new_array;
- }
-
- /* FIXME: fix the order in keywords */
-
+ old_to_newseq_map = i_new(uint32_t, count);
+ for (i = 0; i < count; i++)
+ old_to_newseq_map[new_uid_map[i].idx] = i + t->first_new_seq;
i_free(new_uid_map);
- i_free(old_to_new_map);
+
+ mail_index_transaction_sort_appends_ext(t, old_to_newseq_map);
+ mail_index_transaction_sort_appends_keywords(t, old_to_newseq_map);
+ i_free(old_to_newseq_map);
t->appends_nonsorted = FALSE;
}
More information about the dovecot-cvs
mailing list