dovecot-2.0: lib-index: Fixes to handling UID changes.
dovecot at dovecot.org
dovecot at dovecot.org
Thu Aug 6 03:30:50 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/773b91d3ed13
changeset: 9724:773b91d3ed13
user: Timo Sirainen <tss at iki.fi>
date: Wed Aug 05 20:01:02 2009 -0400
description:
lib-index: Fixes to handling UID changes.
diffstat:
5 files changed, 67 insertions(+), 15 deletions(-)
src/lib-index/mail-index-sync-update.c | 4 -
src/lib-index/mail-index-transaction-export.c | 67 +++++++++++++++++++++----
src/lib-index/mail-index-transaction-update.c | 2
src/lib-index/mail-index-transaction.c | 8 +-
src/lib-index/mail-transaction-log-file.c | 1
diffs (149 lines):
diff -r 89a3b2d09a26 -r 773b91d3ed13 src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c Tue Aug 04 14:54:36 2009 -0400
+++ b/src/lib-index/mail-index-sync-update.c Wed Aug 05 20:01:02 2009 -0400
@@ -301,10 +301,10 @@ static void sync_uid_update(struct mail_
map->hdr.next_uid = new_uid+1;
map->rec_map->last_appended_uid = new_uid;
- rec = MAIL_INDEX_MAP_IDX(map, old_seq-1);
-
/* add the new record */
dest = sync_append_record(map);
+ rec = MAIL_INDEX_MAP_IDX(map, old_seq-1);
+ rec->uid = new_uid;
memcpy(dest, rec, map->hdr.record_size);
/* @UNSAFE: remove the old record */
diff -r 89a3b2d09a26 -r 773b91d3ed13 src/lib-index/mail-index-transaction-export.c
--- a/src/lib-index/mail-index-transaction-export.c Tue Aug 04 14:54:36 2009 -0400
+++ b/src/lib-index/mail-index-transaction-export.c Wed Aug 05 20:01:02 2009 -0400
@@ -327,6 +327,61 @@ log_append_keyword_updates(struct mail_i
return change_mask;
}
+static bool
+mail_index_transaction_export_new_uids(struct mail_index_export_context *ctx,
+ struct mail_index_transaction *t)
+{
+ const struct mail_index_record *appends;
+ const struct mail_transaction_uid_update *updates;
+ unsigned int a, u, append_count, update_count;
+
+ if (!array_is_created(&t->uid_updates)) {
+ /* fast path */
+ if (!array_is_created(&t->appends))
+ return FALSE;
+
+ log_append_buffer(ctx, t->appends.arr.buffer,
+ MAIL_TRANSACTION_APPEND);
+ return TRUE;
+ }
+ if (!array_is_created(&t->appends)) {
+ log_append_buffer(ctx, t->uid_updates.arr.buffer,
+ MAIL_TRANSACTION_UID_UPDATE);
+ return TRUE;
+ }
+
+ /* we'll need to merge so that UIDs are only being appended.
+ appends quite a lot of separate records unnecessarily,
+ but UID updates are rare.. */
+ appends = array_get(&t->appends, &append_count);
+ updates = array_get(&t->uid_updates, &update_count);
+
+ for (a = u = 0; a < append_count && u < update_count; ) {
+ if (appends[a].uid < updates[u].new_uid) {
+ mail_transaction_log_append_add(ctx->append_ctx,
+ MAIL_TRANSACTION_APPEND,
+ &appends[a], sizeof(appends[a]));
+ a++;
+ } else {
+ mail_transaction_log_append_add(ctx->append_ctx,
+ MAIL_TRANSACTION_UID_UPDATE,
+ &updates[u], sizeof(updates[u]));
+ u++;
+ }
+ }
+ if (a < append_count) {
+ mail_transaction_log_append_add(ctx->append_ctx,
+ MAIL_TRANSACTION_APPEND, &appends[a],
+ (append_count - a) * sizeof(appends[a]));
+ }
+ if (u < update_count) {
+ mail_transaction_log_append_add(ctx->append_ctx,
+ MAIL_TRANSACTION_UID_UPDATE, &updates[u],
+ (update_count - u) * sizeof(updates[u]));
+ }
+ return TRUE;
+}
+
void mail_index_transaction_export(struct mail_index_transaction *t,
struct mail_transaction_log_append_ctx *append_ctx)
{
@@ -345,11 +400,9 @@ void mail_index_transaction_export(struc
log_append_buffer(&ctx, log_get_hdr_update_buffer(t, TRUE),
MAIL_TRANSACTION_HEADER_UPDATE);
}
- if (array_is_created(&t->appends)) {
+ if (mail_index_transaction_export_new_uids(&ctx, t))
change_mask |= MAIL_INDEX_SYNC_TYPE_APPEND;
- log_append_buffer(&ctx, t->appends.arr.buffer,
- MAIL_TRANSACTION_APPEND);
- }
+
if (array_is_created(&t->updates)) {
change_mask |= MAIL_INDEX_SYNC_TYPE_FLAGS;
log_append_buffer(&ctx, t->updates.arr.buffer,
@@ -387,12 +440,6 @@ void mail_index_transaction_export(struc
log_append_buffer(&ctx, t->expunges.arr.buffer,
MAIL_TRANSACTION_EXPUNGE_GUID);
}
- /* keep uid updates last. if there are other updates to the message,
- they're referring to the old uid. */
- if (array_is_created(&t->uid_updates)) {
- log_append_buffer(&ctx, t->uid_updates.arr.buffer,
- MAIL_TRANSACTION_UID_UPDATE);
- }
if (t->post_hdr_changed) {
log_append_buffer(&ctx, log_get_hdr_update_buffer(t, FALSE),
diff -r 89a3b2d09a26 -r 773b91d3ed13 src/lib-index/mail-index-transaction-update.c
--- a/src/lib-index/mail-index-transaction-update.c Tue Aug 04 14:54:36 2009 -0400
+++ b/src/lib-index/mail-index-transaction-update.c Wed Aug 05 20:01:02 2009 -0400
@@ -252,6 +252,8 @@ void mail_index_update_uid(struct mail_i
u = array_append_space(&t->uid_updates);
u->old_uid = seq;
u->new_uid = new_uid;
+
+ t->log_updates = TRUE;
}
void mail_index_update_modseq(struct mail_index_transaction *t, uint32_t seq,
diff -r 89a3b2d09a26 -r 773b91d3ed13 src/lib-index/mail-index-transaction.c
--- a/src/lib-index/mail-index-transaction.c Tue Aug 04 14:54:36 2009 -0400
+++ b/src/lib-index/mail-index-transaction.c Wed Aug 05 20:01:02 2009 -0400
@@ -67,9 +67,11 @@ uint32_t mail_index_transaction_get_next
next_uid = t->reset || head_hdr->uid_validity != hdr->uid_validity ?
1 : hdr->next_uid;
if (array_is_created(&t->appends) && t->highest_append_uid != 0) {
- /* get next_uid from appends if they have UIDs */
- i_assert(next_uid <= t->highest_append_uid);
- next_uid = t->highest_append_uid + 1;
+ /* get next_uid from appends if they have UIDs. it's possible
+ that some appends have too low UIDs, they'll be caught
+ later. */
+ if (next_uid <= t->highest_append_uid)
+ next_uid = t->highest_append_uid + 1;
}
/* see if it's been updated in pre/post header changes */
diff -r 89a3b2d09a26 -r 773b91d3ed13 src/lib-index/mail-transaction-log-file.c
--- a/src/lib-index/mail-transaction-log-file.c Tue Aug 04 14:54:36 2009 -0400
+++ b/src/lib-index/mail-transaction-log-file.c Wed Aug 05 20:01:02 2009 -0400
@@ -808,6 +808,7 @@ void mail_transaction_update_modseq(cons
case MAIL_TRANSACTION_FLAG_UPDATE:
case MAIL_TRANSACTION_KEYWORD_UPDATE:
case MAIL_TRANSACTION_KEYWORD_RESET:
+ case MAIL_TRANSACTION_UID_UPDATE:
/* these changes increase modseq */
*cur_modseq += 1;
break;
More information about the dovecot-cvs
mailing list