summaryrefslogtreecommitdiff
path: root/src/generic/problemresolver
diff options
context:
space:
mode:
Diffstat (limited to 'src/generic/problemresolver')
-rw-r--r--src/generic/problemresolver/Makefile.am1
-rw-r--r--src/generic/problemresolver/problemresolver.h151
-rw-r--r--src/generic/problemresolver/promotion_set.h61
-rw-r--r--src/generic/problemresolver/search_graph.h16
-rw-r--r--src/generic/problemresolver/solution.h16
-rw-r--r--src/generic/problemresolver/tier.cc27
-rw-r--r--src/generic/problemresolver/tier.h289
-rw-r--r--src/generic/problemresolver/tier_limits.cc6
-rw-r--r--src/generic/problemresolver/tier_limits.h6
-rw-r--r--src/generic/problemresolver/tier_operation.cc33
-rw-r--r--src/generic/problemresolver/tier_operation.h17
11 files changed, 77 insertions, 546 deletions
diff --git a/src/generic/problemresolver/Makefile.am b/src/generic/problemresolver/Makefile.am
index bb7a1798..f64997e3 100644
--- a/src/generic/problemresolver/Makefile.am
+++ b/src/generic/problemresolver/Makefile.am
@@ -16,7 +16,6 @@ libgeneric_problemresolver_a_SOURCES = \
problemresolver.h \
promotion_set.h sanity_check_universe.h \
search_graph.h solution.h \
- tier.cc tier.h \
tier_limits.cc tier_limits.h \
tier_operation.cc tier_operation.h
diff --git a/src/generic/problemresolver/problemresolver.h b/src/generic/problemresolver/problemresolver.h
index 1d79c100..62609701 100644
--- a/src/generic/problemresolver/problemresolver.h
+++ b/src/generic/problemresolver/problemresolver.h
@@ -548,14 +548,15 @@ public:
*/
bool finished;
- /** \brief The search tier of the next solution to consider.
+ /** \brief The search tier operation of the next solution to
+ * consider.
*/
- tier current_tier;
+ tier_operation current_tier_op;
queue_counts()
: open(0), closed(0), deferred(0), conflicts(0), promotions(0),
finished(false),
- current_tier(tier_limits::minimum_tier)
+ current_tier_op()
{
}
};
@@ -604,10 +605,9 @@ private:
// Note that *lower* tiers come "before" higher tiers, hence the
// reversed comparison there.
- if(step1.effective_step_tier < step2.effective_step_tier)
- return true;
- else if(step2.effective_step_tier < step1.effective_step_tier)
- return false;
+ int tier_op_cmp = step1.final_step_tier_op.compare(step2.final_step_tier_op);
+ if(tier_op_cmp != 0)
+ return tier_op_cmp < 0;
else if(step2.score < step1.score)
return true;
else if(step1.score < step2.score)
@@ -846,23 +846,6 @@ private:
/** \brief Counts how many steps are deferred. */
int num_deferred;
- /** \brief The current minimum search tier.
- *
- * Solutions generated below this tier are discarded. Defaults to
- * minimum_tier.
- */
- tier minimum_search_tier;
-
- /** \brief The current maximum search tier.
- *
- * Solutions generated above this tier are placed into deferred.
- * This is advanced automatically when the current tier is
- * exhausted; it can also be advanced manually by the user.
- *
- * Defaults to minimum_tier.
- */
- tier maximum_search_tier;
-
/** Solutions generated "in the future", stored by reference to
* their step numbers.
*
@@ -1285,7 +1268,7 @@ private:
non_incipient);
if(non_incipient.get_has_value() &&
- s.effective_step_tier < non_incipient.get_value().get_tier())
+ s.final_step_tier_op < non_incipient.get_value().get_tier())
LOG_ERROR(logger, "In step " << s.step_num << ": the embedded promotion "
<< non_incipient.get_value() << " was not applied.");
else
@@ -1294,7 +1277,7 @@ private:
promotions.find_highest_promotion_for(s.actions);
if(found_promotion != promotions.end() &&
- s.effective_step_tier < found_promotion->get_tier())
+ s.final_step_tier_op < found_promotion->get_tier())
LOG_ERROR(logger, "In step " << s.step_num << ": the embedded promotion "
<< *found_promotion << " was not applied.");
}
@@ -1356,27 +1339,15 @@ private:
#endif
}
- /** \return \b true if the given tier is one that should cause
- * solvers and search steps to be discarded.
- */
- bool is_discard_tier(const tier &t) const
- {
- return
- t.get_structural_level() >= tier_limits::already_generated_structural_level;
- }
-
/** \return \b true if the given tier operation will always cause
- * the given step to be discarded.
+ * any step to be discarded.
*
* \param op the operation to test.
- *
- * \param s the step to test; is_discard_op returns \b true iff
- * applying the tier operation to this step's base tier
- * results in a discarding tier.
*/
- bool is_discard_op(const tier_operation &op, const step &s) const
+ bool is_discard_op(const tier_operation &op) const
{
- return is_discard_tier(op.apply(s.base_step_tier));
+ return
+ op.get_structural_level() >= tier_limits::already_generated_structural_level;
}
/** \return \b true if the given step is "irrelevant": that is,
@@ -1386,8 +1357,8 @@ private:
*/
bool irrelevant(const step &s)
{
- const tier &s_tier = s.effective_step_tier;
- if(is_discard_tier(s_tier))
+ const tier_operation &s_tier = s.final_step_tier_op;
+ if(is_discard_op(s_tier))
{
LOG_TRACE(logger, "Step " << s.step_num << " is irrelevant: its tier " << s_tier << " indicates it should be discarded.");
return true;
@@ -1405,14 +1376,14 @@ private:
}
/** \brief Adjust the tier of a step, keeping everything consistent. */
- void set_step_tier(int step_num,
- const tier &t)
+ void set_base_step_tier_op(int step_num,
+ const tier_operation &t_op)
{
step &s(graph.get_step(step_num));
- s.base_step_tier = t;
+ s.base_step_tier_op = t_op;
- update_effective_step_tier(step_num);
+ update_final_step_tier_op(step_num);
}
/** \brief Update the operation that computes the *effective* tier
@@ -1427,42 +1398,42 @@ private:
s.effective_step_tier_op = t_op;
- update_effective_step_tier(step_num);
+ update_final_step_tier_op(step_num);
}
/** \brief Update the effective tier of a step.
*
- * This should only be invoked by set_base_step_tier and
+ * This should only be invoked by set_base_step_tier_op and
* set_effective_step_tier_op. It recomputes the effective tier
* from its components and performs any follow-up work that's
* needed to enforce consistency.
*/
- void update_effective_step_tier(int step_num)
+ void update_final_step_tier_op(int step_num)
{
step &s(graph.get_step(step_num));
- tier new_effective_step_tier =
- s.effective_step_tier_op.apply(s.base_step_tier);
+ tier_operation new_final_step_tier_op =
+ s.effective_step_tier_op + s.base_step_tier_op;
- if(s.effective_step_tier == new_effective_step_tier)
+ if(s.final_step_tier_op == new_final_step_tier_op)
return;
- if(s.is_blessed_solution && is_discard_tier(new_effective_step_tier))
+ if(s.is_blessed_solution && is_discard_op(new_final_step_tier_op))
{
LOG_TRACE(logger, "Step " << s.step_num
- << " is a blessed solution; ignoring the attempt to promote it to tier " << new_effective_step_tier);
+ << " is a blessed solution; ignoring the attempt to promote it to tier " << new_final_step_tier_op);
return;
}
- LOG_TRACE(logger, "Setting the effective tier of step " << step_num
- << " to " << new_effective_step_tier);
+ LOG_TRACE(logger, "Setting the final tier of step " << step_num
+ << " to " << new_final_step_tier_op);
bool was_in_pending = (pending.erase(step_num) > 0);
bool was_in_pending_future_solutions = (pending_future_solutions.erase(step_num) > 0);
- if(s.effective_step_tier >= tier_limits::defer_tier &&
- !is_discard_tier(s.effective_step_tier))
+ if(s.final_step_tier_op.get_structural_level() >= tier_limits::defer_structural_level &&
+ !is_discard_op(s.final_step_tier_op))
{
if(was_in_pending)
--num_deferred;
@@ -1470,7 +1441,7 @@ private:
--num_deferred;
}
- s.effective_step_tier = new_effective_step_tier;
+ s.final_step_tier_op = new_final_step_tier_op;
if(was_in_pending)
@@ -1479,15 +1450,15 @@ private:
pending_future_solutions.insert(step_num);
- if(s.effective_step_tier >= tier_limits::defer_tier &&
- !is_discard_tier(s.effective_step_tier))
+ if(s.final_step_tier_op.get_structural_level() >= tier_limits::defer_structural_level &&
+ !is_discard_op(s.final_step_tier_op))
{
if(was_in_pending)
++num_deferred;
if(was_in_pending_future_solutions)
++num_deferred;
}
- else if(s.effective_step_tier < tier_limits::defer_tier)
+ else if(s.final_step_tier_op.get_structural_level() < tier_limits::defer_structural_level)
{
// Clear the "finished" flag if this is now a pending
// candidate.
@@ -2495,7 +2466,7 @@ private:
bool operator()(const promotion &p) const
{
if(blessed)
- return !resolver.is_discard_op(p.get_tier_op(), s);
+ return !resolver.is_discard_op(p.get_tier_op() + s.base_step_tier_op);
else
return true;
}
@@ -2845,8 +2816,8 @@ private:
*/
void recompute_effective_step_tier_op(step &s)
{
- LOG_TRACE(logger, "Recomputing the effective tier operation of step " << s.step_num
- << " (was " << s.effective_step_tier << ")");
+ LOG_TRACE(logger, "Recomputing the final tier operation of step " << s.step_num
+ << " (was " << s.final_step_tier_op << ")");
tier_operation new_tier_op(tier_limits::minimum_op);
s.unresolved_deps.for_each(find_dep_tier_op_upper_bound(new_tier_op, *this));
@@ -2953,7 +2924,7 @@ private:
// checks whether t_op consists only of maximizing operations that
// are below the current search tier, in which case there's no
// point in saving it.
- if(t_op.apply(get_current_search_tier()) == get_current_search_tier() &&
+ if(t_op + get_current_search_tier() == get_current_search_tier() &&
s.effective_step_tier_op.is_above_or_equal(t_op))
return;
@@ -3125,7 +3096,7 @@ private:
// to the point that the solver should be ejected, or the tier
// should just be bumped up a bit. Either way, we might end up
// changing the tier of the whole step.
- if(is_discard_op(new_tier_op, s))
+ if(is_discard_op(new_tier_op + s.base_step_tier_op))
{
// \todo this throws away information about whether we're at
// the already-generated tier. This isn't that important,
@@ -3536,9 +3507,9 @@ private:
output.action_score = parent.action_score;
output.score = parent.score;
output.reason = c;
- output.base_step_tier = c_op.apply(parent.base_step_tier);
+ output.base_step_tier_op = c_op + parent.base_step_tier_op;
output.effective_step_tier_op = tier_operation();
- output.effective_step_tier = output.effective_step_tier_op.apply(output.base_step_tier);
+ output.final_step_tier_op = output.effective_step_tier_op + output.base_step_tier_op;
output.is_deferred_listener = build_is_deferred_listener(c);
output.unresolved_deps = parent.unresolved_deps;
output.unresolved_deps_by_num_solvers = parent.unresolved_deps_by_num_solvers;
@@ -3634,10 +3605,10 @@ private:
extend_score_to_new_step(output, c);
LOG_TRACE(logger, "Generated step " << output.step_num
- << " (" << output.actions.size() << " actions): " << output.actions << ";T" << output.effective_step_tier
+ << " (" << output.actions.size() << " actions): " << output.actions << ";T" << output.final_step_tier_op
<< "S" << output.score);
- if(is_discard_tier(output.effective_step_tier))
+ if(is_discard_op(output.final_step_tier_op))
++num_deferred;
pending.insert(output.step_num);
@@ -3777,8 +3748,6 @@ public:
solver_executing(false), solver_cancelled(false),
pending(step_goodness_compare(graph)),
num_deferred(0),
- minimum_search_tier(tier_limits::minimum_tier),
- maximum_search_tier(tier_limits::minimum_tier),
pending_future_solutions(step_goodness_compare(graph)),
closed(),
promotions(_universe, *this),
@@ -4228,7 +4197,7 @@ public:
counts.conflicts = promotions.conflicts_size();
counts.promotions = promotions.size() - counts.conflicts;
counts.finished = finished;
- counts.current_tier = get_current_search_tier();
+ counts.current_tier_op = get_current_search_tier();
}
/** If no resolver is running, run through the deferred list and
@@ -4249,12 +4218,12 @@ public:
* solution that would be considered (or minimum_search_tier if
* pending is empty).
*/
- const tier &get_current_search_tier() const
+ tier_operation get_current_search_tier() const
{
if(pending.empty())
- return tier_limits::minimum_tier;
+ return tier_operation();
else
- return graph.get_step(*pending.begin()).effective_step_tier;
+ return graph.get_step(*pending.begin()).final_step_tier_op;
}
private:
@@ -4265,7 +4234,7 @@ private:
{
return
!pending.empty() &&
- graph.get_step(*pending.begin()).effective_step_tier < tier_limits::defer_tier;
+ graph.get_step(*pending.begin()).final_step_tier_op.get_structural_level() < tier_limits::defer_structural_level;
}
/** \brief Returns \b true if the pending future solutions queue
@@ -4275,7 +4244,7 @@ private:
{
return
!pending_future_solutions.empty() &&
- graph.get_step(*pending_future_solutions.begin()).effective_step_tier < tier_limits::defer_tier;
+ graph.get_step(*pending_future_solutions.begin()).final_step_tier_op.get_structural_level() < tier_limits::defer_structural_level;
}
// Counts how many action hits existed in a promotion, allowing up
@@ -4461,10 +4430,10 @@ private:
step &s = graph.get_step(step_num);
LOG_INFO(logger, "Examining step " << step_num
- << " (" << s.actions.size() << " actions): " << s.actions << ";T" << s.effective_step_tier
+ << " (" << s.actions.size() << " actions): " << s.actions << ";T" << s.final_step_tier_op
<< "S" << s.score);
- if(s.effective_step_tier >= tier_limits::defer_tier)
+ if(s.final_step_tier_op.get_structural_level() >= tier_limits::defer_structural_level)
{
LOG_ERROR(logger, "Internal error: the tier of step "
<< s.step_num
@@ -4487,7 +4456,7 @@ private:
}
// The step might have been promoted to the defer tier by
// check_for_new_promotions.
- else if(s.effective_step_tier >= tier_limits::defer_tier)
+ else if(s.final_step_tier_op.get_structural_level() >= tier_limits::defer_structural_level)
{
LOG_DEBUG(logger, "Skipping newly deferred step " << s.step_num);
// Stick it back into the open queue.
@@ -4504,7 +4473,7 @@ private:
if(s.unresolved_deps.empty())
{
LOG_INFO(logger, " --- Found solution at step " << s.step_num
- << ": " << s.actions << ";T" << s.effective_step_tier
+ << ": " << s.actions << ";T" << s.final_step_tier_op
<< "S" << s.score);
// Remember this solution, so we don't try to return it
@@ -4528,7 +4497,7 @@ private:
// was a forced dependency and we should process that
// successor before returning.
if(s.first_child != -1 && graph.get_step(s.first_child).is_last_child &&
- graph.get_step(s.first_child).effective_step_tier < tier_limits::defer_tier)
+ graph.get_step(s.first_child).final_step_tier_op.get_structural_level() < tier_limits::defer_structural_level)
{
LOG_TRACE(logger, "Following forced dependency resolution from step "
<< step_num << " to step " << s.first_child);
@@ -4614,9 +4583,9 @@ public:
if(initial_broken.empty())
root.score += weights.full_solution_score;
- root.base_step_tier = tier_limits::minimum_tier;
+ root.base_step_tier_op = tier_operation();
root.effective_step_tier_op = tier_operation();
- root.effective_step_tier = tier_limits::minimum_tier;
+ root.final_step_tier_op = tier_operation();
root.promotion_queue_location = promotion_queue_tail;
for(typename imm::set<dep>::const_iterator it = initial_broken.begin();
@@ -4624,7 +4593,7 @@ public:
add_unresolved_dep(root, *it);
LOG_TRACE(logger, "Inserting the root at step " << root.step_num
- << " with tier " << root.effective_step_tier);
+ << " with tier " << root.final_step_tier_op);
pending.insert(root.step_num);
}
@@ -4686,14 +4655,14 @@ public:
{
int best_future_solution = *pending_future_solutions.begin();
step &best_future_solution_step = graph.get_step(best_future_solution);
- if(best_future_solution_step.effective_step_tier < tier_limits::defer_tier)
+ if(best_future_solution_step.final_step_tier_op.get_structural_level() < tier_limits::defer_structural_level)
{
sanity_check_not_deferred(best_future_solution_step);
solution rval(best_future_solution_step.actions,
initial_state,
best_future_solution_step.score,
- best_future_solution_step.effective_step_tier);
+ best_future_solution_step.final_step_tier_op);
LOG_INFO(logger, " *** Converged after " << odometer << " steps.");
diff --git a/src/generic/problemresolver/promotion_set.h b/src/generic/problemresolver/promotion_set.h
index 29397748..c90dec0f 100644
--- a/src/generic/problemresolver/promotion_set.h
+++ b/src/generic/problemresolver/promotion_set.h
@@ -1647,67 +1647,6 @@ private:
choices.for_each(find_results_f);
}
- /** \brief Predicate testing whether an entry reference refers to
- * something in a particular tier.
- */
- struct entry_ref_in_tier_pred
- {
- tier selected_tier;
-
- entry_ref_in_tier_pred(const tier &_selected_tier)
- : selected_tier(_selected_tier)
- {
- }
-
- bool operator()(entry_ref r) const
- {
- return r->p.get_tier() == selected_tier;
- }
- };
-
- /** \brief Predicate testing whether an entry reference refers to
- * something between two tiers.
- */
- struct entry_ref_between_tiers_pred
- {
- tier begin_tier, end_tier;
-
- /** \brief Create a new entry_ref_in_tier_pred.
- *
- * \param _begin_tier The first tier to select.
- * \param _end_tier The first tier to *not* select.
- */
- entry_ref_between_tiers_pred(const tier &_begin_tier, const tier &_end_tier)
- : begin_tier(_begin_tier), end_tier(_end_tier)
- {
- }
-
- bool operator()(entry_ref r) const
- {
- const tier &r_tier(r->p.get_tier());
-
- return r_tier >= begin_tier && r_tier < end_tier;
- }
- };
-
- /** \brief Predicate testing whether an entry reference is strictly
- * below a particular tier.
- */
- struct entry_ref_strictly_below_tier_pred
- {
- tier selected_tier;
-
- entry_ref_strictly_below_tier_pred(const tier &_selected_tier)
- : selected_tier(_selected_tier)
- {
- }
-
- bool operator()(entry_ref r) const
- {
- return r->p.get_tier() < selected_tier;
- }
- };
-
/** \brief Collect the versions and soft dependencies related
* to a single choice.
*/
diff --git a/src/generic/problemresolver/search_graph.h b/src/generic/problemresolver/search_graph.h
index c99de55c..a467e0ad 100644
--- a/src/generic/problemresolver/search_graph.h
+++ b/src/generic/problemresolver/search_graph.h
@@ -790,12 +790,13 @@ public:
*/
int action_score;
- /** \brief The true tier of this step.
+ /** \brief The tier operation induced by the actions performed at
+ * this step.
*
* This is the tier *before* any forward-looking operations are
* applied to it.
*/
- tier base_step_tier;
+ tier_operation base_step_tier_op;
/** \brief The cumulative effect of all forward-looking operations
* applied to this step.
@@ -809,12 +810,13 @@ public:
*/
tier_operation effective_step_tier_op;
- /** \brief The effective tier of this step.
+ /** \brief The tier of this step after taking into account
+ * knowledge about the available solutions to its dependencies.
*
* This tier is step_tier combined with any inferred tier
* operations, and is used to sort the step in the search queue.
*/
- tier effective_step_tier;
+ tier_operation final_step_tier_op;
/** \brief A side-effecting expression that fires when the most
* recently added action becomes deferred or un-deferred.
@@ -1790,11 +1792,11 @@ private:
{
bool operator()(const promotion &p) const
{
- const tier &p_tier(p.get_tier());
+ const tier_operation &p_tier_op(p.get_tier_op());
return
- p_tier >= tier_limits::defer_tier &&
- p_tier < tier_limits::already_generated_tier;
+ p_tier_op.get_structural_level() >= tier_limits::defer_structural_level &&
+ p_tier_op.get_structural_level() < tier_limits::already_generated_structural_level;
}
};
diff --git a/src/generic/problemresolver/solution.h b/src/generic/problemresolver/solution.h
index 23c57f42..538314fa 100644
--- a/src/generic/problemresolver/solution.h
+++ b/src/generic/problemresolver/solution.h
@@ -31,7 +31,7 @@
#include <generic/util/refcounted_base.h>
#include "choice.h"
#include "choice_set.h"
-#include "tier.h"
+#include "tier_operation.h"
/** \brief The solution class for the problem resolver.
*
@@ -294,7 +294,7 @@ private:
* Informational only; not considered when comparing solutions by
* identity.
*/
- tier sol_tier;
+ tier_operation sol_tier_op;
/** The reference count of this solution. */
mutable unsigned int refcount;
@@ -307,10 +307,10 @@ private:
solution_rep(const choice_set &_choices,
const resolver_initial_state<PackageUniverse> &_initial_state,
int _score,
- const tier &_sol_tier)
+ const tier_operation &_sol_tier_op)
: initial_state(_initial_state), choices(_choices),
score(_score),
- sol_tier(_sol_tier),
+ sol_tier_op(_sol_tier_op),
refcount(1)
{
}
@@ -326,7 +326,7 @@ private:
}
int get_score() const {return score;}
- const tier &get_tier() const { return sol_tier; }
+ const tier_operation &get_tier() const { return sol_tier_op; }
version version_of(const package &pkg) const
{
@@ -394,8 +394,8 @@ public:
generic_solution(const choice_set &choices,
const resolver_initial_state<PackageUniverse> &initial_state,
int score,
- const tier &sol_tier)
- : real_soln(new solution_rep(choices, initial_state, score, sol_tier))
+ const tier_operation &sol_tier_op)
+ : real_soln(new solution_rep(choices, initial_state, score, sol_tier_op))
{
}
@@ -487,7 +487,7 @@ public:
}
/** \return The tier at which this solution was calculated. */
- const tier &get_tier() const
+ const tier_operation &get_tier() const
{
return real_soln->get_tier();
}
diff --git a/src/generic/problemresolver/tier.cc b/src/generic/problemresolver/tier.cc
index c2369d5f..8ef840c2 100644
--- a/src/generic/problemresolver/tier.cc
+++ b/src/generic/problemresolver/tier.cc
@@ -33,30 +33,3 @@ std::ostream &operator<<(std::ostream &out, const level &l)
return out;
}
-
-std::ostream &operator<<(std::ostream &out, const tier &t)
-{
- out << "(";
-
- const int t_structural_level = t.get_structural_level();
-
- if(t_structural_level == tier_limits::conflict_structural_level)
- out << "conflict";
- else if(t_structural_level == tier_limits::already_generated_structural_level)
- out << "already-generated";
- else if(t_structural_level == tier_limits::defer_structural_level)
- out << "defer";
- else if(t_structural_level == tier_limits::minimum_level)
- out << "minimum";
- else
- out << t_structural_level;
-
- for(tier::user_level_iterator it = t.user_levels_begin();
- it != t.user_levels_end(); ++it)
- out << ", " << *it;
-
- out << ")";
-
- return out;
-}
-
diff --git a/src/generic/problemresolver/tier.h b/src/generic/problemresolver/tier.h
index f608c7cb..b358078d 100644
--- a/src/generic/problemresolver/tier.h
+++ b/src/generic/problemresolver/tier.h
@@ -271,293 +271,4 @@ namespace aptitude
}
}
-/** \brief Represents the tier of a search node.
- *
- * The resolver is \e guaranteed to produce solutions in increasing
- * order by tier. This is as opposed to score, which is merely used
- * in a best-effort manner.
- *
- * A tier is a sequence of levels (as defined above). By convention,
- * each tier in a search should have the same length; tiers are
- * compared lexicographically.
- *
- * The first level in the tier is reserved by the resolver to store
- * "structural" priorities (for instance, to mark nodes as conflicted
- * or deferred); to make things simpler for client code that doesn't
- * care about this information, that level is stored and accessed
- * separately from the main list.
- */
-class tier
-{
- /** \brief The object that actually stores the tier data. */
- struct tier_impl
- {
- // Level set by the resolver itself to control the search
- // algorithm. This is always increased in an upper-bound / cutoff
- // fashion.
- int structural_level;
-
- // Levels set by client code to customize the search order.
- std::vector<level> user_levels;
-
- // Cache the hash value. Initialized during construction.
- std::size_t hash_value;
-
- /** \brief Initialize a tier object from a collection of user levels.
- *
- * The structural level is set to INT_MIN.
- */
- template<typename Iterator>
- tier_impl(Iterator user_levels_begin, Iterator user_levels_end)
- : structural_level(INT_MIN),
- user_levels(user_levels_begin, user_levels_end),
- hash_value(0)
- {
- hash_value = get_hash_value();
- }
-
- /** \brief Initialize a tier object with no user levels.
- *
- * This will be the smallest tier in its structural level.
- */
- tier_impl(int _structural_level)
- : structural_level(_structural_level),
- user_levels(),
- hash_value(0)
- {
- hash_value = get_hash_value();
- }
-
- /** \brief Initialize a tier object given its contents. */
- template<typename Iterator>
- tier_impl(int _structural_level,
- Iterator user_levels_begin, Iterator user_levels_end)
- : structural_level(_structural_level),
- user_levels(user_levels_begin, user_levels_end),
- hash_value(0)
- {
- hash_value = get_hash_value();
- }
-
- std::size_t get_hash_value() const
- {
- std::size_t rval = 0;
-
- boost::hash_combine(rval, structural_level);
- for(std::vector<level>::const_iterator it = user_levels.begin();
- it != user_levels.end(); ++it)
- boost::hash_combine(rval, *it);
-
- return rval;
- }
-
- bool operator==(const tier_impl &other) const
- {
- return
- structural_level == other.structural_level &&
- user_levels == other.user_levels;
- }
-
- bool operator!=(const tier_impl &other) const
- {
- return
- structural_level != other.structural_level ||
- user_levels != other.user_levels;
- }
- };
-
- class tier_impl_hasher
- {
- public:
- std::size_t operator()(const tier_impl &impl) const
- {
- return impl.hash_value;
- }
- };
-
- typedef boost::shared_ptr<tier_impl> tier_impl_ref;
-
- tier_impl_ref impl_ref;
-
- tier(const tier_impl_ref &_impl_ref)
- : impl_ref(_impl_ref)
- {
- }
-
- const tier_impl &get_impl() const
- {
- return *impl_ref;
- }
-
-public:
- /** \brief A default-constructed tier is the smallest possible tier. */
- tier()
- : impl_ref(boost::make_shared<tier_impl>(INT_MIN))
- {
- }
-
- /** \brief Create a new tier object with structural level INT_MIN.
- *
- * \param user_level_begin The beginning of a range of levels to
- * insert into the user level list.
- *
- * \param user_level_end The end of a range of levels to insert
- * into the user level list.
- */
- template<typename Iterator>
- tier(Iterator user_levels_begin, Iterator user_levels_end)
- : impl_ref(boost::make_shared<tier_impl>(user_levels_begin, user_levels_end))
- {
- }
-
- /** \brief Create a new tier object with the given structural level
- * and no user levels.
- *
- * The new tier will be the smallest tier in its structural level.
- */
- tier(int structural_level)
- : impl_ref(boost::make_shared<tier_impl>(structural_level))
- {
- }
-
- /** \brief Create a new tier object.
- *
- * \param structural_level The structural level to store in the new
- * level object.
- *
- * \param user_level_begin The beginning of a range of levels to
- * insert into the user level list.
- *
- * \param user_level_end The end of a range of levels to insert
- * into the user level list.
- */
- template<typename Iterator>
- tier(int structural_level,
- Iterator user_levels_begin, Iterator user_levels_end)
- : impl_ref(boost::make_shared<tier_impl>(structural_level, user_levels_begin, user_levels_end))
- {
- }
-
- /** \brief Create a new tier object in which this object's
- * structural level has been modified.
- *
- * \param new_structural_level The structural level of the new
- * level object.
- *
- * \return a tier object with the same user levels as this object
- * and the given structural level.
- */
- tier set_structural_level(int new_structural_level) const
- {
- const tier_impl &impl(get_impl());
-
- return tier(boost::make_shared<tier_impl>(new_structural_level,
- impl.user_levels.begin(),
- impl.user_levels.end()));
- }
-
- /** \brief Retrieve the value of the structural level slot. */
- int get_structural_level() const { return get_impl().structural_level; }
-
- typedef std::vector<level>::const_iterator user_level_iterator;
-
- /** \brief Get a reference to the first user level as a
- * random-access iterator.
- */
- user_level_iterator user_levels_begin() const { return get_impl().user_levels.begin(); }
- /** \brief Get a reference to the end of the user level list as a
- * random-access iterator.
- */
- user_level_iterator user_levels_end() const { return get_impl().user_levels.end(); }
-
- /** \brief Retrieve one user level from this tier. */
- const level &get_user_level(int index) const { return get_impl().user_levels[index]; }
-
- /** \brief Retrieve the number of user levels in this tier. */
- std::size_t get_num_user_levels() const { return get_impl().user_levels.size(); }
-
- std::size_t get_hash_value() const
- {
- return get_impl().hash_value;
- }
-
- tier &operator=(const tier &other)
- {
- impl_ref = other.impl_ref;
-
- return *this;
- }
-
- /** \brief Compare two tiers.
- *
- * Tiers are compared lexicographically, ignoring level states.
- */
- int compare(const tier &other) const
- {
- const tier_impl &impl(get_impl());
- const tier_impl &other_impl(other.get_impl());
-
- using aptitude::util::compare3;
-
- const int cmp = compare3(impl.structural_level, other_impl.structural_level);
- if(cmp != 0)
- return cmp;
- else
- return compare3(impl.user_levels, other_impl.user_levels);
- }
-
- bool operator==(const tier &other) const
- {
- return compare(other) == 0;
- }
-
- bool operator!=(const tier &other) const
- {
- return compare(other) != 0;
- }
-
- bool operator<(const tier &other) const
- {
- return compare(other) < 0;
- }
-
- bool operator<=(const tier &other) const
- {
- return compare(other) <= 0;
- }
-
- bool operator>(const tier &other) const
- {
- return compare(other) > 0;
- }
-
- bool operator>=(const tier &other) const
- {
- return compare(other) >= 0;
- }
-};
-
-inline std::size_t hash_value(const tier &t)
-{
- return t.get_hash_value();
-}
-
-namespace aptitude
-{
- namespace util
- {
- template<>
- class compare3_f<tier>
- {
- public:
- int operator()(const tier &t1, const tier &t2) const
- {
- return t1.compare(t2);
- }
- };
- }
-}
-
-std::ostream &operator<<(std::ostream &, const tier &t);
-
#endif // TIER_H
diff --git a/src/generic/problemresolver/tier_limits.cc b/src/generic/problemresolver/tier_limits.cc
index 495f895f..02ce4b6b 100644
--- a/src/generic/problemresolver/tier_limits.cc
+++ b/src/generic/problemresolver/tier_limits.cc
@@ -26,12 +26,6 @@ const int tier_limits::defer_structural_level;
const int tier_limits::already_generated_structural_level;
const int tier_limits::minimum_level;
-const tier tier_limits::maximum_tier(tier_limits::maximum_level);
-const tier tier_limits::conflict_tier(tier_limits::conflict_structural_level);
-const tier tier_limits::already_generated_tier(tier_limits::already_generated_structural_level);
-const tier tier_limits::defer_tier(tier_limits::defer_structural_level);
-const tier tier_limits::minimum_tier(tier_limits::minimum_level);
-
const tier_operation tier_limits::increase_to_maximum_op(tier_operation::make_advance_structural_level(maximum_level));
const tier_operation tier_limits::increase_to_conflict_op(tier_operation::make_advance_structural_level(conflict_structural_level));
const tier_operation tier_limits::increase_to_already_generated_op(tier_operation::make_advance_structural_level(already_generated_structural_level));
diff --git a/src/generic/problemresolver/tier_limits.h b/src/generic/problemresolver/tier_limits.h
index 567d5ea1..0f7b8e4d 100644
--- a/src/generic/problemresolver/tier_limits.h
+++ b/src/generic/problemresolver/tier_limits.h
@@ -55,12 +55,6 @@ public:
*/
static const int minimum_level = INT_MIN;
- static const tier maximum_tier;
- static const tier conflict_tier;
- static const tier already_generated_tier;
- static const tier defer_tier;
- static const tier minimum_tier;
-
/** \brief Tier operations that just increase the structural level.
*/
// @{
diff --git a/src/generic/problemresolver/tier_operation.cc b/src/generic/problemresolver/tier_operation.cc
index 180c0825..e5907f96 100644
--- a/src/generic/problemresolver/tier_operation.cc
+++ b/src/generic/problemresolver/tier_operation.cc
@@ -59,39 +59,6 @@ tier_operation::op_impl::op_impl(const op_impl &op1, const op_impl &op2, combine
actions.insert(actions.end(), it2, op2.actions.end());
}
-tier tier_operation::op_impl::apply(const tier &t) const
-{
- int out_structural_level =
- std::max<int>(t.get_structural_level(), structural_level);
- std::vector<level> out_user_levels(t.user_levels_begin(), t.user_levels_end());
-
- if(!actions.empty())
- {
- // If the actions array will modify slots off the end of the
- // tier's list of levels, we first pre-extend that list.
- if(out_user_levels.size() <= actions.back().first)
- {
- level_index
- gap_size = actions.back().first + 1 - out_user_levels.size();
-
- out_user_levels.insert(out_user_levels.end(),
- gap_size,
- level());
- }
-
- for(std::vector<std::pair<level_index, level> >::const_iterator it =
- actions.begin(); it != actions.end(); ++it)
- {
- level &target(out_user_levels[it->first]);
- target = level::combine(target, it->second);
- }
- }
-
- return tier(out_structural_level,
- out_user_levels.begin(),
- out_user_levels.end());
-}
-
bool tier_operation::op_impl::is_above_or_equal(const op_impl &other) const
{
std::vector<std::pair<level_index, level> >::const_iterator
diff --git a/src/generic/problemresolver/tier_operation.h b/src/generic/problemresolver/tier_operation.h
index aac1dd19..f5e05642 100644
--- a/src/generic/problemresolver/tier_operation.h
+++ b/src/generic/problemresolver/tier_operation.h
@@ -163,14 +163,6 @@ class tier_operation
actions == other.actions;
}
- /** \brief Apply the operation to the tier.
- *
- * Each level is combined with the corresponding level in the
- * target tier. If there is no corresponding level, it is copied
- * directly (which is exactly the desired behavior).
- */
- tier apply(const tier &t) const;
-
/** \brief Compare two operations by their identity.
*/
int compare(const op_impl &other) const;
@@ -342,15 +334,6 @@ public:
return impl_flyweight != other.impl_flyweight;
}
- /** \brief Apply this operation to a tier.
- *
- * \param t The tier that this operation should modify.
- */
- tier apply(const tier &t) const
- {
- return get_impl().apply(t);
- }
-
/** \brief Write a description of a tier operation to an ostream.
*/
void dump(std::ostream &out) const