aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-03-07 22:13:01 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-03-07 22:13:01 +0000
commit51e09af4120ba2fd4d9a1562510988564b480c69 (patch)
tree0e3c73eb2b1c77f64543e2307fdb77fb27d7b994
parent12a7a8b5a83d209153c95b2215f4ddcebd5c4c41 (diff)
downloadpaludis-51e09af4120ba2fd4d9a1562510988564b480c69.tar.gz
paludis-51e09af4120ba2fd4d9a1562510988564b480c69.tar.xz
Implement dependent removing
-rw-r--r--paludis/resolver/decider.cc101
-rw-r--r--paludis/resolver/decider.hh5
2 files changed, 73 insertions, 33 deletions
diff --git a/paludis/resolver/decider.cc b/paludis/resolver/decider.cc
index 8e9647d..7797a63 100644
--- a/paludis/resolver/decider.cc
+++ b/paludis/resolver/decider.cc
@@ -53,6 +53,7 @@
#include <paludis/slot_requirement.hh>
#include <paludis/choice.hh>
#include <paludis/action.hh>
+#include <paludis/elike_slot_requirement.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
@@ -138,50 +139,81 @@ Decider::_resolve_decide_with_dependencies()
}
}
-void
+bool
Decider::_resolve_dependents()
{
Context context("When finding dependents:");
- bool changed(true);
- while (changed)
- {
- changed = false;
+ bool changed(false);
+ const std::pair<
+ std::tr1::shared_ptr<const PackageIDSequence>,
+ std::tr1::shared_ptr<const PackageIDSequence> > changing(_collect_changing());
- const std::pair<
- std::tr1::shared_ptr<const PackageIDSequence>,
- std::tr1::shared_ptr<const PackageIDSequence> > changing(_collect_changing());
+ if (changing.first->empty())
+ return false;
- if (changing.first->empty())
- break;
+ const std::tr1::shared_ptr<const PackageIDSequence> staying(_collect_staying(changing.first));
- const std::tr1::shared_ptr<const PackageIDSequence> staying(_collect_staying(changing.first));
+ for (PackageIDSequence::ConstIterator s(staying->begin()), s_end(staying->end()) ;
+ s != s_end ; ++s)
+ {
+ _imp->env->trigger_notifier_callback(NotifierCallbackResolverStepEvent());
- for (PackageIDSequence::ConstIterator s(staying->begin()), s_end(staying->end()) ;
- s != s_end ; ++s)
- {
- _imp->env->trigger_notifier_callback(NotifierCallbackResolverStepEvent());
+ bool allowed_to_break(_allowed_to_break(*s)), should_remove(_remove_if_dependent(*s));
- bool allowed_to_break(_allowed_to_break(*s)), should_remove(_remove_if_dependent(*s));
+ if (allowed_to_break && ! should_remove)
+ continue;
- if (allowed_to_break && ! should_remove)
- continue;
+ if (! _dependent(*s, changing.first, changing.second))
+ continue;
- if (! _dependent(*s, changing.first, changing.second))
- continue;
+ if (should_remove)
+ {
+ Resolvent resolvent(*s, dt_install_to_slash);
- if (should_remove)
- {
- throw InternalError(PALUDIS_HERE, "remove " + stringify(**s));
- }
- else if (! allowed_to_break)
- {
- throw InternalError(PALUDIS_HERE, "unsafe " + stringify(**s));
- }
+ /* we've changed things if we've not already done anything for this resolvent */
+ if (_imp->resolutions_by_resolvent.end() == _imp->resolutions_by_resolvent.find(resolvent))
+ changed = true;
+
+ const std::tr1::shared_ptr<Resolution> resolution(_resolution_for_resolvent(resolvent, true));
+ _apply_resolution_constraint(resolvent, _resolution_for_resolvent(resolvent, true),
+ _make_constraint_for_removing_dependent(*s));
+ }
+ else if (! allowed_to_break)
+ {
+ throw InternalError(PALUDIS_HERE, "unsafe " + stringify(**s));
}
}
+
+ return changed;
+}
+
+const std::tr1::shared_ptr<const Constraint>
+Decider::_make_constraint_for_removing_dependent(
+ const std::tr1::shared_ptr<const PackageID> & id) const
+{
+ const std::tr1::shared_ptr<PresetReason> reason(new PresetReason("dependent", make_null_shared_ptr()));
+
+ PartiallyMadePackageDepSpec partial_spec((PartiallyMadePackageDepSpecOptions()));
+ partial_spec.package(id->name());
+ if (id->slot_key())
+ partial_spec.slot_requirement(make_shared_ptr(new ELikeSlotExactRequirement(
+ id->slot_key()->value(), false)));
+ PackageDepSpec spec(partial_spec);
+
+ const std::tr1::shared_ptr<Constraint> result(new Constraint(make_named_values<Constraint>(
+ value_for<n::destination_type>(dt_install_to_slash),
+ value_for<n::nothing_is_fine_too>(true),
+ value_for<n::reason>(reason),
+ value_for<n::spec>(BlockDepSpec("!" + stringify(spec), spec, false)),
+ value_for<n::untaken>(false),
+ value_for<n::use_existing>(ue_if_possible)
+ )));
+
+ return result;
}
+
namespace
{
struct DependentChecker
@@ -1733,10 +1765,15 @@ Decider::add_target_with_reason(const PackageOrBlockDepSpec & spec, const std::t
void
Decider::resolve()
{
- _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Deciding"));
- _resolve_decide_with_dependencies();
- _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Finding Dependents"));
- _resolve_dependents();
+ while (true)
+ {
+ _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Deciding"));
+ _resolve_decide_with_dependencies();
+ _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Finding Dependents"));
+ if (! _resolve_dependents())
+ break;
+ }
+
_imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Finding Destinations"));
_resolve_destinations();
}
diff --git a/paludis/resolver/decider.hh b/paludis/resolver/decider.hh
index a39cda9..9e6918a 100644
--- a/paludis/resolver/decider.hh
+++ b/paludis/resolver/decider.hh
@@ -85,6 +85,9 @@ namespace paludis
const Resolvent & resolvent, const BlockDepSpec & dep,
const std::tr1::shared_ptr<const Reason> & reason) const;
+ const std::tr1::shared_ptr<const Constraint> _make_constraint_for_removing_dependent(
+ const std::tr1::shared_ptr<const PackageID> &) const;
+
void _apply_resolution_constraint(const Resolvent &,
const std::tr1::shared_ptr<Resolution> &,
const std::tr1::shared_ptr<const Constraint> &);
@@ -123,7 +126,7 @@ namespace paludis
const ChangesToMakeDecision &) const;
void _resolve_decide_with_dependencies();
- void _resolve_dependents();
+ bool _resolve_dependents() PALUDIS_ATTRIBUTE((warn_unused_result));
void _resolve_destinations();
const std::tr1::shared_ptr<Destination> _make_destination_for(