コード例 #1
0
ファイル: fts-storage.c プロジェクト: Raffprta/core
static void fts_transaction_rollback(struct mailbox_transaction_context *t)
{
	struct fts_mailbox *fbox = FTS_CONTEXT(t->box);

	(void)fts_transaction_end(t);
	fbox->module_ctx.super.transaction_rollback(t);
}
コード例 #2
0
ファイル: fts-storage.c プロジェクト: Raffprta/core
static bool fts_mailbox_build_continue(struct mail_search_context *ctx)
{
	struct fts_search_context *fctx = FTS_CONTEXT(ctx);
	int ret;

	ret = fts_indexer_more(fctx->indexer_ctx);
	if (ret == 0)
		return FALSE;

	/* indexing finished */
	ctx->progress_hidden = FALSE;
	if (fts_indexer_deinit(&fctx->indexer_ctx) < 0)
		ret = -1;
	if (ret > 0)
		fts_search_lookup(fctx);
	if (ret < 0) {
		/* if indexing timed out, it probably means that
		   the mailbox is still being indexed, but it's a large
		   mailbox and it takes a while. in this situation
		   we'll simply abort the search.

		   if indexing failed for any other reason, just
		   fallback to searching the slow way. */
		fctx->indexing_timed_out =
			mailbox_get_last_mail_error(fctx->box) == MAIL_ERROR_INUSE;
	}
	return TRUE;
}
コード例 #3
0
ファイル: fts-storage.c プロジェクト: Raffprta/core
static int fts_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
				const char **value_r)
{
	struct mail_private *mail = (struct mail_private *)_mail;
	struct fts_mail *fmail = FTS_MAIL_CONTEXT(mail);
	struct fts_transaction_context *ft = FTS_CONTEXT(_mail->transaction);
	const struct fts_score_map *scores;

	if (field != MAIL_FETCH_SEARCH_RELEVANCY || ft->scores == NULL)
		scores = NULL;
	else {
		scores = array_bsearch(&ft->scores->score_map, &_mail->uid,
				       fts_score_cmp);
	}
	if (scores != NULL) {
		i_assert(scores->uid == _mail->uid);
		(void)i_snprintf(fmail->score, sizeof(fmail->score),
				 "%f", scores->score);
			
		*value_r = fmail->score;
		return 0;
	}

	return fmail->module_ctx.super.get_special(_mail, field, value_r);
}
コード例 #4
0
ファイル: fts-storage.c プロジェクト: manuelm/dovecot
static int fts_sync_deinit(struct mailbox_sync_context *ctx,
			   struct mailbox_sync_status *status_r)
{
	struct mailbox *box = ctx->box;
	struct fts_mailbox *fbox = FTS_CONTEXT(box);
	struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(box->list);
	bool optimize;
	int ret = 0;

	optimize = (ctx->flags & (MAILBOX_SYNC_FLAG_FORCE_RESYNC |
				  MAILBOX_SYNC_FLAG_OPTIMIZE)) != 0;
	if (fbox->module_ctx.super.sync_deinit(ctx, status_r) < 0)
		return -1;
	ctx = NULL;

	if (optimize) {
		if (fts_backend_optimize(flist->backend) < 0) {
			mail_storage_set_critical(box->storage,
				"FTS optimize for mailbox %s failed",
				box->vname);
			ret = -1;
		}
	}
	return ret;
}
コード例 #5
0
ファイル: fts-storage.c プロジェクト: manuelm/dovecot
static void fts_mailbox_sync_notify(struct mailbox *box, uint32_t uid,
				    enum mailbox_sync_type sync_type)
{
	struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(box->list);
	struct fts_mailbox *fbox = FTS_CONTEXT(box);

	if (fbox->module_ctx.super.sync_notify != NULL)
		fbox->module_ctx.super.sync_notify(box, uid, sync_type);

	if (sync_type != MAILBOX_SYNC_TYPE_EXPUNGE) {
		if (uid == 0 && fbox->sync_update_ctx != NULL) {
			/* this sync is finished */
			(void)fts_backend_update_deinit(&fbox->sync_update_ctx);
		}
		return;
	}

	if (fbox->sync_update_ctx == NULL) {
		if (fts_backend_is_updating(flist->backend)) {
			/* FIXME: maildir workaround - we could get here
			   because we're building an index, which doesn't find
			   some mail and starts syncing the mailbox.. */
			return;
		}
		fbox->sync_update_ctx = fts_backend_update_init(flist->backend);
		fts_backend_update_set_mailbox(fbox->sync_update_ctx, box);
	}
	fts_backend_update_expunge(fbox->sync_update_ctx, uid);
}
コード例 #6
0
ファイル: fts-storage.c プロジェクト: manuelm/dovecot
static int fts_transaction_end(struct mailbox_transaction_context *t, const char **error_r)
{
	struct fts_transaction_context *ft = FTS_CONTEXT(t);
	struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(t->box->list);
	int ret = ft->failed ? -1 : 0;

	if (ft->failed)
		*error_r = "transaction context";

	if (ft->precached) {
		i_assert(flist->update_ctx_refcount > 0);
		if (--flist->update_ctx_refcount == 0) {
			if (fts_backend_update_deinit(&flist->update_ctx) < 0) {
				ret = -1;
				*error_r = "backend deinit";
			}
		}
	} else if (ft->highest_virtual_uid > 0) {
		if (fts_index_set_last_uid(t->box, ft->highest_virtual_uid) < 0) {
			ret = -1;
			*error_r = "index last uid setting";
		}
	}
	if (ft->scores != NULL)
		fts_scores_unref(&ft->scores);
	i_free(ft);
	return ret;
}
コード例 #7
0
ファイル: fts-storage.c プロジェクト: Raffprta/core
static struct mailbox_transaction_context *
fts_transaction_begin(struct mailbox *box,
		      enum mailbox_transaction_flags flags)
{
	struct fts_mailbox *fbox = FTS_CONTEXT(box);
	struct mailbox_transaction_context *t;
	struct fts_transaction_context *ft;

	ft = i_new(struct fts_transaction_context, 1);

	t = fbox->module_ctx.super.transaction_begin(box, flags);
	MODULE_CONTEXT_SET(t, fts_storage_module, ft);
	return t;
}
コード例 #8
0
ファイル: fts-storage.c プロジェクト: Raffprta/core
static void fts_mail_precache(struct mail *_mail)
{
	struct mail_private *mail = (struct mail_private *)_mail;
	struct fts_mail *fmail = FTS_MAIL_CONTEXT(mail);
	struct fts_transaction_context *ft = FTS_CONTEXT(_mail->transaction);

	fmail->module_ctx.super.precache(_mail);
	if (fmail->virtual_mail) {
		if (ft->highest_virtual_uid < _mail->uid)
			ft->highest_virtual_uid = _mail->uid;
	} else T_BEGIN {
		fts_mail_index(_mail);
	} T_END;
}
コード例 #9
0
ファイル: fts-storage.c プロジェクト: Raffprta/core
static int fts_mail_precache_init(struct mail *_mail)
{
	struct fts_transaction_context *ft = FTS_CONTEXT(_mail->transaction);
	struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(_mail->box->list);
	uint32_t last_seq;

	if (fts_mailbox_get_last_cached_seq(_mail->box, &last_seq) < 0)
		return -1;

	ft->precached = TRUE;
	ft->next_index_seq = last_seq + 1;
	if (flist->update_ctx == NULL)
		flist->update_ctx = fts_backend_update_init(flist->backend);
	flist->update_ctx_refcount++;
	return 0;
}
コード例 #10
0
ファイル: fts-storage.c プロジェクト: manuelm/dovecot
void fts_mail_allocated(struct mail *_mail)
{
	struct mail_private *mail = (struct mail_private *)_mail;
	struct mail_vfuncs *v = mail->vlast;
	struct fts_mailbox *fbox = FTS_CONTEXT(_mail->box);
	struct fts_mail *fmail;

	if (fbox == NULL)
		return;

	fmail = p_new(mail->pool, struct fts_mail, 1);
	fmail->module_ctx.super = *v;
	mail->vlast = &fmail->module_ctx.super;
	fmail->virtual_mail = _mail->box->virtual_vfuncs != NULL;

	v->get_special = fts_mail_get_special;
	v->precache = fts_mail_precache;
	MODULE_CONTEXT_SET(mail, fts_mail_module, fmail);
}
コード例 #11
0
ファイル: fts-storage.c プロジェクト: Raffprta/core
static int
fts_mailbox_get_status(struct mailbox *box, enum mailbox_status_items items,
		       struct mailbox_status *status_r)
{
	struct fts_mailbox *fbox = FTS_CONTEXT(box);
	uint32_t seq;

	if (fbox->module_ctx.super.get_status(box, items, status_r) < 0)
		return -1;

	if ((items & STATUS_LAST_CACHED_SEQ) != 0) {
		if (fts_mailbox_get_last_cached_seq(box, &seq) < 0)
			return -1;

		/* use whichever is smaller */
		if (status_r->last_cached_seq > seq)
			status_r->last_cached_seq = seq;
	}
	return 0;
}
コード例 #12
0
ファイル: fts-storage.c プロジェクト: Raffprta/core
static void fts_mail_index(struct mail *_mail)
{
	struct fts_transaction_context *ft = FTS_CONTEXT(_mail->transaction);
	struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(_mail->box->list);

	if (ft->failed)
		return;

	if (!ft->precached) {
		if (fts_mail_precache_init(_mail) < 0) {
			ft->failed = TRUE;
			return;
		}
	}
	if (ft->next_index_seq < _mail->seq) {
		/* most likely a virtual mailbox. we'll first need to
		   index all mails up to the current one. */
		fts_backend_update_set_mailbox(flist->update_ctx, _mail->box);
		if (fts_mail_precache_range(_mail->transaction,
					    flist->update_ctx,
					    ft->next_index_seq,
					    _mail->seq-1) < 0) {
			ft->failed = TRUE;
			return;
		}
	}

	if (ft->next_index_seq == _mail->seq) {
		fts_backend_update_set_mailbox(flist->update_ctx, _mail->box);
		if (fts_build_mail(flist->update_ctx, _mail) < 0) {
			mail_storage_set_internal_error(_mail->box->storage);
			ft->failed = TRUE;
		}
		ft->next_index_seq = _mail->seq + 1;
	}
}
コード例 #13
0
ファイル: fts-storage.c プロジェクト: Raffprta/core
static void
fts_search_apply_results_level(struct mail_search_context *ctx,
			       struct mail_search_arg *args, unsigned int *idx)
{
	struct fts_search_context *fctx = FTS_CONTEXT(ctx);
	const struct fts_search_level *level;

	level = array_idx(&fctx->levels, *idx);

	if (array_is_created(&level->definite_seqs) &&
	    seq_range_exists(&level->definite_seqs, ctx->seq))
		fts_search_deserialize_add_matches(args, level->args_matches);
	else if (!array_is_created(&level->maybe_seqs) ||
		 !seq_range_exists(&level->maybe_seqs, ctx->seq))
		fts_search_deserialize_add_nonmatches(args, level->args_matches);

	for (; args != NULL; args = args->next) {
		if (args->type != SEARCH_OR && args->type != SEARCH_SUB)
			continue;

		*idx += 1;
		fts_search_apply_results_level(ctx, args->value.subargs, idx);
	}
}