dovecot-2.1: mailbox list indexes: Code cleanups.

dovecot at dovecot.org dovecot at dovecot.org
Sun Oct 2 18:04:45 EEST 2011


details:   http://hg.dovecot.org/dovecot-2.1/rev/6912969d94e8
changeset: 13590:6912969d94e8
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Oct 02 18:12:05 2011 +0300
description:
mailbox list indexes: Code cleanups.

diffstat:

 src/lib-storage/list/mailbox-list-index-sync.c |  68 ++++++++++++++-----------
 src/lib-storage/list/mailbox-list-index.c      |   6 +-
 src/lib-storage/list/mailbox-list-index.h      |   2 +-
 3 files changed, 43 insertions(+), 33 deletions(-)

diffs (253 lines):

diff -r 75679aca405a -r 6912969d94e8 src/lib-storage/list/mailbox-list-index-sync.c
--- a/src/lib-storage/list/mailbox-list-index-sync.c	Sun Oct 02 17:48:23 2011 +0300
+++ b/src/lib-storage/list/mailbox-list-index-sync.c	Sun Oct 02 18:12:05 2011 +0300
@@ -47,7 +47,7 @@
 	node = p_new(ctx->ilist->mailbox_pool,
 		     struct mailbox_list_index_node, 1);
 	node->flags = MAILBOX_LIST_INDEX_FLAG_NONEXISTENT |
-		MAILBOX_LIST_INDEX_FLAG_MARKED;
+		MAILBOX_LIST_INDEX_FLAG_SYNC_EXISTS;
 	/* we don't bother doing name deduplication here, even though it would
 	   be possible. */
 	node->name = dup_name = p_strdup(ctx->ilist->mailbox_pool, name);
@@ -82,28 +82,32 @@
 	uint32_t seq = 0;
 
 	path = t_strsplit(name, ctx->sep);
+	/* find the last node that exists in the path */
 	node = ctx->ilist->mailbox_tree; parent = NULL;
 	for (i = 0; path[i] != NULL; i++) {
 		node = mailbox_list_index_node_find_sibling(node, path[i]);
 		if (node == NULL)
 			break;
-		node->flags |= MAILBOX_LIST_INDEX_FLAG_MARKED;
+
+		node->flags |= MAILBOX_LIST_INDEX_FLAG_SYNC_EXISTS;
 		parent = node;
 		node = node->children;
 	}
 
 	node = parent;
 	if (path[i] == NULL) {
+		/* the entire path exists */
 		if (!mail_index_lookup_seq(ctx->view, node->uid, &seq))
 			i_panic("mailbox list index: lost uid=%u", node->uid);
 	} else {
+		/* create missing parts of the path */
 		for (; path[i] != NULL; i++) {
 			node = mailbox_list_index_node_add(ctx, node, path[i],
 							   &seq);
 		}
 	}
 
-	node->flags = flags | MAILBOX_LIST_INDEX_FLAG_MARKED;
+	node->flags = flags | MAILBOX_LIST_INDEX_FLAG_SYNC_EXISTS;
 	return seq;
 }
 
@@ -112,7 +116,7 @@
 		      const struct mailbox_list_index_node *node)
 {
 	for (; node != NULL; node = node->next) {
-		if ((node->flags & MAILBOX_LIST_INDEX_FLAG_MARKED) != 0) {
+		if ((node->flags & MAILBOX_LIST_INDEX_FLAG_SYNC_EXISTS) != 0) {
 			if (node->children != NULL)
 				get_existing_name_ids(ids, node->children);
 			array_append(ids, &node->name_id, 1);
@@ -131,64 +135,66 @@
 {
 	struct mailbox_list_index *ilist = ctx->ilist;
 	ARRAY_TYPE(uint32_t) existing_name_ids;
-	buffer_t *buf;
+	buffer_t *hdr_buf;
 	const void *ext_data;
 	size_t ext_size;
 	const char *name;
 	const uint32_t *id_p;
 	uint32_t prev_id = 0;
 
+	/* get all existing name IDs sorted */
 	t_array_init(&existing_name_ids, 64);
 	get_existing_name_ids(&existing_name_ids, ilist->mailbox_tree);
 	array_sort(&existing_name_ids, uint32_cmp);
 
-	buf = buffer_create_dynamic(pool_datastack_create(), 1024);
-	buffer_append_zero(buf, sizeof(struct mailbox_list_index_header));
+	hdr_buf = buffer_create_dynamic(pool_datastack_create(), 1024);
+	buffer_append_zero(hdr_buf, sizeof(struct mailbox_list_index_header));
 
+	/* add existing names to header (with deduplication) */
 	array_foreach(&existing_name_ids, id_p) {
 		if (*id_p != prev_id) {
-			buffer_append(buf, id_p, sizeof(*id_p));
+			buffer_append(hdr_buf, id_p, sizeof(*id_p));
 			name = hash_table_lookup(ilist->mailbox_names,
 						 POINTER_CAST(*id_p));
-			buffer_append(buf, name, strlen(name) + 1);
+			buffer_append(hdr_buf, name, strlen(name) + 1);
 			prev_id = *id_p;
 		}
 	}
-	buffer_append_zero(buf, sizeof(*id_p));
+	buffer_append_zero(hdr_buf, sizeof(*id_p));
 
+	/* make sure header size is ok in index and update it */
 	mail_index_get_header_ext(ctx->view, ilist->ext_id,
 				  &ext_data, &ext_size);
-	if (nearest_power(ext_size) != nearest_power(buf->used)) {
+	if (nearest_power(ext_size) != nearest_power(hdr_buf->used)) {
 		mail_index_ext_resize(ctx->trans, ilist->ext_id,
-				      nearest_power(buf->used),
+				      nearest_power(hdr_buf->used),
 				      sizeof(struct mailbox_list_index_record),
 				      sizeof(uint32_t));
 	}
 	mail_index_update_header_ext(ctx->trans, ilist->ext_id,
-				     0, buf->data, buf->used);
+				     0, hdr_buf->data, hdr_buf->used);
 }
 
 static void
-mailbox_list_index_node_unmark_recursive(struct mailbox_list_index_node *node)
+mailbox_list_index_node_clear_exists(struct mailbox_list_index_node *node)
 {
 	while (node != NULL) {
 		if (node->children != NULL)
-			mailbox_list_index_node_unmark_recursive(node->children);
+			mailbox_list_index_node_clear_exists(node->children);
 
-		node->flags &= ~MAILBOX_LIST_INDEX_FLAG_MARKED;
+		node->flags &= ~MAILBOX_LIST_INDEX_FLAG_SYNC_EXISTS;
 		node = node->next;
 	}
 }
 
 static void
-mailbox_list_index_node_unlink(struct mailbox_list_index_sync_context *sync_ctx,
+mailbox_list_index_node_unlink(struct mailbox_list_index *ilist,
 			       struct mailbox_list_index_node *node)
 {
 	struct mailbox_list_index_node **prev;
 
 	prev = node->parent == NULL ?
-		&sync_ctx->ilist->mailbox_tree :
-		&node->parent->children;
+		&ilist->mailbox_tree : &node->parent->children;
 
 	while (*prev != node)
 		prev = &(*prev)->next;
@@ -196,22 +202,20 @@
 }
 
 static void
-mailbox_list_index_nodes_expunge(struct mailbox_list_index_sync_context *sync_ctx,
-				 struct mailbox_list_index_node *node)
+sync_expunge_nonexistent(struct mailbox_list_index_sync_context *sync_ctx,
+			 struct mailbox_list_index_node *node)
 {
 	uint32_t seq;
 
 	while (node != NULL) {
-		if (node->children != NULL) {
-			mailbox_list_index_nodes_expunge(sync_ctx,
-							 node->children);
-		}
+		if (node->children != NULL)
+			sync_expunge_nonexistent(sync_ctx, node->children);
 
-		if ((node->flags & MAILBOX_LIST_INDEX_FLAG_MARKED) == 0) {
+		if ((node->flags & MAILBOX_LIST_INDEX_FLAG_SYNC_EXISTS) == 0) {
 			if (mail_index_lookup_seq(sync_ctx->view, node->uid,
 						  &seq))
 				mail_index_expunge(sync_ctx->trans, seq);
-			mailbox_list_index_node_unlink(sync_ctx, node);
+			mailbox_list_index_node_unlink(sync_ctx->ilist, node);
 		}
 		node = node->next;
 	}
@@ -239,6 +243,7 @@
 		mailbox_list_index_set_index_error(list);
 		return -1;
 	}
+	/* re-parse mailbox list now that it's refreshed and locked */
 	if (mailbox_list_index_parse(ilist, sync_ctx.view, TRUE) < 0) {
 		mail_index_sync_rollback(&sync_ctx.sync_ctx);
 		return -1;
@@ -249,6 +254,7 @@
 	sync_ctx.next_uid = hdr->next_uid;
 
 	if (hdr->uid_validity == 0) {
+		/* first time indexing, set uidvalidity */
 		uint32_t uid_validity = ioloop_time;
 
 		mail_index_update_header(sync_ctx.trans,
@@ -256,7 +262,8 @@
 			&uid_validity, sizeof(uid_validity), TRUE);
 	}
 
-	mailbox_list_index_node_unmark_recursive(ilist->mailbox_tree);
+	/* clear EXISTS-flags, so after sync we know what can be expunged */
+	mailbox_list_index_node_clear_exists(ilist->mailbox_tree);
 
 	patterns[0] = "*"; patterns[1] = NULL;
 	iter = ilist->module_ctx.super.iter_init(list, patterns, 0);
@@ -285,14 +292,15 @@
 		return -1;
 	}
 
-	mailbox_list_index_nodes_expunge(&sync_ctx, ilist->mailbox_tree);
+	sync_expunge_nonexistent(&sync_ctx, ilist->mailbox_tree);
 
 	if (orig_highest_name_id != ilist->highest_name_id) {
-		/* new names added */
+		/* new names added. this implicitly resets refresh flag */
 		T_BEGIN {
 			mailbox_list_index_sync_names(&sync_ctx);
 		} T_END;
 	} else {
+		/* we're synced, reset refresh flag */
 		struct mailbox_list_index_header new_hdr;
 
 		new_hdr.refresh_flag = 0;
diff -r 75679aca405a -r 6912969d94e8 src/lib-storage/list/mailbox-list-index.c
--- a/src/lib-storage/list/mailbox-list-index.c	Sun Oct 02 17:48:23 2011 +0300
+++ b/src/lib-storage/list/mailbox-list-index.c	Sun Oct 02 18:12:05 2011 +0300
@@ -19,6 +19,8 @@
 
 void mailbox_list_index_reset(struct mailbox_list_index *ilist)
 {
+	i_assert(ilist->iter_refcount == 0);
+
 	hash_table_clear(ilist->mailbox_names, FALSE);
 	hash_table_clear(ilist->mailbox_hash, FALSE);
 	p_clear(ilist->mailbox_pool);
@@ -49,8 +51,6 @@
 	unsigned int i;
 	char sep[2];
 
-	(void)mailbox_list_index_refresh(list);
-
 	sep[0] = mailbox_list_get_hierarchy_sep(list); sep[1] = '\0';
 	path = t_strsplit(name, sep);
 	node = ilist->mailbox_tree;
@@ -172,6 +172,8 @@
 	const struct mail_index_header *hdr;
 	int ret;
 
+	i_assert(ilist->iter_refcount == 0);
+
 	hdr = mail_index_get_header(view);
 	if (!force &&
 	    hdr->log_file_seq == ilist->sync_log_file_seq &&
diff -r 75679aca405a -r 6912969d94e8 src/lib-storage/list/mailbox-list-index.h
--- a/src/lib-storage/list/mailbox-list-index.h	Sun Oct 02 17:48:23 2011 +0300
+++ b/src/lib-storage/list/mailbox-list-index.h	Sun Oct 02 18:12:05 2011 +0300
@@ -19,7 +19,7 @@
 	MAILBOX_LIST_INDEX_FLAG_NOINFERIORS = MAIL_ANSWERED,
 
 	/* set during syncing for mailboxes that still exist */
-	MAILBOX_LIST_INDEX_FLAG_MARKED
+	MAILBOX_LIST_INDEX_FLAG_SYNC_EXISTS = MAIL_FLAGGED
 };
 
 struct mailbox_list_index_header {


More information about the dovecot-cvs mailing list