On Wed, Dec 28, 2016 at 04:03:41PM -0800, Kevin J. McCarthy wrote: > I'm attaching a "general idea" patch. This is <10 minutes of work, > absolutely incomplete, without comments, etc etc
Whoops, I forgot I initially set the cache->list to be a single bit. I've changed it to an int for now in the attached patch. -- Kevin J. McCarthy GPG Fingerprint: 8975 A9B3 3AA3 7910 385C 5308 ADEF 7684 8031 6BDA
# HG changeset patch # User Kevin McCarthy <ke...@8t8.us> # Date 1482970849 28800 # Wed Dec 28 16:20:49 2016 -0800 # Node ID 62f386b31c931080e8c73563a0705f69e2f4467b # Parent 4cb0cd767af2a7534dfcd0b4859b2484dc31d09d [mq]: pattern-cache diff --git a/curs_main.c b/curs_main.c --- a/curs_main.c +++ b/curs_main.c @@ -371,17 +371,17 @@ #define THIS_BODY ctx->hdrs[j]->content for (j = (check == MUTT_REOPENED) ? 0 : oldcount; j < ctx->msgcount; j++) { if (!j) ctx->vcount = 0; if (mutt_pattern_exec (ctx->limit_pattern, MUTT_MATCH_FULL_ADDRESS, - ctx, ctx->hdrs[j])) + ctx, ctx->hdrs[j], NULL)) { assert (ctx->vcount < ctx->msgcount); ctx->hdrs[j]->virtual = ctx->vcount; ctx->v2r[ctx->vcount] = j; ctx->hdrs[j]->limited = 1; ctx->vcount++; ctx->vsize += THIS_BODY->length + THIS_BODY->offset - THIS_BODY->hdr_offset; } @@ -2436,20 +2436,24 @@ mutt_menuDestroy (&menu); return (close); } void mutt_set_header_color (CONTEXT *ctx, HEADER *curhdr) { COLOR_LINE *color; + pattern_cache_t cache; if (!curhdr) return; + memset (&cache, 0, sizeof (cache)); + for (color = ColorIndexList; color; color = color->next) - if (mutt_pattern_exec (color->color_pattern, MUTT_MATCH_FULL_ADDRESS, ctx, curhdr)) - { + if (mutt_pattern_exec (color->color_pattern, MUTT_MATCH_FULL_ADDRESS, ctx, curhdr, + &cache)) + { curhdr->pair = color->pair; return; - } + } curhdr->pair = ColorDefs[MT_COLOR_NORMAL]; } diff --git a/hook.c b/hook.c --- a/hook.c +++ b/hook.c @@ -368,17 +368,17 @@ err.data = safe_malloc (err.dsize); mutt_buffer_init (&token); 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, NULL) > 0) ^ hook->rx.not) if (mutt_parse_rc_line (hook->command, &token, &err) != 0) { FREE (&token.data); mutt_error ("%s", err.data); mutt_sleep (1); current_hook_type = 0; FREE (&err.data); @@ -398,17 +398,17 @@ /* determine if a matching hook exists */ 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, NULL) > 0) ^ hook->rx.not) { mutt_make_string (path, pathlen, hook->command, ctx, hdr); return 0; } } return -1; } diff --git a/mutt.h b/mutt.h --- a/mutt.h +++ b/mutt.h @@ -869,16 +869,21 @@ union { regex_t *rx; group_t *g; char *str; } p; } pattern_t; +typedef struct +{ + int list; +} pattern_cache_t; + /* ACL Rights */ enum { MUTT_ACL_LOOKUP = 0, MUTT_ACL_READ, MUTT_ACL_SEEN, MUTT_ACL_WRITE, MUTT_ACL_INSERT, diff --git a/pattern.c b/pattern.c --- a/pattern.c +++ b/pattern.c @@ -990,29 +990,29 @@ tmp->op = or ? MUTT_OR : MUTT_AND; tmp->child = curlist; curlist = tmp; } return (curlist); } static int -perform_and (pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *hdr) +perform_and (pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *hdr, pattern_cache_t *cache) { for (; pat; pat = pat->next) - if (mutt_pattern_exec (pat, flags, ctx, hdr) <= 0) + if (mutt_pattern_exec (pat, flags, ctx, hdr, cache) <= 0) return 0; return 1; } static int -perform_or (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *hdr) +perform_or (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *hdr, pattern_cache_t *cache) { for (; pat; pat = pat->next) - if (mutt_pattern_exec (pat, flags, ctx, hdr) > 0) + if (mutt_pattern_exec (pat, flags, ctx, hdr, cache) > 0) return 1; return 0; } static int match_adrlist (pattern_t *pat, int match_personal, int n, ...) { va_list ap; ADDRESS *a; @@ -1089,41 +1089,42 @@ { int a; HEADER *h; if(!t) return 0; h = t->message; if(h) - if(mutt_pattern_exec(pat, flags, ctx, h)) + if(mutt_pattern_exec(pat, flags, ctx, h, NULL)) return 1; if(up && (a=match_threadcomplete(pat, flags, ctx, t->parent,1,1,1,0))) return a; if(right && t->parent && (a=match_threadcomplete(pat, flags, ctx, t->next,0,0,1,1))) return a; if(left && t->parent && (a=match_threadcomplete(pat, flags, ctx, t->prev,1,0,0,1))) return a; if(down && (a=match_threadcomplete(pat, flags, ctx, t->child,1,0,1,1))) return a; return 0; } /* flags MUTT_MATCH_FULL_ADDRESS match both personal and machine address */ int -mutt_pattern_exec (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *h) +mutt_pattern_exec (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *h, + pattern_cache_t *cache) { switch (pat->op) { case MUTT_AND: - return (pat->not ^ (perform_and (pat->child, flags, ctx, h) > 0)); + return (pat->not ^ (perform_and (pat->child, flags, ctx, h, cache) > 0)); case MUTT_OR: - return (pat->not ^ (perform_or (pat->child, flags, ctx, h) > 0)); + return (pat->not ^ (perform_or (pat->child, flags, ctx, h, cache) > 0)); case MUTT_THREAD: return (pat->not ^ match_threadcomplete(pat->child, flags, ctx, h->thread, 1, 1, 1, 1)); case MUTT_ALL: return (!pat->not); case MUTT_EXPIRED: return (pat->not ^ h->expired); case MUTT_SUPERSEDED: return (pat->not ^ h->superseded); @@ -1193,17 +1194,24 @@ case MUTT_ADDRESS: return (pat->not ^ match_adrlist (pat, flags & MUTT_MATCH_FULL_ADDRESS, 4, h->env->from, h->env->sender, h->env->to, h->env->cc)); case MUTT_RECIPIENT: return (pat->not ^ match_adrlist (pat, flags & MUTT_MATCH_FULL_ADDRESS, 2, h->env->to, h->env->cc)); case MUTT_LIST: /* known list, subscribed or not */ - return (pat->not ^ mutt_is_list_cc (pat->alladdr, h->env->to, h->env->cc)); + if (cache) + { + if (!cache->list) + cache->list = 1 + mutt_is_list_cc (pat->alladdr, h->env->to, h->env->cc); + return (pat->not ^ (cache->list - 1)); + } + else + return (pat->not ^ mutt_is_list_cc (pat->alladdr, h->env->to, h->env->cc)); case MUTT_SUBSCRIBED_LIST: return (pat->not ^ mutt_is_list_recipient (pat->alladdr, h->env->to, h->env->cc)); case MUTT_PERSONAL_RECIP: return (pat->not ^ match_user (pat->alladdr, h->env->to, h->env->cc)); case MUTT_PERSONAL_FROM: return (pat->not ^ match_user (pat->alladdr, h->env->from, NULL)); case MUTT_COLLAPSED: return (pat->not ^ (h->collapsed && h->num_hidden > 1)); @@ -1359,33 +1367,33 @@ for (i = 0; i < Context->msgcount; i++) { mutt_progress_update (&progress, i, -1); /* new limit pattern implicitly uncollapses all threads */ Context->hdrs[i]->virtual = -1; Context->hdrs[i]->limited = 0; Context->hdrs[i]->collapsed = 0; Context->hdrs[i]->num_hidden = 0; - if (mutt_pattern_exec (pat, MUTT_MATCH_FULL_ADDRESS, Context, Context->hdrs[i])) + if (mutt_pattern_exec (pat, MUTT_MATCH_FULL_ADDRESS, Context, Context->hdrs[i], NULL)) { Context->hdrs[i]->virtual = Context->vcount; Context->hdrs[i]->limited = 1; Context->v2r[Context->vcount] = i; Context->vcount++; Context->vsize+=THIS_BODY->length + THIS_BODY->offset - THIS_BODY->hdr_offset; } } } else { for (i = 0; i < Context->vcount; i++) { mutt_progress_update (&progress, i, -1); - if (mutt_pattern_exec (pat, MUTT_MATCH_FULL_ADDRESS, Context, Context->hdrs[Context->v2r[i]])) + if (mutt_pattern_exec (pat, MUTT_MATCH_FULL_ADDRESS, Context, Context->hdrs[Context->v2r[i]], NULL)) { switch (op) { case MUTT_UNDELETE: mutt_set_flag (Context, Context->hdrs[Context->v2r[i]], MUTT_PURGE, 0); case MUTT_DELETE: mutt_set_flag (Context, Context->hdrs[Context->v2r[i]], MUTT_DELETE, @@ -1535,17 +1543,17 @@ mutt_message (msg); return i; } } else { /* remember that we've already searched this message */ h->searched = 1; - if ((h->matched = (mutt_pattern_exec (SearchPattern, MUTT_MATCH_FULL_ADDRESS, Context, h) > 0))) + if ((h->matched = (mutt_pattern_exec (SearchPattern, MUTT_MATCH_FULL_ADDRESS, Context, h, NULL) > 0))) { mutt_clear_error(); if (msg && *msg) mutt_message (msg); return i; } } diff --git a/protos.h b/protos.h --- a/protos.h +++ b/protos.h @@ -401,17 +401,17 @@ (option (OPTLOCALES) ? 0 : \ ((unsigned char)(c) >= 0xa0))) #define IsWPrint(wc) (iswprint(wc) || \ (option (OPTLOCALES) ? 0 : (wc >= 0xa0))) #endif #define new_pattern() safe_calloc(1, sizeof (pattern_t)) -int mutt_pattern_exec (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *h); +int mutt_pattern_exec (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *h, pattern_cache_t *); pattern_t *mutt_pattern_comp (/* const */ char *s, int flags, BUFFER *err); void mutt_check_simple (char *s, size_t len, const char *simple); void mutt_pattern_free (pattern_t **pat); /* ---------------------------------------------------------------------------- * Prototypes for broken systems */ diff --git a/score.c b/score.c --- a/score.c +++ b/score.c @@ -128,17 +128,17 @@ void mutt_score_message (CONTEXT *ctx, HEADER *hdr, int upd_ctx) { SCORE *tmp; hdr->score = 0; /* in case of re-scoring */ for (tmp = Score; tmp; tmp = tmp->next) { - if (mutt_pattern_exec (tmp->pat, 0, NULL, hdr) > 0) + if (mutt_pattern_exec (tmp->pat, 0, NULL, hdr, NULL) > 0) { if (tmp->exact || tmp->val == 9999 || tmp->val == -9999) { hdr->score = tmp->val; break; } hdr->score += tmp->val; }
signature.asc
Description: PGP signature