aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-06-28 11:40:26 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-06-28 12:13:06 +0100
commit39a39db092298018330339d5303a76c887abe0eb (patch)
tree62e2d4c08263c1b81452ba2d8b73bb8f2cbcf3f3
parentc40ae4b578f905df8aa5656b7763956e19165094 (diff)
downloadpaludis-39a39db092298018330339d5303a76c887abe0eb.tar.gz
paludis-39a39db092298018330339d5303a76c887abe0eb.tar.xz
Part-copy constraints across destinations
-rw-r--r--paludis/resolver/constraint.cc5
-rw-r--r--paludis/resolver/decider.cc93
-rw-r--r--paludis/resolver/decider.hh9
-rw-r--r--paludis/resolver/orderer.cc6
-rw-r--r--paludis/resolver/reason-fwd.hh1
-rw-r--r--paludis/resolver/reason.cc55
-rw-r--r--paludis/resolver/reason.hh18
-rw-r--r--src/clients/cave/cmd_display_resolution.cc11
-rw-r--r--src/clients/cave/cmd_resolve_dump.cc8
-rw-r--r--src/clients/cave/resolve_common.cc27
10 files changed, 228 insertions, 5 deletions
diff --git a/paludis/resolver/constraint.cc b/paludis/resolver/constraint.cc
index 055cddd..a50c0fe 100644
--- a/paludis/resolver/constraint.cc
+++ b/paludis/resolver/constraint.cc
@@ -159,6 +159,11 @@ namespace
return make_null_shared_ptr();
}
+ const std::tr1::shared_ptr<const PackageID> visit(const LikeOtherDestinationTypeReason &) const
+ {
+ return make_null_shared_ptr();
+ }
+
const std::tr1::shared_ptr<const PackageID> visit(const PresetReason &) const
{
return make_null_shared_ptr();
diff --git a/paludis/resolver/decider.cc b/paludis/resolver/decider.cc
index c7ea559..a5dc18f 100644
--- a/paludis/resolver/decider.cc
+++ b/paludis/resolver/decider.cc
@@ -517,19 +517,21 @@ Decider::_create_resolution_for_resolvent(const Resolvent & r) const
}
const std::tr1::shared_ptr<Resolution>
-Decider::_resolution_for_resolvent(const Resolvent & r, const bool create)
+Decider::_resolution_for_resolvent(const Resolvent & r, const Tribool if_not_exist)
{
ResolutionsByResolvent::ConstIterator i(_imp->resolutions_by_resolvent->find(r));
if (_imp->resolutions_by_resolvent->end() == i)
{
- if (create)
+ if (if_not_exist.is_true())
{
std::tr1::shared_ptr<Resolution> resolution(_create_resolution_for_resolvent(r));
i = _imp->resolutions_by_resolvent->insert_new(resolution);
}
- else
+ else if (if_not_exist.is_false())
throw InternalError(PALUDIS_HERE, "resolver bug: expected resolution for "
+ stringify(r) + " to exist, but it doesn't");
+ else
+ return make_null_shared_ptr();
}
return *i;
@@ -893,6 +895,8 @@ Decider::_decide(const std::tr1::shared_ptr<Resolution> & resolution)
{
Context context("When deciding upon an origin ID to use for '" + stringify(resolution->resolvent()) + "':");
+ _copy_other_destination_constraints(resolution);
+
std::tr1::shared_ptr<Decision> decision(_try_to_find_decision_for(resolution));
if (decision)
resolution->decision() = decision;
@@ -900,6 +904,35 @@ Decider::_decide(const std::tr1::shared_ptr<Resolution> & resolution)
resolution->decision() = _cannot_decide_for(resolution);
}
+void
+Decider::_copy_other_destination_constraints(const std::tr1::shared_ptr<Resolution> & resolution)
+{
+ for (EnumIterator<DestinationType> t, t_end(last_dt) ; t != t_end ; ++t)
+ {
+ if (*t == resolution->resolvent().destination_type())
+ continue;
+
+ Resolvent copy_from_resolvent(resolution->resolvent());
+ copy_from_resolvent.destination_type() = *t;
+
+ const std::tr1::shared_ptr<Resolution> copy_from_resolution(
+ _resolution_for_resolvent(copy_from_resolvent, indeterminate));
+ if (! copy_from_resolution)
+ continue;
+
+ for (Constraints::ConstIterator c(copy_from_resolution->constraints()->begin()),
+ c_end(copy_from_resolution->constraints()->end()) ;
+ c != c_end ; ++c)
+ {
+ const std::tr1::shared_ptr<ConstraintSequence> constraints(_make_constraints_from_other_destination(
+ resolution, copy_from_resolution, *c));
+ for (ConstraintSequence::ConstIterator d(constraints->begin()), d_end(constraints->end()) ;
+ d != d_end ; ++d)
+ _apply_resolution_constraint(resolution, *d);
+ }
+ }
+}
+
namespace
{
struct DependenciesNecessityVisitor
@@ -2063,3 +2096,57 @@ Decider::_make_constraints_for_purge(
return _imp->fns.get_constraints_for_purge_fn()(resolution, id, r);
}
+namespace
+{
+ struct ConstraintFromOtherDestinationVisitor
+ {
+ const DestinationType destination_type;
+ const std::tr1::shared_ptr<const Constraint> from_constraint;
+ const Resolvent resolvent;
+
+ ConstraintFromOtherDestinationVisitor(
+ const DestinationType t,
+ const std::tr1::shared_ptr<const Constraint> f,
+ const Resolvent & r) :
+ destination_type(t),
+ from_constraint(f),
+ resolvent(r)
+ {
+ }
+
+ const std::tr1::shared_ptr<ConstraintSequence> visit(const LikeOtherDestinationTypeReason &) const
+ {
+ std::tr1::shared_ptr<ConstraintSequence> result(new ConstraintSequence);
+ return result;
+ }
+
+ const std::tr1::shared_ptr<ConstraintSequence> visit(const Reason &) const
+ {
+ std::tr1::shared_ptr<ConstraintSequence> result(new ConstraintSequence);
+ result->push_back(make_shared_copy(make_named_values<Constraint>(
+ n::destination_type() = destination_type,
+ n::nothing_is_fine_too() = true,
+ n::reason() = make_shared_ptr(new LikeOtherDestinationTypeReason(
+ resolvent,
+ from_constraint->reason()
+ )),
+ n::spec() = from_constraint->spec(),
+ n::untaken() = from_constraint->untaken(),
+ n::use_existing() = ue_if_possible
+ )));
+ return result;
+ }
+ };
+}
+
+const std::tr1::shared_ptr<ConstraintSequence>
+Decider::_make_constraints_from_other_destination(
+ const std::tr1::shared_ptr<const Resolution> & new_resolution,
+ const std::tr1::shared_ptr<const Resolution> & from_resolution,
+ const std::tr1::shared_ptr<const Constraint> & from_constraint) const
+{
+ return from_constraint->reason()->accept_returning<std::tr1::shared_ptr<ConstraintSequence> >(
+ ConstraintFromOtherDestinationVisitor(new_resolution->resolvent().destination_type(),
+ from_constraint, from_resolution->resolvent()));
+}
+
diff --git a/paludis/resolver/decider.hh b/paludis/resolver/decider.hh
index fa4dd21..708614f 100644
--- a/paludis/resolver/decider.hh
+++ b/paludis/resolver/decider.hh
@@ -39,6 +39,7 @@
#include <paludis/resolver/resolutions_by_resolvent-fwd.hh>
#include <paludis/util/attributes.hh>
#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/tribool-fwd.hh>
#include <paludis/dep_spec-fwd.hh>
#include <paludis/package_id-fwd.hh>
#include <paludis/repository-fwd.hh>
@@ -54,7 +55,7 @@ namespace paludis
{
private:
const std::tr1::shared_ptr<Resolution> _create_resolution_for_resolvent(const Resolvent &) const;
- const std::tr1::shared_ptr<Resolution> _resolution_for_resolvent(const Resolvent &, const bool create);
+ const std::tr1::shared_ptr<Resolution> _resolution_for_resolvent(const Resolvent &, const Tribool);
const std::tr1::shared_ptr<const Resolvents> _get_resolvents_for_blocker(const BlockDepSpec &) const;
@@ -99,6 +100,11 @@ namespace paludis
const std::tr1::shared_ptr<const PackageID> &,
const std::tr1::shared_ptr<const PackageIDSequence> &) const;
+ const std::tr1::shared_ptr<ConstraintSequence> _make_constraints_from_other_destination(
+ const std::tr1::shared_ptr<const Resolution> & resolution,
+ const std::tr1::shared_ptr<const Resolution> & from_resolution,
+ const std::tr1::shared_ptr<const Constraint> & from_constraint) const;
+
void _apply_resolution_constraint(
const std::tr1::shared_ptr<Resolution> &,
const std::tr1::shared_ptr<const Constraint> &);
@@ -155,6 +161,7 @@ namespace paludis
FilteredGenerator _make_destination_filtered_generator(const Generator &, const Resolvent & resolvent) const;
void _decide(const std::tr1::shared_ptr<Resolution> & resolution);
+ void _copy_other_destination_constraints(const std::tr1::shared_ptr<Resolution> & resolution);
const std::tr1::shared_ptr<Decision> _try_to_find_decision_for(
const std::tr1::shared_ptr<const Resolution> & resolution) const;
diff --git a/paludis/resolver/orderer.cc b/paludis/resolver/orderer.cc
index dc7e0aa..80ef112 100644
--- a/paludis/resolver/orderer.cc
+++ b/paludis/resolver/orderer.cc
@@ -350,6 +350,12 @@ namespace
r.reason_for_set()->accept(*this);
}
+ void visit(const LikeOtherDestinationTypeReason & r)
+ {
+ if (r.reason_for_other())
+ r.reason_for_other()->accept(*this);
+ }
+
void visit(const PresetReason &)
{
}
diff --git a/paludis/resolver/reason-fwd.hh b/paludis/resolver/reason-fwd.hh
index 4b64a74..d76f90f 100644
--- a/paludis/resolver/reason-fwd.hh
+++ b/paludis/resolver/reason-fwd.hh
@@ -33,6 +33,7 @@ namespace paludis
struct SetReason;
struct DependentReason;
struct WasUsedByReason;
+ struct LikeOtherDestinationTypeReason;
}
}
diff --git a/paludis/resolver/reason.cc b/paludis/resolver/reason.cc
index 3969bf5..5731e54 100644
--- a/paludis/resolver/reason.cc
+++ b/paludis/resolver/reason.cc
@@ -272,6 +272,52 @@ SetReason::serialise(Serialiser & s) const
;
}
+namespace paludis
+{
+ template <>
+ struct Implementation<LikeOtherDestinationTypeReason>
+ {
+ const Resolvent other_resolvent;
+ const std::tr1::shared_ptr<const Reason> reason_for_other;
+
+ Implementation(const Resolvent & s, const std::tr1::shared_ptr<const Reason> & r) :
+ other_resolvent(s),
+ reason_for_other(r)
+ {
+ }
+ };
+}
+
+LikeOtherDestinationTypeReason::LikeOtherDestinationTypeReason(const Resolvent & s, const std::tr1::shared_ptr<const Reason> & r) :
+ PrivateImplementationPattern<LikeOtherDestinationTypeReason>(new Implementation<LikeOtherDestinationTypeReason>(s, r))
+{
+}
+
+LikeOtherDestinationTypeReason::~LikeOtherDestinationTypeReason()
+{
+}
+
+const Resolvent
+LikeOtherDestinationTypeReason::other_resolvent() const
+{
+ return _imp->other_resolvent;
+}
+
+const std::tr1::shared_ptr<const Reason>
+LikeOtherDestinationTypeReason::reason_for_other() const
+{
+ return _imp->reason_for_other;
+}
+
+void
+LikeOtherDestinationTypeReason::serialise(Serialiser & s) const
+{
+ s.object("LikeOtherDestinationTypeReason")
+ .member(SerialiserFlags<serialise::might_be_null>(), "reason_for_other", reason_for_other())
+ .member(SerialiserFlags<>(), "other_resolvent", other_resolvent())
+ ;
+}
+
const std::tr1::shared_ptr<Reason>
Reason::deserialise(Deserialisation & d)
{
@@ -322,6 +368,14 @@ Reason::deserialise(Deserialisation & d)
ids_being_removed->push_back(vv.member<std::tr1::shared_ptr<const PackageID> >(stringify(n)));
return make_shared_ptr(new WasUsedByReason(ids_being_removed));
}
+ else if (d.class_name() == "LikeOtherDestinationTypeReason")
+ {
+ Deserialisator v(d, "LikeOtherDestinationTypeReason");
+ return make_shared_ptr(new LikeOtherDestinationTypeReason(
+ v.member<Resolvent>("other_resolvent"),
+ v.member<std::tr1::shared_ptr<Reason> >("reason_for_other")
+ ));
+ }
else
throw InternalError(PALUDIS_HERE, "unknown class '" + stringify(d.class_name()) + "'");
}
@@ -331,4 +385,5 @@ template class PrivateImplementationPattern<DependentReason>;
template class PrivateImplementationPattern<SetReason>;
template class PrivateImplementationPattern<PresetReason>;
template class PrivateImplementationPattern<WasUsedByReason>;
+template class PrivateImplementationPattern<LikeOtherDestinationTypeReason>;
diff --git a/paludis/resolver/reason.hh b/paludis/resolver/reason.hh
index b7620d7..90ed077 100644
--- a/paludis/resolver/reason.hh
+++ b/paludis/resolver/reason.hh
@@ -37,7 +37,8 @@ namespace paludis
{
class Reason :
public virtual DeclareAbstractAcceptMethods<Reason, MakeTypeList<
- TargetReason, DependencyReason, DependentReason, WasUsedByReason, PresetReason, SetReason>::Type>
+ TargetReason, DependencyReason, DependentReason, WasUsedByReason, PresetReason,
+ SetReason, LikeOtherDestinationTypeReason>::Type>
{
public:
virtual ~Reason() = 0;
@@ -138,6 +139,21 @@ namespace paludis
virtual void serialise(Serialiser &) const;
};
+
+ class LikeOtherDestinationTypeReason :
+ public Reason,
+ private PrivateImplementationPattern<LikeOtherDestinationTypeReason>,
+ public ImplementAcceptMethods<Reason, LikeOtherDestinationTypeReason>
+ {
+ public:
+ LikeOtherDestinationTypeReason(const Resolvent &, const std::tr1::shared_ptr<const Reason> &);
+ ~LikeOtherDestinationTypeReason();
+
+ const Resolvent other_resolvent() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ const std::tr1::shared_ptr<const Reason> reason_for_other() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ virtual void serialise(Serialiser &) const;
+ };
}
#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
diff --git a/src/clients/cave/cmd_display_resolution.cc b/src/clients/cave/cmd_display_resolution.cc
index 57f289c..d9757d2 100644
--- a/src/clients/cave/cmd_display_resolution.cc
+++ b/src/clients/cave/cmd_display_resolution.cc
@@ -224,6 +224,12 @@ namespace
return std::make_pair(rr.first + " (" + stringify(r.set_name()) + ")", rr.second);
}
+ std::pair<std::string, bool> visit(const LikeOtherDestinationTypeReason & r) const
+ {
+ std::pair<std::string, bool> rr(r.reason_for_other()->accept_returning<std::pair<std::string, bool> >(*this));
+ return std::make_pair(rr.first + " (to be like " + stringify(r.other_resolvent()) + ")", rr.second);
+ }
+
std::pair<std::string, bool> visit(const PresetReason & r) const
{
std::pair<std::string, bool> rr("", false);
@@ -711,6 +717,11 @@ namespace
return r.reason_for_set()->accept_returning<bool>(*this);
}
+ bool visit(const LikeOtherDestinationTypeReason & r) const
+ {
+ return r.reason_for_other()->accept_returning<bool>(*this);
+ }
+
bool visit(const PresetReason &) const
{
return false;
diff --git a/src/clients/cave/cmd_resolve_dump.cc b/src/clients/cave/cmd_resolve_dump.cc
index 9a697bc..93742b6 100644
--- a/src/clients/cave/cmd_resolve_dump.cc
+++ b/src/clients/cave/cmd_resolve_dump.cc
@@ -159,6 +159,14 @@ namespace
str = "Set(" + stringify(r.set_name()) + " " + f.str + ")";
}
+ void visit(const LikeOtherDestinationTypeReason & r)
+ {
+ ReasonFinder f;
+ if (r.reason_for_other())
+ r.reason_for_other()->accept(f);
+ str = "LikeOtherDestinationTypeReason(" + stringify(r.other_resolvent()) + " " + f.str + ")";
+ }
+
void visit(const DependentReason & r)
{
str = "Dependent(" + stringify(*r.id_being_removed()) + ")";
diff --git a/src/clients/cave/resolve_common.cc b/src/clients/cave/resolve_common.cc
index ae02e33..97ec221 100644
--- a/src/clients/cave/resolve_common.cc
+++ b/src/clients/cave/resolve_common.cc
@@ -308,6 +308,11 @@ namespace
return DestinationTypes();
}
+ DestinationTypes visit(const LikeOtherDestinationTypeReason & r) const
+ {
+ return r.reason_for_other()->accept_returning<DestinationTypes>(*this);
+ }
+
DestinationTypes visit(const SetReason & r) const
{
return r.reason_for_set()->accept_returning<DestinationTypes>(*this);
@@ -460,6 +465,12 @@ namespace
UseExistingVisitor v(resolution_options, true);
return r.reason_for_set()->accept_returning<UseExisting>(v);
}
+
+ UseExisting visit(const LikeOtherDestinationTypeReason & r) const
+ {
+ UseExistingVisitor v(resolution_options, true);
+ return r.reason_for_other()->accept_returning<UseExisting>(v);
+ }
};
bool use_existing_from_withish(
@@ -665,6 +676,11 @@ namespace
return true;
}
+ bool visit(const LikeOtherDestinationTypeReason & r) const
+ {
+ return r.reason_for_other()->accept_returning<bool>(*this);
+ }
+
bool visit(const SetReason & r) const
{
return r.reason_for_set()->accept_returning<bool>(*this);
@@ -1038,6 +1054,11 @@ namespace
return r.reason_for_set()->accept_returning<bool>(*this);
}
+ bool visit(const LikeOtherDestinationTypeReason & r) const
+ {
+ return r.reason_for_other()->accept_returning<bool>(*this);
+ }
+
bool visit(const PresetReason &) const
{
return false;
@@ -1539,6 +1560,12 @@ namespace
{
return "from " + stringify(r.set_name()) + " (" + r.reason_for_set()->accept_returning<std::string>(*this) + ")";
}
+
+ const std::string visit(const LikeOtherDestinationTypeReason & r) const
+ {
+ return "from being like " + stringify(r.other_resolvent())
+ + " (" + r.reason_for_other()->accept_returning<std::string>(*this) + ")";
+ }
};
void display_restarts_if_requested(const std::list<SuggestRestart> & restarts,