dovecot-2.0: dsync: Skip syncing mailboxes whose uidvalidity/uid...

dovecot at dovecot.org dovecot at dovecot.org
Fri Jul 17 01:12:37 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/ffda7bd92ebc
changeset: 9639:ffda7bd92ebc
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Jul 16 18:12:30 2009 -0400
description:
dsync: Skip syncing mailboxes whose uidvalidity/uidnext/highest-modseq hasn't changed.

diffstat:

3 files changed, 69 insertions(+), 16 deletions(-)
src/dsync/dsync-brain.c      |   54 +++++++++++++++++++++++++++++++++++-------
src/dsync/dsync-data.h       |    1 
src/dsync/test-dsync-brain.c |   30 +++++++++++++++++------

diffs (171 lines):

diff -r b11a3eda2477 -r ffda7bd92ebc src/dsync/dsync-brain.c
--- 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 @@ dsync_brain_msg_iter_init(struct dsync_b
 	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 @@ dsync_brain_msg_sync_init(struct dsync_b
 	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);
diff -r b11a3eda2477 -r ffda7bd92ebc src/dsync/dsync-data.h
--- 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 {
 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;
diff -r b11a3eda2477 -r ffda7bd92ebc src/dsync/test-dsync-brain.c
--- 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 {
 enum {
 	FLAG_EXISTS	= 0x01,
 	FLAG_CREATED	= 0x02,
+	FLAG_UNCHANGED	= 0x04
 };
 
 struct test_dsync_mailbox {
@@ -72,6 +73,10 @@ static struct test_dsync_mailbox basic_m
 	  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 }
 };
 
@@ -120,6 +125,8 @@ static void test_dsync_sync_msgs(struct 
 	for (i = 0; mailboxes[i].box.name != NULL; i++) {
 		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++) {
@@ -309,8 +316,10 @@ test_dsync_brain_verify_msg_events(struc
 
 	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 @@ test_dsync_brain_run(const struct test_d
 	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 @@ test_dsync_brain_run(const struct test_d
 		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_brain_run(const struct test_d
 	      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);
 


More information about the dovecot-cvs mailing list