diff options
author | 2011-03-18 20:04:06 +0000 | |
---|---|---|
committer | 2011-03-18 20:04:06 +0000 | |
commit | 874d242a793bc8bfabd52977dea1a5d994ccab09 (patch) | |
tree | 6ce7b1744f8e125780e7a17657bd9e1befcca23a | |
parent | d689a43ea041769c1a8d8c6e7dde46bdf7250752 (diff) | |
download | paludis-874d242a793bc8bfabd52977dea1a5d994ccab09.tar.gz paludis-874d242a793bc8bfabd52977dea1a5d994ccab09.tar.xz |
Split out
-rw-r--r-- | paludis/repositories/e/Makefile.am | 2 | ||||
-rw-r--r-- | paludis/repositories/e/e_repository.cc | 87 | ||||
-rw-r--r-- | paludis/repositories/e/eapi-fwd.hh | 6 | ||||
-rw-r--r-- | paludis/repositories/e/profile_file.cc | 27 | ||||
-rw-r--r-- | paludis/repositories/e/profile_file.hh | 5 | ||||
-rw-r--r-- | paludis/repositories/e/repository_mask_store.cc | 135 | ||||
-rw-r--r-- | paludis/repositories/e/repository_mask_store.hh | 65 |
7 files changed, 256 insertions, 71 deletions
diff --git a/paludis/repositories/e/Makefile.am b/paludis/repositories/e/Makefile.am index 88d7c198f..904ec0e61 100644 --- a/paludis/repositories/e/Makefile.am +++ b/paludis/repositories/e/Makefile.am @@ -86,6 +86,7 @@ noinst_HEADERS = \ pipe_command_handler.hh \ profile.hh \ profile_file.hh \ + repository_mask_store.hh \ required_use_verifier.hh \ source_uri_finder.hh \ spec_tree_pretty_printer.hh \ @@ -162,6 +163,7 @@ libpaludiserepository_la_SOURCES = \ profile.cc \ profile_file.cc \ registration.cc \ + repository_mask_store.cc \ required_use_verifier.cc \ source_uri_finder.cc \ spec_tree_pretty_printer.cc \ diff --git a/paludis/repositories/e/e_repository.cc b/paludis/repositories/e/e_repository.cc index fc839dbd3..dfbc771bd 100644 --- a/paludis/repositories/e/e_repository.cc +++ b/paludis/repositories/e/e_repository.cc @@ -43,6 +43,7 @@ #include <paludis/repositories/e/check_userpriv.hh> #include <paludis/repositories/e/make_use.hh> #include <paludis/repositories/e/a_finder.hh> +#include <paludis/repositories/e/repository_mask_store.hh> #include <paludis/about.hh> #include <paludis/action.hh> @@ -62,9 +63,11 @@ #include <paludis/syncer.hh> #include <paludis/util/accept_visitor.hh> +#include <paludis/util/active_object_ptr.hh> #include <paludis/util/cookie.hh> #include <paludis/util/config_file.hh> #include <paludis/util/create_iterator-impl.hh> +#include <paludis/util/deferred_construction_ptr.hh> #include <paludis/util/destringify.hh> #include <paludis/util/extract_host_from_url.hh> #include <paludis/util/fs_stat.hh> @@ -127,9 +130,6 @@ using namespace paludis; using namespace paludis::erepository; -typedef std::unordered_map<QualifiedPackageName, - std::list<std::pair<std::shared_ptr<const PackageDepSpec>, std::shared_ptr<const MaskInfo> > >, - Hash<QualifiedPackageName> > RepositoryMaskMap; typedef std::unordered_map<std::string, std::shared_ptr<MirrorsSequence> > MirrorMap; typedef std::unordered_map<QualifiedPackageName, std::shared_ptr<const PackageDepSpec>, Hash<QualifiedPackageName> > VirtualsMap; @@ -182,6 +182,21 @@ namespace tokenise_whitespace(s, result->inserter()); return result; } + + std::shared_ptr<RepositoryMaskStore> make_mask_store( + const Environment * const env, + const RepositoryName & repo_name, + const FetchRepositoryMaskFilesFunction & f, + const EAPIForFileFunction & e) + { + return std::make_shared<RepositoryMaskStore>(env, repo_name, f, e); + } + + std::shared_ptr<const FSPathSequence> fetch_repository_mask_files( + const std::shared_ptr<const Layout> & layout) + { + return layout->repository_mask_files(); + } } namespace paludis @@ -196,7 +211,6 @@ namespace paludis { struct Mutexes { - Mutex repo_mask_mutex; Mutex arch_flags_mutex; Mutex mirrors_mutex; Mutex use_desc_mutex; @@ -212,9 +226,6 @@ namespace paludis std::shared_ptr<RepositoryNameCache> names_cache; - mutable RepositoryMaskMap repo_mask; - mutable bool has_repo_mask; - const std::map<QualifiedPackageName, QualifiedPackageName> provide_map; mutable std::shared_ptr<Set<UnprefixedChoiceName> > arch_flags; @@ -231,6 +242,8 @@ namespace paludis mutable std::shared_ptr<ERepositorySets> sets_ptr; const std::shared_ptr<Layout> layout; + ActiveObjectPtr<DeferredConstructionPtr<std::shared_ptr<RepositoryMaskStore> > > repository_mask_store; + mutable EAPIForFileMap eapi_for_file_map; Imp(ERepository * const, const ERepositoryParams &, std::shared_ptr<Mutexes> = std::make_shared<Mutexes>()); @@ -284,11 +297,14 @@ namespace paludis params(p), mutexes(m), names_cache(std::make_shared<RepositoryNameCache>(p.names_cache(), r)), - has_repo_mask(false), has_mirrors(false), sets_ptr(std::make_shared<ERepositorySets>(params.environment(), r, p)), layout(LayoutFactory::get_instance()->create(params.layout(), r, params.location(), get_master_locations( params.master_repositories()))), + repository_mask_store(DeferredConstructionPtr<std::shared_ptr<RepositoryMaskStore> > ( + std::bind(&make_mask_store, params.environment(), r->name(), + FetchRepositoryMaskFilesFunction(std::bind(fetch_repository_mask_files, layout)), + EAPIForFileFunction(std::bind(std::mem_fn(&ERepository::eapi_for_file), r, std::placeholders::_1))))), format_key(std::make_shared<LiteralMetadataValueKey<std::string> >("format", "format", mkt_significant, params.entry_format())), layout_key(std::make_shared<LiteralMetadataValueKey<std::string> >("layout", "layout", @@ -618,60 +634,7 @@ ERepository::package_ids(const QualifiedPackageName & n, const RepositoryContent std::shared_ptr<const MaskInfo> ERepository::repository_masked(const std::shared_ptr<const PackageID> & id) const { - Lock l(_imp->mutexes->repo_mask_mutex); - - if (! _imp->has_repo_mask) - { - Context context("When querying repository mask for '" + stringify(*id) + "':"); - - using namespace std::placeholders; - - std::shared_ptr<const FSPathSequence> repository_mask_files(_imp->layout->repository_mask_files()); - ProfileFile<MaskFile> repository_mask_file(this); - std::for_each(repository_mask_files->begin(), repository_mask_files->end(), - std::bind(&ProfileFile<MaskFile>::add_file, std::ref(repository_mask_file), _1)); - - for (ProfileFile<MaskFile>::ConstIterator - line(repository_mask_file.begin()), line_end(repository_mask_file.end()) ; - line != line_end ; ++line) - { - try - { - std::shared_ptr<const PackageDepSpec> a(std::make_shared<PackageDepSpec>(parse_elike_package_dep_spec( - line->second.first, line->first->supported()->package_dep_spec_parse_options(), - line->first->supported()->version_spec_options()))); - if (a->package_ptr()) - _imp->repo_mask[*a->package_ptr()].push_back(std::make_pair(a, line->second.second)); - else - Log::get_instance()->message("e.package_mask.bad_spec", ll_warning, lc_context) - << "Loading package mask spec '" << line->second.first << "' failed because specification does not restrict to a " - "unique package"; - } - catch (const InternalError &) - { - throw; - } - catch (const Exception & e) - { - Log::get_instance()->message("e.package_mask.bad_spec", ll_warning, lc_context) << "Loading package mask spec '" - << line->second.first << "' failed due to exception '" << e.message() << "' (" - << e.what() << ")"; - } - } - - _imp->has_repo_mask = true; - } - - RepositoryMaskMap::iterator r(_imp->repo_mask.find(id->name())); - if (_imp->repo_mask.end() == r) - return std::shared_ptr<const MaskInfo>(); - else - for (std::list<std::pair<std::shared_ptr<const PackageDepSpec>, std::shared_ptr<const MaskInfo> > >::const_iterator - k(r->second.begin()), k_end(r->second.end()) ; k != k_end ; ++k) - if (match_package(*_imp->params.environment(), *k->first, id, make_null_shared_ptr(), { })) - return k->second; - - return std::shared_ptr<const MaskInfo>(); + return _imp->repository_mask_store->query(id); } const std::shared_ptr<const Set<UnprefixedChoiceName> > diff --git a/paludis/repositories/e/eapi-fwd.hh b/paludis/repositories/e/eapi-fwd.hh index 299cef638..176afa85c 100644 --- a/paludis/repositories/e/eapi-fwd.hh +++ b/paludis/repositories/e/eapi-fwd.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 @@ -21,6 +21,7 @@ #define PALUDIS_GUARD_PALUDIS_EAPI_FWD_HH 1 #include <paludis/repositories/e/dep_parser-fwd.hh> +#include <paludis/util/fs_path-fwd.hh> #include <paludis/fs_merger-fwd.hh> #include <paludis/name-fwd.hh> #include <paludis/elike_package_dep_spec-fwd.hh> @@ -45,6 +46,9 @@ namespace paludis class EAPI; class EAPIMetadataVariable; + + typedef std::function<const std::string (const FSPath &)> EAPIForFileFunction; + } } diff --git a/paludis/repositories/e/profile_file.cc b/paludis/repositories/e/profile_file.cc index 3b4ed613b..8de4cd0ac 100644 --- a/paludis/repositories/e/profile_file.cc +++ b/paludis/repositories/e/profile_file.cc @@ -84,7 +84,7 @@ namespace paludis template <typename F_> struct Imp<ProfileFile<F_> > { - const ERepository * const repository; + const EAPIForFileFunction eapi_for_file; typedef std::list<std::pair<std::shared_ptr<const EAPI>, const typename std::remove_reference<typename F_::ConstIterator::value_type>::type> > Lines; @@ -92,8 +92,8 @@ namespace paludis std::set<std::string> removed; - Imp(const ERepository * const r) : - repository(r) + Imp(const EAPIForFileFunction & e) : + eapi_for_file(e) { } }; @@ -140,8 +140,7 @@ ProfileFile<F_>::add_file(const FSPath & f) if (! f.stat().exists()) return; - const std::shared_ptr<const EAPI> eapi(EAPIData::get_instance()->eapi_from_string( - this->_imp->repository->eapi_for_file(f))); + const std::shared_ptr<const EAPI> eapi(EAPIData::get_instance()->eapi_from_string(_imp->eapi_for_file(f))); if (! eapi->supported()) throw ERepositoryConfigurationError("Can't use profile file '" + stringify(f) + "' because it uses an unsupported EAPI"); @@ -181,9 +180,23 @@ ProfileFile<F_>::add_file(const FSPath & f) } } +namespace +{ + const std::string eapi_for_file(const ERepository * const repo, const FSPath & path) + { + return repo->eapi_for_file(path); + } +} + +template <typename F_> +ProfileFile<F_>::ProfileFile(const ERepository * const repo) : + _imp(std::bind(eapi_for_file, repo, std::placeholders::_1)) +{ +} + template <typename F_> -ProfileFile<F_>::ProfileFile(const ERepository * const r) : - _imp(r) +ProfileFile<F_>::ProfileFile(const EAPIForFileFunction & f) : + _imp(f) { } diff --git a/paludis/repositories/e/profile_file.hh b/paludis/repositories/e/profile_file.hh index a55b1264e..3975e2f14 100644 --- a/paludis/repositories/e/profile_file.hh +++ b/paludis/repositories/e/profile_file.hh @@ -27,6 +27,7 @@ #include <paludis/util/wrapped_forward_iterator-fwd.hh> #include <paludis/mask-fwd.hh> #include <type_traits> +#include <functional> namespace paludis { @@ -44,7 +45,9 @@ namespace paludis ///\name Basic operations ///\{ - ProfileFile(const ERepository * const); + explicit ProfileFile(const EAPIForFileFunction &); + explicit ProfileFile(const ERepository * const); + ~ProfileFile(); ///\} diff --git a/paludis/repositories/e/repository_mask_store.cc b/paludis/repositories/e/repository_mask_store.cc new file mode 100644 index 000000000..c5225e61e --- /dev/null +++ b/paludis/repositories/e/repository_mask_store.cc @@ -0,0 +1,135 @@ +/* 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/repository_mask_store.hh> +#include <paludis/repositories/e/profile_file.hh> +#include <paludis/repositories/e/e_repository_mask_file.hh> +#include <paludis/repositories/e/eapi.hh> +#include <paludis/util/pimp-impl.hh> +#include <paludis/util/exception.hh> +#include <paludis/util/hashes.hh> +#include <paludis/util/stringify.hh> +#include <paludis/util/log.hh> +#include <paludis/util/make_null_shared_ptr.hh> +#include <paludis/dep_spec.hh> +#include <paludis/package_id.hh> +#include <paludis/match_package.hh> + +#include <algorithm> +#include <unordered_map> +#include <list> + +using namespace paludis; +using namespace paludis::erepository; + +typedef std::unordered_map<QualifiedPackageName, + std::list<std::pair<PackageDepSpec, std::shared_ptr<const MaskInfo> > >, + Hash<QualifiedPackageName> > RepositoryMaskMap; + +namespace paludis +{ + template <> + struct Imp<RepositoryMaskStore> + { + const Environment * const env; + RepositoryName repo_name; + FetchRepositoryMaskFilesFunction fetch_repository_mask_files; + EAPIForFileFunction eapi_for_file; + + RepositoryMaskMap repo_mask; + + Imp(const Environment * const e, const RepositoryName & r, const FetchRepositoryMaskFilesFunction & f, const EAPIForFileFunction & n) : + env(e), + repo_name(r), + fetch_repository_mask_files(f), + eapi_for_file(n) + { + } + }; +} + +RepositoryMaskStore::RepositoryMaskStore( + const Environment * const e, + const RepositoryName & r, + const FetchRepositoryMaskFilesFunction & f, + const EAPIForFileFunction & n) : + _imp(e, r, f, n) +{ + _populate(); +} + +RepositoryMaskStore::~RepositoryMaskStore() +{ +} + +void +RepositoryMaskStore::_populate() +{ + Context context("When loading repository masks for '" + stringify(_imp->repo_name) + "':"); + + using namespace std::placeholders; + + auto repository_mask_files(_imp->fetch_repository_mask_files()); + ProfileFile<MaskFile> repository_mask_file(_imp->eapi_for_file); + std::for_each(repository_mask_files->begin(), repository_mask_files->end(), + std::bind(&ProfileFile<MaskFile>::add_file, std::ref(repository_mask_file), _1)); + + for (ProfileFile<MaskFile>::ConstIterator + line(repository_mask_file.begin()), line_end(repository_mask_file.end()) ; + line != line_end ; ++line) + { + try + { + auto a(parse_elike_package_dep_spec( + line->second.first, line->first->supported()->package_dep_spec_parse_options(), + line->first->supported()->version_spec_options())); + if (a.package_ptr()) + _imp->repo_mask[*a.package_ptr()].push_back(std::make_pair(a, line->second.second)); + else + Log::get_instance()->message("e.package_mask.bad_spec", ll_warning, lc_context) + << "Loading package mask spec '" << line->second.first << "' failed because specification does not restrict to a " + "unique package"; + } + catch (const InternalError &) + { + throw; + } + catch (const Exception & e) + { + Log::get_instance()->message("e.package_mask.bad_spec", ll_warning, lc_context) << "Loading package mask spec '" + << line->second.first << "' failed due to exception '" << e.message() << "' (" + << e.what() << ")"; + } + } +} + +const std::shared_ptr<const MaskInfo> +RepositoryMaskStore::query(const std::shared_ptr<const PackageID> & id) const +{ + auto r(_imp->repo_mask.find(id->name())); + if (_imp->repo_mask.end() == r) + return std::shared_ptr<const MaskInfo>(); + else + for (auto k(r->second.begin()), k_end(r->second.end()) ; k != k_end ; ++k) + if (match_package(*_imp->env, k->first, id, make_null_shared_ptr(), { })) + return k->second; + + return std::shared_ptr<const MaskInfo>(); +} + diff --git a/paludis/repositories/e/repository_mask_store.hh b/paludis/repositories/e/repository_mask_store.hh new file mode 100644 index 000000000..424723cd7 --- /dev/null +++ b/paludis/repositories/e/repository_mask_store.hh @@ -0,0 +1,65 @@ +/* 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_REPOSITORY_MASK_STORE_HH +#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_E_REPOSITORY_MASK_STORE_HH 1 + +#include <paludis/repositories/e/mask_info.hh> +#include <paludis/repositories/e/eapi-fwd.hh> +#include <paludis/util/pimp.hh> +#include <paludis/util/attributes.hh> +#include <paludis/util/fs_path-fwd.hh> +#include <paludis/util/sequence-fwd.hh> +#include <paludis/environment-fwd.hh> +#include <paludis/repository-fwd.hh> +#include <paludis/name-fwd.hh> +#include <paludis/package_id-fwd.hh> + +#include <memory> +#include <functional> + +namespace paludis +{ + namespace erepository + { + typedef std::function<const std::shared_ptr<const FSPathSequence> & ()> FetchRepositoryMaskFilesFunction; + + class PALUDIS_VISIBLE RepositoryMaskStore + { + private: + Pimp<RepositoryMaskStore> _imp; + + void _populate(); + + public: + RepositoryMaskStore( + const Environment * const, + const RepositoryName &, + const FetchRepositoryMaskFilesFunction &, + const EAPIForFileFunction &); + + ~RepositoryMaskStore(); + + const std::shared_ptr<const MaskInfo> query(const std::shared_ptr<const PackageID> & id) const; + }; + } + +} + +#endif |