dovecot: Added missing files.
dovecot at dovecot.org
dovecot at dovecot.org
Mon Dec 3 10:23:10 EET 2007
details: http://hg.dovecot.org/dovecot/rev/a8d3513b54c5
changeset: 6903:a8d3513b54c5
user: Timo Sirainen <tss at iki.fi>
date: Mon Dec 03 10:23:06 2007 +0200
description:
Added missing files.
diffstat:
2 files changed, 233 insertions(+)
src/plugins/fts/fts-search.c | 195 +++++++++++++++++++++++++++++++++++++++++
src/plugins/fts/fts-storage.h | 38 +++++++
diffs (241 lines):
diff -r cff5428c3c4d -r a8d3513b54c5 src/plugins/fts/fts-search.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/fts/fts-search.c Mon Dec 03 10:23:06 2007 +0200
@@ -0,0 +1,195 @@
+/* Copyright (c) 2006-2007 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "seq-range-array.h"
+#include "mail-search.h"
+#include "mail-storage-private.h"
+#include "fts-api-private.h"
+#include "fts-storage.h"
+
+static void
+uid_range_to_seqs(struct mailbox *box, const ARRAY_TYPE(seq_range) *uid_range,
+ ARRAY_TYPE(seq_range) *seq_range)
+{
+ const struct seq_range *range;
+ struct seq_range new_range;
+ unsigned int i, count;
+
+ range = array_get(uid_range, &count);
+ i_array_init(seq_range, count);
+ for (i = 0; i < count; i++) {
+ mailbox_get_uids(box, range[i].seq1, range[i].seq2,
+ &new_range.seq1, &new_range.seq2);
+ if (new_range.seq1 != 0)
+ array_append(seq_range, &new_range, 1);
+ }
+}
+
+static void fts_uid_results_to_seq(struct fts_search_context *fctx)
+{
+ ARRAY_TYPE(seq_range) uid_range;
+
+ uid_range = fctx->definite_seqs;
+ i_array_init(&fctx->definite_seqs, array_count(&uid_range));
+ uid_range_to_seqs(fctx->t->box, &uid_range, &fctx->definite_seqs);
+ array_free(&uid_range);
+
+ uid_range = fctx->maybe_seqs;
+ i_array_init(&fctx->maybe_seqs, array_count(&uid_range));
+ uid_range_to_seqs(fctx->t->box, &uid_range, &fctx->maybe_seqs);
+ array_free(&uid_range);
+}
+
+static int fts_search_lookup_arg(struct fts_search_context *fctx,
+ struct mail_search_arg *arg, bool filter)
+{
+ struct fts_backend *backend;
+ enum fts_lookup_flags flags = 0;
+ const char *key;
+
+ switch (arg->type) {
+ case SEARCH_HEADER:
+ /* we can filter out messages that don't have the header,
+ but we can't trust definite results list. */
+ flags = FTS_LOOKUP_FLAG_HEADER;
+ backend = fctx->fbox->backend_substr;
+ key = arg->value.str;
+ if (*key == '\0') {
+ /* we're only checking the existence
+ of the header. */
+ key = arg->hdr_field_name;
+ }
+ break;
+ case SEARCH_TEXT:
+ case SEARCH_TEXT_FAST:
+ flags = FTS_LOOKUP_FLAG_HEADER;
+ case SEARCH_BODY:
+ case SEARCH_BODY_FAST:
+ flags |= FTS_LOOKUP_FLAG_BODY;
+ key = arg->value.str;
+ backend = fctx->fbox->backend_fast != NULL &&
+ (arg->type == SEARCH_TEXT_FAST ||
+ arg->type == SEARCH_BODY_FAST) ?
+ fctx->fbox->backend_fast : fctx->fbox->backend_substr;
+ break;
+ default:
+ /* can't filter this */
+ i_assert(filter);
+ return 0;
+ }
+ if (arg->not)
+ flags |= FTS_LOOKUP_FLAG_INVERT;
+
+ if (!backend->locked) {
+ if (fts_backend_lock(backend) <= 0)
+ return -1;
+ }
+
+ if (!filter) {
+ return fts_backend_lookup(backend, key, flags,
+ &fctx->definite_seqs,
+ &fctx->maybe_seqs);
+ } else {
+ return fts_backend_filter(backend, key, flags,
+ &fctx->definite_seqs,
+ &fctx->maybe_seqs);
+ }
+}
+
+void fts_search_lookup(struct fts_search_context *fctx)
+{
+ struct mail_search_arg *arg;
+ int ret;
+
+ if (fctx->best_arg == NULL)
+ return;
+
+ i_array_init(&fctx->definite_seqs, 64);
+ i_array_init(&fctx->maybe_seqs, 64);
+
+ /* start filtering with the best arg */
+ ret = fts_search_lookup_arg(fctx, fctx->best_arg, FALSE);
+ /* filter the rest */
+ for (arg = fctx->args; arg != NULL && ret == 0; arg = arg->next) {
+ if (arg != fctx->best_arg)
+ ret = fts_search_lookup_arg(fctx, arg, TRUE);
+ }
+
+ if (fctx->fbox->backend_fast != NULL &&
+ fctx->fbox->backend_fast->locked)
+ fts_backend_unlock(fctx->fbox->backend_fast);
+ if (fctx->fbox->backend_substr != NULL &&
+ fctx->fbox->backend_substr->locked)
+ fts_backend_unlock(fctx->fbox->backend_substr);
+
+ if (ret == 0) {
+ fctx->seqs_set = TRUE;
+ fts_uid_results_to_seq(fctx);
+ }
+}
+
+static bool arg_is_better(const struct mail_search_arg *new_arg,
+ const struct mail_search_arg *old_arg)
+{
+ if (old_arg == NULL)
+ return TRUE;
+ if (new_arg == NULL)
+ return FALSE;
+
+ /* avoid NOTs */
+ if (old_arg->not && !new_arg->not)
+ return TRUE;
+ if (!old_arg->not && new_arg->not)
+ return FALSE;
+
+ /* prefer not to use headers. they have a larger possibility of
+ having lots of identical strings */
+ if (old_arg->type == SEARCH_HEADER)
+ return TRUE;
+ else if (new_arg->type == SEARCH_HEADER)
+ return FALSE;
+
+ return strlen(new_arg->value.str) > strlen(old_arg->value.str);
+}
+
+static void
+fts_search_args_find_best(struct mail_search_arg *args,
+ struct mail_search_arg **best_fast_arg,
+ struct mail_search_arg **best_substr_arg)
+{
+ for (; args != NULL; args = args->next) {
+ switch (args->type) {
+ case SEARCH_BODY_FAST:
+ case SEARCH_TEXT_FAST:
+ if (arg_is_better(args, *best_fast_arg))
+ *best_fast_arg = args;
+ break;
+ case SEARCH_BODY:
+ case SEARCH_TEXT:
+ case SEARCH_HEADER:
+ if (arg_is_better(args, *best_substr_arg))
+ *best_substr_arg = args;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void fts_search_analyze(struct fts_search_context *fctx)
+{
+ struct mail_search_arg *best_fast_arg = NULL, *best_substr_arg = NULL;
+
+ fts_search_args_find_best(fctx->args, &best_fast_arg, &best_substr_arg);
+
+ if (best_fast_arg != NULL && fctx->fbox->backend_fast != NULL) {
+ /* use fast backend whenever possible */
+ fctx->best_arg = best_fast_arg;
+ fctx->build_backend = fctx->fbox->backend_fast;
+ } else if (best_fast_arg != NULL || best_substr_arg != NULL) {
+ fctx->build_backend = fctx->fbox->backend_substr;
+ fctx->best_arg = arg_is_better(best_substr_arg, best_fast_arg) ?
+ best_substr_arg : best_fast_arg;
+ }
+}
diff -r cff5428c3c4d -r a8d3513b54c5 src/plugins/fts/fts-storage.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/fts/fts-storage.h Mon Dec 03 10:23:06 2007 +0200
@@ -0,0 +1,38 @@
+#ifndef FTS_STORAGE_H
+#define FTS_STORAGE_H
+
+struct fts_mailbox {
+ union mailbox_module_context module_ctx;
+ struct fts_backend *backend_substr;
+ struct fts_backend *backend_fast;
+
+ const char *env;
+ unsigned int backend_set:1;
+};
+
+struct fts_search_context {
+ union mail_search_module_context module_ctx;
+
+ struct fts_mailbox *fbox;
+ struct mailbox_transaction_context *t;
+ struct mail_search_arg *args;
+ struct mail_search_arg *best_arg;
+
+ ARRAY_TYPE(seq_range) definite_seqs, maybe_seqs;
+ unsigned int definite_idx, maybe_idx;
+ uint32_t first_nonindexed_seq;
+
+ struct fts_backend *build_backend;
+ struct fts_storage_build_context *build_ctx;
+
+ unsigned int build_initialized:1;
+ unsigned int seqs_set:1;
+};
+
+/* Figure out if we want to use full text search indexes and update
+ backends in fctx accordingly. */
+void fts_search_analyze(struct fts_search_context *fctx);
+/* Perform the actual index lookup and update definite_uids and maybe_uids. */
+void fts_search_lookup(struct fts_search_context *fctx);
+
+#endif
More information about the dovecot-cvs
mailing list