diff options
author | Tor Egge <Tor.Egge@online.no> | 2022-04-12 20:13:50 +0200 |
---|---|---|
committer | Tor Egge <Tor.Egge@online.no> | 2022-04-12 20:13:50 +0200 |
commit | d39e86ba1b6f9c18fb540392d18d2e415b9c7dc4 (patch) | |
tree | 4cdc7cb32d6a55596eb850e1ec8250b9aadef18a /searchlib | |
parent | 4f22734462a0fac9dcc4fcdc8542218bb849c842 (diff) |
Stop sharing multivalue read views.
Diffstat (limited to 'searchlib')
8 files changed, 105 insertions, 34 deletions
diff --git a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt index 2e562b4a54f..79c68ba4fe3 100644 --- a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt @@ -94,6 +94,7 @@ vespa_add_library(searchlib_attribute OBJECT postinglisttraits.cpp postingstore.cpp predicate_attribute.cpp + raw_multi_value_read_view.cpp readerbase.cpp reference_attribute.cpp reference_attribute_saver.cpp diff --git a/searchlib/src/vespa/searchlib/attribute/multivalueattribute.h b/searchlib/src/vespa/searchlib/attribute/multivalueattribute.h index 9eb1a06d042..3844c0f9b02 100644 --- a/searchlib/src/vespa/searchlib/attribute/multivalueattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/multivalueattribute.h @@ -19,8 +19,7 @@ namespace search { */ template <typename B, typename M> class MultiValueAttribute : public B, - public attribute::IMultiValueAttribute, - public attribute::IMultiValueReadView<M> + public attribute::IMultiValueAttribute { protected: typedef typename B::DocId DocId; @@ -80,19 +79,10 @@ public: void onShrinkLidSpace() override ; void onAddDocs(DocId lidLimit) override; - const IMultiValueAttribute* as_multi_value_attribute() const override { - return this; - } + const IMultiValueAttribute* as_multi_value_attribute() const override; // Implements attribute::IMultiValueAttribute - const attribute::IMultiValueReadView<MultiValueType>* as_read_view(attribute::IMultiValueAttribute::Tag<MultiValueType>) const override { - return this; - } - - // Implements attribute::IMultiValueReadView - vespalib::ConstArrayRef<MultiValueType> get_raw_values(uint32_t docid) const override { - return this->_mvMapping.get(docid); - } + const attribute::IMultiValueReadView<MultiValueType>* make_read_view(attribute::IMultiValueAttribute::Tag<MultiValueType>, vespalib::Stash& stash) const override; }; } // namespace search diff --git a/searchlib/src/vespa/searchlib/attribute/multivalueattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multivalueattribute.hpp index 8cf86f66236..04194f662d9 100644 --- a/searchlib/src/vespa/searchlib/attribute/multivalueattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/multivalueattribute.hpp @@ -3,10 +3,12 @@ #pragma once #include "address_space_components.h" +#include "raw_multi_value_read_view.h" #include <vespa/searchlib/attribute/multivalueattribute.h> #include <vespa/vespalib/stllike/hash_map.h> #include <vespa/vespalib/stllike/hash_map.hpp> #include <vespa/vespalib/util/memory_allocator.h> +#include <vespa/vespalib/util/stash.h> namespace search { @@ -289,6 +291,19 @@ MultiValueAttribute<B, M>::onShrinkLidSpace() this->setNumDocs(committedDocIdLimit); } +template <typename B, typename M> +const attribute::IMultiValueAttribute* +MultiValueAttribute<B, M>::as_multi_value_attribute() const +{ + return this; +} + +template <typename B, typename M> +const attribute::IMultiValueReadView<M>* +MultiValueAttribute<B, M>::make_read_view(attribute::IMultiValueAttribute::Tag<MultiValueType>, vespalib::Stash& stash) const +{ + return &stash.create<attribute::RawMultiValueReadView<MultiValueType>>(this->_mvMapping.make_read_view(this->getCommittedDocIdLimit())); +} } // namespace search diff --git a/searchlib/src/vespa/searchlib/attribute/raw_multi_value_read_view.cpp b/searchlib/src/vespa/searchlib/attribute/raw_multi_value_read_view.cpp new file mode 100644 index 00000000000..66e7b7fec9b --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/raw_multi_value_read_view.cpp @@ -0,0 +1,41 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "raw_multi_value_read_view.h" + +namespace search::attribute { + +template <typename MultiValueType> +RawMultiValueReadView<MultiValueType>::RawMultiValueReadView(MultiValueMappingReadView<MultiValueType> mv_mapping_read_view) + : _mv_mapping_read_view(mv_mapping_read_view) +{ +} + +template <typename MultiValueType> +RawMultiValueReadView<MultiValueType>::~RawMultiValueReadView() = default; + +template <typename MultiValueType> +vespalib::ConstArrayRef<MultiValueType> +RawMultiValueReadView<MultiValueType>::get_values(uint32_t docid) const +{ + return _mv_mapping_read_view.get(docid); +} + +template class RawMultiValueReadView<int8_t>; +template class RawMultiValueReadView<int16_t>; +template class RawMultiValueReadView<int32_t>; +template class RawMultiValueReadView<int64_t>; +template class RawMultiValueReadView<float>; +template class RawMultiValueReadView<double>; +template class RawMultiValueReadView<vespalib::datastore::AtomicEntryRef>; + +using multivalue::WeightedValue; + +template class RawMultiValueReadView<WeightedValue<int8_t>>; +template class RawMultiValueReadView<WeightedValue<int16_t>>; +template class RawMultiValueReadView<WeightedValue<int32_t>>; +template class RawMultiValueReadView<WeightedValue<int64_t>>; +template class RawMultiValueReadView<WeightedValue<float>>; +template class RawMultiValueReadView<WeightedValue<double>>; +template class RawMultiValueReadView<WeightedValue<vespalib::datastore::AtomicEntryRef>>; + +} diff --git a/searchlib/src/vespa/searchlib/attribute/raw_multi_value_read_view.h b/searchlib/src/vespa/searchlib/attribute/raw_multi_value_read_view.h new file mode 100644 index 00000000000..dc243c2a24f --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/raw_multi_value_read_view.h @@ -0,0 +1,24 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include "multi_value_mapping_read_view.h" +#include <vespa/searchcommon/attribute/i_multi_value_read_view.h> + +namespace search::attribute { + +/** + * Read view for the raw data stored in a multi-value attribute. + * @tparam MultiValueType The multi-value type of the raw data to access. + */ +template <typename MultiValueType> +class RawMultiValueReadView : public IMultiValueReadView<MultiValueType> +{ + MultiValueMappingReadView<MultiValueType> _mv_mapping_read_view; +public: + RawMultiValueReadView(MultiValueMappingReadView<MultiValueType> mv_mapping_read_view); + ~RawMultiValueReadView() override; + vespalib::ConstArrayRef<MultiValueType> get_values(uint32_t docid) const override; +}; + +} diff --git a/searchlib/src/vespa/searchlib/features/attributefeature.cpp b/searchlib/src/vespa/searchlib/features/attributefeature.cpp index 47445e9e8ee..3b768633dd3 100644 --- a/searchlib/src/vespa/searchlib/features/attributefeature.cpp +++ b/searchlib/src/vespa/searchlib/features/attributefeature.cpp @@ -243,7 +243,7 @@ template <typename BaseType> void MultiAttributeExecutor<BaseType>::execute(uint32_t docId) { - auto values = _array_read_view->get_raw_values(docId); + auto values = _array_read_view->get_values(docId); auto o = outputs().get_bound(); o[0].as_number = __builtin_expect(_idx < values.size(), true) ? multivalue::get_value(values[_idx]) : 0; } @@ -341,10 +341,10 @@ struct MultiValueExecutorCreator { using ArrayReadView = attribute::IArrayReadView<typename T::BaseType>; using ExecType = MultiAttributeExecutor<typename T::BaseType>; MultiValueExecutorCreator() : _array_read_view(nullptr) {} - bool handle(const IAttributeVector *attribute) { + bool handle(vespalib::Stash &stash, const IAttributeVector *attribute) { 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<typename T::BaseType>()); + _array_read_view = multi_value_attribute->make_read_view(attribute::IMultiValueAttribute::Tag<typename T::BaseType>(), stash); } return _array_read_view != nullptr; } @@ -422,19 +422,19 @@ createAttributeExecutor(uint32_t numOutputs, const IAttributeVector *attribute, } else if (attribute->isIntegerType()) { if (basicType == BasicType::INT32) { MultiValueExecutorCreator<IntegerAttributeTemplate<int32_t>> creator; - if (creator.handle(attribute)) return creator.create(stash, idx); + if (creator.handle(stash, attribute)) return creator.create(stash, idx); } else if (basicType == BasicType::INT64) { MultiValueExecutorCreator<IntegerAttributeTemplate<int64_t>> creator; - if (creator.handle(attribute)) return creator.create(stash, idx); + if (creator.handle(stash, attribute)) return creator.create(stash, idx); } return stash.create<AttributeExecutor<IntegerContent>>(attribute, idx); } else { // FLOAT if (basicType == BasicType::DOUBLE) { MultiValueExecutorCreator<FloatingPointAttributeTemplate<double>> creator; - if (creator.handle(attribute)) return creator.create(stash, idx); + if (creator.handle(stash, attribute)) return creator.create(stash, idx); } else { MultiValueExecutorCreator<FloatingPointAttributeTemplate<float>> creator; - if (creator.handle(attribute)) return creator.create(stash, idx); + if (creator.handle(stash, attribute)) return creator.create(stash, idx); } return stash.create<AttributeExecutor<FloatContent>>(attribute, idx); } diff --git a/searchlib/src/vespa/searchlib/features/dotproductfeature.cpp b/searchlib/src/vespa/searchlib/features/dotproductfeature.cpp index b279cf6ca08..8f75b6ecc7d 100644 --- a/searchlib/src/vespa/searchlib/features/dotproductfeature.cpp +++ b/searchlib/src/vespa/searchlib/features/dotproductfeature.cpp @@ -145,7 +145,7 @@ template <typename BaseType> vespalib::ConstArrayRef<typename DotProductByWeightedSetReadViewExecutor<BaseType>::AT> DotProductByWeightedSetReadViewExecutor<BaseType>::getAttributeValues(uint32_t docId) { - return _weighted_set_read_view->get_raw_values(docId); + return _weighted_set_read_view->get_values(docId); } namespace { @@ -190,7 +190,7 @@ DotProductExecutorByEnum::~DotProductExecutorByEnum() = default; void DotProductExecutorByEnum::execute(uint32_t docId) { feature_t val = 0; - auto values = _weighted_set_enum_read_view->get_raw_values(docId); + auto values = _weighted_set_enum_read_view->get_values(docId); for (size_t i = 0; i < values.size(); ++i) { auto itr = _queryVector.getDimMap().find(values[i].value_ref().load_relaxed().ref()); if (itr != _end) { @@ -210,7 +210,7 @@ public: {} void execute(uint32_t docId) override { - auto values = _weighted_set_enum_read_view->get_raw_values(docId); + auto values = _weighted_set_enum_read_view->get_values(docId); for (size_t i = 0; i < values.size(); ++i) { if (values[i].value_ref().load_relaxed().ref() == _key) { outputs().set_number(0, values[i].weight()*_value); @@ -236,7 +236,7 @@ public: {} void execute(uint32_t docId) override { - auto values = _weighted_set_read_view->get_raw_values(docId); + auto values = _weighted_set_read_view->get_values(docId); for (size_t i = 0; i < values.size(); ++i) { if (values[i].value() == _key) { outputs().set_number(0, values[i].weight() * _value); @@ -290,7 +290,7 @@ template <typename BaseType> vespalib::ConstArrayRef<BaseType> DotProductByArrayReadViewExecutor<BaseType>::getAttributeValues(uint32_t docId) { - return _array_read_view->get_raw_values(docId); + return _array_read_view->get_values(docId); } template <typename A> @@ -328,7 +328,7 @@ template <typename BaseType> vespalib::ConstArrayRef<BaseType> SparseDotProductByArrayReadViewExecutor<BaseType>::getAttributeValues(uint32_t docid) { - auto allValues = _array_read_view->get_raw_values(docid); + auto allValues = _array_read_view->get_values(docid); size_t i(0); for (; (i < _queryIndexes.size()) && (_queryIndexes[i] < allValues.size()); i++) { _scratch[i] = allValues[_queryIndexes[i]]; @@ -533,11 +533,11 @@ using dotproduct::ArrayParam; template <typename AT> const attribute::IMultiValueReadView<AT>* -get_multi_value_read_view(const IAttributeVector& attribute) +make_multi_value_read_view(const IAttributeVector& attribute, vespalib::Stash& stash) { auto multi_value_attribute = attribute.as_multi_value_attribute(); if (multi_value_attribute != nullptr) { - return multi_value_attribute->as_read_view(attribute::IMultiValueAttribute::Tag<AT>()); + return multi_value_attribute->make_read_view(attribute::IMultiValueAttribute::Tag<AT>(), stash); } return nullptr; } @@ -556,7 +556,7 @@ createForDirectArrayImpl(const IAttributeVector * attribute, const A * iattr = dynamic_cast<const A *>(attribute); using T = typename A::BaseType; using VT = T; - auto array_read_view = get_multi_value_read_view<VT>(*attribute); + auto array_read_view = make_multi_value_read_view<VT>(*attribute, stash); if (indexes.empty()) { if (array_read_view != nullptr) { return stash.create<dotproduct::array::DotProductByArrayReadViewExecutor<T>>(array_read_view, values); @@ -658,7 +658,7 @@ createForDirectWSetImpl(const IAttributeVector * attribute, V && vector, vespali using T = typename A::BaseType; const A * iattr = dynamic_cast<const A *>(attribute); using VT = multivalue::WeightedValue<T>; - auto weighted_set_read_view = get_multi_value_read_view<VT>(*attribute); + auto weighted_set_read_view = make_multi_value_read_view<VT>(*attribute, stash); if (!attribute->isImported() && (iattr != nullptr) && weighted_set_read_view != nullptr) { if (extractSize(vector) == 1) { auto elem = extractElem(vector, 0ul); @@ -719,7 +719,7 @@ createFromObject(const IAttributeVector * attribute, const fef::Anything & objec return stash.create<SingleZeroValueExecutor>(); } using VT = multivalue::WeightedValue<vespalib::datastore::AtomicEntryRef>; - auto* weighted_set_enum_read_view = get_multi_value_read_view<VT>(*attribute); + auto* weighted_set_enum_read_view = make_multi_value_read_view<VT>(*attribute, stash); if (weighted_set_enum_read_view != nullptr) { if (vector.getVector().size() == 1) { const auto & elem = vector.getVector()[0]; @@ -814,7 +814,7 @@ createTypedWsetExecutor(const IAttributeVector * attribute, const Property & pro } vector->syncMap(); using VT = multivalue::WeightedValue<vespalib::datastore::AtomicEntryRef>; - auto* weighted_set_enum_read_view = get_multi_value_read_view<VT>(*attribute); + auto* weighted_set_enum_read_view = make_multi_value_read_view<VT>(*attribute, stash); if (weighted_set_enum_read_view != nullptr) { if (vector->getVector().size() == 1) { const auto & elem = vector->getVector()[0]; 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 e69c3703c2c..5e3dc727279 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 @@ -90,7 +90,7 @@ feature_t maxProduct(const A &array, size_t count, const V &query) { template<typename BaseType> void RawExecutor<BaseType>::execute(uint32_t docId) { - auto values = _array_read_view->get_raw_values(docId); + auto values = _array_read_view->get_values(docId); outputs().set_number(0, maxProduct(values.data(), values.size(), _queryVector)); } @@ -147,7 +147,7 @@ selectTypedExecutor(const IAttributeVector *attribute, V && vector, vespalib::St using VT = BaseType; 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>()); + auto array_read_view = multi_value_attribute->make_read_view(attribute::IMultiValueAttribute::Tag<VT>(), stash); if (array_read_view != nullptr) { return stash.create<RawExecutor<BaseType>>(array_read_view, std::forward<V>(vector)); } |