dovecot-2.0: Changed mail_index_append_assign_uids() to mail_ind...

dovecot at dovecot.org dovecot at dovecot.org
Tue Jul 28 02:04:46 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/fb8bc26d7194
changeset: 9684:fb8bc26d7194
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Jul 27 19:00:56 2009 -0400
description:
Changed mail_index_append_assign_uids() to mail_index_append_finish_uids() with API changes.
It's now possible to call mail_index_append() with UIDs before locking
mailbox and have the _finish_uids() change them if another session had
already used those UIDs.

diffstat:

8 files changed, 105 insertions(+), 69 deletions(-)
src/lib-index/mail-index-transaction-update.c      |   42 +++++++++++++++-----
src/lib-index/mail-index.h                         |   11 +++--
src/lib-index/test-mail-index-transaction-update.c |   26 ++++++++----
src/lib-storage/index/cydir/cydir-save.c           |   19 +++------
src/lib-storage/index/dbox/dbox-map.c              |   32 +++++++++------
src/lib-storage/index/dbox/dbox-map.h              |    2 
src/lib-storage/index/dbox/dbox-save.c             |   16 ++-----
src/lib-storage/index/maildir/maildir-save.c       |   26 ++++++------

diffs (truncated from 365 to 300 lines):

diff -r b56b06cdd1d7 -r fb8bc26d7194 src/lib-index/mail-index-transaction-update.c
--- a/src/lib-index/mail-index-transaction-update.c	Mon Jul 27 18:54:02 2009 -0400
+++ b/src/lib-index/mail-index-transaction-update.c	Mon Jul 27 19:00:56 2009 -0400
@@ -196,24 +196,46 @@ void mail_index_append(struct mail_index
 	}
 }
 
-void mail_index_append_assign_uids(struct mail_index_transaction *t,
-				   uint32_t first_uid, uint32_t *next_uid_r)
+void mail_index_append_finish_uids(struct mail_index_transaction *t,
+				   uint32_t first_uid,
+				   ARRAY_TYPE(seq_range) *uids_r)
 {
 	struct mail_index_record *recs;
 	unsigned int i, count;
-
+	struct seq_range *range;
+	uint32_t next_uid;
+	
 	if (!array_is_created(&t->appends))
 		return;
 
-	i_assert(first_uid > t->highest_append_uid);
-
+	/* first find the highest assigned uid */
 	recs = array_get_modifiable(&t->appends, &count);
+	i_assert(count > 0);
+
+	next_uid = first_uid;
 	for (i = 0; i < count; i++) {
-		if (recs[i].uid == 0)
-			recs[i].uid = first_uid++;
-	}
-
-	*next_uid_r = first_uid;
+		if (next_uid <= recs[i].uid)
+			next_uid = recs[i].uid + 1;
+	}
+
+	/* assign missing uids */
+	for (i = 0; i < count; i++) {
+		if (recs[i].uid == 0 || recs[i].uid < first_uid)
+			recs[i].uid = next_uid++;
+	}
+
+	/* write the saved uids range */
+	array_clear(uids_r);
+	range = array_append_space(uids_r);
+	range->seq1 = range->seq2 = recs[0].uid;
+	for (i = 1; i < count; i++) {
+		if (range->seq2 + 1 == recs[i].uid)
+			range->seq2++;
+		else {
+			range = array_append_space(uids_r);
+			range->seq1 = range->seq2 = recs[i].uid;
+		}
+	}
 }
 
 void mail_index_update_uid(struct mail_index_transaction *t, uint32_t seq,
diff -r b56b06cdd1d7 -r fb8bc26d7194 src/lib-index/mail-index.h
--- a/src/lib-index/mail-index.h	Mon Jul 27 18:54:02 2009 -0400
+++ b/src/lib-index/mail-index.h	Mon Jul 27 19:00:56 2009 -0400
@@ -396,10 +396,13 @@ void mail_index_lookup_first(struct mail
 /* Append a new record to index. */
 void mail_index_append(struct mail_index_transaction *t, uint32_t uid,
 		       uint32_t *seq_r);
-/* Assigns UIDs for appended mails all at once. UID must have been given as 0
-   for mail_index_append(). Returns the next unused UID. */
-void mail_index_append_assign_uids(struct mail_index_transaction *t,
-				   uint32_t first_uid, uint32_t *next_uid_r);
+/* Assign UIDs for mails with uid=0 or uid<first_uid. Assumes that mailbox is
+   locked in a way that UIDs can be safely assigned. Returns UIDs for all
+   asigned messages, in their sequence order (so UIDs are not necessary
+   ascending). */
+void mail_index_append_finish_uids(struct mail_index_transaction *t,
+				   uint32_t first_uid,
+				   ARRAY_TYPE(seq_range) *uids_r);
 /* Update message's UID. The new UID must not be lower than next_uid at the
    commit time, otherwise the UID update fails and is just ignored.
    If there are appends in the same transaction, the updated UIDs must be
diff -r b56b06cdd1d7 -r fb8bc26d7194 src/lib-index/test-mail-index-transaction-update.c
--- a/src/lib-index/test-mail-index-transaction-update.c	Mon Jul 27 18:54:02 2009 -0400
+++ b/src/lib-index/test-mail-index-transaction-update.c	Mon Jul 27 19:00:56 2009 -0400
@@ -57,8 +57,10 @@ static void test_mail_index_append(void)
 {
 	struct mail_index_transaction *t;
 	const struct mail_index_record *appends;
-	unsigned int count;
-	uint32_t seq, next_uid;
+	ARRAY_TYPE(seq_range) saved_uids_arr;
+	const struct seq_range *saved_uids;
+	unsigned int count;
+	uint32_t seq;
 
 	hdr.messages_count = 4;
 	t = mail_index_transaction_new();
@@ -71,8 +73,11 @@ static void test_mail_index_append(void)
 	test_assert(seq == 6);
 	test_assert(!t->appends_nonsorted);
 
-	mail_index_append_assign_uids(t, 123, &next_uid);
-	test_assert(next_uid == 125);
+	t_array_init(&saved_uids_arr, 128);
+	mail_index_append_finish_uids(t, 123, &saved_uids_arr);
+	saved_uids = array_get(&saved_uids_arr, &count);
+	test_assert(count == 1);
+	test_assert(saved_uids[0].seq1 == 123 && saved_uids[0].seq2 == 124);
 
 	appends = array_get(&t->appends, &count);
 	test_assert(appends[0].uid == 123);
@@ -99,15 +104,20 @@ static void test_mail_index_append(void)
 	test_assert(seq == 9);
 	test_assert(t->highest_append_uid == 128);
 
-	mail_index_append_assign_uids(t, 129, &next_uid);
-	test_assert(next_uid == 131);
+	mail_index_append_finish_uids(t, 125, &saved_uids_arr);
+	saved_uids = array_get(&saved_uids_arr, &count);
+	test_assert(count == 4);
+	test_assert(saved_uids[0].seq1 == 129 && saved_uids[0].seq2 == 129);
+	test_assert(saved_uids[1].seq1 == 126 && saved_uids[1].seq2 == 126);
+	test_assert(saved_uids[2].seq1 == 130 && saved_uids[2].seq2 == 131);
+	test_assert(saved_uids[3].seq1 == 128 && saved_uids[3].seq2 == 128);
 
 	appends = array_get(&t->appends, &count);
 	test_assert(count == 5);
 	test_assert(appends[0].uid == 129);
 	test_assert(appends[1].uid == 126);
-	test_assert(appends[2].uid == 124);
-	test_assert(appends[3].uid == 130);
+	test_assert(appends[2].uid == 130);
+	test_assert(appends[3].uid == 131);
 	test_assert(appends[4].uid == 128);
 	test_end();
 }
diff -r b56b06cdd1d7 -r fb8bc26d7194 src/lib-storage/index/cydir/cydir-save.c
--- a/src/lib-storage/index/cydir/cydir-save.c	Mon Jul 27 18:54:02 2009 -0400
+++ b/src/lib-storage/index/cydir/cydir-save.c	Mon Jul 27 19:00:56 2009 -0400
@@ -232,11 +232,11 @@ int cydir_transaction_save_commit_pre(st
 {
 	struct mailbox_transaction_context *_t = ctx->ctx.transaction;
 	const struct mail_index_header *hdr;
-	struct seq_range *range;
-	uint32_t i, uid, next_uid;
+	struct seq_range_iter iter;
+	uint32_t uid;
 	const char *dir;
 	string_t *src_path, *dest_path;
-	unsigned int src_prefixlen, dest_prefixlen;
+	unsigned int n, src_prefixlen, dest_prefixlen;
 
 	i_assert(ctx->finished);
 
@@ -247,13 +247,9 @@ int cydir_transaction_save_commit_pre(st
 	}
 
 	hdr = mail_index_get_header(ctx->sync_ctx->sync_view);
-	uid = hdr->next_uid;
-	mail_index_append_assign_uids(ctx->trans, uid, &next_uid);
-
+	mail_index_append_finish_uids(ctx->trans, hdr->next_uid,
+				      &_t->changes->saved_uids);
 	_t->changes->uid_validity = ctx->sync_ctx->uid_validity;
-	range = array_append_space(&_t->changes->saved_uids);
-	range->seq1 = uid;
-	range->seq2 = next_uid - 1;
 
 	dir = mailbox_list_get_path(ctx->mbox->ibox.box.list,
 				    ctx->mbox->ibox.box.name,
@@ -268,10 +264,11 @@ int cydir_transaction_save_commit_pre(st
 	str_append_c(dest_path, '/');
 	dest_prefixlen = str_len(dest_path);
 
-	for (i = 0; i < ctx->mail_count; i++, uid++) {
+	seq_range_array_iter_init(&iter, &_t->changes->saved_uids); n = 0;
+	while (seq_range_array_iter_nth(&iter, n++, &uid) > 0) {
 		str_truncate(src_path, src_prefixlen);
 		str_truncate(dest_path, dest_prefixlen);
-		str_printfa(src_path, "%u", i);
+		str_printfa(src_path, "%u", n-1);
 		str_printfa(dest_path, "%u.", uid);
 
 		if (rename(str_c(src_path), str_c(dest_path)) < 0) {
diff -r b56b06cdd1d7 -r fb8bc26d7194 src/lib-storage/index/dbox/dbox-map.c
--- a/src/lib-storage/index/dbox/dbox-map.c	Mon Jul 27 18:54:02 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-map.c	Mon Jul 27 19:00:56 2009 -0400
@@ -964,7 +964,9 @@ int dbox_map_append_assign_map_uids(stru
 	const struct mail_index_header *hdr;
 	struct dbox_mail_index_map_record rec;
 	unsigned int i, count;
-	uint32_t seq, first_uid, next_uid;
+	ARRAY_TYPE(seq_range) uids;
+	const struct seq_range *range;
+	uint32_t seq;
 	uint16_t ref16;
 	int ret = 0;
 
@@ -998,9 +1000,10 @@ int dbox_map_append_assign_map_uids(stru
 
 	/* assign map UIDs for appended records */
 	hdr = mail_index_get_header(ctx->sync_view);
-	first_uid = hdr->next_uid;
-	mail_index_append_assign_uids(ctx->trans, first_uid, &next_uid);
-	i_assert(next_uid - first_uid == count);
+	t_array_init(&uids, 1);
+	mail_index_append_finish_uids(ctx->trans, hdr->next_uid, &uids);
+	range = array_idx(&uids, 0);
+	i_assert(range[0].seq2 - range[0].seq1 + 1 == count);
 
 	if (hdr->uid_validity == 0) {
 		/* we don't really care about uidvalidity, but it can't be 0 */
@@ -1016,8 +1019,8 @@ int dbox_map_append_assign_map_uids(stru
 		return -1;
 	}
 
-	*first_map_uid_r = first_uid;
-	*last_map_uid_r = next_uid - 1;
+	*first_map_uid_r = range[0].seq1;
+	*last_map_uid_r = range[0].seq2;
 	return ret;
 }
 
@@ -1062,21 +1065,26 @@ int dbox_map_append_move(struct dbox_map
 }
 
 int dbox_map_append_assign_uids(struct dbox_map_append_context *ctx,
-				uint32_t first_uid, uint32_t last_uid)
+				const ARRAY_TYPE(seq_range) *uids)
 {
 	struct dbox_file *const *files;
-	unsigned int i, count;
-	uint32_t next_uid = first_uid;
-
+	struct seq_range_iter iter;
+	unsigned int i, count, n = 0;
+	uint32_t uid;
+	bool ret;
+
+	seq_range_array_iter_init(&iter, uids);
 	files = array_get(&ctx->files, &count);
 	for (i = 0; i < count; i++) {
 		if (files[i]->single_mbox == NULL)
 			continue;
 
-		if (dbox_file_assign_id(files[i], next_uid++) < 0)
+		ret = seq_range_array_iter_nth(&iter, n++, &uid);
+		i_assert(ret);
+		if (dbox_file_assign_id(files[i], uid) < 0)
 			return -1;
 	}
-	i_assert(next_uid == last_uid + 1);
+	i_assert(!seq_range_array_iter_nth(&iter, n, &uid));
 	return 0;
 }
 
diff -r b56b06cdd1d7 -r fb8bc26d7194 src/lib-storage/index/dbox/dbox-map.h
--- a/src/lib-storage/index/dbox/dbox-map.h	Mon Jul 27 18:54:02 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-map.h	Mon Jul 27 19:00:56 2009 -0400
@@ -77,7 +77,7 @@ int dbox_map_append_assign_map_uids(stru
 				    uint32_t *last_map_uid_r);
 /* Assign UIDs to all created single-files. */
 int dbox_map_append_assign_uids(struct dbox_map_append_context *ctx,
-				uint32_t first_uid, uint32_t last_uid);
+				const ARRAY_TYPE(seq_range) *uids);
 /* The appends are existing messages that were simply moved to a new file.
    map_uids contains the moved messages' map UIDs. */
 int dbox_map_append_move(struct dbox_map_append_context *ctx,
diff -r b56b06cdd1d7 -r fb8bc26d7194 src/lib-storage/index/dbox/dbox-save.c
--- a/src/lib-storage/index/dbox/dbox-save.c	Mon Jul 27 18:54:02 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-save.c	Mon Jul 27 19:00:56 2009 -0400
@@ -310,8 +310,7 @@ int dbox_transaction_save_commit_pre(str
 {
 	struct mailbox_transaction_context *_t = ctx->ctx.transaction;
 	const struct mail_index_header *hdr;
-	struct seq_range *range;
-	uint32_t uid, first_map_uid, last_map_uid, next_uid;
+	uint32_t first_map_uid, last_map_uid;
 
 	i_assert(ctx->finished);
 
@@ -334,15 +333,13 @@ int dbox_transaction_save_commit_pre(str
 
 	/* assign UIDs for new messages */
 	hdr = mail_index_get_header(ctx->sync_ctx->sync_view);
-	uid = hdr->next_uid;
-	mail_index_append_assign_uids(ctx->trans, uid, &next_uid);
+	mail_index_append_finish_uids(ctx->trans, hdr->next_uid,
+				      &_t->changes->saved_uids);
 
 	/* if we saved any single-files, rename the files to contain UIDs */
 	if (ctx->single_count > 0) {
-		uint32_t last_uid = uid + ctx->single_count - 1;
-
-		if (dbox_map_append_assign_uids(ctx->append_ctx, uid,
-						last_uid) < 0) {
+		if (dbox_map_append_assign_uids(ctx->append_ctx,
+						&_t->changes->saved_uids) < 0) {
 			dbox_transaction_save_rollback(ctx);
 			return -1;


More information about the dovecot-cvs mailing list