[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[SCM] GNU Mailutils branch, master, updated. release-2.2-551-gd16a3de
From: |
Sergey Poznyakoff |
Subject: |
[SCM] GNU Mailutils branch, master, updated. release-2.2-551-gd16a3de |
Date: |
Mon, 26 Dec 2011 08:49:00 +0000 |
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Mailutils".
http://git.savannah.gnu.org/cgit/mailutils.git/commit/?id=d16a3de50d8c43f7b45f18db1704fa784ee4cb7b
The branch, master has been updated
via d16a3de50d8c43f7b45f18db1704fa784ee4cb7b (commit)
from babd0be48657946dcf3589060b707dd3cfe0844c (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit d16a3de50d8c43f7b45f18db1704fa784ee4cb7b
Author: Sergey Poznyakoff <address@hidden>
Date: Sun Dec 25 11:00:12 2011 +0200
imap mbox: minor improvements.
* libproto/imap/mbox.c: Add some debugging messages.
(_imap_mbx_gensync): New function shared among _imap_mbx_sync and
_imap_mbx_expunge. It aggregates message numbers with same flags
to separate message sets, thereby reducing the number of STORE
commands sent to the server.
-----------------------------------------------------------------------
Summary of changes:
libproto/imap/mbox.c | 240 +++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 199 insertions(+), 41 deletions(-)
diff --git a/libproto/imap/mbox.c b/libproto/imap/mbox.c
index 934551a..609c86c 100644
--- a/libproto/imap/mbox.c
+++ b/libproto/imap/mbox.c
@@ -157,7 +157,9 @@ __imap_msg_get_stream (struct _mu_imap_message *imsg,
size_t msgno,
if (!(imsg->flags & _MU_IMAP_MSG_CACHED))
{
char *msgset;
-
+
+ mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
+ (_("caching message %lu"), (unsigned long) msgno));
if (!imbx->cache)
{
rc = mu_temp_file_stream_create (&imbx->cache, NULL, 0);
@@ -183,7 +185,14 @@ __imap_msg_get_stream (struct _mu_imap_message *imsg,
size_t msgno,
_save_message, &clos);
free (msgset);
if (rc == 0 && !_imap_mbx_errno (imbx))
- imsg->message_size = clos.size;
+ {
+ mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
+ (_("cached message %lu: offset=%lu, size=%lu"),
+ (unsigned long) msgno,
+ (unsigned long) imsg->offset,
+ (unsigned long) clos.size));
+ imsg->message_size = clos.size;
+ }
}
if (rc)
@@ -360,6 +369,9 @@ _imap_hdr_fill (void *data, char **pbuf, size_t *plen)
rc = mu_asprintf (&msgset, "%lu", msgno);
if (rc == 0)
{
+ mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
+ (_("message %lu: reading headers"),
+ (unsigned long) msgno));
rc = _imap_fetch_with_callback (imap, msgset, "BODY.PEEK[HEADER]",
_save_message, &clos);
free (msgset);
@@ -720,6 +732,8 @@ _imap_mbx_open (mu_mailbox_t mbox, int flags)
rc = mu_mailbox_get_url (mbox, &url);
if (rc)
return rc;
+ mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
+ (_("opening mailbox %s"), mu_url_to_string (url)));
rc = mu_url_sget_path (url, &mbox_name);
if (rc == MU_ERR_NOENT)
mbox_name = "INBOX";
@@ -758,6 +772,8 @@ _imap_mbx_close (mu_mailbox_t mbox)
mu_folder_t folder = mbox->folder;
mu_imap_t imap = folder->data;
+ mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
+ (_("closing mailbox %s"), mu_url_to_string (mbox->url)));
if (mu_imap_capability_test (imap, "UNSELECT", NULL) == 0)
rc = mu_imap_unselect (imap);
else
@@ -820,76 +836,216 @@ _imap_uidvalidity (mu_mailbox_t mbox, unsigned long *pn)
return 0;
}
+struct attr_tab
+{
+ size_t start;
+ size_t end;
+ int attr_flags;
+};
+
static int
-_imap_mbx_expunge (mu_mailbox_t mbox)
+attr_tab_cmp (void const *a, void const *b)
{
- struct _mu_imap_mailbox *imbx = mbox->data;
- mu_folder_t folder = mbox->folder;
- mu_imap_t imap = folder->data;
- size_t i;
- char *msgset;
- int rc;
- int delflg = 0;
+ struct attr_tab const *ta = a;
+ struct attr_tab const *tb = b;
+
+ if (ta->attr_flags < tb->attr_flags)
+ return -1;
+ else if (ta->attr_flags > tb->attr_flags)
+ return 1;
+
+ if (ta->start < tb->start)
+ return -1;
+ else if (ta->start > tb->start)
+ return 1;
+ return 0;
+}
+
+static int
+aggregate_attributes (struct _mu_imap_mailbox *imbx,
+ struct attr_tab **ptab, size_t *pcnt)
+{
+ size_t i, j;
+ size_t count;
+ struct attr_tab *tab;
+ /* Pass 1: Count modified attributes */
+ count = 0;
for (i = 0; i < imbx->msgs_cnt; i++)
{
if (imbx->msgs[i].flags & _MU_IMAP_MSG_ATTRCHG)
+ count++;
+ }
+
+ if (count == 0)
+ {
+ *ptab = NULL;
+ *pcnt = 0;
+ return 0;
+ }
+
+ /* Pass 2: Create and populate expanded array */
+ tab = calloc (count, sizeof (*tab));
+ if (!tab)
+ return ENOMEM;
+ for (i = j = 0; i < imbx->msgs_cnt; i++)
+ {
+ if (imbx->msgs[i].flags & _MU_IMAP_MSG_ATTRCHG)
{
- rc = mu_asprintf (&msgset, "%lu", i + 1);
- if (rc)
- break;
- rc = mu_imap_store_flags (imap, 0, msgset,
- MU_IMAP_STORE_SET|MU_IMAP_STORE_SILENT,
- imbx->msgs[i].attr_flags);
- delflg |= imbx->msgs[i].attr_flags & MU_ATTRIBUTE_DELETED;
- free (msgset);
- if (rc)
- break;
+ tab[j].start = tab[j].end = i;
+ tab[j].attr_flags = imbx->msgs[i].attr_flags;
+ j++;
}
}
+
+ /* Sort the array */
+ qsort (tab, count, sizeof (tab[0]), attr_tab_cmp);
- if (rc)
- return rc;
+ /* Pass 3: Coalesce message ranges */
+ for (i = j = 0; i < count; i++)
+ {
+ if (i == j)
+ continue;
+ else if ((tab[i].attr_flags == tab[j].attr_flags) &&
+ (tab[i].start == tab[j].end + 1))
+ tab[j].end++;
+ else
+ tab[++j] = tab[i];
+ }
- if (delflg)
- rc = mu_imap_expunge (imap);
-
+ *ptab = tab;
+ *pcnt = j + 1;
+ return 0;
+}
+
+static int
+flush_attributes (mu_imap_t imap, mu_stream_t str, int attr_flags)
+{
+ int rc;
+ mu_transport_t trans[2];
+
+ mu_stream_write (str, "", 1, NULL);
+ if (mu_stream_err (str))
+ return mu_stream_last_error (str);
+
+ rc = mu_stream_ioctl (str, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET, trans);
+ if (rc == 0)
+ rc = mu_imap_store_flags (imap, 0, (char*)trans[0],
+ MU_IMAP_STORE_SET|MU_IMAP_STORE_SILENT,
+ attr_flags);
return rc;
}
static int
-_imap_mbx_sync (mu_mailbox_t mbox)
+_imap_mbx_gensync (mu_mailbox_t mbox, int *pdel)
{
struct _mu_imap_mailbox *imbx = mbox->data;
mu_folder_t folder = mbox->folder;
mu_imap_t imap = folder->data;
- size_t i;
+ size_t i, j;
char *msgset;
int rc;
+ int delflg = 0;
+ struct attr_tab *tab;
+ size_t count;
- if (!imbx->msgs)
- return 0;
-
- for (i = 0; i < imbx->msgs_cnt; i++)
+ rc = aggregate_attributes (imbx, &tab, &count);
+ if (rc)
{
- if (imbx->msgs[i].flags & _MU_IMAP_MSG_ATTRCHG)
+ /* Too bad, but try to use naive approach */
+ for (i = 0; i < imbx->msgs_cnt; i++)
{
- rc = mu_asprintf (&msgset, "%lu", i + 1);
- if (rc)
- break;
- rc = mu_imap_store_flags (imap, 0, msgset,
- MU_IMAP_STORE_SET|MU_IMAP_STORE_SILENT,
- imbx->msgs[i].attr_flags);
- free (msgset);
- if (rc)
- break;
+ if (imbx->msgs[i].flags & _MU_IMAP_MSG_ATTRCHG)
+ {
+ rc = mu_asprintf (&msgset, "%lu", i + 1);
+ if (rc)
+ break;
+ rc = mu_imap_store_flags (imap, 0, msgset,
+ MU_IMAP_STORE_SET|MU_IMAP_STORE_SILENT,
+ imbx->msgs[i].attr_flags);
+ delflg |= imbx->msgs[i].attr_flags & MU_ATTRIBUTE_DELETED;
+ free (msgset);
+ if (rc)
+ break;
+ }
}
}
+ else
+ {
+ mu_stream_t str;
+
+ rc = mu_memory_stream_create (&str, MU_STREAM_RDWR);
+ if (rc == 0)
+ {
+ for (i = j = 0; i < count; i++)
+ {
+ if (j < i)
+ {
+ if (tab[j].attr_flags != tab[i].attr_flags)
+ {
+ rc = flush_attributes (imap, str, tab[j].attr_flags);
+ delflg |= tab[j].attr_flags & MU_ATTRIBUTE_DELETED;
+ if (rc)
+ break;
+ mu_stream_truncate (str, 0);
+ j = i;
+ }
+ else
+ mu_stream_printf (str, ",");
+ }
+ if (tab[i].end == tab[i].start)
+ mu_stream_printf (str, "%lu", (unsigned long)tab[i].start+1);
+ else
+ mu_stream_printf (str, "%lu:%lu",
+ (unsigned long)tab[i].start+1,
+ (unsigned long)tab[i].end+1);
+ }
+
+ if (j < i)
+ {
+ rc = flush_attributes (imap, str, tab[j].attr_flags);
+ delflg |= tab[j].attr_flags & MU_ATTRIBUTE_DELETED;
+ }
+ mu_stream_unref (str);
+ }
+ free (tab);
+ }
+
+ if (rc)
+ return rc;
+
+ if (pdel)
+ *pdel = delflg;
+
+ return 0;
+}
+
+static int
+_imap_mbx_expunge (mu_mailbox_t mbox)
+{
+ int rc, del = 0;
+ mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
+ (_("expunging mailbox %s"), mu_url_to_string (mbox->url)));
+ rc = _imap_mbx_gensync (mbox, &del);
+ if (rc == 0 && del)
+ {
+ mu_folder_t folder = mbox->folder;
+ mu_imap_t imap = folder->data;
+ rc = mu_imap_expunge (imap);
+ }
return rc;
}
static int
+_imap_mbx_sync (mu_mailbox_t mbox)
+{
+ mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
+ (_("synchronizing mailbox %s"), mu_url_to_string (mbox->url)));
+ return _imap_mbx_gensync (mbox, NULL);
+}
+
+static int
_imap_mbx_append_message (mu_mailbox_t mbox, mu_message_t msg)
{
int rc;
@@ -1030,6 +1186,8 @@ _imap_mbx_scan (mu_mailbox_t mbox, size_t msgno, size_t
*pcount)
int rc;
static char _imap_scan_items[] = "(UID FLAGS ENVELOPE RFC822.SIZE BODY)";
+ mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
+ (_("scanning mailbox %s"), mu_url_to_string (mbox->url)));
rc = mu_asprintf (&msgset, "%lu:*", (unsigned long) msgno);
if (rc)
return rc;
hooks/post-receive
--
GNU Mailutils
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [SCM] GNU Mailutils branch, master, updated. release-2.2-551-gd16a3de,
Sergey Poznyakoff <=