# vi: ft=diff This is the header cache patch by Thomas Glanzmann . The home page for this patch is: http://wwwcip.informatik.uni-erlangen.de/~sithglan/mutt/ * Patch last synced with upstream: - Date: 2005-02-10 - File: http://wwwcip.informatik.uni-erlangen.de/~sithglan/mutt/mutt-cvs-header-cache.28 * Changes made: NONE. == END PATCH diff -Nru a/PATCHES b/PATCHES --- a/PATCHES +++ b/PATCHES @@ -0,0 +1 @@ +mutt-cvs-header-cache.28 diff -Nru a/init.h b/init.h --- a/init.h 2005-01-27 20:54:24 +01:00 +++ b/init.h 2005-01-28 15:12:41 +01:00 @@ -1032,6 +1032,13 @@ ** global header cache for all folders is used. Per 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 -Nru a/mh.c b/mh.c --- a/mh.c 2005-01-27 20:45:37 +01:00 +++ b/mh.c 2005-02-03 09:09:50 +01:00 @@ -787,6 +787,14 @@ 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. @@ -882,27 +890,67 @@ * 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. * @@ -1399,6 +1447,9 @@ { 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); @@ -1408,6 +1459,11 @@ 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 @@ -1416,7 +1472,13 @@ 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 */ @@ -1438,16 +1500,21 @@ 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); @@ -1468,6 +1535,13 @@ } 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 -Nru a/mutt.h b/mutt.h --- a/mutt.h 2005-01-27 20:54:24 +01:00 +++ b/mutt.h 2005-01-28 15:12:54 +01:00 @@ -353,6 +353,9 @@ OPTFORCENAME, OPTFORWDECODE, OPTFORWQUOTE, +#if USE_HCACHE + OPTHCACHEVERIFY, +#endif OPTHDRS, OPTHEADER, OPTHELP,