Re: [PATCH 8/8] wildmatch: advance faster in <asterisk> + <literal> patterns

2 messages, 2 authors, 2016-06-15 · open the first message on its own page

Re: [PATCH 8/8] wildmatch: advance faster in <asterisk> + <literal> patterns

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:55:36

Nguyễn Thái Ngọc Duy  [off-list ref] writes:
quoted hunk
compat, '*/*/*' on linux-2.6.git file list 2000 times, before:
wildmatch 7s 985049us
fnmatch   2s 735541us or 34.26% faster

and after:
wildmatch 4s 492549us
fnmatch   0s 888263us or 19.77% slower

Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
 wildmatch.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
diff --git a/wildmatch.c b/wildmatch.c
index 3794c4d..68b02e4 100644
--- a/wildmatch.c
+++ b/wildmatch.c
@@ -132,6 +132,27 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags)
 			while (1) {
 				if (t_ch == '\0')
 					break;
+				/*
+				 * Try to advance faster when an asterisk is
+				 * followed by a literal. We know in this case
+				 * that the the string before the literal
+				 * must belong to "*".
+				 */
+				if (!is_glob_special(*p)) {
So far, we have looked at "*x" or "**x" in the pattern, p points at
'x' (not an asterisk), and we have "text" to match.  For "text" to
match this pattern, the earlier part of it that is consumed to match
the asterisk must be followed by "x".  "special" tells us if we are
allowed to treat '/' as matching the asterisk.
+					p_ch = *p;
+					if ((flags & WM_CASEFOLD) && ISUPPER(p_ch))
+						p_ch = tolower(p_ch);
That "x" in the example is picked up here and stored in "p_ch".
Let's skip over "text" and find that "x" in there.
+					while ((t_ch = *text) != '\0' &&
+					       (!(flags & WM_PATHNAME) || t_ch != '/')) {
Why do we look at (flags & WM_PATHMAME) and not "special" here?
+						if ((flags & WM_CASEFOLD) && ISUPPER(t_ch))
+							t_ch = tolower(t_ch);
+						if (t_ch == p_ch)
+							break;
Found it.
+						text++;
+					}
+					if (t_ch != p_ch)
+						return WM_NOMATCH;
If we did not find that "x", then "**x" or "*x" can never match.
OK.  And at this point "text" points at that "x" we found, and "p"
points at "x" after the asterisk in the pattern.

Looks good so far.  Thanks.
+				}
 				if ((matched = dowild(p, text,  flags)) != WM_NOMATCH) {
 					if (!special || matched != WM_ABORT_TO_STARSTAR)
 						return matched;

Re: [PATCH 8/8] wildmatch: advance faster in <asterisk> + <literal> patterns

From: Nguyen Thai Ngoc Duy <hidden>
Date: 2016-06-15 22:55:36

On Fri, Dec 28, 2012 at 1:24 PM, Junio C Hamano [off-list ref] wrote:
quoted
+                                     while ((t_ch = *text) != '\0' &&
+                                            (!(flags & WM_PATHNAME) || t_ch != '/')) {
Why do we look at (flags & WM_PATHMAME) and not "special" here?
Because I was careless. Thanks for spotting it. I'll fix it and add
some more tests about **<literal> with WM_PATHNAME.
-- 
Duy
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help