]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: Added internal mail_index_transaction_finish_so_far()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 14 Nov 2016 16:37:31 +0000 (17:37 +0100)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 18 Nov 2016 11:55:48 +0000 (13:55 +0200)
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().

src/lib-index/mail-index-transaction-finish.c
src/lib-index/mail-index-transaction-private.h
src/lib-index/test-mail-index-transaction-finish.c

index dfd4da3c1247f9d2e2190474759d8f191738af17..0e47c254d3c9a909e2b82c88e6b5cdbc05f565b4 100644 (file)
@@ -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);
index 8b51e7f6557420d841abbce3d32e129f9873da74..44120f2c4323f0085707a87ad4a30538d70ea7ae 100644 (file)
@@ -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);
index edc4c8cf727acae79e50b9e68c27341f539e8b21..40bef559408355daf08d90b4e11e0ca06b11eb23 100644 (file)
@@ -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);
 }