fts-api.c revision 263d455e9198e8aa45c7a99601ad6a5a9dcdd915
a8c5a86d183db25a57bf193c06b41e092ec2e151Timo Sirainen/* Copyright (c) 2006-2014 Dovecot authors, see the included COPYING file */
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainenstatic ARRAY(const struct fts_backend *) backends;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenvoid fts_backend_register(const struct fts_backend *backend)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen unsigned int i, count;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen for (i = 0; i < count; i++) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen i_panic("fts_backend_unregister(%s): unknown backend", name);
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainenstatic const struct fts_backend *
459c61c9a0beaa6986958d55b059b2d246032c4cTimo Sirainenfts_backend_class_lookup(const char *backend_name)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen unsigned int i, count;
c63544d7d2580c680b07f9569e87e9cebee383d5Timo Sirainen for (i = 0; i < count; i++) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_backend_init(const char *backend_name, struct mail_namespace *ns,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const char **error_r, struct fts_backend **backend_r)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenvoid fts_backend_deinit(struct fts_backend **_backend)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_backend_get_last_uid(struct fts_backend *backend, struct mailbox *box,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (strcmp(box->storage->name, VIRTUAL_STORAGE_NAME) == 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* virtual mailboxes themselves don't have any indexes,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen so catch this call here */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return backend->v.get_last_uid(backend, box, last_uid_r);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenbool fts_backend_is_updating(struct fts_backend *backend)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_update_init(struct fts_backend *backend)
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen if ((backend->flags & FTS_BACKEND_FLAG_NORMALIZE_INPUT) != 0)
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen ctx->normalizer = backend->ns->user->default_normalizer;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic void fts_backend_set_cur_mailbox(struct fts_backend_update_context *ctx)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->backend->v.update_set_mailbox(ctx, ctx->cur_box);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_backend_update_deinit(struct fts_backend_update_context **_ctx)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct fts_backend_update_context *ctx = *_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid fts_backend_update_set_mailbox(struct fts_backend_update_context *ctx,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ctx->backend_box != NULL && box != ctx->backend_box) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* make sure we don't reference the backend box anymore */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->backend->v.update_set_mailbox(ctx, NULL);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid fts_backend_update_expunge(struct fts_backend_update_context *ctx,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenbool fts_backend_update_set_build_key(struct fts_backend_update_context *ctx,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (!ctx->backend->v.update_set_build_key(ctx, key))
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid fts_backend_update_unset_build_key(struct fts_backend_update_context *ctx)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_backend_update_build_more(struct fts_backend_update_context *ctx,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return ctx->backend->v.update_build_more(ctx, data, size);
de11cf486e0d0448537b1b5d546496ab85e7cda8Timo Sirainenint fts_backend_refresh(struct fts_backend *backend)
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainenint fts_backend_reset_last_uids(struct fts_backend *backend)
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen iter = mailbox_list_iter_init(backend->ns->list, "*",
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen while ((info = mailbox_list_iter_next(iter)) != NULL) {
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen (MAILBOX_NONEXISTENT | MAILBOX_NOSELECT)) != 0)
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen box = mailbox_alloc(info->ns->list, info->vname, 0);
a569c6df4ffe05acc242e269d926449e50702d59Timo Sirainenint fts_backend_rescan(struct fts_backend *backend)
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen if (strcmp(backend->ns->storage->name, VIRTUAL_STORAGE_NAME) == 0) {
263d455e9198e8aa45c7a99601ad6a5a9dcdd915Timo Sirainen /* just reset the last-uids for a virtual storage. */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_backend_optimize(struct fts_backend *backend)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenfts_merge_maybies(ARRAY_TYPE(seq_range) *dest_maybe,
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen unsigned int i, count;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen /* add/leave to dest_maybe if at least one list has maybe,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen and no lists have none */
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen /* create unwanted sequences list from both sources */
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen new_range.seq1 = 0; new_range.seq2 = (uint32_t)-1;
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen seq_range_array_remove_seq_range(&src_unwanted, src_maybe);
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen seq_range_array_remove_seq_range(&src_unwanted, src_definite);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen /* drop unwanted uids */
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen seq_range_array_remove_seq_range(dest_maybe, &src_unwanted);
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen /* add uids that are in dest_definite and src_maybe lists */
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen for (i = 0; i < count; i++) {
a1f517528af314cb6f5f39187a71dbed8a6e1152Timo Sirainen for (seq = range[i].seq1; seq <= range[i].seq2; seq++) {
809923ba26218971792182ae8894936f9ac99364Timo Sirainenvoid fts_filter_uids(ARRAY_TYPE(seq_range) *definite_dest,
809923ba26218971792182ae8894936f9ac99364Timo Sirainen /* keep only what exists in both lists. the rest is in
809923ba26218971792182ae8894936f9ac99364Timo Sirainen maybies or not wanted */
809923ba26218971792182ae8894936f9ac99364Timo Sirainen seq_range_array_intersect(definite_dest, definite_filter);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenbool fts_backend_default_can_lookup(struct fts_backend *backend,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenbool fts_backend_can_lookup(struct fts_backend *backend,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic int fts_score_map_sort(const struct fts_score_map *m1,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_backend_lookup(struct fts_backend *backend, struct mailbox *box,
117fb8c00336dc54bab9cfa547249df7a4970611Timo Sirainen if (backend->v.lookup(backend, box, args, flags, result) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (!result->scores_sorted && array_is_created(&result->scores)) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_sort(&result->scores, fts_score_map_sort);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_backend_lookup_multi(struct fts_backend *backend,
2022c259052c6cbb595cc90d36c0d4bdbf5254b6Timo Sirainen unsigned int i;
f3bed8816ef2842845b8bf1714a9458dd47460d0Timo Sirainen if (backend->v.lookup_multi(backend, boxes, args,
2022c259052c6cbb595cc90d36c0d4bdbf5254b6Timo Sirainen result->box_results = p_new(result->pool, struct fts_result, i+1);
db0fb9eb7da6059fa1af1e5429c898c81bdc2aa9Timo Sirainen struct fts_result *box_result = &result->box_results[i];
db0fb9eb7da6059fa1af1e5429c898c81bdc2aa9Timo Sirainen p_array_init(&box_result->definite_uids, result->pool, 32);
db0fb9eb7da6059fa1af1e5429c898c81bdc2aa9Timo Sirainen p_array_init(&box_result->maybe_uids, result->pool, 32);
db0fb9eb7da6059fa1af1e5429c898c81bdc2aa9Timo Sirainen p_array_init(&box_result->scores, result->pool, 32);
2022c259052c6cbb595cc90d36c0d4bdbf5254b6Timo Sirainen if (backend->v.lookup(backend, boxes[i], args,
b7fdf4fe23801de680e0be5aca0596a3c9ea3f8fTimo Sirainenvoid fts_backend_lookup_done(struct fts_backend *backend)
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainenstatic uint32_t fts_index_get_ext_id(struct mailbox *box)
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen return mail_index_ext_register(box->index, "fts",
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainenbool fts_index_get_header(struct mailbox *box, struct fts_index_header *hdr_r)
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen mail_index_get_header_ext(view, fts_index_get_ext_id(box),
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen trans = mail_index_transaction_begin(box->view, 0);
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen mail_index_update_header_ext(trans, ext_id, 0, hdr, sizeof(*hdr));
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_index_set_last_uid(struct mailbox *box, uint32_t last_uid)
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainenint fts_index_have_compatible_settings(struct mailbox_list *list,
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen struct mail_namespace *ns = mailbox_list_get_namespace(list);
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen unsigned int len;
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen if ((ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0)
96da164ade36c54e94083de1a545216ebc2afa31Timo Sirainen if (len > 0 && ns->prefix[len-1] == mail_namespace_get_sep(ns))
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen if (mailbox_sync(box, (enum mailbox_sync_flags)0) < 0) {
54d437dea655b338e45a8917880f3d3a2a7b698dTimo Sirainen i_error("lucene: Failed to sync mailbox INBOX: %s",
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic const char *indexed_headers[] = {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenbool fts_header_want_indexed(const char *hdr_name)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen unsigned int i;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen for (i = 0; i < N_ELEMENTS(indexed_headers); i++) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (strcasecmp(hdr_name, indexed_headers[i]) == 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint fts_mailbox_get_guid(struct mailbox *box, const char **guid_r)