Subject: bug#17350: [PATCH] grep: speed up for a case to repeat failure in DFA after success in kwset

From: Norihiro Tanaka <[email-masked]>
Date: Sun, 27 Apr 2014 15:15:27 +0900

Paul, Thank you always for everything.  Fix for dfaisfast() is right.  A
superset never has BACKREF.  However, I think that we don't have to check
the end pointer when dfaisfast is true, because run DFA for whole a buffer
(use buflim) and check the end pointer.

By the way, I took into another bug by my previous patch.  If
`kwsm.index < kwset_exact_matches', don't have to run DFA for whole a buffer.

Norihiro
From 8654b1ea60b378bfb0d89e4eb9184092f479918c Mon Sep 17 00:00:00 2001
From: Norihiro Tanaka <[email-masked]>
Date: Sun, 27 Apr 2014 14:58:36 +0900
Subject: [PATCH] grep: fix the bugs in previous patch

* src/dfasearch.c (EGexecute): Fix it.
---
 src/dfasearch.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/dfasearch.c b/src/dfasearch.c
index 7edc96b..f23009c 100644
--- a/src/dfasearch.c
+++ b/src/dfasearch.c
@@ -235,11 +235,11 @@ EGexecute (char const *buf, size_t size, size_t *match_size,
               /* Narrow down to the line containing the candidate.  */
               beg = memrchr (buf, eol, match - buf);
               beg = beg ? beg + 1 : buf;
-              end = memchr (match, eol, buflim - match);
-              end = end ? end + 1 : buflim;
 
               if (kwsm.index < kwset_exact_matches)
                 {
+                  end = memchr (match, eol, buflim - match);
+                  end = end ? end + 1 : buflim;
                   if (MB_CUR_MAX == 1)
                     goto success;
                   if (mb_start < beg)
@@ -256,13 +256,15 @@ EGexecute (char const *buf, size_t size, size_t *match_size,
                 }
               else if (!dfafast)
                 {
+                  end = memchr (match, eol, buflim - match);
+                  end = end ? end + 1 : buflim;
                   if (dfahint (dfa, beg, (char *) end, NULL) == (size_t) -1)
                     continue;
                   if (! dfaexec (dfa, beg, (char *) end, 0, NULL, &backref))
                     continue;
                 }
             }
-          if (!kwset || dfafast)
+          if (!kwset || (dfafast && kwsm.index >= kwset_exact_matches))
             {
               /* No good fixed strings or DFA is fast; use DFA.  */
               size_t offset, count;
-- 
1.9.2