Mercurial > dovecot > core-2.2
changeset 15698:798a335d99b0
dsync: When we know that remote does a flag update, try to guess the remote's new modseq and set it
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 31 Jan 2013 19:05:55 +0200 |
parents | 86629f621fe4 |
children | 9b7d80a8db44 |
files | src/doveadm/dsync/dsync-mailbox-import.c |
diffstat | 1 files changed, 25 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/doveadm/dsync/dsync-mailbox-import.c Thu Jan 31 18:47:20 2013 +0200 +++ b/src/doveadm/dsync/dsync-mailbox-import.c Thu Jan 31 19:05:55 2013 +0200 @@ -482,7 +482,8 @@ merge_flags(uint32_t local_final, uint32_t local_add, uint32_t local_remove, uint32_t remote_final, uint32_t remote_add, uint32_t remote_remove, uint32_t pvt_mask, bool prefer_remote, bool prefer_pvt_remote, - uint32_t *change_add_r, uint32_t *change_remove_r) + uint32_t *change_add_r, uint32_t *change_remove_r, + bool *remote_changed) { uint32_t combined_add, combined_remove, conflict_flags; uint32_t local_wanted, remote_wanted, conflict_pvt_flags; @@ -538,6 +539,8 @@ *change_add_r = local_wanted & ~local_final; *change_remove_r = local_final & ~local_wanted; + if (local_wanted != remote_final) + *remote_changed = TRUE; } static bool @@ -576,7 +579,7 @@ static void merge_keywords(struct mail *mail, const ARRAY_TYPE(const_string) *local_changes, const ARRAY_TYPE(const_string) *remote_changes, - bool prefer_remote) + bool prefer_remote, bool *remote_changed) { /* local_changes and remote_changes are assumed to have no duplicates names */ @@ -681,7 +684,7 @@ merge_flags(local_final[i], local_add[i], local_remove[i], remote_final[i], remote_add[i], remote_remove[i], 0, prefer_remote, prefer_remote, - &change_add[i], &change_remove[i]); + &change_add[i], &change_remove[i], remote_changed); if (change_add[i] != 0) { keywords_append(&add_keywords, &all_keywords, change_add[i], i*32); @@ -757,9 +760,10 @@ const struct dsync_mail_change *local_change; enum mail_flags local_add, local_remove; uint32_t change_add, change_remove; + uint64_t new_modseq; ARRAY_TYPE(const_string) local_keyword_changes = ARRAY_INIT; struct mail *mail; - bool prefer_remote, prefer_pvt_remote; + bool prefer_remote, prefer_pvt_remote, remote_changed = FALSE; i_assert((change->add_flags & change->remove_flags) == 0); @@ -812,7 +816,7 @@ change->final_flags, change->add_flags, change->remove_flags, mailbox_get_private_flags_mask(mail->box), prefer_remote, prefer_pvt_remote, - &change_add, &change_remove); + &change_add, &change_remove, &remote_changed); if (change_add != 0) mail_update_flags(mail, MODIFY_ADD, change_add); @@ -821,11 +825,22 @@ /* merge keywords */ merge_keywords(mail, &local_keyword_changes, &change->keyword_changes, - prefer_remote); - if (mail_get_modseq(mail) < change->modseq) - mail_update_modseq(mail, change->modseq); - if (mail_get_pvt_modseq(mail) < change->pvt_modseq) - mail_update_pvt_modseq(mail, change->pvt_modseq); + prefer_remote, &remote_changed); + + /* update modseqs. try to anticipate when we have to increase modseq + to get it closer to what remote has (although we can't guess it + exactly correctly) */ + new_modseq = change->modseq; + if (remote_changed && new_modseq <= importer->remote_highest_modseq) + new_modseq = importer->remote_highest_modseq+1; + if (mail_get_modseq(mail) < new_modseq) + mail_update_modseq(mail, new_modseq); + + new_modseq = change->pvt_modseq; + if (remote_changed && new_modseq <= importer->remote_highest_pvt_modseq) + new_modseq = importer->remote_highest_pvt_modseq+1; + if (mail_get_pvt_modseq(mail) < new_modseq) + mail_update_pvt_modseq(mail, new_modseq); } static void