diff options
author | Tor Egge <Tor.Egge@online.no> | 2022-09-10 21:35:00 +0200 |
---|---|---|
committer | Tor Egge <Tor.Egge@online.no> | 2022-09-10 21:35:00 +0200 |
commit | 9f9cf315337f9df383acf734a3b790d1f5df985e (patch) | |
tree | 97a3018cc7daadea3235a91f66af2b365922f603 /searchsummary | |
parent | 2b533a5bda75247b4cff2754c0d48bfd2909b87c (diff) |
Factor out helper classes for dynamic docsum field writer.
Diffstat (limited to 'searchsummary')
9 files changed, 355 insertions, 254 deletions
diff --git a/searchsummary/src/vespa/searchsummary/docsummary/CMakeLists.txt b/searchsummary/src/vespa/searchsummary/docsummary/CMakeLists.txt index 8070bed8b03..27946336e90 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/CMakeLists.txt +++ b/searchsummary/src/vespa/searchsummary/docsummary/CMakeLists.txt @@ -17,7 +17,10 @@ vespa_add_library(searchsummary_docsummary OBJECT empty_dfw.cpp geoposdfw.cpp getdocsumargs.cpp + juniper_dfw_query_item.cpp + juniper_dfw_term_visitor.cpp juniper_input.cpp + juniper_query_adapter.cpp juniperproperties.cpp keywordextractor.cpp linguisticsannotation.cpp diff --git a/searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp index 74845853fce..591f053d1cb 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp @@ -1,16 +1,11 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "juniperdfw.h" -#include "docsumwriter.h" #include "docsumstate.h" #include "i_docsum_store_document.h" -#include "keywordextractor.h" -#include <vespa/searchlib/parsequery/stackdumpiterator.h> -#include <vespa/searchlib/queryeval/split_float.h> +#include "juniper_query_adapter.h" #include <vespa/vespalib/objects/hexdump.h> #include <vespa/juniper/config.h> -#include <vespa/juniper/queryhandle.h> -#include <vespa/juniper/query_item.h> #include <vespa/juniper/result.h> #include <vespa/vespalib/data/slime/inserter.h> #include <sstream> @@ -20,254 +15,6 @@ LOG_SETUP(".searchlib.docsummary.dynamicteaserdfw"); namespace search::docsummary { -struct ExplicitItemData -{ - vespalib::stringref _index; - int32_t _weight; - - ExplicitItemData() - : _index(), _weight(0) - {} -}; - - - -/** - * This struct is used to point to the traversal state located on - * the stack of the IQuery Traverse method. This is needed because - * the Traverse method is const. - **/ -class JuniperDFWQueryItem : public juniper::QueryItem -{ - search::SimpleQueryStackDumpIterator *_si; - const ExplicitItemData *_data; -public: - JuniperDFWQueryItem() : _si(nullptr), _data(nullptr) {} - ~JuniperDFWQueryItem() override = default; - explicit JuniperDFWQueryItem(search::SimpleQueryStackDumpIterator *si) : _si(si), _data(nullptr) {} - explicit JuniperDFWQueryItem(const ExplicitItemData *data) : _si(nullptr), _data(data) {} - JuniperDFWQueryItem(const QueryItem&) = delete; - JuniperDFWQueryItem& operator= (const QueryItem&) = delete; - - vespalib::stringref get_index() const override; - int get_weight() const override; - juniper::ItemCreator get_creator() const override; -}; - -vespalib::stringref -JuniperDFWQueryItem::get_index() const -{ - return _si != nullptr ? _si->getIndexName() : _data->_index; -} - -int -JuniperDFWQueryItem::get_weight() const -{ - return _si != nullptr ? _si->GetWeight().percent() : _data->_weight; -} - -juniper::ItemCreator -JuniperDFWQueryItem::get_creator() const -{ - return _si != nullptr ? _si->getCreator() : juniper::ItemCreator::CREA_ORIG; -} - -class TermVisitor : public search::fef::IPropertiesVisitor -{ -public: - juniper::IQueryVisitor *_visitor; - JuniperDFWQueryItem _item; - - explicit TermVisitor(juniper::IQueryVisitor *visitor) - : _visitor(visitor), - _item() - {} - void visitProperty(const search::fef::Property::Value &key, const search::fef::Property &values) override; - -}; - -void -TermVisitor::visitProperty(const search::fef::Property::Value &key, const search::fef::Property &values) -{ - ExplicitItemData data; - JuniperDFWQueryItem item(&data); - int index = 0; - int numBlocks = atoi(values.getAt(index++).c_str()); - data._index = key; - - _visitor->VisitAND(&item, numBlocks); - - for (int i = 0; i < numBlocks; i++) { - const search::fef::Property::Value * s = & values.getAt(index++); - if ((*s)[0] == '"') { - s = & values.getAt(index++); - int phraseLen = atoi(s->c_str()); - _visitor->VisitPHRASE(&item, phraseLen); - s = & values.getAt(index++); - while ((*s)[0] != '"') { - _visitor->VisitKeyword(&item, s->c_str(), s->length()); - s = & values.getAt(index++); - } - } else { - _visitor->VisitKeyword(&item, s->c_str(), s->length()); - } - } -} - -class JuniperQueryAdapter : public juniper::IQuery -{ -private: - KeywordExtractor *_kwExtractor; - const vespalib::stringref _buf; - const search::fef::Properties *_highlightTerms; - -public: - JuniperQueryAdapter(const JuniperQueryAdapter&) = delete; - JuniperQueryAdapter operator= (const JuniperQueryAdapter&) = delete; - JuniperQueryAdapter(KeywordExtractor *kwExtractor, vespalib::stringref buf, - const search::fef::Properties *highlightTerms = nullptr) - : _kwExtractor(kwExtractor), _buf(buf), _highlightTerms(highlightTerms) {} - - // TODO: put this functionality into the stack dump iterator - bool SkipItem(search::SimpleQueryStackDumpIterator *iterator) const - { - uint32_t skipCount = iterator->getArity(); - - while (skipCount > 0) { - if (!iterator->next()) - return false; // stack too small - skipCount = skipCount - 1 + iterator->getArity(); - } - return true; - } - - bool Traverse(juniper::IQueryVisitor *v) const override; - - bool UsefulIndex(const juniper::QueryItem* item) const override - { - if (_kwExtractor == nullptr) { - return true; - } - auto index = item->get_index(); - return _kwExtractor->IsLegalIndex(index); - } -}; - -bool -JuniperQueryAdapter::Traverse(juniper::IQueryVisitor *v) const -{ - bool rc = true; - search::SimpleQueryStackDumpIterator iterator(_buf); - JuniperDFWQueryItem item(&iterator); - - if (_highlightTerms->numKeys() > 0) { - v->VisitAND(&item, 2); - } - while (rc && iterator.next()) { - bool isSpecialToken = iterator.hasSpecialTokenFlag(); - switch (iterator.getType()) { - case search::ParseItem::ITEM_OR: - case search::ParseItem::ITEM_WEAK_AND: - case search::ParseItem::ITEM_EQUIV: - case search::ParseItem::ITEM_WORD_ALTERNATIVES: - if (!v->VisitOR(&item, iterator.getArity())) - rc = SkipItem(&iterator); - break; - case search::ParseItem::ITEM_AND: - if (!v->VisitAND(&item, iterator.getArity())) - rc = SkipItem(&iterator); - break; - case search::ParseItem::ITEM_NOT: - if (!v->VisitANDNOT(&item, iterator.getArity())) - rc = SkipItem(&iterator); - break; - case search::ParseItem::ITEM_RANK: - if (!v->VisitRANK(&item, iterator.getArity())) - rc = SkipItem(&iterator); - break; - case search::ParseItem::ITEM_TERM: - case search::ParseItem::ITEM_EXACTSTRINGTERM: - case search::ParseItem::ITEM_PURE_WEIGHTED_STRING: - { - vespalib::stringref term = iterator.getTerm(); - v->VisitKeyword(&item, term.data(), term.size(), false, isSpecialToken); - } - break; - case search::ParseItem::ITEM_NUMTERM: - { - vespalib::string term = iterator.getTerm(); - queryeval::SplitFloat splitter(term); - if (splitter.parts() > 1) { - if (v->VisitPHRASE(&item, splitter.parts())) { - for (size_t i = 0; i < splitter.parts(); ++i) { - v->VisitKeyword(&item, - splitter.getPart(i).c_str(), - splitter.getPart(i).size(), false); - } - } - } else if (splitter.parts() == 1) { - v->VisitKeyword(&item, - splitter.getPart(0).c_str(), - splitter.getPart(0).size(), false); - } else { - v->VisitKeyword(&item, term.c_str(), term.size(), false, true); - } - } - break; - case search::ParseItem::ITEM_PHRASE: - if (!v->VisitPHRASE(&item, iterator.getArity())) - rc = SkipItem(&iterator); - break; - case search::ParseItem::ITEM_PREFIXTERM: - case search::ParseItem::ITEM_SUBSTRINGTERM: - { - vespalib::stringref term = iterator.getTerm(); - v->VisitKeyword(&item, term.data(), term.size(), true, isSpecialToken); - } - break; - case search::ParseItem::ITEM_ANY: - if (!v->VisitANY(&item, iterator.getArity())) - rc = SkipItem(&iterator); - break; - case search::ParseItem::ITEM_NEAR: - if (!v->VisitNEAR(&item, iterator.getArity(),iterator.getNearDistance())) - rc = SkipItem(&iterator); - break; - case search::ParseItem::ITEM_ONEAR: - if (!v->VisitWITHIN(&item, iterator.getArity(),iterator.getNearDistance())) - rc = SkipItem(&iterator); - break; - case search::ParseItem::ITEM_TRUE: - case search::ParseItem::ITEM_FALSE: - break; - // Unhandled items are just ignored by juniper - case search::ParseItem::ITEM_WAND: - case search::ParseItem::ITEM_WEIGHTED_SET: - case search::ParseItem::ITEM_DOT_PRODUCT: - case search::ParseItem::ITEM_PURE_WEIGHTED_LONG: - case search::ParseItem::ITEM_SUFFIXTERM: - case search::ParseItem::ITEM_REGEXP: - case search::ParseItem::ITEM_PREDICATE_QUERY: - case search::ParseItem::ITEM_SAME_ELEMENT: - case search::ParseItem::ITEM_NEAREST_NEIGHBOR: - case search::ParseItem::ITEM_GEO_LOCATION_TERM: - if (!v->VisitOther(&item, iterator.getArity())) { - rc = SkipItem(&iterator); - } - break; - default: - rc = false; - } - } - - if (_highlightTerms->numKeys() > 1) { - v->VisitAND(&item, _highlightTerms->numKeys()); - } - TermVisitor tv(v); - _highlightTerms->visitProperties(tv); - - return rc; -} JuniperDFW::JuniperDFW(const juniper::Juniper * juniper) : _input_field_name(), diff --git a/searchsummary/src/vespa/searchsummary/docsummary/juniper_dfw_explicit_item_data.h b/searchsummary/src/vespa/searchsummary/docsummary/juniper_dfw_explicit_item_data.h new file mode 100644 index 00000000000..aaa342e7d70 --- /dev/null +++ b/searchsummary/src/vespa/searchsummary/docsummary/juniper_dfw_explicit_item_data.h @@ -0,0 +1,23 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/vespalib/stllike/string.h> + +namespace search::docsummary { + +/* + * Explicit values used when JuniperDFWQueryItem doesn't have a query + * stack dump iterator. + */ +struct JuniperDFWExplicitItemData +{ + vespalib::stringref _index; + int32_t _weight; + + JuniperDFWExplicitItemData() + : _index(), _weight(0) + {} +}; + +} diff --git a/searchsummary/src/vespa/searchsummary/docsummary/juniper_dfw_query_item.cpp b/searchsummary/src/vespa/searchsummary/docsummary/juniper_dfw_query_item.cpp new file mode 100644 index 00000000000..589d6eaabfb --- /dev/null +++ b/searchsummary/src/vespa/searchsummary/docsummary/juniper_dfw_query_item.cpp @@ -0,0 +1,27 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "juniper_dfw_query_item.h" +#include "juniper_dfw_explicit_item_data.h" +#include <vespa/searchlib/parsequery/stackdumpiterator.h> + +namespace search::docsummary { + +vespalib::stringref +JuniperDFWQueryItem::get_index() const +{ + return _si != nullptr ? _si->getIndexName() : _data->_index; +} + +int +JuniperDFWQueryItem::get_weight() const +{ + return _si != nullptr ? _si->GetWeight().percent() : _data->_weight; +} + +juniper::ItemCreator +JuniperDFWQueryItem::get_creator() const +{ + return _si != nullptr ? _si->getCreator() : juniper::ItemCreator::CREA_ORIG; +} + +} diff --git a/searchsummary/src/vespa/searchsummary/docsummary/juniper_dfw_query_item.h b/searchsummary/src/vespa/searchsummary/docsummary/juniper_dfw_query_item.h new file mode 100644 index 00000000000..bec71b2e6fe --- /dev/null +++ b/searchsummary/src/vespa/searchsummary/docsummary/juniper_dfw_query_item.h @@ -0,0 +1,35 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/juniper/query_item.h> + +namespace search { class SimpleQueryStackDumpIterator; } + +namespace search::docsummary { + +struct JuniperDFWExplicitItemData; + +/** + * This struct is used to point to the traversal state located on + * the stack of the IQuery Traverse method. This is needed because + * the Traverse method is const. + **/ +class JuniperDFWQueryItem : public juniper::QueryItem +{ + search::SimpleQueryStackDumpIterator *_si; + const JuniperDFWExplicitItemData *_data; +public: + JuniperDFWQueryItem() : _si(nullptr), _data(nullptr) {} + ~JuniperDFWQueryItem() override = default; + explicit JuniperDFWQueryItem(search::SimpleQueryStackDumpIterator *si) : _si(si), _data(nullptr) {} + explicit JuniperDFWQueryItem(const JuniperDFWExplicitItemData *data) : _si(nullptr), _data(data) {} + JuniperDFWQueryItem(const QueryItem&) = delete; + JuniperDFWQueryItem& operator= (const QueryItem&) = delete; + + vespalib::stringref get_index() const override; + int get_weight() const override; + juniper::ItemCreator get_creator() const override; +}; + +} diff --git a/searchsummary/src/vespa/searchsummary/docsummary/juniper_dfw_term_visitor.cpp b/searchsummary/src/vespa/searchsummary/docsummary/juniper_dfw_term_visitor.cpp new file mode 100644 index 00000000000..54db3ed6d0b --- /dev/null +++ b/searchsummary/src/vespa/searchsummary/docsummary/juniper_dfw_term_visitor.cpp @@ -0,0 +1,37 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "juniper_dfw_term_visitor.h" +#include "juniper_dfw_explicit_item_data.h" +#include <vespa/juniper/query.h> + +namespace search::docsummary { + +void +JuniperDFWTermVisitor::visitProperty(const search::fef::Property::Value &key, const search::fef::Property &values) +{ + JuniperDFWExplicitItemData data; + JuniperDFWQueryItem item(&data); + int index = 0; + int numBlocks = atoi(values.getAt(index++).c_str()); + data._index = key; + + _visitor->VisitAND(&item, numBlocks); + + for (int i = 0; i < numBlocks; i++) { + const search::fef::Property::Value * s = & values.getAt(index++); + if ((*s)[0] == '"') { + s = & values.getAt(index++); + int phraseLen = atoi(s->c_str()); + _visitor->VisitPHRASE(&item, phraseLen); + s = & values.getAt(index++); + while ((*s)[0] != '"') { + _visitor->VisitKeyword(&item, s->c_str(), s->length()); + s = & values.getAt(index++); + } + } else { + _visitor->VisitKeyword(&item, s->c_str(), s->length()); + } + } +} + +} diff --git a/searchsummary/src/vespa/searchsummary/docsummary/juniper_dfw_term_visitor.h b/searchsummary/src/vespa/searchsummary/docsummary/juniper_dfw_term_visitor.h new file mode 100644 index 00000000000..4b8b3dd8e7b --- /dev/null +++ b/searchsummary/src/vespa/searchsummary/docsummary/juniper_dfw_term_visitor.h @@ -0,0 +1,29 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include "juniper_dfw_query_item.h" +#include <vespa/searchlib/fef/properties.h> + +namespace juniper { class IQueryVisitor; } + +namespace search::docsummary { + +/* + * Visitor used by juniper query adapter to visit properties describing + * terms to highlight. + */ +class JuniperDFWTermVisitor : public search::fef::IPropertiesVisitor +{ +public: + juniper::IQueryVisitor *_visitor; + JuniperDFWQueryItem _item; + + explicit JuniperDFWTermVisitor(juniper::IQueryVisitor *visitor) + : _visitor(visitor), + _item() + {} + void visitProperty(const search::fef::Property::Value &key, const search::fef::Property &values) override; +}; + +} diff --git a/searchsummary/src/vespa/searchsummary/docsummary/juniper_query_adapter.cpp b/searchsummary/src/vespa/searchsummary/docsummary/juniper_query_adapter.cpp new file mode 100644 index 00000000000..814fe0aafe4 --- /dev/null +++ b/searchsummary/src/vespa/searchsummary/docsummary/juniper_query_adapter.cpp @@ -0,0 +1,163 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "juniper_query_adapter.h" +#include "juniper_dfw_query_item.h" +#include "juniper_dfw_term_visitor.h" +#include "keywordextractor.h" +#include <vespa/searchlib/fef/properties.h> +#include <vespa/searchlib/parsequery/stackdumpiterator.h> +#include <vespa/searchlib/queryeval/split_float.h> + +namespace search::docsummary { + +JuniperQueryAdapter::JuniperQueryAdapter(KeywordExtractor *kwExtractor, vespalib::stringref buf, + const search::fef::Properties *highlightTerms) + : _kwExtractor(kwExtractor), + _buf(buf), + _highlightTerms(highlightTerms) +{ +} + +JuniperQueryAdapter::~JuniperQueryAdapter() = default; + +// TODO: put this functionality into the stack dump iterator +bool +JuniperQueryAdapter::SkipItem(search::SimpleQueryStackDumpIterator *iterator) const +{ + uint32_t skipCount = iterator->getArity(); + + while (skipCount > 0) { + if (!iterator->next()) + return false; // stack too small + skipCount = skipCount - 1 + iterator->getArity(); + } + return true; +} + +bool +JuniperQueryAdapter::Traverse(juniper::IQueryVisitor *v) const +{ + bool rc = true; + search::SimpleQueryStackDumpIterator iterator(_buf); + JuniperDFWQueryItem item(&iterator); + + if (_highlightTerms->numKeys() > 0) { + v->VisitAND(&item, 2); + } + while (rc && iterator.next()) { + bool isSpecialToken = iterator.hasSpecialTokenFlag(); + switch (iterator.getType()) { + case search::ParseItem::ITEM_OR: + case search::ParseItem::ITEM_WEAK_AND: + case search::ParseItem::ITEM_EQUIV: + case search::ParseItem::ITEM_WORD_ALTERNATIVES: + if (!v->VisitOR(&item, iterator.getArity())) + rc = SkipItem(&iterator); + break; + case search::ParseItem::ITEM_AND: + if (!v->VisitAND(&item, iterator.getArity())) + rc = SkipItem(&iterator); + break; + case search::ParseItem::ITEM_NOT: + if (!v->VisitANDNOT(&item, iterator.getArity())) + rc = SkipItem(&iterator); + break; + case search::ParseItem::ITEM_RANK: + if (!v->VisitRANK(&item, iterator.getArity())) + rc = SkipItem(&iterator); + break; + case search::ParseItem::ITEM_TERM: + case search::ParseItem::ITEM_EXACTSTRINGTERM: + case search::ParseItem::ITEM_PURE_WEIGHTED_STRING: + { + vespalib::stringref term = iterator.getTerm(); + v->VisitKeyword(&item, term.data(), term.size(), false, isSpecialToken); + } + break; + case search::ParseItem::ITEM_NUMTERM: + { + vespalib::string term = iterator.getTerm(); + queryeval::SplitFloat splitter(term); + if (splitter.parts() > 1) { + if (v->VisitPHRASE(&item, splitter.parts())) { + for (size_t i = 0; i < splitter.parts(); ++i) { + v->VisitKeyword(&item, + splitter.getPart(i).c_str(), + splitter.getPart(i).size(), false); + } + } + } else if (splitter.parts() == 1) { + v->VisitKeyword(&item, + splitter.getPart(0).c_str(), + splitter.getPart(0).size(), false); + } else { + v->VisitKeyword(&item, term.c_str(), term.size(), false, true); + } + } + break; + case search::ParseItem::ITEM_PHRASE: + if (!v->VisitPHRASE(&item, iterator.getArity())) + rc = SkipItem(&iterator); + break; + case search::ParseItem::ITEM_PREFIXTERM: + case search::ParseItem::ITEM_SUBSTRINGTERM: + { + vespalib::stringref term = iterator.getTerm(); + v->VisitKeyword(&item, term.data(), term.size(), true, isSpecialToken); + } + break; + case search::ParseItem::ITEM_ANY: + if (!v->VisitANY(&item, iterator.getArity())) + rc = SkipItem(&iterator); + break; + case search::ParseItem::ITEM_NEAR: + if (!v->VisitNEAR(&item, iterator.getArity(),iterator.getNearDistance())) + rc = SkipItem(&iterator); + break; + case search::ParseItem::ITEM_ONEAR: + if (!v->VisitWITHIN(&item, iterator.getArity(),iterator.getNearDistance())) + rc = SkipItem(&iterator); + break; + case search::ParseItem::ITEM_TRUE: + case search::ParseItem::ITEM_FALSE: + break; + // Unhandled items are just ignored by juniper + case search::ParseItem::ITEM_WAND: + case search::ParseItem::ITEM_WEIGHTED_SET: + case search::ParseItem::ITEM_DOT_PRODUCT: + case search::ParseItem::ITEM_PURE_WEIGHTED_LONG: + case search::ParseItem::ITEM_SUFFIXTERM: + case search::ParseItem::ITEM_REGEXP: + case search::ParseItem::ITEM_PREDICATE_QUERY: + case search::ParseItem::ITEM_SAME_ELEMENT: + case search::ParseItem::ITEM_NEAREST_NEIGHBOR: + case search::ParseItem::ITEM_GEO_LOCATION_TERM: + if (!v->VisitOther(&item, iterator.getArity())) { + rc = SkipItem(&iterator); + } + break; + default: + rc = false; + } + } + + if (_highlightTerms->numKeys() > 1) { + v->VisitAND(&item, _highlightTerms->numKeys()); + } + JuniperDFWTermVisitor tv(v); + _highlightTerms->visitProperties(tv); + + return rc; +} + +bool +JuniperQueryAdapter::UsefulIndex(const juniper::QueryItem* item) const +{ + if (_kwExtractor == nullptr) { + return true; + } + auto index = item->get_index(); + return _kwExtractor->IsLegalIndex(index); +} + +} diff --git a/searchsummary/src/vespa/searchsummary/docsummary/juniper_query_adapter.h b/searchsummary/src/vespa/searchsummary/docsummary/juniper_query_adapter.h new file mode 100644 index 00000000000..18886ca2007 --- /dev/null +++ b/searchsummary/src/vespa/searchsummary/docsummary/juniper_query_adapter.h @@ -0,0 +1,37 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/juniper/query.h> +#include <vespa/vespalib/stllike/string.h> + +namespace search { class SimpleQueryStackDumpIterator; } +namespace search::fef { class Properties; } + +namespace search::docsummary { + +class KeywordExtractor; + +/* + * Class implementing an adapter used by juniper to examine the current + * query. + */ +class JuniperQueryAdapter : public juniper::IQuery +{ +private: + KeywordExtractor *_kwExtractor; + const vespalib::stringref _buf; + const search::fef::Properties *_highlightTerms; + +public: + JuniperQueryAdapter(const JuniperQueryAdapter&) = delete; + JuniperQueryAdapter operator= (const JuniperQueryAdapter&) = delete; + JuniperQueryAdapter(KeywordExtractor *kwExtractor, vespalib::stringref buf, + const search::fef::Properties *highlightTerms = nullptr); + ~JuniperQueryAdapter() override; + bool SkipItem(search::SimpleQueryStackDumpIterator *iterator) const; + bool Traverse(juniper::IQueryVisitor *v) const override; + bool UsefulIndex(const juniper::QueryItem* item) const override; +}; + +} |