diff options
author | Tor Egge <Tor.Egge@online.no> | 2023-04-25 15:14:03 +0200 |
---|---|---|
committer | Tor Egge <Tor.Egge@online.no> | 2023-04-25 15:14:03 +0200 |
commit | c3e9f699bb2d958937437c71e4f7d89192ab30f5 (patch) | |
tree | 6447813e626ff4d02a5aeed1b3836a6ab41df112 /searchlib/src | |
parent | d5f17d23f377776e85aa687be17b211b54423c59 (diff) |
Check target attribute lid range.
Diffstat (limited to 'searchlib/src')
37 files changed, 160 insertions, 26 deletions
diff --git a/searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp b/searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp index 9e65dfcfc07..7d0bd9bc065 100644 --- a/searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp +++ b/searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp @@ -240,6 +240,22 @@ TEST_F("original lid range is used by read guard", Fixture) EXPECT_EQUAL(getUndefined<int>(), first_guard->getInt(DocId(10))); } +TEST_F("Original target lid range is used by read guard", Fixture) +{ + reset_with_single_value_reference_mappings<IntegerAttribute, int32_t>( + f, BasicType::INT32, + {}); + auto first_guard = f.get_imported_attr(); + add_n_docs_with_undefined_values(*f.target_attr, 1); + auto typed_target_attr = f.template target_attr_as<IntegerAttribute>(); + ASSERT_TRUE(typed_target_attr->update(11, 2345)); + f.target_attr->commit(); + f.map_reference(DocId(8), dummy_gid(11), DocId(11)); + auto second_guard = f.get_imported_attr(); + EXPECT_EQUAL(2345, second_guard->getInt(DocId(8))); + EXPECT_NOT_EQUAL(2345, first_guard->getInt(DocId(8))); +} + struct SingleStringAttrFixture : Fixture { SingleStringAttrFixture() : Fixture() { setup(); 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 847a992d241..fac1284f1a6 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 @@ -429,6 +429,19 @@ TEST_F("original lid range is used by search context", SingleValueFixture) EXPECT_TRUE(second_ctx->matches(DocId(10))); } +TEST_F("Original target lid range is used by search context", SingleValueFixture) +{ + auto first_ctx = f.create_context(word_term("2345")); + add_n_docs_with_undefined_values(*f.target_attr, 1); + auto typed_target_attr = f.template target_attr_as<IntegerAttribute>(); + ASSERT_TRUE(typed_target_attr->update(11, 2345)); + f.target_attr->commit(); + f.map_reference(DocId(8), dummy_gid(11), DocId(11)); + auto second_ctx = f.create_context(word_term("2345")); + EXPECT_FALSE(first_ctx->matches(DocId(8))); + EXPECT_TRUE(second_ctx->matches(DocId(8))); +} + // Note: this uses an underlying string attribute, as queryTerm() does not seem to // implemented at all for (single) numeric attributes. Intentional? TEST_F("queryTerm() returns term context was created with", WsetValueFixture) { diff --git a/searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp b/searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp index 2804e3f74e4..5ba90d2b077 100644 --- a/searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp +++ b/searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp @@ -390,7 +390,7 @@ TEST("testSingleValue") { EXPECT_EQUAL(24u, sizeof(SearchContext)); EXPECT_EQUAL(32u, sizeof(StringSearchHelper)); - EXPECT_EQUAL(80u, sizeof(attribute::SingleStringEnumSearchContext)); + EXPECT_EQUAL(88u, sizeof(attribute::SingleStringEnumSearchContext)); { Config cfg(BasicType::STRING, CollectionType::SINGLE); SingleValueStringAttribute svsa("svsa", cfg); diff --git a/searchlib/src/vespa/searchcommon/attribute/i_search_context.h b/searchlib/src/vespa/searchcommon/attribute/i_search_context.h index 8867d1b87e4..4657d41a4a0 100644 --- a/searchlib/src/vespa/searchcommon/attribute/i_search_context.h +++ b/searchlib/src/vespa/searchcommon/attribute/i_search_context.h @@ -70,6 +70,11 @@ public: bool matches(DocId docId, int32_t &weight) const { return matches(*this, docId, weight); } bool matches(DocId doc) const { return find(doc, 0) >= 0; } + /* + * Committed docid limit on attribute vector when search context was + * created. + */ + virtual uint32_t get_committed_docid_limit() const noexcept = 0; }; } diff --git a/searchlib/src/vespa/searchlib/attribute/empty_search_context.cpp b/searchlib/src/vespa/searchlib/attribute/empty_search_context.cpp index 7a5d82cd9ba..91bdb45ff19 100644 --- a/searchlib/src/vespa/searchlib/attribute/empty_search_context.cpp +++ b/searchlib/src/vespa/searchlib/attribute/empty_search_context.cpp @@ -30,6 +30,12 @@ EmptySearchContext::approximateHits() const return 0u; } +uint32_t +EmptySearchContext::get_committed_docid_limit() const noexcept +{ + return 0u; +} + std::unique_ptr<queryeval::SearchIterator> EmptySearchContext::createIterator(fef::TermFieldMatchData*, bool) { diff --git a/searchlib/src/vespa/searchlib/attribute/empty_search_context.h b/searchlib/src/vespa/searchlib/attribute/empty_search_context.h index ae6f6d76edf..133e540d87f 100644 --- a/searchlib/src/vespa/searchlib/attribute/empty_search_context.h +++ b/searchlib/src/vespa/searchlib/attribute/empty_search_context.h @@ -19,6 +19,7 @@ class EmptySearchContext : public SearchContext public: EmptySearchContext(const AttributeVector& attr) noexcept; ~EmptySearchContext(); + uint32_t get_committed_docid_limit() const noexcept override; }; } diff --git a/searchlib/src/vespa/searchlib/attribute/enumhintsearchcontext.h b/searchlib/src/vespa/searchlib/attribute/enumhintsearchcontext.h index 0342976ffd6..86ffa1c8ab0 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumhintsearchcontext.h +++ b/searchlib/src/vespa/searchlib/attribute/enumhintsearchcontext.h @@ -41,6 +41,7 @@ protected: void fetchPostings(const queryeval::ExecuteInfo & execInfo) override; unsigned int approximateHits() const override; + uint32_t get_committed_docid_limit() const noexcept { return _docIdLimit; } }; } 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 a1a5e9f7894..b50a3720ff8 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 @@ -17,12 +17,14 @@ ImportedAttributeVectorReadGuard::ImportedAttributeVectorReadGuard(std::shared_p _target_document_meta_store_read_guard(std::move(targetMetaStoreReadGuard)), _imported_attribute(imported_attribute), _targetLids(), + _target_docid_limit(0u), _reference_attribute_guard(imported_attribute.getReferenceAttribute()), _target_attribute_guard(imported_attribute.getTargetAttribute()->makeReadGuard(stableEnumGuard)), _reference_attribute(*imported_attribute.getReferenceAttribute()), _target_attribute(*_target_attribute_guard->attribute()) { _targetLids = _reference_attribute.getTargetLids(); + _target_docid_limit = _target_attribute.getCommittedDocIdLimit(); } ImportedAttributeVectorReadGuard::~ImportedAttributeVectorReadGuard() = default; 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 cb48399f688..1297acad9b8 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 @@ -95,6 +95,7 @@ private: std::shared_ptr<MetaStoreReadGuard> _target_document_meta_store_read_guard; const ImportedAttributeVector &_imported_attribute; TargetLids _targetLids; + uint32_t _target_docid_limit; AttributeGuard _reference_attribute_guard; std::unique_ptr<attribute::AttributeReadGuard> _target_attribute_guard; const ReferenceAttribute &_reference_attribute; @@ -103,7 +104,9 @@ protected: uint32_t getTargetLid(uint32_t lid) const { // Check range to avoid reading memory beyond end of mapping array - return lid < _targetLids.size() ? _targetLids[lid].load_acquire() : 0u; + uint32_t target_lid = lid < _targetLids.size() ? _targetLids[lid].load_acquire() : 0u; + // Check target range + return target_lid < _target_docid_limit ? target_lid : 0u; } 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 1e8adc3922e..3d308b82b04 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp +++ b/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp @@ -43,6 +43,7 @@ ImportedSearchContext::ImportedSearchContext( _target_attribute(target_attribute), _target_search_context(_target_attribute.createSearchContext(std::move(term), params)), _targetLids(_reference_attribute.getTargetLids()), + _target_docid_limit(_target_search_context->get_committed_docid_limit()), _merger(_reference_attribute.getCommittedDocIdLimit()), _params(params), _zero_hits(false) @@ -327,4 +328,10 @@ const vespalib::string& ImportedSearchContext::attributeName() const { return _imported_attribute.getName(); } +uint32_t +ImportedSearchContext::get_committed_docid_limit() const noexcept +{ + return _targetLids.size(); +} + } diff --git a/searchlib/src/vespa/searchlib/attribute/imported_search_context.h b/searchlib/src/vespa/searchlib/attribute/imported_search_context.h index d9c09d8c645..d6b6d09e8fc 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_search_context.h +++ b/searchlib/src/vespa/searchlib/attribute/imported_search_context.h @@ -39,6 +39,7 @@ class ImportedSearchContext : public ISearchContext { const IAttributeVector &_target_attribute; std::unique_ptr<ISearchContext> _target_search_context; TargetLids _targetLids; + uint32_t _target_docid_limit; PostingListMerger<int32_t> _merger; SearchContextParams _params; mutable std::atomic<bool> _zero_hits; @@ -47,7 +48,9 @@ class ImportedSearchContext : public ISearchContext { uint32_t getTargetLid(uint32_t lid) const { // Check range to avoid reading memory beyond end of mapping array - return lid < _targetLids.size() ? _targetLids[lid].load_acquire() : 0u; + uint32_t target_lid = lid < _targetLids.size() ? _targetLids[lid].load_acquire() : 0u; + // Check target range + return target_lid < _target_docid_limit ? target_lid : 0u; } void makeMergedPostings(bool isFilter); @@ -90,6 +93,7 @@ public: const ISearchContext &target_search_context() const noexcept { return *_target_search_context; } + uint32_t get_committed_docid_limit() const noexcept override; }; } diff --git a/searchlib/src/vespa/searchlib/attribute/multi_enum_search_context.h b/searchlib/src/vespa/searchlib/attribute/multi_enum_search_context.h index 5b393d8bdb2..161c6799787 100644 --- a/searchlib/src/vespa/searchlib/attribute/multi_enum_search_context.h +++ b/searchlib/src/vespa/searchlib/attribute/multi_enum_search_context.h @@ -59,6 +59,7 @@ public: std::unique_ptr<queryeval::SearchIterator> createFilterIterator(fef::TermFieldMatchData* matchData, bool strict) override; + uint32_t get_committed_docid_limit() const noexcept override; }; } diff --git a/searchlib/src/vespa/searchlib/attribute/multi_enum_search_context.hpp b/searchlib/src/vespa/searchlib/attribute/multi_enum_search_context.hpp index e7901199e50..15abcf6f0d9 100644 --- a/searchlib/src/vespa/searchlib/attribute/multi_enum_search_context.hpp +++ b/searchlib/src/vespa/searchlib/attribute/multi_enum_search_context.hpp @@ -33,4 +33,11 @@ MultiEnumSearchContext<T, BaseSC, M>::createFilterIterator(fef::TermFieldMatchDa : std::make_unique<AttributeIteratorT<MultiEnumSearchContext>>(*this, matchData); } +template <typename T, typename BaseSC, typename M> +uint32_t +MultiEnumSearchContext<T, BaseSC, M>::get_committed_docid_limit() const noexcept +{ + return _mv_mapping_read_view.get_committed_docid_limit(); +} + } diff --git a/searchlib/src/vespa/searchlib/attribute/multi_numeric_search_context.h b/searchlib/src/vespa/searchlib/attribute/multi_numeric_search_context.h index b2c76a120f9..23e56e23af9 100644 --- a/searchlib/src/vespa/searchlib/attribute/multi_numeric_search_context.h +++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_search_context.h @@ -54,6 +54,7 @@ public: std::unique_ptr<queryeval::SearchIterator> createFilterIterator(fef::TermFieldMatchData* matchData, bool strict) override; + uint32_t get_committed_docid_limit() const noexcept override; }; } diff --git a/searchlib/src/vespa/searchlib/attribute/multi_numeric_search_context.hpp b/searchlib/src/vespa/searchlib/attribute/multi_numeric_search_context.hpp index 15b851215f8..7e1fd1aeb5a 100644 --- a/searchlib/src/vespa/searchlib/attribute/multi_numeric_search_context.hpp +++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_search_context.hpp @@ -33,4 +33,11 @@ MultiNumericSearchContext<T, M>::createFilterIterator(fef::TermFieldMatchData* m : std::make_unique<AttributeIteratorT<MultiNumericSearchContext<T, M>>>(*this, matchData); } +template <typename T, typename M> +uint32_t +MultiNumericSearchContext<T, M>::get_committed_docid_limit() const noexcept +{ + return _mv_mapping_read_view.get_committed_docid_limit(); +} + } diff --git a/searchlib/src/vespa/searchlib/attribute/multi_value_mapping_read_view.h b/searchlib/src/vespa/searchlib/attribute/multi_value_mapping_read_view.h index 41138ff0890..609989208c3 100644 --- a/searchlib/src/vespa/searchlib/attribute/multi_value_mapping_read_view.h +++ b/searchlib/src/vespa/searchlib/attribute/multi_value_mapping_read_view.h @@ -33,6 +33,7 @@ public: } vespalib::ConstArrayRef<ElemT> get(uint32_t doc_id) const { return _store->get(_indices[doc_id].load_acquire()); } bool valid() const noexcept { return _store != nullptr; } + uint32_t get_committed_docid_limit() const noexcept { return _indices.size(); } }; } diff --git a/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp b/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp index b701a6fd08f..9343dafe917 100644 --- a/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp +++ b/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp @@ -454,12 +454,14 @@ class ReferenceSearchContext : public attribute::SearchContext { private: const ReferenceAttribute& _ref_attr; GlobalId _term; + uint32_t _docid_limit; public: ReferenceSearchContext(const ReferenceAttribute& ref_attr, const GlobalId& term) : attribute::SearchContext(ref_attr), _ref_attr(ref_attr), - _term(term) + _term(term), + _docid_limit(ref_attr.getCommittedDocIdLimit()) { } bool valid() const override { @@ -480,8 +482,15 @@ public: int32_t weight; return onFind(docId, elementId, weight); } + uint32_t get_committed_docid_limit() const noexcept override; }; +uint32_t +ReferenceSearchContext::get_committed_docid_limit() const noexcept +{ + return _docid_limit; +} + } std::unique_ptr<attribute::SearchContext> diff --git a/searchlib/src/vespa/searchlib/attribute/single_enum_search_context.h b/searchlib/src/vespa/searchlib/attribute/single_enum_search_context.h index 83d6c696117..f6a2f94dedb 100644 --- a/searchlib/src/vespa/searchlib/attribute/single_enum_search_context.h +++ b/searchlib/src/vespa/searchlib/attribute/single_enum_search_context.h @@ -17,7 +17,9 @@ class SingleEnumSearchContext : public BaseSC { protected: using DocId = ISearchContext::DocId; - const vespalib::datastore::AtomicEntryRef* _enum_indices; + using AtomicEntryRef = vespalib::datastore::AtomicEntryRef; + using EnumIndices = vespalib::ConstArrayRef<AtomicEntryRef>; + EnumIndices _enum_indices; const EnumStoreT<T>& _enum_store; int32_t onFind(DocId docId, int32_t elemId, int32_t & weight) const final { @@ -29,7 +31,7 @@ protected: } public: - SingleEnumSearchContext(typename BaseSC::MatcherType&& matcher, const AttributeVector& toBeSearched, const vespalib::datastore::AtomicEntryRef* enum_indices, const EnumStoreT<T>& enum_store); + SingleEnumSearchContext(typename BaseSC::MatcherType&& matcher, const AttributeVector& toBeSearched, EnumIndices enum_indices, const EnumStoreT<T>& enum_store); int32_t find(DocId docId, int32_t elemId, int32_t & weight) const { if ( elemId != 0) return -1; @@ -46,6 +48,7 @@ public: std::unique_ptr<queryeval::SearchIterator> createFilterIterator(fef::TermFieldMatchData* matchData, bool strict) override; + uint32_t get_committed_docid_limit() const noexcept override; }; } diff --git a/searchlib/src/vespa/searchlib/attribute/single_enum_search_context.hpp b/searchlib/src/vespa/searchlib/attribute/single_enum_search_context.hpp index a415c301f9c..6b6cf480d6a 100644 --- a/searchlib/src/vespa/searchlib/attribute/single_enum_search_context.hpp +++ b/searchlib/src/vespa/searchlib/attribute/single_enum_search_context.hpp @@ -9,7 +9,7 @@ namespace search::attribute { template <typename T, typename BaseSC> -SingleEnumSearchContext<T, BaseSC>::SingleEnumSearchContext(typename BaseSC::MatcherType&& matcher, const AttributeVector& toBeSearched, const vespalib::datastore::AtomicEntryRef* enum_indices, const EnumStoreT<T>& enum_store) +SingleEnumSearchContext<T, BaseSC>::SingleEnumSearchContext(typename BaseSC::MatcherType&& matcher, const AttributeVector& toBeSearched, EnumIndices enum_indices, const EnumStoreT<T>& enum_store) : BaseSC(toBeSearched, std::move(matcher)), _enum_indices(enum_indices), _enum_store(enum_store) @@ -33,4 +33,11 @@ SingleEnumSearchContext<T, BaseSC>::createFilterIterator(fef::TermFieldMatchData : std::make_unique<AttributeIteratorT<SingleEnumSearchContext>>(*this, matchData); } +template <typename T, typename BaseSC> +uint32_t +SingleEnumSearchContext<T, BaseSC>::get_committed_docid_limit() const noexcept +{ + return _enum_indices.size(); +} + } diff --git a/searchlib/src/vespa/searchlib/attribute/single_numeric_enum_search_context.h b/searchlib/src/vespa/searchlib/attribute/single_numeric_enum_search_context.h index 86283f59283..fd3f4c03a8a 100644 --- a/searchlib/src/vespa/searchlib/attribute/single_numeric_enum_search_context.h +++ b/searchlib/src/vespa/searchlib/attribute/single_numeric_enum_search_context.h @@ -16,7 +16,9 @@ template <typename T> class SingleNumericEnumSearchContext : public SingleEnumSearchContext<T, NumericSearchContext<NumericRangeMatcher<T>>> { public: - SingleNumericEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const vespalib::datastore::AtomicEntryRef* enum_indices, const EnumStoreT<T>& enum_store); + using AtomicEntryRef = vespalib::datastore::AtomicEntryRef; + using EnumIndices = vespalib::ConstArrayRef<AtomicEntryRef>; + SingleNumericEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, EnumIndices enum_indices, const EnumStoreT<T>& enum_store); }; } diff --git a/searchlib/src/vespa/searchlib/attribute/single_numeric_enum_search_context.hpp b/searchlib/src/vespa/searchlib/attribute/single_numeric_enum_search_context.hpp index f4e049cb6f1..c0818d4d18a 100644 --- a/searchlib/src/vespa/searchlib/attribute/single_numeric_enum_search_context.hpp +++ b/searchlib/src/vespa/searchlib/attribute/single_numeric_enum_search_context.hpp @@ -8,7 +8,7 @@ namespace search::attribute { template <typename T> -SingleNumericEnumSearchContext<T>::SingleNumericEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const vespalib::datastore::AtomicEntryRef* enum_indices, const EnumStoreT<T>& enum_store) +SingleNumericEnumSearchContext<T>::SingleNumericEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, EnumIndices enum_indices, const EnumStoreT<T>& enum_store) : SingleEnumSearchContext<T, NumericSearchContext<NumericRangeMatcher<T>>>(NumericRangeMatcher<T>(*qTerm, true), toBeSearched, enum_indices, enum_store) { } diff --git a/searchlib/src/vespa/searchlib/attribute/single_numeric_search_context.h b/searchlib/src/vespa/searchlib/attribute/single_numeric_search_context.h index 5f6925f7f4d..6362c69cdac 100644 --- a/searchlib/src/vespa/searchlib/attribute/single_numeric_search_context.h +++ b/searchlib/src/vespa/searchlib/attribute/single_numeric_search_context.h @@ -3,6 +3,7 @@ #pragma once #include "numeric_search_context.h" +#include <vespa/vespalib/util/arrayref.h> #include <vespa/vespalib/util/atomic.h> namespace search::attribute { @@ -16,7 +17,7 @@ class SingleNumericSearchContext final : public NumericSearchContext<M> { private: using DocId = ISearchContext::DocId; - const T* _data; + vespalib::ConstArrayRef<T> _data; int32_t onFind(DocId docId, int32_t elemId, int32_t& weight) const override { return find(docId, elemId, weight); @@ -27,7 +28,7 @@ private: } public: - SingleNumericSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const T* data); + SingleNumericSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, vespalib::ConstArrayRef<T> data); int32_t find(DocId docId, int32_t elemId, int32_t& weight) const { if ( elemId != 0) return -1; const T v = vespalib::atomic::load_ref_relaxed(_data[docId]); @@ -43,6 +44,7 @@ public: std::unique_ptr<queryeval::SearchIterator> createFilterIterator(fef::TermFieldMatchData* matchData, bool strict) override; + uint32_t get_committed_docid_limit() const noexcept override; }; } diff --git a/searchlib/src/vespa/searchlib/attribute/single_numeric_search_context.hpp b/searchlib/src/vespa/searchlib/attribute/single_numeric_search_context.hpp index 75d3da9de7f..b40b1336e6f 100644 --- a/searchlib/src/vespa/searchlib/attribute/single_numeric_search_context.hpp +++ b/searchlib/src/vespa/searchlib/attribute/single_numeric_search_context.hpp @@ -9,7 +9,7 @@ namespace search::attribute { template <typename T, typename M> -SingleNumericSearchContext<T, M>::SingleNumericSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const T* data) +SingleNumericSearchContext<T, M>::SingleNumericSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, vespalib::ConstArrayRef<T> data) : NumericSearchContext<M>(toBeSearched, *qTerm, true), _data(data) { @@ -32,4 +32,11 @@ SingleNumericSearchContext<T, M>::createFilterIterator(fef::TermFieldMatchData* : std::make_unique<AttributeIteratorT<SingleNumericSearchContext<T, M>>>(*this, matchData); } +template <typename T, typename M> +uint32_t +SingleNumericSearchContext<T, M>::get_committed_docid_limit() const noexcept +{ + return _data.size(); +} + } diff --git a/searchlib/src/vespa/searchlib/attribute/single_small_numeric_search_context.cpp b/searchlib/src/vespa/searchlib/attribute/single_small_numeric_search_context.cpp index 5eeef7cd61a..074435809cc 100644 --- a/searchlib/src/vespa/searchlib/attribute/single_small_numeric_search_context.cpp +++ b/searchlib/src/vespa/searchlib/attribute/single_small_numeric_search_context.cpp @@ -6,13 +6,14 @@ namespace search::attribute { -SingleSmallNumericSearchContext::SingleSmallNumericSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const Word* word_data, Word value_mask, uint32_t value_shift_shift, uint32_t value_shift_mask, uint32_t word_shift) +SingleSmallNumericSearchContext::SingleSmallNumericSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const Word* word_data, Word value_mask, uint32_t value_shift_shift, uint32_t value_shift_mask, uint32_t word_shift, uint32_t docid_limit) : NumericSearchContext<NumericRangeMatcher<T>>(toBeSearched, *qTerm, false), _wordData(word_data), _valueMask(value_mask), _valueShiftShift(value_shift_shift), _valueShiftMask(value_shift_mask), - _wordShift(word_shift) + _wordShift(word_shift), + _docid_limit(docid_limit) { } @@ -32,4 +33,10 @@ SingleSmallNumericSearchContext::createFilterIterator(fef::TermFieldMatchData* m : std::make_unique<AttributeIteratorT<SingleSmallNumericSearchContext>>(*this, matchData); } +uint32_t +SingleSmallNumericSearchContext::get_committed_docid_limit() const noexcept +{ + return _docid_limit; +} + } diff --git a/searchlib/src/vespa/searchlib/attribute/single_small_numeric_search_context.h b/searchlib/src/vespa/searchlib/attribute/single_small_numeric_search_context.h index 46ed02b3eca..a42c8b9b29c 100644 --- a/searchlib/src/vespa/searchlib/attribute/single_small_numeric_search_context.h +++ b/searchlib/src/vespa/searchlib/attribute/single_small_numeric_search_context.h @@ -22,6 +22,7 @@ private: uint32_t _valueShiftShift; uint32_t _valueShiftMask; uint32_t _wordShift; + uint32_t _docid_limit; int32_t onFind(DocId docId, int32_t elementId, int32_t & weight) const override { return find(docId, elementId, weight); @@ -32,7 +33,7 @@ private: } public: - SingleSmallNumericSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const Word* word_data, Word value_mask, uint32_t value_shift_shift, uint32_t value_shift_mask, uint32_t word_shift); + SingleSmallNumericSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const Word* word_data, Word value_mask, uint32_t value_shift_shift, uint32_t value_shift_mask, uint32_t word_shift, uint32_t docid_limit); int32_t find(DocId docId, int32_t elemId, int32_t & weight) const { if ( elemId != 0) return -1; @@ -53,6 +54,7 @@ public: std::unique_ptr<queryeval::SearchIterator> createFilterIterator(fef::TermFieldMatchData* matchData, bool strict) override; + uint32_t get_committed_docid_limit() const noexcept override; }; } diff --git a/searchlib/src/vespa/searchlib/attribute/single_string_enum_hint_search_context.cpp b/searchlib/src/vespa/searchlib/attribute/single_string_enum_hint_search_context.cpp index 70023b27802..2d1748cefa5 100644 --- a/searchlib/src/vespa/searchlib/attribute/single_string_enum_hint_search_context.cpp +++ b/searchlib/src/vespa/searchlib/attribute/single_string_enum_hint_search_context.cpp @@ -5,10 +5,10 @@ namespace search::attribute { -SingleStringEnumHintSearchContext::SingleStringEnumHintSearchContext(std::unique_ptr<QueryTermSimple> qTerm, bool cased, const AttributeVector& toBeSearched, const vespalib::datastore::AtomicEntryRef* enum_indices, const EnumStoreT<const char*>& enum_store, uint32_t doc_id_limit, uint64_t num_values) +SingleStringEnumHintSearchContext::SingleStringEnumHintSearchContext(std::unique_ptr<QueryTermSimple> qTerm, bool cased, const AttributeVector& toBeSearched, EnumIndices enum_indices, const EnumStoreT<const char*>& enum_store, uint64_t num_values) : SingleStringEnumSearchContext(std::move(qTerm), cased, toBeSearched, enum_indices, enum_store), EnumHintSearchContext(enum_store.get_dictionary(), - doc_id_limit, num_values) + enum_indices.size(), num_values) { setup_enum_hint_sc(enum_store, *this); } diff --git a/searchlib/src/vespa/searchlib/attribute/single_string_enum_hint_search_context.h b/searchlib/src/vespa/searchlib/attribute/single_string_enum_hint_search_context.h index f9d44454cd0..f157bf17a71 100644 --- a/searchlib/src/vespa/searchlib/attribute/single_string_enum_hint_search_context.h +++ b/searchlib/src/vespa/searchlib/attribute/single_string_enum_hint_search_context.h @@ -16,7 +16,7 @@ class SingleStringEnumHintSearchContext : public SingleStringEnumSearchContext, public EnumHintSearchContext { public: - SingleStringEnumHintSearchContext(std::unique_ptr<QueryTermSimple> qTerm, bool cased, const AttributeVector& toBeSearched, const vespalib::datastore::AtomicEntryRef* enum_indices, const EnumStoreT<const char*>& enum_store, uint32_t doc_id_limit, uint64_t num_values); + SingleStringEnumHintSearchContext(std::unique_ptr<QueryTermSimple> qTerm, bool cased, const AttributeVector& toBeSearched, EnumIndices enum_indices, const EnumStoreT<const char*>& enum_store, uint64_t num_values); ~SingleStringEnumHintSearchContext() override; }; diff --git a/searchlib/src/vespa/searchlib/attribute/single_string_enum_search_context.cpp b/searchlib/src/vespa/searchlib/attribute/single_string_enum_search_context.cpp index cba1d207501..8d23eaf7af0 100644 --- a/searchlib/src/vespa/searchlib/attribute/single_string_enum_search_context.cpp +++ b/searchlib/src/vespa/searchlib/attribute/single_string_enum_search_context.cpp @@ -6,7 +6,7 @@ namespace search::attribute { -SingleStringEnumSearchContext::SingleStringEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, bool cased, const AttributeVector& toBeSearched, const vespalib::datastore::AtomicEntryRef* enum_indices, const EnumStoreT<const char*>& enum_store) +SingleStringEnumSearchContext::SingleStringEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, bool cased, const AttributeVector& toBeSearched, EnumIndices enum_indices, const EnumStoreT<const char*>& enum_store) : SingleEnumSearchContext<const char*, StringSearchContext>(StringMatcher(std::move(qTerm), cased), toBeSearched, enum_indices, enum_store) { } diff --git a/searchlib/src/vespa/searchlib/attribute/single_string_enum_search_context.h b/searchlib/src/vespa/searchlib/attribute/single_string_enum_search_context.h index 6a9ed38b4ea..b8014b1b0e3 100644 --- a/searchlib/src/vespa/searchlib/attribute/single_string_enum_search_context.h +++ b/searchlib/src/vespa/searchlib/attribute/single_string_enum_search_context.h @@ -14,7 +14,7 @@ namespace search::attribute { class SingleStringEnumSearchContext : public SingleEnumSearchContext<const char*, StringSearchContext> { public: - SingleStringEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, bool cased, const AttributeVector& toBeSearched, const vespalib::datastore::AtomicEntryRef* enum_indices, const EnumStoreT<const char*>& enum_store); + SingleStringEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, bool cased, const AttributeVector& toBeSearched, EnumIndices enum_indices, const EnumStoreT<const char*>& enum_store); SingleStringEnumSearchContext(SingleStringEnumSearchContext&&) noexcept; ~SingleStringEnumSearchContext() override; }; diff --git a/searchlib/src/vespa/searchlib/attribute/singleboolattribute.cpp b/searchlib/src/vespa/searchlib/attribute/singleboolattribute.cpp index 15fc819300c..87b7049b9b7 100644 --- a/searchlib/src/vespa/searchlib/attribute/singleboolattribute.cpp +++ b/searchlib/src/vespa/searchlib/attribute/singleboolattribute.cpp @@ -132,6 +132,7 @@ public: void fetchPostings(const queryeval::ExecuteInfo &execInfo) override; std::unique_ptr<queryeval::SearchIterator> createPostingIterator(fef::TermFieldMatchData *matchData, bool strict) override; unsigned int approximateHits() const override; + uint32_t get_committed_docid_limit() const noexcept override; }; BitVectorSearchContext::BitVectorSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const SingleBoolAttribute & attr) @@ -177,6 +178,12 @@ BitVectorSearchContext::approximateHits() const { : 0; } +uint32_t +BitVectorSearchContext::get_committed_docid_limit() const noexcept +{ + return _doc_id_limit; +} + } std::unique_ptr<attribute::SearchContext> diff --git a/searchlib/src/vespa/searchlib/attribute/singlenumericattribute.hpp b/searchlib/src/vespa/searchlib/attribute/singlenumericattribute.hpp index c75ee0aacb5..606c7a92ef5 100644 --- a/searchlib/src/vespa/searchlib/attribute/singlenumericattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/singlenumericattribute.hpp @@ -164,7 +164,7 @@ SingleValueNumericAttribute<B>::getSearch(QueryTermSimple::UP qTerm, { (void) params; QueryTermSimple::RangeResult<T> res = qTerm->getRange<T>(); - const T* data = &_data.acquire_elem_ref(0); + auto data = _data.make_read_view(this->getCommittedDocIdLimit()); if (res.isEqual()) { return std::make_unique<attribute::SingleNumericSearchContext<T, attribute::NumericMatcher<T>>>(std::move(qTerm), *this, data); } else { diff --git a/searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.hpp b/searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.hpp index b840a0516b2..e459d3d9c9c 100644 --- a/searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.hpp @@ -160,7 +160,8 @@ SingleValueNumericEnumAttribute<B>::getSearch(QueryTermSimple::UP qTerm, const attribute::SearchContextParams & params) const { (void) params; - return std::make_unique<attribute::SingleNumericEnumSearchContext<T>>(std::move(qTerm), *this, &this->_enumIndices.acquire_elem_ref(0), this->_enumStore); + auto docid_limit = this->getCommittedDocIdLimit(); + return std::make_unique<attribute::SingleNumericEnumSearchContext<T>>(std::move(qTerm), *this, this->_enumIndices.make_read_view(docid_limit), this->_enumStore); } } diff --git a/searchlib/src/vespa/searchlib/attribute/singlenumericpostattribute.hpp b/searchlib/src/vespa/searchlib/attribute/singlenumericpostattribute.hpp index e353d03a9e8..a4b9abb084a 100644 --- a/searchlib/src/vespa/searchlib/attribute/singlenumericpostattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/singlenumericpostattribute.hpp @@ -143,7 +143,8 @@ SingleValueNumericPostingAttribute<B>::getSearch(QueryTermSimple::UP qTerm, { using BaseSC = attribute::SingleNumericEnumSearchContext<T>; using SC = attribute::NumericPostingSearchContext<BaseSC, SelfType, vespalib::btree::BTreeNoLeafData>; - BaseSC base_sc(std::move(qTerm), *this, &this->_enumIndices.acquire_elem_ref(0), this->_enumStore); + auto docid_limit = this->getCommittedDocIdLimit(); + BaseSC base_sc(std::move(qTerm), *this, this->_enumIndices.make_read_view(docid_limit), this->_enumStore); return std::make_unique<SC>(std::move(base_sc), params, *this); } diff --git a/searchlib/src/vespa/searchlib/attribute/singlesmallnumericattribute.cpp b/searchlib/src/vespa/searchlib/attribute/singlesmallnumericattribute.cpp index 13bf2f932e8..3c1621ac244 100644 --- a/searchlib/src/vespa/searchlib/attribute/singlesmallnumericattribute.cpp +++ b/searchlib/src/vespa/searchlib/attribute/singlesmallnumericattribute.cpp @@ -170,7 +170,8 @@ std::unique_ptr<attribute::SearchContext> SingleValueSmallNumericAttribute::getSearch(std::unique_ptr<QueryTermSimple> qTerm, const attribute::SearchContextParams &) const { - return std::make_unique<attribute::SingleSmallNumericSearchContext>(std::move(qTerm), *this, &_wordData.acquire_elem_ref(0), _valueMask, _valueShiftShift, _valueShiftMask, _wordShift); + auto docid_limit = getCommittedDocIdLimit(); + return std::make_unique<attribute::SingleSmallNumericSearchContext>(std::move(qTerm), *this, &_wordData.acquire_elem_ref(0), _valueMask, _valueShiftShift, _valueShiftMask, _wordShift, docid_limit); } void diff --git a/searchlib/src/vespa/searchlib/attribute/singlestringattribute.hpp b/searchlib/src/vespa/searchlib/attribute/singlestringattribute.hpp index 69fe6435a03..c3f5c295260 100644 --- a/searchlib/src/vespa/searchlib/attribute/singlestringattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/singlestringattribute.hpp @@ -46,7 +46,8 @@ SingleValueStringAttributeT<B>::getSearch(QueryTermSimpleUP qTerm, const attribute::SearchContextParams &) const { bool cased = this->get_match_is_cased(); - return std::make_unique<attribute::SingleStringEnumHintSearchContext>(std::move(qTerm), cased, *this, &this->_enumIndices.acquire_elem_ref(0), this->_enumStore, this->getCommittedDocIdLimit(), this->getStatus().getNumValues()); + auto docid_limit = this->getCommittedDocIdLimit(); + return std::make_unique<attribute::SingleStringEnumHintSearchContext>(std::move(qTerm), cased, *this, this->_enumIndices.make_read_view(docid_limit), this->_enumStore, this->getStatus().getNumValues()); } } diff --git a/searchlib/src/vespa/searchlib/attribute/singlestringpostattribute.hpp b/searchlib/src/vespa/searchlib/attribute/singlestringpostattribute.hpp index 5b5214f6d3e..60847636baa 100644 --- a/searchlib/src/vespa/searchlib/attribute/singlestringpostattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/singlestringpostattribute.hpp @@ -145,7 +145,8 @@ SingleValueStringPostingAttributeT<B>::getSearch(QueryTermSimpleUP qTerm, using BaseSC = attribute::SingleStringEnumSearchContext; using SC = attribute::StringPostingSearchContext<BaseSC, SelfType, vespalib::btree::BTreeNoLeafData>; bool cased = this->get_match_is_cased(); - BaseSC base_sc(std::move(qTerm), cased, *this, &this->_enumIndices.acquire_elem_ref(0), this->_enumStore); + auto docid_limit = this->getCommittedDocIdLimit(); + BaseSC base_sc(std::move(qTerm), cased, *this, this->_enumIndices.make_read_view(docid_limit), this->_enumStore); return std::make_unique<SC>(std::move(base_sc), params.useBitVector(), *this); diff --git a/searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.cpp b/searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.cpp index c50c6ec49f5..86f520c8711 100644 --- a/searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.cpp @@ -129,8 +129,16 @@ struct FakeContext : attribute::ISearchContext { DoubleRange getAsDoubleTerm() const override { abort(); } const QueryTermUCS4 * queryTerm() const override { abort(); } const vespalib::string &attributeName() const override { return name; } + uint32_t get_committed_docid_limit() const noexcept override; }; +uint32_t +FakeContext::get_committed_docid_limit() const noexcept +{ + auto& documents = result.inspect(); + return documents.empty() ? 0 : (documents.back().docId + 1); +} + } SearchIterator::UP |