dovecot: Fixed handling non-indexed characters in search key.

dovecot at dovecot.org dovecot at dovecot.org
Mon Dec 3 09:51:09 EET 2007


details:   http://hg.dovecot.org/dovecot/rev/cff5428c3c4d
changeset: 6902:cff5428c3c4d
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Dec 03 09:51:04 2007 +0200
description:
Fixed handling non-indexed characters in search key.

diffstat:

1 file changed, 89 insertions(+), 30 deletions(-)
src/plugins/fts-squat/squat-trie.c |  119 ++++++++++++++++++++++++++----------

diffs (150 lines):

diff -r 92e197fa699e -r cff5428c3c4d src/plugins/fts-squat/squat-trie.c
--- a/src/plugins/fts-squat/squat-trie.c	Mon Dec 03 09:50:40 2007 +0200
+++ b/src/plugins/fts-squat/squat-trie.c	Mon Dec 03 09:51:04 2007 +0200
@@ -1316,29 +1316,107 @@ squat_trie_filter_type(enum squat_index_
 	}
 }
 
+struct squat_trie_lookup_context {
+	struct squat_trie *trie;
+	enum squat_index_type type;
+
+	ARRAY_TYPE(seq_range) *definite_uids, *maybe_uids;
+	ARRAY_TYPE(seq_range) tmp_uids, tmp_uids2;
+	bool first;
+};
+
+static int
+squat_trie_lookup_partial(struct squat_trie_lookup_context *ctx,
+			  const unsigned char *data, unsigned int size)
+{
+	const unsigned char *block;
+	unsigned int block_len;
+	int ret;
+
+	do {
+		if (size <= MAX_PARTIAL_LEN)
+			block_len = size;
+		else
+			block_len = MAX_PARTIAL_LEN;
+		block = data + size - block_len;
+
+		ret = squat_trie_lookup_data(ctx->trie, block, block_len,
+					     &ctx->tmp_uids);
+		if (ret <= 0) {
+			array_clear(ctx->maybe_uids);
+			return ret;
+		}
+
+		if (ctx->first) {
+			squat_trie_filter_type(ctx->type, &ctx->tmp_uids,
+					       ctx->maybe_uids);
+			ctx->first = FALSE;
+		} else {
+			squat_trie_filter_type(ctx->type, &ctx->tmp_uids,
+					       &ctx->tmp_uids2);
+			seq_range_array_remove_invert_range(ctx->maybe_uids,
+							    &ctx->tmp_uids2);
+		}
+	} while (--size >= MAX_PARTIAL_LEN);
+	return 1;
+}
+
 int squat_trie_lookup(struct squat_trie *trie, const char *str,
 		      enum squat_index_type type,
 		      ARRAY_TYPE(seq_range) *definite_uids,
 		      ARRAY_TYPE(seq_range) *maybe_uids)
 {
-	ARRAY_TYPE(seq_range) tmp_uids, tmp_uids2;
-	unsigned char *data, *block;
-	unsigned int size;
-	bool first;
+	struct squat_trie_lookup_context ctx;
+	unsigned char *data;
+	unsigned int i, start, size;
 	int ret = 0;
 
 	t_push();
+	memset(&ctx, 0, sizeof(ctx));
+	ctx.trie = trie;
+	ctx.type = type;
+	ctx.definite_uids = definite_uids;
+	ctx.maybe_uids = maybe_uids;
+	t_array_init(&ctx.tmp_uids, 128);
+	t_array_init(&ctx.tmp_uids2, 128);
+	ctx.first = TRUE;
+
 	size = strlen(str);
 	data = t_malloc(size);
 	memcpy(data, str, size);
 	data = squat_data_normalize(trie, data, size);
-	t_array_init(&tmp_uids, 128);
-	t_array_init(&tmp_uids2, 128);
+
+	for (i = start = 0; i < size && ret >= 0; i++) {
+		if (data[i] != '\0')
+			continue;
+
+		/* string has nonindexed characters.
+		   search it in parts. */
+		if (i != start) {
+			ret = squat_trie_lookup_partial(&ctx, data + start,
+							i - start);
+		}
+		start = i + 1;
+	}
+
+	if (start != 0) {
+		/* string has nonindexed characters. finish the search. */
+		array_clear(definite_uids);
+		if (i != start && ret >= 0) {
+			ret = squat_trie_lookup_partial(&ctx, data + start,
+							i - start);
+		}
+		t_pop();
+		return ret < 0 ? -1 :
+			(array_count(maybe_uids) > 0 ? 1 : 0);
+	}
 
 	if (MAX_FULL_LEN > MAX_PARTIAL_LEN || size <= MAX_PARTIAL_LEN) {
-		ret = squat_trie_lookup_data(trie, data, size, &tmp_uids);
-		if (ret > 0)
-			squat_trie_filter_type(type, &tmp_uids, definite_uids);
+		ret = squat_trie_lookup_data(trie, data, size, &ctx.tmp_uids);
+		if (ret > 0) {
+			squat_trie_filter_type(type, &ctx.tmp_uids,
+					       definite_uids);
+		}
 	} else {
 		array_clear(definite_uids);
 	}
@@ -1347,27 +1425,8 @@ int squat_trie_lookup(struct squat_trie 
 		/* we have the result */
 		array_clear(maybe_uids);
 	} else {
-		first = TRUE;
-		do {
-			block = data + size - MAX_PARTIAL_LEN;
-			ret = squat_trie_lookup_data(trie, block,
-						     MAX_PARTIAL_LEN,
-						     &tmp_uids);
-			if (ret <= 0) {
-				array_clear(maybe_uids);
-				break;
-			}
-			if (first) {
-				squat_trie_filter_type(type, &tmp_uids,
-						       maybe_uids);
-				first = FALSE;
-			} else {
-				squat_trie_filter_type(type, &tmp_uids,
-						       &tmp_uids2);
-				seq_range_array_remove_invert_range(maybe_uids,
-								    &tmp_uids2);
-			}
-		} while (--size >= MAX_PARTIAL_LEN);
+		ret = squat_trie_lookup_partial(&ctx, data + start,
+						i - start);
 	}
 	t_pop();
 	return ret < 0 ? -1 :


More information about the dovecot-cvs mailing list