From ff0e244701a6ead7f5a0b5826ac39bd42bad55ff Mon Sep 17 00:00:00 2001 From: Kathryn Andersen Date: Sun, 14 Nov 2010 16:22:15 +0000 Subject: [PATCH 1/4] Improve the speed of match_glob --- IkiWiki.pm | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/IkiWiki.pm b/IkiWiki.pm index 08a3d7875..75b7a7b3e 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -2482,6 +2482,8 @@ sub derel ($$) { return $path; } +my %glob_cache; + sub match_glob ($$;@) { my $page=shift; my $glob=shift; @@ -2489,8 +2491,14 @@ sub match_glob ($$;@) { $glob=derel($glob, $params{location}); - my $regexp=IkiWiki::glob2re($glob); - if ($page=~/^$regexp$/i) { + # Instead of converting the glob to a regex every time, + # cache the compiled regex to save time. + if (!exists $glob_cache{$glob} + or !defined $glob_cache{$glob}) { + my $re = IkiWiki::glob2re($glob); + $glob_cache{$glob} = qr/^$re$/i; + } + if ($page=~ $glob_cache{$glob}) { if (! IkiWiki::isinternal($page) || $params{internal}) { return IkiWiki::SuccessReason->new("$glob matches $page"); } From 321bf7ec19641d12626c71f87792b4edf40aa306 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 17 Nov 2010 20:04:55 +0000 Subject: [PATCH 2/4] match_glob: streamline glob cache slightly --- IkiWiki.pm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/IkiWiki.pm b/IkiWiki.pm index 75b7a7b3e..57e23fda8 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -2493,8 +2493,7 @@ sub match_glob ($$;@) { # Instead of converting the glob to a regex every time, # cache the compiled regex to save time. - if (!exists $glob_cache{$glob} - or !defined $glob_cache{$glob}) { + if (!defined $glob_cache{$glob}) { my $re = IkiWiki::glob2re($glob); $glob_cache{$glob} = qr/^$re$/i; } From 788105e2a73a3be0f9a05a390702ee28318a5673 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 19 Nov 2010 23:59:04 +0000 Subject: [PATCH 3/4] glob2re: return a precompiled, anchored case-insensitive regex In practice every use of glob2re uses it like that. --- IkiWiki.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IkiWiki.pm b/IkiWiki.pm index 57e23fda8..bb7d46ccf 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -2388,7 +2388,7 @@ sub glob2re ($) { my $re=quotemeta(shift); $re=~s/\\\*/.*/g; $re=~s/\\\?/./g; - return $re; + return qr/^$re$/i; } package IkiWiki::FailReason; From 55515050e1f3aad13dc96796a347cefa98e8e472 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Sat, 20 Nov 2010 00:02:49 +0000 Subject: [PATCH 4/4] make use of precompiled regex objects --- IkiWiki.pm | 4 ++-- IkiWiki/Plugin/filecheck.pm | 2 +- IkiWiki/Plugin/meta.pm | 2 +- IkiWiki/Plugin/po.pm | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/IkiWiki.pm b/IkiWiki.pm index bb7d46ccf..e5370f4a6 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -2495,7 +2495,7 @@ sub match_glob ($$;@) { # cache the compiled regex to save time. if (!defined $glob_cache{$glob}) { my $re = IkiWiki::glob2re($glob); - $glob_cache{$glob} = qr/^$re$/i; + $glob_cache{$glob} = $re; } if ($page=~ $glob_cache{$glob}) { if (! IkiWiki::isinternal($page) || $params{internal}) { @@ -2667,7 +2667,7 @@ sub match_user ($$;@) { return IkiWiki::ErrorReason->new("no user specified"); } - if (defined $params{user} && $params{user}=~/^$regexp$/i) { + if (defined $params{user} && $params{user}=~$regexp) { return IkiWiki::SuccessReason->new("user is $user"); } elsif (! defined $params{user}) { diff --git a/IkiWiki/Plugin/filecheck.pm b/IkiWiki/Plugin/filecheck.pm index 3b0a7b314..4f4e67489 100644 --- a/IkiWiki/Plugin/filecheck.pm +++ b/IkiWiki/Plugin/filecheck.pm @@ -161,7 +161,7 @@ sub match_mimetype ($$;@) { } my $regexp=IkiWiki::glob2re($wanted); - if ($mimetype!~/^$regexp$/i) { + if ($mimetype!~$regexp) { return IkiWiki::FailReason->new("file MIME type is $mimetype, not $wanted"); } else { diff --git a/IkiWiki/Plugin/meta.pm b/IkiWiki/Plugin/meta.pm index 5cfa72833..47007afe2 100644 --- a/IkiWiki/Plugin/meta.pm +++ b/IkiWiki/Plugin/meta.pm @@ -355,7 +355,7 @@ sub match { } if (defined $val) { - if ($val=~/^$re$/i) { + if ($val=~$re) { return IkiWiki::SuccessReason->new("$re matches $field of $page", $page => $IkiWiki::DEPEND_CONTENT, "" => 1); } else { diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index a79e7d7f0..79142ed1f 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -1297,7 +1297,7 @@ sub match_lang ($$;@) { my $regexp=IkiWiki::glob2re($wanted); my $lang=IkiWiki::Plugin::po::lang($page); - if ($lang !~ /^$regexp$/i) { + if ($lang !~ $regexp) { return IkiWiki::FailReason->new("file language is $lang, not $wanted"); } else {