aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2011-01-31 16:17:41 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2011-01-31 16:17:41 +0000
commit8cd3f89f1e7817fafca33e410b24af18fc333874 (patch)
tree1f991906a1512f4b8f508db07834575671fde660
parent6eeca897e480fbb24cc5bfd6df6cf97fc5d82594 (diff)
downloadpaludis-8cd3f89f1e7817fafca33e410b24af18fc333874.tar.gz
paludis-8cd3f89f1e7817fafca33e410b24af18fc333874.tar.xz
Reuse common choice values
-rw-r--r--paludis/repositories/e/e_choice_value.cc107
-rw-r--r--paludis/repositories/e/e_choice_value.hh27
-rw-r--r--paludis/repositories/e/e_choices_key.cc2
-rw-r--r--paludis/repositories/e/e_installed_repository_id.cc4
-rw-r--r--paludis/repositories/e/e_installed_repository_id.hh2
-rw-r--r--paludis/repositories/e/e_repository_id.hh4
-rw-r--r--paludis/repositories/e/ebuild_id.cc4
-rw-r--r--paludis/repositories/e/ebuild_id.hh2
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 2251efa..a89866f 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 5f65656..829cb3c 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 89635a4..b4d55ef 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 c33464f..d2e7bb6 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 7d4765f..954187d 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 6fd3f8c..27129f4 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 83519d4..c34d07f 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 ab9c734..21af840 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;