dovecot-2.2: dsync: Optimization for a large number of mails wit...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Mar 27 12:25:40 UTC 2014
details: http://hg.dovecot.org/dovecot-2.2/rev/ea737947fac8
changeset: 17174:ea737947fac8
user: Timo Sirainen <tss at iki.fi>
date: Thu Mar 27 13:25:12 2014 +0100
description:
dsync: Optimization for a large number of mails with the same GUID.
Still not ideal, but better than before.
diffstat:
src/doveadm/dsync/dsync-mailbox-import.c | 30 ++++++++++++++++++++----------
1 files changed, 20 insertions(+), 10 deletions(-)
diffs (85 lines):
diff -r b697a214e122 -r ea737947fac8 src/doveadm/dsync/dsync-mailbox-import.c
--- a/src/doveadm/dsync/dsync-mailbox-import.c Thu Mar 27 10:02:08 2014 +0100
+++ b/src/doveadm/dsync/dsync-mailbox-import.c Thu Mar 27 13:25:12 2014 +0100
@@ -616,7 +616,10 @@
}
}
/* 1) add the newmail to the end of the linked list
- 2) find our link */
+ 2) find our link
+
+ FIXME: this loop is slow if the same GUID has a ton of instances.
+ Could it be improved in some way? */
last = &first_mail->next;
for (mail = first_mail; mail != NULL; mail = mail->next) {
if (mail->final_uid == newmail->final_uid)
@@ -1877,20 +1880,22 @@
static int
dsync_msg_try_copy(struct dsync_mailbox_importer *importer,
struct mail_save_context **save_ctx_p,
- struct importer_new_mail *all_newmails)
+ struct importer_new_mail **all_newmails_forcopy)
{
struct importer_new_mail *inst;
- for (inst = all_newmails; inst != NULL; inst = inst->next) {
+ for (inst = *all_newmails_forcopy; inst != NULL; inst = inst->next) {
if (inst->uid_in_local && !inst->copy_failed &&
mail_set_uid(importer->mail, inst->local_uid)) {
if (mailbox_copy(save_ctx_p, importer->mail) < 0) {
inst->copy_failed = TRUE;
return -1;
}
+ *all_newmails_forcopy = inst;
return 1;
}
}
+ *all_newmails_forcopy = NULL;
return 0;
}
@@ -1914,10 +1919,11 @@
return save_ctx;
}
-static void dsync_mailbox_save_body(struct dsync_mailbox_importer *importer,
- const struct dsync_mail *mail,
- struct importer_new_mail *newmail,
- struct importer_new_mail *all_newmails)
+static void
+dsync_mailbox_save_body(struct dsync_mailbox_importer *importer,
+ const struct dsync_mail *mail,
+ struct importer_new_mail *newmail,
+ struct importer_new_mail **all_newmails_forcopy)
{
struct mail_save_context *save_ctx;
ssize_t ret;
@@ -1925,7 +1931,7 @@
/* try to save the mail by copying an existing mail */
save_ctx = dsync_mailbox_save_init(importer, mail, newmail);
- if ((ret = dsync_msg_try_copy(importer, &save_ctx, all_newmails)) < 0) {
+ if ((ret = dsync_msg_try_copy(importer, &save_ctx, all_newmails_forcopy)) < 0) {
if (save_ctx == NULL)
save_ctx = dsync_mailbox_save_init(importer, mail, newmail);
}
@@ -2000,13 +2006,17 @@
const struct dsync_mail *mail,
struct importer_new_mail *all_newmails)
{
- struct importer_new_mail *newmail;
+ struct importer_new_mail *newmail, *all_newmails_forcopy;
+
+ /* if all_newmails list is large, avoid scanning through the
+ uninteresting ones for each newmail */
+ all_newmails_forcopy = all_newmails;
/* save all instances of the message */
for (newmail = all_newmails; newmail != NULL; newmail = newmail->next) {
if (!newmail->skip) T_BEGIN {
dsync_mailbox_save_body(importer, mail, newmail,
- all_newmails);
+ &all_newmails_forcopy);
} T_END;
}
}
More information about the dovecot-cvs
mailing list