diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2020-05-03 18:23:30 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2020-05-04 08:38:55 +0000 |
commit | 1e8a78d38165897e4c0daad243b21f5db82aa71e (patch) | |
tree | 9ea6db1eaa4f756022c1f257ffbdb4f7de2ccde2 | |
parent | e3f135fc9ccad48719e462397915c6efeaf450b6 (diff) |
Create a QueryTermVector once and do the significance and connectedness lookups once.
16 files changed, 161 insertions, 92 deletions
diff --git a/searchlib/src/vespa/searchlib/features/attributematchfeature.cpp b/searchlib/src/vespa/searchlib/features/attributematchfeature.cpp index c26d18eb11c..bae7b2a1157 100644 --- a/searchlib/src/vespa/searchlib/features/attributematchfeature.cpp +++ b/searchlib/src/vespa/searchlib/features/attributematchfeature.cpp @@ -61,8 +61,8 @@ AttributeMatchExecutor<T>::Computer::Computer(const IQueryEnvironment & env, Att _md(nullptr) { _buffer.allocate(_params.attribute->getMaxValueCount()); - for (uint32_t i = 0; i < env.getNumTerms(); ++i) { - QueryTerm qt = QueryTermFactory::create(env, i); + QueryTermHelper queryTerms(env); + for (const QueryTerm & qt : queryTerms.terms()) { _totalTermWeight += qt.termData()->getWeight().percent(); _totalTermSignificance += qt.significance(); @@ -71,8 +71,9 @@ AttributeMatchExecutor<T>::Computer::Computer(const IQueryEnvironment & env, Att _totalAttrTermWeight += qt.termData()->getWeight().percent(); const ITermFieldData *field = qt.termData()->lookupField(_params.attrInfo->id()); if (field != nullptr) { - qt.fieldHandle(field->getHandle()); - _queryTerms.push_back(qt); + QueryTerm myQt(qt); + myQt.fieldHandle(field->getHandle()); + _queryTerms.push_back(myQt); } } } @@ -300,7 +301,7 @@ AttributeMatchBlueprint::visitDumpFeatures(const IIndexEnvironment &env, Blueprint::UP AttributeMatchBlueprint::createInstance() const { - return Blueprint::UP(new AttributeMatchBlueprint()); + return std::make_unique<AttributeMatchBlueprint>(); } bool @@ -368,4 +369,9 @@ AttributeMatchBlueprint::createExecutor(const IQueryEnvironment & env, vespalib: } } +void +AttributeMatchBlueprint::prepareSharedState(const IQueryEnvironment &queryEnv, IObjectStore &objectStore) const { + QueryTermHelper::lookupAndStoreQueryTerms(queryEnv, objectStore); +} + } diff --git a/searchlib/src/vespa/searchlib/features/attributematchfeature.h b/searchlib/src/vespa/searchlib/features/attributematchfeature.h index 4566a417e47..d4527626d66 100644 --- a/searchlib/src/vespa/searchlib/features/attributematchfeature.h +++ b/searchlib/src/vespa/searchlib/features/attributematchfeature.h @@ -2,8 +2,8 @@ #pragma once -#include "queryterm.h" #include <vespa/searchlib/fef/blueprint.h> +#include "queryterm.h" namespace search::features { @@ -103,6 +103,8 @@ public: bool setup(const fef::IIndexEnvironment & env, const fef::ParameterList & params) override; fef::FeatureExecutor &createExecutor(const fef::IQueryEnvironment &env, vespalib::Stash &stash) const override; + + void prepareSharedState(const fef::IQueryEnvironment &queryEnv, fef::IObjectStore &objectStore) const override; }; } diff --git a/searchlib/src/vespa/searchlib/features/fieldmatch/computer.cpp b/searchlib/src/vespa/searchlib/features/fieldmatch/computer.cpp index 1b943c596c6..6dba7b87c08 100644 --- a/searchlib/src/vespa/searchlib/features/fieldmatch/computer.cpp +++ b/searchlib/src/vespa/searchlib/features/fieldmatch/computer.cpp @@ -5,7 +5,6 @@ #include <vespa/searchlib/fef/properties.h> #include <vespa/vespalib/util/stringfmt.h> #include <vespa/vespalib/locale/c.h> -#include <iostream> #include <set> #include <vespa/log/log.h> @@ -39,7 +38,7 @@ Computer::Computer(const vespalib::string &propertyNamespace, const PhraseSplitt _queryTermFieldMatch.reserve(splitter.getNumTerms()); _cachedHits.reserve(splitter.getNumTerms()); for (uint32_t i = 0; i < splitter.getNumTerms(); ++i) { - QueryTerm qt = QueryTermFactory::create(splitter, i, true, true); + QueryTerm qt = QueryTermFactory::create(splitter, i, true); _totalTermWeight += qt.termData()->getWeight().percent(); _totalTermSignificance += qt.significance(); _simpleMetrics.addQueryTerm(qt.termData()->getWeight().percent()); diff --git a/searchlib/src/vespa/searchlib/features/fieldmatch/computer.h b/searchlib/src/vespa/searchlib/features/fieldmatch/computer.h index c429796cdd2..12535ac105c 100644 --- a/searchlib/src/vespa/searchlib/features/fieldmatch/computer.h +++ b/searchlib/src/vespa/searchlib/features/fieldmatch/computer.h @@ -1,18 +1,16 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once +#include "metrics.h" +#include "params.h" +#include "segmentstart.h" +#include "simplemetrics.h" #include <vespa/searchlib/fef/iqueryenvironment.h> #include <vespa/searchlib/fef/fieldinfo.h> #include <vespa/searchlib/fef/matchdata.h> #include <vespa/searchlib/fef/phrasesplitter.h> #include <vespa/searchlib/features/queryterm.h> #include <vespa/searchlib/common/allocatedbitvector.h> -#include <string> -#include <vector> -#include "metrics.h" -#include "params.h" -#include "segmentstart.h" -#include "simplemetrics.h" namespace search::features::fieldmatch { @@ -64,8 +62,8 @@ public: * @param fieldInfo The info object of the matched field. * @param params The parameter object for this computer. */ - Computer(const vespalib::string &propertyNamespace, const search::fef::PhraseSplitter &splitter, - const search::fef::FieldInfo &fieldInfo, const Params ¶ms); + Computer(const vespalib::string &propertyNamespace, const fef::PhraseSplitter &splitter, + const fef::FieldInfo &fieldInfo, const Params ¶ms); /** * Resets this object according to the given document id @@ -127,7 +125,7 @@ public: * * @return The query environment. */ - const search::fef::IQueryEnvironment &getQueryEnvironment() const { + const fef::IQueryEnvironment &getQueryEnvironment() const { return _splitter; } @@ -216,7 +214,7 @@ public: * @param The index of the term match to return. * @return The term match. */ - const search::fef::TermFieldMatchData *getQueryTermFieldMatch(int term) const { + const fef::TermFieldMatchData *getQueryTermFieldMatch(int term) const { return _queryTermFieldMatch[term]; } @@ -323,8 +321,8 @@ private: private: - typedef std::shared_ptr<search::BitVector> BitVectorPtr; - typedef std::vector<const search::fef::TermFieldMatchData *> TermFieldMatchDataVector; + typedef std::shared_ptr<BitVector> BitVectorPtr; + typedef std::vector<const fef::TermFieldMatchData *> TermFieldMatchDataVector; struct SegmentData { SegmentData() : segment(), valid(false) {} @@ -335,7 +333,7 @@ private: struct BitVectorData { BitVectorData() : bitvector(0), valid(false) {} - search::AllocatedBitVector bitvector; + AllocatedBitVector bitvector; bool valid; }; diff --git a/searchlib/src/vespa/searchlib/features/fieldmatchfeature.cpp b/searchlib/src/vespa/searchlib/features/fieldmatchfeature.cpp index 7ad9eef0506..94240422106 100644 --- a/searchlib/src/vespa/searchlib/features/fieldmatchfeature.cpp +++ b/searchlib/src/vespa/searchlib/features/fieldmatchfeature.cpp @@ -2,6 +2,7 @@ #include "fieldmatchfeature.h" #include "utils.h" +#include <vespa/searchlib/features/fieldmatch/computer.h> #include <vespa/searchlib/fef/featurenamebuilder.h> #include <vespa/searchlib/fef/indexproperties.h> #include <vespa/searchlib/fef/properties.h> @@ -14,6 +15,24 @@ using CollectionType = FieldInfo::CollectionType; namespace search::features { +/** + * Implements the executor for THE field match feature. + */ +class FieldMatchExecutor : public fef::FeatureExecutor { +private: + fef::PhraseSplitter _splitter; + const fef::FieldInfo & _field; + fieldmatch::Computer _cmp; + + void handle_bind_match_data(const fef::MatchData &md) override; + +public: + FieldMatchExecutor(const fef::IQueryEnvironment & queryEnv, + const fef::FieldInfo & field, + const fieldmatch::Params & params); + void execute(uint32_t docId) override; +}; + FieldMatchExecutor::FieldMatchExecutor(const IQueryEnvironment & queryEnv, const FieldInfo & field, [[maybe_unused]] const fieldmatch::Params & params) : @@ -305,4 +324,11 @@ FieldMatchBlueprint::createExecutor(const IQueryEnvironment & env, vespalib::Sta return stash.create<FieldMatchExecutor>(env, *_field, _params); } +void FieldMatchBlueprint::prepareSharedState(const IQueryEnvironment &env, IObjectStore & store) const { + (void) env; + (void) store; + //TODO WE need too extract the const and costly parts from PhraseSpiltter and Computer + // and initialize it here for later reuse in the multiple search threads. +} + } diff --git a/searchlib/src/vespa/searchlib/features/fieldmatchfeature.h b/searchlib/src/vespa/searchlib/features/fieldmatchfeature.h index bec6ccb2bda..0e5f873005d 100644 --- a/searchlib/src/vespa/searchlib/features/fieldmatchfeature.h +++ b/searchlib/src/vespa/searchlib/features/fieldmatchfeature.h @@ -3,31 +3,11 @@ #pragma once #include <vespa/searchlib/fef/blueprint.h> -#include <vespa/searchlib/features/fieldmatch/computer.h> #include <vespa/searchlib/features/fieldmatch/params.h> namespace search::features { /** - * Implements the executor for THE field match feature. - */ -class FieldMatchExecutor : public fef::FeatureExecutor { -private: - fef::PhraseSplitter _splitter; - const fef::FieldInfo & _field; - fieldmatch::Computer _cmp; - - void handle_bind_match_data(const fef::MatchData &md) override; - -public: - FieldMatchExecutor(const fef::IQueryEnvironment & queryEnv, - const fef::FieldInfo & field, - const fieldmatch::Params & params); - void execute(uint32_t docId) override; -}; - - -/** * Implements the blueprint for THE field match feature. */ class FieldMatchBlueprint : public fef::Blueprint { @@ -46,6 +26,8 @@ public: bool setup(const fef::IIndexEnvironment & env, const fef::ParameterList & params) override; fef::FeatureExecutor &createExecutor(const fef::IQueryEnvironment &env, vespalib::Stash &stash) const override; + + void prepareSharedState(const fef::IQueryEnvironment &queryEnv, fef::IObjectStore &objectStore) const override; }; } diff --git a/searchlib/src/vespa/searchlib/features/nativefieldmatchfeature.cpp b/searchlib/src/vespa/searchlib/features/nativefieldmatchfeature.cpp index 2cdda669dd7..64ae94ddc90 100644 --- a/searchlib/src/vespa/searchlib/features/nativefieldmatchfeature.cpp +++ b/searchlib/src/vespa/searchlib/features/nativefieldmatchfeature.cpp @@ -46,10 +46,11 @@ NativeFieldMatchExecutor::NativeFieldMatchExecutor(const IQueryEnvironment & env _divisor(0), _md(nullptr) { - for (uint32_t i = 0; i < env.getNumTerms(); ++i) { - MyQueryTerm qt(QueryTermFactory::create(env, i)); - if (qt.termData()->getWeight().percent() != 0) // only consider query terms with contribution + QueryTermHelper queryTerms(env); + for (const QueryTerm & qtTmp : queryTerms.terms()) { + if (qtTmp.termData()->getWeight().percent() != 0) // only consider query terms with contribution { + MyQueryTerm qt(qtTmp); typedef search::fef::ITermFieldRangeAdapter FRA; uint32_t totalFieldWeight = 0; for (FRA iter(*qt.termData()); iter.valid(); iter.next()) { @@ -179,4 +180,9 @@ NativeFieldMatchBlueprint::createExecutor(const IQueryEnvironment &env, vespalib } } +void +NativeFieldMatchBlueprint::prepareSharedState(const IQueryEnvironment &queryEnv, IObjectStore &objectStore) const { + QueryTermHelper::lookupAndStoreQueryTerms(queryEnv, objectStore); +} + } diff --git a/searchlib/src/vespa/searchlib/features/nativefieldmatchfeature.h b/searchlib/src/vespa/searchlib/features/nativefieldmatchfeature.h index 6b627b84720..9b132561cd3 100644 --- a/searchlib/src/vespa/searchlib/features/nativefieldmatchfeature.h +++ b/searchlib/src/vespa/searchlib/features/nativefieldmatchfeature.h @@ -110,6 +110,8 @@ public: fef::FeatureExecutor &createExecutor(const fef::IQueryEnvironment & env, vespalib::Stash &stash) const override; const NativeFieldMatchParams & getParams() const { return _params; } + + void prepareSharedState(const fef::IQueryEnvironment &queryEnv, fef::IObjectStore &objectStore) const override; }; } diff --git a/searchlib/src/vespa/searchlib/features/nativeproximityfeature.cpp b/searchlib/src/vespa/searchlib/features/nativeproximityfeature.cpp index 887daa4735d..98fd41aad0e 100644 --- a/searchlib/src/vespa/searchlib/features/nativeproximityfeature.cpp +++ b/searchlib/src/vespa/searchlib/features/nativeproximityfeature.cpp @@ -47,7 +47,6 @@ NativeProximityExecutor::calculateScoreForPair(const TermPair & pair, uint32_t f return score; } - NativeProximityExecutor::NativeProximityExecutor(const IQueryEnvironment & env, const NativeProximityParams & params) : FeatureExecutor(), @@ -56,16 +55,16 @@ NativeProximityExecutor::NativeProximityExecutor(const IQueryEnvironment & env, _totalFieldWeight(0), _md(nullptr) { + QueryTermHelper queryTerms(env); std::map<uint32_t, QueryTermVector> fields; - for (uint32_t i = 0; i < env.getNumTerms(); ++i) { - QueryTerm qt = QueryTermFactory::create(env, i); - + for (const QueryTerm & qt : queryTerms.terms()) { typedef search::fef::ITermFieldRangeAdapter FRA; for (FRA iter(*qt.termData()); iter.valid(); iter.next()) { uint32_t fieldId = iter.get().getFieldId(); if (_params.considerField(fieldId)) { // only consider fields with contribution - qt.fieldHandle(iter.get().getHandle()); - fields[fieldId].push_back(qt); + QueryTerm myQt = qt; + myQt.fieldHandle(iter.get().getHandle()); + fields[fieldId].push_back(myQt); } } } @@ -213,4 +212,9 @@ NativeProximityBlueprint::createExecutor(const IQueryEnvironment &env, vespalib: } +void +NativeProximityBlueprint::prepareSharedState(const IQueryEnvironment &queryEnv, IObjectStore &objectStore) const { + QueryTermHelper::lookupAndStoreQueryTerms(queryEnv, objectStore); +} + } diff --git a/searchlib/src/vespa/searchlib/features/nativeproximityfeature.h b/searchlib/src/vespa/searchlib/features/nativeproximityfeature.h index f2acdf9c593..4241e81a95e 100644 --- a/searchlib/src/vespa/searchlib/features/nativeproximityfeature.h +++ b/searchlib/src/vespa/searchlib/features/nativeproximityfeature.h @@ -3,7 +3,6 @@ #pragma once #include "nativerankfeature.h" -#include "queryterm.h" #include "termdistancecalculator.h" namespace search::features { @@ -95,6 +94,8 @@ public: fef::FeatureExecutor &createExecutor(const fef::IQueryEnvironment &env, vespalib::Stash &stash) const override; const NativeProximityParams & getParams() const { return _params; } + + void prepareSharedState(const fef::IQueryEnvironment &queryEnv, fef::IObjectStore &objectStore) const override; }; } diff --git a/searchlib/src/vespa/searchlib/features/queryterm.cpp b/searchlib/src/vespa/searchlib/features/queryterm.cpp index a6b1a6a8f2a..2da1dedf7d4 100644 --- a/searchlib/src/vespa/searchlib/features/queryterm.cpp +++ b/searchlib/src/vespa/searchlib/features/queryterm.cpp @@ -3,45 +3,66 @@ #include "queryterm.h" #include "utils.h" -using namespace search::fef; using search::feature_t; +using namespace search::fef; namespace search::features { -QueryTerm::QueryTerm() : - _termData(nullptr), - _handle(IllegalHandle), - _significance(0), - _connectedness(0) +QueryTerm +QueryTermFactory::create(const IQueryEnvironment & env, uint32_t termIdx, bool lookupConnectedness) { + const ITermData *termData = env.getTerm(termIdx); + feature_t fallback = util::getSignificance(*termData); + feature_t significance = features::util::lookupSignificance(env, termIdx, fallback); + feature_t connectedness = 0; + if (lookupConnectedness) { + connectedness = util::lookupConnectedness(env, termIdx); + } + return QueryTerm(termData, significance, connectedness); } -QueryTerm::QueryTerm(const ITermData * td, feature_t sig, feature_t con) : - _termData(td), - _handle(IllegalHandle), - _significance(sig), - _connectedness(con) +QueryTermHelper::QueryTermHelper(const IQueryEnvironment &env) + : _fallBack(), + _queryTerms(lookupQueryTerms(env)) { + if (_queryTerms == nullptr) { + _fallBack = createQueryTermvector(env); + _queryTerms = & _fallBack; + } } -QueryTerm -QueryTermFactory::create(const IQueryEnvironment & env, - uint32_t termIdx, - bool lookupSignificance, - bool lookupConnectedness) +namespace { + +using QueryTermVectorWrapper = AnyWrapper<QueryTermVector>; +const vespalib::string QUERY_TERMS_KEY("queryvectorhelper.queryterms"); + +} +const QueryTermVector & +QueryTermHelper::lookupAndStoreQueryTerms(const IQueryEnvironment &env, IObjectStore & store) { - const ITermData *termData = env.getTerm(termIdx); - feature_t significance = 0; - if (lookupSignificance) { - feature_t fallback = util::getSignificance(*termData); - significance = util::lookupSignificance(env, termIdx, fallback); - } - feature_t connectedness = 0; - if (lookupConnectedness) { - connectedness = search::features::util::lookupConnectedness(env, termIdx); + const Anything * obj = store.get(QUERY_TERMS_KEY); + if (obj == nullptr) { + store.add(QUERY_TERMS_KEY, std::make_unique<QueryTermVectorWrapper>(createQueryTermvector(env))); + obj = store.get(QUERY_TERMS_KEY); } - return QueryTerm(termData, significance, connectedness); + return static_cast<const QueryTermVectorWrapper *>(obj)->getValue(); } +const QueryTermVector * +QueryTermHelper::lookupQueryTerms(const IQueryEnvironment & env) +{ + const Anything * obj = env.getObjectStore().get(QUERY_TERMS_KEY); + return (obj != nullptr) ? & static_cast<const QueryTermVectorWrapper *>(obj)->getValue() : nullptr; +} + +QueryTermVector +QueryTermHelper::createQueryTermvector(const IQueryEnvironment &env) { + QueryTermVector vector; + vector.reserve(env.getNumTerms()); + for (size_t i(0); i < env.getNumTerms(); i++) { + vector.emplace_back(QueryTermFactory::create(env, i)); + } + return vector; +} } diff --git a/searchlib/src/vespa/searchlib/features/queryterm.h b/searchlib/src/vespa/searchlib/features/queryterm.h index 75902c33022..d920fe6a386 100644 --- a/searchlib/src/vespa/searchlib/features/queryterm.h +++ b/searchlib/src/vespa/searchlib/features/queryterm.h @@ -3,8 +3,8 @@ #pragma once #include <vespa/searchlib/common/feature.h> -#include <vespa/searchlib/fef/iqueryenvironment.h> -#include <vespa/searchlib/fef/itermdata.h> +#include "vespa/searchlib/fef/iqueryenvironment.h" +#include "vespa/searchlib/fef/itermdata.h" namespace search::features { @@ -15,12 +15,22 @@ namespace search::features { class QueryTerm { private: const fef::ITermData *_termData; - fef::TermFieldHandle _handle; - feature_t _significance; - feature_t _connectedness; + fef::TermFieldHandle _handle; + feature_t _significance; + feature_t _connectedness; public: - QueryTerm(); - QueryTerm(const fef::ITermData *td, feature_t sig = 0, feature_t con = 0); + QueryTerm() + : _termData(nullptr), + _handle(fef::IllegalHandle), + _significance(0), + _connectedness(0) + { } + QueryTerm(const fef::ITermData *td, feature_t sig = 0, feature_t con = 0) + : _termData(td), + _handle(fef::IllegalHandle), + _significance(sig), + _connectedness(con) + { } const fef::ITermData *termData() const { return _termData; } feature_t significance() const { return _significance; } feature_t connectedness() const { return _connectedness; } @@ -36,7 +46,7 @@ public: /** * Convenience typedef for a vector of QueryTerm objects. */ -typedef std::vector<QueryTerm> QueryTermVector; +using QueryTermVector = std::vector<QueryTerm>; /** * This class is a factory for creating QueryTerm objects. @@ -51,10 +61,20 @@ public: * @param lookupSignificance whether we should look up the significance for this term. * @param lookupConnectedness whether we should look up the connectedness this term has with the previous term. */ - static QueryTerm create(const fef::IQueryEnvironment & env, - uint32_t termIndex, - bool lookupSignificance = true, + static QueryTerm create(const fef::IQueryEnvironment & env, uint32_t termIndex, bool lookupConnectedness = false); }; +class QueryTermHelper { +public: + QueryTermHelper(const fef::IQueryEnvironment & env); + const QueryTermVector & terms() const { return *_queryTerms; } + static const QueryTermVector & lookupAndStoreQueryTerms(const fef::IQueryEnvironment & env, fef::IObjectStore & objectStore); +private: + static const QueryTermVector * lookupQueryTerms(const fef::IQueryEnvironment & env); + static QueryTermVector createQueryTermvector(const fef::IQueryEnvironment & env); + QueryTermVector _fallBack; + const QueryTermVector * _queryTerms; +}; + } diff --git a/searchlib/src/vespa/searchlib/features/termdistancecalculator.h b/searchlib/src/vespa/searchlib/features/termdistancecalculator.h index e606e8666e3..09aecddbe28 100644 --- a/searchlib/src/vespa/searchlib/features/termdistancecalculator.h +++ b/searchlib/src/vespa/searchlib/features/termdistancecalculator.h @@ -3,6 +3,7 @@ #pragma once #include "queryterm.h" +#include <cstdint> namespace search::fef { class TermFieldMatchData; diff --git a/searchlib/src/vespa/searchlib/features/termdistancefeature.h b/searchlib/src/vespa/searchlib/features/termdistancefeature.h index bd234589ff8..06f5c243c5d 100644 --- a/searchlib/src/vespa/searchlib/features/termdistancefeature.h +++ b/searchlib/src/vespa/searchlib/features/termdistancefeature.h @@ -24,9 +24,9 @@ struct TermDistanceParams { class TermDistanceExecutor : public fef::FeatureExecutor { private: - QueryTerm _termA; - QueryTerm _termB; - const fef::MatchData *_md; + QueryTerm _termA; + QueryTerm _termB; + const fef::MatchData *_md; virtual void handle_bind_match_data(const fef::MatchData &md) override; diff --git a/searchlib/src/vespa/searchlib/fef/blueprint.h b/searchlib/src/vespa/searchlib/fef/blueprint.h index 81f37f7224d..9bbbbdb1603 100644 --- a/searchlib/src/vespa/searchlib/fef/blueprint.h +++ b/searchlib/src/vespa/searchlib/fef/blueprint.h @@ -136,6 +136,7 @@ protected: static const IAttributeVector * lookupAttribute(const vespalib::string & key, vespalib::stringref attrName, const IQueryEnvironment & env); static vespalib::string createAttributeKey(vespalib::stringref attrName); + public: Blueprint(const Blueprint &) = delete; Blueprint &operator=(const Blueprint &) = delete; diff --git a/searchlib/src/vespa/searchlib/fef/objectstore.h b/searchlib/src/vespa/searchlib/fef/objectstore.h index 2debcd277e9..051bbdd7fac 100644 --- a/searchlib/src/vespa/searchlib/fef/objectstore.h +++ b/searchlib/src/vespa/searchlib/fef/objectstore.h @@ -23,7 +23,7 @@ template<typename T> class AnyWrapper : public Anything { public: - AnyWrapper(T value) : _value(value) { } + AnyWrapper(T value) : _value(std::move(value)) { } const T & getValue() const { return _value; } private: T _value; |