diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-12-28 14:37:37 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-12-28 14:37:37 +0200 |
commit | d85540094f0df7258af1cae7c61cc6d45c2a4f53 (patch) | |
tree | f7315477b24e65729cdce00c617281f5c5d48583 /libmailutils/base/amd.c | |
parent | 42838314448528fd390d93a0b07a0d3d2d9d312f (diff) | |
download | mailutils-d85540094f0df7258af1cae7c61cc6d45c2a4f53.tar.gz mailutils-d85540094f0df7258af1cae7c61cc6d45c2a4f53.tar.bz2 |
mh,maildir: speed up scanning.
* include/mailutils/sys/amd.h (_amd_message_append, amd_sort): New protos.
* libmailutils/base/amd.c (amd_array_expand): Call memmove only if there is
actually something to move.
(_amd_message_append, amd_sort): New functions.
* libproto/maildir/mbox.c (maildir_scan_dir): Append new messages to the
end of the array, and sort it afterwards. This avoids unnecessary memory
moves, which improves performance considerably, especially on large
mailboxes.
* libproto/mh/mbox.c (mh_scan0): Likewise.
Diffstat (limited to 'libmailutils/base/amd.c')
-rw-r--r-- | libmailutils/base/amd.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/libmailutils/base/amd.c b/libmailutils/base/amd.c index f77cf3a45..96d55cc39 100644 --- a/libmailutils/base/amd.c +++ b/libmailutils/base/amd.c @@ -241,8 +241,9 @@ amd_array_expand (struct _amd_data *amd, size_t index) } amd->msg_array = p; } - memmove (&amd->msg_array[index+1], &amd->msg_array[index], - (amd->msg_count-index) * amd->msg_size); + if (amd->msg_count > index) + memmove (&amd->msg_array[index+1], &amd->msg_array[index], + (amd->msg_count-index) * amd->msg_size); amd->msg_count++; return 0; } @@ -1381,6 +1382,35 @@ _amd_message_insert (struct _amd_data *amd, struct _amd_message *msg) return 0; } +/* Append message to the end of the array, expanding it if necessary */ +int +_amd_message_append (struct _amd_data *amd, struct _amd_message *msg) +{ + size_t index = amd->msg_count; + int rc = amd_array_expand (amd, index); + if (rc) + return rc; + amd->msg_array[index] = msg; + msg->amd = amd; + return 0; +} + +static int +msg_array_comp (const void *a, const void *b) +{ + struct _amd_message **ma = (struct _amd_message **) a; + struct _amd_message **mb = (struct _amd_message **) b; + struct _amd_data *amd = (*ma)->amd; + return amd->msg_cmp (*ma, *mb); +} + +void +amd_sort (struct _amd_data *amd) +{ + qsort (amd->msg_array, amd->msg_count, sizeof (amd->msg_array[0]), + msg_array_comp); +} + static void _amd_message_delete (struct _amd_data *amd, struct _amd_message *msg) { |