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