From: Timo Sirainen Date: Mon, 14 Nov 2016 16:37:31 +0000 (+0100) Subject: lib-index: Added internal mail_index_transaction_finish_so_far() X-Git-Tag: 2.2.27~123 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3ccf77afa814cc08736a684acfb0e95083d17c68;p=thirdparty%2Fdovecot%2Fcore.git lib-index: Added internal mail_index_transaction_finish_so_far() This can be called multiple times before mail_index_transaction_finish(). It's going to perform all the work of reordering mails and dropping unnecessary changes that can be done before changing sequences to UIDs. This will be needed for the following patch that implements mail_index_transaction_get_highest_modseq(). --- diff --git a/src/lib-index/mail-index-transaction-finish.c b/src/lib-index/mail-index-transaction-finish.c index dfd4da3c12..0e47c254d3 100644 --- a/src/lib-index/mail-index-transaction-finish.c +++ b/src/lib-index/mail-index-transaction-finish.c @@ -323,18 +323,23 @@ mail_index_transaction_convert_to_uids(struct mail_index_transaction *t) mail_index_convert_to_uid_ranges(t, (void *)&t->updates); } -void mail_index_transaction_finish(struct mail_index_transaction *t) +void mail_index_transaction_finish_so_far(struct mail_index_transaction *t) { - if (array_is_created(&t->appends)) { + if (array_is_created(&t->appends)) mail_index_transaction_sort_appends(t); - mail_index_update_day_headers(t); - } mail_index_transaction_finish_flag_updates(t); + if (t->max_modseq != 0) + mail_index_transaction_check_conflicts(t); +} +void mail_index_transaction_finish(struct mail_index_transaction *t) +{ + mail_index_transaction_finish_so_far(t); + + if (array_is_created(&t->appends)) + mail_index_update_day_headers(t); if (array_is_created(&t->ext_reset_atomic)) transaction_update_atomic_reset_ids(t); - if (t->max_modseq != 0) - mail_index_transaction_check_conflicts(t); /* finally convert all sequences to UIDs before we write them, but after we've checked and removed conflicts */ mail_index_transaction_convert_to_uids(t); diff --git a/src/lib-index/mail-index-transaction-private.h b/src/lib-index/mail-index-transaction-private.h index 8b51e7f655..44120f2c43 100644 --- a/src/lib-index/mail-index-transaction-private.h +++ b/src/lib-index/mail-index-transaction-private.h @@ -137,6 +137,7 @@ bool mail_index_cancel_flag_updates(struct mail_index_transaction *t, bool mail_index_cancel_keyword_updates(struct mail_index_transaction *t, uint32_t seq); +void mail_index_transaction_finish_so_far(struct mail_index_transaction *t); void mail_index_transaction_finish(struct mail_index_transaction *t); void mail_index_transaction_export(struct mail_index_transaction *t, struct mail_transaction_log_append_ctx *append_ctx); diff --git a/src/lib-index/test-mail-index-transaction-finish.c b/src/lib-index/test-mail-index-transaction-finish.c index edc4c8cf72..40bef55940 100644 --- a/src/lib-index/test-mail-index-transaction-finish.c +++ b/src/lib-index/test-mail-index-transaction-finish.c @@ -56,7 +56,13 @@ uint64_t mail_index_modseq_get_highest(struct mail_index_view *view ATTR_UNUSED) return modseqs[0]; } -static void test_mail_index_transaction_finish_flag_updates(void) +#define MAIL_INDEX_TRANSACTION_FINISH(t, n_so_far) \ + for (unsigned int sofar = 0; sofar < n_so_far; sofar++) \ + mail_index_transaction_finish_so_far(t); \ + mail_index_transaction_finish(t); + +static void +test_mail_index_transaction_finish_flag_updates(unsigned int n_so_far) { struct mail_index_transaction *t; const struct mail_index_flag_update *updates; @@ -69,7 +75,7 @@ static void test_mail_index_transaction_finish_flag_updates(void) memset(&u, 0, sizeof(u)); u.add_flags = MAIL_SEEN; u.remove_flags = MAIL_DRAFT; - test_begin("mail index transaction finish flag updates"); + test_begin(t_strdup_printf("mail index transaction finish flag updates n_so_far=%u", n_so_far)); /* test fast path: all changed */ t_array_init(&t->updates, 10); @@ -77,7 +83,7 @@ static void test_mail_index_transaction_finish_flag_updates(void) array_append(&t->updates, &u, 1); u.uid1 = 4; u.uid2 = 5; array_append(&t->updates, &u, 1); - mail_index_transaction_finish(t); + MAIL_INDEX_TRANSACTION_FINISH(t, n_so_far); updates = array_get(&t->updates, &count); test_assert(count == 4); @@ -96,7 +102,7 @@ static void test_mail_index_transaction_finish_flag_updates(void) recs[2].flags = MAIL_SEEN; recs[4].flags = MAIL_SEEN; recs[5].flags = MAIL_SEEN; - mail_index_transaction_finish(t); + MAIL_INDEX_TRANSACTION_FINISH(t, n_so_far); test_assert(!array_is_created(&t->updates)); /* some changes */ @@ -105,7 +111,7 @@ static void test_mail_index_transaction_finish_flag_updates(void) array_append(&t->updates, &u, 1); u.uid1 = 5; u.uid2 = 6; array_append(&t->updates, &u, 1); - mail_index_transaction_finish(t); + MAIL_INDEX_TRANSACTION_FINISH(t, n_so_far); updates = array_get(&t->updates, &count); test_assert(count == 2); @@ -115,7 +121,8 @@ static void test_mail_index_transaction_finish_flag_updates(void) test_end(); } -static void test_mail_index_transaction_finish_check_conflicts(void) +static void +test_mail_index_transaction_finish_check_conflicts(unsigned int n_so_far) { struct mail_index_transaction *t; const struct seq_range *conflicts; @@ -134,16 +141,16 @@ static void test_mail_index_transaction_finish_check_conflicts(void) modseqs[7] = 6; modseqs[8] = 7; - test_begin("mail index transaction finish check conflicts"); + test_begin(t_strdup_printf("mail index transaction finish check conflicts n_so_far=%u", n_so_far)); /* fast path: no conflicts */ t->max_modseq = 1234; - mail_index_transaction_finish(t); + MAIL_INDEX_TRANSACTION_FINISH(t, n_so_far); test_assert(!array_is_created(&conflict_seqs)); /* try some conflicts */ t->max_modseq = 6; - mail_index_transaction_finish(t); + MAIL_INDEX_TRANSACTION_FINISH(t, n_so_far); conflicts = array_get(&conflict_seqs, &count); test_assert(count == 2); @@ -154,7 +161,8 @@ static void test_mail_index_transaction_finish_check_conflicts(void) array_free(t->conflict_seqs); } -static void test_mail_index_transaction_finish_modseq_updates(void) +static void +test_mail_index_transaction_finish_modseq_updates(unsigned int n_so_far) { struct mail_index_transaction *t; const struct mail_transaction_modseq_update *ups; @@ -163,7 +171,7 @@ static void test_mail_index_transaction_finish_modseq_updates(void) t = t_new(struct mail_index_transaction, 1); - test_begin("mail index transaction finish modseq updates"); + test_begin(t_strdup_printf("mail index transaction finish modseq updates n_so_far=%u", n_so_far)); t_array_init(&t->modseq_updates, 10); u.modseq_low32 = 1234567890; @@ -179,7 +187,7 @@ static void test_mail_index_transaction_finish_modseq_updates(void) u.modseq_high32 = 0; u.uid = 2; array_append(&t->modseq_updates, &u, 1); - mail_index_transaction_finish(t); + MAIL_INDEX_TRANSACTION_FINISH(t, n_so_far); ups = array_get(&t->modseq_updates, &count); test_assert(count == 4); @@ -199,7 +207,8 @@ static void test_mail_index_transaction_finish_modseq_updates(void) test_end(); } -static void test_mail_index_transaction_finish_expunges(void) +static void +test_mail_index_transaction_finish_expunges(unsigned int n_so_far) { struct mail_index_transaction *t; guid_128_t guid1, guid2, guid3; @@ -220,7 +229,7 @@ static void test_mail_index_transaction_finish_expunges(void) t = t_new(struct mail_index_transaction, 1); t->expunges_nonsorted = TRUE; - test_begin("mail index transaction finish expunges"); + test_begin(t_strdup_printf("mail index transaction finish expunges n_so_far=%u", n_so_far)); t_array_init(&t->expunges, 3); expunge.uid = 2; @@ -236,7 +245,7 @@ static void test_mail_index_transaction_finish_expunges(void) array_append(&t->expunges, &expunge, 1); array_append(&t->expunges, &expunge, 1); - mail_index_transaction_finish(t); + MAIL_INDEX_TRANSACTION_FINISH(t, n_so_far); expunges = array_get(&t->expunges, &count); test_assert(count == 3); @@ -249,18 +258,38 @@ static void test_mail_index_transaction_finish_expunges(void) test_end(); } -int main(void) +static void test_state_reset(void) { - static void (*test_functions[])(void) = { + memset(recs, 0, sizeof(recs)); + memset(modseqs, 0, sizeof(modseqs)); + for (unsigned int n = 1; n < N_ELEMENTS(recs); n++) + recs[n].uid = n*2; +} + +static void test_mail_index_transaction_finish(void) +{ + void (*const test_finish_functions[])(unsigned int) = { test_mail_index_transaction_finish_flag_updates, test_mail_index_transaction_finish_check_conflicts, test_mail_index_transaction_finish_modseq_updates, test_mail_index_transaction_finish_expunges, + }; + unsigned int i, j; + + for (i = 0; i < N_ELEMENTS(test_finish_functions); i++) { + for (j = 0; j < 3; j++) { + test_state_reset(); + test_finish_functions[i](j); + } + } +} + +int main(void) +{ + static void (*test_functions[])(void) = { + test_mail_index_transaction_finish, NULL }; - unsigned int i; - for (i = 1; i < N_ELEMENTS(recs); i++) - recs[i].uid = i*2; return test_run(test_functions); }