diff options
author | 2011-01-31 16:17:41 +0000 | |
---|---|---|
committer | 2011-01-31 16:17:41 +0000 | |
commit | 8cd3f89f1e7817fafca33e410b24af18fc333874 (patch) | |
tree | 1f991906a1512f4b8f508db07834575671fde660 | |
parent | 6eeca897e480fbb24cc5bfd6df6cf97fc5d82594 (diff) | |
download | paludis-8cd3f89f1e7817fafca33e410b24af18fc333874.tar.gz paludis-8cd3f89f1e7817fafca33e410b24af18fc333874.tar.xz |
Reuse common choice values
-rw-r--r-- | paludis/repositories/e/e_choice_value.cc | 107 | ||||
-rw-r--r-- | paludis/repositories/e/e_choice_value.hh | 27 | ||||
-rw-r--r-- | paludis/repositories/e/e_choices_key.cc | 2 | ||||
-rw-r--r-- | paludis/repositories/e/e_installed_repository_id.cc | 4 | ||||
-rw-r--r-- | paludis/repositories/e/e_installed_repository_id.hh | 2 | ||||
-rw-r--r-- | paludis/repositories/e/e_repository_id.hh | 4 | ||||
-rw-r--r-- | paludis/repositories/e/ebuild_id.cc | 4 | ||||
-rw-r--r-- | paludis/repositories/e/ebuild_id.hh | 2 |
8 files changed, 129 insertions, 23 deletions
diff --git a/paludis/repositories/e/e_choice_value.cc b/paludis/repositories/e/e_choice_value.cc index 2251efa97..a89866fb2 100644 --- a/paludis/repositories/e/e_choice_value.cc +++ b/paludis/repositories/e/e_choice_value.cc @@ -20,10 +20,38 @@ #include <paludis/repositories/e/e_choice_value.hh> #include <paludis/repositories/e/use_desc.hh> #include <paludis/util/make_null_shared_ptr.hh> +#include <paludis/util/hashes.hh> +#include <paludis/util/mutex.hh> +#include <paludis/util/pimp-impl.hh> +#include <paludis/util/singleton-impl.hh> +#include <unordered_map> using namespace paludis; using namespace paludis::erepository; +namespace +{ + class EChoiceValue : + public ChoiceValue + { + private: + const EChoiceValueParams _params; + + public: + EChoiceValue(const EChoiceValueParams &); + + const UnprefixedChoiceName unprefixed_name() const; + const ChoiceNameWithPrefix name_with_prefix() const; + bool enabled() const; + bool enabled_by_default() const; + bool locked() const; + const std::string description() const; + bool explicitly_listed() const; + const std::string parameter() const PALUDIS_ATTRIBUTE((warn_unused_result)); + const std::shared_ptr<const PermittedChoiceValueParameterValues> permitted_parameter_values() const PALUDIS_ATTRIBUTE((warn_unused_result)); + }; +} + EChoiceValue::EChoiceValue(const EChoiceValueParams & p) : _params(p) { @@ -83,3 +111,82 @@ EChoiceValue::permitted_parameter_values() const return make_null_shared_ptr(); } +namespace +{ + struct EChoiceValueParamsHash + { + Hash<ChoiceNameWithPrefix> choice_name_with_prefix_hash; + Hash<ChoicePrefixName> choice_prefix_name_hash; + Hash<std::string> description_hash; + Hash<bool> enabled_hash; + Hash<bool> enabled_by_default_hash; + Hash<bool> explicitly_listed_hash; + Hash<bool> locked_hash; + Hash<UnprefixedChoiceName> unprefixed_choice_name_hash; + + std::size_t operator() (const EChoiceValueParams & p) const + { + return 0 + ^ choice_name_with_prefix_hash(p.choice_name_with_prefix()) + ^ choice_prefix_name_hash(p.choice_prefix_name()) + ^ description_hash(p.description()) + ^ enabled_hash(p.enabled()) + ^ enabled_by_default_hash(p.enabled_by_default()) + ^ explicitly_listed_hash(p.explicitly_listed()) + ^ locked_hash(p.locked()) + ^ unprefixed_choice_name_hash(p.unprefixed_choice_name()) + ; + } + }; + + struct EChoiceValueParamsCompare + { + bool operator() (const EChoiceValueParams & a, const EChoiceValueParams & b) const + { + return true + && (a.choice_name_with_prefix() == b.choice_name_with_prefix()) + && (a.choice_prefix_name() == b.choice_prefix_name()) + && (a.description() == b.description()) + && (a.enabled() == b.enabled()) + && (a.enabled_by_default() == b.enabled_by_default()) + && (a.explicitly_listed() == b.explicitly_listed()) + && (a.locked() == b.locked()) + && (a.unprefixed_choice_name() == b.unprefixed_choice_name()) + ; + } + }; + + typedef std::unordered_map<EChoiceValueParams, std::shared_ptr<const EChoiceValue>, EChoiceValueParamsHash, EChoiceValueParamsCompare> Store; +} + +namespace paludis +{ + template <> + struct Imp<EChoiceValueStore> + { + mutable Mutex mutex; + mutable Store store; + }; +} + +EChoiceValueStore::EChoiceValueStore() : + _imp() +{ +} + +EChoiceValueStore::~EChoiceValueStore() = default; + +const std::shared_ptr<const ChoiceValue> +EChoiceValueStore::fetch(const EChoiceValueParams & p) const +{ + Lock lock(_imp->mutex); + auto i(_imp->store.find(p)); + if (i == _imp->store.end()) + i = _imp->store.insert(std::make_pair(p, std::make_shared<EChoiceValue>(p))).first; + + return i->second; +} + +template class Pimp<erepository::EChoiceValueStore>; +template class Singleton<erepository::EChoiceValueStore>; + diff --git a/paludis/repositories/e/e_choice_value.hh b/paludis/repositories/e/e_choice_value.hh index 5f65656fb..829cb3cab 100644 --- a/paludis/repositories/e/e_choice_value.hh +++ b/paludis/repositories/e/e_choice_value.hh @@ -22,6 +22,7 @@ #include <paludis/util/attributes.hh> #include <paludis/util/named_value.hh> +#include <paludis/util/singleton.hh> #include <paludis/choice.hh> #include <paludis/name.hh> #include <functional> @@ -55,26 +56,24 @@ namespace paludis NamedValue<n::unprefixed_choice_name, UnprefixedChoiceName> unprefixed_choice_name; }; - class PALUDIS_VISIBLE EChoiceValue : - public ChoiceValue + class PALUDIS_VISIBLE EChoiceValueStore : + public Singleton<EChoiceValueStore> { + friend class Singleton<EChoiceValueStore>; + private: - const EChoiceValueParams _params; + EChoiceValueStore(); + ~EChoiceValueStore(); - public: - EChoiceValue(const EChoiceValueParams &); + Pimp<EChoiceValueStore> _imp; - const UnprefixedChoiceName unprefixed_name() const; - const ChoiceNameWithPrefix name_with_prefix() const; - bool enabled() const; - bool enabled_by_default() const; - bool locked() const; - const std::string description() const; - bool explicitly_listed() const; - const std::string parameter() const PALUDIS_ATTRIBUTE((warn_unused_result)); - const std::shared_ptr<const PermittedChoiceValueParameterValues> permitted_parameter_values() const PALUDIS_ATTRIBUTE((warn_unused_result)); + public: + const std::shared_ptr<const ChoiceValue> fetch(const EChoiceValueParams &) const PALUDIS_ATTRIBUTE((warn_unused_result)); }; } + + extern template class Pimp<erepository::EChoiceValueStore>; + extern template class Singleton<erepository::EChoiceValueStore>; } #endif diff --git a/paludis/repositories/e/e_choices_key.cc b/paludis/repositories/e/e_choices_key.cc index 89635a490..b4d55efab 100644 --- a/paludis/repositories/e/e_choices_key.cc +++ b/paludis/repositories/e/e_choices_key.cc @@ -185,7 +185,7 @@ namespace } }; - std::shared_ptr<ChoiceValue> make_myoption( + std::shared_ptr<const ChoiceValue> make_myoption( const std::shared_ptr<const ERepositoryID> & id, std::shared_ptr<Choice> & choice, const UnprefixedChoiceName & unprefixed, diff --git a/paludis/repositories/e/e_installed_repository_id.cc b/paludis/repositories/e/e_installed_repository_id.cc index c33464fd5..d2e7bb604 100644 --- a/paludis/repositories/e/e_installed_repository_id.cc +++ b/paludis/repositories/e/e_installed_repository_id.cc @@ -1042,7 +1042,7 @@ EInstalledRepositoryID::slot_key() const return _imp->keys->slot; } -std::shared_ptr<ChoiceValue> +const std::shared_ptr<const ChoiceValue> EInstalledRepositoryID::make_choice_value(const std::shared_ptr<const Choice> & c, const UnprefixedChoiceName & v, const Tribool, const bool, const bool explicitly_listed, const std::string & override_description, const bool) const { @@ -1064,7 +1064,7 @@ EInstalledRepositoryID::make_choice_value(const std::shared_ptr<const Choice> & if (raw_use_key()) enabled = (raw_use_key()->value()->end() != raw_use_key()->value()->find(name_with_prefix)); - return std::make_shared<EChoiceValue>(make_named_values<EChoiceValueParams>( + return EChoiceValueStore::get_instance()->fetch(make_named_values<EChoiceValueParams>( n::choice_name_with_prefix() = ChoiceNameWithPrefix(name_with_prefix), n::choice_prefix_name() = c->prefix(), n::description() = override_description, diff --git a/paludis/repositories/e/e_installed_repository_id.hh b/paludis/repositories/e/e_installed_repository_id.hh index 7d4765f4e..954187dcf 100644 --- a/paludis/repositories/e/e_installed_repository_id.hh +++ b/paludis/repositories/e/e_installed_repository_id.hh @@ -106,7 +106,7 @@ namespace paludis virtual std::string contents_filename() const = 0; virtual std::shared_ptr<MetadataValueKey<std::shared_ptr<const Contents> > > make_contents_key() const = 0; - virtual std::shared_ptr<ChoiceValue> make_choice_value( + virtual const std::shared_ptr<const ChoiceValue> make_choice_value( const std::shared_ptr<const Choice> &, const UnprefixedChoiceName &, const Tribool, const bool, const bool, const std::string &, const bool) const; diff --git a/paludis/repositories/e/e_repository_id.hh b/paludis/repositories/e/e_repository_id.hh index 6fd3f8c62..27129f40b 100644 --- a/paludis/repositories/e/e_repository_id.hh +++ b/paludis/repositories/e/e_repository_id.hh @@ -1,7 +1,7 @@ /* vim: set sw=4 sts=4 et foldmethod=syntax : */ /* - * Copyright (c) 2007, 2008, 2009, 2010 Ciaran McCreesh + * Copyright (c) 2007, 2008, 2009, 2010, 2011 Ciaran McCreesh * * This file is part of the Paludis package manager. Paludis is free software; * you can redistribute it and/or modify it under the terms of the GNU General @@ -48,7 +48,7 @@ namespace paludis virtual std::shared_ptr<const Set<std::string> > breaks_portage() const PALUDIS_ATTRIBUTE((warn_unused_result)); - virtual std::shared_ptr<ChoiceValue> make_choice_value( + virtual const std::shared_ptr<const ChoiceValue> make_choice_value( const std::shared_ptr<const Choice> &, const UnprefixedChoiceName &, const Tribool, const bool, const bool, const std::string &, const bool) const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0; diff --git a/paludis/repositories/e/ebuild_id.cc b/paludis/repositories/e/ebuild_id.cc index 83519d430..c34d07fe8 100644 --- a/paludis/repositories/e/ebuild_id.cc +++ b/paludis/repositories/e/ebuild_id.cc @@ -1419,7 +1419,7 @@ namespace } -std::shared_ptr<ChoiceValue> +const std::shared_ptr<const ChoiceValue> EbuildID::make_choice_value( const std::shared_ptr<const Choice> & choice, const UnprefixedChoiceName & value_name, @@ -1498,7 +1498,7 @@ EbuildID::make_choice_value( } } - return std::make_shared<EChoiceValue>(make_named_values<EChoiceValueParams>( + return EChoiceValueStore::get_instance()->fetch(make_named_values<EChoiceValueParams>( n::choice_name_with_prefix() = ChoiceNameWithPrefix(name_with_prefix), n::choice_prefix_name() = choice->prefix(), n::description() = get_description(e_repo->use_desc(), override_description, name(), choice->prefix(), value_name), diff --git a/paludis/repositories/e/ebuild_id.hh b/paludis/repositories/e/ebuild_id.hh index ab9c73493..21af84003 100644 --- a/paludis/repositories/e/ebuild_id.hh +++ b/paludis/repositories/e/ebuild_id.hh @@ -158,7 +158,7 @@ namespace paludis virtual void invalidate_masks() const; - virtual std::shared_ptr<ChoiceValue> make_choice_value( + virtual const std::shared_ptr<const ChoiceValue> make_choice_value( const std::shared_ptr<const Choice> &, const UnprefixedChoiceName &, const Tribool, const bool, const bool, const std::string &, const bool) const; |