]> granicus.if.org Git - mutt/commitdiff
Maildir header cache.
authorThomas Glanzmann <sithglan@stud.uni-erlangen.de>
Wed, 23 Mar 2005 10:51:11 +0000 (10:51 +0000)
committerThomas Glanzmann <sithglan@stud.uni-erlangen.de>
Wed, 23 Mar 2005 10:51:11 +0000 (10:51 +0000)
init.h
mh.c
mutt.h

diff --git a/init.h b/init.h
index bb8c4d5cbc7cf7b1cc057a23bf7664811db7eba7..9bb00e4d734c544bc2fed04e75ba20b0854f17e0 100644 (file)
--- a/init.h
+++ b/init.h
@@ -1032,6 +1032,13 @@ struct option_t MuttVars[] = {
   ** be a single global header cache. By default it is unset and so no
   ** header caching will be used.
   */
+  { "maildir_header_cache_verify", DT_BOOL, R_NONE, OPTHCACHEVERIFY, 1 },
+  /*
+  ** .pp
+  ** Check for Maildir unaware programs other than mutt having modified maildir
+  ** files when the header cache is in use.  This incurs one stat(2) per
+  ** message every time the folder is opened.
+  */
   { "header_cache_pagesize", DT_STR, R_NONE, UL &HeaderCachePageSize, UL "16384" },
   /*
   ** .pp
diff --git a/mh.c b/mh.c
index 966aa5b6eb80e2caf80897c9042adc1831a17fbb..5d9f9f996b42c8f0f7eac51b52c2858623a5c8e7 100644 (file)
--- a/mh.c
+++ b/mh.c
@@ -791,6 +791,14 @@ static int maildir_move_to_context (CONTEXT * ctx, struct maildir **md)
   return r;
 }
 
+#if USE_HCACHE
+static size_t maildir_hcache_keylen (const char *fn)
+{
+  const char * p = strrchr (fn, ':');
+  return p ? (size_t) (p - fn) : mutt_strlen(fn);
+}
+#endif
+
 #ifdef USE_INODESORT
 /*
  * Merge two maildir lists according to the inode numbers.
@@ -886,27 +894,67 @@ static struct maildir* maildir_sort_inode(struct maildir* list)
  * This function does the second parsing pass for a maildir-style
  * folder.
  */
-
 void maildir_delayed_parsing (CONTEXT * ctx, struct maildir *md)
 {
   struct maildir *p;
   char fn[_POSIX_PATH_MAX];
   int count;
 
+#if USE_HCACHE
+  void *hc = NULL;
+  void *data;
+  struct timeval *when = NULL;
+  struct stat lastchanged;
+  int ret;
+
+  hc = mutt_hcache_open (HeaderCache, ctx->path);
+#endif
+
   for (p = md, count = 0; p; p = p->next, count++)
-    if (p && p->h && !p->header_parsed)
-    {
-      if (!ctx->quiet && ReadInc && ((count % ReadInc) == 0 || count == 1))
-       mutt_message (_("Reading %s... %d"), ctx->path, count);
-      snprintf (fn, sizeof (fn), "%s/%s", ctx->path, p->h->path);
-      if (maildir_parse_message (ctx->magic, fn, p->h->old, p->h))
-       p->header_parsed = 1;
-      else
-       mutt_free_header (&p->h);
-    }
-}
+  {
+    if (! (p && p->h && !p->header_parsed))
+      continue;
+
+    if (!ctx->quiet && ReadInc && ((count % ReadInc) == 0 || count == 1))
+      mutt_message (_("Reading %s... %d"), ctx->path, count);
 
+#if USE_HCACHE
+    data = mutt_hcache_fetch (hc, p->h->path + 3, &maildir_hcache_keylen);
+    when = (struct timeval *) data;
+#endif
 
+    snprintf (fn, sizeof (fn), "%s/%s", ctx->path, p->h->path);
+
+#if USE_HCACHE
+    if (option(OPTHCACHEVERIFY))
+      ret = stat(fn, &lastchanged);
+    else {
+      lastchanged.st_mtime = 0;
+      ret = 0;
+    }
+    
+    if (data != NULL && !ret && lastchanged.st_mtime <= when->tv_sec)
+    {
+      p->h = mutt_hcache_restore ((unsigned char *)data, &p->h);
+      maildir_parse_flags (p->h, fn);
+    } else
+#endif
+    if (maildir_parse_message (ctx->magic, fn, p->h->old, p->h))
+    {
+      p->header_parsed = 1;
+#if USE_HCACHE
+      mutt_hcache_store (hc, p->h->path + 3, p->h, 0, &maildir_hcache_keylen);
+#endif
+    } else
+      mutt_free_header (&p->h);
+#if USE_HCACHE
+    FREE(&data);
+#endif
+  }
+#if USE_HCACHE
+  mutt_hcache_close (hc);
+#endif
+}
 
 /* Read a MH/maildir style mailbox.
  *
@@ -1403,6 +1451,9 @@ int mh_sync_mailbox (CONTEXT * ctx, int *index_hint)
 {
   char path[_POSIX_PATH_MAX], tmp[_POSIX_PATH_MAX];
   int i, j;
+#if USE_HCACHE
+  void *hc = NULL;
+#endif /* USE_HCACHE */
 
   if (ctx->magic == M_MH)
     i = mh_check_mailbox (ctx, index_hint);
@@ -1412,6 +1463,11 @@ int mh_sync_mailbox (CONTEXT * ctx, int *index_hint)
   if (i != 0)
     return i;
 
+#if USE_HCACHE
+  if (ctx->magic == M_MAILDIR)
+    hc = mutt_hcache_open(HeaderCache, ctx->path);
+#endif /* USE_HCACHE */
+
   for (i = 0; i < ctx->msgcount; i++)
   {
     if (ctx->hdrs[i]->deleted
@@ -1420,7 +1476,13 @@ int mh_sync_mailbox (CONTEXT * ctx, int *index_hint)
       snprintf (path, sizeof (path), "%s/%s", ctx->path, ctx->hdrs[i]->path);
       if (ctx->magic == M_MAILDIR
          || (option (OPTMHPURGE) && ctx->magic == M_MH))
+      {
+#if USE_HCACHE
+        if (ctx->magic == M_MAILDIR)
+          mutt_hcache_delete (hc, ctx->hdrs[i]->path + 3, &maildir_hcache_keylen);
+#endif /* USE_HCACHE */
        unlink (path);
+      }
       else if (ctx->magic == M_MH)
       {
        /* MH just moves files out of the way when you delete them */
@@ -1442,16 +1504,21 @@ int mh_sync_mailbox (CONTEXT * ctx, int *index_hint)
       if (ctx->magic == M_MAILDIR)
       {
        if (maildir_sync_message (ctx, i) == -1)
-         return -1;
+         goto err;
       }
       else
       {
        if (mh_sync_message (ctx, i) == -1)
-         return -1;
+         goto err;
       }
     }
   }
 
+#if USE_HCACHE
+  if (ctx->magic == M_MAILDIR)
+    mutt_hcache_close (hc);
+#endif /* USE_HCACHE */
+
   if (ctx->magic == M_MH)
     mh_update_sequences (ctx);
 
@@ -1472,6 +1539,13 @@ int mh_sync_mailbox (CONTEXT * ctx, int *index_hint)
   }
 
   return 0;
+
+err:
+#if USE_HCACHE
+  if (ctx->magic == M_MAILDIR)
+    mutt_hcache_close (hc);
+#endif /* USE_HCACHE */
+  return -1;
 }
 
 static char *maildir_canon_filename (char *dest, const char *src, size_t l)
diff --git a/mutt.h b/mutt.h
index 1376c5b304131539e86e9fbd0b34fac8f2952fd2..dc92151f77ef686e199671e361c97ec614f19ce9 100644 (file)
--- a/mutt.h
+++ b/mutt.h
@@ -351,6 +351,9 @@ enum
   OPTFORCENAME,
   OPTFORWDECODE,
   OPTFORWQUOTE,
+#if USE_HCACHE
+  OPTHCACHEVERIFY,
+#endif
   OPTHDRS,
   OPTHEADER,
   OPTHELP,