summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--src/generic/problemresolver/problemresolver.h68
-rw-r--r--src/generic/problemresolver/search_graph.h11
3 files changed, 40 insertions, 40 deletions
diff --git a/configure.ac b/configure.ac
index 30d8dda3..50001354 100644
--- a/configure.ac
+++ b/configure.ac
@@ -56,6 +56,7 @@ dnl Check for Boost headers. Place each one on a line by itself and
dnl write "dnl" at the end: the "dnl" deletes the newline, and without
dnl it you'll get an error when you run the configure script.
AC_CHECK_HEADERS( dnl
+boost/flyweight.hpp dnl
boost/functional/hash.hpp dnl
boost/optional.hpp dnl
boost/shared_ptr.hpp dnl
diff --git a/src/generic/problemresolver/problemresolver.h b/src/generic/problemresolver/problemresolver.h
index 9dc5e76c..baaecc95 100644
--- a/src/generic/problemresolver/problemresolver.h
+++ b/src/generic/problemresolver/problemresolver.h
@@ -71,6 +71,7 @@
#include <generic/util/dense_setset.h>
#include <generic/util/maybe.h>
+#include <boost/flyweight.hpp>
#include <boost/unordered_set.hpp>
/** \brief Generic problem resolver
@@ -1102,27 +1103,6 @@ private:
std::map<choice, expression_weak_ref<expression_box<bool> >,
compare_choices_for_deferral> memoized_is_deferred;
- /** \todo This should hold weak references to heap-allocated
- * structures so that memoizations wouldn't last longer than needed
- * (if every instance of a solver set was changed, that solver set
- * would be dropped).
- */
- boost::unordered_set<typename step::dep_solvers> memoized_dep_solvers;
-
- typename step::dep_solvers memoize_dep_solvers(const typename step::dep_solvers &solvers)
- {
- // std::set will insert a new element only if it doesn't already
- // contain an element with the same key, which is exactly what we
- // want here.
- std::pair<typename boost::unordered_set<typename step::dep_solvers>::const_iterator, bool>
- insert_result = memoized_dep_solvers.insert(solvers);
-
- if(insert_result.second)
- LOG_TRACE(logger, "Memoized new solver set: " << solvers);
-
- return *insert_result.first;
- }
-
/** \brief If the given step is already "seen", mark it as a clone
* and return true (telling our caller to abort).
*/
@@ -1251,7 +1231,7 @@ private:
typedef generic_dep_solvers<PackageUniverse> dep_solvers;
- for(typename imm::map<dep, dep_solvers>::const_iterator it =
+ for(typename imm::map<dep, boost::flyweight<dep_solvers> >::const_iterator it =
s.unresolved_deps.begin(); it != s.unresolved_deps.end(); ++it)
{
const dep &d(it->first);
@@ -1787,12 +1767,12 @@ private:
// Need to look up the solvers of the dep in order to know
// the number of solvers that it was entered into the
// by-num-solvers set with.
- typename imm::map<dep, typename search_graph::step::dep_solvers>::node
+ typename imm::map<dep, typename step::flyweight_dep_solvers>::node
solvers = s.unresolved_deps.lookup(d);
if(solvers.isValid())
{
- const typename search_graph::step::dep_solvers &
+ const typename step::dep_solvers &
dep_solvers(solvers.getVal().second);
const imm::map<choice, typename step::solver_information, compare_choices_by_effects> &solver_map =
@@ -1901,7 +1881,7 @@ private:
// Find the current number of solvers so we can yank the
// dependency out of the unresolved-by-num-solvers set.
- typename imm::map<dep, typename step::dep_solvers>::node
+ typename imm::map<dep, typename step::flyweight_dep_solvers>::node
current_solver_set_found = s.unresolved_deps.lookup(d);
if(current_solver_set_found.isValid())
@@ -1923,7 +1903,11 @@ private:
<< ", new solvers: " << new_solvers.get_solvers());
// Actually update the solvers of the dep.
- s.unresolved_deps.put(d, resolver.memoize_dep_solvers(new_solvers));
+ {
+ const typename step::flyweight_dep_solvers
+ memoized_new_solvers(new_solvers);
+ s.unresolved_deps.put(d, memoized_new_solvers);
+ }
const int new_num_solvers = new_solvers.get_solvers().size();
@@ -2224,7 +2208,7 @@ private:
const tier &check_tier = tier_limits::minimum_tier,
bool do_check_tier = false)
{
- typename imm::map<dep, typename step::dep_solvers>::node
+ typename imm::map<dep, typename step::flyweight_dep_solvers>::node
found_solvers(s.unresolved_deps.lookup(solver_dep));
if(found_solvers.isValid())
@@ -2255,7 +2239,12 @@ private:
new_tier_valid,
new_tier_is_deferred);
new_dep_solvers.set_solver_information(solver_with_dep, new_solver_inf);
- s.unresolved_deps.put(solver_dep, memoize_dep_solvers(new_dep_solvers));
+ {
+ typename step::flyweight_dep_solvers
+ memoized_new_dep_solvers(new_dep_solvers);
+
+ s.unresolved_deps.put(solver_dep, memoized_new_dep_solvers);
+ }
LOG_TRACE(logger, "Recomputed the tier of "
<< solver << " in the solver list of "
<< solver_dep << " in step " << s.step_num
@@ -2680,7 +2669,7 @@ private:
const dep &d(*it);
choice solver_with_dep(solver.copy_and_set_dep(d));
- typename imm::map<dep, typename step::dep_solvers>::node current_solver_set_found =
+ typename imm::map<dep, typename step::flyweight_dep_solvers>::node current_solver_set_found =
s.unresolved_deps.lookup(d);
if(current_solver_set_found.isValid())
@@ -2717,7 +2706,9 @@ private:
old_inf.get_is_deferred_listener());
new_solvers.set_solver_information(solver_with_dep, new_inf);
- s.unresolved_deps.put(d, resolver.memoize_dep_solvers(new_solvers));
+ typename step::flyweight_dep_solvers
+ memoized_new_solvers(new_solvers);
+ s.unresolved_deps.put(d, memoized_new_solvers);
resolver.check_solvers_tier(s, new_solvers);
LOG_TRACE(logger, "Increased the tier of "
@@ -2864,7 +2855,7 @@ private:
*/
void find_promotions_for_dep_solvers(step &s, const dep &d)
{
- typename imm::map<dep, typename step::dep_solvers>::node found =
+ typename imm::map<dep, typename step::flyweight_dep_solvers>::node found =
s.unresolved_deps.lookup(d);
if(found.isValid())
@@ -2919,7 +2910,9 @@ private:
add_solver(s, solvers, d,
choice::make_break_soft_dep(d, -1));
- s.unresolved_deps.put(d, memoize_dep_solvers(solvers));
+ typename step::flyweight_dep_solvers
+ memoized_solvers(solvers);
+ s.unresolved_deps.put(d, memoized_solvers);
LOG_TRACE(logger, "Marked the dependency " << d
<< " as unresolved in step " << s.step_num
<< " with solver list " << solvers);
@@ -3296,7 +3289,7 @@ private:
return;
}
- typename imm::map<dep, typename step::dep_solvers>::node bestSolvers =
+ typename imm::map<dep, typename step::flyweight_dep_solvers>::node bestSolvers =
s.unresolved_deps.lookup(best.getVal().second);
if(!bestSolvers.isValid())
@@ -3307,17 +3300,18 @@ private:
return;
}
- if(bestSolvers.getVal().second.get_solvers().empty())
+ const typename step::dep_solvers &bestDepSolvers(bestSolvers.getVal().second);
+ if(bestDepSolvers.get_solvers().empty())
LOG_ERROR(logger, "Internal error: a step containing a dependency with no solvers was not promoted to the conflict tier.");
LOG_TRACE(logger, "Generating successors for step " << step_num
- << " for the dependency " << best.getVal().second
+ << " for the dependency " << bestDepSolvers
<< " with " << best.getVal().first << " solvers: "
- << bestSolvers.getVal().second.get_solvers());
+ << bestDepSolvers.get_solvers());
bool first_successor = false;
do_generate_single_successor generate_successor_f(s.step_num, *this,
first_successor);
- bestSolvers.getVal().second.get_solvers().for_each(generate_successor_f);
+ bestDepSolvers.get_solvers().for_each(generate_successor_f);
}
public:
diff --git a/src/generic/problemresolver/search_graph.h b/src/generic/problemresolver/search_graph.h
index 4635a17f..1d04838f 100644
--- a/src/generic/problemresolver/search_graph.h
+++ b/src/generic/problemresolver/search_graph.h
@@ -34,6 +34,8 @@
#include <generic/util/immlist.h>
#include <generic/util/immset.h>
+#include <boost/flyweight.hpp>
+#include <boost/flyweight/no_tracking.hpp>
#include <boost/functional/hash.hpp>
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
@@ -567,6 +569,9 @@ public:
typedef generic_solver_information<PackageUniverse> solver_information;
typedef generic_dep_solvers<PackageUniverse> dep_solvers;
+ typedef boost::flyweight<dep_solvers,
+ boost::flyweights::no_tracking> flyweight_dep_solvers;
+
/** \brief The actions performed by this step. */
choice_set actions;
@@ -595,7 +600,7 @@ public:
* one maps to the reasons that any of its solvers were
* dropped.
*/
- imm::map<dep, dep_solvers> unresolved_deps;
+ imm::map<dep, flyweight_dep_solvers> unresolved_deps;
/** \brief The unresolved dependencies, sorted by the number of
* solvers each one has.
@@ -1093,11 +1098,11 @@ private:
// Check if we have a solver in this step first -- if you think
// about it, it's more likely that this is true than that we
// have an action.
- typename imm::map<dep, typename step::dep_solvers>::node found =
+ typename imm::map<dep, typename step::flyweight_dep_solvers>::node found =
s.unresolved_deps.lookup(d);
if(found.isValid() &&
- found.getVal().second.get_solvers().domain_contains(c))
+ found.getVal().second.get().get_solvers().domain_contains(c))
return visit(s, choice_mapping_solver);
else
{