diff options
author | Geir Storli <geirstorli@yahoo.no> | 2018-04-23 11:26:19 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-23 11:26:19 +0200 |
commit | 506f66bda3b65f41496064307ba010bd9c353101 (patch) | |
tree | da25bb6bf6590006ef437a39723aab7746507da3 /searchlib | |
parent | bc6e85549a8239c71edffc26927b8e989e682f18 (diff) | |
parent | dc10c2f5fbd33f3a83d0dade44ceffa7425b1fcb (diff) |
Merge pull request #5647 from vespa-engine/toregge/use-getattributereadguard-method-in-attribute-context
Use getAttributeReadGuard in AttributeContext
Diffstat (limited to 'searchlib')
29 files changed, 182 insertions, 135 deletions
diff --git a/searchlib/src/tests/attribute/guard/attributeguard.cpp b/searchlib/src/tests/attribute/guard/attributeguard.cpp index 314c5f336e0..b042806eb35 100644 --- a/searchlib/src/tests/attribute/guard/attributeguard.cpp +++ b/searchlib/src/tests/attribute/guard/attributeguard.cpp @@ -20,7 +20,7 @@ AttributeGuardTest::Main() AttributeVector::SP ssattr(new SingleStringExtAttribute("ss1")); - AttributeEnumGuard guard(ssattr); + AttributeGuard guard(ssattr); EXPECT_TRUE(guard.valid()); TEST_DONE(); diff --git a/searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp b/searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp index 53ad20c3b03..e8e16ffcc98 100644 --- a/searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp +++ b/searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp @@ -20,7 +20,7 @@ struct Fixture : ImportedAttributeFixture { Fixture(bool useSearchCache = false) : ImportedAttributeFixture(useSearchCache) {} std::unique_ptr<ImportedSearchContext> create_context(std::unique_ptr<QueryTermSimple> term) { - return std::make_unique<ImportedSearchContext>(std::move(term), SearchContextParams(), *imported_attr); + return std::make_unique<ImportedSearchContext>(std::move(term), SearchContextParams(), *imported_attr, *target_attr); } std::unique_ptr<SearchIterator> create_iterator( diff --git a/searchlib/src/tests/attribute/searchable/attribute_searchable_adapter_test.cpp b/searchlib/src/tests/attribute/searchable/attribute_searchable_adapter_test.cpp index 1306a0aaaac..e5af6931977 100644 --- a/searchlib/src/tests/attribute/searchable/attribute_searchable_adapter_test.cpp +++ b/searchlib/src/tests/attribute/searchable/attribute_searchable_adapter_test.cpp @@ -7,6 +7,7 @@ #include <vespa/searchlib/attribute/attributecontext.h> #include <vespa/searchlib/attribute/attributeguard.h> #include <vespa/searchlib/attribute/attributevector.h> +#include <vespa/searchlib/attribute/attribute_read_guard.h> #include <vespa/searchlib/attribute/extendableattributes.h> #include <vespa/searchlib/attribute/iattributemanager.h> #include <vespa/searchlib/attribute/predicate_attribute.h> @@ -27,7 +28,6 @@ #include <vespa/searchlib/queryeval/wand/parallel_weak_and_search.h> #include <memory> -using search::AttributeEnumGuard; using search::AttributeFactory; using search::AttributeGuard; using search::AttributeVector; @@ -100,13 +100,13 @@ public: } } - AttributeGuard::UP getAttributeStableEnum(const string &name) const override { - if (name == field) { - return AttributeGuard::UP(new AttributeEnumGuard(_attribute_vector)); - } else if (name == other) { - return AttributeGuard::UP(new AttributeEnumGuard(_other)); + std::unique_ptr<attribute::AttributeReadGuard> getAttributeReadGuard(const string &name, bool stableEnumGuard) const override { + if (name == field && _attribute_vector) { + return _attribute_vector->makeReadGuard(stableEnumGuard); + } else if (name == other && _other) { + return _other->makeReadGuard(stableEnumGuard); } else { - return AttributeGuard::UP(nullptr); + return std::unique_ptr<attribute::AttributeReadGuard>(); } } diff --git a/searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp b/searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp index c22807f8bf5..39bbb8fb5ad 100644 --- a/searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp +++ b/searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp @@ -5,6 +5,7 @@ #include <vespa/searchlib/attribute/attribute_weighted_set_blueprint.h> #include <vespa/searchlib/attribute/attributecontext.h> #include <vespa/searchlib/attribute/attributevector.h> +#include <vespa/searchlib/attribute/attribute_read_guard.h> #include <vespa/searchlib/attribute/extendableattributes.h> #include <vespa/searchlib/attribute/singlestringattribute.h> #include <vespa/searchlib/attribute/attributefactory.h> @@ -50,8 +51,13 @@ public: return AttributeGuard::UP(new AttributeGuard(lookup(name))); } - virtual AttributeGuard::UP getAttributeStableEnum(const vespalib::string &name) const override { - return AttributeGuard::UP(new AttributeEnumGuard(lookup(name))); + virtual std::unique_ptr<attribute::AttributeReadGuard> getAttributeReadGuard(const string &name, bool stableEnumGuard) const override { + auto vector = lookup(name); + if (vector) { + return vector->makeReadGuard(stableEnumGuard); + } else { + return std::unique_ptr<attribute::AttributeReadGuard>(); + } } virtual void getAttributeList(std::vector<AttributeGuard> &list) const override { diff --git a/searchlib/src/tests/attribute/searchable/attributeblueprint_test.cpp b/searchlib/src/tests/attribute/searchable/attributeblueprint_test.cpp index 6753153c224..dc7cf53d188 100644 --- a/searchlib/src/tests/attribute/searchable/attributeblueprint_test.cpp +++ b/searchlib/src/tests/attribute/searchable/attributeblueprint_test.cpp @@ -4,6 +4,7 @@ #include <vespa/searchlib/attribute/attribute_blueprint_factory.h> #include <vespa/searchlib/attribute/attributecontext.h> #include <vespa/searchlib/attribute/attributevector.h> +#include <vespa/searchlib/attribute/attribute_read_guard.h> #include <vespa/searchlib/attribute/extendableattributes.h> #include <vespa/searchlib/attribute/singlenumericattribute.h> #include <vespa/searchlib/attribute/singlenumericattribute.hpp> @@ -17,7 +18,6 @@ #include <vespa/log/log.h> LOG_SETUP("attributeblueprint_test"); -using search::AttributeEnumGuard; using search::AttributeGuard; using search::AttributeVector; using search::IAttributeManager; @@ -64,10 +64,13 @@ public: return AttributeGuard::UP(new AttributeGuard(_attribute_vector)); } - AttributeGuard::UP getAttributeStableEnum(const string &) const override { - return AttributeGuard::UP(new AttributeEnumGuard(_attribute_vector)); + virtual std::unique_ptr<attribute::AttributeReadGuard> getAttributeReadGuard(const string &, bool stableEnumGuard) const override { + if (_attribute_vector) { + return _attribute_vector->makeReadGuard(stableEnumGuard); + } else { + return std::unique_ptr<attribute::AttributeReadGuard>(); + } } - void getAttributeList(vector<AttributeGuard> &) const override { assert(!"Not implemented"); } diff --git a/searchlib/src/vespa/searchlib/attribute/attributecontext.cpp b/searchlib/src/vespa/searchlib/attribute/attributecontext.cpp index 0a3fe963aae..df8e7858f5f 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributecontext.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attributecontext.cpp @@ -2,6 +2,7 @@ #include "attributecontext.h" #include "attributevector.h" +#include "attribute_read_guard.h" #include <vespa/vespalib/stllike/hash_map.hpp> using namespace search; @@ -14,20 +15,19 @@ AttributeContext::getAttribute(AttributeMap & map, const string & name, bool sta { AttributeMap::const_iterator itr = map.find(name); if (itr != map.end()) { - return itr->second->get(); - } else { - AttributeGuard::UP ret; - if (stableEnum) { - ret = _manager.getAttributeStableEnum(name); + if (itr->second) { + return itr->second->attribute(); } else { - ret = _manager.getAttribute(name); + return nullptr; } - if (ret) { - const AttributeGuard & guard = *ret; - map[name] = std::move(ret); - return guard.get(); + } else { + auto readGuard = _manager.getAttributeReadGuard(name, stableEnum); + const IAttributeVector *attribute = nullptr; + if (readGuard) { + attribute = readGuard->attribute(); } - return nullptr; + map[name] = std::move(readGuard); + return attribute; } } diff --git a/searchlib/src/vespa/searchlib/attribute/attributecontext.h b/searchlib/src/vespa/searchlib/attribute/attributecontext.h index 80abe84f8ef..6a158a26229 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributecontext.h +++ b/searchlib/src/vespa/searchlib/attribute/attributecontext.h @@ -16,7 +16,7 @@ namespace search { class AttributeContext : public attribute::IAttributeContext { private: - typedef vespalib::hash_map<string, AttributeGuard::UP> AttributeMap; + typedef vespalib::hash_map<string, std::unique_ptr<attribute::AttributeReadGuard>> AttributeMap; const search::IAttributeManager & _manager; mutable AttributeMap _attributes; diff --git a/searchlib/src/vespa/searchlib/attribute/attributeguard.cpp b/searchlib/src/vespa/searchlib/attribute/attributeguard.cpp index 3b41ca9364b..02f1eb39853 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributeguard.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attributeguard.cpp @@ -16,31 +16,6 @@ AttributeGuard::AttributeGuard(const AttributeVector::SP & attr) : { } -AttributeEnumGuard::AttributeEnumGuard(const AttributeVector::SP & attr) : - AttributeGuard(attr), - _lock() -{ - takeLock(); -} - -AttributeEnumGuard::AttributeEnumGuard(const AttributeGuard & attr) : - AttributeGuard(attr), - _lock() -{ - takeLock(); -} - -AttributeEnumGuard::~AttributeEnumGuard() { } - -void AttributeEnumGuard::takeLock() { - if (valid()) { - std::shared_lock<std::shared_timed_mutex> take(get()->getEnumLock(), - std::defer_lock); - _lock = std::move(take); - _lock.lock(); - } -} - template class ComponentGuard<AttributeVector>; } diff --git a/searchlib/src/vespa/searchlib/attribute/attributeguard.h b/searchlib/src/vespa/searchlib/attribute/attributeguard.h index ea389f8dda7..09538b75334 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributeguard.h +++ b/searchlib/src/vespa/searchlib/attribute/attributeguard.h @@ -23,21 +23,5 @@ public: AttributeGuard(const AttributeVectorSP & attribute); }; -/** - * This class makes sure that the attribute vector is not updated with enum changes while the guard is held. - **/ -class AttributeEnumGuard : public AttributeGuard -{ -public: - AttributeEnumGuard(const AttributeEnumGuard &) = delete; - AttributeEnumGuard & operator = (const AttributeEnumGuard &) = delete; - explicit AttributeEnumGuard(const AttributeVectorSP & attribute); - explicit AttributeEnumGuard(const AttributeGuard & attribute); - ~AttributeEnumGuard(); -private: - mutable std::shared_lock<std::shared_timed_mutex> _lock; - void takeLock(); -}; - } diff --git a/searchlib/src/vespa/searchlib/attribute/attributemanager.cpp b/searchlib/src/vespa/searchlib/attribute/attributemanager.cpp index f10f3491ac0..402824327ff 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributemanager.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attributemanager.cpp @@ -3,6 +3,7 @@ #include "attributemanager.h" #include "attributecontext.h" #include "attributefactory.h" +#include "attribute_read_guard.h" #include "attrvector.h" #include "attributefile.h" #include "interlock.h" @@ -177,15 +178,15 @@ AttributeManager::getAttribute(const string & name) const return attrGuard; } -AttributeGuard::UP -AttributeManager::getAttributeStableEnum(const string & name) const +std::unique_ptr<attribute::AttributeReadGuard> +AttributeManager::getAttributeReadGuard(const string &name, bool stableEnumGuard) const { - AttributeGuard::UP attrGuard(new AttributeEnumGuard(VectorHolder())); const VectorHolder * vh = findAndLoadAttribute(name); - if ( vh != NULL ) { - attrGuard.reset(new AttributeEnumGuard(*vh)); + if (vh != nullptr) { + return (*vh)->makeReadGuard(stableEnumGuard); + } else { + return std::unique_ptr<attribute::AttributeReadGuard>(); } - return attrGuard; } bool diff --git a/searchlib/src/vespa/searchlib/attribute/attributemanager.h b/searchlib/src/vespa/searchlib/attribute/attributemanager.h index 3b23881e3bc..7f3937a7721 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributemanager.h +++ b/searchlib/src/vespa/searchlib/attribute/attributemanager.h @@ -37,7 +37,7 @@ public: const VectorHolder * getAttributeRef(const string & name) const; AttributeGuard::UP getAttribute(const string & name) const override; - AttributeGuard::UP getAttributeStableEnum(const string & name) const override; + std::unique_ptr<attribute::AttributeReadGuard> getAttributeReadGuard(const string &name, bool stableEnumGuard) const override; /** * This will load attributes in the most memory economical way by loading largest first. */ diff --git a/searchlib/src/vespa/searchlib/attribute/attributevector.cpp b/searchlib/src/vespa/searchlib/attribute/attributevector.cpp index e94eaa3f542..e92c7e38114 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributevector.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attributevector.cpp @@ -330,6 +330,28 @@ AttributeVector::getCollectionType() const { } bool +AttributeVector::getIsFilter() const { + return _config.getIsFilter(); +} + +bool +AttributeVector::getIsFastSearch() const { + return _config.fastSearch(); +} + +uint32_t +AttributeVector::getCommittedDocIdLimitSlow() const +{ + return getCommittedDocIdLimit(); +} + +bool +AttributeVector::isImported() const +{ + return false; +} + +bool AttributeVector::headerTypeOK(const vespalib::GenericHeader &header) const { return header.hasTag(dataTypeTag) && @@ -886,12 +908,30 @@ AttributeVector::getEstimatedShrinkLidSpaceGain() const return canFree; } + +namespace { + +class ReadGuard : public attribute::AttributeReadGuard +{ + using GenerationHandler = vespalib::GenerationHandler; + GenerationHandler::Guard _generationGuard; + using EnumGuard = std::shared_lock<std::shared_timed_mutex>; + EnumGuard _enumGuard; +public: + ReadGuard(const attribute::IAttributeVector *attr, GenerationHandler::Guard &&generationGuard, std::shared_timed_mutex *enumLock) + : attribute::AttributeReadGuard(attr), + _generationGuard(std::move(generationGuard)), + _enumGuard(enumLock != nullptr ? EnumGuard(*enumLock) : EnumGuard()) + { + } +}; + +} + std::unique_ptr<attribute::AttributeReadGuard> AttributeVector::makeReadGuard(bool stableEnumGuard) const { - (void) stableEnumGuard; - // TODO: implement - return std::unique_ptr<attribute::AttributeReadGuard>(); + return std::make_unique<ReadGuard>(this, _genHandler.takeGuard(), stableEnumGuard ? &_enumLock : nullptr); } MemoryUsage diff --git a/searchlib/src/vespa/searchlib/attribute/attributevector.h b/searchlib/src/vespa/searchlib/attribute/attributevector.h index 5917972b4fe..9d69bf587ed 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributevector.h +++ b/searchlib/src/vespa/searchlib/attribute/attributevector.h @@ -431,6 +431,10 @@ public: // Implements IAttributeVector virtual BasicType::Type getBasicType() const override; virtual CollectionType::Type getCollectionType() const override; + virtual bool getIsFilter() const override; + virtual bool getIsFastSearch() const override; + virtual uint32_t getCommittedDocIdLimitSlow() const override; + virtual bool isImported() const override; /** * Updates the base file name of this attribute vector and saves @@ -590,7 +594,7 @@ private: BaseName _baseFileName; Config _config; std::shared_ptr<attribute::Interlock> _interlock; - std::shared_timed_mutex _enumLock; + mutable std::shared_timed_mutex _enumLock; GenerationHandler _genHandler; GenerationHolder _genHolder; Status _status; @@ -626,7 +630,6 @@ private: std::shared_timed_mutex & getEnumLock() { return _enumLock; } friend class ComponentGuard<AttributeVector>; - friend class AttributeEnumGuard; friend class AttributeValueGuard; friend class AttributeTest; friend class AttributeManagerTest; diff --git a/searchlib/src/vespa/searchlib/attribute/iattributemanager.h b/searchlib/src/vespa/searchlib/attribute/iattributemanager.h index 5dc692d56a8..079463dd290 100644 --- a/searchlib/src/vespa/searchlib/attribute/iattributemanager.h +++ b/searchlib/src/vespa/searchlib/attribute/iattributemanager.h @@ -8,6 +8,8 @@ namespace search { +namespace attribute { class AttributeReadGuard; } + /** * This is an interface used to access all registered attribute vectors. **/ @@ -27,13 +29,13 @@ public: virtual AttributeGuard::UP getAttribute(const string & name) const = 0; /** - * Returns a view of the attribute vector with the given name. - * Makes sure that the underlying enum values are stable during the use of this attribute vector. + * Returns a read view of the attribute vector with the given name. * * @param name name of the attribute vector. - * @return view of the attribute vector or empty view if the attribute vector does not exists. + * @param stableEnumGuard flag to block enumeration changes during use of the attribute vector via the view. + * @return read view of the attribute vector if the attribute vector exists **/ - virtual AttributeGuard::UP getAttributeStableEnum(const string & name) const = 0; + virtual std::unique_ptr<attribute::AttributeReadGuard> getAttributeReadGuard(const string &name, bool stableEnumGuard) const = 0; /** * Fill the given list with all attribute vectors registered in this manager. diff --git a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.cpp b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.cpp index 62244b2c3d6..37969bc1eed 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.cpp +++ b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.cpp @@ -10,7 +10,7 @@ namespace search::attribute { ImportedAttributeVector::ImportedAttributeVector( vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, - std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<ReadableAttributeVector> target_attribute, std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, bool use_search_cache) : _name(name), @@ -24,7 +24,7 @@ ImportedAttributeVector::ImportedAttributeVector( ImportedAttributeVector::ImportedAttributeVector(vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, - std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<ReadableAttributeVector> target_attribute, std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, std::shared_ptr<BitVectorSearchCache> search_cache) : _name(name), diff --git a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.h b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.h index fa5470d2449..6ad69fa88eb 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.h +++ b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.h @@ -3,19 +3,18 @@ #pragma once #include "readable_attribute_vector.h" -#include "reference_attribute.h" #include <vespa/vespalib/stllike/string.h> #include <memory> namespace search { -class AttributeGuard; -class AttributeEnumGuard; class IDocumentMetaStoreContext; namespace attribute { class BitVectorSearchCache; +class ReadableAttributeVector; +class ReferenceAttribute; /** * Attribute vector which does not store values of its own, but rather serves as a @@ -32,12 +31,12 @@ public: using SP = std::shared_ptr<ImportedAttributeVector>; ImportedAttributeVector(vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, - std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<ReadableAttributeVector> target_attribute, std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, bool use_search_cache); ImportedAttributeVector(vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, - std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<ReadableAttributeVector> target_attribute, std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, std::shared_ptr<BitVectorSearchCache> search_cache); virtual ~ImportedAttributeVector(); @@ -45,7 +44,7 @@ public: const std::shared_ptr<ReferenceAttribute>& getReferenceAttribute() const noexcept { return _reference_attribute; } - const std::shared_ptr<AttributeVector>& getTargetAttribute() const noexcept { + const std::shared_ptr<ReadableAttributeVector>& getTargetAttribute() const noexcept { return _target_attribute; } const std::shared_ptr<IDocumentMetaStoreContext> &getDocumentMetaStore() const { @@ -64,7 +63,7 @@ public: protected: vespalib::string _name; std::shared_ptr<ReferenceAttribute> _reference_attribute; - std::shared_ptr<AttributeVector> _target_attribute; + std::shared_ptr<ReadableAttributeVector> _target_attribute; std::shared_ptr<IDocumentMetaStoreContext> _document_meta_store; std::shared_ptr<BitVectorSearchCache> _search_cache; }; diff --git a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_factory.cpp b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_factory.cpp index 8161abe61f4..ae0fdcf1b83 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_factory.cpp +++ b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_factory.cpp @@ -2,6 +2,8 @@ #include "imported_attribute_vector_factory.h" #include "imported_attribute_vector.h" +#include "attribute_read_guard.h" +#include <vespa/searchcommon/attribute/iattributevector.h> #include <vespa/searchlib/tensor/imported_tensor_attribute_vector.h> namespace search::attribute { @@ -10,9 +12,14 @@ using search::tensor::ImportedTensorAttributeVector; namespace { -BasicType::Type getBasicType(const std::shared_ptr<AttributeVector> &attr) +BasicType::Type getBasicType(const std::shared_ptr<attribute::ReadableAttributeVector> &attr) { - return attr ? attr->getBasicType() : BasicType::Type::NONE; + if (attr) { + auto readGuard = attr->makeReadGuard(false); + return readGuard->attribute()->getBasicType(); + } else { + return BasicType::Type::NONE; + } } } @@ -20,7 +27,7 @@ BasicType::Type getBasicType(const std::shared_ptr<AttributeVector> &attr) std::shared_ptr<ImportedAttributeVector> ImportedAttributeVectorFactory::create(vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, - std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<attribute::ReadableAttributeVector> target_attribute, std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, bool use_search_cache) { @@ -36,7 +43,7 @@ ImportedAttributeVectorFactory::create(vespalib::stringref name, std::shared_ptr<ImportedAttributeVector> ImportedAttributeVectorFactory::create(vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, - std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<attribute::ReadableAttributeVector> target_attribute, std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, std::shared_ptr<BitVectorSearchCache> search_cache) { diff --git a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_factory.h b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_factory.h index 363fb9f29bc..9c3b5a8bb47 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_factory.h +++ b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_factory.h @@ -7,13 +7,13 @@ namespace search { -class AttributeVector; class IDocumentMetaStoreContext; namespace attribute { class BitVectorSearchCache; class ImportedAttributeVector; +class ReadableAttributeVector; class ReferenceAttribute; /* @@ -25,14 +25,14 @@ public: static std::shared_ptr<ImportedAttributeVector> create(vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, - std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<attribute::ReadableAttributeVector> target_attribute, std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, bool use_search_cache); static std::shared_ptr<ImportedAttributeVector> create(vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, - std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<attribute::ReadableAttributeVector> target_attribute, std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, std::shared_ptr<BitVectorSearchCache> search_cache); }; 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 0a752980a19..a27c73e112e 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 @@ -1,7 +1,9 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "imported_attribute_vector_read_guard.h" +#include "imported_attribute_vector.h" #include "imported_search_context.h" +#include "reference_attribute.h" #include <vespa/searchlib/common/i_gid_to_lid_mapper.h> #include <vespa/searchlib/common/i_gid_to_lid_mapper_factory.h> #include <vespa/searchlib/query/queryterm.h> @@ -16,10 +18,9 @@ ImportedAttributeVectorReadGuard::ImportedAttributeVectorReadGuard( _imported_attribute(imported_attribute), _referencedLids(), _reference_attribute_guard(imported_attribute.getReferenceAttribute()), - _target_attribute_guard(stableEnumGuard ? std::shared_ptr<AttributeVector>() : imported_attribute.getTargetAttribute()), - _target_attribute_enum_guard(stableEnumGuard ? imported_attribute.getTargetAttribute(): std::shared_ptr<AttributeVector>()), + _target_attribute_guard(imported_attribute.getTargetAttribute()->makeReadGuard(stableEnumGuard)), _reference_attribute(*imported_attribute.getReferenceAttribute()), - _target_attribute(*imported_attribute.getTargetAttribute()), + _target_attribute(*_target_attribute_guard->attribute()), _mapper(_reference_attribute.getGidToLidMapperFactory()->getMapper()) { _referencedLids = _reference_attribute.getReferencedLids(); @@ -106,7 +107,7 @@ const char * ImportedAttributeVectorReadGuard::getStringFromEnum(EnumHandle e) c std::unique_ptr<ISearchContext> ImportedAttributeVectorReadGuard::createSearchContext(std::unique_ptr<QueryTermSimple> term, const SearchContextParams ¶ms) const { - return std::make_unique<ImportedSearchContext>(std::move(term), params, _imported_attribute); + return std::make_unique<ImportedSearchContext>(std::move(term), params, _imported_attribute, _target_attribute); } const IDocumentWeightAttribute *ImportedAttributeVectorReadGuard::asDocumentWeightAttribute() const { @@ -133,6 +134,23 @@ bool ImportedAttributeVectorReadGuard::hasEnum() const { return _target_attribute.hasEnum(); } +bool ImportedAttributeVectorReadGuard::getIsFilter() const { + return _target_attribute.getIsFilter(); +} + +bool ImportedAttributeVectorReadGuard::getIsFastSearch() const { + return _target_attribute.getIsFastSearch(); +} + +uint32_t ImportedAttributeVectorReadGuard::getCommittedDocIdLimitSlow() const { + return _reference_attribute.getCommittedDocIdLimit(); +} + +bool ImportedAttributeVectorReadGuard::isImported() const +{ + return true; +} + long ImportedAttributeVectorReadGuard::onSerializeForAscendingSort(DocId doc, void *serTo, long available, 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 92d4af518f2..6c8dca11d31 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 @@ -4,7 +4,7 @@ #include "attribute_read_guard.h" #include "attributeguard.h" -#include "imported_attribute_vector.h" +#include <vespa/vespalib/util/arrayref.h> #include <vespa/searchcommon/attribute/iattributevector.h> namespace search { class IGidToLidMapper; } @@ -12,6 +12,8 @@ namespace search { class IGidToLidMapper; } namespace search::attribute { class BitVectorSearchCache; +class ImportedAttributeVector; +class ReferenceAttribute; /* * Short lived attribute vector that does not store values on its own. @@ -27,10 +29,11 @@ private: const ImportedAttributeVector &_imported_attribute; ReferencedLids _referencedLids; AttributeGuard _reference_attribute_guard; - AttributeGuard _target_attribute_guard; - AttributeEnumGuard _target_attribute_enum_guard; + std::unique_ptr<attribute::AttributeReadGuard> _target_attribute_guard; const ReferenceAttribute &_reference_attribute; - const AttributeVector &_target_attribute; +protected: + const IAttributeVector &_target_attribute; +private: std::unique_ptr<IGidToLidMapper> _mapper; protected: @@ -70,6 +73,10 @@ public: virtual size_t getFixedWidth() const override; virtual CollectionType::Type getCollectionType() const override; virtual bool hasEnum() const override; + virtual bool getIsFilter() const override; + virtual bool getIsFastSearch() const override; + virtual uint32_t getCommittedDocIdLimitSlow() const override; + virtual bool isImported() const override; protected: virtual long onSerializeForAscendingSort(DocId doc, void * serTo, long available, diff --git a/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp b/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp index cfac9f66062..3c4029627df 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp +++ b/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp @@ -3,6 +3,7 @@ #include "bitvector_search_cache.h" #include "imported_search_context.h" #include "imported_attribute_vector.h" +#include "reference_attribute.h" #include <vespa/searchlib/common/bitvectoriterator.h> #include <vespa/searchlib/queryeval/emptysearch.h> #include "attributeiterators.hpp" @@ -23,7 +24,8 @@ namespace search::attribute { ImportedSearchContext::ImportedSearchContext( std::unique_ptr<QueryTermSimple> term, const SearchContextParams& params, - const ImportedAttributeVector& imported_attribute) + const ImportedAttributeVector& imported_attribute, + const IAttributeVector &target_attribute) : _imported_attribute(imported_attribute), _queryTerm(term->getTerm()), _useSearchCache(_imported_attribute.getSearchCache().get() != nullptr), @@ -32,7 +34,7 @@ ImportedSearchContext::ImportedSearchContext( _dmsReadGuard((_useSearchCache && !_searchCacheLookup) ? imported_attribute.getDocumentMetaStore()->getReadGuard() : std::unique_ptr<IDocumentMetaStoreContext::IReadGuard>()), _reference_attribute(*_imported_attribute.getReferenceAttribute()), - _target_attribute(*_imported_attribute.getTargetAttribute()), + _target_attribute(target_attribute), _target_search_context(_target_attribute.createSearchContext(std::move(term), params)), _referencedLids(_reference_attribute.getReferencedLids()), _merger(_reference_attribute.getCommittedDocIdLimit()), @@ -193,7 +195,7 @@ public: void ImportedSearchContext::makeMergedPostings(bool isFilter) { - uint32_t committedTargetDocIdLimit = _target_attribute.getCommittedDocIdLimit(); + uint32_t committedTargetDocIdLimit = _target_attribute.getCommittedDocIdLimitSlow(); std::atomic_thread_fence(std::memory_order_acquire); const auto &reverseMapping = _reference_attribute.getReverseMapping(); if (isFilter) { @@ -229,8 +231,8 @@ void ImportedSearchContext::fetchPostings(bool strict) { _fetchPostingsDone = true; if (!_searchCacheLookup) { _target_search_context->fetchPostings(strict); - if (strict || _target_attribute.getConfig().fastSearch()) { - makeMergedPostings(_target_attribute.getConfig().getIsFilter()); + if (strict || _target_attribute.getIsFastSearch()) { + makeMergedPostings(_target_attribute.getIsFilter()); considerAddSearchCacheEntry(); } } diff --git a/searchlib/src/vespa/searchlib/attribute/imported_search_context.h b/searchlib/src/vespa/searchlib/attribute/imported_search_context.h index 32bca66cc1b..e7f4c89fc46 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_search_context.h +++ b/searchlib/src/vespa/searchlib/attribute/imported_search_context.h @@ -33,7 +33,7 @@ class ImportedSearchContext : public ISearchContext { BitVectorSearchCache::Entry::SP _searchCacheLookup; IDocumentMetaStoreContext::IReadGuard::UP _dmsReadGuard; const ReferenceAttribute& _reference_attribute; - const AttributeVector& _target_attribute; + const IAttributeVector &_target_attribute; std::unique_ptr<ISearchContext> _target_search_context; ReferencedLids _referencedLids; PostingListMerger<int32_t> _merger; @@ -48,7 +48,8 @@ class ImportedSearchContext : public ISearchContext { public: ImportedSearchContext(std::unique_ptr<QueryTermSimple> term, const SearchContextParams& params, - const ImportedAttributeVector& imported_attribute); + const ImportedAttributeVector& imported_attribute, + const attribute::IAttributeVector &target_attribute); ~ImportedSearchContext(); diff --git a/searchlib/src/vespa/searchlib/features/dotproductfeature.cpp b/searchlib/src/vespa/searchlib/features/dotproductfeature.cpp index be909d7a7e6..3688e00d47d 100644 --- a/searchlib/src/vespa/searchlib/features/dotproductfeature.cpp +++ b/searchlib/src/vespa/searchlib/features/dotproductfeature.cpp @@ -355,10 +355,6 @@ template class ArrayParam<double>; namespace { -bool isImportedAttribute(const IAttributeVector& attribute) noexcept { - return dynamic_cast<const ImportedAttributeVectorReadGuard*>(&attribute) != nullptr; -} - using dotproduct::ArrayParam; template <typename A> @@ -373,7 +369,7 @@ bool supportsGetRawValues(const A & attr) noexcept { } } -// Precondition: isImportedAttribute(*attribute) == false +// Precondition: attribute->isImported() == false template <typename A> FeatureExecutor & createForDirectArrayImpl(const IAttributeVector * attribute, @@ -471,7 +467,7 @@ FeatureExecutor & createFromObject(const IAttributeVector * attribute, const fef::Anything & object, vespalib::Stash &stash) { if (attribute->getCollectionType() == attribute::CollectionType::ARRAY) { - if (!isImportedAttribute(*attribute)) { + if (!attribute->isImported()) { switch (attribute->getBasicType()) { case BasicType::INT32: return createForDirectArray<IntegerAttributeTemplate<int32_t>>(attribute, dynamic_cast<const ArrayParam<int32_t> &>(object), stash); @@ -507,7 +503,7 @@ createFromObject(const IAttributeVector * attribute, const fef::Anything & objec FeatureExecutor * createTypedArrayExecutor(const IAttributeVector * attribute, const Property & prop, vespalib::Stash & stash) { - if (!isImportedAttribute(*attribute)) { + if (!attribute->isImported()) { switch (attribute->getBasicType()) { case BasicType::INT32: return &createForDirectArray<IntegerAttributeTemplate<int32_t>>(attribute, prop, stash); @@ -586,7 +582,7 @@ createFromString(const IAttributeVector * attribute, const Property & prop, vesp } fef::Anything::UP attemptParseArrayQueryVector(const IAttributeVector & attribute, const Property & prop) { - if (!isImportedAttribute(attribute)) { + if (!attribute.isImported()) { switch (attribute.getBasicType()) { case BasicType::INT32: return std::make_unique<ArrayParam<int32_t>>(prop); 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 b9a9d96ff66..90451c01294 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 @@ -143,10 +143,6 @@ InternalMaxReduceProdJoinBlueprint::setup(const IIndexEnvironment &env, const Pa return true; } -bool isImportedAttribute(const IAttributeVector &attribute) noexcept { - return dynamic_cast<const ImportedAttributeVectorReadGuard*>(&attribute) != nullptr; -} - template<typename A> bool supportsGetRawValues(const A &attr) noexcept { try { @@ -163,7 +159,7 @@ template <typename BaseType> FeatureExecutor & selectTypedExecutor(const IAttributeVector *attribute, const IntegerVector &vector, vespalib::Stash &stash) { - if (!isImportedAttribute(*attribute)) { + if (!attribute->isImported()) { using A = IntegerAttributeTemplate<BaseType>; using VT = multivalue::Value<BaseType>; using ExactA = MultiValueNumericAttribute<A, VT>; diff --git a/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector.cpp b/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector.cpp index 71aca30ca5e..6b3f4adb6e4 100644 --- a/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector.cpp +++ b/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector.cpp @@ -10,7 +10,7 @@ using vespalib::tensor::Tensor; ImportedTensorAttributeVector::ImportedTensorAttributeVector(vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, - std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<attribute::ReadableAttributeVector> target_attribute, std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, bool use_search_cache) : ImportedAttributeVector(name, std::move(reference_attribute), @@ -22,7 +22,7 @@ ImportedTensorAttributeVector::ImportedTensorAttributeVector(vespalib::stringref ImportedTensorAttributeVector::ImportedTensorAttributeVector(vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, - std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<attribute::ReadableAttributeVector> target_attribute, std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, std::shared_ptr<BitVectorSearchCache> search_cache) : ImportedAttributeVector(name, std::move(reference_attribute), diff --git a/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector.h b/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector.h index b9f643b179f..c7ccd9ec599 100644 --- a/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector.h +++ b/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector.h @@ -19,12 +19,12 @@ class ImportedTensorAttributeVector : public attribute::ImportedAttributeVector public: ImportedTensorAttributeVector(vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, - std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<attribute::ReadableAttributeVector> target_attribute, std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, bool use_search_cache); ImportedTensorAttributeVector(vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, - std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<attribute::ReadableAttributeVector> target_attribute, std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, std::shared_ptr<BitVectorSearchCache> search_cache); ~ImportedTensorAttributeVector(); diff --git a/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector_read_guard.cpp b/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector_read_guard.cpp index 4f355255db5..c6db5a76ed1 100644 --- a/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector_read_guard.cpp +++ b/searchlib/src/vespa/searchlib/tensor/imported_tensor_attribute_vector_read_guard.cpp @@ -1,6 +1,7 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "imported_tensor_attribute_vector_read_guard.h" +#include <vespa/searchlib/attribute/attributevector.h> #include <vespa/eval/tensor/tensor.h> namespace search::tensor { @@ -23,7 +24,7 @@ ImportedTensorAttributeVectorReadGuard::ImportedTensorAttributeVectorReadGuard(c bool stableEnumGuard) : ImportedAttributeVectorReadGuard(imported_attribute, stableEnumGuard), - _target_tensor_attribute(getTensorAttribute(*imported_attribute.getTargetAttribute())) + _target_tensor_attribute(getTensorAttribute(_target_attribute)) { } diff --git a/searchlib/src/vespa/searchlib/test/imported_attribute_fixture.h b/searchlib/src/vespa/searchlib/test/imported_attribute_fixture.h index 339060bbfc3..3eb20e1b646 100644 --- a/searchlib/src/vespa/searchlib/test/imported_attribute_fixture.h +++ b/searchlib/src/vespa/searchlib/test/imported_attribute_fixture.h @@ -13,6 +13,7 @@ #include <vespa/searchlib/attribute/imported_attribute_vector_factory.h> #include <vespa/searchlib/attribute/integerbase.h> #include <vespa/searchlib/attribute/not_implemented_attribute.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/query/queryterm.h> diff --git a/searchlib/src/vespa/searchlib/test/mock_attribute_manager.h b/searchlib/src/vespa/searchlib/test/mock_attribute_manager.h index 33bd11e8d6f..fa12089b3cf 100644 --- a/searchlib/src/vespa/searchlib/test/mock_attribute_manager.h +++ b/searchlib/src/vespa/searchlib/test/mock_attribute_manager.h @@ -4,6 +4,7 @@ #include <vespa/searchlib/attribute/attributecontext.h> #include <vespa/searchlib/attribute/attributeguard.h> #include <vespa/searchlib/attribute/attributevector.h> +#include <vespa/searchlib/attribute/attribute_read_guard.h> #include <vespa/searchlib/attribute/iattributemanager.h> namespace search { @@ -33,9 +34,13 @@ public: return AttributeGuard::UP(new AttributeGuard(attr)); } - virtual AttributeGuard::UP getAttributeStableEnum(const vespalib::string &name) const override { + virtual std::unique_ptr<AttributeReadGuard> getAttributeReadGuard(const vespalib::string &name, bool stableEnumGuard) const override { AttributeVector::SP attr = findAttribute(name); - return AttributeGuard::UP(new AttributeEnumGuard(attr)); + if (attr) { + return attr->makeReadGuard(stableEnumGuard); + } else { + return std::unique_ptr<AttributeReadGuard>(); + } } virtual void getAttributeList(std::vector<AttributeGuard> &list) const override { |