diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2022-03-31 19:31:47 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-31 19:31:47 +0200 |
commit | a7e3bc6fd0c771cfb1643d4b04874ecd6f289cc3 (patch) | |
tree | e78334f890eab3e7080988b56665e7c8f8b901a3 | |
parent | 1409da607c17e6b4fc73773e9f889b102c9bcd66 (diff) | |
parent | 4a5b38b3a004ad980292cb1e760d4652364c4735 (diff) |
Merge pull request #21925 from vespa-engine/toregge/factor-out-multi-numeric-enum-search-context
Factor out MultiNumericEnumSearchContext from MultiValueNumericEnumAttribute.
8 files changed, 142 insertions, 196 deletions
diff --git a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt index 1089a08b3a5..e86f04db56d 100644 --- a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt @@ -64,6 +64,7 @@ vespa_add_library(searchlib_attribute OBJECT loadedenumvalue.cpp loadednumericvalue.cpp loadedvalue.cpp + multi_numeric_enum_search_context.cpp multi_numeric_search_context.cpp multi_value_mapping.cpp multi_value_mapping_base.cpp diff --git a/searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.cpp b/searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.cpp new file mode 100644 index 00000000000..29b6f75a3d6 --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.cpp @@ -0,0 +1,25 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "multi_numeric_enum_search_context.hpp" +#include <vespa/searchcommon/attribute/multivalue.h> + +using ValueRef = search::multivalue::Value<vespalib::datastore::AtomicEntryRef>; +using WeightedValueRef = search::multivalue::WeightedValue<vespalib::datastore::AtomicEntryRef>; + +namespace search::attribute { + +template class MultiNumericEnumSearchContext<int8_t, ValueRef>; +template class MultiNumericEnumSearchContext<int16_t, ValueRef>; +template class MultiNumericEnumSearchContext<int32_t, ValueRef>; +template class MultiNumericEnumSearchContext<int64_t, ValueRef>; +template class MultiNumericEnumSearchContext<float, ValueRef>; +template class MultiNumericEnumSearchContext<double, ValueRef>; + +template class MultiNumericEnumSearchContext<int8_t, WeightedValueRef>; +template class MultiNumericEnumSearchContext<int16_t, WeightedValueRef>; +template class MultiNumericEnumSearchContext<int32_t, WeightedValueRef>; +template class MultiNumericEnumSearchContext<int64_t, WeightedValueRef>; +template class MultiNumericEnumSearchContext<float, WeightedValueRef>; +template class MultiNumericEnumSearchContext<double, WeightedValueRef>; + +} diff --git a/searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.h b/searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.h new file mode 100644 index 00000000000..e381609bda1 --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.h @@ -0,0 +1,65 @@ +// 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 "enumstore.h" +#include "multi_value_mapping.h" +#include "numeric_range_matcher.h" + +namespace search::attribute { + +/* + * MultiNumericEnumSearchContext handles the creation of search iterators for + * a query term on a multi value numeric enumerated attribute vector. + */ +template <typename T, typename M> +class MultiNumericEnumSearchContext : public NumericRangeMatcher<T>, public SearchContext +{ +protected: + const MultiValueMapping<M>& _mv_mapping; + const EnumStoreT<T>& _enum_store; + + 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 { return this->isValid(); } + +public: + MultiNumericEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const MultiValueMapping<M>& mv_mapping, const EnumStoreT<T>& enum_store); + + int32_t find(DocId doc, int32_t elemId, int32_t & weight) const { + auto indices(_mv_mapping.get(doc)); + for (uint32_t i(elemId); i < indices.size(); i++) { + T v = _enum_store.get_value(indices[i].value_ref().load_acquire()); + if (this->match(v)) { + weight = indices[i].weight(); + return i; + } + } + weight = 0; + return -1; + } + + int32_t find(DocId doc, int32_t elemId) const { + auto indices(_mv_mapping.get(doc)); + for (uint32_t i(elemId); i < indices.size(); i++) { + T v = _enum_store.get_value(indices[i].value_ref().load_acquire()); + if (this->match(v)) { + 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_enum_search_context.hpp b/searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.hpp new file mode 100644 index 00000000000..38fd9f80535 --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.hpp @@ -0,0 +1,44 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include "multi_numeric_enum_search_context.h" +#include "attributeiterators.hpp" +#include <vespa/searchlib/queryeval/emptysearch.h> + +namespace search::attribute { + +template <typename T, typename M> +MultiNumericEnumSearchContext<T, M>::MultiNumericEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const MultiValueMapping<M>& mv_mapping, const EnumStoreT<T>& enum_store) + : NumericRangeMatcher<T>(*qTerm), + SearchContext(toBeSearched), + _mv_mapping(mv_mapping), + _enum_store(enum_store) +{ +} + +template <typename T, typename M> +Int64Range +MultiNumericEnumSearchContext<T, M>::getAsIntegerTerm() const +{ + return this->getRange(); +} + +template <typename T, typename M> +std::unique_ptr<queryeval::SearchIterator> +MultiNumericEnumSearchContext<T, M>::createFilterIterator(fef::TermFieldMatchData* matchData, bool strict) +{ + if (!valid()) { + return std::make_unique<queryeval::EmptySearch>(); + } + if (getIsFilter()) { + return strict + ? std::make_unique<FilterAttributeIteratorStrict<MultiNumericEnumSearchContext>>(*this, matchData) + : std::make_unique<FilterAttributeIteratorT<MultiNumericEnumSearchContext>>(*this, matchData); + } + return strict + ? std::make_unique<AttributeIteratorStrict<MultiNumericEnumSearchContext>>(*this, matchData) + : std::make_unique<AttributeIteratorT<MultiNumericEnumSearchContext>>(*this, matchData); +} + +} diff --git a/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.h b/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.h index 784a7d827c4..d981ba2015e 100644 --- a/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.h @@ -40,116 +40,6 @@ protected: using WeightedInt = typename B::BaseClass::WeightedInt; using largeint_t = typename B::BaseClass::largeint_t; - /* - * Specialization of SearchContext for weighted set type - */ - class SetSearchContext : public attribute::NumericRangeMatcher<T>, public attribute::SearchContext - { - protected: - const MultiValueNumericEnumAttribute<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 { return this->isValid(); } - - public: - SetSearchContext(QueryTermSimpleUP qTerm, const NumericAttribute & toBeSearched); - - int32_t - find(DocId doc, int32_t elemId, int32_t & weight) const - { - WeightedIndexArrayRef indices(_toBeSearched._mvMapping.get(doc)); - for (uint32_t i(elemId); i < indices.size(); i++) { - T v = _toBeSearched._enumStore.get_value(indices[i].value_ref().load_acquire()); - if (this->match(v)) { - weight = indices[i].weight(); - return i; - } - } - return -1; - } - - int32_t - find(DocId doc, int32_t elemId) const - { - WeightedIndexArrayRef indices(_toBeSearched._mvMapping.get(doc)); - for (uint32_t i(elemId); i < indices.size(); i++) { - T v = _toBeSearched._enumStore.get_value(indices[i].value_ref().load_acquire()); - if (this->match(v)) { - return i; - } - } - return -1; - } - Int64Range getAsIntegerTerm() const override; - - 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 - { - protected: - const MultiValueNumericEnumAttribute<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 { return this->isValid(); } - - public: - ArraySearchContext(QueryTermSimpleUP qTerm, const NumericAttribute & toBeSearched); - Int64Range getAsIntegerTerm() const override; - - int32_t - find(DocId doc, int32_t elemId, int32_t & weight) const - { - WeightedIndexArrayRef indices(_toBeSearched._mvMapping.get(doc)); - for (uint32_t i(elemId); i < indices.size(); i++) { - T v = _toBeSearched._enumStore.get_value(indices[i].value_ref().load_acquire()); - if (this->match(v)) { - weight = 1; - return i; - } - } - weight = 0; - - return -1; - } - - int32_t - find(DocId doc, int32_t elemId) const - { - WeightedIndexArrayRef indices(_toBeSearched._mvMapping.get(doc)); - for (uint32_t i(elemId); i < indices.size(); i++) { - T v = _toBeSearched._enumStore.get_value(indices[i].value_ref().load_acquire()); - if (this->match(v)) { - return i; - } - } - - return -1; - } - - std::unique_ptr<queryeval::SearchIterator> - createFilterIterator(fef::TermFieldMatchData * matchData, bool strict) override; - }; - - public: MultiValueNumericEnumAttribute(const vespalib::string & baseFileName, const AttributeVector::Config & cfg); diff --git a/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.hpp index 7f6f57553ce..201bff48be7 100644 --- a/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.hpp @@ -6,6 +6,7 @@ #include "load_utils.h" #include "loadednumericvalue.h" #include "multinumericenumattribute.h" +#include "multi_numeric_enum_search_context.h" #include <vespa/searchlib/query/query_term_simple.h> #include <vespa/searchlib/queryeval/emptysearch.h> #include <vespa/searchlib/util/fileutil.hpp> @@ -120,82 +121,7 @@ MultiValueNumericEnumAttribute<B, M>::getSearch(QueryTermSimple::UP qTerm, const attribute::SearchContextParams & params) const { (void) params; - QueryTermSimple::RangeResult<T> res = qTerm->getRange<T>(); - if (this->hasArrayType()) { - if (res.isEqual()) { - return std::make_unique<ArraySearchContext>(std::move(qTerm), *this); - } else { - return std::make_unique<ArraySearchContext>(std::move(qTerm), *this); - } - } else { - if (res.isEqual()) { - return std::make_unique<SetSearchContext>(std::move(qTerm), *this); - } else { - return std::make_unique<SetSearchContext>(std::move(qTerm), *this); - } - } -} - -template <typename B, typename M> -MultiValueNumericEnumAttribute<B, M>::SetSearchContext::SetSearchContext(QueryTermSimpleUP qTerm, const NumericAttribute & toBeSearched) : - attribute::NumericRangeMatcher<T>(*qTerm), - SearchContext(toBeSearched), - _toBeSearched(static_cast<const MultiValueNumericEnumAttribute<B, M> &>(toBeSearched)) -{ } - -template <typename B, typename M> -Int64Range -MultiValueNumericEnumAttribute<B, M>::SetSearchContext::getAsIntegerTerm() const -{ - return this->getRange(); -} - -template <typename B, typename M> -std::unique_ptr<queryeval::SearchIterator> -MultiValueNumericEnumAttribute<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> -std::unique_ptr<queryeval::SearchIterator> -MultiValueNumericEnumAttribute<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); -} - -template <typename B, typename M> -MultiValueNumericEnumAttribute<B, M>::ArraySearchContext::ArraySearchContext(QueryTermSimpleUP qTerm, const NumericAttribute & toBeSearched) : - attribute::NumericRangeMatcher<T>(*qTerm), - SearchContext(toBeSearched), - _toBeSearched(static_cast<const MultiValueNumericEnumAttribute<B, M> &>(toBeSearched)) -{ } - -template <typename B, typename M> -Int64Range -MultiValueNumericEnumAttribute<B, M>::ArraySearchContext::getAsIntegerTerm() const -{ - return this->getRange(); + return std::make_unique<attribute::MultiNumericEnumSearchContext<T, M>>(std::move(qTerm), *this, this->_mvMapping, this->_enumStore); } } // namespace search diff --git a/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.h b/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.h index 26e6ee12439..c972170f408 100644 --- a/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.h @@ -13,7 +13,7 @@ namespace search { * multi value mapping uses an underlying posting list to provide faster search. * This class is used for both array and weighted set types. * - * B: EnumAttribute<P, BaseClass> + * B: EnumAttribute<BaseClass> * M: multivalue::Value<IEnumStore::Index> (array) or * multivalue::WeightedValue<IEnumStore::Index> (weighted set) * M specifies the type stored in the MultiValueMapping @@ -52,9 +52,6 @@ private: using PostingParent = PostingListAttributeSubBase<AttributeWeightPosting, LoadedVector, typename B::LoadedValueType, EnumStore>; - using ArraySearchContext = typename MultiValueNumericEnumAttribute<B, M>::ArraySearchContext; - using ArrayNumericSearchContext = ArraySearchContext; - using ArrayPostingSearchContext = attribute::NumericPostingSearchContext<ArrayNumericSearchContext, SelfType, int32_t>; using ComparatorType = typename EnumStore::ComparatorType; using Dictionary = EnumPostingTree; using DictionaryConstIterator = typename Dictionary::ConstIterator; @@ -65,9 +62,6 @@ private: using PostingList = typename PostingParent::PostingList; using PostingMap = typename PostingParent::PostingMap; using QueryTermSimpleUP = AttributeVector::QueryTermSimpleUP; - using SetSearchContext = typename MultiValueNumericEnumAttribute<B, M>::SetSearchContext; - using SetNumericSearchContext = SetSearchContext; - using SetPostingSearchContext = attribute::NumericPostingSearchContext<SetNumericSearchContext, SelfType, int32_t>; using WeightedIndex = typename MultiValueNumericEnumAttribute<B, M>::WeightedIndex; using generation_t = typename MultiValueNumericEnumAttribute<B, M>::generation_t; diff --git a/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.hpp index cf3102744f6..688bcaf1825 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 "multi_numeric_enum_search_context.h" #include <charconv> namespace search { @@ -75,9 +76,9 @@ std::unique_ptr<attribute::SearchContext> MultiValueNumericPostingAttribute<B, M>::getSearch(QueryTermSimpleUP qTerm, const attribute::SearchContextParams & params) const { - using BaseSC = std::conditional_t<M::_hasWeight, SetNumericSearchContext, ArrayNumericSearchContext>; - using SC = std::conditional_t<M::_hasWeight, SetPostingSearchContext, ArrayPostingSearchContext>; - BaseSC base_sc(std::move(qTerm), *this); + using BaseSC = attribute::MultiNumericEnumSearchContext<typename B::BaseClass::BaseType, M>; + using SC = attribute::NumericPostingSearchContext<BaseSC, SelfType, int32_t>; + BaseSC base_sc(std::move(qTerm), *this, this->_mvMapping, this->_enumStore); return std::make_unique<SC>(std::move(base_sc), params, *this); } |