diff options
author | Geir Storli <geirst@yahooinc.com> | 2022-04-20 16:11:46 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-20 16:11:46 +0200 |
commit | 8b948d5a85225af85e1b694e9259bceb75b35800 (patch) | |
tree | 711e89fc6394cda97ec11dd7c6bc009a11584885 | |
parent | 0cbd9956e29ac0706e1e1b569609536c3fbc8dd6 (diff) | |
parent | db6e199a7cff0d8d57512231016e0d041a4ea92b (diff) |
Merge pull request #22176 from vespa-engine/toregge/support-multi-value-read-view-for-imported-attribute-vectors
Enable MultiValueReadView for imported attribute vectors.
6 files changed, 359 insertions, 22 deletions
diff --git a/searchlib/src/tests/attribute/multi_value_read_view/multi_value_read_view_test.cpp b/searchlib/src/tests/attribute/multi_value_read_view/multi_value_read_view_test.cpp index 43d819ca966..c81fea79590 100644 --- a/searchlib/src/tests/attribute/multi_value_read_view/multi_value_read_view_test.cpp +++ b/searchlib/src/tests/attribute/multi_value_read_view/multi_value_read_view_test.cpp @@ -1,19 +1,86 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <vespa/document/base/documentid.h> #include <vespa/searchcommon/attribute/i_multi_value_attribute.h> #include <vespa/searchcommon/attribute/multi_value_traits.h> #include <vespa/searchlib/attribute/attributefactory.h> +#include <vespa/searchlib/attribute/attribute_read_guard.h> #include <vespa/searchlib/attribute/extendableattributes.h> #include <vespa/searchlib/attribute/floatbase.h> +#include <vespa/searchlib/attribute/imported_attribute_vector.h> +#include <vespa/searchlib/attribute/imported_attribute_vector_factory.h> #include <vespa/searchlib/attribute/integerbase.h> +#include <vespa/searchlib/attribute/reference_attribute.h> #include <vespa/searchlib/attribute/stringbase.h> +#include <vespa/searchlib/common/i_document_meta_store_context.h> +#include <vespa/searchlib/test/mock_gid_to_lid_mapping.h> #include <vespa/vespalib/gtest/gtest.h> #include <vespa/vespalib/util/stash.h> - +using document::GlobalId; +using document::DocumentId; namespace search::attribute { +using test::MockGidToLidMapperFactory; + +namespace { + +GlobalId toGid(vespalib::stringref docId) { + return DocumentId(docId).getGlobalId(); +} + +vespalib::string doc1("id:test:music::1"); +vespalib::string doc2("id:test:music::2"); + +struct MyGidToLidMapperFactory : public MockGidToLidMapperFactory +{ + MyGidToLidMapperFactory() + : MockGidToLidMapperFactory() + { + _map.insert({toGid(doc1), 1}); + _map.insert({toGid(doc2), 2}); + } +}; + +struct MockReadGuard : public IDocumentMetaStoreContext::IReadGuard { + virtual const search::IDocumentMetaStore &get() const override { + search::IDocumentMetaStore *nullStore = nullptr; + return static_cast<search::IDocumentMetaStore &>(*nullStore); + } +}; + +struct MockDocumentMetaStoreContext : public IDocumentMetaStoreContext +{ + std::unique_ptr<IReadGuard> getReadGuard() const override; +}; + +std::unique_ptr<IDocumentMetaStoreContext::IReadGuard> +MockDocumentMetaStoreContext::getReadGuard() const +{ + return std::make_unique<MockReadGuard>(); +} + + +std::shared_ptr<ReferenceAttribute> +create_reference_attribute(const vespalib::string &name, const std::shared_ptr<IGidToLidMapperFactory> gid_to_lid_mapper_factory) +{ + auto attr = std::make_shared<ReferenceAttribute>(name, Config(BasicType::REFERENCE)); + attr->addReservedDoc(); + while (attr->getNumDocs() < 20u) { + uint32_t doc_id = 0; + attr->addDoc(doc_id); + EXPECT_NE(0u, doc_id); + } + attr->update(4, toGid(doc1)); + attr->update(11, toGid(doc2)); + attr->setGidToLidMapperFactory(gid_to_lid_mapper_factory); + attr->populateTargetLids({}); + return attr; +} + +} + class TestParam { BasicType _basic_type; @@ -35,8 +102,12 @@ std::ostream& operator<<(std::ostream& os, const TestParam& param) class MultiValueReadViewTest : public ::testing::TestWithParam<TestParam> { protected: + std::shared_ptr<IGidToLidMapperFactory> _gid_to_lid_mapper_factory; + std::shared_ptr<ReferenceAttribute> _reference_attribute; MultiValueReadViewTest() - : ::testing::TestWithParam<TestParam>() + : ::testing::TestWithParam<TestParam>(), + _gid_to_lid_mapper_factory(std::make_shared<MyGidToLidMapperFactory>()), + _reference_attribute(create_reference_attribute("ref", _gid_to_lid_mapper_factory)) { } ~MultiValueReadViewTest() override = default; @@ -45,15 +116,18 @@ protected: void populate_helper(AttributeVector& attr, const std::vector<BaseType>& values); void populate(AttributeVector& attr); template <typename MultiValueType> - void check_values_helper(const AttributeVector &attr, const std::vector<multivalue::ValueType_t<MultiValueType>>& exp_values); + void check_values_helper(const IAttributeVector &attr, const std::vector<multivalue::ValueType_t<MultiValueType>>& exp_values); template <typename BasicType> - void check_integer_values(const AttributeVector &attr); + void check_integer_values(const IAttributeVector &attr); template <typename BasicType> - void check_floating_point_values(const AttributeVector &attr); - void check_string_values(const AttributeVector &attr); - void check_values(const AttributeVector& attr); + void check_floating_point_values(const IAttributeVector &attr); + void check_string_values(const IAttributeVector &attr); + void check_values(const IAttributeVector& attr); + std::shared_ptr<AttributeVector> make_attribute(CollectionType collection_type, bool fast_search); + std::shared_ptr<ReadableAttributeVector> make_imported_attribute(std::shared_ptr<AttributeVector> target); std::shared_ptr<AttributeVector> make_extendable_attribute(CollectionType collection_type); void test_normal_attribute_vector(CollectionType collection_type, bool fast_search); + void test_imported_attribute_vector(CollectionType collection_type, bool fast_search); void test_extendable_attribute_vector(CollectionType collection_type); }; @@ -135,20 +209,21 @@ struct CompareValues<const char *> template <typename MultiValueType> void -MultiValueReadViewTest::check_values_helper(const AttributeVector &attr, const std::vector<multivalue::ValueType_t<MultiValueType>>& exp_values) +MultiValueReadViewTest::check_values_helper(const IAttributeVector &attr, const std::vector<multivalue::ValueType_t<MultiValueType>>& exp_values) { vespalib::Stash stash; auto mv_attr = attr.as_multi_value_attribute(); EXPECT_NE(nullptr, mv_attr); auto read_view = mv_attr->make_read_view(IMultiValueAttribute::Tag<MultiValueType>(), stash); EXPECT_NE(nullptr, read_view); - auto values = read_view->get_values(1); + bool is_imported = attr.isImported(); + auto values = read_view->get_values(is_imported ? 4 : 1); EXPECT_TRUE(values.empty()); - values = read_view->get_values(2); + values = read_view->get_values(is_imported ? 11 : 2); std::vector<MultiValueType> values_copy(values.begin(), values.end()); bool was_array = true; CompareValues<multivalue::ValueType_t<MultiValueType>> compare_values; - if (attr.getConfig().collectionType().type() == CollectionType::Type::WSET) { + if (attr.getCollectionType() == CollectionType::Type::WSET) { std::sort(values_copy.begin(), values_copy.end(), compare_values); was_array = false; } @@ -166,7 +241,7 @@ MultiValueReadViewTest::check_values_helper(const AttributeVector &attr, const s template <typename BasicType> void -MultiValueReadViewTest::check_integer_values(const AttributeVector &attr) +MultiValueReadViewTest::check_integer_values(const IAttributeVector &attr) { std::vector<BasicType> exp_values{42, 44}; check_values_helper<BasicType>(attr, exp_values); @@ -175,7 +250,7 @@ MultiValueReadViewTest::check_integer_values(const AttributeVector &attr) template <typename BasicType> void -MultiValueReadViewTest::check_floating_point_values(const AttributeVector &attr) +MultiValueReadViewTest::check_floating_point_values(const IAttributeVector &attr) { std::vector<BasicType> exp_values{42.0, 44.0}; check_values_helper<BasicType>(attr, exp_values); @@ -183,7 +258,7 @@ MultiValueReadViewTest::check_floating_point_values(const AttributeVector &attr) } void -MultiValueReadViewTest::check_string_values(const AttributeVector &attr) +MultiValueReadViewTest::check_string_values(const IAttributeVector &attr) { std::vector<const char *> exp_values{"42", "44"}; check_values_helper<const char *>(attr, exp_values); @@ -191,9 +266,9 @@ MultiValueReadViewTest::check_string_values(const AttributeVector &attr) } void -MultiValueReadViewTest::check_values(const AttributeVector& attr) +MultiValueReadViewTest::check_values(const IAttributeVector& attr) { - switch (attr.getConfig().basicType().type()) { + switch (attr.getBasicType()) { case BasicType::Type::INT8: check_integer_values<int8_t>(attr); break; @@ -221,6 +296,27 @@ MultiValueReadViewTest::check_values(const AttributeVector& attr) } std::shared_ptr<AttributeVector> +MultiValueReadViewTest::make_attribute(CollectionType collection_type, bool fast_search) +{ + auto param = GetParam(); + Config config(param.basic_type(), collection_type); + config.setFastSearch(fast_search); + auto attr = AttributeFactory::createAttribute("attr", config); + return attr; +} + +std::shared_ptr<ReadableAttributeVector> +MultiValueReadViewTest::make_imported_attribute(std::shared_ptr<AttributeVector> target) +{ + return ImportedAttributeVectorFactory::create("imported", + _reference_attribute, + std::make_shared<MockDocumentMetaStoreContext>(), + target, + std::make_shared<MockDocumentMetaStoreContext>(), + false); +} + +std::shared_ptr<AttributeVector> MultiValueReadViewTest::make_extendable_attribute(CollectionType collection_type) { vespalib::string name("attr"); @@ -267,15 +363,22 @@ MultiValueReadViewTest::make_extendable_attribute(CollectionType collection_type void MultiValueReadViewTest::test_normal_attribute_vector(CollectionType collection_type, bool fast_search) { - auto param = GetParam(); - Config config(param.basic_type(), collection_type); - config.setFastSearch(fast_search); - auto attr = AttributeFactory::createAttribute("attr", config); + auto attr = make_attribute(collection_type, fast_search); populate(*attr); check_values(*attr); } void +MultiValueReadViewTest::test_imported_attribute_vector(CollectionType collection_type, bool fast_search) +{ + auto attr = make_attribute(collection_type, fast_search); + populate(*attr); + auto imported_attr = make_imported_attribute(attr); + auto guard = imported_attr->makeReadGuard(false); + check_values(**guard); +} + +void MultiValueReadViewTest::test_extendable_attribute_vector(CollectionType collection_type) { auto attr = make_extendable_attribute(collection_type); @@ -306,6 +409,26 @@ TEST_P(MultiValueReadViewTest, test_enumerated_weighted_set) test_normal_attribute_vector(CollectionType::Type::WSET, true); }; +TEST_P(MultiValueReadViewTest, test_imported_array) +{ + test_imported_attribute_vector(CollectionType::Type::ARRAY, false); +}; + +TEST_P(MultiValueReadViewTest, test_imported_enumerated_array) +{ + test_imported_attribute_vector(CollectionType::Type::ARRAY, true); +}; + +TEST_P(MultiValueReadViewTest, test_importe_weighted_set) +{ + test_imported_attribute_vector(CollectionType::Type::WSET, false); +}; + +TEST_P(MultiValueReadViewTest, test_imported_enumerated_weighted_set) +{ + test_imported_attribute_vector(CollectionType::Type::WSET, true); +}; + TEST_P(MultiValueReadViewTest, test_extendable_array) { test_extendable_attribute_vector(CollectionType::Type::ARRAY); diff --git a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt index 108beb96833..5fa691394fb 100644 --- a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt @@ -62,6 +62,7 @@ vespa_add_library(searchlib_attribute OBJECT imported_attribute_vector.cpp imported_attribute_vector_factory.cpp imported_attribute_vector_read_guard.cpp + imported_multi_value_read_view.cpp imported_search_context.cpp integerbase.cpp ipostinglistsearchcontext.cpp diff --git a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.cpp b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.cpp index f1ae5252031..c8a6309c282 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.cpp +++ b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.cpp @@ -2,9 +2,11 @@ #include "imported_attribute_vector_read_guard.h" #include "imported_attribute_vector.h" +#include "imported_multi_value_read_view.h" #include "imported_search_context.h" #include "reference_attribute.h" #include <vespa/searchlib/query/query_term_simple.h> +#include <vespa/vespalib/util/stash.h> namespace search::attribute { @@ -120,7 +122,7 @@ const tensor::ITensorAttribute *ImportedAttributeVectorReadGuard::asTensorAttrib } const attribute::IMultiValueAttribute* ImportedAttributeVectorReadGuard::as_multi_value_attribute() const { - return nullptr; + return this; } BasicType::Type ImportedAttributeVectorReadGuard::getBasicType() const { @@ -156,6 +158,117 @@ bool ImportedAttributeVectorReadGuard::isImported() const return true; } +template <typename MultiValueType> +const IMultiValueReadView<MultiValueType>* +ImportedAttributeVectorReadGuard::make_read_view_helper(Tag<MultiValueType> tag, vespalib::Stash &stash) const +{ + auto target_mv_attr = _target_attribute.as_multi_value_attribute(); + if (target_mv_attr == nullptr) { + return nullptr; + } + auto target_read_view = target_mv_attr->make_read_view(tag, stash); + if (target_read_view == nullptr) { + return nullptr; + } + return &stash.create<ImportedMultiValueReadView<MultiValueType>>(_targetLids, target_read_view); +} + +const IArrayReadView<int8_t>* +ImportedAttributeVectorReadGuard::make_read_view(ArrayTag<int8_t> tag, vespalib::Stash& stash) const +{ + return make_read_view_helper(tag, stash); +} + +const IArrayReadView<int16_t>* +ImportedAttributeVectorReadGuard::make_read_view(ArrayTag<int16_t> tag, vespalib::Stash& stash) const +{ + return make_read_view_helper(tag, stash); +} + +const IArrayReadView<int32_t>* +ImportedAttributeVectorReadGuard::make_read_view(ArrayTag<int32_t> tag, vespalib::Stash& stash) const +{ + return make_read_view_helper(tag, stash); +} + +const IArrayReadView<int64_t>* +ImportedAttributeVectorReadGuard::make_read_view(ArrayTag<int64_t> tag, vespalib::Stash& stash) const +{ + return make_read_view_helper(tag, stash); +} + +const IArrayReadView<float>* +ImportedAttributeVectorReadGuard::make_read_view(ArrayTag<float> tag, vespalib::Stash& stash) const +{ + return make_read_view_helper(tag, stash); +} + +const IArrayReadView<double>* +ImportedAttributeVectorReadGuard::make_read_view(ArrayTag<double> tag, vespalib::Stash& stash) const +{ + return make_read_view_helper(tag, stash); +} + +const IArrayReadView<const char*>* +ImportedAttributeVectorReadGuard::make_read_view(ArrayTag<const char*> tag, vespalib::Stash& stash) const +{ + return make_read_view_helper(tag, stash); +} + +const IWeightedSetReadView<int8_t>* +ImportedAttributeVectorReadGuard::make_read_view(WeightedSetTag<int8_t> tag, vespalib::Stash& stash) const +{ + return make_read_view_helper(tag, stash); +} + +const IWeightedSetReadView<int16_t>* +ImportedAttributeVectorReadGuard::make_read_view(WeightedSetTag<int16_t> tag, vespalib::Stash& stash) const +{ + return make_read_view_helper(tag, stash); +} + +const IWeightedSetReadView<int32_t>* +ImportedAttributeVectorReadGuard::make_read_view(WeightedSetTag<int32_t> tag, vespalib::Stash& stash) const +{ + return make_read_view_helper(tag, stash); +} + +const IWeightedSetReadView<int64_t>* +ImportedAttributeVectorReadGuard::make_read_view(WeightedSetTag<int64_t> tag, vespalib::Stash& stash) const +{ + return make_read_view_helper(tag, stash); +} + +const IWeightedSetReadView<float>* +ImportedAttributeVectorReadGuard::make_read_view(WeightedSetTag<float> tag, vespalib::Stash& stash) const +{ + return make_read_view_helper(tag, stash); +} + +const IWeightedSetReadView<double>* +ImportedAttributeVectorReadGuard:: make_read_view(WeightedSetTag<double> tag, vespalib::Stash& stash) const +{ + return make_read_view_helper(tag, stash); +} + +const IWeightedSetReadView<const char*>* +ImportedAttributeVectorReadGuard::make_read_view(WeightedSetTag<const char*> tag, vespalib::Stash& stash) const +{ + return make_read_view_helper(tag, stash); +} + +const IArrayEnumReadView* +ImportedAttributeVectorReadGuard::make_read_view(ArrayEnumTag tag, vespalib::Stash& stash) const +{ + return make_read_view_helper(tag, stash); +} + +const IWeightedSetEnumReadView* +ImportedAttributeVectorReadGuard::make_read_view(WeightedSetEnumTag tag, vespalib::Stash& stash) const +{ + return make_read_view_helper(tag, stash); +} + bool ImportedAttributeVectorReadGuard::isUndefined(DocId doc) const { return _target_attribute.isUndefined(getTargetLid(doc)); } diff --git a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.h b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.h index f5b896e2da5..9e596078678 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.h +++ b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.h @@ -5,6 +5,7 @@ #include "attribute_read_guard.h" #include "attributeguard.h" #include <vespa/searchcommon/attribute/iattributevector.h> +#include <vespa/searchcommon/attribute/i_multi_value_attribute.h> #include <vespa/searchlib/common/i_document_meta_store_context.h> #include <vespa/vespalib/datastore/atomic_value_wrapper.h> #include <vespa/vespalib/util/arrayref.h> @@ -27,7 +28,8 @@ class ReferenceAttribute; * boundary check is setup during construction. */ class ImportedAttributeVectorReadGuard : public IAttributeVector, - public AttributeReadGuard + public AttributeReadGuard, + public IMultiValueAttribute { private: using AtomicTargetLid = vespalib::datastore::AtomicValueWrapper<uint32_t>; @@ -86,6 +88,24 @@ public: uint32_t getCommittedDocIdLimit() const override; bool isImported() const override; bool isUndefined(DocId doc) const override; + template <typename MultiValueType> + const IMultiValueReadView<MultiValueType>* make_read_view_helper(Tag<MultiValueType> tag, vespalib::Stash& stash) const; + const IArrayReadView<int8_t>* make_read_view(ArrayTag<int8_t> tag, vespalib::Stash& stash) const override; + const IArrayReadView<int16_t>* make_read_view(ArrayTag<int16_t> tag, vespalib::Stash& stash) const override; + const IArrayReadView<int32_t>* make_read_view(ArrayTag<int32_t> tag, vespalib::Stash& stash) const override; + const IArrayReadView<int64_t>* make_read_view(ArrayTag<int64_t> tag, vespalib::Stash& stash) const override; + const IArrayReadView<float>* make_read_view(ArrayTag<float> tag, vespalib::Stash& stash) const override; + const IArrayReadView<double>* make_read_view(ArrayTag<double> tag, vespalib::Stash& stash) const override; + const IArrayReadView<const char*>* make_read_view(ArrayTag<const char*> tag, vespalib::Stash& stash) const override; + const IWeightedSetReadView<int8_t>* make_read_view(WeightedSetTag<int8_t> tag, vespalib::Stash& stash) const override; + const IWeightedSetReadView<int16_t>* make_read_view(WeightedSetTag<int16_t> tag, vespalib::Stash& stash) const override; + const IWeightedSetReadView<int32_t>* make_read_view(WeightedSetTag<int32_t> tag, vespalib::Stash& stash) const override; + const IWeightedSetReadView<int64_t>* make_read_view(WeightedSetTag<int64_t> tag, vespalib::Stash& stash) const override; + const IWeightedSetReadView<float>* make_read_view(WeightedSetTag<float> tag, vespalib::Stash& stash) const override; + const IWeightedSetReadView<double>* make_read_view(WeightedSetTag<double> tag, vespalib::Stash& stash) const override; + const IWeightedSetReadView<const char*>* make_read_view(WeightedSetTag<const char*> tag, vespalib::Stash& stash) const override; + const IArrayEnumReadView* make_read_view(ArrayEnumTag tag, vespalib::Stash& stash) const override; + const IWeightedSetEnumReadView* make_read_view(WeightedSetEnumTag tag, vespalib::Stash& stash) const override; protected: long onSerializeForAscendingSort(DocId doc, void * serTo, long available, diff --git a/searchlib/src/vespa/searchlib/attribute/imported_multi_value_read_view.cpp b/searchlib/src/vespa/searchlib/attribute/imported_multi_value_read_view.cpp new file mode 100644 index 00000000000..b36d321694e --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/imported_multi_value_read_view.cpp @@ -0,0 +1,47 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "imported_multi_value_read_view.h" + +using vespalib::datastore::AtomicEntryRef; + +namespace search::attribute { + +template <typename MultiValueType> +ImportedMultiValueReadView<MultiValueType>::ImportedMultiValueReadView(TargetLids target_lids, const IMultiValueReadView<MultiValueType>* target_read_view) + : _target_lids(target_lids), + _target_read_view(target_read_view) +{ +} + +template <typename MultiValueType> +ImportedMultiValueReadView<MultiValueType>::~ImportedMultiValueReadView() = default; + +template <typename MultiValueType> +vespalib::ConstArrayRef<MultiValueType> +ImportedMultiValueReadView<MultiValueType>::get_values(uint32_t docid) const +{ + auto target_lid = get_target_lid(docid); + return _target_read_view->get_values(target_lid); +} + +using multivalue::WeightedValue; + +template class ImportedMultiValueReadView<int8_t>; +template class ImportedMultiValueReadView<int16_t>; +template class ImportedMultiValueReadView<int32_t>; +template class ImportedMultiValueReadView<int64_t>; +template class ImportedMultiValueReadView<float>; +template class ImportedMultiValueReadView<double>; +template class ImportedMultiValueReadView<AtomicEntryRef>; +template class ImportedMultiValueReadView<const char*>; + +template class ImportedMultiValueReadView<WeightedValue<int8_t>>; +template class ImportedMultiValueReadView<WeightedValue<int16_t>>; +template class ImportedMultiValueReadView<WeightedValue<int32_t>>; +template class ImportedMultiValueReadView<WeightedValue<int64_t>>; +template class ImportedMultiValueReadView<WeightedValue<float>>; +template class ImportedMultiValueReadView<WeightedValue<double>>; +template class ImportedMultiValueReadView<WeightedValue<AtomicEntryRef>>; +template class ImportedMultiValueReadView<WeightedValue<const char*>>; + +} diff --git a/searchlib/src/vespa/searchlib/attribute/imported_multi_value_read_view.h b/searchlib/src/vespa/searchlib/attribute/imported_multi_value_read_view.h new file mode 100644 index 00000000000..9ec54feca9e --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/imported_multi_value_read_view.h @@ -0,0 +1,33 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/searchcommon/attribute/i_multi_value_read_view.h> +#include <vespa/vespalib/datastore/atomic_value_wrapper.h> + +namespace search::attribute { + +/** + * Multi value read view adapter for imported atributes vectors. + * Performs lid mapping. + * @tparam MultiValueType The multi-value type of the data to access. + */ +template <typename MultiValueType> +class ImportedMultiValueReadView : public IMultiValueReadView<MultiValueType> +{ + using AtomicTargetLid = vespalib::datastore::AtomicValueWrapper<uint32_t>; + using TargetLids = vespalib::ConstArrayRef<AtomicTargetLid>; + TargetLids _target_lids; + const IMultiValueReadView<MultiValueType>* _target_read_view; + + uint32_t get_target_lid(uint32_t lid) const { + // Check range to avoid reading memory beyond end of mapping array + return lid < _target_lids.size() ? _target_lids[lid].load_acquire() : 0u; + } +public: + ImportedMultiValueReadView(TargetLids target_lids, const IMultiValueReadView<MultiValueType>* target_read_view); + ~ImportedMultiValueReadView() override; + vespalib::ConstArrayRef<MultiValueType> get_values(uint32_t docid) const override; +}; + +} |