[mutt] 02/04: + performance improvements for imap and maildir open times backported from mutt head: * upstream/fast-imap-flag-handling.patch * upstream/imap-poll-timeout.patch * upstream/maildir-hash.patch

Antonio Radici antonio at moszumanska.debian.org
Tue Nov 21 22:11:32 UTC 2017


This is an automated email from the git hooks/post-receive script.

antonio pushed a commit to branch master
in repository mutt.

commit 7f2974bd1e4e05ebe882b9b412e92fd49f72806f
Author: Antonio Radici <antonio at debian.org>
Date:   Tue Nov 21 21:58:38 2017 +0000

    + performance improvements for imap and maildir open times backported from mutt head: * upstream/fast-imap-flag-handling.patch * upstream/imap-poll-timeout.patch * upstream/maildir-hash.patch
---
 debian/changelog                                   |   6 +
 debian/patches/series                              |   3 +
 .../patches/upstream/fast-imap-flag-handling.patch | 169 +++++++++++++++++++++
 debian/patches/upstream/imap-poll-timeout.patch    |  37 +++++
 debian/patches/upstream/maildir-hash.patch         |  74 +++++++++
 5 files changed, 289 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 64af5dd..57c1c27 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -3,6 +3,12 @@ mutt (1.9.1-2) UNRELEASED; urgency=medium
   * debian/patches:
     + upstream/749483-conststrings.patch: removed, already upstream, albeit in
       a different way
+    + performance improvements for imap and maildir open times backported from
+      mutt head:
+        * upstream/fast-imap-flag-handling.patch
+        * upstream/imap-poll-timeout.patch
+        * upstream/maildir-hash.patch
+
 
  -- Antonio Radici <antonio at debian.org>  Tue, 21 Nov 2017 21:51:31 +0000
 
diff --git a/debian/patches/series b/debian/patches/series
index 1921239..ef78fe4 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -10,3 +10,6 @@ misc/gpg.rc-paths.patch
 misc/smime.rc.patch
 upstream/528233-readonly-open.patch
 upstream/383769-score-match.patch
+upstream/fast-imap-flag-handling.patch
+upstream/imap-poll-timeout.patch
+upstream/maildir-hash.patch
diff --git a/debian/patches/upstream/fast-imap-flag-handling.patch b/debian/patches/upstream/fast-imap-flag-handling.patch
new file mode 100644
index 0000000..3d59bec
--- /dev/null
+++ b/debian/patches/upstream/fast-imap-flag-handling.patch
@@ -0,0 +1,169 @@
+# HG changeset patch
+# User Kevin McCarthy <kevin at 8t8.us>
+# Date 1506545136 25200
+#      Wed Sep 27 13:45:36 2017 -0700
+# Node ID e98ad54466409d7cd8bd75027ba0be73f7811750
+# Parent  cbe207b97a2adb151e368057ae6844c71fca433c
+Make cmd_parse_fetch() more precise about setting reopen/check flags.
+
+Previously any FETCH with FLAGS would result in either
+  idata->reopen |= IMAP_EXPUNGE_PENDING;
+  -or-
+  idata->check_status = IMAP_FLAGS_PENDING;
+being set.
+
+This is unnecessary in the case of responses to FLAGS.SILENT updates
+sent by mutt (which seem to commonly happen now-a-days).
+
+Change imap_set_flags() to compare the old server flags against the
+new ones, and report when _those_ updates would/did result in a local
+header flag change.  Only set one of the reopen/check_status flags in
+the event of an actual change (or potential change if a local change
+has been made to the header.)
+
+diff -r cbe207b97a2a -r e98ad5446640 imap/command.c
+--- a/imap/command.c	Tue Sep 26 19:45:23 2017 -0700
++++ b/imap/command.c	Wed Sep 27 13:45:36 2017 -0700
+@@ -652,6 +652,7 @@
+ {
+   unsigned int msn, uid;
+   HEADER *h;
++  int server_changes = 0;
+ 
+   dprint (3, (debugfile, "Handling FETCH\n"));
+ 
+@@ -687,13 +688,14 @@
+ 
+     if (ascii_strncasecmp ("FLAGS", s, 5) == 0)
+     {
+-      /* If server flags could conflict with mutt's flags, reopen the mailbox. */
+-      if (h->changed)
+-        idata->reopen |= IMAP_EXPUNGE_PENDING;
+-      else
++      imap_set_flags (idata, h, s, &server_changes);
++      if (server_changes)
+       {
+-        imap_set_flags (idata, h, s);
+-        idata->check_status = IMAP_FLAGS_PENDING;
++        /* If server flags could conflict with mutt's flags, reopen the mailbox. */
++        if (h->changed)
++          idata->reopen |= IMAP_EXPUNGE_PENDING;
++        else
++          idata->check_status = IMAP_FLAGS_PENDING;
+       }
+       return;
+     }
+diff -r cbe207b97a2a -r e98ad5446640 imap/imap_private.h
+--- a/imap/imap_private.h	Tue Sep 26 19:45:23 2017 -0700
++++ b/imap/imap_private.h	Wed Sep 27 13:45:36 2017 -0700
+@@ -269,7 +269,7 @@
+ void imap_add_keywords (char* s, HEADER* keywords, LIST* mailbox_flags, size_t slen);
+ void imap_free_header_data (IMAP_HEADER_DATA** data);
+ int imap_read_headers (IMAP_DATA* idata, unsigned int msn_begin, unsigned int msn_end);
+-char* imap_set_flags (IMAP_DATA* idata, HEADER* h, char* s);
++char* imap_set_flags (IMAP_DATA* idata, HEADER* h, char* s, int *server_changes);
+ int imap_cache_del (IMAP_DATA* idata, HEADER* h);
+ int imap_cache_clean (IMAP_DATA* idata);
+ 
+diff -r cbe207b97a2a -r e98ad5446640 imap/message.c
+--- a/imap/message.c	Tue Sep 26 19:45:23 2017 -0700
++++ b/imap/message.c	Wed Sep 27 13:45:36 2017 -0700
+@@ -652,7 +652,7 @@
+ 	 * incrementally update flags later, this won't stop us syncing */
+ 	else if ((ascii_strncasecmp ("FLAGS", pc, 5) == 0) && !h->changed)
+ 	{
+-	  if ((pc = imap_set_flags (idata, h, pc)) == NULL)
++	  if ((pc = imap_set_flags (idata, h, pc, NULL)) == NULL)
+ 	    goto bail;
+ 	}
+       }
+@@ -1183,19 +1183,55 @@
+   }
+ }
+ 
++/* Sets server_changes to 1 if a change to a flag is made, or in the
++ * case of local_changes, if a change to a flag _would_ have been
++ * made. */
++static void imap_set_changed_flag (CONTEXT *ctx, HEADER *h, int local_changes,
++                                   int *server_changes, int flag_name, int old_hd_flag,
++                                   int new_hd_flag, int h_flag)
++{
++  /* If there are local_changes, we only want to note if the server
++   * flags have changed, so we can set a reopen flag in
++   * cmd_parse_fetch().  We don't want to count a local modification
++   * to the header flag as a "change".
++   */
++  if ((old_hd_flag != new_hd_flag) || (!local_changes))
++  {
++    if (new_hd_flag != h_flag)
++    {
++      if (server_changes)
++        *server_changes = 1;
++
++      /* Local changes have priority */
++      if (!local_changes)
++        mutt_set_flag (ctx, h, flag_name, new_hd_flag);
++    }
++  }
++}
++
+ /* imap_set_flags: fill out the message header according to the flags from
+- *   the server. Expects a flags line of the form "FLAGS (flag flag ...)" */
+-char* imap_set_flags (IMAP_DATA* idata, HEADER* h, char* s)
++ * the server. Expects a flags line of the form "FLAGS (flag flag ...)"
++ *
++ * Sets server_changes to 1 if a change to a flag is made, or in the
++ * case of h->changed, if a change to a flag _would_ have been
++ * made. */
++char* imap_set_flags (IMAP_DATA* idata, HEADER* h, char* s, int *server_changes)
+ {
+   CONTEXT* ctx = idata->ctx;
+   IMAP_HEADER newh;
++  IMAP_HEADER_DATA old_hd;
+   IMAP_HEADER_DATA* hd;
+   unsigned char readonly;
++  int local_changes;
++
++  local_changes = h->changed;
+ 
+   memset (&newh, 0, sizeof (newh));
+   hd = h->data;
+   newh.data = hd;
+ 
++  memcpy (&old_hd, hd, sizeof(old_hd));
++
+   dprint (2, (debugfile, "imap_set_flags: parsing FLAGS\n"));
+   if ((s = msg_parse_flags (&newh, s)) == NULL)
+     return NULL;
+@@ -1207,16 +1243,24 @@
+   readonly = ctx->readonly;
+   ctx->readonly = 0;
+ 
+-  mutt_set_flag (ctx, h, MUTT_NEW, !(hd->read || hd->old));
+-  mutt_set_flag (ctx, h, MUTT_OLD, hd->old);
+-  mutt_set_flag (ctx, h, MUTT_READ, hd->read);
+-  mutt_set_flag (ctx, h, MUTT_DELETE, hd->deleted);
+-  mutt_set_flag (ctx, h, MUTT_FLAG, hd->flagged);
+-  mutt_set_flag (ctx, h, MUTT_REPLIED, hd->replied);
++  /* This is redundant with the following two checks. Removing:
++   * mutt_set_flag (ctx, h, MUTT_NEW, !(hd->read || hd->old));
++   */
++  imap_set_changed_flag (ctx, h, local_changes, server_changes,
++                         MUTT_OLD, old_hd.old, hd->old, h->old);
++  imap_set_changed_flag (ctx, h, local_changes, server_changes,
++                         MUTT_READ, old_hd.read, hd->read, h->read);
++  imap_set_changed_flag (ctx, h, local_changes, server_changes,
++                         MUTT_DELETE, old_hd.deleted, hd->deleted, h->deleted);
++  imap_set_changed_flag (ctx, h, local_changes, server_changes,
++                         MUTT_FLAG, old_hd.flagged, hd->flagged, h->flagged);
++  imap_set_changed_flag (ctx, h, local_changes, server_changes,
++                         MUTT_REPLIED, old_hd.replied, hd->replied, h->replied);
+ 
+   /* this message is now definitively *not* changed (mutt_set_flag
+    * marks things changed as a side-effect) */
+-  h->changed = 0;
++  if (!local_changes)
++    h->changed = 0;
+   ctx->changed &= ~readonly;
+   ctx->readonly = readonly;
+ 
diff --git a/debian/patches/upstream/imap-poll-timeout.patch b/debian/patches/upstream/imap-poll-timeout.patch
new file mode 100644
index 0000000..9a54622
--- /dev/null
+++ b/debian/patches/upstream/imap-poll-timeout.patch
@@ -0,0 +1,37 @@
+# HG changeset patch
+# User Kevin McCarthy <kevin at 8t8.us>
+# Date 1508051598 -28800
+#      Sun Oct 15 15:13:18 2017 +0800
+# Node ID 321805c70d99f0dfc63ae995d9c981055a260be0
+# Parent  ba4a3cb944c59ca53adfc3f99cf67dc2c22d7b6a
+Add polling for the IDLE command. (closes #3957)
+
+Add $imap_poll_timeout poll for IDLE, since this is also a command
+that will freeze after waking if $imap_idle is set.
+
+diff -r ba4a3cb944c5 -r 321805c70d99 imap/command.c
+--- a/imap/command.c	Sat Sep 30 19:16:56 2017 -0700
++++ b/imap/command.c	Sun Oct 15 15:13:18 2017 +0800
+@@ -333,7 +333,21 @@
+ {
+   int rc;
+ 
+-  imap_cmd_start (idata, "IDLE");
++  if (cmd_start (idata, "IDLE", IMAP_CMD_POLL) < 0)
++  {
++    cmd_handle_fatal (idata);
++    return -1;
++  }
++
++  if ((ImapPollTimeout > 0) &&
++      (mutt_socket_poll (idata->conn, ImapPollTimeout)) == 0)
++  {
++    mutt_error (_("Connection to %s timed out"), idata->conn->account.host);
++    mutt_sleep (2);
++    cmd_handle_fatal (idata);
++    return -1;
++  }
++
+   do
+     rc = imap_cmd_step (idata);
+   while (rc == IMAP_CMD_CONTINUE);
diff --git a/debian/patches/upstream/maildir-hash.patch b/debian/patches/upstream/maildir-hash.patch
new file mode 100644
index 0000000..16a4c4c
--- /dev/null
+++ b/debian/patches/upstream/maildir-hash.patch
@@ -0,0 +1,74 @@
+# HG changeset patch
+# User Kevin McCarthy <kevin at 8t8.us>
+# Date 1506390032 25200
+#      Mon Sep 25 18:40:32 2017 -0700
+# Node ID 9221d39b7b8a1c4a88eede5b9121c22be86e4687
+# Parent  cde585b4e2795df30674cba9e6343fc43d9be4ad
+Change maildir and mh check_mailbox to use dynamic sized hash. (closes #3973)
+
+The original patch is by Matt Fleming, originally posted at
+http://www.codeblueprint.co.uk/2017/01/15/a-kernel-devs-approach-to-improving2
+
+The comments there indicate Matt tried to submit to trac and mutt-dev,
+but ran into registration problems.  Thank you for the patch, and
+sorry for those problems, Matt.
+
+I modified the patch by making the same change to the
+mh_check_mailbox() code too.
+
+diff -r cde585b4e279 -r 9221d39b7b8a mh.c
+--- a/mh.c	Sat Sep 23 11:41:25 2017 -0700
++++ b/mh.c	Mon Sep 25 18:40:32 2017 -0700
+@@ -2095,6 +2095,7 @@
+   struct maildir *md;		/* list of messages in the mailbox */
+   struct maildir **last, *p;
+   int i;
++  int count = 0;
+   HASH *fnames;			/* hash table for quickly looking up the base filename
+ 				   for a maildir message */
+   struct mh_data *data = mh_data (ctx);
+@@ -2132,15 +2133,15 @@
+   md = NULL;
+   last = &md;
+   if (changed & 1)
+-    maildir_parse_dir (ctx, &last, "new", NULL, NULL);
++    maildir_parse_dir (ctx, &last, "new", &count, NULL);
+   if (changed & 2)
+-    maildir_parse_dir (ctx, &last, "cur", NULL, NULL);
++    maildir_parse_dir (ctx, &last, "cur", &count, NULL);
+ 
+   /* we create a hash table keyed off the canonical (sans flags) filename
+    * of each message we scanned.  This is used in the loop over the
+    * existing messages below to do some correlation.
+    */
+-  fnames = hash_create (1031, 0);
++  fnames = hash_create (count, 0);
+ 
+   for (p = md; p; p = p->next)
+   {
+@@ -2248,6 +2249,7 @@
+   struct maildir *md, *p;
+   struct maildir **last = NULL;
+   struct mh_sequences mhs;
++  int count = 0;
+   HASH *fnames;
+   int i;
+   struct mh_data *data = mh_data (ctx);
+@@ -2292,7 +2294,7 @@
+   md   = NULL;
+   last = &md;
+ 
+-  maildir_parse_dir (ctx, &last, NULL, NULL, NULL);
++  maildir_parse_dir (ctx, &last, NULL, &count, NULL);
+   maildir_delayed_parsing (ctx, &md, NULL);
+ 
+   if (mh_read_sequences (&mhs, ctx->path) < 0)
+@@ -2301,7 +2303,7 @@
+   mhs_free_sequences (&mhs);
+ 
+   /* check for modifications and adjust flags */
+-  fnames = hash_create (1031, 0);
++  fnames = hash_create (count, 0);
+ 
+   for (p = md; p; p = p->next)
+   {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mutt/mutt.git



More information about the pkg-mutt-commits mailing list