bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2006-2018 Dovecot authors, see the included COPYING file */
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen#define SQUAT_FILE_PREFIX "dovecot.index.search"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic struct fts_backend *fts_backend_squat_alloc(void)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_init(struct fts_backend *_backend, const char **error_r)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen env = mail_user_plugin_getenv(_backend->ns->user, "fts_squat");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen for (tmp = t_strsplit_spaces(env, " "); *tmp != NULL; tmp++) {
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen if (str_to_uint(*tmp + 8, &len) < 0 || len == 0) {
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen if (str_to_uint(*tmp + 5, &len) < 0 || len == 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen *error_r = t_strdup_printf("Invalid setting: %s", *tmp);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_unset_box(struct squat_fts_backend *backend)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic void fts_backend_squat_deinit(struct fts_backend *_backend)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_set_box(struct squat_fts_backend *backend,
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen if (mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_INDEX, &path) <= 0)
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen mailbox_get_open_status(box, STATUS_UIDVALIDITY, &status);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen squat_trie_init(t_strconcat(path, "/"SQUAT_FILE_PREFIX, NULL),
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen squat_trie_set_partial_len(backend->trie, backend->partial_len);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen squat_trie_set_full_len(backend->trie, backend->full_len);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_get_last_uid(struct fts_backend *_backend,
e62f6437a4ff01d692a5a61369fe4168d69191edTimo Sirainen return squat_trie_get_last_uid(backend->trie, last_uid_r);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_update_init(struct fts_backend *_backend)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx = i_new(struct squat_fts_backend_update_context, 1);
1caf757864e7734345660e7d190f84e42668a6f8Timo Sirainenstatic int get_all_msg_uids(struct mailbox *box, ARRAY_TYPE(seq_range) *uids)
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi t = mailbox_transaction_begin(box, 0, __func__);
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen search_ctx = mailbox_search_init(t, search_args, NULL, 0, NULL);
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen while (mailbox_search_next(search_ctx, &mail)) {
fcde781c3ceb470c8dff34a68df19c69f93bcec9Timo Sirainen /* *2 because even/odd is for body/header */
fcde781c3ceb470c8dff34a68df19c69f93bcec9Timo Sirainen seq_range_array_add_range(uids, mail->uid * 2,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_update_uid_changed(struct squat_fts_backend_update_context *ctx)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (squat_trie_build_more(ctx->build_ctx, ctx->uid,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_build_deinit(struct squat_fts_backend_update_context *ctx)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fts_backend_squat_update_uid_changed(ctx) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (get_all_msg_uids(backend->box, &uids) < 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (void)squat_trie_build_deinit(&ctx->build_ctx, NULL);
fcde781c3ceb470c8dff34a68df19c69f93bcec9Timo Sirainen seq_range_array_invert(&uids, 2, (uint32_t)-2);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (squat_trie_build_deinit(&ctx->build_ctx, &uids) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_update_deinit(struct fts_backend_update_context *_ctx)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct squat_fts_backend_update_context *ctx =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (struct squat_fts_backend_update_context *)_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_update_set_mailbox(struct fts_backend_update_context *_ctx,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct squat_fts_backend_update_context *ctx =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (struct squat_fts_backend_update_context *)_ctx;
37cd04fc1d01c4a7140ffcb514e15cee1e97986aTimo Sirainen if (squat_trie_build_init(backend->trie, &ctx->build_ctx) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_update_expunge(struct fts_backend_update_context *_ctx ATTR_UNUSED,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_update_set_build_key(struct fts_backend_update_context *_ctx,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct squat_fts_backend_update_context *ctx =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (struct squat_fts_backend_update_context *)_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (fts_backend_squat_update_uid_changed(ctx) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_update_unset_build_key(struct fts_backend_update_context *_ctx)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct squat_fts_backend_update_context *ctx =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (struct squat_fts_backend_update_context *)_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ctx->squat_type == SQUAT_INDEX_TYPE_HEADER)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_update_build_more(struct fts_backend_update_context *_ctx,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct squat_fts_backend_update_context *ctx =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (struct squat_fts_backend_update_context *)_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ctx->squat_type == SQUAT_INDEX_TYPE_HEADER) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return squat_trie_build_more(ctx->build_ctx, ctx->uid, ctx->squat_type,
de11cf486e0d0448537b1b5d546496ab85e7cda8Timo Sirainenstatic int fts_backend_squat_refresh(struct fts_backend *_backend)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic int fts_backend_squat_optimize(struct fts_backend *_backend ATTR_UNUSED)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* FIXME: drop expunged messages */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic int squat_lookup_arg(struct squat_fts_backend *backend,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct mail_search_arg *arg, bool and_args,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ARRAY_TYPE(seq_range) tmp_definite_uids, tmp_maybe_uids;
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen default_normalizer(arg->value.str, strlen(arg->value.str), dtc) < 0)
5601c23c0d59376dfda22c7eb807c9e1a0870426Timo Sirainen ret = squat_trie_lookup(backend->trie, str_c(dtc), squat_type,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* definite -> non-match
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen maybe -> maybe
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen non-match -> maybe */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (squat_trie_get_last_uid(backend->trie, &last_uid) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_add_range(&tmp_maybe_uids, 1, last_uid);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_remove_seq_range(&tmp_maybe_uids,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen definite && definite -> definite
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen definite && maybe -> maybe
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen maybe && maybe -> maybe */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* put definites among maybies, so they can be intersected */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_merge(maybe_uids, definite_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_merge(&tmp_maybe_uids, &tmp_definite_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_intersect(maybe_uids, &tmp_maybe_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_intersect(definite_uids, &tmp_definite_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* remove duplicate maybies that are also definites */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_remove_seq_range(maybe_uids, definite_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen definite || definite -> definite
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen definite || maybe -> definite
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen maybe || maybe -> maybe */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* remove maybies that are now definites */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_remove_seq_range(&tmp_maybe_uids,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_merge(definite_uids, &tmp_definite_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq_range_array_merge(maybe_uids, &tmp_maybe_uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenfts_backend_squat_lookup(struct fts_backend *_backend, struct mailbox *box,
117fb8c00336dc54bab9cfa547249df7a4970611Timo Sirainen bool and_args = (flags & FTS_LOOKUP_FLAG_AND_ARGS) != 0;