diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-08-19 23:45:38 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-08-19 23:45:38 +0900 |
| commit | cd7c3fce2472656b2a1247429751e43350976677 (patch) | |
| tree | 95e8760e3417fc3e63dac28bc0cd823a6af768f2 /crates/shirabe/src/repository | |
| parent | b8fb046bd7c4cd28598bcce9f3955d834ea5d008 (diff) | |
| download | php-shirabe-cd7c3fce2472656b2a1247429751e43350976677.tar.gz php-shirabe-cd7c3fce2472656b2a1247429751e43350976677.tar.zst php-shirabe-cd7c3fce2472656b2a1247429751e43350976677.zip | |
perf(package): hand out link maps behind Rc
PackageInterface::getRequires() and friends return the array of Link objects;
in PHP that is a copy-on-write array of object references, so a caller pays
nothing to look at it. The port returned IndexMap<String, Link> by value, so
every call deep-cloned the whole map, keys and constraints included. Pool
building calls these accessors once per package per candidate, which put
IndexMap::clone at 13.5% of `require laravel/laravel`.
Store the maps as Rc<IndexMap<String, Link>> and return a handle. Callers that
mutate the map clone it explicitly at the point of mutation, matching where PHP
would separate the array.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/repository')
5 files changed, 28 insertions, 18 deletions
diff --git a/crates/shirabe/src/repository/filesystem_repository.rs b/crates/shirabe/src/repository/filesystem_repository.rs index 54c2fa1f..5f06505a 100644 --- a/crates/shirabe/src/repository/filesystem_repository.rs +++ b/crates/shirabe/src/repository/filesystem_repository.rs @@ -510,7 +510,7 @@ impl FilesystemRepository { .as_array() .map(|m| m.contains_key(&package.get_name())) .unwrap_or(false); - for (_, replace) in package.get_replaces() { + for (_, replace) in package.get_replaces().iter() { // exclude platform replaces as when they are really there we can not check for their presence if PlatformRepository::is_platform_package(replace.get_target()) { continue; @@ -527,7 +527,7 @@ impl FilesystemRepository { is_dev_package, ); } - for (_, provide) in package.get_provides() { + for (_, provide) in package.get_provides().iter() { // exclude platform provides as when they are really there we can not check for their presence if PlatformRepository::is_platform_package(provide.get_target()) { continue; diff --git a/crates/shirabe/src/repository/installed_repository.rs b/crates/shirabe/src/repository/installed_repository.rs index 36ad510c..097fca84 100644 --- a/crates/shirabe/src/repository/installed_repository.rs +++ b/crates/shirabe/src/repository/installed_repository.rs @@ -84,8 +84,10 @@ impl InstalledRepository { continue; } - let provides_and_replaces = - array_merge_map(candidate.get_provides(), candidate.get_replaces()); + let provides_and_replaces = array_merge_map( + (*candidate.get_provides()).clone(), + (*candidate.get_replaces()).clone(), + ); for link in provides_and_replaces.values() { if name == link.get_target() && (constraint.is_none() @@ -126,12 +128,12 @@ impl InstalledRepository { } for package in self.inner.get_packages()? { - let mut links: IndexMap<String, Link> = package.get_requires(); + let mut links: IndexMap<String, Link> = (*package.get_requires()).clone(); let mut packages_in_tree = packages_found.clone(); if !invert { - for (k, v) in package.get_replaces() { - links.entry(k).or_insert(v); + for (k, v) in package.get_replaces().iter() { + links.entry(k.clone()).or_insert(v.clone()); } let needles_snapshot = needles.clone(); @@ -169,8 +171,8 @@ impl InstalledRepository { } if package.as_root().is_some() { - for (k, v) in package.get_dev_requires() { - links.entry(k).or_insert(v); + for (k, v) in package.get_dev_requires().iter() { + links.entry(k.clone()).or_insert(v.clone()); } } @@ -297,8 +299,10 @@ impl InstalledRepository { .into(); if link.get_target() != pkg.get_name().as_str() { - let replaces_and_provides = - array_merge_map(pkg.get_replaces(), pkg.get_provides()); + let replaces_and_provides = array_merge_map( + (*pkg.get_replaces()).clone(), + (*pkg.get_provides()).clone(), + ); for prov in replaces_and_provides.values() { if link.get_target() == prov.get_target() { version = prov.get_constraint().clone(); @@ -309,9 +313,10 @@ impl InstalledRepository { if !link.get_constraint().matches(&version) { if let Some(root_pkg) = root_package.as_ref() { - let mut root_reqs: IndexMap<String, Link> = root_pkg.get_requires(); - for (k, v) in root_pkg.get_dev_requires() { - root_reqs.entry(k).or_insert(v); + let mut root_reqs: IndexMap<String, Link> = + (*root_pkg.get_requires()).clone(); + for (k, v) in root_pkg.get_dev_requires().iter() { + root_reqs.entry(k.clone()).or_insert(v.clone()); } for root_req in root_reqs.values() { if pkg diff --git a/crates/shirabe/src/repository/repository_utils.rs b/crates/shirabe/src/repository/repository_utils.rs index c2997f31..3df86b05 100644 --- a/crates/shirabe/src/repository/repository_utils.rs +++ b/crates/shirabe/src/repository/repository_utils.rs @@ -16,9 +16,14 @@ impl RepositoryUtils { include_require_dev: bool, mut bucket: Vec<crate::package::BasePackageHandle>, ) -> Vec<crate::package::BasePackageHandle> { - let mut requires: IndexMap<String, Link> = requirer.get_requires(); + let mut requires: IndexMap<String, Link> = (*requirer.get_requires()).clone(); if include_require_dev { - requires.extend(requirer.get_dev_requires()); + requires.extend( + requirer + .get_dev_requires() + .iter() + .map(|(k, v)| (k.clone(), v.clone())), + ); } for candidate in packages { diff --git a/crates/shirabe/src/repository/vcs/github_driver.rs b/crates/shirabe/src/repository/vcs/github_driver.rs index f2b2d458..60920969 100644 --- a/crates/shirabe/src/repository/vcs/github_driver.rs +++ b/crates/shirabe/src/repository/vcs/github_driver.rs @@ -1230,7 +1230,7 @@ impl GitHubDriver { } let links = explode(",", &header); - for link in &links { + for link in links.iter() { if let Some(m) = preg_match(php_regex!(r#"{<(.+?)>; *rel="next"}"#), link) { return Some(m.get(1).unwrap_or_default().to_string()); } diff --git a/crates/shirabe/src/repository/vcs/gitlab_driver.rs b/crates/shirabe/src/repository/vcs/gitlab_driver.rs index d21a9ca1..f77eec5d 100644 --- a/crates/shirabe/src/repository/vcs/gitlab_driver.rs +++ b/crates/shirabe/src/repository/vcs/gitlab_driver.rs @@ -972,7 +972,7 @@ impl GitLabDriver { let header = response.get_header("link").unwrap_or_default(); let links = explode(",", &header); - for link in &links { + for link in links.iter() { if let Some(match_) = preg_match(php_regex!(r#"{<(.+?)>; *rel="next"}"#), link) { return Some(match_.get(1).unwrap_or_default().to_string()); } |
