fts-backend-squat.c revision e62f6437a4ff01d692a5a61369fe4168d69191ed
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (C) 2006 Timo Sirainen */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "lib.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "array.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "mail-storage-private.h"
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen#include "mail-search.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "squat-trie.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "fts-squat-plugin.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#define SQUAT_FILE_PREFIX "dovecot.index.search"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct squat_fts_backend {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct fts_backend backend;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct squat_trie *trie;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch};
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct squat_fts_backend_build_context {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct fts_backend_build_context ctx;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct squat_trie_build_context *trie_ctx;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch};
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic struct fts_backend *fts_backend_squat_init(struct mailbox *box)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen struct squat_fts_backend *backend;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mail_storage *storage;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const char *path;
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch storage = mailbox_get_storage(box);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch path = mail_storage_get_mailbox_index_dir(storage,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch mailbox_get_name(box));
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch if (*path == '\0') {
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch /* in-memory indexes */
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch return NULL;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch backend = i_new(struct squat_fts_backend, 1);
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch backend->backend = fts_backend_squat;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch backend->trie =
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch squat_trie_open(t_strconcat(path, "/"SQUAT_FILE_PREFIX, NULL),
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch storage->lock_method);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return &backend->backend;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void fts_backend_squat_deinit(struct fts_backend *_backend)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct squat_fts_backend *backend =
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen (struct squat_fts_backend *)_backend;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch squat_trie_close(backend->trie);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_free(backend);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic int fts_backend_squat_get_last_uid(struct fts_backend *_backend,
6dad0888fcec8372f230941c70d8940b8c203b32Stephan Bosch uint32_t *last_uid_r)
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch{
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch struct squat_fts_backend *backend =
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch (struct squat_fts_backend *)_backend;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return squat_trie_get_last_uid(backend->trie, last_uid_r);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainenstatic struct fts_backend_build_context *
7384b4e78eaab44693c985192276e31322155e32Stephan Boschfts_backend_squat_build_init(struct fts_backend *_backend, uint32_t *last_uid_r)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct squat_fts_backend *backend =
1bc12a53ddc6696bb209fb79d7cc66262d2ea621Timo Sirainen (struct squat_fts_backend *)_backend;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct squat_fts_backend_build_context *ctx;
1bc12a53ddc6696bb209fb79d7cc66262d2ea621Timo Sirainen
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ctx = i_new(struct squat_fts_backend_build_context, 1);
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch ctx->ctx.backend = _backend;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ctx->trie_ctx = squat_trie_build_init(backend->trie, last_uid_r);
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen return &ctx->ctx;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic int
7384b4e78eaab44693c985192276e31322155e32Stephan Boschfts_backend_squat_build_more(struct fts_backend_build_context *_ctx,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t uid, const unsigned char *data,
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen size_t size)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct squat_fts_backend_build_context *ctx =
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch (struct squat_fts_backend_build_context *)_ctx;
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen return squat_trie_build_more(ctx->trie_ctx, uid, data, size);
1bc12a53ddc6696bb209fb79d7cc66262d2ea621Timo Sirainen}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainenstatic int
7384b4e78eaab44693c985192276e31322155e32Stephan Boschfts_backend_squat_build_deinit(struct fts_backend_build_context *_ctx)
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch{
6dad0888fcec8372f230941c70d8940b8c203b32Stephan Bosch struct squat_fts_backend_build_context *ctx =
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen (struct squat_fts_backend_build_context *)_ctx;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch int ret;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ret = squat_trie_build_deinit(ctx->trie_ctx);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_free(ctx);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return ret;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void
7384b4e78eaab44693c985192276e31322155e32Stephan Boschfts_backend_squat_expunge(struct fts_backend *_backend __attr_unused__,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mail *mail __attr_unused__)
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen{
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainenstatic int get_uids(struct mailbox *box, ARRAY_TYPE(seq_range) *uids,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int *message_count_r)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mail_search_arg search_arg;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mailbox_transaction_context *t;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mail_search_context *ctx;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mail *mail;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int count = 0;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch int ret;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch memset(&search_arg, 0, sizeof(search_arg));
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch search_arg.type = SEARCH_ALL;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch t = mailbox_transaction_begin(box, 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ctx = mailbox_search_init(t, NULL, &search_arg, NULL);
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch mail = mail_alloc(t, 0, NULL);
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen while (mailbox_search_next(ctx, mail) > 0) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch seq_range_array_add(uids, 0, mail->uid);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch count++;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen mail_free(&mail);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ret = mailbox_search_deinit(&ctx);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch mailbox_transaction_rollback(&t);
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen *message_count_r = count;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return ret;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainenfts_backend_squat_expunge_finish(struct fts_backend *_backend,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mailbox *box, bool committed)
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct squat_fts_backend *backend =
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch (struct squat_fts_backend *)_backend;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ARRAY_TYPE(seq_range) uids = ARRAY_INIT;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int count;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen if (!committed)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch t_push();
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen t_array_init(&uids, 128);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (get_uids(box, &uids, &count) == 0) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch (void)squat_trie_mark_having_expunges(backend->trie, &uids,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch count);
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen }
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen t_pop();
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic int fts_backend_squat_lock(struct fts_backend *_backend)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen struct squat_fts_backend *backend =
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch (struct squat_fts_backend *)_backend;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return squat_trie_lock(backend->trie, F_RDLCK);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainenstatic void fts_backend_squat_unlock(struct fts_backend *_backend)
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen{
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen struct squat_fts_backend *backend =
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen (struct squat_fts_backend *)_backend;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen squat_trie_unlock(backend->trie);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic int
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainenfts_backend_squat_lookup(struct fts_backend *_backend, const char *key,
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen ARRAY_TYPE(seq_range) *result)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen struct squat_fts_backend *backend =
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch (struct squat_fts_backend *)_backend;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return squat_trie_lookup(backend->trie, result, key);
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen}
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic int
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainenfts_backend_squat_filter(struct fts_backend *_backend, const char *key,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ARRAY_TYPE(seq_range) *result)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen struct squat_fts_backend *backend =
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch (struct squat_fts_backend *)_backend;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return squat_trie_filter(backend->trie, result, key);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct fts_backend fts_backend_squat = {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch MEMBER(name) "squat",
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch MEMBER(definite_lookups) FALSE,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch fts_backend_squat_init,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch fts_backend_squat_deinit,
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen fts_backend_squat_get_last_uid,
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen fts_backend_squat_build_init,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch fts_backend_squat_build_more,
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen fts_backend_squat_build_deinit,
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen fts_backend_squat_expunge,
1bc12a53ddc6696bb209fb79d7cc66262d2ea621Timo Sirainen fts_backend_squat_expunge_finish,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch fts_backend_squat_lock,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch fts_backend_squat_unlock,
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen fts_backend_squat_lookup,
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen fts_backend_squat_filter
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen }
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen};
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch