aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/command
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-08-19 23:45:38 +0900
committernsfisis <nsfisis@gmail.com>2026-08-19 23:45:38 +0900
commitcd7c3fce2472656b2a1247429751e43350976677 (patch)
tree95e8760e3417fc3e63dac28bc0cd823a6af768f2 /crates/shirabe/src/command
parentb8fb046bd7c4cd28598bcce9f3955d834ea5d008 (diff)
downloadphp-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/command')
-rw-r--r--crates/shirabe/src/command/bump_command.rs9
-rw-r--r--crates/shirabe/src/command/check_platform_reqs_command.rs45
-rw-r--r--crates/shirabe/src/command/remove_command.rs10
-rw-r--r--crates/shirabe/src/command/require_command.rs10
-rw-r--r--crates/shirabe/src/command/show_command.rs4
-rw-r--r--crates/shirabe/src/command/update_command.rs14
6 files changed, 55 insertions, 37 deletions
diff --git a/crates/shirabe/src/command/bump_command.rs b/crates/shirabe/src/command/bump_command.rs
index 8f95366f..71ee2ffe 100644
--- a/crates/shirabe/src/command/bump_command.rs
+++ b/crates/shirabe/src/command/bump_command.rs
@@ -167,10 +167,13 @@ impl BumpCommand {
let bumper = VersionBumper;
let mut tasks = indexmap::IndexMap::new();
if !dev_only {
- tasks.insert("require", composer.get_package().get_requires());
+ tasks.insert("require", (*composer.get_package().get_requires()).clone());
}
if !no_dev_only {
- tasks.insert("require-dev", composer.get_package().get_dev_requires());
+ tasks.insert(
+ "require-dev",
+ (*composer.get_package().get_dev_requires()).clone(),
+ );
}
let packages_filter = if !packages_filter.is_empty() {
@@ -196,7 +199,7 @@ impl BumpCommand {
let mut updates: indexmap::IndexMap<&str, indexmap::IndexMap<String, String>> =
indexmap::IndexMap::new();
for (key, reqs) in &tasks {
- for (pkg_name, link) in reqs {
+ for (pkg_name, link) in reqs.iter() {
if PlatformRepository::is_platform_package(pkg_name) {
continue;
}
diff --git a/crates/shirabe/src/command/check_platform_reqs_command.rs b/crates/shirabe/src/command/check_platform_reqs_command.rs
index 21e71fee..b672b9cd 100644
--- a/crates/shirabe/src/command/check_platform_reqs_command.rs
+++ b/crates/shirabe/src/command/check_platform_reqs_command.rs
@@ -243,7 +243,7 @@ impl Command for CheckPlatformReqsCommand {
};
if !no_dev {
- for (require, link) in composer.get_package().get_dev_requires() {
+ for (require, link) in composer.get_package().get_dev_requires().iter() {
requires
.entry(require.to_string())
.or_default()
@@ -263,7 +263,7 @@ impl Command for CheckPlatformReqsCommand {
if remove_packages.contains(&package.get_name().to_string()) {
continue;
}
- for (require, link) in package.get_requires() {
+ for (require, link) in package.get_requires().iter() {
requires
.entry(require.to_string())
.or_default()
@@ -289,27 +289,28 @@ impl Command for CheckPlatformReqsCommand {
if !candidates.is_empty() {
let mut req_results: Vec<CheckResult> = vec![];
'candidates: for candidate in &candidates {
- let candidate_constraint: Option<AnyConstraint> = if candidate.get_name()
- == *require
- {
- let c = SimpleConstraint::new(
- "=".to_string(),
- candidate.get_version().to_string(),
- Some(candidate.get_pretty_version().to_string()),
- );
- Some(c.into())
- } else {
- let mut found: Option<AnyConstraint> = None;
- let provides_and_replaces =
- array_merge_map(candidate.get_provides(), candidate.get_replaces());
- for (_, link) in &provides_and_replaces {
- if link.get_target() == require {
- found = Some(link.get_constraint().clone());
- break;
+ let candidate_constraint: Option<AnyConstraint> =
+ if candidate.get_name() == *require {
+ let c = SimpleConstraint::new(
+ "=".to_string(),
+ candidate.get_version().to_string(),
+ Some(candidate.get_pretty_version().to_string()),
+ );
+ Some(c.into())
+ } else {
+ let mut found: Option<AnyConstraint> = None;
+ let provides_and_replaces = array_merge_map(
+ (*candidate.get_provides()).clone(),
+ (*candidate.get_replaces()).clone(),
+ );
+ for (_, link) in &provides_and_replaces {
+ if link.get_target() == require {
+ found = Some(link.get_constraint().clone());
+ break;
+ }
}
- }
- found
- };
+ found
+ };
let candidate_constraint = match candidate_constraint {
Some(c) => c,
diff --git a/crates/shirabe/src/command/remove_command.rs b/crates/shirabe/src/command/remove_command.rs
index 9004a9fd..e50999bb 100644
--- a/crates/shirabe/src/command/remove_command.rs
+++ b/crates/shirabe/src/command/remove_command.rs
@@ -479,8 +479,14 @@ impl Command for RemoveCommand {
if dry_run {
let root_package = composer.get_package();
let mut links: IndexMap<String, IndexMap<String, _>> = IndexMap::new();
- links.insert("require".to_string(), root_package.get_requires());
- links.insert("require-dev".to_string(), root_package.get_dev_requires());
+ links.insert(
+ "require".to_string(),
+ (*root_package.get_requires()).clone(),
+ );
+ links.insert(
+ "require-dev".to_string(),
+ (*root_package.get_dev_requires()).clone(),
+ );
for (link_type, names) in &to_remove {
for name in names {
if let Some(section) = links.get_mut(link_type.as_str()) {
diff --git a/crates/shirabe/src/command/require_command.rs b/crates/shirabe/src/command/require_command.rs
index 15eae91b..197adfd6 100644
--- a/crates/shirabe/src/command/require_command.rs
+++ b/crates/shirabe/src/command/require_command.rs
@@ -200,8 +200,14 @@ impl RequireCommand {
let root_package = composer.get_package();
let mut links: IndexMap<String, IndexMap<String, crate::package::Link>> =
IndexMap::new();
- links.insert("require".to_string(), root_package.get_requires());
- links.insert("require-dev".to_string(), root_package.get_dev_requires());
+ links.insert(
+ "require".to_string(),
+ (*root_package.get_requires()).clone(),
+ );
+ links.insert(
+ "require-dev".to_string(),
+ (*root_package.get_dev_requires()).clone(),
+ );
let loader = ArrayLoader::new(None, false);
let requirements_mixed: IndexMap<String, PhpMixed> = requirements
.iter()
diff --git a/crates/shirabe/src/command/show_command.rs b/crates/shirabe/src/command/show_command.rs
index f605e2b5..090678eb 100644
--- a/crates/shirabe/src/command/show_command.rs
+++ b/crates/shirabe/src/command/show_command.rs
@@ -939,7 +939,7 @@ impl ShowCommand {
remote_repos: &RepositoryInterfaceHandle,
) -> PackageTree {
let requires = {
- let mut r: IndexMap<String, Link> = package.get_requires();
+ let mut r: IndexMap<String, Link> = (*package.get_requires()).clone();
r.sort_keys();
r
};
@@ -1055,7 +1055,7 @@ impl ShowCommand {
};
let (package, _) = self.get_package(installed_repo, remote_repos, name, version_arg)?;
if let Some(package) = package {
- let mut requires = package.get_requires();
+ let mut requires = (*package.get_requires()).clone();
requires.sort_keys();
for (require_name, require) in requires.iter() {
let mut current_tree = packages_in_tree.to_vec();
diff --git a/crates/shirabe/src/command/update_command.rs b/crates/shirabe/src/command/update_command.rs
index 0548fc02..09809eb2 100644
--- a/crates/shirabe/src/command/update_command.rs
+++ b/crates/shirabe/src/command/update_command.rs
@@ -83,8 +83,8 @@ impl UpdateCommand {
let platform_req_filter = self.get_platform_requirement_filter(input);
let stability_flags = composer_ref.get_package().get_stability_flags();
let requires = array_merge_map(
- composer_ref.get_package().get_requires(),
- composer_ref.get_package().get_dev_requires(),
+ (*composer_ref.get_package().get_requires()).clone(),
+ (*composer_ref.get_package().get_dev_requires()).clone(),
);
let filter: Option<String> = if !packages.is_empty() {
@@ -156,7 +156,7 @@ impl UpdateCommand {
}
}
if installed_packages.is_empty() {
- for (req, _constraint) in &requires {
+ for (req, _constraint) in requires.iter() {
if PlatformRepository::is_platform_package(req) {
continue;
}
@@ -401,9 +401,11 @@ impl Command for UpdateCommand {
let parser = VersionParser::new();
let mut temporary_constraints: IndexMap<String, _> = IndexMap::new();
- let root_requirements =
- array_merge_map(root_package.get_requires(), root_package.get_dev_requires());
- for (package, constraint) in &reqs {
+ let root_requirements = array_merge_map(
+ (*root_package.get_requires()).clone(),
+ (*root_package.get_dev_requires()).clone(),
+ );
+ for (package, constraint) in reqs.iter() {
let package = strtolower(package);
let parsed_constraint = parser.parse_constraints(constraint)?;
temporary_constraints.insert(package.clone(), parsed_constraint.clone());