From 522c26d54379b38d3dbdc7d1537eee075157841a Mon Sep 17 00:00:00 2001 From: Kevin McCarthy Date: Mon, 2 Jan 2017 18:08:17 -0800 Subject: Add a pattern_cache_t to speed up a few repeated matches. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Vincent Lefèvre reported experiencing an index display performance issue. This occurred with messages containing many recipients. He had many index color lines containing ~l. The ~l ended up being run over and over on these messages, resulting in a noticable slowdown displaying the index. This patch adds caching for just a few of the pattern operations (~l, ~u, ~p, ~P) that are potentially expensive and also don't have arguments. The caching is only enabled for operations repeatedly matching against the same message: color, hooks, scoring. The caching is fairly targeted, but isn't that invasive or complicated. --- hook.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'hook.c') diff --git a/hook.c b/hook.c index d8f678a8..0cb40344 100644 --- a/hook.c +++ b/hook.c @@ -360,6 +360,7 @@ void mutt_message_hook (CONTEXT *ctx, HEADER *hdr, int type) { BUFFER err, token; HOOK *hook; + pattern_cache_t cache; current_hook_type = type; @@ -367,13 +368,15 @@ void mutt_message_hook (CONTEXT *ctx, HEADER *hdr, int type) err.dsize = STRING; err.data = safe_malloc (err.dsize); mutt_buffer_init (&token); + memset (&cache, 0, sizeof (cache)); for (hook = Hooks; hook; hook = hook->next) { if(!hook->command) continue; if (hook->type & type) - if ((mutt_pattern_exec (hook->pattern, 0, ctx, hdr) > 0) ^ hook->rx.not) + if ((mutt_pattern_exec (hook->pattern, 0, ctx, hdr, &cache) > 0) ^ hook->rx.not) + { if (mutt_parse_rc_line (hook->command, &token, &err) != 0) { FREE (&token.data); @@ -384,6 +387,10 @@ void mutt_message_hook (CONTEXT *ctx, HEADER *hdr, int type) return; } + /* Executing arbitrary commands could affect the pattern results, + * so the cache has to be wiped */ + memset (&cache, 0, sizeof (cache)); + } } FREE (&token.data); FREE (&err.data); @@ -395,7 +402,9 @@ static int mutt_addr_hook (char *path, size_t pathlen, int type, CONTEXT *ctx, HEADER *hdr) { HOOK *hook; + pattern_cache_t cache; + memset (&cache, 0, sizeof (cache)); /* determine if a matching hook exists */ for (hook = Hooks; hook; hook = hook->next) { @@ -403,7 +412,7 @@ mutt_addr_hook (char *path, size_t pathlen, int type, CONTEXT *ctx, HEADER *hdr) continue; if (hook->type & type) - if ((mutt_pattern_exec (hook->pattern, 0, ctx, hdr) > 0) ^ hook->rx.not) + if ((mutt_pattern_exec (hook->pattern, 0, ctx, hdr, &cache) > 0) ^ hook->rx.not) { mutt_make_string (path, pathlen, hook->command, ctx, hdr); return 0; -- cgit v1.2.3