#include "mail-user.h"
#include "mail-storage-private.h"
#include "fts-api.h"
+#include "fts-storage.h"
#include "fts-indexer.h"
#define INDEXER_NOTIFY_INTERVAL_SECS 10
{
struct ioloop *prev_ioloop = current_ioloop;
struct fts_indexer_context *ctx;
- struct mailbox_status status;
uint32_t last_uid, seq1, seq2;
const char *path, *value, *error;
unsigned int timeout_secs = 0;
}
}
- if (fts_backend_get_last_uid(backend, box, &last_uid) < 0)
+ ret = fts_search_get_first_missing_uid(backend, box, &last_uid);
+ if (ret < 0)
return -1;
-
- mailbox_get_open_status(box, STATUS_UIDNEXT, &status);
- if (status.uidnext == last_uid+1) {
+ if (ret > 0) {
/* everything is already indexed */
return 0;
}
TRUE, &fctx->scores->score_map);
}
+int fts_search_get_first_missing_uid(struct fts_backend *backend,
+ struct mailbox *box,
+ uint32_t *last_indexed_uid_r)
+{
+ uint32_t messages_count = mail_index_view_get_messages_count(box->view);
+ uint32_t uid, last_indexed_uid;
+ int ret;
+
+ if (messages_count == 0)
+ return 1;
+
+ mail_index_lookup_uid(box->view, messages_count, &uid);
+ for (bool refreshed = FALSE;; refreshed = TRUE) {
+ ret = fts_backend_is_uid_indexed(backend, box, uid,
+ &last_indexed_uid);
+ if (ret != 0)
+ return ret;
+ if (refreshed || backend->updating) {
+ *last_indexed_uid_r = last_indexed_uid;
+ return 0;
+ }
+
+ /* UID doesn't seem to be indexed yet.
+ Refresh FTS and check again. */
+ if (fts_backend_refresh(backend) < 0)
+ return -1;
+ }
+ i_unreached();
+}
+
static void fts_search_try_lookup(struct fts_search_context *fctx)
{
uint32_t last_uid, seq1, seq2;
+ int ret;
i_assert(array_count(&fctx->levels) == 0);
i_assert(fctx->args->simplified);
- if (fts_backend_refresh(fctx->backend) < 0)
- return;
- if (fts_backend_get_last_uid(fctx->backend, fctx->box, &last_uid) < 0)
+ ret = fts_search_get_first_missing_uid(fctx->backend, fctx->box,
+ &last_uid);
+ if (ret < 0)
return;
- mailbox_get_seq_range(fctx->box, last_uid+1, (uint32_t)-1,
- &seq1, &seq2);
+
+ if (ret > 0) {
+ /* everything is already indexed */
+ seq1 = seq2 = 0;
+ } else {
+ mailbox_get_seq_range(fctx->box, last_uid+1, (uint32_t)-1,
+ &seq1, &seq2);
+ }
fctx->first_unindexed_seq = seq1 != 0 ? seq1 : (uint32_t)-1;
if (fctx->virtual_mailbox) {
{
struct fts_mailbox_list *flist = FTS_LIST_CONTEXT_REQUIRE(box->list);
uint32_t seq1, seq2, last_uid;
+ int ret;
- if (fts_backend_get_last_uid(flist->backend, box, &last_uid) < 0) {
+ ret = fts_search_get_first_missing_uid(flist->backend, box, &last_uid);
+ if (ret < 0) {
mail_storage_set_internal_error(box->storage);
return -1;
}
- if (last_uid == 0)
+ if (ret == 0 && last_uid == 0) {
+ /* nothing is indexed. */
*seq_r = 0;
- else {
+ } else {
+ if (ret > 0) {
+ /* everything is indexed */
+ last_uid = (uint32_t)-1;
+ }
mailbox_get_seq_range(box, 1, last_uid, &seq1, &seq2);
*seq_r = seq2;
}
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);
+/* Returns 1 if everything is already indexed, 0 if not, -1 on error. */
+int fts_search_get_first_missing_uid(struct fts_backend *backend,
+ struct mailbox *box,
+ uint32_t *last_indexed_uid_r);
/* Returns FTS backend for the given mailbox (assumes it has one). */
struct fts_backend *fts_mailbox_backend(struct mailbox *box);
/* Returns FTS backend for the given mailbox list, or NULL if it has none. */