Mercurial > dovecot > core-2.2
changeset 9639:ffda7bd92ebc HEAD
dsync: Skip syncing mailboxes whose uidvalidity/uidnext/highest-modseq hasn't changed.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 16 Jul 2009 18:12:30 -0400 |
parents | b11a3eda2477 |
children | ac52d79b7b94 |
files | src/dsync/dsync-brain.c src/dsync/dsync-data.h src/dsync/test-dsync-brain.c |
diffstat | 3 files changed, 68 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/src/dsync/dsync-brain.c Wed Jul 15 18:31:59 2009 -0400 +++ b/src/dsync/dsync-brain.c Thu Jul 16 18:12:30 2009 -0400 @@ -409,20 +409,55 @@ return iter; } +static bool dsync_mailbox_has_changed_msgs(const struct dsync_mailbox *box1, + const struct dsync_mailbox *box2) +{ + return box1->uid_validity != box2->uid_validity || + box1->uid_next != box2->uid_next || + box1->highest_modseq != box2->highest_modseq; +} + +static void +dsync_brain_get_changed_mailboxes(struct dsync_brain *brain, + ARRAY_TYPE(mailbox_guid) *guids) +{ + struct dsync_mailbox *const *src_boxes, *const *dest_boxes; + unsigned int src, dest, src_count, dest_count; + int ret; + + src_boxes = array_get(&brain->src_mailbox_list->mailboxes, &src_count); + dest_boxes = array_get(&brain->dest_mailbox_list->mailboxes, &dest_count); + + for (src = dest = 0; src < src_count && dest < dest_count; ) { + ret = dsync_mailbox_guid_cmp(src_boxes[src], dest_boxes[dest]); + if (ret == 0) { + if (dsync_mailbox_has_changed_msgs(src_boxes[src], + dest_boxes[dest])) + array_append(guids, &src_boxes[src]->guid, 1); + src++; dest++; + } else if (ret < 0) { + /* exists only in source */ + array_append(guids, &src_boxes[src]->guid, 1); + src++; + } else { + /* exists only in dest */ + dest++; + } + } + for (; src < src_count; src++) + array_append(guids, &src_boxes[src]->guid, 1); +} + static struct dsync_brain_mailbox_sync * dsync_brain_msg_sync_init(struct dsync_brain *brain) { struct dsync_brain_mailbox_sync *sync; - ARRAY_DEFINE(guids, mailbox_guid_t); - struct dsync_mailbox *const *mailboxes; - unsigned int i, count; + ARRAY_TYPE(mailbox_guid) guids; + unsigned int count; pool_t pool; - /* initialize message iteration on both workers */ - mailboxes = array_get(&brain->src_mailbox_list->mailboxes, &count); - t_array_init(&guids, count); - for (i = 0; i < count; i++) - array_append(&guids, &mailboxes[i]->guid, 1); + t_array_init(&guids, array_count(&brain->src_mailbox_list->mailboxes)); + dsync_brain_get_changed_mailboxes(brain, &guids); pool = pool_alloconly_create("dsync brain mailbox sync", 1024*256); sync = p_new(pool, struct dsync_brain_mailbox_sync, 1); @@ -432,6 +467,9 @@ i_array_init(&sync->uid_conflicts, 128); i_array_init(&sync->new_msgs, 128); i_array_init(&sync->copy_retry_indexes, 32); + + /* initialize message iteration on both workers */ + count = array_count(&guids); sync->src_msg_iter = dsync_brain_msg_iter_init(sync, brain->src_worker, array_idx(&guids, 0), count);
--- a/src/dsync/dsync-data.h Wed Jul 15 18:31:59 2009 -0400 +++ b/src/dsync/dsync-data.h Thu Jul 16 18:12:30 2009 -0400 @@ -6,6 +6,7 @@ typedef struct { uint8_t guid[MAILBOX_GUID_SIZE]; } mailbox_guid_t; +ARRAY_DEFINE_TYPE(mailbox_guid, mailbox_guid_t); struct dsync_mailbox { const char *name;
--- a/src/dsync/test-dsync-brain.c Wed Jul 15 18:31:59 2009 -0400 +++ b/src/dsync/test-dsync-brain.c Thu Jul 16 18:12:30 2009 -0400 @@ -14,6 +14,7 @@ enum { FLAG_EXISTS = 0x01, FLAG_CREATED = 0x02, + FLAG_UNCHANGED = 0x04 }; struct test_dsync_mailbox { @@ -72,6 +73,10 @@ box3_dest_msgs, FLAG_EXISTS }, { { "dir1", { { 0, } }, 0, 0, 0 }, NULL, NULL, FLAG_EXISTS }, { { "dir2", { { 0, } }, 0, 0, 0 }, NULL, NULL, 0 }, + { { "box4", { { 0x46, 0x2d, 0xa3, 0x24, 0x2e, 0x5e, 0x28, 0x67, + 0xa6, 0xc7, 0xca, 0x8a, 0xe7, 0x36, 0xd4, 0xa4 } }, + 2142, 445, 53535 }, box3_src_msgs, + box3_dest_msgs, FLAG_EXISTS | FLAG_UNCHANGED }, { { NULL, { { 0, } }, 0, 0, 0 }, NULL, NULL, 0 } }; @@ -121,6 +126,8 @@ msgs = dest ? mailboxes[i].dest_msgs : mailboxes[i].src_msgs; if (msgs == NULL) continue; + if ((mailboxes[i].dest_flags & FLAG_UNCHANGED) != 0) + continue; for (j = 0; msgs[j].guid != NULL; j++) { test_msg.msg = msgs[j]; @@ -309,8 +316,10 @@ events = array_get(&msg_events, &event_count); events_end = events + event_count; - for (i = 0; mailboxes[i].box.name != NULL; i++) - test_dsync_brain_verify_mailbox(&mailboxes[i], &events); + for (i = 0; mailboxes[i].box.name != NULL; i++) { + if ((mailboxes[i].dest_flags & FLAG_UNCHANGED) == 0) + test_dsync_brain_verify_mailbox(&mailboxes[i], &events); + } test_assert(events == events_end); } @@ -323,7 +332,7 @@ struct test_dsync_worker *src_test_worker, *dest_test_worker; struct dsync_mailbox new_box; struct test_dsync_box_event box_event; - unsigned int i, box_count; + unsigned int i, j, box_count; box_count = 0; while (test_mailboxes[box_count].box.name != NULL) @@ -345,7 +354,9 @@ src_test_worker->box_iter.next_box = &mailboxes[i].box; src_worker->input_callback(src_worker->input_context); - if (mailboxes[i].dest_flags & FLAG_EXISTS) { + if ((mailboxes[i].dest_flags & FLAG_EXISTS) != 0) { + if ((mailboxes[i].dest_flags & FLAG_UNCHANGED) == 0) + mailboxes[i].box.highest_modseq++; dest_test_worker->box_iter.next_box = &mailboxes[i].box; dest_worker->input_callback(dest_worker->input_context); } @@ -374,11 +385,14 @@ test_dsync_mailbox_cmp); /* start syncing messages */ - test_assert(dest_test_worker->msg_iter_mailbox_count == box_count); - for (i = 0; mailboxes[i].box.name != NULL; i++) { - test_assert(memcmp(&dest_test_worker->msg_iter_mailboxes[i], + for (i = j = 0; mailboxes[i].box.name != NULL; i++) { + if ((mailboxes[i].dest_flags & FLAG_UNCHANGED) != 0) + continue; + test_assert(memcmp(&dest_test_worker->msg_iter_mailboxes[j], mailboxes[i].box.guid.guid, MAILBOX_GUID_SIZE) == 0); + j++; } + test_assert(dest_test_worker->msg_iter_mailbox_count == j); test_dsync_sync_msgs(src_test_worker, FALSE); test_dsync_sync_msgs(dest_test_worker, TRUE);