static void mail_thread_clear(struct mail_thread_context *ctx);
static int
-mail_strmap_rec_get_msgid(struct mail_thread_context *ctx,
+mail_strmap_rec_get_msgid(struct mail *mail,
const struct mail_index_strmap_rec *rec,
const char **msgid_r)
{
unsigned int n = 0;
int ret;
- if (!mail_set_uid(ctx->tmp_mail, rec->uid))
+ if (!mail_set_uid(mail, rec->uid))
return 0;
switch (rec->ref_index) {
case MAIL_THREAD_NODE_REF_MSGID:
/* Message-ID: header */
- ret = mail_get_first_header(ctx->tmp_mail, HDR_MESSAGE_ID,
- &msgids);
+ ret = mail_get_first_header(mail, HDR_MESSAGE_ID, &msgids);
break;
case MAIL_THREAD_NODE_REF_INREPLYTO:
/* In-Reply-To: header */
- ret = mail_get_first_header(ctx->tmp_mail, HDR_IN_REPLY_TO,
- &msgids);
+ ret = mail_get_first_header(mail, HDR_IN_REPLY_TO, &msgids);
break;
default:
/* References: header */
- ret = mail_get_first_header(ctx->tmp_mail, HDR_REFERENCES,
- &msgids);
+ ret = mail_get_first_header(mail, HDR_REFERENCES, &msgids);
n = rec->ref_index - MAIL_THREAD_NODE_REF_REFERENCES1;
break;
}
if (ret < 0) {
- if (ctx->tmp_mail->expunged) {
+ if (mail->expunged) {
/* treat it as if it didn't exist. trying to add it
again will result in failure. */
return 0;
if (msgid == NULL) {
/* shouldn't have happened */
- mail_storage_set_critical(ctx->box->storage,
+ mail_storage_set_critical(mail->box->storage,
"Threading lost Message ID");
return -1;
}
/* either a match or a collision, need to look closer */
T_BEGIN {
- ret = mail_strmap_rec_get_msgid(ctx, rec, &msgid);
+ ret = mail_strmap_rec_get_msgid(ctx->tmp_mail, rec, &msgid);
if (ret <= 0) {
if (ret < 0)
ctx->failed = TRUE;
int ret;
T_BEGIN {
- ret = mail_strmap_rec_get_msgid(ctx, rec1, &msgid1);
+ ret = mail_strmap_rec_get_msgid(ctx->tmp_mail, rec1, &msgid1);
if (ret > 0) {
msgid1 = t_strdup(msgid1);
- ret = mail_strmap_rec_get_msgid(ctx, rec2, &msgid2);
+ ret = mail_strmap_rec_get_msgid(ctx->tmp_mail, rec2,
+ &msgid2);
}
ret = ret <= 0 ? -1 :
strcmp(msgid1, msgid2) == 0;
&tbox->msgid_hash);
}
- ctx->t = mailbox_transaction_begin(ctx->box, 0);
headers_ctx = mailbox_header_lookup_init(ctx->box, wanted_headers);
ctx->tmp_mail = mail_alloc(ctx->t, 0, headers_ctx);
mailbox_search_result_free(&cache->search_result);
}
-static int mail_thread_cache_sync_add(struct mail_thread_mailbox *tbox,
- struct mail_thread_context *ctx)
+static void mail_thread_cache_sync_add(struct mail_thread_mailbox *tbox,
+ struct mail_thread_context *ctx,
+ struct mail_search_context *search_ctx)
{
struct mail_thread_cache *cache = tbox->cache;
- struct mail_search_context *search_ctx;
struct mail *mail;
const struct mail_index_strmap_rec *msgid_map;
unsigned int i, count;
/* we already checked at sync_remove that we can use this
search result. */
mail_thread_cache_update_adds(tbox, &ctx->added_uids);
- return 0;
+ return;
}
cache->last_uid = 0;
THREAD_INVALID_MSGID_STR_IDX_SKIP_COUNT;
array_clear(&cache->thread_nodes);
- search_ctx = mailbox_search_init(ctx->t, ctx->search_args, NULL);
mail = mail_alloc(ctx->t, 0, NULL);
cache->search_result =
mail_thread_add(cache, msgid_map+i, &i);
}
mail_free(&mail);
- return mailbox_search_deinit(&search_ctx);
}
int mail_thread_init(struct mailbox *box, struct mail_search_args *args,
{
struct mail_thread_mailbox *tbox = MAIL_THREAD_CONTEXT(box);
struct mail_thread_context *ctx;
+ struct mail_search_context *search_ctx;
+ int ret;
i_assert(tbox->ctx == NULL);
else {
args = mail_search_build_init();
mail_search_build_add_all(args);
- args->simplified = TRUE;
+ mail_search_args_init(args, box, FALSE, NULL);
}
ctx = i_new(struct mail_thread_context, 1);
- tbox->ctx = ctx;
ctx->box = box;
ctx->search_args = args;
+ ctx->t = mailbox_transaction_begin(ctx->box, 0);
+ /* perform search first, so we don't break if there are INTHREAD keys */
+ search_ctx = mailbox_search_init(ctx->t, args, NULL);
+
+ tbox->ctx = ctx;
mail_thread_cache_sync_remove(tbox, ctx);
- if (mail_thread_index_map_build(ctx) < 0 ||
- mail_thread_cache_sync_add(tbox, ctx) < 0) {
+ ret = mail_thread_index_map_build(ctx) < 0;
+ if (ret == 0)
+ mail_thread_cache_sync_add(tbox, ctx, search_ctx);
+ if (mailbox_search_deinit(&search_ctx) < 0)
+ ret = -1;
+
+ if (ret < 0) {
mail_thread_deinit(&ctx);
return -1;
+ } else {
+ memset(&ctx->added_uids, 0, sizeof(ctx->added_uids));
+ *ctx_r = ctx;
+ return 0;
}
- memset(&ctx->added_uids, 0, sizeof(ctx->added_uids));
-
- *ctx_r = ctx;
- return 0;
}
static void mail_thread_clear(struct mail_thread_context *ctx)
mail_thread_clear(ctx);
mail_search_args_unref(&ctx->search_args);
- tbox->ctx = NULL;
+ tbox->ctx = NULL;
i_free(ctx);
}