dovecot: Locking and error handling fixes.

dovecot at dovecot.org dovecot at dovecot.org
Tue Dec 4 20:00:01 EET 2007


details:   http://hg.dovecot.org/dovecot/rev/97702c9c4111
changeset: 6931:97702c9c4111
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Dec 04 19:59:57 2007 +0200
description:
Locking and error handling fixes.

diffstat:

3 files changed, 469 insertions(+), 344 deletions(-)
src/plugins/fts-squat/squat-trie.c    |  238 ++++++++------
src/plugins/fts-squat/squat-uidlist.c |  559 ++++++++++++++++++---------------
src/plugins/fts-squat/squat-uidlist.h |   16 

diffs (truncated from 1504 to 300 lines):

diff -r 48ddc0c4036c -r 97702c9c4111 src/plugins/fts-squat/squat-trie.c
--- a/src/plugins/fts-squat/squat-trie.c	Tue Dec 04 15:20:01 2007 +0200
+++ b/src/plugins/fts-squat/squat-trie.c	Tue Dec 04 19:59:57 2007 +0200
@@ -29,6 +29,9 @@ struct squat_trie_build_context {
 struct squat_trie_build_context {
 	struct squat_trie *trie;
 	struct ostream *output;
+	struct squat_uidlist_build_context *uidlist_build_ctx;
+
+	struct file_lock *file_lock;
 
 	uint32_t first_uid;
 	unsigned int compress_nodes:1;
@@ -46,7 +49,7 @@ struct squat_trie_iterate_context {
 	bool failed;
 };
 
-static int squat_trie_map(struct squat_trie *trie);
+static int squat_trie_map(struct squat_trie *trie, bool building);
 
 void squat_trie_delete(struct squat_trie *trie)
 {
@@ -113,14 +116,6 @@ static void node_free(struct squat_trie 
 
 		i_free(node->children.data);
 	}
-}
-
-static void squat_trie_clear(struct squat_trie *trie)
-{
-	trie->corrupted = FALSE;
-	node_free(trie, &trie->root);
-	memset(&trie->root, 0, sizeof(trie->root));
-	memset(&trie->hdr, 0, sizeof(trie->hdr));
 }
 
 struct squat_trie *
@@ -139,19 +134,13 @@ squat_trie_init(const char *path, uint32
 	return trie;
 }
 
-void squat_trie_deinit(struct squat_trie **_trie)
-{
-	struct squat_trie *trie = *_trie;
-
-	*_trie = NULL;
-	squat_trie_clear(trie);
-	squat_uidlist_deinit(trie->uidlist);
-	i_free(trie->path);
-	i_free(trie);
-}
-
 static void squat_trie_close(struct squat_trie *trie)
 {
+	trie->corrupted = FALSE;
+	node_free(trie, &trie->root);
+	memset(&trie->root, 0, sizeof(trie->root));
+	memset(&trie->hdr, 0, sizeof(trie->hdr));
+
 	if (trie->mmap_size != 0) {
 		if (munmap(trie->mmap_base, trie->mmap_size) < 0)
 			i_error("munmap(%s) failed: %m", trie->path);
@@ -162,7 +151,17 @@ static void squat_trie_close(struct squa
 		trie->fd = -1;
 	}
 	trie->locked_file_size = 0;
-	squat_uidlist_close(trie->uidlist);
+}
+
+void squat_trie_deinit(struct squat_trie **_trie)
+{
+	struct squat_trie *trie = *_trie;
+
+	*_trie = NULL;
+	squat_trie_close(trie);
+	squat_uidlist_deinit(trie->uidlist);
+	i_free(trie->path);
+	i_free(trie);
 }
 
 static void squat_trie_header_init(struct squat_trie *trie)
@@ -197,14 +196,10 @@ static int squat_trie_open(struct squat_
 static int squat_trie_open(struct squat_trie *trie)
 {
 	squat_trie_close(trie);
-	squat_trie_clear(trie);
 
 	if (squat_trie_open_fd(trie) < 0)
 		return -1;
-	if (squat_trie_map(trie) < 0)
-		return -1;
-
-	return squat_uidlist_open(trie->uidlist);
+	return squat_trie_map(trie, FALSE);
 }
 
 static int squat_trie_is_file_stale(struct squat_trie *trie)
@@ -522,7 +517,8 @@ node_write_children(struct squat_trie_bu
 }
 
 static inline void
-node_add_uid(struct squat_trie *trie, uint32_t uid, struct squat_node *node)
+node_add_uid(struct squat_trie_build_context *ctx, uint32_t uid,
+	     struct squat_node *node)
 {
 	if (uid < node->next_uid) {
 		/* duplicate */
@@ -532,11 +528,12 @@ node_add_uid(struct squat_trie *trie, ui
 	node->next_uid = uid + 1;
 
 	node->uid_list_idx =
-		squat_uidlist_build_add_uid(trie->uidlist,
+		squat_uidlist_build_add_uid(ctx->uidlist_build_ctx,
 					    node->uid_list_idx, uid);
 }
 
-static void node_split_string(struct squat_trie *trie, struct squat_node *node)
+static void
+node_split_string(struct squat_trie_build_context *ctx, struct squat_node *node)
 {
 	struct squat_node *child;
 	unsigned char *str;
@@ -557,14 +554,14 @@ static void node_split_string(struct squ
 	node->leaf_string_length = 0;
 
 	/* create a new child node for the rest of the string */
-	idx = node_add_child(trie, node, str[0], MAX_FAST_LEVEL);
+	idx = node_add_child(ctx->trie, node, str[0], MAX_FAST_LEVEL);
 	child = NODE_CHILDREN_NODES(node) + idx;
 
 	/* update uidlist to contain all of parent's UIDs */
 	child->next_uid =  node->next_uid - node->unused_uids;
 	for (uid = 0; uid < child->next_uid; uid++) {
 		child->uid_list_idx =
-			squat_uidlist_build_add_uid(trie->uidlist,
+			squat_uidlist_build_add_uid(ctx->uidlist_build_ctx,
 						    child->uid_list_idx, uid);
 	}
 
@@ -585,7 +582,8 @@ static void node_split_string(struct squ
 }
 
 static bool
-node_leaf_string_add_or_split(struct squat_trie *trie, struct squat_node *node,
+node_leaf_string_add_or_split(struct squat_trie_build_context *ctx,
+			      struct squat_node *node,
 			      const unsigned char *data, unsigned int data_len)
 {
 	const unsigned char *str = NODE_LEAF_STRING(node);
@@ -594,23 +592,24 @@ node_leaf_string_add_or_split(struct squ
 
 	if (data_len != str_len) {
 		/* different lengths, can't match */
-		node_split_string(trie, node);
+		node_split_string(ctx, node);
 		return FALSE;
 	}
 
 	for (i = 0; i < data_len; i++) {
 		if (data[i] != str[i]) {
 			/* non-match */
-			node_split_string(trie, node);
+			node_split_string(ctx, node);
 			return FALSE;
 		}
 	}
 	return TRUE;
 }
 
-static int squat_build_add(struct squat_trie *trie, uint32_t uid,
+static int squat_build_add(struct squat_trie_build_context *ctx, uint32_t uid,
 			   const unsigned char *data, unsigned int size)
 {
+	struct squat_trie *trie = ctx->trie;
 	struct squat_node *node = &trie->root;
 	const unsigned char *end = data + size;
 	unsigned char *chars;
@@ -626,14 +625,14 @@ static int squat_build_add(struct squat_
 		if (node->leaf_string_length != 0) {
 			/* the whole string must match or we need to split
 			   the node */
-			if (node_leaf_string_add_or_split(trie, node, data,
+			if (node_leaf_string_add_or_split(ctx, node, data,
 							  end - data)) {
-				node_add_uid(trie, uid, node);
+				node_add_uid(ctx, uid, node);
 				return 0;
 			}
 		}
 
-		node_add_uid(trie, uid, node);
+		node_add_uid(ctx, uid, node);
 
 		if (unlikely(uid < node->unused_uids)) {
 			squat_trie_set_corrupted(trie);
@@ -677,7 +676,7 @@ static int squat_build_add(struct squat_
 				     size - (end - data) + 1);
 		node = NODE_CHILDREN_NODES(node) + idx;
 
-		node_add_uid(trie, uid, node);
+		node_add_uid(ctx, uid, node);
 		uid = 0;
 
 		if (++data == end)
@@ -703,23 +702,24 @@ static int squat_build_add(struct squat_
 }
 
 static int
-squat_build_word_bytes(struct squat_trie *trie, uint32_t uid,
+squat_build_word_bytes(struct squat_trie_build_context *ctx, uint32_t uid,
 		       const unsigned char *data, unsigned int size)
 {
+	struct squat_trie *trie = ctx->trie;
 	unsigned int i;
 
 	if (trie->hdr.full_len <= trie->hdr.partial_len)
 		i = 0;
 	else {
 		/* the first word is longer than others */
-		if (squat_build_add(trie, uid, data,
+		if (squat_build_add(ctx, uid, data,
 				    I_MIN(size, trie->hdr.full_len)) < 0)
 			return -1;
 		i = 1;
 	}
 
 	for (; i < size; i++) {
-		if (squat_build_add(trie, uid, data + i,
+		if (squat_build_add(ctx, uid, data + i,
 				    I_MIN(trie->hdr.partial_len, size-i)) < 0)
 			return -1;
 	}
@@ -727,15 +727,16 @@ squat_build_word_bytes(struct squat_trie
 }
 
 static int
-squat_build_word(struct squat_trie *trie, uint32_t uid,
+squat_build_word(struct squat_trie_build_context *ctx, uint32_t uid,
 		 const unsigned char *data, const uint8_t *char_lengths,
 		 unsigned int size)
 {
+	struct squat_trie *trie = ctx->trie;
 	unsigned int i, j, bytelen;
 
 	if (char_lengths == NULL) {
 		/* optimization path: all characters are bytes */
-		return squat_build_word_bytes(trie, uid, data, size);
+		return squat_build_word_bytes(ctx, uid, data, size);
 	}
 
 	if (trie->hdr.full_len <= trie->hdr.partial_len)
@@ -747,7 +748,7 @@ squat_build_word(struct squat_trie *trie
 			bytelen += char_lengths[bytelen];
 		i_assert(bytelen <= size);
 
-		if (squat_build_add(trie, uid, data, bytelen) < 0)
+		if (squat_build_add(ctx, uid, data, bytelen) < 0)
 			return -1;
 		i = char_lengths[0];
 	}
@@ -758,7 +759,7 @@ squat_build_word(struct squat_trie *trie
 			bytelen += char_lengths[i + bytelen];
 		i_assert(i + bytelen <= size);
 
-		if (squat_build_add(trie, uid, data + i, bytelen) < 0)
+		if (squat_build_add(ctx, uid, data + i, bytelen) < 0)
 			return -1;
 	}
 	return 0;
@@ -803,7 +804,7 @@ int squat_trie_build_more(struct squat_t
 		while (start < i && data[start] == '\0')
 			start++;
 		if (i != start) {
-			if (squat_build_word(trie, uid, data + start,
+			if (squat_build_word(ctx, uid, data + start,
 					     !multibyte_chars ? NULL :
 					     char_lengths + start,
 					     i - start) < 0) {
@@ -817,7 +818,7 @@ int squat_trie_build_more(struct squat_t
 	while (start < i && data[start] == '\0')
 		start++;
 	if (i != start) {
-		if (squat_build_word(trie, uid, data + start,
+		if (squat_build_word(ctx, uid, data + start,
 				     !multibyte_chars ? NULL :
 				     char_lengths + start, i - start) < 0)
 			ret = -1;
@@ -1014,31 +1015,37 @@ squat_trie_iterate_uidlist_next(struct s
 	}
 }
 
-static int squat_trie_renumber_uidlists(struct squat_trie *trie, bool finish)
+static int
+squat_trie_renumber_uidlists(struct squat_trie_build_context *ctx,
+			     bool compress)
 {
 	struct squat_trie_iterate_context *iter;
 	struct squat_node *node;
-	struct squat_uidlist *uidlist = trie->uidlist;
-	struct squat_uidlist_rebuild_context *ctx;


More information about the dovecot-cvs mailing list