summaryrefslogtreecommitdiffstats
path: root/hook.c
diff options
context:
space:
mode:
authorKevin McCarthy <kevin@8t8.us>2017-01-02 18:08:17 -0800
committerKevin McCarthy <kevin@8t8.us>2017-01-02 18:08:17 -0800
commit522c26d54379b38d3dbdc7d1537eee075157841a (patch)
treeb59463d6634343de651e0abe6f8fcc8d29b6c7e9 /hook.c
parent17030b4700a498161ff5ab1eda28f0750cdbceb2 (diff)
Add a pattern_cache_t to speed up a few repeated matches.
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.
Diffstat (limited to 'hook.c')
-rw-r--r--hook.c13
1 files changed, 11 insertions, 2 deletions
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;