static int fts_mail_precache_range(struct mailbox_transaction_context *trans, struct fts_backend_update_context *update_ctx, uint32_t seq1, uint32_t seq2) { struct mail_search_args *search_args; struct mail_search_context *ctx; struct mail *mail; int ret = 0; search_args = mail_search_build_init(); mail_search_build_add_seqset(search_args, seq1, seq2); ctx = mailbox_search_init(trans, search_args, NULL, MAIL_FETCH_STREAM_HEADER | MAIL_FETCH_STREAM_BODY, NULL); mail_search_args_unref(&search_args); while (mailbox_search_next(ctx, &mail)) { if (fts_build_mail(update_ctx, mail) < 0) { mail_storage_set_internal_error(trans->box->storage); ret = -1; break; } mail_precache(mail); } if (mailbox_search_deinit(&ctx) < 0) ret = -1; return ret; }
static int index_mailbox_precache(struct master_connection *conn, struct mailbox *box) { struct mail_storage *storage = mailbox_get_storage(box); const char *username = mail_storage_get_user(storage)->username; const char *box_vname = mailbox_get_vname(box); struct mailbox_status status; struct mailbox_transaction_context *trans; struct mail_search_args *search_args; struct mail_search_context *ctx; struct mail *mail; struct mailbox_metadata metadata; uint32_t seq; char percentage_str[2+1+1]; unsigned int counter = 0, max, percentage, percentage_sent = 0; int ret = 0; if (mailbox_get_metadata(box, MAILBOX_METADATA_PRECACHE_FIELDS, &metadata) < 0 || mailbox_get_status(box, STATUS_MESSAGES | STATUS_LAST_CACHED_SEQ, &status) < 0) return -1; seq = status.last_cached_seq + 1; trans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC); search_args = mail_search_build_init(); mail_search_build_add_seqset(search_args, seq, status.messages); ctx = mailbox_search_init(trans, search_args, NULL, metadata.precache_fields, NULL); mail_search_args_unref(&search_args); max = status.messages - seq + 1; while (mailbox_search_next(ctx, &mail)) { mail_precache(mail); if (++counter % 100 == 0) { percentage = counter*100 / max; if (percentage != percentage_sent && percentage < 100) { percentage_sent = percentage; if (i_snprintf(percentage_str, sizeof(percentage_str), "%u\n", percentage) < 0) i_unreached(); (void)write_full(conn->fd, percentage_str, strlen(percentage_str)); } indexer_worker_refresh_proctitle(username, box_vname, counter, max); } } if (mailbox_search_deinit(&ctx) < 0) ret = -1; if (mailbox_transaction_commit(&trans) < 0) ret = -1; if (ret == 0) { i_info("Indexed %u messages in %s", counter, mailbox_get_vname(box)); } return ret; }
static int index_mailbox_precache(struct master_connection *conn, struct mailbox *box) { struct mail_storage *storage = mailbox_get_storage(box); const char *username = mail_storage_get_user(storage)->username; const char *box_vname = mailbox_get_vname(box); struct mailbox_status status; struct mailbox_transaction_context *trans; struct mail_search_args *search_args; struct mail_search_context *ctx; struct mail *mail; struct mailbox_metadata metadata; uint32_t seq, first_uid = 0, last_uid = 0; char percentage_str[2+1+1]; unsigned int counter = 0, max, percentage, percentage_sent = 0; int ret = 0; if (mailbox_get_metadata(box, MAILBOX_METADATA_PRECACHE_FIELDS, &metadata) < 0) { i_error("Mailbox %s: Precache-fields lookup failed: %s", mailbox_get_vname(box), mailbox_get_last_internal_error(box, NULL)); return -1; } if (mailbox_get_status(box, STATUS_MESSAGES | STATUS_LAST_CACHED_SEQ, &status) < 0) { i_error("Mailbox %s: Status lookup failed: %s", mailbox_get_vname(box), mailbox_get_last_internal_error(box, NULL)); return -1; } seq = status.last_cached_seq + 1; trans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC, "indexing"); search_args = mail_search_build_init(); mail_search_build_add_seqset(search_args, seq, status.messages); ctx = mailbox_search_init(trans, search_args, NULL, metadata.precache_fields, NULL); mail_search_args_unref(&search_args); max = status.messages + 1 - seq; while (mailbox_search_next(ctx, &mail)) { if (first_uid == 0) first_uid = mail->uid; last_uid = mail->uid; mail_precache(mail); if (++counter % 100 == 0) { percentage = counter*100 / max; if (percentage != percentage_sent && percentage < 100) { percentage_sent = percentage; if (i_snprintf(percentage_str, sizeof(percentage_str), "%u\n", percentage) < 0) i_unreached(); (void)write_full(conn->fd, percentage_str, strlen(percentage_str)); } indexer_worker_refresh_proctitle(username, box_vname, counter, max); } } if (mailbox_search_deinit(&ctx) < 0) { i_error("Mailbox %s: Mail search failed: %s", mailbox_get_vname(box), mailbox_get_last_internal_error(box, NULL)); ret = -1; } const char *uids = first_uid == 0 ? "" : t_strdup_printf(" (UIDs %u..%u)", first_uid, last_uid); if (mailbox_transaction_commit(&trans) < 0) { i_error("Mailbox %s: Transaction commit failed: %s" " (attempted to index %u messages%s)", mailbox_get_vname(box), mailbox_get_last_internal_error(box, NULL), counter, uids); ret = -1; } else { i_info("Indexed %u messages in %s%s", counter, mailbox_get_vname(box), uids); } return ret; }