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