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