diff options
author | Tor Egge <Tor.Egge@online.no> | 2022-03-30 19:47:52 +0200 |
---|---|---|
committer | Tor Egge <Tor.Egge@online.no> | 2022-03-30 19:47:52 +0200 |
commit | 5e32acd8ee6f027ae21ef902d4525556ed775bc9 (patch) | |
tree | 2540d01f77821d865b839cadd43346f712fe1711 /searchlib/src | |
parent | 76ef40f11cbb25e5117f9ddfcec5260bc19c13fa (diff) |
Factor out MultiNumericArraySearchContext and MultiNumericWeightedSetSearchContext from MultiValueNumericAttribute.
Diffstat (limited to 'searchlib/src')
11 files changed, 278 insertions, 175 deletions
diff --git a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt index 4f4d892d887..bbd3a03a983 100644 --- a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt @@ -64,6 +64,8 @@ vespa_add_library(searchlib_attribute OBJECT loadedenumvalue.cpp loadednumericvalue.cpp loadedvalue.cpp + multi_numeric_array_search_context.cpp + multi_numeric_weighted_set_search_context.cpp multi_value_mapping.cpp multi_value_mapping_base.cpp multienumattribute.cpp diff --git a/searchlib/src/vespa/searchlib/attribute/flagattribute.cpp b/searchlib/src/vespa/searchlib/attribute/flagattribute.cpp index cfa70beeefc..f6139c28d65 100644 --- a/searchlib/src/vespa/searchlib/attribute/flagattribute.cpp +++ b/searchlib/src/vespa/searchlib/attribute/flagattribute.cpp @@ -56,7 +56,7 @@ template <typename B> std::unique_ptr<attribute::SearchContext> FlagAttributeT<B>::getSearch(QueryTermSimple::UP qTerm, const attribute::SearchContextParams &) const { - return std::make_unique<SearchContext>(std::move(qTerm), *this); + return std::make_unique<SearchContext>(std::move(qTerm), *this, this->_mvMapping); } template <typename B> @@ -233,9 +233,9 @@ FlagAttributeT<B>::removeOldGenerations(vespalib::GenerationHandler::generation_ } template <typename B> -FlagAttributeT<B>::SearchContext::SearchContext(QueryTermSimple::UP qTerm, const FlagAttributeT<B> & toBeSearched) : - BaseSC(std::move(qTerm), toBeSearched), - _zeroHits(false) +FlagAttributeT<B>::SearchContext::SearchContext(QueryTermSimple::UP qTerm, const FlagAttributeT<B> & toBeSearched, const MvMapping& mv_mapping) + : BaseSC(std::move(qTerm), toBeSearched, mv_mapping), + _zeroHits(false) { } @@ -243,10 +243,10 @@ template <typename B> SearchIterator::UP FlagAttributeT<B>::SearchContext::createIterator(fef::TermFieldMatchData * matchData, bool strict) { - if (valid()) { - if (_low == _high) { - const Attribute & attr(static_cast<const Attribute &>(attribute())); - const BitVector * bv(attr.getBitVector(_low)); + if (this->valid()) { + if (this->_low == this->_high) { + const Attribute & attr(static_cast<const Attribute &>(this->attribute())); + const BitVector * bv(attr.getBitVector(this->_low)); if (bv != nullptr) { return BitVectorIterator::create(bv, attr.getCommittedDocIdLimit(), *matchData, strict); } else { diff --git a/searchlib/src/vespa/searchlib/attribute/flagattribute.h b/searchlib/src/vespa/searchlib/attribute/flagattribute.h index cdf1c83e41b..63806d7172f 100644 --- a/searchlib/src/vespa/searchlib/attribute/flagattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/flagattribute.h @@ -2,6 +2,7 @@ #pragma once #include "multinumericattribute.h" +#include "multi_numeric_array_search_context.h" namespace search { @@ -14,11 +15,12 @@ public: FlagAttributeT(const vespalib::string & baseFileName, const AttributeVector::Config & cfg); private: typedef AttributeVector::DocId DocId; - typedef FlagBaseImpl::ArraySearchContext BaseSC; + using BaseSC = attribute::MultiNumericArraySearchContext<typename B::BaseType, typename B::WType>; class SearchContext : public BaseSC { public: typedef FlagAttributeT<B> Attribute; - SearchContext(std::unique_ptr<QueryTermSimple> qTerm, const FlagAttributeT<B> & toBeSearched); + using MvMapping = attribute::MultiValueMapping<typename B::WType>; + SearchContext(std::unique_ptr<QueryTermSimple> qTerm, const FlagAttributeT<B> & toBeSearched, const MvMapping& mv_mapping); std::unique_ptr<queryeval::SearchIterator> createIterator(fef::TermFieldMatchData * matchData, bool strict) override; diff --git a/searchlib/src/vespa/searchlib/attribute/multi_numeric_array_search_context.cpp b/searchlib/src/vespa/searchlib/attribute/multi_numeric_array_search_context.cpp new file mode 100644 index 00000000000..401670b28cf --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_array_search_context.cpp @@ -0,0 +1,17 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "multi_numeric_array_search_context.hpp" +#include <vespa/searchcommon/attribute/multivalue.h> + +using search::multivalue::Value; + +namespace search::attribute { + +template class MultiNumericArraySearchContext<int8_t, Value<int8_t>>; +template class MultiNumericArraySearchContext<int16_t, Value<int16_t>>; +template class MultiNumericArraySearchContext<int32_t, Value<int32_t>>; +template class MultiNumericArraySearchContext<int64_t, Value<int64_t>>; +template class MultiNumericArraySearchContext<float, Value<float>>; +template class MultiNumericArraySearchContext<double, Value<double>>; + +} diff --git a/searchlib/src/vespa/searchlib/attribute/multi_numeric_array_search_context.h b/searchlib/src/vespa/searchlib/attribute/multi_numeric_array_search_context.h new file mode 100644 index 00000000000..59067974129 --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_array_search_context.h @@ -0,0 +1,62 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include "search_context.h" +#include "multi_value_mapping.h" +#include "numeric_range_matcher.h" + +namespace search::attribute { + +/* + * MultiNumericArraySearchContext handles the creation of search iterators for + * a query term on a multi value numeric array attribute vector. + */ +template <typename T, typename M> +class MultiNumericArraySearchContext : public NumericRangeMatcher<T>, public SearchContext +{ +private: + const MultiValueMapping<M>& _mv_mapping; + + int32_t onFind(DocId docId, int32_t elemId, int32_t& weight) const override final { + return find(docId, elemId, weight); + } + + int32_t onFind(DocId docId, int32_t elemId) const override final { + return find(docId, elemId); + } + +protected: + bool valid() const override; + +public: + MultiNumericArraySearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const MultiValueMapping<M>& mv_mapping); + int32_t find(DocId doc, int32_t elemId, int32_t & weight) const { + auto values(_mv_mapping.get(doc)); + for (uint32_t i(elemId); i < values.size(); i++) { + if (this->match(values[i].value())) { + weight = 1; + return i; + } + } + weight = 0; + return -1; + } + + int32_t find(DocId doc, int32_t elemId) const { + auto values(_mv_mapping.get(doc)); + for (uint32_t i(elemId); i < values.size(); i++) { + if (this->match(values[i].value())) { + return i; + } + } + return -1; + } + + Int64Range getAsIntegerTerm() const override; + + std::unique_ptr<queryeval::SearchIterator> + createFilterIterator(fef::TermFieldMatchData* matchData, bool strict) override; +}; + +} diff --git a/searchlib/src/vespa/searchlib/attribute/multi_numeric_array_search_context.hpp b/searchlib/src/vespa/searchlib/attribute/multi_numeric_array_search_context.hpp new file mode 100644 index 00000000000..0331277e05d --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_array_search_context.hpp @@ -0,0 +1,51 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include "multi_numeric_array_search_context.h" +#include "attributeiterators.hpp" +#include "multi_value_mapping.h" +#include <vespa/searchlib/queryeval/emptysearch.h> + +namespace search::attribute { + +template <typename T, typename M> +bool +MultiNumericArraySearchContext<T, M>::valid() const +{ + return this->isValid(); +} + +template <typename T, typename M> +MultiNumericArraySearchContext<T, M>::MultiNumericArraySearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const MultiValueMapping<M>& mv_mapping) + : attribute::NumericRangeMatcher<T>(*qTerm), + attribute::SearchContext(toBeSearched), + _mv_mapping(mv_mapping) +{ +} + +template <typename T, typename M> +Int64Range +MultiNumericArraySearchContext<T, M>::getAsIntegerTerm() const +{ + return this->getRange(); +} + +template <typename T, typename M> +std::unique_ptr<queryeval::SearchIterator> +MultiNumericArraySearchContext<T, M>::createFilterIterator(fef::TermFieldMatchData* matchData, bool strict) +{ + if (!valid()) { + return std::make_unique<queryeval::EmptySearch>(); + } + if (getIsFilter()) { + return strict + ? std::make_unique<FilterAttributeIteratorStrict<MultiNumericArraySearchContext<T, M>>>(*this, matchData) + : std::make_unique<FilterAttributeIteratorT<MultiNumericArraySearchContext<T, M>>>(*this, matchData); + } + return strict + ? std::make_unique<AttributeIteratorStrict<MultiNumericArraySearchContext<T, M>>>(*this, matchData) + : std::make_unique<AttributeIteratorT<MultiNumericArraySearchContext<T, M>>>(*this, matchData); +} + +} diff --git a/searchlib/src/vespa/searchlib/attribute/multi_numeric_weighted_set_search_context.cpp b/searchlib/src/vespa/searchlib/attribute/multi_numeric_weighted_set_search_context.cpp new file mode 100644 index 00000000000..dc754e8c7b3 --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_weighted_set_search_context.cpp @@ -0,0 +1,17 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "multi_numeric_weighted_set_search_context.hpp" +#include <vespa/searchcommon/attribute/multivalue.h> + +using search::multivalue::WeightedValue; + +namespace search::attribute { + +template class MultiNumericWeightedSetSearchContext<int8_t, WeightedValue<int8_t>>; +template class MultiNumericWeightedSetSearchContext<int16_t, WeightedValue<int16_t>>; +template class MultiNumericWeightedSetSearchContext<int32_t, WeightedValue<int32_t>>; +template class MultiNumericWeightedSetSearchContext<int64_t, WeightedValue<int64_t>>; +template class MultiNumericWeightedSetSearchContext<float, WeightedValue<float>>; +template class MultiNumericWeightedSetSearchContext<double, WeightedValue<double>>; + +} diff --git a/searchlib/src/vespa/searchlib/attribute/multi_numeric_weighted_set_search_context.h b/searchlib/src/vespa/searchlib/attribute/multi_numeric_weighted_set_search_context.h new file mode 100644 index 00000000000..aa643f4bed3 --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_weighted_set_search_context.h @@ -0,0 +1,61 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include "search_context.h" +#include "multi_value_mapping.h" +#include "numeric_range_matcher.h" + +namespace search::attribute { + +/* + * MultiNumericWeightedSearchContext handles the creation of search iterators for + * a query term on a multi value numeric weighted set attribute vector. + */ +template <typename T, typename M> +class MultiNumericWeightedSetSearchContext final : public NumericRangeMatcher<T>, public SearchContext +{ +private: + const MultiValueMapping<M>& _mv_mapping; + + int32_t onFind(DocId docId, int32_t elemId, int32_t& weight) const override { + return find(docId, elemId, weight); + } + + int32_t onFind(DocId docId, int32_t elemId) const override { + return find(docId, elemId); + } + + bool valid() const override; + +public: + MultiNumericWeightedSetSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const MultiValueMapping<M>& mv_mapping); + + Int64Range getAsIntegerTerm() const override; + + int32_t find(DocId doc, int32_t elemId, int32_t & weight) const { + auto values(_mv_mapping.get(doc)); + for (uint32_t i(elemId); i < values.size(); i++) { + if (this->match(values[i].value())) { + weight = values[i].weight(); + return i; + } + } + return -1; + } + + int32_t find(DocId doc, int32_t elemId) const { + auto values(_mv_mapping.get(doc)); + for (uint32_t i(elemId); i < values.size(); i++) { + if (this->match(values[i].value())) { + return i; + } + } + return -1; + } + + std::unique_ptr<queryeval::SearchIterator> + createFilterIterator(fef::TermFieldMatchData* matchData, bool strict) override; +}; + +} diff --git a/searchlib/src/vespa/searchlib/attribute/multi_numeric_weighted_set_search_context.hpp b/searchlib/src/vespa/searchlib/attribute/multi_numeric_weighted_set_search_context.hpp new file mode 100644 index 00000000000..ffb761cfe41 --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_weighted_set_search_context.hpp @@ -0,0 +1,51 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include "multi_numeric_weighted_set_search_context.h" +#include "attributeiterators.hpp" +#include "multi_value_mapping.h" +#include <vespa/searchlib/queryeval/emptysearch.h> + +namespace search::attribute { + +template <typename T, typename M> +bool +MultiNumericWeightedSetSearchContext<T, M>::valid() const +{ + return this->isValid(); +} + +template <typename T, typename M> +MultiNumericWeightedSetSearchContext<T, M>::MultiNumericWeightedSetSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const MultiValueMapping<M>& mv_mapping) + : attribute::NumericRangeMatcher<T>(*qTerm), + attribute::SearchContext(toBeSearched), + _mv_mapping(mv_mapping) +{ +} + +template <typename T, typename M> +Int64Range +MultiNumericWeightedSetSearchContext<T, M>::getAsIntegerTerm() const +{ + return this->getRange(); +} + +template <typename T, typename M> +std::unique_ptr<queryeval::SearchIterator> +MultiNumericWeightedSetSearchContext<T, M>::createFilterIterator(fef::TermFieldMatchData* matchData, bool strict) +{ + if (!valid()) { + return std::make_unique<queryeval::EmptySearch>(); + } + if (getIsFilter()) { + return strict + ? std::make_unique<FilterAttributeIteratorStrict<MultiNumericWeightedSetSearchContext<T, M>>>(*this, matchData) + : std::make_unique<FilterAttributeIteratorT<MultiNumericWeightedSetSearchContext<T, M>>>(*this, matchData); + } + return strict + ? std::make_unique<AttributeIteratorStrict<MultiNumericWeightedSetSearchContext<T, M>>>(*this, matchData) + : std::make_unique<AttributeIteratorT<MultiNumericWeightedSetSearchContext<T, M>>>(*this, matchData); +} + +} diff --git a/searchlib/src/vespa/searchlib/attribute/multinumericattribute.h b/searchlib/src/vespa/searchlib/attribute/multinumericattribute.h index 3d579f4aded..90345c50742 100644 --- a/searchlib/src/vespa/searchlib/attribute/multinumericattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/multinumericattribute.h @@ -5,7 +5,6 @@ #include "integerbase.h" #include "floatbase.h" #include "multivalueattribute.h" -#include "numeric_range_matcher.h" #include "search_context.h" #include <limits> @@ -58,103 +57,6 @@ public: uint32_t getRawValues(DocId doc, const WType * & values) const final override { return get(doc, values); } - /* - * Specialization of SearchContext for weighted set type - */ - class SetSearchContext final : public attribute::NumericRangeMatcher<T>, public attribute::SearchContext - { - private: - const MultiValueNumericAttribute<B, M> & _toBeSearched; - - int32_t onFind(DocId docId, int32_t elemId, int32_t & weight) const override { - return find(docId, elemId, weight); - } - - int32_t onFind(DocId docId, int32_t elemId) const override { - return find(docId, elemId); - } - - bool valid() const override; - - public: - SetSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const NumericAttribute & toBeSearched); - - Int64Range getAsIntegerTerm() const override; - - int32_t find(DocId doc, int32_t elemId, int32_t & weight) const { - MultiValueArrayRef values(_toBeSearched._mvMapping.get(doc)); - for (uint32_t i(elemId); i < values.size(); i++) { - if (this->match(values[i].value())) { - weight = values[i].weight(); - return i; - } - } - return -1; - } - - int32_t find(DocId doc, int32_t elemId) const { - MultiValueArrayRef values(_toBeSearched._mvMapping.get(doc)); - for (uint32_t i(elemId); i < values.size(); i++) { - if (this->match(values[i].value())) { - return i; - } - } - return -1; - } - - std::unique_ptr<queryeval::SearchIterator> - createFilterIterator(fef::TermFieldMatchData * matchData, bool strict) override; - }; - - /* - * Specialization of SearchContext for array type - */ - class ArraySearchContext : public attribute::NumericRangeMatcher<T>, public attribute::SearchContext - { - private: - const MultiValueNumericAttribute<B, M> & _toBeSearched; - - int32_t onFind(DocId docId, int32_t elemId, int32_t & weight) const override final { - return find(docId, elemId, weight); - } - - int32_t onFind(DocId docId, int32_t elemId) const override final { - return find(docId, elemId); - } - - protected: - bool valid() const override; - - public: - ArraySearchContext(std::unique_ptr<QueryTermSimple> qTerm, const NumericAttribute & toBeSearched); - int32_t find(DocId doc, int32_t elemId, int32_t & weight) const { - MultiValueArrayRef values(_toBeSearched._mvMapping.get(doc)); - for (uint32_t i(elemId); i < values.size(); i++) { - if (this->match(values[i].value())) { - weight = 1; - return i; - } - } - weight = 0; - - return -1; - } - - int32_t find(DocId doc, int32_t elemId) const { - MultiValueArrayRef values(_toBeSearched._mvMapping.get(doc)); - for (uint32_t i(elemId); i < values.size(); i++) { - if (this->match(values[i].value())) { - return i; - } - } - return -1; - } - - Int64Range getAsIntegerTerm() const override; - - std::unique_ptr<queryeval::SearchIterator> - createFilterIterator(fef::TermFieldMatchData * matchData, bool strict) override; - }; MultiValueNumericAttribute(const vespalib::string & baseFileName, const AttributeVector::Config & c = AttributeVector::Config(AttributeVector::BasicType::fromType(T()), diff --git a/searchlib/src/vespa/searchlib/attribute/multinumericattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multinumericattribute.hpp index 4664c657096..be5932ef963 100644 --- a/searchlib/src/vespa/searchlib/attribute/multinumericattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/multinumericattribute.hpp @@ -6,6 +6,8 @@ #include "attributevector.hpp" #include "attributeiterators.hpp" #include "multinumericattributesaver.h" +#include "multi_numeric_array_search_context.h" +#include "multi_numeric_weighted_set_search_context.h" #include "load_utils.h" #include "primitivereader.h" #include <vespa/searchlib/query/query_term_simple.h> @@ -170,10 +172,10 @@ MultiValueNumericAttribute<B, M>::getSearch(QueryTermSimple::UP qTerm, const attribute::SearchContextParams & params) const { (void) params; - if (this->hasArrayType()) { - return std::make_unique<ArraySearchContext>(std::move(qTerm), *this); + if constexpr (!M::_hasWeight) { + return std::make_unique<attribute::MultiNumericArraySearchContext<T, M>>(std::move(qTerm), *this, this->_mvMapping); } else { - return std::make_unique<SetSearchContext>(std::move(qTerm), *this); + return std::make_unique<attribute::MultiNumericWeightedSetSearchContext<T, M>>(std::move(qTerm), *this, this->_mvMapping); } } @@ -187,68 +189,4 @@ MultiValueNumericAttribute<B, M>::onInitSave(vespalib::stringref fileName) (std::move(guard), this->createAttributeHeader(fileName), this->_mvMapping); } -template <typename B, typename M> -bool MultiValueNumericAttribute<B, M>::SetSearchContext::valid() const { return this->isValid(); } - -template <typename B, typename M> -MultiValueNumericAttribute<B, M>::SetSearchContext::SetSearchContext(QueryTermSimple::UP qTerm, const NumericAttribute & toBeSearched) : - attribute::NumericRangeMatcher<T>(*qTerm), - attribute::SearchContext(toBeSearched), - _toBeSearched(static_cast<const MultiValueNumericAttribute<B, M> &>(toBeSearched)) -{ } - -template <typename B, typename M> -Int64Range MultiValueNumericAttribute<B, M>::SetSearchContext::getAsIntegerTerm() const { - return this->getRange(); -} - -template <typename B, typename M> -std::unique_ptr<queryeval::SearchIterator> -MultiValueNumericAttribute<B, M>::SetSearchContext::createFilterIterator(fef::TermFieldMatchData * matchData, bool strict) -{ - if (!valid()) { - return std::make_unique<queryeval::EmptySearch>(); - } - if (getIsFilter()) { - return strict - ? std::make_unique<FilterAttributeIteratorStrict<SetSearchContext>>(*this, matchData) - : std::make_unique<FilterAttributeIteratorT<SetSearchContext>>(*this, matchData); - } - return strict - ? std::make_unique<AttributeIteratorStrict<SetSearchContext>>(*this, matchData) - : std::make_unique<AttributeIteratorT<SetSearchContext>>(*this, matchData); -} - -template <typename B, typename M> -bool MultiValueNumericAttribute<B, M>::ArraySearchContext::valid() const { return this->isValid(); } - -template <typename B, typename M> -MultiValueNumericAttribute<B, M>::ArraySearchContext::ArraySearchContext(QueryTermSimple::UP qTerm, const NumericAttribute & toBeSearched) : - attribute::NumericRangeMatcher<T>(*qTerm), - attribute::SearchContext(toBeSearched), - _toBeSearched(static_cast<const MultiValueNumericAttribute<B, M> &>(toBeSearched)) -{ } - -template <typename B, typename M> -Int64Range MultiValueNumericAttribute<B, M>::ArraySearchContext::getAsIntegerTerm() const { - return this->getRange(); -} - -template <typename B, typename M> -std::unique_ptr<queryeval::SearchIterator> -MultiValueNumericAttribute<B, M>::ArraySearchContext::createFilterIterator(fef::TermFieldMatchData * matchData, bool strict) -{ - if (!valid()) { - return std::make_unique<queryeval::EmptySearch>(); - } - if (getIsFilter()) { - return strict - ? std::make_unique<FilterAttributeIteratorStrict<ArraySearchContext>>(*this, matchData) - : std::make_unique<FilterAttributeIteratorT<ArraySearchContext>>(*this, matchData); - } - return strict - ? std::make_unique<AttributeIteratorStrict<ArraySearchContext>>(*this, matchData) - : std::make_unique<AttributeIteratorT<ArraySearchContext>>(*this, matchData); -} - } // namespace search |