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