diff options
20 files changed, 110 insertions, 222 deletions
diff --git a/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp b/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp index ebd51c82794..9c9c10c1a79 100644 --- a/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp @@ -37,19 +37,26 @@ const MapDataType *verifyMapType(const DataType& type) { struct Hasher { Hasher(const MapFieldValue::IArray * keys) : _keys(keys) {} - uint32_t operator () (uint32_t index) const { return (*_keys)[index].hash(); } - const MapFieldValue::IArray * _keys; -}; - -struct Extract { - Extract(const MapFieldValue::IArray * keys) : _keys(keys) {} - const FieldValue & operator () (uint32_t index) const { return (*_keys)[index]; } + uint32_t operator () (uint32_t index) const { + return (*_keys)[index].hash(); + } + uint32_t operator () (const FieldValue & fv) const { + return fv.hash(); + } const MapFieldValue::IArray * _keys; }; struct Equal { Equal(const MapFieldValue::IArray * keys) : _keys(keys) {} - bool operator () (uint32_t a, uint32_t b) const { return (*_keys)[a].fastCompare((*_keys)[b]) == 0; } + bool operator () (uint32_t a, uint32_t b) const { + return (*_keys)[a].fastCompare((*_keys)[b]) == 0; + } + bool operator () (const FieldValue & a, uint32_t b) const { + return a.fastCompare((*_keys)[b]) == 0; + } + bool operator () (uint32_t a, const FieldValue & b) const { + return (*_keys)[a].fastCompare(b) == 0; + } const MapFieldValue::IArray * _keys; }; @@ -387,8 +394,7 @@ MapFieldValue::findIndex(const FieldValue& key) const { if ((size() > 0) && (key.getClass().id() == (*_keys)[0].getClass().id())) { ensureLookupMap(); - Extract extract(_keys.get()); - auto found = _lookupMap->find<FieldValue, Extract, vespalib::hash<FieldValue>, std::equal_to<FieldValue>>(key, extract); + auto found = _lookupMap->find(key); if (found != _lookupMap->end()) { uint32_t index = *found; assert(_present[index]); diff --git a/juniper/src/vespa/juniper/stringmap.cpp b/juniper/src/vespa/juniper/stringmap.cpp index a65350432fd..f673f22e29c 100644 --- a/juniper/src/vespa/juniper/stringmap.cpp +++ b/juniper/src/vespa/juniper/stringmap.cpp @@ -10,7 +10,7 @@ void Fast_StringMap::Insert(const char* key, const char* value) const char * -Fast_StringMap::Lookup(const char *key, const char *defval) +Fast_StringMap::Lookup(const char *key, const char *defval) const { Map::const_iterator found(_backing.find(key)); return (found != _backing.end()) ? found->second.c_str() : defval; diff --git a/juniper/src/vespa/juniper/stringmap.h b/juniper/src/vespa/juniper/stringmap.h index c202ecb5888..068eeaf3d16 100644 --- a/juniper/src/vespa/juniper/stringmap.h +++ b/juniper/src/vespa/juniper/stringmap.h @@ -10,10 +10,10 @@ class Fast_StringMap { private: - typedef vespalib::hash_map<vespalib::string, vespalib::string> Map; + using Map = vespalib::hash_map<vespalib::string, vespalib::string>; Map _backing; public: void Insert(const char* key, const char* value); - const char *Lookup(const char* key, const char* defval); + const char *Lookup(const char* key, const char* defval) const; }; diff --git a/metrics/src/vespa/metrics/CMakeLists.txt b/metrics/src/vespa/metrics/CMakeLists.txt index 147e88cd61c..96156dc84b0 100644 --- a/metrics/src/vespa/metrics/CMakeLists.txt +++ b/metrics/src/vespa/metrics/CMakeLists.txt @@ -12,7 +12,6 @@ vespa_add_library(metrics metricsnapshot.cpp metrictimer.cpp metricvalueset.cpp - namehash.cpp printutils.cpp name_repo.cpp state_api_adapter.cpp diff --git a/metrics/src/vespa/metrics/memoryconsumption.cpp b/metrics/src/vespa/metrics/memoryconsumption.cpp index 5a3280c20ab..0391e496ecd 100644 --- a/metrics/src/vespa/metrics/memoryconsumption.cpp +++ b/metrics/src/vespa/metrics/memoryconsumption.cpp @@ -1,12 +1,11 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "memoryconsumption.h" -#include <vespa/vespalib/stllike/hash_set.h> -#include <vespa/vespalib/stllike/hashtable.hpp> +#include <vespa/vespalib/stllike/hash_set.hpp> #include <sstream> namespace metrics { -struct SeenStrings : public vespalib::hash_set<const void*> { }; +struct SeenStrings : public vespalib::hash_set<const char*> { }; struct SnapShotUsage : public std::vector<std::pair<std::string, uint32_t> > { }; MemoryConsumption::MemoryConsumption() diff --git a/metrics/src/vespa/metrics/namehash.cpp b/metrics/src/vespa/metrics/namehash.cpp deleted file mode 100644 index bd0b3a05697..00000000000 --- a/metrics/src/vespa/metrics/namehash.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "namehash.h" -#include "memoryconsumption.h" -#include <vespa/vespalib/stllike/hash_set.h> - -namespace metrics { - -struct NameSet : public vespalib::hash_set<std::string> { }; - -NameHash::NameHash() - : _hash(std::make_unique<NameSet>()), - _unifiedCounter(0), - _checkedCounter(0) -{ } - -NameHash::~NameHash() { } - -void -NameHash::updateName(std::string& name) { - ++_checkedCounter; - NameSet::const_iterator it(_hash->find(name)); - if (it != _hash->end()) { - if (name.c_str() != it->c_str()) { - name = *it; - ++_unifiedCounter; - } - } else { - _hash->insert(name); - } -} - -void -NameHash::addMemoryUsage(MemoryConsumption& mc) const { - mc._nameHash += sizeof(NameHash) - + _hash->getMemoryConsumption() - - sizeof(NameSet); - for (const std::string & name : *_hash) { - mc._nameHashStrings += mc.getStringMemoryUsage(name, mc._nameHashUnique); - } -} - -} // metrics diff --git a/metrics/src/vespa/metrics/namehash.h b/metrics/src/vespa/metrics/namehash.h deleted file mode 100644 index 94b4c984f6b..00000000000 --- a/metrics/src/vespa/metrics/namehash.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -/** - * \class metrics::NameHash - * \ingroup metrics - * - * \brief Simple class to enable string reference counting to work better. - * - * When creating metrics, it is easy to use const char references from code, - * for instance having a for loop setting up metrics for each thread, this will - * not actually generate ref counted strings, but rather unique strings. - * - * Also, with ref counted strings, it is easy to screw it up if you access the - * string in a way requiring copy. - * - * This class is used to just keep a set of strings, and having a class for - * users to input their strings and get the "master" string with that content. - * - * Metrics use this after having registered metrics, to ensure we dont keep more - * copies of non-unique strings than needed. - */ -#pragma once - -#include "memoryconsumption.h" - -namespace metrics { - -class NameSet; - -class NameHash { - std::unique_ptr<NameSet> _hash; - uint32_t _unifiedCounter; - uint32_t _checkedCounter; - -public: - NameHash(const NameHash &) = delete; - NameHash & operator = (const NameHash &) = delete; - NameHash(); - ~NameHash(); - - void updateName(std::string& name); - - uint32_t getUnifiedStringCount() const { return _unifiedCounter; } - uint32_t getCheckedStringCount() const { return _checkedCounter; } - void resetCounts() { _unifiedCounter = 0; _checkedCounter = 0; } - void addMemoryUsage(MemoryConsumption& mc) const; -}; - -} // metrics diff --git a/searchlib/src/vespa/searchlib/aggregation/group.cpp b/searchlib/src/vespa/searchlib/aggregation/group.cpp index 6eb131fe77d..ca22707ec27 100644 --- a/searchlib/src/vespa/searchlib/aggregation/group.cpp +++ b/searchlib/src/vespa/searchlib/aggregation/group.cpp @@ -103,7 +103,7 @@ Group::Value::groupSingle(const ResultNode & selectResult, HitRank rank, const G } GroupHash & childMap = *_childInfo._childMap; Group * group(NULL); - GroupHash::iterator found = childMap.find<ResultNode, GroupResult, ResultHash, ResultEqual>(selectResult, GroupResult(&_children)); + GroupHash::iterator found = childMap.find<ResultNode>(selectResult); if (found == childMap.end()) { // group not present in child map if (level.allowMoreGroups(childMap.size())) { group = new Group(level.getGroupPrototype()); diff --git a/searchlib/src/vespa/searchlib/aggregation/group.h b/searchlib/src/vespa/searchlib/aggregation/group.h index c769b6c1d27..fe3f19cb615 100644 --- a/searchlib/src/vespa/searchlib/aggregation/group.h +++ b/searchlib/src/vespa/searchlib/aggregation/group.h @@ -42,11 +42,17 @@ public: struct GroupEqual : public std::binary_function<ChildP, ChildP, bool> { GroupEqual(const GroupList * v) : _v(v) { } bool operator()(uint32_t a, uint32_t b) { return (*_v)[a]->getId().cmpFast((*_v)[b]->getId()) == 0; } + bool operator()(const Group & a, uint32_t b) { return a.getId().cmpFast((*_v)[b]->getId()) == 0; } + bool operator()(uint32_t a, const Group & b) { return (*_v)[a]->getId().cmpFast(b.getId()) == 0; } + bool operator()(const ResultNode & a, uint32_t b) { return a.cmpFast((*_v)[b]->getId()) == 0; } + bool operator()(uint32_t a, const ResultNode & b) { return (*_v)[a]->getId().cmpFast(b) == 0; } const GroupList *_v; }; struct GroupHasher { GroupHasher(const GroupList * v) : _v(v) { } size_t operator() (uint32_t arg) const { return (*_v)[arg]->getId().hash(); } + size_t operator() (const Group & arg) const { return arg.getId().hash(); } + size_t operator() (const ResultNode & arg) const { return arg.hash(); } const GroupList *_v; }; struct GroupResult { diff --git a/searchlib/src/vespa/searchlib/grouping/groupengine.cpp b/searchlib/src/vespa/searchlib/grouping/groupengine.cpp index aa289da068b..b652d5a840d 100644 --- a/searchlib/src/vespa/searchlib/grouping/groupengine.cpp +++ b/searchlib/src/vespa/searchlib/grouping/groupengine.cpp @@ -6,12 +6,10 @@ #include <vespa/vespalib/stllike/hash_set.hpp> #include <cassert> -namespace search { +using namespace search::expression; +using namespace search::aggregation; -using namespace expression; -using namespace aggregation; - -namespace grouping { +namespace search::grouping { GroupEngine::GroupEngine(const GroupingLevel * request, size_t level, GroupEngine * nextEngine, bool frozen) : Collect(request->getGroupPrototype()), @@ -52,7 +50,7 @@ GroupRef GroupEngine::group(Children & children, uint32_t docId, double rank) throw std::runtime_error("Does not know how to handle failed select statements"); } const ResultNode &selectResult = selector.getResult(); - Children::iterator found = children.find<ResultNode, GroupResult, Group::ResultHash, Group::ResultEqual>(selectResult, GroupResult(*this)); + Children::iterator found = children.find(selectResult); GroupRef gr; if (found == children.end()) { if (_request->allowMoreGroups(children.size())) { @@ -228,7 +226,6 @@ GroupEngine::preFillEngine(const Group & r, size_t depth) } } -} // this function was added by ../../forcelink.sh void forcelink_file_searchlib_grouping_groupengine() {} diff --git a/searchlib/src/vespa/searchlib/grouping/groupengine.h b/searchlib/src/vespa/searchlib/grouping/groupengine.h index a4f6d7a43f6..5167c37560a 100644 --- a/searchlib/src/vespa/searchlib/grouping/groupengine.h +++ b/searchlib/src/vespa/searchlib/grouping/groupengine.h @@ -5,8 +5,7 @@ #include <vespa/searchlib/grouping/collect.h> #include <vespa/vespalib/util/sort.h> -namespace search { -namespace grouping { +namespace search::grouping { class GroupEngine : protected Collect { @@ -15,6 +14,7 @@ public: public: GroupHash(const GroupEngine & engine) : _engine(engine) { } uint32_t operator () (GroupRef a) const { return _engine.hash(a); } + uint32_t operator () (const expression::ResultNode & a) const { return a.hash(); } private: const GroupEngine & _engine; }; @@ -22,6 +22,8 @@ public: public: GroupEqual(const GroupEngine & engine) : _engine(engine) { } bool operator () (GroupRef a, GroupRef b) const { return _engine.cmpId(a, b) == 0; } + bool operator () (const expression::ResultNode & a, GroupRef b) const { return a.cmpFast(_engine.getGroupId(b)) == 0; } + bool operator () (GroupRef a, const expression::ResultNode & b) const { return _engine.getGroupId(a).cmpFast(b) == 0; } private: const GroupEngine & _engine; }; @@ -137,4 +139,3 @@ private: }; } -} diff --git a/staging_vespalib/src/vespa/vespalib/objects/identifiable.cpp b/staging_vespalib/src/vespa/vespalib/objects/identifiable.cpp index 7e14fbc0014..ecd7aed185b 100644 --- a/staging_vespalib/src/vespa/vespalib/objects/identifiable.cpp +++ b/staging_vespalib/src/vespa/vespalib/objects/identifiable.cpp @@ -31,14 +31,30 @@ public: unsigned name2Id(const char * name) const; bool empty() const { return _listById.empty(); } private: - struct GetId { uint32_t operator() (const RuntimeClass * f) const { return f->id(); } }; - struct HashId { size_t operator() (const RuntimeClass * f) const { return f->id(); } }; - struct EqualId { bool operator() (const RuntimeClass * a, const RuntimeClass * b) const { return a->id() == b->id(); } }; - struct GetName { const char * operator() (const RuntimeClass * f) const { return f->name(); } }; - struct HashName { size_t operator() (const RuntimeClass * f) const { return hashValue(f->name()); } }; - struct EqualName { bool operator() (const RuntimeClass * a, const RuntimeClass * b) const { return strcmp(a->name(), b->name()) == 0; } }; - typedef hash_set<RuntimeClass *, HashId, EqualId> IdList; - typedef hash_set<RuntimeClass *, HashName, EqualName> NameList; + struct HashId { + uint32_t operator() (const RuntimeClass * f) const { return f->id(); } + uint32_t operator() (uint32_t id) const { return id; } + }; + struct EqualId { + bool operator() (const RuntimeClass * a, const RuntimeClass * b) const { return a->id() == b->id(); } + bool operator() (const RuntimeClass * a, uint32_t b) const { return a->id() == b; } + bool operator() (uint32_t a, const RuntimeClass * b) const { return a == b->id(); } + + + }; + struct HashName { + uint32_t operator() (const RuntimeClass * f) const { return hashValue(f->name()); } + uint32_t operator() (const char * name) const { return hashValue(name); } + + }; + struct EqualName { + bool operator() (const RuntimeClass * a, const RuntimeClass * b) const { return strcmp(a->name(), b->name()) == 0; } + bool operator() (const RuntimeClass * a, const char * b) const { return strcmp(a->name(), b) == 0; } + bool operator() (const char * a, const RuntimeClass * b) const { return strcmp(a, b->name()) == 0; } + + }; + using IdList = hash_set<RuntimeClass *, HashId, EqualId>; + using NameList = hash_set<RuntimeClass *, HashName, EqualName>; IdList _listById; NameList _listByName; }; @@ -69,14 +85,14 @@ bool Register::append(Identifiable::RuntimeClass * c) const Identifiable::RuntimeClass * Register::classFromId(unsigned id) const { - IdList::const_iterator it(_listById.find<uint32_t, GetId, hash<uint32_t>, std::equal_to<uint32_t> >(id)); - return (it != _listById.end()) ? *it : NULL; + IdList::const_iterator it(_listById.find<uint32_t>(id)); + return (it != _listById.end()) ? *it : nullptr; } const Identifiable::RuntimeClass * Register::classFromName(const char *name) const { - NameList::const_iterator it(_listByName.find<const char *, GetName, hash<const char *>, std::equal_to<const char *> >(name)); - return (it != _listByName.end()) ? *it : NULL; + NameList::const_iterator it(_listByName.find<const char *>(name)); + return (it != _listByName.end()) ? *it : nullptr; } Register * _register = nullptr; diff --git a/vespalib/src/tests/stllike/hash_test.cpp b/vespalib/src/tests/stllike/hash_test.cpp index 4feeaef8349..017a16ee7b6 100644 --- a/vespalib/src/tests/stllike/hash_test.cpp +++ b/vespalib/src/tests/stllike/hash_test.cpp @@ -341,11 +341,11 @@ private: struct myhash { size_t operator() (const S & arg) const { return arg.hash(); } + size_t operator() (uint32_t arg) const { return arg; } }; -struct myextract { - uint32_t operator() (const S & arg) const { return arg.a(); } -}; +bool operator == (uint32_t a, const S & b) { return a == b.a(); } +bool operator == (const S & a, uint32_t b) { return a.a() == b; } TEST("test hash set find") { @@ -354,7 +354,7 @@ TEST("test hash set find") set.insert(S(i)); } EXPECT_TRUE(*set.find(S(1)) == S(1)); - hash_set<S, myhash>::iterator cit = set.find<uint32_t, myextract, vespalib::hash<uint32_t>, std::equal_to<uint32_t> >(7); + auto cit = set.find<uint32_t>(7); EXPECT_TRUE(*cit == S(7)); } diff --git a/vespalib/src/vespa/vespalib/stllike/hash_fun.h b/vespalib/src/vespa/vespalib/stllike/hash_fun.h index de849b8924e..a3401083f95 100644 --- a/vespalib/src/vespa/vespalib/stllike/hash_fun.h +++ b/vespalib/src/vespa/vespalib/stllike/hash_fun.h @@ -6,20 +6,6 @@ namespace vespalib { -template<typename T, typename F> -struct cast_static { - T operator() (const F & o) const { - return static_cast<T>(o); - } -}; - -template<typename L, typename R> -struct equal_to : public std::binary_function<L, R, bool> -{ - bool operator()(const L & __x, const R & __y) const { return __x == __y; } - bool operator()(const R & __x, const L & __y) const { return __x == __y; } -}; - template<typename K> struct hash { // specializations operate as functor for known key types size_t operator() (const K & v) const { @@ -76,22 +62,18 @@ template<typename T> struct hash<const T *> { size_t hashValue(const char *str); size_t hashValue(const void *str, size_t sz); -template<> struct hash<const char *> { - size_t operator() (const char * arg) const { return hashValue(arg); } -}; - -template<> struct hash<vespalib::stringref> { - size_t operator() (vespalib::stringref arg) const { return hashValue(arg.data(), arg.size()); } -}; - -template<> struct hash<vespalib::string> { +struct hash_strings { size_t operator() (const vespalib::string & arg) const { return hashValue(arg.c_str()); } -}; - -template<> struct hash<std::string> { + size_t operator() (vespalib::stringref arg) const { return hashValue(arg.data(), arg.size()); } + size_t operator() (const char * arg) const { return hashValue(arg); } size_t operator() (const std::string& arg) const { return hashValue(arg.c_str()); } }; +template<> struct hash<const char *> : hash_strings { }; +template<> struct hash<vespalib::stringref> : public hash_strings { }; +template<> struct hash<vespalib::string> : hash_strings {}; +template<> struct hash<std::string> : hash_strings {}; + template<typename V> struct size { size_t operator() (const V & arg) const { return arg.size(); } }; @@ -100,6 +82,4 @@ template<typename V> struct zero { size_t operator() (const V & ) const { return 0; } }; - } // namespace vespalib - diff --git a/vespalib/src/vespa/vespalib/stllike/hash_map.h b/vespalib/src/vespa/vespalib/stllike/hash_map.h index 929a3740a1d..34b22ba7ca3 100644 --- a/vespalib/src/vespa/vespalib/stllike/hash_map.h +++ b/vespalib/src/vespa/vespalib/stllike/hash_map.h @@ -6,7 +6,7 @@ namespace vespalib { -template< typename K, typename V, typename H = vespalib::hash<K>, typename EQ = std::equal_to<K>, typename M=hashtable_base::prime_modulator > +template< typename K, typename V, typename H = vespalib::hash<K>, typename EQ = std::equal_to<>, typename M=hashtable_base::prime_modulator > class hash_map { public: @@ -51,22 +51,13 @@ public: iterator find(const K & key) { return _ht.find(key); } const_iterator find(const K & key) const { return _ht.find(key); } - template< typename AltKey, typename AltExtract=std::_Identity<K>, typename AltHash=vespalib::hash<AltKey>, typename AltEqual=equal_to<AltKey, K> > + template< typename AltKey > const_iterator find(const AltKey & key) const { - return _ht.template find<AltKey, AltExtract, AltHash, AltEqual>(key); + return _ht.template find<AltKey>(key); } - template< typename AltKey, typename AltExtract=std::_Identity<K>, typename AltHash=vespalib::hash<AltKey>, typename AltEqual=equal_to<AltKey, K> > + template< typename AltKey> iterator find(const AltKey & key) { - return _ht.template find<AltKey, AltExtract, AltHash, AltEqual>(key); - } - template< typename AltKey, typename AltExtract, typename AltHash=vespalib::hash<AltKey>, typename AltEqual=equal_to<AltKey, K> > - const_iterator find(const AltKey & key, const AltExtract & altExtract) const { - return _ht.template find<AltKey, AltExtract, AltHash, AltEqual>(key, altExtract); - } - - template< typename AltKey, typename AltExtract, typename AltHash=vespalib::hash<AltKey>, typename AltEqual=equal_to<AltKey, K> > - iterator find(const AltKey & key, const AltExtract & altExtract) { - return _ht.template find<AltKey, AltExtract, AltHash, AltEqual>(key, altExtract); + return _ht.template find<AltKey>(key); } void clear(); diff --git a/vespalib/src/vespa/vespalib/stllike/hash_map.hpp b/vespalib/src/vespa/vespalib/stllike/hash_map.hpp index b526188b8b2..74f1594965a 100644 --- a/vespalib/src/vespa/vespalib/stllike/hash_map.hpp +++ b/vespalib/src/vespa/vespalib/stllike/hash_map.hpp @@ -71,7 +71,7 @@ hash_map<K, V, H, EQ, M>::getMemoryUsed() const #define VESPALIB_HASH_MAP_INSTANTIATE_H_E(K, V, H, E) \ VESPALIB_HASH_MAP_INSTANTIATE_H_E_M(K, V, H, E, vespalib::hashtable_base::prime_modulator) -#define VESPALIB_HASH_MAP_INSTANTIATE_H(K, V, H) VESPALIB_HASH_MAP_INSTANTIATE_H_E(K, V, H, std::equal_to<K>) +#define VESPALIB_HASH_MAP_INSTANTIATE_H(K, V, H) VESPALIB_HASH_MAP_INSTANTIATE_H_E(K, V, H, std::equal_to<>) #define VESPALIB_HASH_MAP_INSTANTIATE(K, V) VESPALIB_HASH_MAP_INSTANTIATE_H(K, V, vespalib::hash<K>) diff --git a/vespalib/src/vespa/vespalib/stllike/hash_set.h b/vespalib/src/vespa/vespalib/stllike/hash_set.h index 9756a3083df..7a2db4735aa 100644 --- a/vespalib/src/vespa/vespalib/stllike/hash_set.h +++ b/vespalib/src/vespa/vespalib/stllike/hash_set.h @@ -7,7 +7,7 @@ namespace vespalib { -template< typename K, typename H = vespalib::hash<K>, typename EQ = std::equal_to<K>, typename M=hashtable_base::prime_modulator> +template< typename K, typename H = vespalib::hash<K>, typename EQ = std::equal_to<>, typename M=hashtable_base::prime_modulator> class hash_set { private: @@ -48,21 +48,11 @@ public: template <typename Func> void for_each(Func func) const { _ht.for_each(func); } - template< typename AltKey, typename AltExtract=std::_Identity<K>, typename AltHash=vespalib::hash<AltKey>, typename AltEqual=equal_to<AltKey, K> > - const_iterator find(const AltKey & key) const { return _ht.template find<AltKey, AltExtract, AltHash, AltEqual>(key); } + template< typename AltKey > + const_iterator find(const AltKey & key) const { return _ht.template find<AltKey>(key); } - template< typename AltKey, typename AltExtract=std::_Identity<K>, typename AltHash=vespalib::hash<AltKey>, typename AltEqual=equal_to<AltKey, K> > - iterator find(const AltKey & key) { return _ht.template find<AltKey, AltExtract, AltHash, AltEqual>(key); } - - template< typename AltKey, typename AltExtract, typename AltHash=vespalib::hash<AltKey>, typename AltEqual=equal_to<AltKey, K> > - const_iterator find(const AltKey & key, const AltExtract & altExtract) const { - return _ht.template find<AltKey, AltExtract, AltHash, AltEqual>(key, altExtract); - } - - template< typename AltKey, typename AltExtract, typename AltHash=vespalib::hash<AltKey>, typename AltEqual=equal_to<AltKey, K> > - iterator find(const AltKey & key, const AltExtract & altExtract) { - return _ht.template find<AltKey, AltExtract, AltHash, AltEqual>(key, altExtract); - } + template< typename AltKey> + iterator find(const AltKey & key) { return _ht.template find<AltKey>(key); } void clear(); void resize(size_t newSize); diff --git a/vespalib/src/vespa/vespalib/stllike/hash_set.hpp b/vespalib/src/vespa/vespalib/stllike/hash_set.hpp index cf6341218f1..f0427595382 100644 --- a/vespalib/src/vespa/vespalib/stllike/hash_set.hpp +++ b/vespalib/src/vespa/vespalib/stllike/hash_set.hpp @@ -84,11 +84,11 @@ hash_set<K, H, EQ, M>::insert(K &&value) { #define VESPALIB_HASH_SET_INSTANTIATE(K) \ template class vespalib::hash_set<K>; \ - template class vespalib::hashtable<K, K, vespalib::hash<K>, std::equal_to<K>, std::_Identity<K>>; \ + template class vespalib::hashtable<K, K, vespalib::hash<K>, std::equal_to<>, std::_Identity<K>>; \ template class vespalib::Array<vespalib::hash_node<K>>; #define VESPALIB_HASH_SET_INSTANTIATE_H(K, H) \ template class vespalib::hash_set<K, H>; \ - template class vespalib::hashtable<K, K, H, std::equal_to<K>, std::_Identity<K>>; \ + template class vespalib::hashtable<K, K, H, std::equal_to<>, std::_Identity<K>>; \ template class vespalib::Array<vespalib::hash_node<K>>; diff --git a/vespalib/src/vespa/vespalib/stllike/hashtable.h b/vespalib/src/vespa/vespalib/stllike/hashtable.h index 612c50ffb61..fa418cbad02 100644 --- a/vespalib/src/vespa/vespalib/stllike/hashtable.h +++ b/vespalib/src/vespa/vespalib/stllike/hashtable.h @@ -235,15 +235,12 @@ public: size_t capacity() const { return _nodes.capacity(); } size_t size() const { return _count; } bool empty() const { return _count == 0; } - template< typename AltKey, typename AltExtract, typename AltHash, typename AltEqual > - iterator find(const AltKey & key, const AltExtract & altExtract); - template< typename AltKey, typename AltExtract, typename AltHash, typename AltEqual > - iterator find(const AltKey & key) { return find<AltKey, AltExtract, AltHash, AltEqual>(key, AltExtract()); } + template< typename AltKey> + iterator find(const AltKey & key); iterator find(const Key & key); - template< typename AltKey, typename AltExtract, typename AltHash, typename AltEqual > - const_iterator find(const AltKey & key, const AltExtract & altExtract) const; - template< typename AltKey, typename AltExtract, typename AltHash, typename AltEqual > - const_iterator find(const AltKey & key) const { return find<AltKey, AltExtract, AltHash, AltEqual>(key, AltExtract()); } + + template< typename AltKey> + const_iterator find(const AltKey & key) const; const_iterator find(const Key & key) const; template <typename V> insert_result insert(V && node) { @@ -285,7 +282,8 @@ protected: const Value & getByInternalIndex(size_t index) const { return _nodes[index].getValue(); } template <typename MoveHandler> void erase(MoveHandler & moveHandler, next_t h, const const_iterator & key); - next_t hash(const Key & key) const { return modulator(_hasher(key)); } + template<typename K> + next_t hash(const K & key) const { return modulator(_hasher(key)); } private: Modulator _modulator; size_t _count; diff --git a/vespalib/src/vespa/vespalib/stllike/hashtable.hpp b/vespalib/src/vespa/vespalib/stllike/hashtable.hpp index 2fbe83eb226..60c391a0b7e 100644 --- a/vespalib/src/vespa/vespalib/stllike/hashtable.hpp +++ b/vespalib/src/vespa/vespalib/stllike/hashtable.hpp @@ -95,17 +95,15 @@ hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::find(const Key & key) } template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator > -template< typename AltKey, typename AltExtract, typename AltHash, typename AltEqual> -typename hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::const_iterator -hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::find(const AltKey & key, const AltExtract & altExtract) const +template< typename AltKey> +typename hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::iterator +hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::find(const AltKey & key) { - AltHash altHasher; - next_t h = modulator(altHasher(key)); - if (_nodes[h].valid()) { - AltEqual altEqual; + next_t h = hash(key); + if (__builtin_expect(_nodes[h].valid(), true)) { do { - if (altEqual(altExtract(_keyExtractor(_nodes[h].getValue())), key)) { - return const_iterator(this, h); + if (__builtin_expect(_equal(_keyExtractor(_nodes[h].getValue()), key), true)) { + return iterator(this, h); } h = _nodes[h].getNext(); } while (h != Node::npos); @@ -114,17 +112,15 @@ hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::find(const AltKey & k } template< typename Key, typename Value, typename Hash, typename Equal, typename KeyExtract, typename Modulator > -template< typename AltKey, typename AltExtract, typename AltHash, typename AltEqual> -typename hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::iterator -hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::find(const AltKey & key, const AltExtract & altExtract) +template< typename AltKey> +typename hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::const_iterator +hashtable<Key, Value, Hash, Equal, KeyExtract, Modulator>::find(const AltKey & key) const { - AltHash altHasher; - next_t h = modulator(altHasher(key)); - if (_nodes[h].valid()) { - AltEqual altEqual; + next_t h = hash(key); + if (__builtin_expect(_nodes[h].valid(), true)) { do { - if (altEqual(altExtract(_keyExtractor(_nodes[h].getValue())), key)) { - return iterator(this, h); + if (__builtin_expect(_equal(_keyExtractor(_nodes[h].getValue()), key), true)) { + return const_iterator(this, h); } h = _nodes[h].getNext(); } while (h != Node::npos); |