aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@online.no>2023-04-25 15:14:03 +0200
committerTor Egge <Tor.Egge@online.no>2023-04-25 15:14:03 +0200
commitc3e9f699bb2d958937437c71e4f7d89192ab30f5 (patch)
tree6447813e626ff4d02a5aeed1b3836a6ab41df112 /searchlib/src
parentd5f17d23f377776e85aa687be17b211b54423c59 (diff)
Check target attribute lid range.
Diffstat (limited to 'searchlib/src')
-rw-r--r--searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp16
-rw-r--r--searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp13
-rw-r--r--searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp2
-rw-r--r--searchlib/src/vespa/searchcommon/attribute/i_search_context.h5
-rw-r--r--searchlib/src/vespa/searchlib/attribute/empty_search_context.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/attribute/empty_search_context.h1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enumhintsearchcontext.h1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.h5
-rw-r--r--searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp7
-rw-r--r--searchlib/src/vespa/searchlib/attribute/imported_search_context.h6
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_enum_search_context.h1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_enum_search_context.hpp7
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_numeric_search_context.h1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_numeric_search_context.hpp7
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_value_mapping_read_view.h1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp11
-rw-r--r--searchlib/src/vespa/searchlib/attribute/single_enum_search_context.h7
-rw-r--r--searchlib/src/vespa/searchlib/attribute/single_enum_search_context.hpp9
-rw-r--r--searchlib/src/vespa/searchlib/attribute/single_numeric_enum_search_context.h4
-rw-r--r--searchlib/src/vespa/searchlib/attribute/single_numeric_enum_search_context.hpp2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/single_numeric_search_context.h6
-rw-r--r--searchlib/src/vespa/searchlib/attribute/single_numeric_search_context.hpp9
-rw-r--r--searchlib/src/vespa/searchlib/attribute/single_small_numeric_search_context.cpp11
-rw-r--r--searchlib/src/vespa/searchlib/attribute/single_small_numeric_search_context.h4
-rw-r--r--searchlib/src/vespa/searchlib/attribute/single_string_enum_hint_search_context.cpp4
-rw-r--r--searchlib/src/vespa/searchlib/attribute/single_string_enum_hint_search_context.h2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/single_string_enum_search_context.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/single_string_enum_search_context.h2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/singleboolattribute.cpp7
-rw-r--r--searchlib/src/vespa/searchlib/attribute/singlenumericattribute.hpp2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.hpp3
-rw-r--r--searchlib/src/vespa/searchlib/attribute/singlenumericpostattribute.hpp3
-rw-r--r--searchlib/src/vespa/searchlib/attribute/singlesmallnumericattribute.cpp3
-rw-r--r--searchlib/src/vespa/searchlib/attribute/singlestringattribute.hpp3
-rw-r--r--searchlib/src/vespa/searchlib/attribute/singlestringpostattribute.hpp3
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/leaf_blueprints.cpp8
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