diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2021-03-29 15:07:48 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2021-03-29 16:08:58 +0000 |
commit | 61b9bc1d40610af6205a94ed18686008e991ee18 (patch) | |
tree | edc87306041288be953c1dc5083da99aa75903a2 /searchlib | |
parent | d4712740d1281fa3a2fa945dfd3ea4c2182d663c (diff) |
- Use a LookupKey to further delay data conversion until we know it is necessary.
- GC unused code
Diffstat (limited to 'searchlib')
12 files changed, 168 insertions, 99 deletions
diff --git a/searchlib/src/tests/attribute/bitvector/bitvector_test.cpp b/searchlib/src/tests/attribute/bitvector/bitvector_test.cpp index 3bf16aa3e7e..d965f555b79 100644 --- a/searchlib/src/tests/attribute/bitvector/bitvector_test.cpp +++ b/searchlib/src/tests/attribute/bitvector/bitvector_test.cpp @@ -474,20 +474,16 @@ BitVectorTest::test(BasicType bt, bool filter) { Config cfg(bt, ct); - AttributePtr v = make(cfg, pref, fastSearch, - enableBitVectors, enableOnlyBitVector, filter); + AttributePtr v = make(cfg, pref, fastSearch, enableBitVectors, enableOnlyBitVector, filter); addDocs(v, 1024); VectorType &tv = as<VectorType>(v); populate(tv, 2, 1023, true); SearchContextPtr sc = getSearch<VectorType>(tv, true); - checkSearch(v, std::move(sc), 2, 1022, 205, !enableBitVectors && !filter, - true); + checkSearch(v, std::move(sc), 2, 1022, 205, !enableBitVectors && !filter, true); sc = getSearch<VectorType>(tv, false); - checkSearch(v, std::move(sc), 2, 1022, 205, !enableOnlyBitVector && - !filter, true); - const search::IDocumentWeightAttribute *dwa = - v->asDocumentWeightAttribute(); + checkSearch(v, std::move(sc), 2, 1022, 205, !enableOnlyBitVector && !filter, true); + const search::IDocumentWeightAttribute *dwa = v->asDocumentWeightAttribute(); if (dwa != nullptr) { search::IDocumentWeightAttribute::LookupResult lres = dwa->lookup(getSearchStr<VectorType>(), dwa->get_dictionary_snapshot()); @@ -504,21 +500,16 @@ BitVectorTest::test(BasicType bt, } populate(tv, 2, 973, false); sc = getSearch<VectorType>(tv, true); - checkSearch(v, std::move(sc), 977, 1022, 10, !enableOnlyBitVector && - !filter, true); + checkSearch(v, std::move(sc), 977, 1022, 10, !enableOnlyBitVector &&!filter, true); populate(tv, 2, 973, true); sc = getSearch<VectorType>(tv, true); - checkSearch(v, std::move(sc), 2, 1022, 205, !enableBitVectors && !filter, - true); + checkSearch(v, std::move(sc), 2, 1022, 205, !enableBitVectors && !filter, true); addDocs(v, 15000); sc = getSearch<VectorType>(tv, true); - checkSearch(v, std::move(sc), 2, 1022, 205, !enableOnlyBitVector && - !filter, true); + checkSearch(v, std::move(sc), 2, 1022, 205, !enableOnlyBitVector && !filter, true); populateAll(tv, 10, 15000, true); sc = getSearch<VectorType>(tv, true); - checkSearch(v, std::move(sc), 2, 14999, 14992, - !enableBitVectors && !filter, - false); + checkSearch(v, std::move(sc), 2, 14999, 14992, !enableBitVectors && !filter, false); } diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp index 1e96b9be1d5..1edcd67f5cb 100644 --- a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp @@ -37,6 +37,7 @@ #include <vespa/vespalib/util/regexp.h> #include <vespa/vespalib/util/stringfmt.h> #include <sstream> +#include <charconv> #include <vespa/log/log.h> LOG_SETUP(".searchlib.attribute.attribute_blueprint_factory"); @@ -58,6 +59,7 @@ using search::query::StackDumpCreator; using search::query::StringTerm; using search::query::SubstringTerm; using search::query::SuffixTerm; +using search::query::MultiTerm; using search::queryeval::AndBlueprint; using search::queryeval::AndSearchStrict; using search::queryeval::Blueprint; @@ -81,10 +83,26 @@ using search::tensor::DenseTensorAttribute; using vespalib::geo::ZCurve; using vespalib::make_string; using vespalib::string; +using vespalib::stringref; namespace search { namespace { +class NodeAsKey final : public IDocumentWeightAttribute::LookupKey { +public: + NodeAsKey(const Node & node, vespalib::string & scratchPad) + : _node(node), + _scratchPad(scratchPad) + { } + + stringref asString() const override { + return queryeval::termAsString(_node, _scratchPad); + } + +private: + const Node & _node; + vespalib::string & _scratchPad; +}; //----------------------------------------------------------------------------- /** @@ -312,6 +330,24 @@ make_location_blueprint(const FieldSpec &field, const IAttributeVector &attribut return root; } +class LookupKey : public IDocumentWeightAttribute::LookupKey { +public: + LookupKey(MultiTerm & terms, uint32_t index) : _terms(terms), _index(index) {} + + stringref asString() const override { + return _terms.getAsString(_index).first; + } + + bool asInteger(int64_t &value) const override { + value = _terms.getAsInteger(_index).first; + return true; + } + +private: + const MultiTerm & _terms; + uint32_t _index; +}; + //----------------------------------------------------------------------------- template <typename SearchType> @@ -342,8 +378,8 @@ public: _terms.reserve(size_hint); } - void addTerm(const vespalib::string &term, int32_t weight) { - IDocumentWeightAttribute::LookupResult result = _attr.lookup(term, _dictionary_snapshot); + void addTerm(const IDocumentWeightAttribute::LookupKey & key, int32_t weight) { + IDocumentWeightAttribute::LookupResult result = _attr.lookup(key, _dictionary_snapshot); HitEstimate childEst(result.posting_size, (result.posting_size == 0)); if (!childEst.empty) { if (_estimate.empty) { @@ -422,14 +458,13 @@ public: _terms(), _attr(attr), _dictionary_snapshot(_attr.get_dictionary_snapshot()) - { _weights.reserve(size_hint); _terms.reserve(size_hint); } - void addTerm(const vespalib::string &term, int32_t weight) { - IDocumentWeightAttribute::LookupResult result = _attr.lookup(term, _dictionary_snapshot); + void addTerm(const IDocumentWeightAttribute::LookupKey & key, int32_t weight) { + IDocumentWeightAttribute::LookupResult result = _attr.lookup(key, _dictionary_snapshot); HitEstimate childEst(result.posting_size, (result.posting_size == 0)); if (!childEst.empty) { if (_estimate.empty) { @@ -487,13 +522,14 @@ private: public: DirectAttributeBlueprint(const FieldSpec &field, const vespalib::string & name, const IAttributeVector &iattr, - const IDocumentWeightAttribute &attr, const vespalib::string &term) + const IDocumentWeightAttribute &attr, + const IDocumentWeightAttribute::LookupKey & key) : SimpleLeafBlueprint(field), _attrName(name), _iattr(iattr), _attr(attr), _dictionary_snapshot(_attr.get_dictionary_snapshot()), - _dict_entry(_attr.lookup(term, _dictionary_snapshot)) + _dict_entry(_attr.lookup(key, _dictionary_snapshot)) { setEstimate(HitEstimate(_dict_entry.posting_size, (_dict_entry.posting_size == 0))); } @@ -547,6 +583,7 @@ private: const FieldSpec &_field; const IAttributeVector &_attr; const IDocumentWeightAttribute *_dwa; + vespalib::string _scratchPad; public: CreateBlueprintVisitor(Searchable &searchable, const IRequestContext &requestContext, @@ -554,15 +591,17 @@ public: : CreateBlueprintVisitorHelper(searchable, field, requestContext), _field(field), _attr(attr), - _dwa(attr.asDocumentWeightAttribute()) + _dwa(attr.asDocumentWeightAttribute()), + _scratchPad() { } + ~CreateBlueprintVisitor() override; template <class TermNode> void visitTerm(TermNode &n, bool simple = false) { if (simple && (_dwa != nullptr) && !_field.isFilter() && n.isRanked()) { - vespalib::string term = queryeval::termAsString(n); - setResult(std::make_unique<DirectAttributeBlueprint>(_field, _attr.getName(), _attr, *_dwa, term)); + NodeAsKey key(n, _scratchPad); + setResult(std::make_unique<DirectAttributeBlueprint>(_field, _attr.getName(), _attr, *_dwa, key)); } else { const string stack = StackDumpCreator::create(n); setResult(std::make_unique<AttributeFieldBlueprint>(_field, _attr, stack)); @@ -621,20 +660,12 @@ public: void visit(RegExpTerm & n) override { visitTerm(n); } template <typename WS> - void createDirectWeightedSet(WS *bp, search::query::MultiTerm &n); + void createDirectWeightedSet(WS *bp, MultiTerm &n); template <typename WS> - void createShallowWeightedSet(WS *bp, search::query::MultiTerm &n, const FieldSpec &fs, bool isInteger); + void createShallowWeightedSet(WS *bp, MultiTerm &n, const FieldSpec &fs, bool isInteger); static QueryTermSimple::UP - extractTerm(const query::Node &node, bool isInteger) { - vespalib::string term = queryeval::termAsString(node); - if (isInteger) { - return std::make_unique<QueryTermSimple>(term, QueryTermSimple::Type::WORD); - } - return std::make_unique<QueryTermUCS4>(term, QueryTermSimple::Type::WORD); - } - static QueryTermSimple::UP extractTerm(vespalib::stringref term, bool isInteger) { if (isInteger) { return std::make_unique<QueryTermSimple>(term, QueryTermSimple::Type::WORD); @@ -731,18 +762,17 @@ public: template <typename WS> void -CreateBlueprintVisitor::createDirectWeightedSet(WS *bp, search::query::MultiTerm &n) { +CreateBlueprintVisitor::createDirectWeightedSet(WS *bp, MultiTerm &n) { Blueprint::UP result(bp); for (uint32_t i(0); i < n.getNumTerms(); i++) { - auto term = n.getAsString(i); - bp->addTerm(term.first, term.second.percent()); + bp->addTerm(LookupKey(n, i), n.weight(i).percent()); } setResult(std::move(result)); } template <typename WS> void -CreateBlueprintVisitor::createShallowWeightedSet(WS *bp, search::query::MultiTerm &n, const FieldSpec &fs, bool isInteger) { +CreateBlueprintVisitor::createShallowWeightedSet(WS *bp, MultiTerm &n, const FieldSpec &fs, bool isInteger) { Blueprint::UP result(bp); for (uint32_t i(0); i < n.getNumTerms(); i++) { FieldSpec childfs = bp->getNextChildField(fs); @@ -752,6 +782,8 @@ CreateBlueprintVisitor::createShallowWeightedSet(WS *bp, search::query::MultiTer setResult(std::move(result)); } +CreateBlueprintVisitor::~CreateBlueprintVisitor() = default; + } // namespace //----------------------------------------------------------------------------- diff --git a/searchlib/src/vespa/searchlib/attribute/i_document_weight_attribute.cpp b/searchlib/src/vespa/searchlib/attribute/i_document_weight_attribute.cpp index 12ce1a22209..8852bf3f421 100644 --- a/searchlib/src/vespa/searchlib/attribute/i_document_weight_attribute.cpp +++ b/searchlib/src/vespa/searchlib/attribute/i_document_weight_attribute.cpp @@ -1,3 +1,32 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "i_document_weight_attribute.h" +#include <charconv> + +namespace search { +namespace { +class StringAsKey final : public IDocumentWeightAttribute::LookupKey { +public: + StringAsKey(vespalib::stringref key) + : _key(key) + { } + + vespalib::stringref asString() const override { return _key; } +private: + vespalib::string _key; +}; +} + +bool +IDocumentWeightAttribute::LookupKey::asInteger(int64_t &value) const { + vespalib::stringref str = asString(); + const char *end = str.data() + str.size(); + auto res = std::from_chars(str.data(), end, value); + return res.ptr == end; +} + +IDocumentWeightAttribute::LookupResult +IDocumentWeightAttribute::lookup(vespalib::stringref term, vespalib::datastore::EntryRef dictionary_snapshot) const { + return lookup(StringAsKey(term), dictionary_snapshot); +} +}
\ No newline at end of file diff --git a/searchlib/src/vespa/searchlib/attribute/i_document_weight_attribute.h b/searchlib/src/vespa/searchlib/attribute/i_document_weight_attribute.h index e76fbcb0378..a3b045fdd3f 100644 --- a/searchlib/src/vespa/searchlib/attribute/i_document_weight_attribute.h +++ b/searchlib/src/vespa/searchlib/attribute/i_document_weight_attribute.h @@ -3,17 +3,20 @@ #pragma once #include "postinglisttraits.h" - #include <functional> namespace search { -namespace query { class Node; } - using DocumentWeightIterator = attribute::PostingListTraits<int32_t>::const_iterator; struct IDocumentWeightAttribute { + struct LookupKey { + virtual ~LookupKey() = default; + virtual vespalib::stringref asString() const = 0; + virtual bool asInteger(int64_t &value) const; + }; + struct LookupResult { const vespalib::datastore::EntryRef posting_idx; const uint32_t posting_size; @@ -25,7 +28,8 @@ struct IDocumentWeightAttribute : posting_idx(posting_idx_in), posting_size(posting_size_in), min_weight(min_weight_in), max_weight(max_weight_in), enum_idx(enum_idx_in) {} }; virtual vespalib::datastore::EntryRef get_dictionary_snapshot() const = 0; - virtual LookupResult lookup(const vespalib::string &term, vespalib::datastore::EntryRef dictionary_snapshot) const = 0; + virtual LookupResult lookup(const LookupKey & key, vespalib::datastore::EntryRef dictionary_snapshot) const = 0; + LookupResult lookup(vespalib::stringref term, vespalib::datastore::EntryRef dictionary_snapshot) const; /* * Collect enum indexes (via callback) where folded * (e.g. lowercased) value equals the folded value for enum_idx. diff --git a/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.h b/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.h index c09366cdaea..d8d7e7f902c 100644 --- a/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.h @@ -36,7 +36,7 @@ private: const MultiValueNumericPostingAttribute &self; DocumentWeightAttributeAdapter(const MultiValueNumericPostingAttribute &self_in) : self(self_in) {} vespalib::datastore::EntryRef get_dictionary_snapshot() const override; - LookupResult lookup(const vespalib::string &term, vespalib::datastore::EntryRef dictionary_snapshot) const override; + LookupResult lookup(const LookupKey & key, vespalib::datastore::EntryRef dictionary_snapshot) const override; void collect_folded(vespalib::datastore::EntryRef enum_idx, vespalib::datastore::EntryRef dictionary_snapshot, const std::function<void(vespalib::datastore::EntryRef)>& callback) const override; void create(vespalib::datastore::EntryRef idx, std::vector<DocumentWeightIterator> &dst) const override; DocumentWeightIterator create(vespalib::datastore::EntryRef idx) const override; diff --git a/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.hpp index f91dac630d3..5f0b06a1294 100644 --- a/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.hpp @@ -3,6 +3,7 @@ #pragma once #include "multinumericpostattribute.h" +#include <charconv> namespace search { @@ -92,12 +93,11 @@ MultiValueNumericPostingAttribute<B, M>::DocumentWeightAttributeAdapter::get_dic template <typename B, typename M> IDocumentWeightAttribute::LookupResult -MultiValueNumericPostingAttribute<B, M>::DocumentWeightAttributeAdapter::lookup(const vespalib::string &term, vespalib::datastore::EntryRef dictionary_snapshot) const +MultiValueNumericPostingAttribute<B, M>::DocumentWeightAttributeAdapter::lookup(const LookupKey & key, vespalib::datastore::EntryRef dictionary_snapshot) const { const IEnumStoreDictionary& dictionary = self._enumStore.get_dictionary(); - char *end = nullptr; - int64_t int_term = strtoll(term.c_str(), &end, 10); - if (*end == '\0') { + int64_t int_term; + if (key.asInteger(int_term)) { auto comp = self._enumStore.make_comparator(int_term); auto find_result = dictionary.find_posting_list(comp, dictionary_snapshot); if (find_result.first.valid()) { diff --git a/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.h b/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.h index c324ecdf125..f80d85dadee 100644 --- a/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.h @@ -34,7 +34,7 @@ private: const MultiValueStringPostingAttributeT &self; DocumentWeightAttributeAdapter(const MultiValueStringPostingAttributeT &self_in) : self(self_in) {} vespalib::datastore::EntryRef get_dictionary_snapshot() const override; - LookupResult lookup(const vespalib::string &term, vespalib::datastore::EntryRef dictionary_snapshot) const override; + LookupResult lookup(const LookupKey & key, vespalib::datastore::EntryRef dictionary_snapshot) const override; void collect_folded(vespalib::datastore::EntryRef enum_idx, vespalib::datastore::EntryRef dictionary_snapshot, const std::function<void(vespalib::datastore::EntryRef)>& callback) const override; void create(vespalib::datastore::EntryRef idx, std::vector<DocumentWeightIterator> &dst) const override; DocumentWeightIterator create(vespalib::datastore::EntryRef idx) const override; diff --git a/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.hpp index 7dea95b2e55..817f7630a3a 100644 --- a/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.hpp @@ -108,10 +108,10 @@ MultiValueStringPostingAttributeT<B, T>::DocumentWeightAttributeAdapter::get_dic template <typename B, typename T> IDocumentWeightAttribute::LookupResult -MultiValueStringPostingAttributeT<B, T>::DocumentWeightAttributeAdapter::lookup(const vespalib::string &term, vespalib::datastore::EntryRef dictionary_snapshot) const +MultiValueStringPostingAttributeT<B, T>::DocumentWeightAttributeAdapter::lookup(const LookupKey & key, vespalib::datastore::EntryRef dictionary_snapshot) const { const IEnumStoreDictionary& dictionary = self._enumStore.get_dictionary(); - auto comp = self._enumStore.make_folded_comparator(term.c_str()); + auto comp = self._enumStore.make_folded_comparator(key.asString().data()); auto find_result = dictionary.find_posting_list(comp, dictionary_snapshot); if (find_result.first.valid()) { auto pidx = find_result.second; diff --git a/searchlib/src/vespa/searchlib/query/tree/termnodes.cpp b/searchlib/src/vespa/searchlib/query/tree/termnodes.cpp index ab8431668d8..a6309ce8061 100644 --- a/searchlib/src/vespa/searchlib/query/tree/termnodes.cpp +++ b/searchlib/src/vespa/searchlib/query/tree/termnodes.cpp @@ -51,6 +51,9 @@ public: std::from_chars(v.first.c_str(), v.first.c_str() + v.first.size(), value); return IntegerAndWeight(value, v.second); } + Weight getWeight(uint32_t index) const override { + return _terms[index].second; + } private: std::vector<std::pair<vespalib::string, Weight>> _terms; }; @@ -72,6 +75,9 @@ public: IntegerAndWeight getAsInteger(uint32_t index) const override { return _terms[index]; } + Weight getWeight(uint32_t index) const override { + return _terms[index].second; + } private: std::vector<IntegerAndWeight> _terms; mutable char _scratchPad[24]; diff --git a/searchlib/src/vespa/searchlib/query/tree/termnodes.h b/searchlib/src/vespa/searchlib/query/tree/termnodes.h index 0524405f7f5..00d2257c9cc 100644 --- a/searchlib/src/vespa/searchlib/query/tree/termnodes.h +++ b/searchlib/src/vespa/searchlib/query/tree/termnodes.h @@ -165,12 +165,14 @@ public: virtual void addTerm(int64_t term, Weight weight) = 0; virtual StringAndWeight getAsString(uint32_t index) const = 0; virtual IntegerAndWeight getAsInteger(uint32_t index) const = 0; + virtual Weight getWeight(uint32_t index) const = 0; }; ~MultiTerm() override; void addTerm(vespalib::stringref term, Weight weight); void addTerm(int64_t term, Weight weight); StringAndWeight getAsString(uint32_t index) const { return _terms->getAsString(index); } IntegerAndWeight getAsInteger(uint32_t index) const { return _terms->getAsInteger(index); } + Weight weight(uint32_t index) const { return _terms->getWeight(index); } uint32_t getNumTerms() const { return _num_terms; } protected: MultiTerm(uint32_t num_terms); @@ -182,8 +184,8 @@ private: class WeightedSetTerm : public QueryNodeMixin<WeightedSetTerm, MultiTerm>, public Term { public: WeightedSetTerm(uint32_t num_terms, const vespalib::string &view, int32_t id, Weight weight) - : QueryNodeMixinType(num_terms), - Term(view, id, weight) + : QueryNodeMixinType(num_terms), + Term(view, id, weight) {} virtual ~WeightedSetTerm() = 0; }; @@ -191,8 +193,8 @@ public: class DotProduct : public QueryNodeMixin<DotProduct, MultiTerm>, public Term { public: DotProduct(uint32_t num_terms, const vespalib::string &view, int32_t id, Weight weight) - : QueryNodeMixinType(num_terms), - Term(view, id, weight) + : QueryNodeMixinType(num_terms), + Term(view, id, weight) {} virtual ~DotProduct() = 0; }; @@ -205,11 +207,12 @@ private: public: WandTerm(uint32_t num_terms, const vespalib::string &view, int32_t id, Weight weight, uint32_t targetNumHits, int64_t scoreThreshold, double thresholdBoostFactor) - : QueryNodeMixinType(num_terms), - Term(view, id, weight), - _targetNumHits(targetNumHits), - _scoreThreshold(scoreThreshold), - _thresholdBoostFactor(thresholdBoostFactor) {} + : QueryNodeMixinType(num_terms), + Term(view, id, weight), + _targetNumHits(targetNumHits), + _scoreThreshold(scoreThreshold), + _thresholdBoostFactor(thresholdBoostFactor) + {} virtual ~WandTerm() = 0; uint32_t getTargetNumHits() const { return _targetNumHits; } int64_t getScoreThreshold() const { return _scoreThreshold; } diff --git a/searchlib/src/vespa/searchlib/queryeval/termasstring.cpp b/searchlib/src/vespa/searchlib/queryeval/termasstring.cpp index 7a97110713d..0c881bf32f3 100644 --- a/searchlib/src/vespa/searchlib/queryeval/termasstring.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/termasstring.cpp @@ -38,44 +38,46 @@ using search::query::WandTerm; using search::query::WeakAnd; using search::query::WeightedSetTerm; using vespalib::string; +using vespalib::stringref; namespace search::queryeval { -vespalib::string termAsString(double float_term) { - vespalib::asciistream os; - return (os << float_term).str(); -} +namespace { -vespalib::string termAsString(int64_t int_term) { +stringref +termAsString(const search::query::Range &term, string & scratchPad) { vespalib::asciistream os; - return (os << int_term).str(); + scratchPad = (os << term).str(); + return scratchPad; } -vespalib::string termAsString(const search::query::Range &term) { +stringref +termAsString(const search::query::Location &term, string & scratchPad) { vespalib::asciistream os; - return (os << term).str(); + scratchPad = (os << term).str(); + return scratchPad; } -vespalib::string termAsString(const search::query::Location &term) { - vespalib::asciistream os; - return (os << term).str(); +stringref +termAsString(const string &term, string &) { + return term; } -namespace { struct TermAsStringVisitor : public QueryVisitor { - string term; - bool isSet; + string & _scratchPad; + stringref term; + bool isSet; - TermAsStringVisitor() : term(), isSet(false) {} + TermAsStringVisitor(string & scratchPad) : _scratchPad(scratchPad), term(), isSet(false) {} template <class TermNode> void visitTerm(TermNode &n) { - term = termAsString(n.getTerm()); + term = termAsString(n.getTerm(), _scratchPad); isSet = true; } void illegalVisit() { - term.clear(); + term = stringref(); isSet = false; } @@ -104,15 +106,30 @@ struct TermAsStringVisitor : public QueryVisitor { void visit(PredicateQuery &) override {illegalVisit(); } void visit(NearestNeighborTerm &) override { illegalVisit(); } }; + +void throwFailure(const search::query::Node &term_node) __attribute((noinline)); + +void +throwFailure(const search::query::Node &term_node) { + string err(vespalib::make_string("Trying to convert a non-term node ('%s') to a term string.", typeid(term_node).name())); + LOG(warning, "%s", err.c_str()); + throw vespalib::IllegalArgumentException(err, VESPA_STRLOC); +} + } // namespace -string termAsString(const Node &term_node) { - TermAsStringVisitor visitor; +string +termAsString(const Node &term_node) { + string scratchPad; + return termAsString(term_node, scratchPad); +} + +stringref +termAsString(const search::query::Node &term_node, string & scratchPad) { + TermAsStringVisitor visitor(scratchPad); const_cast<Node &>(term_node).accept(visitor); if (!visitor.isSet) { - vespalib::string err(vespalib::make_string("Trying to convert a non-term node ('%s') to a term string.", typeid(term_node).name())); - LOG(warning, "%s", err.c_str()); - throw vespalib::IllegalArgumentException(err, VESPA_STRLOC); + throwFailure(term_node); } return visitor.term; } diff --git a/searchlib/src/vespa/searchlib/queryeval/termasstring.h b/searchlib/src/vespa/searchlib/queryeval/termasstring.h index c40050f0e2b..8b05bf9eddd 100644 --- a/searchlib/src/vespa/searchlib/queryeval/termasstring.h +++ b/searchlib/src/vespa/searchlib/queryeval/termasstring.h @@ -2,26 +2,13 @@ #pragma once -#include <vespa/searchlib/query/tree/location.h> -#include <vespa/searchlib/query/tree/range.h> -#include <string> +#include <vespa/vespalib/stllike/string.h> namespace search::query { class Node; } namespace search::queryeval { -inline const vespalib::string &termAsString(const vespalib::string &term) { - return term; -} - -vespalib::string termAsString(double float_term); - -vespalib::string termAsString(int64_t int_term); - -vespalib::string termAsString(const search::query::Range &term); - -vespalib::string termAsString(const search::query::Location &term); - vespalib::string termAsString(const search::query::Node &term_node); +vespalib::stringref termAsString(const search::query::Node &term_node, vespalib::string & scratchPad); } |