summaryrefslogtreecommitdiff
path: root/wildmatch.c
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2013-01-01 09:44:09 +0700
committerJunio C Hamano <gitster@pobox.com>2013-01-01 15:32:37 -0800
commit46983441ae17b34abee2954b87efeeefbe0768b3 (patch)
treefa4f76a660b86742f05d8ae2d1a9407cf24c936d /wildmatch.c
parent1b25892636d2f250eb2163301440ee8c8c1ac944 (diff)
downloadgit-46983441ae17b34abee2954b87efeeefbe0768b3.tar.gz
wildmatch: make a special case for "*/" with FNM_PATHNAME
Normally we need recursion for "*". In this case we know that it matches everything until "/" so we can skip the recursion. glibc, '*/*/*' on linux-2.6.git file list 2000 times before: wildmatch 8s 74513us fnmatch 1s 97042us or 13.59% faster after: wildmatch 3s 521862us fnmatch 3s 488616us or 99.06% slower Same test with compat/fnmatch: wildmatch 8s 110763us fnmatch 2s 980845us or 36.75% faster wildmatch 3s 522156us fnmatch 1s 544487us or 43.85% slower Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'wildmatch.c')
-rw-r--r--wildmatch.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/wildmatch.c b/wildmatch.c
index 536470b794..bb425220b0 100644
--- a/wildmatch.c
+++ b/wildmatch.c
@@ -117,6 +117,18 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags)
return WM_NOMATCH;
}
return WM_MATCH;
+ } else if (!match_slash && *p == '/') {
+ /*
+ * _one_ asterisk followed by a slash
+ * with WM_PATHNAME matches the next
+ * directory
+ */
+ const char *slash = strchr((char*)text, '/');
+ if (!slash)
+ return WM_NOMATCH;
+ text = (const uchar*)slash;
+ /* the slash is consumed by the top-level for loop */
+ break;
}
while (1) {
if (t_ch == '\0')