diff options
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | src/generic/problemresolver/problemresolver.h | 68 | ||||
-rw-r--r-- | src/generic/problemresolver/search_graph.h | 11 |
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 { |