aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2011-03-18 20:04:06 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2011-03-18 20:04:06 +0000
commit874d242a793bc8bfabd52977dea1a5d994ccab09 (patch)
tree6ce7b1744f8e125780e7a17657bd9e1befcca23a
parentd689a43ea041769c1a8d8c6e7dde46bdf7250752 (diff)
downloadpaludis-874d242a793bc8bfabd52977dea1a5d994ccab09.tar.gz
paludis-874d242a793bc8bfabd52977dea1a5d994ccab09.tar.xz
Split out
-rw-r--r--paludis/repositories/e/Makefile.am2
-rw-r--r--paludis/repositories/e/e_repository.cc87
-rw-r--r--paludis/repositories/e/eapi-fwd.hh6
-rw-r--r--paludis/repositories/e/profile_file.cc27
-rw-r--r--paludis/repositories/e/profile_file.hh5
-rw-r--r--paludis/repositories/e/repository_mask_store.cc135
-rw-r--r--paludis/repositories/e/repository_mask_store.hh65
7 files changed, 256 insertions, 71 deletions
diff --git a/paludis/repositories/e/Makefile.am b/paludis/repositories/e/Makefile.am
index 88d7c19..904ec0e 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 fc839db..dfbc771 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 299cef6..176afa8 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 3b4ed61..8de4cd0 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 a55b126..3975e2f 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 0000000..c5225e6
--- /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 0000000..424723c
--- /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