diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-22 04:19:14 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-22 04:19:25 +0900 |
| commit | 2a1696906344cb4da768a940bf8b1f89bbc82b47 (patch) | |
| tree | 9e37f93baaa9858037ab3a25b13a676f07ccb3a9 /crates/shirabe/src/dependency_resolver | |
| parent | 6739da8a8e271a82d1bf8ca79bba58640ae6e743 (diff) | |
| download | php-shirabe-2a1696906344cb4da768a940bf8b1f89bbc82b47.tar.gz php-shirabe-2a1696906344cb4da768a940bf8b1f89bbc82b47.tar.zst php-shirabe-2a1696906344cb4da768a940bf8b1f89bbc82b47.zip | |
refactor: share Pool via Rc<RefCell>
Convert Pool to Rc<RefCell<Pool>> so Solver, Decisions, and
RuleSetGenerator share it, resolving the todo!() placeholders that
blocked the dependency resolver (Phase C shared ownership).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/dependency_resolver')
4 files changed, 33 insertions, 29 deletions
diff --git a/crates/shirabe/src/dependency_resolver/decisions.rs b/crates/shirabe/src/dependency_resolver/decisions.rs index 1fdc1d3..f0842d9 100644 --- a/crates/shirabe/src/dependency_resolver/decisions.rs +++ b/crates/shirabe/src/dependency_resolver/decisions.rs @@ -8,7 +8,7 @@ use shirabe_php_shim::LogicException; use std::fmt; pub struct Decisions { - pub(crate) pool: Pool, + pub(crate) pool: std::rc::Rc<std::cell::RefCell<Pool>>, pub(crate) decision_map: IndexMap<i64, i64>, pub(crate) decision_queue: Vec<(i64, Box<dyn Rule>)>, iterator_cursor: Option<usize>, @@ -27,7 +27,7 @@ impl Decisions { pub const DECISION_LITERAL: usize = 0; pub const DECISION_REASON: usize = 1; - pub fn new(pool: Pool) -> Self { + pub fn new(pool: std::rc::Rc<std::cell::RefCell<Pool>>) -> Self { Self { pool, decision_map: IndexMap::new(), @@ -187,10 +187,9 @@ impl Decisions { let previous_decision = self.decision_map.get(&package_id).copied().unwrap_or(0); if previous_decision != 0 { - let literal_string = self - .pool - .literal_to_pretty_string(literal, &IndexMap::new()); - let package = self.pool.literal_to_package(literal); + let pool = self.pool.borrow(); + let literal_string = pool.literal_to_pretty_string(literal, &IndexMap::new()); + let package = pool.literal_to_package(literal); panic!( "{}", SolverBugException::new(format!( diff --git a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs index 57d1d18..2d99d7f 100644 --- a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs +++ b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs @@ -24,14 +24,17 @@ use crate::package::PackageInterface; #[derive(Debug)] pub struct RuleSetGenerator { pub(crate) policy: Box<dyn PolicyInterface>, - pub(crate) pool: Pool, + pub(crate) pool: std::rc::Rc<std::cell::RefCell<Pool>>, pub(crate) rules: RuleSet, pub(crate) added_map: IndexMap<i64, Box<dyn PackageInterface>>, pub(crate) added_packages_by_names: IndexMap<String, Vec<Box<dyn PackageInterface>>>, } impl RuleSetGenerator { - pub fn new(policy: Box<dyn PolicyInterface>, pool: Pool) -> Self { + pub fn new( + policy: Box<dyn PolicyInterface>, + pool: std::rc::Rc<std::cell::RefCell<Pool>>, + ) -> Self { Self { policy, pool, @@ -221,6 +224,7 @@ impl RuleSetGenerator { let possible_requires: Vec<Box<dyn PackageInterface>> = self .pool + .borrow_mut() .what_provides(link.get_target(), Some(&*constraint)) .into_iter() .map(|p| p.clone_package_box()) @@ -276,6 +280,7 @@ impl RuleSetGenerator { let conflicts = self .pool + .borrow_mut() .what_provides(link.get_target(), Some(&*constraint)); for conflict in &conflicts { @@ -327,6 +332,7 @@ impl RuleSetGenerator { // fixed package was not added to the pool as it did not pass the stability requirements, this is fine if self .pool + .borrow() .is_unacceptable_fixed_or_locked_package(package.as_ref()) { continue; @@ -373,6 +379,7 @@ impl RuleSetGenerator { let packages: Vec<Box<dyn PackageInterface>> = self .pool + .borrow_mut() .what_provides(package_name, Some(&*constraint)) .into_iter() .map(|p| p.clone_package_box()) @@ -412,6 +419,7 @@ impl RuleSetGenerator { ) { let packages: Vec<Box<dyn BasePackage>> = self .pool + .borrow() .get_packages() .iter() .map(|p| p.clone_box()) diff --git a/crates/shirabe/src/dependency_resolver/rule_watch_graph.rs b/crates/shirabe/src/dependency_resolver/rule_watch_graph.rs index 639061d..6c41e62 100644 --- a/crates/shirabe/src/dependency_resolver/rule_watch_graph.rs +++ b/crates/shirabe/src/dependency_resolver/rule_watch_graph.rs @@ -44,7 +44,7 @@ impl RuleWatchGraph { self.watch_chains .get_mut(&literal) .unwrap() - .unshift(std::rc::Rc::clone(&node)); + .unshift(node.clone()); } } else { let literals: Vec<i64> = node.borrow().get_rule().get_literals().clone(); @@ -55,7 +55,7 @@ impl RuleWatchGraph { self.watch_chains .get_mut(&literal) .unwrap() - .unshift(std::rc::Rc::clone(&node)); + .unshift(node.clone()); } } } diff --git a/crates/shirabe/src/dependency_resolver/solver.rs b/crates/shirabe/src/dependency_resolver/solver.rs index f9721f8..fd30165 100644 --- a/crates/shirabe/src/dependency_resolver/solver.rs +++ b/crates/shirabe/src/dependency_resolver/solver.rs @@ -31,7 +31,7 @@ use crate::package::BasePackage; #[derive(Debug)] pub struct Solver { pub(crate) policy: Box<dyn PolicyInterface>, - pub(crate) pool: Pool, + pub(crate) pool: std::rc::Rc<std::cell::RefCell<Pool>>, pub(crate) rules: RuleSet, @@ -55,17 +55,18 @@ impl Solver { const BRANCH_LITERALS: usize = 0; const BRANCH_LEVEL: usize = 1; - pub fn new(policy: Box<dyn PolicyInterface>, pool: Pool, io: Box<dyn IOInterface>) -> Self { + pub fn new( + policy: Box<dyn PolicyInterface>, + pool: std::rc::Rc<std::cell::RefCell<Pool>>, + io: Box<dyn IOInterface>, + ) -> Self { + let decisions = Decisions::new(pool.clone()); Self { policy, pool, rules: RuleSet::new(), watch_graph: RuleWatchGraph::new(), - // TODO(phase-b): PHP shares `$pool` between Solver and Decisions by reference. - // Pool has no `Default`/`Clone` impl, so we leave this placeholder until the - // resolver is refactored to use `Rc<RefCell<Pool>>`. `solve()` rebuilds the - // decisions field before any access. - decisions: todo!("Decisions::new requires a shared Pool reference"), + decisions, fixed_map: IndexMap::new(), propagate_index: 0, branches: Vec::new(), @@ -81,8 +82,8 @@ impl Solver { self.rules.count() } - pub fn get_pool(&self) -> &Pool { - &self.pool + pub fn get_pool(&self) -> std::rc::Rc<std::cell::RefCell<Pool>> { + self.pool.clone() } // aka solver_makeruledecisions @@ -213,6 +214,7 @@ impl Solver { if self .pool + .borrow_mut() .what_provides(package_name, Some(active_constraint)) .is_empty() { @@ -252,20 +254,15 @@ impl Solver { self.io .write_error3("Generating rules", true, crate::io::DEBUG); - // TODO(phase-b): Pool is a PHP class without Clone; RuleSetGenerator should hold - // a shared reference (Rc<RefCell<Pool>>). Using a placeholder pool until then. - let mut rule_set_generator = RuleSetGenerator::new( - self.policy.clone_box(), - todo!("share Pool with RuleSetGenerator"), - ); + let mut rule_set_generator = + RuleSetGenerator::new(self.policy.clone_box(), self.pool.clone()); // TODO(phase-b): get_rules_for takes Option<Box<dyn PlatformRequirementFilterInterface>>; // PHP passes the filter directly. Forwarding `None` here keeps the call typecheckable. let _ = platform_requirement_filter.as_ref(); self.rules = rule_set_generator.get_rules_for(request, None)?; drop(rule_set_generator); self.check_for_root_require_problems(request, platform_requirement_filter.as_ref()); - // TODO(phase-b): Pool sharing — same as above. - self.decisions = Decisions::new(todo!("share Pool with Decisions")); + self.decisions = Decisions::new(self.pool.clone()); self.watch_graph = RuleWatchGraph::new(); // TODO(phase-b): RuleSet does not expose `iter()`; RuleWatchNode expects @@ -306,7 +303,7 @@ impl Solver { // and borrows Pool/Decisions. The present/fixed maps from Request are keyed // by BasePackage; converting requires reworking Request. Ok(LockTransaction::new( - &self.pool, + &*self.pool.borrow(), todo!("convert request.get_present_map(false) to PackageInterface map"), todo!("convert request.get_fixed_packages_map() to PackageInterface map"), &self.decisions, @@ -435,7 +432,7 @@ impl Solver { ) -> anyhow::Result<i64> { // choose best package to install from decisionQueue let mut literals = self.policy.select_preferred_packages( - &self.pool, + &*self.pool.borrow(), decision_queue, rule.get_required_package(), ); |
