From: Timo Sirainen Date: Mon, 29 Nov 2021 14:46:04 +0000 (+0100) Subject: lib-storage: Delay creating mail event until mail_event() is called X-Git-Tag: 2.3.18~50 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=165be3edb6e178ce0120b4d32473f08b4c1465cd;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Delay creating mail event until mail_event() is called Mails can be accessed a lot. The event handling code takes up a lot of CPU, but most of the time the created event wasn't actually used for anything. --- diff --git a/src/lib-storage/index/index-mail.c b/src/lib-storage/index/index-mail.c index ff2ed246ca..238c95b1fb 100644 --- a/src/lib-storage/index/index-mail.c +++ b/src/lib-storage/index/index-mail.c @@ -1753,14 +1753,6 @@ index_mail_alloc(struct mailbox_transaction_context *t, return &mail->mail.mail; } -static void index_mail_init_event(struct mail *mail) -{ - struct mail_private *p = (struct mail_private *)mail; - - p->_event = event_create(mail->box->event); - event_add_category(p->_event, &event_category_mail); -} - void index_mail_init(struct index_mail *mail, struct mailbox_transaction_context *t, enum mail_fetch_field wanted_fields, @@ -1775,7 +1767,6 @@ void index_mail_init(struct index_mail *mail, mail->mail.v = *t->box->mail_vfuncs; mail->mail.mail.box = t->box; mail->mail.mail.transaction = t; - index_mail_init_event(&mail->mail.mail); t->mail_ref_count++; if (data_pool != NULL) mail->mail.data_pool = data_pool; @@ -2115,36 +2106,9 @@ void index_mail_update_access_parts_post(struct mail *_mail) } } -static bool index_mail_get_age_days(struct mail *mail, int *days_r) -{ - int age_days; - const struct mail_index_header *hdr = - mail_index_get_header(mail->transaction->view); - int n_days = N_ELEMENTS(hdr->day_first_uid); - - for (age_days = 0; age_days < n_days; age_days++) { - if (mail->uid >= hdr->day_first_uid[age_days]) - break; - } - - if (age_days == n_days) { - /* mail is too old, cannot determine its age from - day_first_uid[]. */ - return FALSE; - } - - if (hdr->day_stamp != 0) { - /* offset for hdr->day_stamp */ - age_days += (ioloop_time - hdr->day_stamp) / (3600 * 24); - } - *days_r = age_days; - return TRUE; -} - void index_mail_set_seq(struct mail *_mail, uint32_t seq, bool saving) { struct index_mail *mail = INDEX_MAIL(_mail); - int age_days; if (mail->data.seq == seq) { if (!saving) @@ -2163,17 +2127,9 @@ void index_mail_set_seq(struct mail *_mail, uint32_t seq, bool saving) &mail->mail.mail.uid); /* Recreate the mail event when changing mails. Even though the same - mail struct is reused, they are practically different mails. */ - event_unref(&mail->mail._event); - index_mail_init_event(_mail); - event_add_int(mail->mail._event, "seq", _mail->seq); - event_add_int(mail->mail._event, "uid", _mail->uid); - /* Add mail age field to event. */ - if (index_mail_get_age_days(_mail, &age_days)) - event_add_int(mail->mail._event, "mail_age_days", age_days); - - event_set_append_log_prefix(mail->mail._event, t_strdup_printf( - "%sUID %u: ", saving ? "saving " : "", _mail->uid)); + mail struct is reused, they are practically different mails. The + event should have already been freed by close(). */ + i_assert(mail->mail._event == NULL); if (mail_index_view_is_inconsistent(_mail->transaction->view)) { mail_set_expunged(&mail->mail.mail); diff --git a/src/lib-storage/mail-storage-private.h b/src/lib-storage/mail-storage-private.h index f5f569c36e..bc462bbd22 100644 --- a/src/lib-storage/mail-storage-private.h +++ b/src/lib-storage/mail-storage-private.h @@ -578,6 +578,7 @@ struct mail_private { allows mail_log plugin to log the copy operation using the original mailbox name. */ struct mail *vmail; + /* Event is created lazily. Use mail_event() to access it. */ struct event *_event; uint32_t seq_pvt; diff --git a/src/lib-storage/mail-storage.h b/src/lib-storage/mail-storage.h index 17e724359e..64e0e49a34 100644 --- a/src/lib-storage/mail-storage.h +++ b/src/lib-storage/mail-storage.h @@ -871,7 +871,8 @@ void mail_add_temp_wanted_fields(struct mail *mail, struct mailbox_header_lookup_ctx *headers) ATTR_NULL(3); -/* Returns mail's event. */ +/* Returns mail's event. This lazily creates the event when called for the + first time for the mail. */ struct event *mail_event(struct mail *mail); /* Returns message's flags */ enum mail_flags mail_get_flags(struct mail *mail); diff --git a/src/lib-storage/mail.c b/src/lib-storage/mail.c index 366670330a..272db1e1e4 100644 --- a/src/lib-storage/mail.c +++ b/src/lib-storage/mail.c @@ -99,17 +99,56 @@ void mail_add_temp_wanted_fields(struct mail *mail, p->v.add_temp_wanted_fields(mail, fields, headers); } +static bool index_mail_get_age_days(struct mail *mail, int *days_r) +{ + int age_days; + const struct mail_index_header *hdr = + mail_index_get_header(mail->transaction->view); + int n_days = N_ELEMENTS(hdr->day_first_uid); + + for (age_days = 0; age_days < n_days; age_days++) { + if (mail->uid >= hdr->day_first_uid[age_days]) + break; + } + + if (age_days == n_days) { + /* mail is too old, cannot determine its age from + day_first_uid[]. */ + return FALSE; + } + + if (hdr->day_stamp != 0) { + /* offset for hdr->day_stamp */ + age_days += (ioloop_time - hdr->day_stamp) / (3600 * 24); + } + *days_r = age_days; + return TRUE; +} + void mail_event_create(struct mail *mail) { struct mail_private *p = (struct mail_private *)mail; + int age_days; + + if (p->_event != NULL) + return; + p->_event = event_create(mail->box->event); + event_add_category(p->_event, &event_category_mail); + event_add_int(p->_event, "seq", mail->seq); + event_add_int(p->_event, "uid", mail->uid); + /* Add mail age field to event. */ + if (index_mail_get_age_days(mail, &age_days)) + event_add_int(p->_event, "mail_age_days", age_days); - i_assert(p->_event != NULL); + event_set_append_log_prefix(p->_event, t_strdup_printf( + "%sUID %u: ", mail->saving ? "saving " : "", mail->uid)); } struct event *mail_event(struct mail *mail) { struct mail_private *p = (struct mail_private *)mail; + mail_event_create(mail); return p->_event; }