I used sysprof to take a look at where uulib spends most of its time,
and it turns out its top two bottlenecks were very tweakable.
With this tweak, the `freeze' time while Pan's decoding and saving
attachments is much shorter.

Testers, give this a spin and see what you think.

cheers,
Charles
Only in pan-devel/uulib/: asfd
Only in pan-devel/uulib/: .deps
diff -u old/uulib/fptools.c pan-devel/uulib/fptools.c
--- old/uulib/fptools.c 2006-04-17 22:19:43.000000000 -0500
+++ pan-devel/uulib/fptools.c   2006-04-24 23:28:37.000000000 -0500
@@ -433,76 +433,36 @@
  * My own fgets function. It handles all kinds of line terminators
  * properly: LF (Unix), CRLF (DOS) and CR (Mac). In all cases, the
  * terminator is replaced by a single LF
+ *
+ * Pan change:  sysprof says this function is standard uulib's biggest
+ * hotspot, and with the per-char fgetc and feof it's easy to see why.
+ * Pan doesn't run on OS9 anyway, so don't sweat CR.
+ * Handle LF (Unix, OSX) and CRLF (DOS) correctly.
+ * In all cases, the terminator is replaced by a single LF
  */
-
 char * TOOLEXPORT
 _FP_fgets (char *buf, int n, FILE *stream)
 {
-  char *obp = buf;
-  int c;
-
-  if (feof (stream))
+  int len;
+  *buf = '\0';
+  if (!fgets (buf, n, stream))
     return NULL;
-
-  while (--n && !feof (stream)) {
-    if ((c = fgetc (stream)) == EOF) {
-      if (ferror (stream))
-       return NULL;
-      else {
-       if (obp == buf)
-         return NULL;
-       *buf = '\0';
-       return obp;
-      }
-    }
-    if (c == '\015') { /* CR */
-      /*
-       * Peek next character. If it's no LF, push it back.
-       * ungetc(EOF, stream) is handled correctly according
-       * to the manual page
-       */
-      if ((c = fgetc (stream)) != '\012')
-       if (!feof (stream))
-         ungetc (c, stream);
-      *buf++ = '\012';
-      *buf   = '\0';
-      return obp;
-    }
-    else if (c == '\012') { /* LF */
-      *buf++ = '\012';
-      *buf   = '\0';
-      return obp;
-    }
-    /*
-     * just another standard character
-     */
-    *buf++ = c;
+  len = strlen (buf);
+  if (!len)
+    return NULL;
+  if (buf[len-1] != '\n') { // eof
+    buf[len++] = '\n';
+    buf[len] = '\0';
   }
-
-  /*
-   * n-1 characters already transferred
-   */
-
-  *buf = '\0';
-
-  /*
-   * If a line break is coming up, read it
-   */
-
-  if (!feof (stream)) {
-    if ((c = fgetc (stream)) == '\015' && !feof (stream)) {
-      if ((c = fgetc (stream)) != '\012' && !feof (stream)) {
-       ungetc (c, stream);
-      }
-    }
-    else if (c != '\012' && !feof (stream)) {
-      ungetc (c, stream);
-    }
+  else if (buf[len-2] == '\r') { // crlf
+    buf[len-1] = '\n';
+    buf[len] = '\0';
+    --len;
   }
-
-  return obp;
+  return buf;
 }
 
+
 /*
  * A replacement strerror function that just returns the error code
  */
Only in pan-devel/uulib/: Makefile
Only in pan-devel/uulib/: makelog
diff -u old/uulib/uuscan.c pan-devel/uulib/uuscan.c
--- old/uulib/uuscan.c  2006-04-17 21:54:12.000000000 -0500
+++ pan-devel/uulib/uuscan.c    2006-04-24 23:26:01.000000000 -0500
@@ -65,29 +65,26 @@
  * of usual MDA, News and MIME headers.
  * We make a distinction of MIME headers as we need the difference
  * to scan the bodies from partial multipart messages.
+ *
+ * Change for Pan: for efficiency's sake, converted to lowercase
+ * and sorted them, so that IsKnownHeader can pass a lowercase buf
+ * to bsearch rather than having to do a stricmp against each header.
  */
 
 static char *knownmsgheaders[] = {
-  "From ", "Return-Path:", "Received:", "Reply-To:",
-  "From:", "Sender:", "Resent-Reply-To:", "Resent-From:",
-  "Resent-Sender:", "Date:", "Resent-Date:", "To:",
-  "Resent-To:", "Cc:", "Bcc:", "Resent-bcc:",
-  "Message-ID:", "Resent-Message-Id:", "In-Reply-To:",
-  "References:", "Keywords:", "Subject:", "Comments:",
-  
-  "Delivery-Date:", "Posted-Date:", "Received-Date:",
-  "Precedence:", 
-
-  "Path:", "Newsgroups:", "Organization:", "Lines:",
-  "NNTP-Posting-Host:",
-  NULL
+  "bcc:", "cc:", "comments:", "date:", "delivery-date:",
+  "from ", "from:", "in-reply-to:", "keywords:", "lines:",
+  "message-id:", "newsgroups:", "nntp-posting-host:",
+  "organization:", "path:", "posted-date:", "precedence:",
+  "received-date:", "received:", "references:", "reply-to:",
+  "resent-bcc:", "resent-date:", "resent-from:", "resent-message-id:",
+  "resent-reply-to:", "resent-sender:", "resent-to:", "return-path:",
+  "sender:", "subject:", "to:"
 };
 
 static char *knownmimeheaders[] = {
-  "Mime-Version:",  "Content-Transfer-Encoding:",
-  "Content-Type:", "Content-Disposition:", 
-  "Content-Description:", "Content-Length:",
-  NULL
+  "content-description:", "content-disposition:", "content-length:",
+  "content-transfer-encoding:", "content-type:", "mime-version:"
 };
 
 /*
@@ -541,20 +538,26 @@
 static int
 IsKnownHeader (char *line)
 {
-  char **iter = knownmsgheaders;
-
-  while (iter && *iter) {
-    if (_FP_strnicmp (line, *iter, strlen (*iter)) == 0)
-      return 1;
-    iter++;
-  }
-
-  iter = knownmimeheaders;
-
-  while (iter && *iter) {
-    if (_FP_strnicmp (line, *iter, strlen (*iter)) == 0)
-      return 2;
-    iter++;
+  static int n_msg = sizeof(knownmsgheaders) / sizeof(knownmsgheaders[0]);
+  static int n_mime = sizeof(knownmimeheaders) / sizeof(knownmimeheaders[0]);
+  static int max_width = 25; // content-transfer-encoding
+
+  int retval = 0;
+  if (line && *line && strlen(line)<max_width)
+  {
+    // buf holds a lowercase version of `line'
+    char buf[32], *pch=buf, *end=buf+sizeof(buf);
+    while (line && *line && !isspace(*line) && pch!=end)
+      *pch++ = tolower (*line++);
+    *pch = '\0';
+ 
+    // search for that in knownmsgheaders 
+    if (bsearch (&buf, knownmsgheaders, n_msg, sizeof(char*), strcmp) != NULL)
+      retval = 1;
+
+    // search for that in knownmimeheaders 
+    else if (bsearch (&buf, knownmimeheaders, n_mime, sizeof(char*), strcmp) 
!= NULL)
+      retval = 2;
   }
 
   return 0;
_______________________________________________
Pan-users mailing list
Pan-users@nongnu.org
http://lists.nongnu.org/mailman/listinfo/pan-users

Reply via email to