diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-07-18 15:03:55 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-07-18 15:54:27 +0900 |
| commit | 91692846909ed191addb7ec1c34aad11392ab88b (patch) | |
| tree | 7c477055e432fd43a98e5dddc016e07dcfc67f60 /crates/shirabe/src/util/url.rs | |
| parent | 4ae58baf8618f5fe916ba2a69faaca93514134ce (diff) | |
| download | php-shirabe-91692846909ed191addb7ec1c34aad11392ab88b.tar.gz php-shirabe-91692846909ed191addb7ec1c34aad11392ab88b.tar.zst php-shirabe-91692846909ed191addb7ec1c34aad11392ab88b.zip | |
perf(regex): eliminate per-call clone overhead in preg_* dispatch
regex::Regex::clone() does not share the underlying meta engine's
search-cache pool, so every fresh clone pays a ~10us warmup cost on
its first use. Two changes together eliminate this across nearly all
preg_* call sites:
- A php_regex! macro resolves PHP-style patterns to a per-call-site
&'static regex::Regex (via regex-macro's LazyLock), applied at the
majority of call sites throughout the codebase.
- Call sites still passing dynamic pattern strings go through
PATTERN_CACHE, which now stores Arc<(Regex, bool)> and hands out
Arc::clone()s instead of cloning the Regex itself.
PregPattern::resolve() returns a ResolvedPattern enum (Arc or
'static reference) rather than an owned Regex, so neither path ever
clones the Regex proper.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/util/url.rs')
| -rw-r--r-- | crates/shirabe/src/util/url.rs | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/crates/shirabe/src/util/url.rs b/crates/shirabe/src/util/url.rs index b1f17fb1..77649308 100644 --- a/crates/shirabe/src/util/url.rs +++ b/crates/shirabe/src/util/url.rs @@ -4,7 +4,7 @@ use crate::config::Config; use crate::util::GitHub; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::{CaptureKey, Preg}; -use shirabe_php_shim::{PHP_URL_HOST, PHP_URL_PORT, PhpMixed, in_array, parse_url}; +use shirabe_php_shim::{PHP_URL_HOST, PHP_URL_PORT, PhpMixed, in_array, parse_url, php_regex}; pub struct Url; @@ -18,7 +18,9 @@ impl Url { if host == "api.github.com" || host == "github.com" || host == "www.github.com" { let mut m: IndexMap<CaptureKey, String> = IndexMap::new(); if Preg::match3( - r"{^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/(zip|tar)ball/(.+)$}i", + php_regex!( + r"{^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/(zip|tar)ball/(.+)$}i" + ), &url, Some(&mut m), ) { @@ -30,7 +32,9 @@ impl Url { r#ref ); } else if Preg::match3( - r"{^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/archive/.+\.(zip|tar)(?:\.gz)?$}i", + php_regex!( + r"{^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/archive/.+\.(zip|tar)(?:\.gz)?$}i" + ), &url, Some(&mut m), ) { @@ -42,7 +46,9 @@ impl Url { r#ref ); } else if Preg::match3( - r"{^https?://api\.github\.com/repos/([^/]+)/([^/]+)/(zip|tar)ball(?:/.+)?$}i", + php_regex!( + r"{^https?://api\.github\.com/repos/([^/]+)/([^/]+)/(zip|tar)ball(?:/.+)?$}i" + ), &url, Some(&mut m), ) { @@ -57,7 +63,9 @@ impl Url { } else if host == "bitbucket.org" || host == "www.bitbucket.org" { let mut m: IndexMap<CaptureKey, String> = IndexMap::new(); if Preg::match3( - r"{^https?://(?:www\.)?bitbucket\.org/([^/]+)/([^/]+)/get/(.+)\.(zip|tar\.gz|tar\.bz2)$}i", + php_regex!( + r"{^https?://(?:www\.)?bitbucket\.org/([^/]+)/([^/]+)/get/(.+)\.(zip|tar\.gz|tar\.bz2)$}i" + ), &url, Some(&mut m), ) { @@ -72,7 +80,9 @@ impl Url { } else if host == "gitlab.com" || host == "www.gitlab.com" { let mut m: IndexMap<CaptureKey, String> = IndexMap::new(); if Preg::match3( - r"{^https?://(?:www\.)?gitlab\.com/api/v[34]/projects/([^/]+)/repository/archive\.(zip|tar\.gz|tar\.bz2|tar)\?sha=.+$}i", + php_regex!( + r"{^https?://(?:www\.)?gitlab\.com/api/v[34]/projects/([^/]+)/repository/archive\.(zip|tar\.gz|tar\.bz2|tar)\?sha=.+$}i" + ), &url, Some(&mut m), ) { @@ -89,7 +99,7 @@ impl Url { true, ) { url = Preg::replace( - r"{(/repos/[^/]+/[^/]+/(zip|tar)ball)(?:/.+)?$}i", + php_regex!(r"{(/repos/[^/]+/[^/]+/(zip|tar)ball)(?:/.+)?$}i"), &format!("$1/{}", r#ref), &url, ); @@ -99,7 +109,9 @@ impl Url { true, ) { url = Preg::replace( - r"{(/api/v[34]/projects/[^/]+/repository/archive\.(?:zip|tar\.gz|tar\.bz2|tar)\?sha=).+$}i", + php_regex!( + r"{(/api/v[34]/projects/[^/]+/repository/archive\.(?:zip|tar\.gz|tar\.bz2|tar)\?sha=).+$}i" + ), &format!("${{1}}{}", r#ref), &url, ); @@ -164,10 +176,10 @@ impl Url { pub fn sanitize(url: String) -> String { // GitHub repository rename result in redirect locations containing the access_token as GET parameter // e.g. https://api.github.com/repositories/9999999999?access_token=github_token - let url = Preg::replace(r"{([&?]access_token=)[^&]+}", "$1***", &url); + let url = Preg::replace(php_regex!(r"{([&?]access_token=)[^&]+}"), "$1***", &url); Preg::replace_callback( - r"{^(?P<prefix>[a-z0-9]+://)?(?P<user>[^:/\s@]+):(?P<password>[^@\s/]+)@}i", + php_regex!(r"{^(?P<prefix>[a-z0-9]+://)?(?P<user>[^:/\s@]+):(?P<password>[^@\s/]+)@}i"), |m| { let user = m .get(&CaptureKey::ByName("user".to_string())) |
