diff options
author | 2011-01-02 02:19:01 +0000 | |
---|---|---|
committer | 2011-01-07 11:32:55 +0000 | |
commit | 20cc98f89f0208619fa8845d784463f03a7c9234 (patch) | |
tree | 11872e31117810463923d4fccb0a955e061e9262 /paludis/repositories/e/e_string_set_key.cc | |
parent | d02f6611a083735106d0f56d6d49f3a4743a5d07 (diff) | |
download | paludis-20cc98f89f0208619fa8845d784463f03a7c9234.tar.gz paludis-20cc98f89f0208619fa8845d784463f03a7c9234.tar.xz |
Share more common metadata
Diffstat (limited to 'paludis/repositories/e/e_string_set_key.cc')
-rw-r--r-- | paludis/repositories/e/e_string_set_key.cc | 162 |
1 files changed, 162 insertions, 0 deletions
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; +} + |