diff options
author | Tor Egge <Tor.Egge@yahooinc.com> | 2022-04-11 15:41:16 +0200 |
---|---|---|
committer | Tor Egge <Tor.Egge@yahooinc.com> | 2022-04-11 15:41:16 +0200 |
commit | 803f56bdb11778a961fa3c3fd0aaba1221b4f845 (patch) | |
tree | c0981b617fc9f5d574f4456b7ce74b048fb28ffc | |
parent | 6bcf1e1075f85e317f54ab62b9137789d045373e (diff) |
Use attribute::IArrayReadView instead of getRawValues().
-rw-r--r-- | searchlib/src/vespa/searchlib/features/attributefeature.cpp | 35 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/features/internal_max_reduce_prod_join_feature.cpp | 71 |
2 files changed, 48 insertions, 58 deletions
diff --git a/searchlib/src/vespa/searchlib/features/attributefeature.cpp b/searchlib/src/vespa/searchlib/features/attributefeature.cpp index 07458743a46..ea88bfb6aa6 100644 --- a/searchlib/src/vespa/searchlib/features/attributefeature.cpp +++ b/searchlib/src/vespa/searchlib/features/attributefeature.cpp @@ -139,13 +139,14 @@ public: /** * Implements the executor for fetching values from a single or array attribute vector */ -template <typename T> +template <typename BaseType> class MultiAttributeExecutor final : public fef::FeatureExecutor { private: - const T & _attribute; + using ArrayReadView = attribute::IArrayReadView<BaseType>; + const ArrayReadView* _array_read_view; uint32_t _idx; public: - MultiAttributeExecutor(const T & attribute, uint32_t idx) : _attribute(attribute), _idx(idx) { } + MultiAttributeExecutor(const ArrayReadView* array_read_view, uint32_t idx) : _array_read_view(array_read_view), _idx(idx) { } void execute(uint32_t docId) override; void handle_bind_outputs(vespalib::ArrayRef<fef::NumberOrObject> outputs_in) override { fef::FeatureExecutor::handle_bind_outputs(outputs_in); @@ -238,15 +239,13 @@ SingleAttributeExecutor<T>::execute(uint32_t docId) : util::getAsFeature(v); } -template <typename T> +template <typename BaseType> void -MultiAttributeExecutor<T>::execute(uint32_t docId) +MultiAttributeExecutor<BaseType>::execute(uint32_t docId) { - const multivalue::Value<typename T::BaseType> * values = nullptr; - uint32_t numValues = _attribute.getRawValues(docId, values); - + auto values = _array_read_view->get_raw_values(docId); auto o = outputs().get_bound(); - o[0].as_number = __builtin_expect(_idx < numValues, true) ? values[_idx].value() : 0; + o[0].as_number = __builtin_expect(_idx < values.size(), true) ? values[_idx].value() : 0; } void @@ -339,19 +338,21 @@ private: template <typename T> struct MultiValueExecutorCreator { - using AttrType = MultiValueNumericAttribute<T, multivalue::Value<typename T::BaseType>>; - using PtrType = const AttrType *; - using ExecType = MultiAttributeExecutor<AttrType>; - MultiValueExecutorCreator() : ptr(nullptr) {} + using ArrayReadView = attribute::IArrayReadView<typename T::BaseType>; + using ExecType = MultiAttributeExecutor<typename T::BaseType>; + MultiValueExecutorCreator() : _array_read_view(nullptr) {} bool handle(const IAttributeVector *attribute) { - ptr = dynamic_cast<PtrType>(attribute); - return ptr != nullptr; + auto multi_value_attribute = attribute->as_multi_value_attribute(); + if (multi_value_attribute != nullptr) { + _array_read_view = multi_value_attribute->as_read_view(attribute::IMultiValueAttribute::Tag<multivalue::Value<typename T::BaseType>>()); + } + return _array_read_view != nullptr; } fef::FeatureExecutor & create(vespalib::Stash &stash, uint32_t idx) const { - return stash.create<ExecType>(*ptr, idx); + return stash.create<ExecType>(_array_read_view, idx); } private: - PtrType ptr; + const ArrayReadView* _array_read_view; }; fef::FeatureExecutor & diff --git a/searchlib/src/vespa/searchlib/features/internal_max_reduce_prod_join_feature.cpp b/searchlib/src/vespa/searchlib/features/internal_max_reduce_prod_join_feature.cpp index 2a326583078..635c8fed4c3 100644 --- a/searchlib/src/vespa/searchlib/features/internal_max_reduce_prod_join_feature.cpp +++ b/searchlib/src/vespa/searchlib/features/internal_max_reduce_prod_join_feature.cpp @@ -32,33 +32,32 @@ namespace { */ template<typename BaseType> class RawExecutor : public FeatureExecutor { -private: + using ArrayReadView = attribute::IArrayReadView<BaseType>; std::unique_ptr<IntegerVector> _backing; -protected: - const IAttributeVector *_attribute; - const IntegerVector &_queryVector; + const ArrayReadView* _array_read_view; + const IntegerVector& _queryVector; public: - RawExecutor(const IAttributeVector *attribute, const IntegerVector & queryVector); - RawExecutor(const IAttributeVector *attribute, std::unique_ptr<IntegerVector> queryVector); + RawExecutor(const ArrayReadView* array_read_view, const IntegerVector& queryVector); + RawExecutor(const ArrayReadView* array_read_view, std::unique_ptr<IntegerVector> queryVector); void execute(uint32_t docId) override; }; template<typename BaseType> -RawExecutor<BaseType>::RawExecutor(const IAttributeVector *attribute, std::unique_ptr<IntegerVector> queryVector) +RawExecutor<BaseType>::RawExecutor(const ArrayReadView* array_read_view, std::unique_ptr<IntegerVector> queryVector) : FeatureExecutor(), _backing(std::move(queryVector)), - _attribute(attribute), + _array_read_view(array_read_view), _queryVector(*_backing) { } template<typename BaseType> -RawExecutor<BaseType>::RawExecutor(const IAttributeVector *attribute, const IntegerVector & queryVector) +RawExecutor<BaseType>::RawExecutor(const ArrayReadView* array_read_view, const IntegerVector& queryVector) : FeatureExecutor(), _backing(), - _attribute(attribute), + _array_read_view(array_read_view), _queryVector(queryVector) { } @@ -81,20 +80,20 @@ feature_t maxProduct(const A &array, size_t count, const V &query) { template<typename BaseType> void RawExecutor<BaseType>::execute(uint32_t docId) { - using A = IntegerAttributeTemplate<BaseType>; - const multivalue::Value<BaseType> *values(nullptr); - const A *iattr = static_cast<const A *>(_attribute); - size_t count = iattr->getRawValues(docId, values); - outputs().set_number(0, maxProduct(values, count, _queryVector)); + auto values = _array_read_view->get_raw_values(docId); + outputs().set_number(0, maxProduct(values.data(), values.size(), _queryVector)); } /** * Executor when array can't be accessed directly */ template<typename BaseType> -class BufferedExecutor : public RawExecutor<BaseType> { +class BufferedExecutor : public FeatureExecutor { private: - WeightedIntegerContent _buffer; + std::unique_ptr<IntegerVector> _backing; + const IAttributeVector* _attribute; + const IntegerVector& _queryVector; + WeightedIntegerContent _buffer; public: BufferedExecutor(const IAttributeVector *attribute, const IntegerVector & queryVector); @@ -104,15 +103,21 @@ public: }; template<typename BaseType> -BufferedExecutor<BaseType>::BufferedExecutor(const IAttributeVector *attribute, const IntegerVector & queryVector) - : RawExecutor<BaseType>(attribute, queryVector), +BufferedExecutor<BaseType>::BufferedExecutor(const IAttributeVector *attribute, const IntegerVector& queryVector) + : FeatureExecutor(), + _backing(), + _attribute(attribute), + _queryVector(queryVector), _buffer() { } template<typename BaseType> BufferedExecutor<BaseType>::BufferedExecutor(const IAttributeVector *attribute, std::unique_ptr<IntegerVector> queryVector) - : RawExecutor<BaseType>(attribute, std::move(queryVector)), + : FeatureExecutor(), + _backing(std::move(queryVector)), + _attribute(attribute), + _queryVector(*_backing), _buffer() { } @@ -125,32 +130,16 @@ BufferedExecutor<BaseType>::execute(uint32_t docId) { this->outputs().set_number(0, maxProduct(_buffer, _buffer.size(), this->_queryVector)); } - -template<typename A> -bool supportsGetRawValues(const A &attr) noexcept { - try { - const multivalue::Value<typename A::BaseType> *tmp = nullptr; - attr.getRawValues(0, tmp); // Throws if unsupported - return true; - } catch (const std::runtime_error &e) { - (void) e; - return false; - } -} - template<typename BaseType, typename V> FeatureExecutor & selectTypedExecutor(const IAttributeVector *attribute, V && vector, vespalib::Stash &stash) { if (!attribute->isImported()) { - using A = IntegerAttributeTemplate<BaseType>; using VT = multivalue::Value<BaseType>; - using ExactA = MultiValueNumericAttribute<A, VT>; - - const A *iattr = dynamic_cast<const A *>(attribute); - if (supportsGetRawValues(*iattr)) { - const ExactA *exactA = dynamic_cast<const ExactA *>(iattr); - if (exactA != nullptr) { - return stash.create<RawExecutor<BaseType>>(attribute, std::forward<V>(vector)); + auto multi_value_attribute = attribute->as_multi_value_attribute(); + if (multi_value_attribute != nullptr) { + auto array_read_view = multi_value_attribute->as_read_view(attribute::IMultiValueAttribute::Tag<VT>()); + if (array_read_view != nullptr) { + return stash.create<RawExecutor<BaseType>>(array_read_view, std::forward<V>(vector)); } } } |