// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. /** * @class search::SearchVisitor * * @brief Visitor that applies a search query to visitor data and converts them to a QueryResultCommand */ #pragma once #include "attrvector.h" #include namespace search { // Translates the actual value type to the type required by IExtendAttribute. template struct AddValueType { using Type = int64_t; }; template <> struct AddValueType { using Type = double; }; //******************** CollectionType::SINGLE ********************// template struct AttributeTemplate { using Type = search::IntegerAttributeTemplate; }; template <> struct AttributeTemplate { using Type = search::FloatingPointAttributeTemplate; }; template class SingleExtAttribute : public NumericDirectAttrVector, typename AttributeTemplate::Type>, public IExtendAttribute { using Super = typename SingleExtAttribute::NumDirectAttrVec; using Config = typename Super::Config; using BasicType = typename Super::BasicType; using QueryTermSimpleUP = typename Super::QueryTermSimpleUP; std::unique_ptr getSearch(QueryTermSimpleUP term, const attribute::SearchContextParams & params) const override; IExtendAttribute * getExtendInterface() override { return this; } public: SingleExtAttribute(const vespalib::string &name); bool addDoc(typename Super::DocId &docId) override; bool add(typename AddValueType::Type v, int32_t = 1) override; bool onLoad(vespalib::Executor *) override { return false; // Emulate that this attribute is never loaded } void onAddDocs(typename Super::DocId lidLimit) override; }; using SingleInt8ExtAttribute = SingleExtAttribute; using SingleInt16ExtAttribute = SingleExtAttribute; using SingleInt32ExtAttribute = SingleExtAttribute; using SingleInt64ExtAttribute = SingleExtAttribute; using SingleFloatExtAttribute = SingleExtAttribute; using SingleIntegerExtAttribute = SingleInt64ExtAttribute; class SingleStringExtAttribute : public StringDirectAttrVector< AttrVector::Features >, public IExtendAttribute { IExtendAttribute * getExtendInterface() override { return this; } public: SingleStringExtAttribute(const vespalib::string & name); bool addDoc(DocId & docId) override; bool add(const char * v, int32_t w = 1) override; bool onLoad(vespalib::Executor *) override { return false; // Emulate that this attribute is never loaded } void onAddDocs(DocId ) override { } }; //******************** CollectionType::ARRAY ********************// template class MultiExtAttribute : public NumericDirectAttrVector, typename AttributeTemplate::Type>, public IExtendAttribute, public attribute::IMultiValueAttribute { protected: using Super = typename MultiExtAttribute::NumDirectAttrVec; using Config = typename Super::Config; using BasicType = typename Super::BasicType; using QueryTermSimpleUP = AttributeVector::QueryTermSimpleUP; MultiExtAttribute(const vespalib::string &name, const attribute::CollectionType &ctype); private: std::unique_ptr getSearch(QueryTermSimpleUP term, const attribute::SearchContextParams & params) const override; IExtendAttribute * getExtendInterface() override { return this; } public: MultiExtAttribute(const vespalib::string &name); ~MultiExtAttribute() override; bool addDoc(typename Super::DocId &docId) override; bool add(typename AddValueType::Type v, int32_t = 1) override; bool onLoad(vespalib::Executor *) override { return false; // Emulate that this attribute is never loaded } void onAddDocs(uint32_t lidLimit) override; const attribute::IMultiValueAttribute* as_multi_value_attribute() const override; // Implements attribute::IMultiValueAttribute const attribute::IArrayReadView* make_read_view(attribute::IMultiValueAttribute::ArrayTag, vespalib::Stash& stash) const override; const attribute::IWeightedSetReadView* make_read_view(attribute::IMultiValueAttribute::WeightedSetTag, vespalib::Stash& stash) const override; }; using MultiInt8ExtAttribute = MultiExtAttribute; using MultiInt16ExtAttribute = MultiExtAttribute; using MultiInt32ExtAttribute = MultiExtAttribute; using MultiInt64ExtAttribute = MultiExtAttribute; using MultiFloatExtAttribute = MultiExtAttribute; using MultiIntegerExtAttribute = MultiInt64ExtAttribute; class MultiStringExtAttribute : public StringDirectAttrVector< AttrVector::Features >, public IExtendAttribute, public attribute::IMultiValueAttribute { IExtendAttribute * getExtendInterface() override { return this; } protected: MultiStringExtAttribute(const vespalib::string & name, const attribute::CollectionType & ctype); public: MultiStringExtAttribute(const vespalib::string & name); bool addDoc(DocId & docId) override; bool add(const char * v, int32_t w = 1) override; bool onLoad(vespalib::Executor *) override { return false; // Emulate that this attribute is never loaded } void onAddDocs(DocId ) override { } const attribute::IMultiValueAttribute* as_multi_value_attribute() const override; // Implements attribute::IMultiValueAttribute const attribute::IArrayReadView* make_read_view(attribute::IMultiValueAttribute::ArrayTag, vespalib::Stash& stash) const override; const attribute::IWeightedSetReadView* make_read_view(attribute::IMultiValueAttribute::WeightedSetTag, vespalib::Stash& stash) const override; }; //******************** CollectionType::WSET ********************// template class WeightedSetExtAttributeBase : public B { private: std::vector _weights; protected: void addWeight(int32_t w); int32_t getWeightHelper(AttributeVector::DocId docId, uint32_t idx) const { return _weights[this->_idx[docId] + idx]; } WeightedSetExtAttributeBase(const vespalib::string & name); ~WeightedSetExtAttributeBase(); const std::vector& get_weights() const noexcept { return _weights; } }; class WeightedSetIntegerExtAttribute : public WeightedSetExtAttributeBase { std::unique_ptr getSearch(QueryTermSimpleUP term, const attribute::SearchContextParams & params) const override; public: WeightedSetIntegerExtAttribute(const vespalib::string & name); ~WeightedSetIntegerExtAttribute(); bool add(int64_t v, int32_t w = 1) override; uint32_t get(DocId doc, AttributeVector::WeightedInt * v, uint32_t sz) const override; // Implements attribute::IMultiValueAttribute const attribute::IWeightedSetReadView* make_read_view(attribute::IMultiValueAttribute::WeightedSetTag, vespalib::Stash& stash) const override; }; class WeightedSetFloatExtAttribute : public WeightedSetExtAttributeBase { std::unique_ptr getSearch(QueryTermSimpleUP term, const attribute::SearchContextParams & params) const override; public: WeightedSetFloatExtAttribute(const vespalib::string & name); ~WeightedSetFloatExtAttribute(); bool add(double v, int32_t w = 1) override; uint32_t get(DocId doc, AttributeVector::WeightedFloat * v, uint32_t sz) const override; // Implements attribute::IMultiValueAttribute const attribute::IWeightedSetReadView* make_read_view(attribute::IMultiValueAttribute::WeightedSetTag, vespalib::Stash& stash) const override; }; class WeightedSetStringExtAttribute : public WeightedSetExtAttributeBase { private: const char * getHelper(DocId doc, int idx) const { return &_buffer[_offsets[_idx[doc] + idx]]; } template uint32_t getAllHelper(DocId doc, T * v, uint32_t sz) const { uint32_t valueCount = _idx[doc + 1] - _idx[doc]; uint32_t num2Read = std::min(valueCount, sz); for (uint32_t i = 0; i < num2Read; ++i) { v[i] = T(getHelper(doc, i), getWeightHelper(doc, i)); } return valueCount; } public: WeightedSetStringExtAttribute(const vespalib::string & name); ~WeightedSetStringExtAttribute(); bool add(const char * v, int32_t w = 1) override; uint32_t get(DocId doc, AttributeVector::WeightedString * v, uint32_t sz) const override; uint32_t get(DocId doc, AttributeVector::WeightedConstChar * v, uint32_t sz) const override; // Implements attribute::IMultiValueAttribute const attribute::IWeightedSetReadView* make_read_view(attribute::IMultiValueAttribute::WeightedSetTag, vespalib::Stash& stash) const override; }; } // namespace search