diff options
author | 2011-04-15 17:35:15 +0100 | |
---|---|---|
committer | 2011-04-15 17:35:15 +0100 | |
commit | ef62f20141855b4ca254dd7b8862ab94015199b4 (patch) | |
tree | e81c6b4ee9d02ed34073e4f039335124b60388d2 | |
parent | 74d92ca6f2ffd4d5bb5ef168061f58e25bf639ea (diff) | |
download | paludis-ef62f20141855b4ca254dd7b8862ab94015199b4.tar.gz paludis-ef62f20141855b4ca254dd7b8862ab94015199b4.tar.xz |
Cache resolvents for helper
-rw-r--r-- | paludis/resolver/get_resolvents_for_helper.cc | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/paludis/resolver/get_resolvents_for_helper.cc b/paludis/resolver/get_resolvents_for_helper.cc index 06a88fc9b..9eb435360 100644 --- a/paludis/resolver/get_resolvents_for_helper.cc +++ b/paludis/resolver/get_resolvents_for_helper.cc @@ -24,11 +24,16 @@ #include <paludis/resolver/reason.hh> #include <paludis/resolver/labels_classifier.hh> #include <paludis/resolver/destination_utils.hh> + #include <paludis/util/pimp-impl.hh> #include <paludis/util/stringify.hh> #include <paludis/util/wrapped_output_iterator.hh> #include <paludis/util/indirect_iterator-impl.hh> #include <paludis/util/enum_iterator.hh> +#include <paludis/util/mutex.hh> +#include <paludis/util/make_named_values.hh> +#include <paludis/util/hashes.hh> + #include <paludis/dep_spec.hh> #include <paludis/environment.hh> #include <paludis/generator.hh> @@ -37,11 +42,20 @@ #include <paludis/selection.hh> #include <paludis/package_id.hh> #include <paludis/metadata_key.hh> +#include <paludis/package_dep_spec_properties.hh> + #include <algorithm> +#include <tuple> +#include <unordered_map> using namespace paludis; using namespace paludis::resolver; +namespace +{ + typedef std::tuple<bool, bool, bool, std::string> CacheKey; +} + namespace paludis { template <> @@ -65,6 +79,12 @@ namespace paludis bool want_installed_slots_otherwise; bool fallback_to_other_slots_otherwise; + mutable Mutex cache_mutex; + mutable std::unordered_map< + CacheKey, + std::pair<std::shared_ptr<const Resolvents>, bool>, + Hash<CacheKey> > cache; + Imp(const Environment * const e) : env(e), target_destination_type(dt_install_to_slash), @@ -259,6 +279,26 @@ namespace want_dependencies_on_slash, want_runtime_dependencies_on_slash, package_id}; return reason->accept_returning<DestinationTypes>(f); } + + bool can_use_cache(const PackageDepSpec & spec) + { + return package_dep_spec_has_properties(spec, make_named_values<PackageDepSpecProperties>( + n::has_any_slot_requirement() = indeterminate, + n::has_category_name_part() = indeterminate, + n::has_choice_requirements() = false, + n::has_exact_slot_requirement() = indeterminate, + n::has_from_repository() = indeterminate, + n::has_in_repository() = indeterminate, + n::has_installable_to_path() = indeterminate, + n::has_installable_to_repository() = indeterminate, + n::has_installed_at_path() = indeterminate, + n::has_key_requirements() = indeterminate, + n::has_package() = indeterminate, + n::has_package_name_part() = indeterminate, + n::has_tag() = indeterminate, + n::has_version_requirements() = indeterminate + )); + } } std::pair<std::shared_ptr<const Resolvents>, bool> @@ -275,6 +315,17 @@ GetResolventsForHelper::operator() ( auto want_best(target ? _imp->want_best_slot_for_targets : _imp->want_best_slot_otherwise); auto fallback(target ? _imp->fallback_to_other_slots_for_targets : _imp->fallback_to_other_slots_otherwise); + auto cache_ok(can_use_cache(spec)); + auto cache_key(std::make_tuple(want_installed, want_best, fallback, stringify(spec))); + + if (cache_ok) + { + Lock lock(_imp->cache_mutex); + auto c(_imp->cache.find(cache_key)); + if (_imp->cache.end() != c) + return c->second; + } + auto result_ids(std::make_shared<PackageIDSequence>()); std::shared_ptr<const PackageID> best; @@ -345,6 +396,12 @@ GetResolventsForHelper::operator() ( } } + if (cache_ok) + { + Lock lock(_imp->cache_mutex); + _imp->cache.insert(std::make_pair(cache_key, result)); + } + return result; } |