diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2018-11-02 15:11:36 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-02 15:11:36 +0100 |
commit | 6b71ac0c62c27e7db981f378fd763637d41ccce1 (patch) | |
tree | 876c83ff8115386f040f547895b0800bf2750138 | |
parent | d4572d3347aafa7061ed6104eb56ec5d63e7e9f8 (diff) | |
parent | 3a10bfc113278a206fd61ea8ff1e2b1afb04aa16 (diff) |
Merge pull request #7540 from vespa-engine/balder/use-templated-find-take-2
Balder/use templated find take 2
30 files changed, 262 insertions, 358 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 13d7bdee980..f673f22e29c 100644 --- a/juniper/src/vespa/juniper/stringmap.cpp +++ b/juniper/src/vespa/juniper/stringmap.cpp @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "stringmap.h" +#include <vespa/vespalib/stllike/hashtable.hpp> void Fast_StringMap::Insert(const char* key, const char* value) { @@ -9,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/loadmetric.hpp b/metrics/src/vespa/metrics/loadmetric.hpp index ce93c761a05..65098662e04 100644 --- a/metrics/src/vespa/metrics/loadmetric.hpp +++ b/metrics/src/vespa/metrics/loadmetric.hpp @@ -55,7 +55,7 @@ LoadMetric<MetricType>::LoadMetric(const LoadMetric<MetricType>& other, MetricSe } template<typename MetricType> -LoadMetric<MetricType>::~LoadMetric() { } +LoadMetric<MetricType>::~LoadMetric() = default; template<typename MetricType> MetricSet* @@ -74,10 +74,9 @@ MetricType& LoadMetric<MetricType>::getMetric(const LoadType& type) { MetricType* metric; - typename vespalib::hash_map<uint32_t, MetricTypeUP>::iterator it( - _metrics.find(type.getId())); + auto it = _metrics.find(type.getId()); if (it == _metrics.end()) { - it = _metrics.find(0); + it = _metrics.find(0u); assert(it != _metrics.end()); // Default should always exist } metric = it->second.get(); diff --git a/metrics/src/vespa/metrics/memoryconsumption.cpp b/metrics/src/vespa/metrics/memoryconsumption.cpp index 0e69defa558..0391e496ecd 100644 --- a/metrics/src/vespa/metrics/memoryconsumption.cpp +++ b/metrics/src/vespa/metrics/memoryconsumption.cpp @@ -1,11 +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/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() @@ -16,7 +16,7 @@ MemoryConsumption::MemoryConsumption() _seenStrings->resize(1000); } -MemoryConsumption::~MemoryConsumption() { } +MemoryConsumption::~MemoryConsumption() = default; uint32_t MemoryConsumption::getStringMemoryUsage(const std::string& s, uint32_t& uniqueCount) { diff --git a/metrics/src/vespa/metrics/metricmanager.cpp b/metrics/src/vespa/metrics/metricmanager.cpp index 5b716e2698f..7125446c168 100644 --- a/metrics/src/vespa/metrics/metricmanager.cpp +++ b/metrics/src/vespa/metrics/metricmanager.cpp @@ -13,6 +13,7 @@ #include <vespa/vespalib/util/stringfmt.h> #include <vespa/vespalib/util/exceptions.h> #include <vespa/vespalib/stllike/asciistream.h> +#include <vespa/vespalib/stllike/hashtable.hpp> #include <sstream> #include <algorithm> @@ -23,8 +24,8 @@ namespace metrics { typedef MetricsmanagerConfig Config; -MetricManager::ConsumerSpec::ConsumerSpec() : includedMetrics() { } -MetricManager::ConsumerSpec::~ConsumerSpec() { } +MetricManager::ConsumerSpec::ConsumerSpec() = default; +MetricManager::ConsumerSpec::~ConsumerSpec() = default; void MetricManager::assertMetricLockLocked(const MetricLockGuard& g) const { 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/searchcommon/src/vespa/searchcommon/common/schema.cpp b/searchcommon/src/vespa/searchcommon/common/schema.cpp index 5e9db03bf31..cef74409024 100644 --- a/searchcommon/src/vespa/searchcommon/common/schema.cpp +++ b/searchcommon/src/vespa/searchcommon/common/schema.cpp @@ -4,6 +4,7 @@ #include <fstream> #include <vespa/config/common/configparser.h> #include <vespa/vespalib/stllike/asciistream.h> +#include <vespa/vespalib/stllike/hashtable.hpp> #include <vespa/fastos/file.h> #include <vespa/log/log.h> @@ -421,6 +422,25 @@ Schema::getFieldSetId(vespalib::stringref name) const return getFieldId(name, _fieldSetIds); } +bool +Schema::isIndexField(vespalib::stringref name) const +{ + return _indexIds.find(name) != _indexIds.end(); +} + +bool +Schema::isSummaryField(vespalib::stringref name) const +{ + return _summaryIds.find(name) != _summaryIds.end(); +} + +bool +Schema::isAttributeField(vespalib::stringref name) const +{ + return _attributeIds.find(name) != _attributeIds.end(); +} + + void Schema::swap(Schema &rhs) { diff --git a/searchcommon/src/vespa/searchcommon/common/schema.h b/searchcommon/src/vespa/searchcommon/common/schema.h index d066ccb0a27..f8020d6ed9a 100644 --- a/searchcommon/src/vespa/searchcommon/common/schema.h +++ b/searchcommon/src/vespa/searchcommon/common/schema.h @@ -293,11 +293,7 @@ public: * @return true if field is an index field. * @param name the name of the field. **/ - bool - isIndexField(vespalib::stringref name) const - { - return _indexIds.find(name) != _indexIds.end(); - } + bool isIndexField(vespalib::stringref name) const; /** * Check if a field is a summary field @@ -305,22 +301,15 @@ public: * @return true if field is an summary field. * @param name the name of the field. **/ - bool - isSummaryField(vespalib::stringref name) const - { - return _summaryIds.find(name) != _summaryIds.end(); - } + bool isSummaryField(vespalib::stringref name) const; + /** * Check if a field is a attribute field * * @return true if field is an attribute field. * @param name the name of the field. **/ - bool - isAttributeField(vespalib::stringref name) const - { - return _attributeIds.find(name) != _attributeIds.end(); - } + bool isAttributeField(vespalib::stringref name) const; /** * Get information about a specific attribute field using the given fieldId. diff --git a/searchlib/src/vespa/searchlib/aggregation/group.cpp b/searchlib/src/vespa/searchlib/aggregation/group.cpp index 6eb131fe77d..17e56c9af21 100644 --- a/searchlib/src/vespa/searchlib/aggregation/group.cpp +++ b/searchlib/src/vespa/searchlib/aggregation/group.cpp @@ -34,8 +34,8 @@ struct SortByGroupRank { } }; -void reset(Group * & v) { v = NULL; } -void destruct(Group * v) { if (v) { delete v; } } +void reset(Group * & v) { v = nullptr; } +void destruct(Group * v) { delete v; } void destruct(Group::GroupList & l, size_t m) @@ -44,7 +44,7 @@ destruct(Group::GroupList & l, size_t m) destruct(l[i]); } delete [] l; - l = NULL; + l = nullptr; } } @@ -97,13 +97,13 @@ Group::groupNext(const GroupingLevel & level, const Doc & doc, HitRank rank) Group * Group::Value::groupSingle(const ResultNode & selectResult, HitRank rank, const GroupingLevel & level) { - if (_childInfo._childMap == NULL) { + if (_childInfo._childMap == nullptr) { assert(getChildrenSize() == 0); _childInfo._childMap = new GroupHash(1, GroupHasher(&_children), GroupEqual(&_children)); } GroupHash & childMap = *_childInfo._childMap; - Group * group(NULL); - GroupHash::iterator found = childMap.find<ResultNode, GroupResult, ResultHash, ResultEqual>(selectResult, GroupResult(&_children)); + Group * group(nullptr); + GroupHash::iterator found = childMap.find(selectResult); if (found == childMap.end()) { // group not present in child map if (level.allowMoreGroups(childMap.size())) { group = new Group(level.getGroupPrototype()); @@ -203,7 +203,7 @@ Group::Group() : Group::Group(const Group & rhs) = default; Group & Group::operator = (const Group & rhs) = default; -Group::~Group() { } +Group::~Group() = default; Group & Group::partialCopy(const Group & rhs) { @@ -230,7 +230,7 @@ void Group::Value::addExpressionResult(ExpressionNode::UP expressionNode) { uint32_t newSize = getAggrSize() + getExprSize() + 1; - ExpressionVector n = new ExpressionNode::CP[newSize]; + auto n = new ExpressionNode::CP[newSize]; for (uint32_t i(0); i < (newSize - 1); i++) { n[i] = std::move(_aggregationResults[i]); } @@ -246,7 +246,7 @@ Group::Value::addAggregationResult(ExpressionNode::UP aggr) { assert(getAggrSize() < 15); size_t newSize = getAggrSize() + 1 + getExprSize(); - ExpressionVector n = new ExpressionNode::CP[newSize]; + auto n = new ExpressionNode::CP[newSize]; for (size_t i(0), m(getAggrSize()); i < m; i++) { n[i] = std::move(_aggregationResults[i]); } @@ -292,10 +292,10 @@ Group::Value::addChild(Group * child) { const size_t sz(getChildrenSize()); assert(sz < 0xffffff); - if (_children == 0) { + if (_children == nullptr) { _children = new ChildP[4]; } else if ((sz >=4) && vespalib::Optimized::msbIdx(sz) == vespalib::Optimized::lsbIdx(sz)) { - GroupList n = new ChildP[sz*2]; + auto n = new ChildP[sz*2]; for (size_t i(0), m(getChildrenSize()); i < m; i++) { n[i] = _children[i]; } @@ -317,7 +317,7 @@ Group::Value::select(const vespalib::ObjectPredicate &predicate, vespalib::Objec void Group::Value::preAggregate() { - assert(_childInfo._childMap == NULL); + assert(_childInfo._childMap == nullptr); _childInfo._childMap = new GroupHash(getChildrenSize()*2, GroupHasher(&_children), GroupEqual(&_children)); GroupHash & childMap = *_childInfo._childMap; for (ChildP *it(_children), *mt(_children + getChildrenSize()); it != mt; ++it) { @@ -330,7 +330,7 @@ void Group::Value::postAggregate() { delete _childInfo._childMap; - _childInfo._childMap = NULL; + _childInfo._childMap = nullptr; for (ChildP *it(_children), *mt(_children + getChildrenSize()); it != mt; ++it) { (*it)->postAggregate(); } @@ -372,7 +372,7 @@ Group::Value::execute() { void Group::Value::mergeLevel(const Group & protoType, const Value & b) { for (ChildP *it(b._children), *mt(b._children + b.getChildrenSize()); it != mt; ++it) { - ChildP g(new Group(protoType)); + auto g(new Group(protoType)); g->partialCopy(**it); addChild(g); } @@ -382,7 +382,7 @@ void Group::Value::merge(const std::vector<GroupingLevel> &levels, uint32_t firstLevel, uint32_t currentLevel, const Value &b) { - GroupList z = new ChildP[getChildrenSize() + b.getChildrenSize()]; + auto z = new ChildP[getChildrenSize() + b.getChildrenSize()]; size_t kept(0); ChildP * px = _children; ChildP * ex = _children + getChildrenSize(); @@ -422,7 +422,7 @@ Group::Value::merge(const std::vector<GroupingLevel> &levels, void Group::Value::prune(const Value & b, uint32_t lastLevel, uint32_t currentLevel) { - GroupList keep = new ChildP[b.getChildrenSize()]; + auto keep = new ChildP[b.getChildrenSize()]; size_t kept(0); ChildP * px = _children; ChildP * ex = _children + getAllChildrenSize(); @@ -562,7 +562,7 @@ Group::Value::deserialize(Deserializer & is) { // results into a temporary buffer, and then reallocate the actual // vector when we know the total size. Then we copy the temp buffer and // deserialize the rest to the end of the vector. - ExpressionVector tmpAggregationResults = new ExpressionNode::CP[aggrSize]; + auto tmpAggregationResults = new ExpressionNode::CP[aggrSize]; setAggrSize(aggrSize); for(uint32_t i(0); i < aggrSize; i++) { is >> tmpAggregationResults[i]; @@ -589,7 +589,7 @@ Group::Value::deserialize(Deserializer & is) { _children = new ChildP[std::max(4ul, 2ul << vespalib::Optimized::msbIdx(count))]; setChildrenSize(count); for(uint32_t i(0); i < count; i++) { - ChildP group(new Group); + auto group(new Group); is >> *group; _children[i] = group; } @@ -633,24 +633,24 @@ Group::Value::visitMembers(vespalib::ObjectVisitor &visitor) const { Group::Value::Value() : _packedLength(0), _tag(-1), - _aggregationResults(NULL), - _children(NULL), + _aggregationResults(nullptr), + _children(nullptr), _childInfo(), _orderBy() { memset(_orderBy, 0, sizeof(_orderBy)); - _childInfo._childMap = NULL; + _childInfo._childMap = nullptr; } Group::Value::Value(const Value & rhs) : _packedLength(rhs._packedLength), _tag(rhs._tag), - _aggregationResults(NULL), - _children(NULL), + _aggregationResults(nullptr), + _children(nullptr), _childInfo(), _orderBy() { - _childInfo._childMap = NULL; + _childInfo._childMap = nullptr; memcpy(_orderBy, rhs._orderBy, sizeof(_orderBy)); uint32_t totalAggrSize = rhs.getAggrSize() + rhs.getExprSize(); if (totalAggrSize > 0) { @@ -665,17 +665,17 @@ Group::Value::Value(const Value & rhs) : _children = new ChildP[std::max(4ul, 2ul << vespalib::Optimized::msbIdx(rhs.getChildrenSize()))]; size_t i(0); for (const ChildP *it(rhs._children), *mt(rhs._children + rhs.getChildrenSize()); it != mt; ++it, i++) { - _children[i] = ChildP(new Group(**it)); + _children[i] = new Group(**it); } } } Group::Value::Value(Value && rhs) noexcept : - _packedLength(std::move(rhs._packedLength)), - _tag(std::move(rhs._tag)), - _aggregationResults(std::move(rhs._aggregationResults)), - _children(std::move(rhs._children)), - _childInfo(std::move(rhs._childInfo)), + _packedLength(rhs._packedLength), + _tag(rhs._tag), + _aggregationResults(rhs._aggregationResults), + _children(rhs._children), + _childInfo(rhs._childInfo), _orderBy() { memcpy(_orderBy, rhs._orderBy, sizeof(_orderBy)); @@ -688,11 +688,11 @@ Group::Value::Value(Value && rhs) noexcept : Group::Value & Group::Value::operator =(Value && rhs) noexcept { - _packedLength = std::move(rhs._packedLength); - _tag = std::move(rhs._tag); - _aggregationResults = std::move(rhs._aggregationResults); - _children = std::move(rhs._children); - _childInfo = std::move(rhs._childInfo); + _packedLength = rhs._packedLength; + _tag = rhs._tag; + _aggregationResults = rhs._aggregationResults; + _children = rhs._children; + _childInfo = rhs._childInfo; memcpy(_orderBy, rhs._orderBy, sizeof(_orderBy)); rhs.setChildrenSize(0); diff --git a/searchlib/src/vespa/searchlib/aggregation/group.h b/searchlib/src/vespa/searchlib/aggregation/group.h index c769b6c1d27..f302346f211 100644 --- a/searchlib/src/vespa/searchlib/aggregation/group.h +++ b/searchlib/src/vespa/searchlib/aggregation/group.h @@ -42,26 +42,18 @@ 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(); } - const GroupList *_v; - }; - struct GroupResult { - GroupResult(const GroupList * v) : _v(v) { } - const ResultNode & operator() (uint32_t arg) const { return (*_v)[arg]->getId(); } - const GroupList *_v; - }; - struct ResultLess : public std::binary_function<ResultNode::CP, ResultNode::CP, bool> { - bool operator()(const ResultNode::CP & a, const ResultNode::CP & b) { return a->cmpFast(*b) < 0; } - }; - struct ResultEqual : public std::binary_function<ResultNode, ResultNode, bool> { - bool operator()(const ResultNode & a, const ResultNode & b) { return a.cmpFast(b) == 0; } - }; - struct ResultHash { + size_t operator() (const Group & arg) const { return arg.getId().hash(); } size_t operator() (const ResultNode & arg) const { return arg.hash(); } + const GroupList *_v; }; using GroupingLevelList = std::vector<GroupingLevel>; @@ -192,12 +184,12 @@ public: return _aggr.groupSingle(result, rank, level); } - bool hasId() const { return (_id.get() != NULL); } + bool hasId() const { return static_cast<bool>(_id); } const ResultNode &getId() const { return *_id; } Group unchain() const { return *this; } - Group &setId(const ResultNode &id) { _id.reset(static_cast<ResultNode *>(id.clone())); return *this; } + Group &setId(const ResultNode &id) { _id.reset(id.clone()); return *this; } Group &addAggregationResult(ExpressionNode::UP result) { _aggr.addAggregationResult(std::move(result)); return *this; 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/searchlib/src/vespa/searchlib/util/stringenum.cpp b/searchlib/src/vespa/searchlib/util/stringenum.cpp index 60238c32cc6..efcf33e73ab 100644 --- a/searchlib/src/vespa/searchlib/util/stringenum.cpp +++ b/searchlib/src/vespa/searchlib/util/stringenum.cpp @@ -2,13 +2,13 @@ #include "stringenum.h" #include <vespa/fastlib/io/bufferedfile.h> +#include <vespa/vespalib/stllike/hashtable.hpp> #include <cassert> #include <vespa/log/log.h> LOG_SETUP(".seachlib.util.stringenum"); -namespace search { -namespace util { +namespace search::util { static inline char * StripString(char *str) @@ -32,7 +32,14 @@ StripString(char *str) return first; } -StringEnum::~StringEnum() { } +StringEnum::StringEnum() + : _numEntries(0), + _mapping(), + _reverseMap() +{ +} + +StringEnum::~StringEnum() = default; void StringEnum::CreateReverseMapping() const @@ -123,5 +130,44 @@ StringEnum::Load(const char *filename) return true; } +void +StringEnum::Clear() +{ + _reverseMap.clear(); + _mapping.clear(); + _numEntries = 0; +} + +int +StringEnum::Add(const char *str) +{ + Map::const_iterator found(_mapping.find(str)); + if (found != _mapping.end()) { + return found->second; + } else { + int value = _numEntries++; + _mapping[str] = value; + return value; + } } + +int +StringEnum::Lookup(const char *str) const +{ + Map::const_iterator found(_mapping.find(str)); + return (found != _mapping.end()) ? found->second : -1; +} + +const char * +StringEnum::Lookup(uint32_t value) const +{ + if (value >= _numEntries) + return NULL; + + if (_numEntries > _reverseMap.size()) + CreateReverseMapping(); + + return _reverseMap[value]; +} + } diff --git a/searchlib/src/vespa/searchlib/util/stringenum.h b/searchlib/src/vespa/searchlib/util/stringenum.h index 44b3afca539..bd234ba2e36 100644 --- a/searchlib/src/vespa/searchlib/util/stringenum.h +++ b/searchlib/src/vespa/searchlib/util/stringenum.h @@ -5,8 +5,7 @@ #include <vector> #include <vespa/vespalib/stllike/hash_map.h> -namespace search { -namespace util { +namespace search::util { /** * An object of this class represents an enumeration of a set of @@ -35,29 +34,17 @@ public: /** * Create an empty string enumeration. **/ - StringEnum() - : _numEntries(0), - _mapping(), - _reverseMap() - { - } + StringEnum(); /** * Destructor. **/ ~StringEnum(); - /** * Discard all entries held by this object. **/ - void Clear() - { - _reverseMap.clear(); - _mapping.clear(); - _numEntries = 0; - } - + void Clear(); /** * Add a string to this enumeration. Equal strings will get the same @@ -68,18 +55,7 @@ public: * @return the enumerated value for the given string. * @param str string you want to add. **/ - int Add(const char *str) - { - Map::const_iterator found(_mapping.find(str)); - if (found != _mapping.end()) { - return found->second; - } else { - int value = _numEntries++; - _mapping[str] = value; - return value; - } - } - + int Add(const char *str); /** * Obtain the enumerated value for the given string. @@ -87,12 +63,7 @@ public: * @return enumerated value or -1 if not present. * @param str the string to look up. **/ - int Lookup(const char *str) const - { - Map::const_iterator found(_mapping.find(str)); - return (found != _mapping.end()) ? found->second : -1; - } - + int Lookup(const char *str) const; /** * Obtain the string for the given enumerated value. @@ -100,17 +71,7 @@ public: * @return string or NULL if out of range. * @param value the enumerated value to look up. **/ - const char *Lookup(uint32_t value) const - { - if (value >= _numEntries) - return NULL; - - if (_numEntries > _reverseMap.size()) - CreateReverseMapping(); - - return _reverseMap[value]; - } - + const char *Lookup(uint32_t value) const; /** * Obtain the number of entries currently present in this @@ -141,5 +102,3 @@ public: }; } -} - diff --git a/searchsummary/src/vespa/searchsummary/docsummary/keywordextractor.cpp b/searchsummary/src/vespa/searchsummary/docsummary/keywordextractor.cpp index d75ca47dd33..79266d34585 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/keywordextractor.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/keywordextractor.cpp @@ -4,6 +4,7 @@ #include "keywordextractor.h" #include "idocsumenvironment.h" #include <vespa/searchlib/parsequery/stackdumpiterator.h> +#include <vespa/vespalib/stllike/hashtable.hpp> /** Tell us what parts of the query we are interested in */ @@ -12,12 +13,7 @@ namespace search::docsummary { bool useful(search::ParseItem::ItemCreator creator) { - switch (creator) { - case search::ParseItem::CREA_ORIG: - return true; - default: - return false; - } + return creator == search::ParseItem::CREA_ORIG; } @@ -38,6 +34,12 @@ KeywordExtractor::~KeywordExtractor() } } +bool +KeywordExtractor::IsLegalIndexName(const char *idxName) const +{ + return _legalIndexes.find(idxName) != _legalIndexes.end(); +} + KeywordExtractor::IndexPrefix::IndexPrefix(const char *prefix, IndexPrefix **list) : _prefix(NULL), _prefixLen(0), diff --git a/searchsummary/src/vespa/searchsummary/docsummary/keywordextractor.h b/searchsummary/src/vespa/searchsummary/docsummary/keywordextractor.h index 6c9ed675225..cfc73d606a0 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/keywordextractor.h +++ b/searchsummary/src/vespa/searchsummary/docsummary/keywordextractor.h @@ -51,11 +51,7 @@ private: return false; } - bool IsLegalIndexName(const char *idxName) const - { - return _legalIndexes.find(idxName) != _legalIndexes.end(); - } - + bool IsLegalIndexName(const char *idxName) const; public: explicit KeywordExtractor(IDocsumEnvironment * env); ~KeywordExtractor(); diff --git a/searchsummary/src/vespa/searchsummary/docsummary/resultclass.cpp b/searchsummary/src/vespa/searchsummary/docsummary/resultclass.cpp index 507ec7b3866..8066a5e65db 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/resultclass.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/resultclass.cpp @@ -2,6 +2,7 @@ #include "resultclass.h" #include "resultconfig.h" +#include <vespa/vespalib/stllike/hashtable.hpp> #include <cassert> #include <zlib.h> @@ -18,8 +19,14 @@ ResultClass::ResultClass(const char *name, uint32_t id, util::StringEnum & field { } -ResultClass::~ResultClass() { } +ResultClass::~ResultClass() = default; +int +ResultClass::GetIndexFromName(const char* name) const +{ + NameIdMap::const_iterator found(_nameMap.find(name)); + return (found != _nameMap.end()) ? found->second : -1; +} bool ResultClass::AddConfigEntry(const char *name, ResType type) diff --git a/searchsummary/src/vespa/searchsummary/docsummary/resultclass.h b/searchsummary/src/vespa/searchsummary/docsummary/resultclass.h index d1504ed5bdd..e7c7c799b5f 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/resultclass.h +++ b/searchsummary/src/vespa/searchsummary/docsummary/resultclass.h @@ -245,11 +245,7 @@ public: * * @return field index or -1 if not found. **/ - int GetIndexFromName(const char* name) const - { - NameIdMap::const_iterator found(_nameMap.find(name)); - return (found != _nameMap.end()) ? found->second : -1; - } + int GetIndexFromName(const char* name) const; /** diff --git a/staging_vespalib/src/vespa/vespalib/objects/identifiable.cpp b/staging_vespalib/src/vespa/vespalib/objects/identifiable.cpp index 7e14fbc0014..84bdc0a45d0 100644 --- a/staging_vespalib/src/vespa/vespalib/objects/identifiable.cpp +++ b/staging_vespalib/src/vespa/vespalib/objects/identifiable.cpp @@ -27,18 +27,28 @@ public: bool erase(RuntimeClass * c); const RuntimeClass * classFromId(unsigned id) const; const RuntimeClass * classFromName(const char * name) const; - const char * id2Name(unsigned id) const; - 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 +79,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; @@ -115,7 +125,7 @@ Identifiable::RuntimeClass::RuntimeClass(RuntimeInfo * info_) : } } } - if (_register == NULL) { + if (_register == nullptr) { _register = new Register(); } if (! _register->append(this)) { @@ -131,7 +141,7 @@ Identifiable::RuntimeClass::~RuntimeClass() } if (_register->empty()) { delete _register; - _register = NULL; + _register = nullptr; } } @@ -142,20 +152,6 @@ bool Identifiable::RuntimeClass::inherits(unsigned cid) const return (cid == cur->_id); } -class SortById : public std::binary_function<const Identifiable::RuntimeClass *, const Identifiable::RuntimeClass *, bool> { -public: - bool operator() (const Identifiable::RuntimeClass * x, const Identifiable::RuntimeClass * y) const { - return x->id() < y->id(); - } -}; - -class SortByName : public std::binary_function<const Identifiable::RuntimeClass *, const Identifiable::RuntimeClass *, bool> { -public: - bool operator() (const Identifiable::RuntimeClass * x, const Identifiable::RuntimeClass * y) const { - return strcmp(x->name(), y->name()) < 0; - } -}; - Serializer & operator << (Serializer & os, const Identifiable & obj) { os.put(Identifiable::classIdField, obj.getClass().id()); @@ -199,16 +195,16 @@ Identifiable::UP Identifiable::create(Deserializer & is) is.get(classIdField, cid); UP obj; const Identifiable::RuntimeClass *rtc = Identifiable::classFromId(cid); - if (rtc == NULL) { - if ((_classLoader != NULL) && _classLoader->hasClass(cid)) { + if (rtc == nullptr) { + if ((_classLoader != nullptr) && _classLoader->hasClass(cid)) { _classLoader->loadClass(cid); rtc = Identifiable::classFromId(cid); - if (rtc == NULL) { + if (rtc == nullptr) { throw std::runtime_error(make_string("Failed loading class for Identifiable with classId %d(%0x)", cid, cid)); } } } - if (rtc != NULL) { + if (rtc != nullptr) { obj.reset(rtc->create()); if (obj.get()) { obj->deserialize(is); diff --git a/vespalib/src/tests/stllike/hash_test.cpp b/vespalib/src/tests/stllike/hash_test.cpp index e7fe729c1ba..017a16ee7b6 100644 --- a/vespalib/src/tests/stllike/hash_test.cpp +++ b/vespalib/src/tests/stllike/hash_test.cpp @@ -154,14 +154,14 @@ TEST("test hash set with simple type") TEST("test hash map iterator stability") { - hash_map<int, int> h; + hash_map<uint32_t, uint32_t> h; EXPECT_EQUAL(1ul, h.capacity()); for (size_t i(0); i < 100; i++) { EXPECT_TRUE(h.find(i) == h.end()); h[i] = i; EXPECT_TRUE(h.find(i) != h.end()); - int * p1 = & h.find(i)->second; - int * p2 = & h[i]; + uint32_t * p1 = & h.find(i)->second; + uint32_t * p2 = & h[i]; EXPECT_EQUAL(p1, p2); } EXPECT_EQUAL(128ul, h.capacity()); @@ -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 f708f49081e..a3401083f95 100644 --- a/vespalib/src/vespa/vespalib/stllike/hash_fun.h +++ b/vespalib/src/vespa/vespalib/stllike/hash_fun.h @@ -62,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(); } }; @@ -86,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 6d6498f8e78..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: @@ -50,6 +50,16 @@ public: void erase(const_iterator it) { return erase(it->first); } iterator find(const K & key) { return _ht.find(key); } const_iterator find(const K & key) const { return _ht.find(key); } + + template< typename AltKey > + const_iterator find(const AltKey & key) const { + return _ht.template find<AltKey>(key); + } + template< typename AltKey> + iterator find(const AltKey & key) { + return _ht.template find<AltKey>(key); + } + void clear(); void resize(size_t newSize); void swap(hash_map & rhs); 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 c4ccc662787..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, typename AltHash, typename AltEqual > - 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, typename AltHash, typename AltEqual > - iterator find(const AltKey & key) { return _ht.template find<AltKey, AltExtract, AltHash, AltEqual>(key); } - - template< typename AltKey, typename AltExtract, typename AltHash, typename AltEqual > - 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, typename AltEqual > - 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); |