diff options
Diffstat (limited to 'paludis/repositories')
-rw-r--r-- | paludis/repositories/e/Makefile.am | 4 | ||||
-rw-r--r-- | paludis/repositories/e/e_installed_repository_id.cc | 35 | ||||
-rw-r--r-- | paludis/repositories/e/e_key.cc | 137 | ||||
-rw-r--r-- | paludis/repositories/e/e_key.hh | 43 | ||||
-rw-r--r-- | paludis/repositories/e/e_keywords_key.cc | 163 | ||||
-rw-r--r-- | paludis/repositories/e/e_keywords_key.hh | 51 | ||||
-rw-r--r-- | paludis/repositories/e/e_string_set_key.cc | 162 | ||||
-rw-r--r-- | paludis/repositories/e/e_string_set_key.hh | 51 | ||||
-rw-r--r-- | paludis/repositories/e/ebuild.cc | 17 | ||||
-rw-r--r-- | paludis/repositories/e/ebuild_flat_metadata_cache.cc | 27 | ||||
-rw-r--r-- | paludis/repositories/e/ebuild_id.cc | 40 | ||||
-rw-r--r-- | paludis/repositories/e/ebuild_id.hh | 14 |
12 files changed, 497 insertions, 247 deletions
diff --git a/paludis/repositories/e/Makefile.am b/paludis/repositories/e/Makefile.am index 956e8f63e..f900a58b7 100644 --- a/paludis/repositories/e/Makefile.am +++ b/paludis/repositories/e/Makefile.am @@ -39,6 +39,7 @@ noinst_HEADERS = \ e_installed_repository_id.hh \ e_choices_key.hh \ e_key.hh \ + e_keywords_key.hh \ e_mask.hh \ e_repository.hh \ e_repository_exceptions.hh \ @@ -49,6 +50,7 @@ noinst_HEADERS = \ e_repository_params.hh \ e_repository_sets.hh \ e_slot_key.hh \ + e_string_set_key.hh \ e_stripper.hh \ eapi.hh \ eapi-fwd.hh \ @@ -111,6 +113,7 @@ libpaludiserepository_la_SOURCES = \ e_installed_repository_id.cc \ e_choices_key.cc \ e_key.cc \ + e_keywords_key.cc \ e_mask.cc \ e_repository.cc \ e_repository_exceptions.cc \ @@ -120,6 +123,7 @@ libpaludiserepository_la_SOURCES = \ e_repository_params.cc \ e_repository_sets.cc \ e_slot_key.cc \ + e_string_set_key.cc \ e_stripper.cc \ eapi.cc \ eapi_phase.cc \ diff --git a/paludis/repositories/e/e_installed_repository_id.cc b/paludis/repositories/e/e_installed_repository_id.cc index 92e521e74..9cd94a8db 100644 --- a/paludis/repositories/e/e_installed_repository_id.cc +++ b/paludis/repositories/e/e_installed_repository_id.cc @@ -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 @@ -26,6 +26,7 @@ #include <paludis/repositories/e/dep_parser.hh> #include <paludis/repositories/e/dependencies_rewriter.hh> #include <paludis/repositories/e/e_choice_value.hh> +#include <paludis/repositories/e/e_string_set_key.hh> #include <paludis/util/stringify.hh> #include <paludis/util/log.hh> @@ -220,8 +221,7 @@ EInstalledRepositoryID::need_keys_added() const if (! env->env_use().empty()) if ((_imp->dir / env->env_use()).stat().exists()) { - _imp->keys->raw_use = std::make_shared<EStringSetKey>(env->env_use(), env->description_use(), - file_contents(_imp->dir / env->env_use()), mkt_internal); + _imp->keys->raw_use = EStringSetKeyStore::get_instance()->fetch(vars->use(), file_contents(_imp->dir / env->env_use()), mkt_internal); add_metadata_key(_imp->keys->raw_use); } @@ -236,8 +236,8 @@ EInstalledRepositoryID::need_keys_added() const if (! vars->inherited()->name().empty()) if ((_imp->dir / vars->inherited()->name()).stat().exists()) { - _imp->keys->inherited = std::make_shared<EStringSetKey>(vars->inherited()->name(), vars->inherited()->description(), - file_contents(_imp->dir / vars->inherited()->name()), mkt_internal); + _imp->keys->inherited = EStringSetKeyStore::get_instance()->fetch(vars->inherited(), + file_contents(_imp->dir / vars->inherited()->name()), mkt_internal); add_metadata_key(_imp->keys->inherited); } @@ -247,8 +247,8 @@ EInstalledRepositoryID::need_keys_added() const std::string d(file_contents(_imp->dir / vars->defined_phases()->name())); if (! d.empty()) { - _imp->keys->defined_phases = std::make_shared<EStringSetKey>(vars->defined_phases()->name(), vars->defined_phases()->description(), - d, mkt_internal); + _imp->keys->defined_phases = EStringSetKeyStore::get_instance()->fetch(vars->defined_phases(), + d, mkt_internal); add_metadata_key(_imp->keys->defined_phases); } } @@ -256,14 +256,14 @@ EInstalledRepositoryID::need_keys_added() const if (! vars->iuse()->name().empty()) { if ((_imp->dir / vars->iuse()->name()).stat().exists()) - _imp->keys->raw_iuse = std::make_shared<EStringSetKey>(vars->iuse()->name(), vars->iuse()->description(), - file_contents(_imp->dir / vars->iuse()->name()), mkt_internal); + _imp->keys->raw_iuse = EStringSetKeyStore::get_instance()->fetch(vars->iuse(), + file_contents(_imp->dir / vars->iuse()->name()), mkt_internal); else { /* hack: if IUSE doesn't exist, we still need an iuse_key to make the choices * code behave sanely. */ - _imp->keys->raw_iuse = std::make_shared<EStringSetKey>(vars->iuse()->name(), vars->iuse()->description(), - "", mkt_internal); + _imp->keys->raw_iuse = EStringSetKeyStore::get_instance()->fetch(vars->iuse(), + "", mkt_internal); } add_metadata_key(_imp->keys->raw_iuse); } @@ -272,9 +272,8 @@ EInstalledRepositoryID::need_keys_added() const { if ((_imp->dir / vars->iuse_effective()->name()).stat().exists()) { - _imp->keys->raw_iuse_effective = std::make_shared<EStringSetKey>( - vars->iuse_effective()->name(), vars->iuse_effective()->description(), - file_contents(_imp->dir / vars->iuse_effective()->name()), mkt_internal); + _imp->keys->raw_iuse_effective = EStringSetKeyStore::get_instance()->fetch(vars->iuse_effective(), + file_contents(_imp->dir / vars->iuse_effective()->name()), mkt_internal); add_metadata_key(_imp->keys->raw_iuse_effective); } } @@ -298,16 +297,16 @@ EInstalledRepositoryID::need_keys_added() const if (! vars->use_expand()->name().empty()) if ((_imp->dir / vars->use_expand()->name()).stat().exists()) { - _imp->keys->raw_use_expand = std::make_shared<EStringSetKey>(vars->use_expand()->name(), vars->use_expand()->description(), - file_contents(_imp->dir / vars->use_expand()->name()), mkt_internal); + _imp->keys->raw_use_expand = EStringSetKeyStore::get_instance()->fetch(vars->use_expand(), + file_contents(_imp->dir / vars->use_expand()->name()), mkt_internal); add_metadata_key(_imp->keys->raw_use_expand); } if (! vars->use_expand_hidden()->name().empty()) if ((_imp->dir / vars->use_expand_hidden()->name()).stat().exists()) { - _imp->keys->raw_use_expand_hidden = std::make_shared<EStringSetKey>(vars->use_expand_hidden()->name(), vars->use_expand_hidden()->description(), - file_contents(_imp->dir / vars->use_expand_hidden()->name()), mkt_internal); + _imp->keys->raw_use_expand_hidden = EStringSetKeyStore::get_instance()->fetch(vars->use_expand_hidden(), + file_contents(_imp->dir / vars->use_expand_hidden()->name()), mkt_internal); add_metadata_key(_imp->keys->raw_use_expand_hidden); } diff --git a/paludis/repositories/e/e_key.cc b/paludis/repositories/e/e_key.cc index abde8a9d8..6bd34a807 100644 --- a/paludis/repositories/e/e_key.cc +++ b/paludis/repositories/e/e_key.cc @@ -792,143 +792,6 @@ EProvideKey::type() const namespace paludis { template <> - struct Imp<EKeywordsKey> - { - const std::shared_ptr<const ERepositoryID> id; - const Environment * const env; - const std::string string_value; - mutable Mutex value_mutex; - mutable std::shared_ptr<KeywordNameSet> value; - - const std::string raw_name; - const std::string human_name; - const MetadataKeyType type; - - Imp(const std::shared_ptr<const ERepositoryID> & i, const Environment * const e, const std::string & v, - const std::string & r, const std::string & h, const MetadataKeyType t) : - id(i), - env(e), - string_value(v), - raw_name(r), - human_name(h), - type(t) - { - } - }; -} - -EKeywordsKey::EKeywordsKey(const Environment * const e, const std::shared_ptr<const ERepositoryID> & id, - const std::string & r, const std::string & h, const std::string & v, const MetadataKeyType t) : - Pimp<EKeywordsKey>(id, e, v, r, h, t) -{ -} - -EKeywordsKey::~EKeywordsKey() -{ -} - -const std::shared_ptr<const KeywordNameSet> -EKeywordsKey::value() const -{ - Lock l(_imp->value_mutex); - if (_imp->value) - return _imp->value; - - _imp->value = std::make_shared<KeywordNameSet>(); - Context context("When parsing metadata key '" + raw_name() + "' from '" + stringify(*_imp->id) + "':"); - tokenise_whitespace(_imp->string_value, create_inserter<KeywordName>(_imp->value->inserter())); - return _imp->value; -} - -const std::string -EKeywordsKey::pretty_print_value(const PrettyPrinter & p, const PrettyPrintOptions &) const -{ - return join(value()->begin(), value()->end(), " ", CallPrettyPrinter(p)); -} - -const std::string -EKeywordsKey::raw_name() const -{ - return _imp->raw_name; -} - -const std::string -EKeywordsKey::human_name() const -{ - return _imp->human_name; -} - -MetadataKeyType -EKeywordsKey::type() const -{ - return _imp->type; -} - -namespace paludis -{ - template <> - struct Imp<EStringSetKey> - { - const std::shared_ptr<Set<std::string> > value; - - const std::string raw_name; - const std::string human_name; - const MetadataKeyType type; - - Imp(const std::string & v, const std::string & r, const std::string & h, const MetadataKeyType t) : - value(std::make_shared<Set<std::string> >()), - raw_name(r), - human_name(h), - type(t) - { - tokenise_whitespace(v, value->inserter()); - } - }; -} - -EStringSetKey::EStringSetKey(const std::string & r, const std::string & h, const std::string & v, const MetadataKeyType t) : - Pimp<EStringSetKey>(v, r, h, t) -{ -} - -EStringSetKey::~EStringSetKey() -{ -} - -const std::shared_ptr<const Set<std::string> > -EStringSetKey::value() const -{ - return _imp->value; -} - -const std::string -EStringSetKey::raw_name() const -{ - return _imp->raw_name; -} - -const std::string -EStringSetKey::human_name() const -{ - return _imp->human_name; -} - -MetadataKeyType -EStringSetKey::type() const -{ - return _imp->type; -} - -const std::string -EStringSetKey::pretty_print_value( - const PrettyPrinter & p, const PrettyPrintOptions &) const -{ - return join(value()->begin(), value()->end(), " ", CallPrettyPrinter(p)); -} - -namespace paludis -{ - template <> struct Imp<EContentsKey> { const std::shared_ptr<const ERepositoryID> id; diff --git a/paludis/repositories/e/e_key.hh b/paludis/repositories/e/e_key.hh index e1cfba5a9..da356f68e 100644 --- a/paludis/repositories/e/e_key.hh +++ b/paludis/repositories/e/e_key.hh @@ -247,49 +247,6 @@ namespace paludis const PrettyPrintOptions &) const PALUDIS_ATTRIBUTE((warn_unused_result)); }; - class EKeywordsKey : - public MetadataCollectionKey<KeywordNameSet>, - private Pimp<EKeywordsKey> - { - public: - EKeywordsKey( - const Environment * const, - const std::shared_ptr<const ERepositoryID> &, - const std::string &, const std::string &, const std::string &, const MetadataKeyType); - ~EKeywordsKey(); - - const std::shared_ptr<const KeywordNameSet> value() const - PALUDIS_ATTRIBUTE((warn_unused_result)); - - virtual const std::string raw_name() const PALUDIS_ATTRIBUTE((warn_unused_result)); - virtual const std::string human_name() const PALUDIS_ATTRIBUTE((warn_unused_result)); - virtual MetadataKeyType type() const PALUDIS_ATTRIBUTE((warn_unused_result)); - - virtual const std::string pretty_print_value( - const PrettyPrinter &, - const PrettyPrintOptions &) const PALUDIS_ATTRIBUTE((warn_unused_result)); - }; - - class EStringSetKey : - public MetadataCollectionKey<Set<std::string> >, - private Pimp<EStringSetKey> - { - public: - EStringSetKey(const std::string &, const std::string &, const std::string &, const MetadataKeyType); - ~EStringSetKey(); - - const std::shared_ptr<const Set<std::string> > value() const - PALUDIS_ATTRIBUTE((warn_unused_result)); - - virtual const std::string raw_name() const PALUDIS_ATTRIBUTE((warn_unused_result)); - virtual const std::string human_name() const PALUDIS_ATTRIBUTE((warn_unused_result)); - virtual MetadataKeyType type() const PALUDIS_ATTRIBUTE((warn_unused_result)); - - virtual const std::string pretty_print_value( - const PrettyPrinter &, - const PrettyPrintOptions &) const PALUDIS_ATTRIBUTE((warn_unused_result)); - }; - class EContentsKey : public MetadataValueKey<std::shared_ptr<const Contents> >, private Pimp<EContentsKey> diff --git a/paludis/repositories/e/e_keywords_key.cc b/paludis/repositories/e/e_keywords_key.cc new file mode 100644 index 000000000..71d05cfbc --- /dev/null +++ b/paludis/repositories/e/e_keywords_key.cc @@ -0,0 +1,163 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 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 + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <paludis/repositories/e/e_keywords_key.hh> +#include <paludis/repositories/e/eapi.hh> + +#include <paludis/util/singleton-impl.hh> +#include <paludis/util/hashes.hh> +#include <paludis/util/singleton-impl.hh> +#include <paludis/util/pimp-impl.hh> +#include <paludis/util/join.hh> +#include <paludis/util/wrapped_output_iterator.hh> +#include <paludis/util/tokeniser.hh> +#include <paludis/util/create_iterator-impl.hh> + +#include <paludis/name.hh> +#include <paludis/pretty_printer.hh> +#include <paludis/call_pretty_printer.hh> + +#include <tuple> +#include <unordered_map> +#include <algorithm> + +using namespace paludis; +using namespace paludis::erepository; + +namespace +{ + struct EKeywordsKey : + MetadataCollectionKey<Set<KeywordName> > + { + const std::shared_ptr<const Set<KeywordName> > parsed_value; + const std::shared_ptr<const EAPIMetadataVariable> variable; + const MetadataKeyType key_type; + + EKeywordsKey( + const std::shared_ptr<const Set<KeywordName> > & v, + const std::shared_ptr<const EAPIMetadataVariable> & m, + const MetadataKeyType t) : + parsed_value(v), + variable(m), + key_type(t) + { + } + + ~EKeywordsKey() + { + } + + const std::shared_ptr<const Set<KeywordName> > value() const + { + return parsed_value; + } + + const std::string raw_name() const + { + return variable->name(); + } + + const std::string human_name() const + { + return variable->description(); + } + + virtual MetadataKeyType type() const + { + return key_type; + } + + virtual const std::string pretty_print_value( + const PrettyPrinter & p, + const PrettyPrintOptions &) const + { + return join(value()->begin(), value()->end(), " ", CallPrettyPrinter(p)); + } + }; + + typedef std::tuple<std::shared_ptr<const EAPIMetadataVariable>, std::shared_ptr<const Set<KeywordName> >, MetadataKeyType> EKeywordsKeyStoreIndex; + + long hash_set(const std::shared_ptr<const Set<KeywordName> > & v) + { + int result(0); + for (auto s(v->begin()), s_end(v->end()) ; + s != s_end ; ++s) + result = (result << 4) ^ Hash<std::string>()(stringify(*s)); + return result; + } + + struct EKeywordsKeyHash + { + std::size_t operator() (const EKeywordsKeyStoreIndex & p) const + { + return + Hash<std::string>()(std::get<0>(p)->description()) ^ + std::get<0>(p)->flat_list_index() ^ + Hash<std::string>()(std::get<0>(p)->name()) ^ + hash_set(std::get<1>(p)) ^ + static_cast<int>(std::get<2>(p)); + } + }; + + struct EKeywordsKeyStoreCompare + { + bool operator() (const EKeywordsKeyStoreIndex & a, const EKeywordsKeyStoreIndex & b) const + { + return std::get<0>(a) == std::get<0>(b) && std::get<2>(a) == std::get<2>(b) && + std::get<1>(a)->size() == std::get<1>(b)->size() && + std::get<1>(a)->end() == std::mismatch(std::get<1>(a)->begin(), std::get<1>(a)->end(), std::get<1>(b)->begin()).first; + } + }; +} + +namespace paludis +{ + template <> + struct Imp<EKeywordsKeyStore> + { + mutable Mutex mutex; + mutable std::unordered_map<EKeywordsKeyStoreIndex, std::shared_ptr<const EKeywordsKey>, EKeywordsKeyHash, EKeywordsKeyStoreCompare> store; + }; +} + +EKeywordsKeyStore::EKeywordsKeyStore() : + Pimp<EKeywordsKeyStore>() +{ +} + +EKeywordsKeyStore::~EKeywordsKeyStore() = default; + +const std::shared_ptr<const MetadataCollectionKey<Set<KeywordName> > > +EKeywordsKeyStore::fetch( + const std::shared_ptr<const EAPIMetadataVariable> & v, + const std::string & s, + const MetadataKeyType t) const +{ + Lock lock(_imp->mutex); + + auto k(std::make_shared<Set<KeywordName> >()); + tokenise_whitespace(s, create_inserter<KeywordName>(k->inserter())); + + EKeywordsKeyStoreIndex x(v, k, t); + auto i(_imp->store.find(x)); + if (i == _imp->store.end()) + i = _imp->store.insert(std::make_pair(x, std::make_shared<const EKeywordsKey>(k, v, t))).first; + return i->second; +} + diff --git a/paludis/repositories/e/e_keywords_key.hh b/paludis/repositories/e/e_keywords_key.hh new file mode 100644 index 000000000..f839f2eaa --- /dev/null +++ b/paludis/repositories/e/e_keywords_key.hh @@ -0,0 +1,51 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 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 + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_E_E_KEYWORDS_KEY_HH +#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_E_E_KEYWORDS_KEY_HH 1 + +#include <paludis/metadata_key.hh> +#include <paludis/util/singleton.hh> +#include <paludis/repositories/e/eapi-fwd.hh> + +namespace paludis +{ + namespace erepository + { + class EKeywordsKeyStore : + private Pimp<EKeywordsKeyStore>, + public Singleton<EKeywordsKeyStore> + { + friend class Singleton<EKeywordsKeyStore>; + + private: + EKeywordsKeyStore(); + ~EKeywordsKeyStore(); + + public: + const std::shared_ptr<const MetadataCollectionKey<Set<KeywordName> > > fetch( + const std::shared_ptr<const EAPIMetadataVariable> &, + const std::string &, + const MetadataKeyType) const PALUDIS_ATTRIBUTE((warn_unused_result)); + }; + + } +} + +#endif diff --git a/paludis/repositories/e/e_string_set_key.cc b/paludis/repositories/e/e_string_set_key.cc new file mode 100644 index 000000000..e7362f38c --- /dev/null +++ b/paludis/repositories/e/e_string_set_key.cc @@ -0,0 +1,162 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 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 + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <paludis/repositories/e/e_string_set_key.hh> +#include <paludis/repositories/e/eapi.hh> + +#include <paludis/util/singleton-impl.hh> +#include <paludis/util/hashes.hh> +#include <paludis/util/singleton-impl.hh> +#include <paludis/util/pimp-impl.hh> +#include <paludis/util/join.hh> +#include <paludis/util/wrapped_output_iterator.hh> +#include <paludis/util/tokeniser.hh> + +#include <paludis/name.hh> +#include <paludis/pretty_printer.hh> +#include <paludis/call_pretty_printer.hh> + +#include <tuple> +#include <unordered_map> +#include <algorithm> + +using namespace paludis; +using namespace paludis::erepository; + +namespace +{ + struct EStringSetKey : + MetadataCollectionKey<Set<std::string> > + { + const std::shared_ptr<const Set<std::string> > parsed_value; + const std::shared_ptr<const EAPIMetadataVariable> variable; + const MetadataKeyType key_type; + + EStringSetKey( + const std::shared_ptr<const Set<std::string> > & v, + const std::shared_ptr<const EAPIMetadataVariable> & m, + const MetadataKeyType t) : + parsed_value(v), + variable(m), + key_type(t) + { + } + + ~EStringSetKey() + { + } + + const std::shared_ptr<const Set<std::string> > value() const + { + return parsed_value; + } + + const std::string raw_name() const + { + return variable->name(); + } + + const std::string human_name() const + { + return variable->description(); + } + + virtual MetadataKeyType type() const + { + return key_type; + } + + virtual const std::string pretty_print_value( + const PrettyPrinter & p, + const PrettyPrintOptions &) const + { + return join(value()->begin(), value()->end(), " ", CallPrettyPrinter(p)); + } + }; + + typedef std::tuple<std::shared_ptr<const EAPIMetadataVariable>, std::shared_ptr<const Set<std::string> >, MetadataKeyType> EStringSetKeyStoreIndex; + + long hash_set(const std::shared_ptr<const Set<std::string> > & v) + { + int result(0); + for (auto s(v->begin()), s_end(v->end()) ; + s != s_end ; ++s) + result = (result << 4) ^ Hash<std::string>()(*s); + return result; + } + + struct EStringSetKeyHash + { + std::size_t operator() (const EStringSetKeyStoreIndex & p) const + { + return + Hash<std::string>()(std::get<0>(p)->description()) ^ + std::get<0>(p)->flat_list_index() ^ + Hash<std::string>()(std::get<0>(p)->name()) ^ + hash_set(std::get<1>(p)) ^ + static_cast<int>(std::get<2>(p)); + } + }; + + struct EStringSetKeyStoreCompare + { + bool operator() (const EStringSetKeyStoreIndex & a, const EStringSetKeyStoreIndex & b) const + { + return std::get<0>(a) == std::get<0>(b) && std::get<2>(a) == std::get<2>(b) && + std::get<1>(a)->size() == std::get<1>(b)->size() && + std::get<1>(a)->end() == std::mismatch(std::get<1>(a)->begin(), std::get<1>(a)->end(), std::get<1>(b)->begin()).first; + } + }; +} + +namespace paludis +{ + template <> + struct Imp<EStringSetKeyStore> + { + mutable Mutex mutex; + mutable std::unordered_map<EStringSetKeyStoreIndex, std::shared_ptr<const EStringSetKey>, EStringSetKeyHash, EStringSetKeyStoreCompare> store; + }; +} + +EStringSetKeyStore::EStringSetKeyStore() : + Pimp<EStringSetKeyStore>() +{ +} + +EStringSetKeyStore::~EStringSetKeyStore() = default; + +const std::shared_ptr<const MetadataCollectionKey<Set<std::string> > > +EStringSetKeyStore::fetch( + const std::shared_ptr<const EAPIMetadataVariable> & v, + const std::string & s, + const MetadataKeyType t) const +{ + Lock lock(_imp->mutex); + + auto k(std::make_shared<Set<std::string> >()); + tokenise_whitespace(s, k->inserter()); + + EStringSetKeyStoreIndex x(v, k, t); + auto i(_imp->store.find(x)); + if (i == _imp->store.end()) + i = _imp->store.insert(std::make_pair(x, std::make_shared<const EStringSetKey>(k, v, t))).first; + return i->second; +} + diff --git a/paludis/repositories/e/e_string_set_key.hh b/paludis/repositories/e/e_string_set_key.hh new file mode 100644 index 000000000..a9d71cbd1 --- /dev/null +++ b/paludis/repositories/e/e_string_set_key.hh @@ -0,0 +1,51 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 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 + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_E_E_STRING_SET_KEY_HH +#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_E_E_STRING_SET_KEY_HH 1 + +#include <paludis/metadata_key.hh> +#include <paludis/util/singleton.hh> +#include <paludis/repositories/e/eapi-fwd.hh> + +namespace paludis +{ + namespace erepository + { + class EStringSetKeyStore : + private Pimp<EStringSetKeyStore>, + public Singleton<EStringSetKeyStore> + { + friend class Singleton<EStringSetKeyStore>; + + private: + EStringSetKeyStore(); + ~EStringSetKeyStore(); + + public: + const std::shared_ptr<const MetadataCollectionKey<Set<std::string> > > fetch( + const std::shared_ptr<const EAPIMetadataVariable> &, + const std::string &, + const MetadataKeyType) const PALUDIS_ATTRIBUTE((warn_unused_result)); + }; + + } +} + +#endif diff --git a/paludis/repositories/e/ebuild.cc b/paludis/repositories/e/ebuild.cc index a51c1c893..96f486c96 100644 --- a/paludis/repositories/e/ebuild.cc +++ b/paludis/repositories/e/ebuild.cc @@ -1,7 +1,7 @@ /* vim: set sw=4 sts=4 et foldmethod=syntax : */ /* - * Copyright (c) 2006, 2007, 2008, 2009, 2010 Ciaran McCreesh + * Copyright (c) 2006, 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 @@ -623,7 +623,7 @@ EbuildMetadataCommand::load(const std::shared_ptr<const EbuildID> & id) id->load_provide(m.provide()->name(), m.provide()->description(), get(keys, m.provide()->name())); if (! m.iuse()->name().empty()) - id->load_iuse(m.iuse()->name(), m.iuse()->description(), get(keys, m.iuse()->name())); + id->load_iuse(m.iuse(), get(keys, m.iuse()->name())); if (! m.myoptions()->name().empty()) id->load_myoptions(m.myoptions()->name(), m.myoptions()->description(), get(keys, m.myoptions()->name())); @@ -632,10 +632,10 @@ EbuildMetadataCommand::load(const std::shared_ptr<const EbuildID> & id) id->load_required_use(m.required_use()->name(), m.required_use()->description(), get(keys, m.required_use()->name())); if (! m.inherited()->name().empty()) - id->load_inherited(m.inherited()->name(), m.inherited()->description(), get(keys, m.inherited()->name())); + id->load_inherited(m.inherited(), get(keys, m.inherited()->name())); if (! m.keywords()->name().empty()) - id->load_keywords(m.keywords()->name(), m.keywords()->description(), get(keys, m.keywords()->name())); + id->load_keywords(m.keywords(), get(keys, m.keywords()->name())); if (! m.restrictions()->name().empty()) id->load_restrict(m.restrictions(), get(keys, m.restrictions()->name())); @@ -644,10 +644,10 @@ EbuildMetadataCommand::load(const std::shared_ptr<const EbuildID> & id) id->load_properties(m.properties(), get(keys, m.properties()->name())); if (! m.use()->name().empty()) - id->load_use(m.use()->name(), m.use()->description(), get(keys, m.use()->name())); + id->load_use(m.use(), get(keys, m.use()->name())); if (! m.generated_from()->name().empty()) - id->load_generated_from(m.generated_from()->name(), m.generated_from()->description(), get(keys, m.generated_from()->name())); + id->load_generated_from(m.generated_from(), get(keys, m.generated_from()->name())); if (! m.generated_time()->name().empty()) id->load_generated_time(m.generated_time()->name(), m.generated_time()->description(), get(keys, m.generated_time()->name())); @@ -719,10 +719,9 @@ EbuildMetadataCommand::load(const std::shared_ptr<const EbuildID> & id) } if (defined_phases.empty()) - id->load_defined_phases(m.defined_phases()->name(), m.defined_phases()->description(), "-"); + id->load_defined_phases(m.defined_phases(), "-"); else - id->load_defined_phases(m.defined_phases()->name(), m.defined_phases()->description(), - join(defined_phases.begin(), defined_phases.end(), " ")); + id->load_defined_phases(m.defined_phases(), join(defined_phases.begin(), defined_phases.end(), " ")); } } diff --git a/paludis/repositories/e/ebuild_flat_metadata_cache.cc b/paludis/repositories/e/ebuild_flat_metadata_cache.cc index ab502a556..5284dbc8b 100644 --- a/paludis/repositories/e/ebuild_flat_metadata_cache.cc +++ b/paludis/repositories/e/ebuild_flat_metadata_cache.cc @@ -1,7 +1,7 @@ /* vim: set sw=4 sts=4 et foldmethod=syntax : */ /* - * Copyright (c) 2006, 2007, 2008, 2009, 2010 Ciaran McCreesh + * Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011 Ciaran McCreesh * Copyright (c) 2008 David Leverton * * This file is part of the Paludis package manager. Paludis is free software; @@ -226,18 +226,17 @@ namespace } if (-1 != m.keywords()->flat_list_index() && ! m.keywords()->name().empty()) - id->load_keywords(m.keywords()->name(), m.keywords()->description(), lines.at(m.keywords()->flat_list_index())); + id->load_keywords(m.keywords(), lines.at(m.keywords()->flat_list_index())); if (-1 != m.inherited()->flat_list_index() && ! m.inherited()->name().empty()) - id->load_inherited(m.inherited()->name(), m.inherited()->description(), lines.at(m.inherited()->flat_list_index())); + id->load_inherited(m.inherited(), lines.at(m.inherited()->flat_list_index())); if (-1 != m.defined_phases()->flat_list_index() && ! m.defined_phases()->name().empty()) if (! lines.at(m.defined_phases()->flat_list_index()).empty()) - id->load_defined_phases(m.defined_phases()->name(), m.defined_phases()->description(), - lines.at(m.defined_phases()->flat_list_index())); + id->load_defined_phases(m.defined_phases(), lines.at(m.defined_phases()->flat_list_index())); if (-1 != m.iuse()->flat_list_index() && ! m.iuse()->name().empty()) - id->load_iuse(m.iuse()->name(), m.iuse()->description(), lines.at(m.iuse()->flat_list_index())); + id->load_iuse(m.iuse(), lines.at(m.iuse()->flat_list_index())); if (-1 != m.myoptions()->flat_list_index() && ! m.myoptions()->name().empty()) id->load_myoptions(m.myoptions()->name(), m.myoptions()->description(), lines.at(m.myoptions()->flat_list_index())); @@ -252,10 +251,10 @@ namespace id->load_provide(m.provide()->name(), m.provide()->description(), lines.at(m.provide()->flat_list_index())); if (-1 != m.use()->flat_list_index() && ! m.use()->name().empty()) - id->load_use(m.use()->name(), m.use()->description(), lines.at(m.use()->flat_list_index())); + id->load_use(m.use(), lines.at(m.use()->flat_list_index())); if (-1 != m.generated_from()->flat_list_index() && ! m.generated_from()->name().empty()) - id->load_generated_from(m.generated_from()->name(), m.generated_from()->description(), lines.at(m.generated_from()->flat_list_index())); + id->load_generated_from(m.generated_from(), lines.at(m.generated_from()->flat_list_index())); if (-1 != m.generated_time()->flat_list_index() && ! m.generated_time()->name().empty()) id->load_generated_time(m.generated_time()->name(), m.generated_time()->description(), lines.at(m.generated_time()->flat_list_index())); @@ -573,17 +572,17 @@ EbuildFlatMetadataCache::load(const std::shared_ptr<const EbuildID> & id, const } if (! m.keywords()->name().empty()) - id->load_keywords(m.keywords()->name(), m.keywords()->description(), keys[m.keywords()->name()]); + id->load_keywords(m.keywords(), keys[m.keywords()->name()]); if (! m.inherited()->name().empty()) - id->load_inherited(m.inherited()->name(), m.inherited()->description(), join(inherited.begin(), inherited.end(), " ")); + id->load_inherited(m.inherited(), join(inherited.begin(), inherited.end(), " ")); if (! m.defined_phases()->name().empty()) if (! keys[m.defined_phases()->name()].empty()) - id->load_defined_phases(m.defined_phases()->name(), m.defined_phases()->description(), keys[m.defined_phases()->name()]); + id->load_defined_phases(m.defined_phases(), keys[m.defined_phases()->name()]); if (! m.iuse()->name().empty()) - id->load_iuse(m.iuse()->name(), m.iuse()->description(), keys[m.iuse()->name()]); + id->load_iuse(m.iuse(), keys[m.iuse()->name()]); if (! m.myoptions()->name().empty()) id->load_myoptions(m.myoptions()->name(), m.myoptions()->description(), keys[m.myoptions()->name()]); @@ -598,10 +597,10 @@ EbuildFlatMetadataCache::load(const std::shared_ptr<const EbuildID> & id, const id->load_provide(m.provide()->name(), m.provide()->description(), keys[m.provide()->name()]); if (! m.use()->name().empty()) - id->load_use(m.use()->name(), m.use()->description(), keys[m.use()->name()]); + id->load_use(m.use(), keys[m.use()->name()]); if (! m.generated_from()->name().empty()) - id->load_generated_from(m.generated_from()->name(), m.generated_from()->description(), keys[m.generated_from()->name()]); + id->load_generated_from(m.generated_from(), keys[m.generated_from()->name()]); if (! m.generated_time()->name().empty()) id->load_generated_time(m.generated_time()->name(), m.generated_time()->description(), keys[m.generated_time()->name()]); diff --git a/paludis/repositories/e/ebuild_id.cc b/paludis/repositories/e/ebuild_id.cc index 418206588..5529adcba 100644 --- a/paludis/repositories/e/ebuild_id.cc +++ b/paludis/repositories/e/ebuild_id.cc @@ -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 @@ -35,6 +35,8 @@ #include <paludis/repositories/e/do_install_action.hh> #include <paludis/repositories/e/do_info_action.hh> #include <paludis/repositories/e/do_fetch_action.hh> +#include <paludis/repositories/e/e_string_set_key.hh> +#include <paludis/repositories/e/e_keywords_key.hh> #include <paludis/name.hh> #include <paludis/version_spec.hh> @@ -143,13 +145,13 @@ namespace paludis mutable std::shared_ptr<const EFetchableURIKey> src_uri; mutable std::shared_ptr<const ESimpleURIKey> homepage; mutable std::shared_ptr<const ELicenseKey> license; - mutable std::shared_ptr<const EKeywordsKey> keywords; - mutable std::shared_ptr<const EStringSetKey> raw_iuse; + mutable std::shared_ptr<const MetadataCollectionKey<KeywordNameSet> > keywords; + mutable std::shared_ptr<const MetadataCollectionKey<Set<std::string> > > raw_iuse; mutable std::shared_ptr<const LiteralMetadataStringSetKey> raw_iuse_effective; mutable std::shared_ptr<const EMyOptionsKey> raw_myoptions; mutable std::shared_ptr<const ERequiredUseKey> required_use; - mutable std::shared_ptr<const EStringSetKey> inherited; - mutable std::shared_ptr<const EStringSetKey> raw_use; + mutable std::shared_ptr<const MetadataCollectionKey<Set<std::string> > > inherited; + mutable std::shared_ptr<const MetadataCollectionKey<Set<std::string> > > raw_use; mutable std::shared_ptr<const LiteralMetadataStringSetKey> raw_use_expand; mutable std::shared_ptr<const LiteralMetadataStringSetKey> raw_use_expand_hidden; mutable std::shared_ptr<EMutableRepositoryMaskInfoKey> repository_mask; @@ -160,8 +162,8 @@ namespace paludis mutable std::shared_ptr<const ESimpleURIKey> upstream_documentation; mutable std::shared_ptr<const ESimpleURIKey> upstream_release_notes; mutable std::shared_ptr<const EChoicesKey> choices; - mutable std::shared_ptr<const EStringSetKey> defined_phases; - mutable std::shared_ptr<const EStringSetKey> generated_from; + mutable std::shared_ptr<const MetadataCollectionKey<Set<std::string> > > defined_phases; + mutable std::shared_ptr<const MetadataCollectionKey<Set<std::string> > > generated_from; mutable std::shared_ptr<const LiteralMetadataTimeKey> generated_time; mutable std::shared_ptr<const LiteralMetadataValueKey<std::string> > generated_using; mutable std::shared_ptr<const LiteralMetadataStringSetKey> behaviours; @@ -1054,10 +1056,10 @@ EbuildID::load_provide(const std::string & r, const std::string & h, const std:: } void -EbuildID::load_iuse(const std::string & r, const std::string & h, const std::string & v) const +EbuildID::load_iuse(const std::shared_ptr<const EAPIMetadataVariable> & k, const std::string & v) const { Lock l(_imp->mutex); - _imp->raw_iuse = std::make_shared<EStringSetKey>(r, h, v, mkt_internal); + _imp->raw_iuse = EStringSetKeyStore::get_instance()->fetch(k, v, mkt_internal); add_metadata_key(_imp->raw_iuse); } @@ -1078,37 +1080,37 @@ EbuildID::load_required_use(const std::string & r, const std::string & h, const } void -EbuildID::load_use(const std::string & r, const std::string & h, const std::string & v) const +EbuildID::load_use(const std::shared_ptr<const EAPIMetadataVariable> & r, const std::string & v) const { Lock l(_imp->mutex); - _imp->raw_use = std::make_shared<EStringSetKey>(r, h, v, mkt_internal); + _imp->raw_use = EStringSetKeyStore::get_instance()->fetch(r, v, mkt_internal); add_metadata_key(_imp->raw_use); } void -EbuildID::load_keywords(const std::string & r, const std::string & h, const std::string & v) const +EbuildID::load_keywords(const std::shared_ptr<const EAPIMetadataVariable> & h, const std::string & v) const { Lock l(_imp->mutex); - _imp->keywords = std::make_shared<EKeywordsKey>(_imp->environment, shared_from_this(), r, h, v, mkt_internal); + _imp->keywords = EKeywordsKeyStore::get_instance()->fetch(h, v, mkt_internal); add_metadata_key(_imp->keywords); } void -EbuildID::load_inherited(const std::string & r, const std::string & h, const std::string & v) const +EbuildID::load_inherited(const std::shared_ptr<const EAPIMetadataVariable> & r, const std::string & v) const { Lock l(_imp->mutex); - _imp->inherited = std::make_shared<EStringSetKey>(r, h, v, mkt_internal); + _imp->inherited = EStringSetKeyStore::get_instance()->fetch(r, v, mkt_internal); add_metadata_key(_imp->inherited); } void -EbuildID::load_defined_phases(const std::string & r, const std::string & h, const std::string & v) const +EbuildID::load_defined_phases(const std::shared_ptr<const EAPIMetadataVariable> & h, const std::string & v) const { if (v.empty()) throw InternalError(PALUDIS_HERE, "v should not be empty"); Lock l(_imp->mutex); - _imp->defined_phases = std::make_shared<EStringSetKey>(r, h, v, mkt_internal); + _imp->defined_phases = EStringSetKeyStore::get_instance()->fetch(h, v, mkt_internal); add_metadata_key(_imp->defined_phases); } @@ -1161,10 +1163,10 @@ EbuildID::load_slot(const std::shared_ptr<const EAPIMetadataVariable> & m, const } void -EbuildID::load_generated_from(const std::string & r, const std::string & h, const std::string & v) const +EbuildID::load_generated_from(const std::shared_ptr<const EAPIMetadataVariable> & h, const std::string & v) const { Lock l(_imp->mutex); - _imp->generated_from = std::make_shared<EStringSetKey>(r, h, v, mkt_normal); + _imp->generated_from = EStringSetKeyStore::get_instance()->fetch(h, v, mkt_normal); add_metadata_key(_imp->generated_from); } diff --git a/paludis/repositories/e/ebuild_id.hh b/paludis/repositories/e/ebuild_id.hh index ebac1a637..8b339eb48 100644 --- a/paludis/repositories/e/ebuild_id.hh +++ b/paludis/repositories/e/ebuild_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 @@ -132,12 +132,12 @@ namespace paludis void load_homepage(const std::string &, const std::string &, const std::string &) const; void load_license(const std::shared_ptr<const EAPIMetadataVariable> &, const std::string &) const; void load_provide(const std::string &, const std::string &, const std::string &) const; - void load_iuse(const std::string &, const std::string &, const std::string &) const; + void load_iuse(const std::shared_ptr<const EAPIMetadataVariable> &, const std::string &) const; void load_myoptions(const std::string &, const std::string &, const std::string &) const; void load_required_use(const std::string &, const std::string &, const std::string &) const; - void load_use(const std::string &, const std::string &, const std::string &) const; - void load_inherited(const std::string &, const std::string &, const std::string &) const; - void load_keywords(const std::string &, const std::string &, const std::string &) const; + void load_use(const std::shared_ptr<const EAPIMetadataVariable> &, const std::string &) const; + void load_inherited(const std::shared_ptr<const EAPIMetadataVariable> &, const std::string &) const; + void load_keywords(const std::shared_ptr<const EAPIMetadataVariable> &, const std::string &) const; void load_restrict(const std::shared_ptr<const EAPIMetadataVariable> & m, const std::string & v) const; void load_properties(const std::shared_ptr<const EAPIMetadataVariable> & m, const std::string &) const; void load_long_description(const std::string &, const std::string &, const std::string &) const; @@ -146,9 +146,9 @@ namespace paludis void load_upstream_release_notes(const std::string &, const std::string &, const std::string &) const; void load_bugs_to(const std::shared_ptr<const EAPIMetadataVariable> &, const std::string &) const; void load_remote_ids(const std::shared_ptr<const EAPIMetadataVariable> &, const std::string &) const; - void load_defined_phases(const std::string &, const std::string &, const std::string &) const; + void load_defined_phases(const std::shared_ptr<const EAPIMetadataVariable> &, const std::string &) const; void load_slot(const std::shared_ptr<const EAPIMetadataVariable> &, const std::string &) const; - void load_generated_from(const std::string &, const std::string &, const std::string &) const; + void load_generated_from(const std::shared_ptr<const EAPIMetadataVariable> &, const std::string &) const; void load_generated_using(const std::string &, const std::string &, const std::string &) const; void load_generated_time(const std::string &, const std::string &, const std::string &) const; |