aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-12-05 23:07:10 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-12-06 16:59:35 +0000
commit4e9142925c02ccbe933804542f84f8b8a3f028e1 (patch)
tree30bfa6223a10047dd4f727a232e28ffb88d7c75a
parent956ad7409b5099e5a40443b98a3eca16e599549a (diff)
downloadpaludis-4e9142925c02ccbe933804542f84f8b8a3f028e1.tar.gz
paludis-4e9142925c02ccbe933804542f84f8b8a3f028e1.tar.xz
Avoid recalculating selections
-rw-r--r--paludis/environment.hh21
-rw-r--r--paludis/environment_implementation.cc20
-rw-r--r--paludis/environment_implementation.hh6
-rw-r--r--paludis/files.m41
-rw-r--r--paludis/selection_cache-fwd.hh29
-rw-r--r--paludis/selection_cache.cc99
-rw-r--r--paludis/selection_cache.hh58
-rw-r--r--src/clients/cave/cmd_resolve.cc3
8 files changed, 236 insertions, 1 deletions
diff --git a/paludis/environment.hh b/paludis/environment.hh
index cf9465d..2f17a9b 100644
--- a/paludis/environment.hh
+++ b/paludis/environment.hh
@@ -37,6 +37,7 @@
#include <paludis/mask-fwd.hh>
#include <paludis/package_database-fwd.hh>
#include <paludis/selection-fwd.hh>
+#include <paludis/selection_cache-fwd.hh>
#include <paludis/metadata_key_holder.hh>
#include <paludis/choice-fwd.hh>
#include <paludis/create_output_manager_info-fwd.hh>
@@ -223,6 +224,26 @@ namespace paludis
virtual std::tr1::shared_ptr<PackageIDSequence> operator[] (const Selection &) const
PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
+ /**
+ * Add a selection cache.
+ *
+ * Probably only to be used by ScopedSelectionCache.
+ *
+ * \since 0.42
+ */
+ virtual void add_selection_cache(
+ const std::tr1::shared_ptr<const SelectionCache> &) = 0;
+
+ /**
+ * Remove a selection cache registered using add_selection_cache.
+ *
+ * Probably only to be used by ScopedSelectionCache.
+ *
+ * \since 0.42
+ */
+ virtual void remove_selection_cache(
+ const std::tr1::shared_ptr<const SelectionCache> &) = 0;
+
///\}
///\name System information
diff --git a/paludis/environment_implementation.cc b/paludis/environment_implementation.cc
index 2393736..7fdb086 100644
--- a/paludis/environment_implementation.cc
+++ b/paludis/environment_implementation.cc
@@ -36,8 +36,10 @@
#include <paludis/hook.hh>
#include <paludis/distribution.hh>
#include <paludis/selection.hh>
+#include <paludis/selection_cache.hh>
#include <algorithm>
#include <map>
+#include <list>
#include "config.h"
using namespace paludis;
@@ -108,6 +110,7 @@ namespace paludis
struct Implementation<EnvironmentImplementation>
{
std::map<unsigned, NotifierCallbackFunction> notifier_callbacks;
+ std::list<std::tr1::shared_ptr<const SelectionCache> > selection_caches;
mutable Mutex sets_mutex;
mutable bool loaded_sets;
@@ -193,7 +196,10 @@ EnvironmentImplementation::is_paludis_package(const QualifiedPackageName & n) co
std::tr1::shared_ptr<PackageIDSequence>
EnvironmentImplementation::operator[] (const Selection & selection) const
{
- return selection.perform_select(this);
+ if (_imp->selection_caches.empty())
+ return selection.perform_select(this);
+ else
+ return _imp->selection_caches.back()->perform_select(this, selection);
}
NotifierCallbackID
@@ -223,6 +229,18 @@ EnvironmentImplementation::trigger_notifier_callback(const NotifierCallbackEvent
}
void
+EnvironmentImplementation::add_selection_cache(const std::tr1::shared_ptr<const SelectionCache> & c)
+{
+ _imp->selection_caches.push_back(c);
+}
+
+void
+EnvironmentImplementation::remove_selection_cache(const std::tr1::shared_ptr<const SelectionCache> & c)
+{
+ _imp->selection_caches.remove(c);
+}
+
+void
EnvironmentImplementation::add_set(
const SetName & name,
const SetName & combined_name,
diff --git a/paludis/environment_implementation.hh b/paludis/environment_implementation.hh
index 94b54d5..50e722c 100644
--- a/paludis/environment_implementation.hh
+++ b/paludis/environment_implementation.hh
@@ -108,6 +108,12 @@ namespace paludis
virtual const std::tr1::shared_ptr<const SetSpecTree> set(const SetName &) const
PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ virtual void add_selection_cache(
+ const std::tr1::shared_ptr<const SelectionCache> &);
+
+ virtual void remove_selection_cache(
+ const std::tr1::shared_ptr<const SelectionCache> &);
};
class PALUDIS_VISIBLE DuplicateSetError :
diff --git a/paludis/files.m4 b/paludis/files.m4
index 91c4830..c1f9ed3 100644
--- a/paludis/files.m4
+++ b/paludis/files.m4
@@ -74,6 +74,7 @@ add(`repository', `hh', `fwd', `cc')
add(`repository_factory', `hh', `fwd', `cc')
add(`repository_name_cache', `hh', `cc', `test', `testscript')
add(`selection', `hh', `cc', `fwd', `test')
+add(`selection_cache', `hh', `cc', `fwd')
add(`selection_handler', `hh', `cc', `fwd')
add(`serialise', `hh', `cc', `fwd', `impl')
add(`set_file', `hh', `cc', `se', `test', `testscript')
diff --git a/paludis/selection_cache-fwd.hh b/paludis/selection_cache-fwd.hh
new file mode 100644
index 0000000..d65971e
--- /dev/null
+++ b/paludis/selection_cache-fwd.hh
@@ -0,0 +1,29 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 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_SELECTION_CACHE_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_SELECTION_CACHE_FWD_HH 1
+
+namespace paludis
+{
+ struct SelectionCache;
+ struct ScopedSelectionCache;
+}
+
+#endif
diff --git a/paludis/selection_cache.cc b/paludis/selection_cache.cc
new file mode 100644
index 0000000..73d40c8
--- /dev/null
+++ b/paludis/selection_cache.cc
@@ -0,0 +1,99 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 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/selection_cache.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/mutex.hh>
+#include <paludis/util/sequence.hh>
+#include <paludis/util/wrapped_forward_iterator.hh>
+#include <paludis/util/wrapped_output_iterator.hh>
+#include <paludis/environment.hh>
+#include <paludis/selection.hh>
+#include <tr1/unordered_map>
+#include <algorithm>
+
+using namespace paludis;
+
+typedef std::tr1::unordered_map<std::string, std::tr1::shared_ptr<const PackageIDSequence> > Cache;
+
+namespace paludis
+{
+ template <>
+ struct Implementation<SelectionCache>
+ {
+ mutable Mutex mutex;
+ mutable Cache cache;
+ };
+
+ template <>
+ struct Implementation<ScopedSelectionCache>
+ {
+ Environment * const environment;
+ const std::tr1::shared_ptr<SelectionCache> selection_cache;
+
+ Implementation(Environment * const e) :
+ environment(e),
+ selection_cache(new SelectionCache)
+ {
+ }
+ };
+}
+
+SelectionCache::SelectionCache() :
+ PrivateImplementationPattern<SelectionCache>(new Implementation<SelectionCache>)
+{
+}
+
+SelectionCache::~SelectionCache()
+{
+}
+
+const std::tr1::shared_ptr<PackageIDSequence>
+SelectionCache::perform_select(const Environment * const env, const Selection & s) const
+{
+ std::string ss(s.as_string());
+ Cache::const_iterator i(_imp->cache.end());
+
+ {
+ Lock lock(_imp->mutex);
+ i = _imp->cache.find(ss);
+
+ if (_imp->cache.end() == i)
+ i = _imp->cache.insert(std::make_pair(ss, s.perform_select(env))).first;
+ }
+
+ std::tr1::shared_ptr<PackageIDSequence> result(new PackageIDSequence);
+ std::copy(i->second->begin(), i->second->end(), result->back_inserter());
+ return result;
+}
+
+ScopedSelectionCache::ScopedSelectionCache(Environment * const e) :
+ PrivateImplementationPattern<ScopedSelectionCache>(new Implementation<ScopedSelectionCache>(e))
+{
+ _imp->environment->add_selection_cache(_imp->selection_cache);
+}
+
+ScopedSelectionCache::~ScopedSelectionCache()
+{
+ _imp->environment->remove_selection_cache(_imp->selection_cache);
+}
+
+template class PrivateImplementationPattern<SelectionCache>;
+template class PrivateImplementationPattern<ScopedSelectionCache>;
+
diff --git a/paludis/selection_cache.hh b/paludis/selection_cache.hh
new file mode 100644
index 0000000..a4db1b4
--- /dev/null
+++ b/paludis/selection_cache.hh
@@ -0,0 +1,58 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 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_SELECTION_CACHE_HH
+#define PALUDIS_GUARD_PALUDIS_SELECTION_CACHE_HH 1
+
+#include <paludis/selection_cache-fwd.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/environment-fwd.hh>
+#include <paludis/selection-fwd.hh>
+#include <paludis/package_id-fwd.hh>
+#include <tr1/memory>
+
+namespace paludis
+{
+ class PALUDIS_VISIBLE SelectionCache :
+ private PrivateImplementationPattern<SelectionCache>
+ {
+ public:
+ SelectionCache();
+ ~SelectionCache();
+
+ const std::tr1::shared_ptr<PackageIDSequence> perform_select(
+ const Environment * const,
+ const Selection &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ class PALUDIS_VISIBLE ScopedSelectionCache :
+ private PrivateImplementationPattern<ScopedSelectionCache>
+ {
+ public:
+ ScopedSelectionCache(Environment * const);
+ ~ScopedSelectionCache();
+ };
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class PrivateImplementationPattern<SelectionCache>;
+ extern template class PrivateImplementationPattern<ScopedSelectionCache>;
+#endif
+}
+
+#endif
diff --git a/src/clients/cave/cmd_resolve.cc b/src/clients/cave/cmd_resolve.cc
index 79e59bd..885a53a 100644
--- a/src/clients/cave/cmd_resolve.cc
+++ b/src/clients/cave/cmd_resolve.cc
@@ -58,6 +58,7 @@
#include <paludis/match_package.hh>
#include <paludis/package_database.hh>
#include <paludis/serialise-impl.hh>
+#include <paludis/selection_cache.hh>
#include <algorithm>
#include <iostream>
@@ -1129,6 +1130,8 @@ ResolveCommand::run(
std::tr1::cref(cmdline), std::tr1::placeholders::_1, std::tr1::placeholders::_2, std::tr1::placeholders::_3))
));
+
+ ScopedSelectionCache selection_cache(env.get());
std::tr1::shared_ptr<Resolver> resolver(new Resolver(env.get(), resolver_functions));
bool is_set(false);
std::list<SuggestRestart> restarts;