dovecot-2.0: Moved around mail-index-transaction code and added ...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Jul 14 02:58:04 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/cae78e734cdb
changeset: 9622:cae78e734cdb
user: Timo Sirainen <tss at iki.fi>
date: Mon Jul 13 19:54:28 2009 -0400
description:
Moved around mail-index-transaction code and added initial unit tests.
diffstat:
6 files changed, 1493 insertions(+), 1046 deletions(-)
src/lib-index/Makefile.am | 6
src/lib-index/mail-index-transaction-finish.c | 5
src/lib-index/mail-index-transaction-private.h | 7
src/lib-index/mail-index-transaction-update.c | 1013 ++++++++++++++++++
src/lib-index/mail-index-transaction.c | 1073 --------------------
src/lib-index/test-mail-index-transaction-update.c | 435 ++++++++
diffs (truncated from 2653 to 300 lines):
diff -r 8c17eb6c28d6 -r cae78e734cdb src/lib-index/Makefile.am
--- a/src/lib-index/Makefile.am Mon Jul 13 19:42:01 2009 -0400
+++ b/src/lib-index/Makefile.am Mon Jul 13 19:54:28 2009 -0400
@@ -25,6 +25,7 @@ libindex_la_SOURCES = \
mail-index-transaction-export.c \
mail-index-transaction-finish.c \
mail-index-transaction-sort-appends.c \
+ mail-index-transaction-update.c \
mail-index-transaction-view.c \
mail-index-strmap.c \
mail-index-sync.c \
@@ -60,6 +61,7 @@ headers = \
mailbox-list-index-private.h
test_programs = \
+ test-mail-index-transaction-update \
test-mail-transaction-log-append \
test-mail-transaction-log-view
@@ -69,6 +71,10 @@ test_libs = \
mail-index-util.lo \
../lib-test/libtest.la \
../lib/liblib.la
+
+test_mail_index_transaction_update_SOURCES = test-mail-index-transaction-update.c
+test_mail_index_transaction_update_LDADD = mail-index-transaction-update.lo $(test_libs)
+test_mail_index_transaction_update_DEPENDENCIES = mail-index-transaction-update.lo $(test_libs)
test_mail_transaction_log_append_SOURCES = test-mail-transaction-log-append.c
test_mail_transaction_log_append_LDADD = mail-transaction-log-append.lo $(test_libs)
diff -r 8c17eb6c28d6 -r cae78e734cdb src/lib-index/mail-index-transaction-finish.c
--- a/src/lib-index/mail-index-transaction-finish.c Mon Jul 13 19:42:01 2009 -0400
+++ b/src/lib-index/mail-index-transaction-finish.c Mon Jul 13 19:54:28 2009 -0400
@@ -338,7 +338,10 @@ mail_index_transaction_convert_to_uids(s
int mail_index_transaction_finish(struct mail_index_transaction *t)
{
- mail_index_transaction_sort_appends(t);
+ if (array_is_created(&t->appends)) {
+ mail_index_update_day_headers(t);
+ mail_index_transaction_sort_appends(t);
+ }
mail_index_transaction_finish_flag_updates(t);
if (array_is_created(&t->ext_reset_atomic) || t->max_modseq != 0) {
diff -r 8c17eb6c28d6 -r cae78e734cdb src/lib-index/mail-index-transaction-private.h
--- a/src/lib-index/mail-index-transaction-private.h Mon Jul 13 19:42:01 2009 -0400
+++ b/src/lib-index/mail-index-transaction-private.h Mon Jul 13 19:54:28 2009 -0400
@@ -101,10 +101,12 @@ mail_index_transaction_lookup(struct mai
void mail_index_transaction_ref(struct mail_index_transaction *t);
void mail_index_transaction_unref(struct mail_index_transaction **t);
+void mail_index_transaction_reset_v(struct mail_index_transaction *t);
void mail_index_transaction_sort_appends(struct mail_index_transaction *t);
uint32_t mail_index_transaction_get_next_uid(struct mail_index_transaction *t);
void mail_index_transaction_set_log_updates(struct mail_index_transaction *t);
+void mail_index_update_day_headers(struct mail_index_transaction *t);
unsigned int
mail_index_transaction_get_flag_update_pos(struct mail_index_transaction *t,
@@ -115,5 +117,10 @@ int mail_index_transaction_finish(struct
int 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);
+unsigned int
+mail_index_transaction_get_flag_update_pos(struct mail_index_transaction *t,
+ unsigned int left_idx,
+ unsigned int right_idx,
+ uint32_t seq);
#endif
diff -r 8c17eb6c28d6 -r cae78e734cdb src/lib-index/mail-index-transaction-update.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-index/mail-index-transaction-update.c Mon Jul 13 19:54:28 2009 -0400
@@ -0,0 +1,1013 @@
+/* Copyright (c) 2003-2009 Dovecot authors, see the included COPYING file */
+
+/* Inside transaction we keep messages stored in sequences in uid fields.
+ Before they're written to transaction log the sequences are changed to
+ UIDs. */
+
+#include "lib.h"
+#include "ioloop.h"
+#include "array.h"
+#include "mail-index-private.h"
+#include "mail-index-transaction-private.h"
+
+static bool
+mail_index_transaction_has_ext_changes(struct mail_index_transaction *t);
+
+struct mail_index_record *
+mail_index_transaction_lookup(struct mail_index_transaction *t, uint32_t seq)
+{
+ i_assert(seq >= t->first_new_seq && seq <= t->last_new_seq);
+
+ return array_idx_modifiable(&t->appends, seq - t->first_new_seq);
+}
+
+void mail_index_transaction_reset_v(struct mail_index_transaction *t)
+{
+ ARRAY_TYPE(seq_array) *recs;
+ struct mail_index_transaction_ext_hdr_update *ext_hdrs;
+ unsigned i, count;
+
+ if (array_is_created(&t->ext_rec_updates)) {
+ recs = array_get_modifiable(&t->ext_rec_updates, &count);
+ for (i = 0; i < count; i++) {
+ if (array_is_created(&recs[i]))
+ array_free(&recs[i]);
+ }
+ array_free(&t->ext_rec_updates);
+ }
+ if (array_is_created(&t->ext_rec_atomics)) {
+ recs = array_get_modifiable(&t->ext_rec_atomics, &count);
+ for (i = 0; i < count; i++) {
+ if (array_is_created(&recs[i]))
+ array_free(&recs[i]);
+ }
+ array_free(&t->ext_rec_atomics);
+ }
+ if (array_is_created(&t->ext_hdr_updates)) {
+ ext_hdrs = array_get_modifiable(&t->ext_hdr_updates, &count);
+ for (i = 0; i < count; i++) {
+ i_free(ext_hdrs[i].data);
+ i_free(ext_hdrs[i].mask);
+ }
+ array_free(&t->ext_hdr_updates);
+ }
+
+ if (array_is_created(&t->keyword_updates)) {
+ struct mail_index_transaction_keyword_update *u;
+
+ u = array_get_modifiable(&t->keyword_updates, &count);
+ for (i = 0; i < count; i++) {
+ if (array_is_created(&u[i].add_seq))
+ array_free(&u[i].add_seq);
+ if (array_is_created(&u[i].remove_seq))
+ array_free(&u[i].remove_seq);
+ }
+ array_free(&t->keyword_updates);
+ }
+ if (array_is_created(&t->keyword_resets))
+ array_free(&t->keyword_resets);
+
+ if (array_is_created(&t->appends))
+ array_free(&t->appends);
+ if (array_is_created(&t->expunges))
+ array_free(&t->expunges);
+ if (array_is_created(&t->updates))
+ array_free(&t->updates);
+ if (array_is_created(&t->ext_resizes))
+ array_free(&t->ext_resizes);
+ if (array_is_created(&t->ext_resets))
+ array_free(&t->ext_resets);
+ if (array_is_created(&t->ext_reset_ids))
+ array_free(&t->ext_reset_ids);
+ if (array_is_created(&t->ext_reset_atomic))
+ array_free(&t->ext_reset_atomic);
+
+ t->first_new_seq = mail_index_view_get_messages_count(t->view)+1;
+ t->last_new_seq = 0;
+ t->last_update_idx = 0;
+ t->min_flagupdate_seq = 0;
+ t->max_flagupdate_seq = 0;
+
+ memset(t->pre_hdr_mask, 0, sizeof(t->pre_hdr_mask));
+ memset(t->post_hdr_mask, 0, sizeof(t->post_hdr_mask));
+
+ t->appends_nonsorted = FALSE;
+ t->drop_unnecessary_flag_updates = FALSE;
+ t->pre_hdr_changed = FALSE;
+ t->post_hdr_changed = FALSE;
+ t->reset = FALSE;
+ t->log_updates = FALSE;
+ t->log_ext_updates = FALSE;
+}
+
+void mail_index_transaction_set_log_updates(struct mail_index_transaction *t)
+{
+ /* flag updates aren't included in log_updates */
+ t->log_updates = array_is_created(&t->appends) ||
+ array_is_created(&t->expunges) ||
+ array_is_created(&t->keyword_resets) ||
+ array_is_created(&t->keyword_updates) ||
+ t->pre_hdr_changed || t->post_hdr_changed;
+}
+
+void mail_index_update_day_headers(struct mail_index_transaction *t)
+{
+ struct mail_index_header hdr;
+ const struct mail_index_record *rec;
+ const int max_days = N_ELEMENTS(hdr.day_first_uid);
+ struct tm tm;
+ time_t stamp;
+ int i, days;
+
+ hdr = *mail_index_get_header(t->view);
+ rec = array_idx(&t->appends, 0);
+
+ /* get beginning of today */
+ tm = *localtime(&ioloop_time);
+ tm.tm_hour = 0;
+ tm.tm_min = 0;
+ tm.tm_sec = 0;
+ stamp = mktime(&tm);
+ i_assert(stamp != (time_t)-1);
+
+ if ((time_t)hdr.day_stamp >= stamp)
+ return;
+
+ /* get number of days since last message */
+ days = (stamp - hdr.day_stamp) / (3600*24);
+ if (days > max_days)
+ days = max_days;
+
+ /* @UNSAFE: move days forward and fill the missing days with old
+ day_first_uid[0]. */
+ memmove(hdr.day_first_uid + days, hdr.day_first_uid, max_days - days);
+ for (i = 1; i < days; i++)
+ hdr.day_first_uid[i] = hdr.day_first_uid[0];
+
+ hdr.day_stamp = stamp;
+ hdr.day_first_uid[0] = rec->uid;
+
+ mail_index_update_header(t,
+ offsetof(struct mail_index_header, day_stamp),
+ &hdr.day_stamp, sizeof(hdr.day_stamp), FALSE);
+ mail_index_update_header(t,
+ offsetof(struct mail_index_header, day_first_uid),
+ hdr.day_first_uid, sizeof(hdr.day_first_uid), FALSE);
+}
+
+void mail_index_append(struct mail_index_transaction *t, uint32_t uid,
+ uint32_t *seq_r)
+{
+ struct mail_index_record *rec;
+
+ i_assert(!t->no_appends);
+
+ t->log_updates = TRUE;
+
+ if (!array_is_created(&t->appends))
+ i_array_init(&t->appends, 32);
+
+ /* sequence number is visible only inside given view,
+ so let it generate it */
+ if (t->last_new_seq != 0)
+ *seq_r = ++t->last_new_seq;
+ else
+ *seq_r = t->last_new_seq = t->first_new_seq;
+
+ rec = array_append_space(&t->appends);
+ if (uid != 0) {
+ rec->uid = uid;
+ if (!t->appends_nonsorted &&
+ t->last_new_seq != t->first_new_seq) {
+ /* if previous record's UID is larger than this one,
+ we'll have to sort the appends later */
+ rec = mail_index_transaction_lookup(t, *seq_r - 1);
+ if (rec->uid > uid)
+ t->appends_nonsorted = TRUE;
+ else if (rec->uid == uid)
+ i_panic("Duplicate UIDs added in transaction");
+ }
+ if (t->highest_append_uid < uid)
+ t->highest_append_uid = uid;
+ }
+}
+
+void mail_index_append_assign_uids(struct mail_index_transaction *t,
+ uint32_t first_uid, uint32_t *next_uid_r)
+{
+ struct mail_index_record *recs;
+ unsigned int i, count;
+
+ if (!array_is_created(&t->appends))
+ return;
+
+ i_assert(first_uid > t->highest_append_uid);
+
+ recs = array_get_modifiable(&t->appends, &count);
+ for (i = 0; i < count; i++) {
+ if (recs[i].uid == 0)
+ recs[i].uid = first_uid++;
+ }
+
+ *next_uid_r = first_uid;
+}
+
+static void
+mail_index_expunge_last_append_ext(ARRAY_TYPE(seq_array_array) *ext_updates,
+ uint32_t seq)
+{
+ ARRAY_TYPE(seq_array) *seqs;
+ unsigned int i, count, idx;
+
+ if (!array_is_created(ext_updates))
+ return;
+
More information about the dovecot-cvs
mailing list