summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@gmail.com>2022-04-07 13:58:39 +0200
committerJon Bratseth <bratseth@gmail.com>2022-04-07 13:58:39 +0200
commitb68f4ba22e523c39e0ca734d7c8627477518c553 (patch)
tree6968efa48259acb6788c2edfab0858de8c8f4765 /searchlib
parenta6656689f92f2bcd45c07491aada64740669d5c5 (diff)
parent4c3de59b341522a53e3ebbf8ad40bd2b12aff86e (diff)
Merge branch 'master' into bratseth/inputs
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/tests/fef/resolver/resolver_test.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/attribute/CMakeLists.txt1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attributeiterators.h2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attributeiterators.hpp19
-rw-r--r--searchlib/src/vespa/searchlib/attribute/flagattribute.cpp39
-rw-r--r--searchlib/src/vespa/searchlib/attribute/flagattribute.h23
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_enum_search_context.h12
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_enum_search_context.hpp4
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.h2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.hpp4
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_numeric_flag_search_context.cpp50
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_numeric_flag_search_context.h39
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_numeric_search_context.h10
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_numeric_search_context.hpp4
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_string_enum_hint_search_context.h2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_string_enum_hint_search_context.hpp4
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_string_enum_search_context.h2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_string_enum_search_context.hpp4
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_value_mapping.h10
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multi_value_mapping_read_view.h38
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multinumericattribute.hpp2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.hpp3
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.hpp3
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multistringattribute.hpp3
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multistringpostattribute.hpp3
-rw-r--r--searchlib/src/vespa/searchlib/expression/documentfieldnode.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/expression/documentfieldnode.h8
-rw-r--r--searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp26
-rw-r--r--searchlib/src/vespa/searchlib/fef/blueprintresolver.h6
-rw-r--r--searchlib/src/vespa/searchlib/fef/verify_feature.cpp4
-rw-r--r--searchlib/src/vespa/searchlib/tensor/direct_tensor_store.cpp3
-rw-r--r--searchlib/src/vespa/searchlib/tensor/direct_tensor_store.h2
-rw-r--r--searchlib/src/vespa/searchlib/tensor/streamed_value_store.cpp3
-rw-r--r--searchlib/src/vespa/searchlib/tensor/streamed_value_store.h2
34 files changed, 230 insertions, 119 deletions
diff --git a/searchlib/src/tests/fef/resolver/resolver_test.cpp b/searchlib/src/tests/fef/resolver/resolver_test.cpp
index 77aba1664ad..536507f3776 100644
--- a/searchlib/src/tests/fef/resolver/resolver_test.cpp
+++ b/searchlib/src/tests/fef/resolver/resolver_test.cpp
@@ -86,4 +86,10 @@ TEST_F("require_that_bad_input_is_handled", Fixture) {
EXPECT_TRUE(dynamic_cast<RankingExpressionBlueprint *>(spec[1].blueprint.get()) != nullptr);
}
+TEST("require that features can be described") {
+ EXPECT_EQUAL(BlueprintResolver::describe_feature("featureName"), vespalib::string("rank feature 'featureName'"));
+ EXPECT_EQUAL(BlueprintResolver::describe_feature("rankingExpression(foo)"), vespalib::string("function 'foo'"));
+ EXPECT_EQUAL(BlueprintResolver::describe_feature("rankingExpression(foo@1234.5678)"), vespalib::string("function 'foo'"));
+}
+
TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt
index b3aa3bd958b..2e562b4a54f 100644
--- a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt
+++ b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt
@@ -65,6 +65,7 @@ vespa_add_library(searchlib_attribute OBJECT
loadednumericvalue.cpp
loadedvalue.cpp
multi_numeric_enum_search_context.cpp
+ multi_numeric_flag_search_context.cpp
multi_numeric_search_context.cpp
multi_string_enum_search_context.cpp
multi_string_enum_hint_search_context.cpp
diff --git a/searchlib/src/vespa/searchlib/attribute/attributeiterators.h b/searchlib/src/vespa/searchlib/attribute/attributeiterators.h
index 8765e52d38a..d12c5a7eadc 100644
--- a/searchlib/src/vespa/searchlib/attribute/attributeiterators.h
+++ b/searchlib/src/vespa/searchlib/attribute/attributeiterators.h
@@ -333,7 +333,6 @@ template <typename SC>
class FlagAttributeIteratorT : public FlagAttributeIterator
{
private:
- using Attribute = typename SC::Attribute;
void doSeek(uint32_t docId) override;
protected:
@@ -366,7 +365,6 @@ private:
using FlagAttributeIteratorT<SC>::setDocId;
using FlagAttributeIteratorT<SC>::setAtEnd;
using FlagAttributeIteratorT<SC>::isAtEnd;
- using Attribute = typename SC::Attribute;
using Trinary=vespalib::Trinary;
void doSeek(uint32_t docId) override;
Trinary is_strict() const override { return Trinary::True; }
diff --git a/searchlib/src/vespa/searchlib/attribute/attributeiterators.hpp b/searchlib/src/vespa/searchlib/attribute/attributeiterators.hpp
index 8cde2862645..16b0c0da143 100644
--- a/searchlib/src/vespa/searchlib/attribute/attributeiterators.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/attributeiterators.hpp
@@ -307,9 +307,8 @@ void
FlagAttributeIteratorStrict<SC>::doSeek(uint32_t docId)
{
const SC & sc(_concreteSearchCtx);
- const Attribute &attr = static_cast<const Attribute &>(sc.attribute());
for (int i = sc._low; (i <= sc._high); ++i) {
- const BitVector * bv = attr.getBitVector(i);
+ const BitVector * bv = sc.get_bit_vector(i);
if ((bv != nullptr) && !isAtEnd(docId) && bv->testBit(docId)) {
setDocId(docId);
return;
@@ -318,7 +317,7 @@ FlagAttributeIteratorStrict<SC>::doSeek(uint32_t docId)
uint32_t minNextBit(search::endDocId);
for (int i = sc._low; (i <= sc._high); ++i) {
- const BitVector * bv = attr.getBitVector(i);
+ const BitVector * bv = sc.get_bit_vector(i);
if (bv != nullptr && !isAtEnd(docId)) {
uint32_t nextBit = bv->getNextTrueBit(docId);
minNextBit = std::min(nextBit, minNextBit);
@@ -336,9 +335,8 @@ void
FlagAttributeIteratorT<SC>::doSeek(uint32_t docId)
{
const SC & sc(_concreteSearchCtx);
- const Attribute &attr = static_cast<const Attribute &>(sc.attribute());
for (int i = sc._low; (i <= sc._high); ++i) {
- const BitVector * bv = attr.getBitVector(i);
+ const BitVector * bv = sc.get_bit_vector(i);
if ((bv != nullptr) && !isAtEnd(docId) && bv->testBit(docId)) {
setDocId(docId);
return;
@@ -351,9 +349,8 @@ void
FlagAttributeIteratorT<SC>::or_hits_into(BitVector &result, uint32_t begin_id) {
(void) begin_id;
const SC & sc(_concreteSearchCtx);
- const Attribute &attr = static_cast<const Attribute &>(sc.attribute());
for (int i = sc._low; (i <= sc._high); ++i) {
- const BitVector * bv = attr.getBitVector(i);
+ const BitVector * bv = sc.get_bit_vector(i);
if (bv != nullptr) {
result.orWith(*bv);
}
@@ -364,9 +361,8 @@ template <typename SC>
void
FlagAttributeIteratorT<SC>::and_hits_into(BitVector &result, uint32_t begin_id) {
const SC & sc(_concreteSearchCtx);
- const Attribute &attr = static_cast<const Attribute &>(sc.attribute());
if (sc._low == sc._high) {
- const BitVector * bv = attr.getBitVector(sc._low);
+ const BitVector * bv = sc.get_bit_vector(sc._low);
if (bv != nullptr) {
result.andWith(*bv);
} else {
@@ -383,18 +379,17 @@ template <typename SC>
std::unique_ptr<BitVector>
FlagAttributeIteratorT<SC>::get_hits(uint32_t begin_id) {
const SC & sc(_concreteSearchCtx);
- const Attribute &attr = static_cast<const Attribute &>(sc.attribute());
int i = sc._low;
BitVector::UP result;
for (;!result && i < sc._high; ++i) {
- const BitVector * bv = attr.getBitVector(i);
+ const BitVector * bv = sc.get_bit_vector(i);
if (bv != nullptr) {
result = BitVector::create(*bv, begin_id, getEndId());
}
}
for (; i <= sc._high; ++i) {
- const BitVector * bv = attr.getBitVector(i);
+ const BitVector * bv = sc.get_bit_vector(i);
if (bv != nullptr) {
result->orWith(*bv);
}
diff --git a/searchlib/src/vespa/searchlib/attribute/flagattribute.cpp b/searchlib/src/vespa/searchlib/attribute/flagattribute.cpp
index f6139c28d65..346c238f0cc 100644
--- a/searchlib/src/vespa/searchlib/attribute/flagattribute.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/flagattribute.cpp
@@ -2,11 +2,8 @@
#include "flagattribute.h"
#include "load_utils.hpp"
-#include "attributeiterators.h"
#include "multinumericattribute.hpp"
-
-#include <vespa/searchlib/queryeval/emptysearch.h>
-#include <vespa/searchlib/common/bitvectoriterator.h>
+#include "multi_numeric_flag_search_context.h"
#include <vespa/log/log.h>
LOG_SETUP(".searchlib.attribute.flag_attribute");
@@ -56,7 +53,7 @@ template <typename B>
std::unique_ptr<attribute::SearchContext>
FlagAttributeT<B>::getSearch(QueryTermSimple::UP qTerm, const attribute::SearchContextParams &) const
{
- return std::make_unique<SearchContext>(std::move(qTerm), *this, this->_mvMapping);
+ return std::make_unique<attribute::MultiNumericFlagSearchContext<typename B::BaseType, typename B::WType>>(std::move(qTerm), *this, this->_mvMapping.make_read_view(this->getCommittedDocIdLimit()), _bitVectors);
}
template <typename B>
@@ -232,38 +229,6 @@ FlagAttributeT<B>::removeOldGenerations(vespalib::GenerationHandler::generation_
_bitVectorHolder.trimHoldLists(firstUsed);
}
-template <typename B>
-FlagAttributeT<B>::SearchContext::SearchContext(QueryTermSimple::UP qTerm, const FlagAttributeT<B> & toBeSearched, const MvMapping& mv_mapping)
- : BaseSC(std::move(qTerm), toBeSearched, mv_mapping),
- _zeroHits(false)
-{
-}
-
-template <typename B>
-SearchIterator::UP
-FlagAttributeT<B>::SearchContext::createIterator(fef::TermFieldMatchData * matchData, bool strict)
-{
- if (this->valid()) {
- if (this->_low == this->_high) {
- const Attribute & attr(static_cast<const Attribute &>(this->attribute()));
- const BitVector * bv(attr.getBitVector(this->_low));
- if (bv != nullptr) {
- return BitVectorIterator::create(bv, attr.getCommittedDocIdLimit(), *matchData, strict);
- } else {
- return std::make_unique<queryeval::EmptySearch>();
- }
- } else {
- SearchIterator::UP flagIterator(
- strict
- ? new FlagAttributeIteratorStrict<typename FlagAttributeT<B>::SearchContext>(*this, matchData)
- : new FlagAttributeIteratorT<typename FlagAttributeT<B>::SearchContext>(*this, matchData));
- return flagIterator;
- }
- } else {
- return std::make_unique<queryeval::EmptySearch>();
- }
-}
-
template class FlagAttributeT<FlagBaseImpl>;
}
diff --git a/searchlib/src/vespa/searchlib/attribute/flagattribute.h b/searchlib/src/vespa/searchlib/attribute/flagattribute.h
index c1ac4e007bf..24bec517eb0 100644
--- a/searchlib/src/vespa/searchlib/attribute/flagattribute.h
+++ b/searchlib/src/vespa/searchlib/attribute/flagattribute.h
@@ -7,7 +7,6 @@
namespace search {
typedef MultiValueNumericAttribute< IntegerAttributeTemplate<int8_t>, multivalue::Value<int8_t> > FlagBaseImpl;
-typedef MultiValueNumericAttribute< IntegerAttributeTemplate<int8_t>, multivalue::Value<int8_t> > HugeFlagBaseImpl;
template <typename B>
class FlagAttributeT : public B {
@@ -15,22 +14,6 @@ public:
FlagAttributeT(const vespalib::string & baseFileName, const AttributeVector::Config & cfg);
private:
typedef AttributeVector::DocId DocId;
- using BaseSC = attribute::MultiNumericSearchContext<typename B::BaseType, typename B::WType>;
- class SearchContext : public BaseSC {
- public:
- typedef FlagAttributeT<B> Attribute;
- using MvMapping = attribute::MultiValueMapping<typename B::WType>;
- SearchContext(std::unique_ptr<QueryTermSimple> qTerm, const FlagAttributeT<B> & toBeSearched, const MvMapping& mv_mapping);
-
- std::unique_ptr<queryeval::SearchIterator>
- createIterator(fef::TermFieldMatchData * matchData, bool strict) override;
-
- private:
- bool _zeroHits;
-
- template <class SC> friend class FlagAttributeIteratorT;
- template <class SC> friend class FlagAttributeIteratorStrict;
- };
bool onLoad(vespalib::Executor *executor) override;
bool onLoadEnumerated(ReaderBase &attrReader) override;
std::unique_ptr<attribute::SearchContext>
@@ -50,20 +33,14 @@ private:
void resizeBitVectors(uint32_t neededSize);
void removeOldGenerations(vespalib::GenerationHandler::generation_t firstUsed) override;
uint32_t getOffset(int8_t value) const { return value + 128; }
- BitVector * getBitVector(typename B::BaseType value) const {
- return _bitVectors[value + 128];
- }
vespalib::GenerationHolder _bitVectorHolder;
std::vector<std::shared_ptr<BitVector> > _bitVectorStore;
std::vector<BitVector *> _bitVectors;
uint32_t _bitVectorSize;
- template <class SC> friend class FlagAttributeIteratorT;
- template <class SC> friend class FlagAttributeIteratorStrict;
};
typedef FlagAttributeT<FlagBaseImpl> FlagAttribute;
-typedef FlagAttributeT<HugeFlagBaseImpl> HugeFlagAttribute;
} // namespace search
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 44e7fe9491f..b88a10652a7 100644
--- a/searchlib/src/vespa/searchlib/attribute/multi_enum_search_context.h
+++ b/searchlib/src/vespa/searchlib/attribute/multi_enum_search_context.h
@@ -4,7 +4,7 @@
#include "numeric_search_context.h"
#include "enumstore.h"
-#include "multi_value_mapping.h"
+#include "multi_value_mapping_read_view.h"
namespace search::attribute {
@@ -18,8 +18,8 @@ class MultiEnumSearchContext : public BaseSC
{
protected:
using DocId = ISearchContext::DocId;
- const MultiValueMapping<M>& _mv_mapping;
- const EnumStoreT<T>& _enum_store;
+ MultiValueMappingReadView<M> _mv_mapping_read_view;
+ const EnumStoreT<T>& _enum_store;
int32_t onFind(DocId docId, int32_t elemId, int32_t & weight) const override {
return find(docId, elemId, weight);
@@ -29,11 +29,11 @@ protected:
return find(docId, elemId);
}
- MultiEnumSearchContext(typename BaseSC::MatcherType&& matcher, const AttributeVector& toBeSearched, const MultiValueMapping<M>& mv_mapping, const EnumStoreT<T>& enum_store);
+ MultiEnumSearchContext(typename BaseSC::MatcherType&& matcher, const AttributeVector& toBeSearched, MultiValueMappingReadView<M> mv_mapping_read_view, const EnumStoreT<T>& enum_store);
public:
int32_t find(DocId doc, int32_t elemId, int32_t & weight) const {
- auto indices(_mv_mapping.get(doc));
+ auto indices(_mv_mapping_read_view.get(doc));
for (uint32_t i(elemId); i < indices.size(); i++) {
T v = _enum_store.get_value(indices[i].value_ref().load_acquire());
if (this->match(v)) {
@@ -46,7 +46,7 @@ public:
}
int32_t find(DocId doc, int32_t elemId) const {
- auto indices(_mv_mapping.get(doc));
+ auto indices(_mv_mapping_read_view.get(doc));
for (uint32_t i(elemId); i < indices.size(); i++) {
T v = _enum_store.get_value(indices[i].value_ref().load_acquire());
if (this->match(v)) {
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 cc1640a08b9..e7901199e50 100644
--- a/searchlib/src/vespa/searchlib/attribute/multi_enum_search_context.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/multi_enum_search_context.hpp
@@ -9,9 +9,9 @@
namespace search::attribute {
template <typename T, typename BaseSC, typename M>
-MultiEnumSearchContext<T, BaseSC, M>::MultiEnumSearchContext(typename BaseSC::MatcherType&& matcher, const AttributeVector& toBeSearched, const MultiValueMapping<M>& mv_mapping, const EnumStoreT<T>& enum_store)
+MultiEnumSearchContext<T, BaseSC, M>::MultiEnumSearchContext(typename BaseSC::MatcherType&& matcher, const AttributeVector& toBeSearched, MultiValueMappingReadView<M> mv_mapping_read_view, const EnumStoreT<T>& enum_store)
: BaseSC(toBeSearched, std::move(matcher)),
- _mv_mapping(mv_mapping),
+ _mv_mapping_read_view(mv_mapping_read_view),
_enum_store(enum_store)
{
}
diff --git a/searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.h b/searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.h
index b70ce2459ee..fe05afc606f 100644
--- a/searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.h
+++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.h
@@ -16,7 +16,7 @@ template <typename T, typename M>
class MultiNumericEnumSearchContext : public MultiEnumSearchContext<T, NumericSearchContext<NumericRangeMatcher<T>>, M>
{
public:
- MultiNumericEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const MultiValueMapping<M>& mv_mapping, const EnumStoreT<T>& enum_store);
+ MultiNumericEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, MultiValueMappingReadView<M> mv_mapping_read_view, const EnumStoreT<T>& enum_store);
};
}
diff --git a/searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.hpp b/searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.hpp
index 9780aa7a507..f4f2c2407fc 100644
--- a/searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_enum_search_context.hpp
@@ -8,8 +8,8 @@
namespace search::attribute {
template <typename T, typename M>
-MultiNumericEnumSearchContext<T, M>::MultiNumericEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const MultiValueMapping<M>& mv_mapping, const EnumStoreT<T>& enum_store)
- : MultiEnumSearchContext<T, NumericSearchContext<NumericRangeMatcher<T>>, M>(NumericRangeMatcher<T>(*qTerm), toBeSearched, mv_mapping, enum_store)
+MultiNumericEnumSearchContext<T, M>::MultiNumericEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, MultiValueMappingReadView<M> mv_mapping_read_view, const EnumStoreT<T>& enum_store)
+ : MultiEnumSearchContext<T, NumericSearchContext<NumericRangeMatcher<T>>, M>(NumericRangeMatcher<T>(*qTerm), toBeSearched, mv_mapping_read_view, enum_store)
{
}
diff --git a/searchlib/src/vespa/searchlib/attribute/multi_numeric_flag_search_context.cpp b/searchlib/src/vespa/searchlib/attribute/multi_numeric_flag_search_context.cpp
new file mode 100644
index 00000000000..1c187c5dbd6
--- /dev/null
+++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_flag_search_context.cpp
@@ -0,0 +1,50 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "multi_numeric_flag_search_context.h"
+#include "attributeiterators.hpp"
+#include "attributevector.h"
+#include <vespa/searchcommon/attribute/multivalue.h>
+#include <vespa/searchlib/common/bitvectoriterator.h>
+#include <vespa/searchlib/queryeval/emptysearch.h>
+#include <vespa/searchlib/query/query_term_simple.h>
+
+namespace search::attribute {
+
+using queryeval::SearchIterator;
+
+template <typename T, typename M>
+MultiNumericFlagSearchContext<T, M>::MultiNumericFlagSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, MultiValueMappingReadView<M> mv_mapping_read_view, vespalib::ConstArrayRef<BitVector *> bit_vectors)
+ : MultiNumericSearchContext<T, M>(std::move(qTerm), toBeSearched, mv_mapping_read_view),
+ _bit_vectors(bit_vectors),
+ _zeroHits(false)
+{
+}
+
+template <typename T, typename M>
+std::unique_ptr<SearchIterator>
+MultiNumericFlagSearchContext<T, M>::createIterator(fef::TermFieldMatchData* matchData, bool strict)
+{
+ if (this->valid()) {
+ if (this->_low == this->_high) {
+ const AttributeVector & attr = this->attribute();
+ const BitVector * bv(get_bit_vector(this->_low));
+ if (bv != nullptr) {
+ return BitVectorIterator::create(bv, attr.getCommittedDocIdLimit(), *matchData, strict);
+ } else {
+ return std::make_unique<queryeval::EmptySearch>();
+ }
+ } else {
+ SearchIterator::UP flagIterator(
+ strict
+ ? new FlagAttributeIteratorStrict<MultiNumericFlagSearchContext>(*this, matchData)
+ : new FlagAttributeIteratorT<MultiNumericFlagSearchContext>(*this, matchData));
+ return flagIterator;
+ }
+ } else {
+ return std::make_unique<queryeval::EmptySearch>();
+ }
+}
+
+template class MultiNumericFlagSearchContext<int8_t, multivalue::Value<int8_t>>;
+
+}
diff --git a/searchlib/src/vespa/searchlib/attribute/multi_numeric_flag_search_context.h b/searchlib/src/vespa/searchlib/attribute/multi_numeric_flag_search_context.h
new file mode 100644
index 00000000000..00f7077b2d0
--- /dev/null
+++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_flag_search_context.h
@@ -0,0 +1,39 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include "multi_numeric_search_context.h"
+
+namespace search {
+class BitVector;
+template <class SC> class FlagAttributeIteratorT;
+template <class SC> class FlagAttributeIteratorStrict;
+}
+
+namespace search::attribute {
+
+/*
+ * MultiNumericFlagSearchContext handles the creation of search iterators for
+ * a query term on a multi value numeric flag attribute vector.
+ */
+template <typename T, typename M>
+class MultiNumericFlagSearchContext : public MultiNumericSearchContext<T, M>
+{
+public:
+ MultiNumericFlagSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, MultiValueMappingReadView<M> mv_mapping_read_view, vespalib::ConstArrayRef<BitVector *> bit_vectors);
+
+ std::unique_ptr<queryeval::SearchIterator>
+ createIterator(fef::TermFieldMatchData * matchData, bool strict) override;
+private:
+ vespalib::ConstArrayRef<BitVector *> _bit_vectors;
+ bool _zeroHits;
+ const BitVector* get_bit_vector(T value) const {
+ static_assert(std::is_same_v<T, int8_t>, "Flag attribute search context is only supported for int8_t data type");
+ return _bit_vectors[value + 128];
+ }
+
+ template <class SC> friend class ::search::FlagAttributeIteratorT;
+ template <class SC> friend class ::search::FlagAttributeIteratorStrict;
+};
+
+}
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 7d43e195d00..3649b542e87 100644
--- a/searchlib/src/vespa/searchlib/attribute/multi_numeric_search_context.h
+++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_search_context.h
@@ -3,7 +3,7 @@
#pragma once
#include "numeric_search_context.h"
-#include "multi_value_mapping.h"
+#include "multi_value_mapping_read_view.h"
#include "numeric_range_matcher.h"
namespace search::attribute {
@@ -17,7 +17,7 @@ class MultiNumericSearchContext : public NumericSearchContext<NumericRangeMatche
{
private:
using DocId = ISearchContext::DocId;
- const MultiValueMapping<M>& _mv_mapping;
+ MultiValueMappingReadView<M> _mv_mapping_read_view;
int32_t onFind(DocId docId, int32_t elemId, int32_t& weight) const override final {
return find(docId, elemId, weight);
@@ -28,9 +28,9 @@ private:
}
public:
- MultiNumericSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const MultiValueMapping<M>& mv_mapping);
+ MultiNumericSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, MultiValueMappingReadView<M> mv_mapping_read_view);
int32_t find(DocId doc, int32_t elemId, int32_t & weight) const {
- auto values(_mv_mapping.get(doc));
+ auto values(_mv_mapping_read_view.get(doc));
for (uint32_t i(elemId); i < values.size(); i++) {
if (this->match(values[i].value())) {
weight = values[i].weight();
@@ -42,7 +42,7 @@ public:
}
int32_t find(DocId doc, int32_t elemId) const {
- auto values(_mv_mapping.get(doc));
+ auto values(_mv_mapping_read_view.get(doc));
for (uint32_t i(elemId); i < values.size(); i++) {
if (this->match(values[i].value())) {
return i;
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 8398c921ec6..15b851215f8 100644
--- a/searchlib/src/vespa/searchlib/attribute/multi_numeric_search_context.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/multi_numeric_search_context.hpp
@@ -10,9 +10,9 @@
namespace search::attribute {
template <typename T, typename M>
-MultiNumericSearchContext<T, M>::MultiNumericSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, const MultiValueMapping<M>& mv_mapping)
+MultiNumericSearchContext<T, M>::MultiNumericSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const AttributeVector& toBeSearched, MultiValueMappingReadView<M> mv_mapping_read_view)
: NumericSearchContext<NumericRangeMatcher<T>>(toBeSearched, *qTerm, false),
- _mv_mapping(mv_mapping)
+ _mv_mapping_read_view(mv_mapping_read_view)
{
}
diff --git a/searchlib/src/vespa/searchlib/attribute/multi_string_enum_hint_search_context.h b/searchlib/src/vespa/searchlib/attribute/multi_string_enum_hint_search_context.h
index 92650851116..3ae342be61b 100644
--- a/searchlib/src/vespa/searchlib/attribute/multi_string_enum_hint_search_context.h
+++ b/searchlib/src/vespa/searchlib/attribute/multi_string_enum_hint_search_context.h
@@ -17,7 +17,7 @@ class MultiStringEnumHintSearchContext : public MultiStringEnumSearchContext<M>,
public EnumHintSearchContext
{
public:
- MultiStringEnumHintSearchContext(std::unique_ptr<QueryTermSimple> qTerm, bool cased, const AttributeVector& toBeSearched, const MultiValueMapping<M>& mv_mapping, const EnumStoreT<const char*>& enum_store, uint32_t doc_id_limit, uint64_t num_values);
+ MultiStringEnumHintSearchContext(std::unique_ptr<QueryTermSimple> qTerm, bool cased, const AttributeVector& toBeSearched, MultiValueMappingReadView<M> mv_mapping_read_view, const EnumStoreT<const char*>& enum_store, uint32_t doc_id_limit, uint64_t num_values);
~MultiStringEnumHintSearchContext() override;
};
diff --git a/searchlib/src/vespa/searchlib/attribute/multi_string_enum_hint_search_context.hpp b/searchlib/src/vespa/searchlib/attribute/multi_string_enum_hint_search_context.hpp
index a6b0f3f5eb9..fc1f72c940f 100644
--- a/searchlib/src/vespa/searchlib/attribute/multi_string_enum_hint_search_context.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/multi_string_enum_hint_search_context.hpp
@@ -6,8 +6,8 @@
namespace search::attribute {
template <typename M>
-MultiStringEnumHintSearchContext<M>::MultiStringEnumHintSearchContext(std::unique_ptr<QueryTermSimple> qTerm, bool cased, const AttributeVector& toBeSearched, const MultiValueMapping<M>& mv_mapping, const EnumStoreT<const char*>& enum_store, uint32_t doc_id_limit, uint64_t num_values)
- : MultiStringEnumSearchContext<M>(std::move(qTerm), cased, toBeSearched, mv_mapping, enum_store),
+MultiStringEnumHintSearchContext<M>::MultiStringEnumHintSearchContext(std::unique_ptr<QueryTermSimple> qTerm, bool cased, const AttributeVector& toBeSearched, MultiValueMappingReadView<M> mv_mapping_read_view, const EnumStoreT<const char*>& enum_store, uint32_t doc_id_limit, uint64_t num_values)
+ : MultiStringEnumSearchContext<M>(std::move(qTerm), cased, toBeSearched, mv_mapping_read_view, enum_store),
EnumHintSearchContext(enum_store.get_dictionary(),
doc_id_limit, num_values)
{
diff --git a/searchlib/src/vespa/searchlib/attribute/multi_string_enum_search_context.h b/searchlib/src/vespa/searchlib/attribute/multi_string_enum_search_context.h
index a4f05a5c9cc..1787ea0086d 100644
--- a/searchlib/src/vespa/searchlib/attribute/multi_string_enum_search_context.h
+++ b/searchlib/src/vespa/searchlib/attribute/multi_string_enum_search_context.h
@@ -15,7 +15,7 @@ template <typename M>
class MultiStringEnumSearchContext : public MultiEnumSearchContext<const char*, StringSearchContext, M>
{
public:
- MultiStringEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, bool cased, const AttributeVector& toBeSearched, const MultiValueMapping<M>& mv_mapping, const EnumStoreT<const char*>& enum_store);
+ MultiStringEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, bool cased, const AttributeVector& toBeSearched, MultiValueMappingReadView<M> mv_mapping_read_view, const EnumStoreT<const char*>& enum_store);
};
}
diff --git a/searchlib/src/vespa/searchlib/attribute/multi_string_enum_search_context.hpp b/searchlib/src/vespa/searchlib/attribute/multi_string_enum_search_context.hpp
index 02a740b06dc..1d74db04373 100644
--- a/searchlib/src/vespa/searchlib/attribute/multi_string_enum_search_context.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/multi_string_enum_search_context.hpp
@@ -9,8 +9,8 @@
namespace search::attribute {
template <typename M>
-MultiStringEnumSearchContext<M>::MultiStringEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, bool cased, const AttributeVector& toBeSearched, const MultiValueMapping<M>& mv_mapping, const EnumStoreT<const char*>& enum_store)
- : MultiEnumSearchContext<const char*, StringSearchContext, M>(StringMatcher(std::move(qTerm), cased), toBeSearched, mv_mapping, enum_store)
+MultiStringEnumSearchContext<M>::MultiStringEnumSearchContext(std::unique_ptr<QueryTermSimple> qTerm, bool cased, const AttributeVector& toBeSearched, MultiValueMappingReadView<M> mv_mapping_read_view, const EnumStoreT<const char*>& enum_store)
+ : MultiEnumSearchContext<const char*, StringSearchContext, M>(StringMatcher(std::move(qTerm), cased), toBeSearched, mv_mapping_read_view, enum_store)
{
}
diff --git a/searchlib/src/vespa/searchlib/attribute/multi_value_mapping.h b/searchlib/src/vespa/searchlib/attribute/multi_value_mapping.h
index 382f5b02642..b57269d04c6 100644
--- a/searchlib/src/vespa/searchlib/attribute/multi_value_mapping.h
+++ b/searchlib/src/vespa/searchlib/attribute/multi_value_mapping.h
@@ -3,13 +3,14 @@
#pragma once
#include "multi_value_mapping_base.h"
+#include "multi_value_mapping_read_view.h"
#include <vespa/vespalib/datastore/array_store.h>
#include <vespa/vespalib/util/address_space.h>
namespace search::attribute {
/**
- * Class for mapping from from document id to an array of values.
+ * Class for mapping from document id to an array of values.
*/
template <typename EntryT, typename RefT = vespalib::datastore::EntryRefT<19> >
class MultiValueMapping : public MultiValueMappingBase
@@ -17,6 +18,7 @@ class MultiValueMapping : public MultiValueMappingBase
public:
using MultiValueType = EntryT;
using RefType = RefT;
+ using ReadView = MultiValueMappingReadView<EntryT, RefT>;
private:
using ArrayRef = vespalib::ArrayRef<EntryT>;
using ArrayStore = vespalib::datastore::ArrayStore<EntryT, RefT>;
@@ -39,6 +41,12 @@ public:
// compacting enum store (replacing old enum index with updated enum index)
ArrayRef get_writable(uint32_t docId) { return _store.get_writable(_indices[docId].load_relaxed()); }
+ /*
+ * Readers holding a generation guard can call make_read_view() to
+ * get a read view to the multi value mapping. Array bound (read_size) must
+ * be specified by reader, cf. committed docid limit in attribute vectors.
+ */
+ ReadView make_read_view(size_t read_size) const { return ReadView(_indices.make_read_view(read_size), &_store); }
// Pass on hold list management to underlying store
void transferHoldLists(generation_t generation) { _store.transferHoldLists(generation); }
void trimHoldLists(generation_t firstUsed) { _store.trimHoldLists(firstUsed); }
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
new file mode 100644
index 00000000000..116e069e8b4
--- /dev/null
+++ b/searchlib/src/vespa/searchlib/attribute/multi_value_mapping_read_view.h
@@ -0,0 +1,38 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include <vespa/vespalib/datastore/atomic_entry_ref.h>
+#include <vespa/vespalib/datastore/array_store.h>
+#include <vespa/vespalib/util/address_space.h>
+
+namespace search::attribute {
+
+/**
+ * Class for mapping from document id to an array of values as reader.
+ */
+template <typename EntryT, typename RefT = vespalib::datastore::EntryRefT<19> >
+class MultiValueMappingReadView
+{
+ using AtomicEntryRef = vespalib::datastore::AtomicEntryRef;
+ using Indices = vespalib::ConstArrayRef<AtomicEntryRef>;
+ using ArrayStore = vespalib::datastore::ArrayStore<EntryT, RefT>;
+
+ Indices _indices;
+ const ArrayStore* _store;
+public:
+ constexpr MultiValueMappingReadView()
+ : _indices(),
+ _store(nullptr)
+ {
+ }
+ MultiValueMappingReadView(Indices indices, const ArrayStore* store)
+ : _indices(indices),
+ _store(store)
+ {
+ }
+ vespalib::ConstArrayRef<EntryT> get(uint32_t doc_id) const { return _store->get(_indices[doc_id].load_acquire()); }
+ bool valid() const noexcept { return _store != nullptr; }
+};
+
+}
diff --git a/searchlib/src/vespa/searchlib/attribute/multinumericattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multinumericattribute.hpp
index 57a7c6a3b14..99963094366 100644
--- a/searchlib/src/vespa/searchlib/attribute/multinumericattribute.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/multinumericattribute.hpp
@@ -171,7 +171,7 @@ MultiValueNumericAttribute<B, M>::getSearch(QueryTermSimple::UP qTerm,
const attribute::SearchContextParams & params) const
{
(void) params;
- return std::make_unique<attribute::MultiNumericSearchContext<T, M>>(std::move(qTerm), *this, this->_mvMapping);
+ return std::make_unique<attribute::MultiNumericSearchContext<T, M>>(std::move(qTerm), *this, this->_mvMapping.make_read_view(this->getCommittedDocIdLimit()));
}
diff --git a/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.hpp
index 201bff48be7..c35a2e55ec3 100644
--- a/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.hpp
@@ -121,7 +121,8 @@ MultiValueNumericEnumAttribute<B, M>::getSearch(QueryTermSimple::UP qTerm,
const attribute::SearchContextParams & params) const
{
(void) params;
- return std::make_unique<attribute::MultiNumericEnumSearchContext<T, M>>(std::move(qTerm), *this, this->_mvMapping, this->_enumStore);
+ auto doc_id_limit = this->getCommittedDocIdLimit();
+ return std::make_unique<attribute::MultiNumericEnumSearchContext<T, M>>(std::move(qTerm), *this, this->_mvMapping.make_read_view(doc_id_limit), this->_enumStore);
}
} // namespace search
diff --git a/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.hpp
index 688bcaf1825..4854728ca37 100644
--- a/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.hpp
@@ -78,7 +78,8 @@ MultiValueNumericPostingAttribute<B, M>::getSearch(QueryTermSimpleUP qTerm,
{
using BaseSC = attribute::MultiNumericEnumSearchContext<typename B::BaseClass::BaseType, M>;
using SC = attribute::NumericPostingSearchContext<BaseSC, SelfType, int32_t>;
- BaseSC base_sc(std::move(qTerm), *this, this->_mvMapping, this->_enumStore);
+ auto doc_id_limit = this->getCommittedDocIdLimit();
+ BaseSC base_sc(std::move(qTerm), *this, this->_mvMapping.make_read_view(doc_id_limit), this->_enumStore);
return std::make_unique<SC>(std::move(base_sc), params, *this);
}
diff --git a/searchlib/src/vespa/searchlib/attribute/multistringattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multistringattribute.hpp
index 212a71dad74..2d60887c23b 100644
--- a/searchlib/src/vespa/searchlib/attribute/multistringattribute.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/multistringattribute.hpp
@@ -43,7 +43,8 @@ MultiValueStringAttributeT<B, M>::getSearch(QueryTermSimpleUP qTerm,
const attribute::SearchContextParams &) const
{
bool cased = this->get_match_is_cased();
- return std::make_unique<attribute::MultiStringEnumHintSearchContext<M>>(std::move(qTerm), cased, *this, this->_mvMapping, this->_enumStore, this->getCommittedDocIdLimit(), this->getStatus().getNumValues());
+ auto doc_id_limit = this->getCommittedDocIdLimit();
+ return std::make_unique<attribute::MultiStringEnumHintSearchContext<M>>(std::move(qTerm), cased, *this, this->_mvMapping.make_read_view(doc_id_limit), this->_enumStore, doc_id_limit, this->getStatus().getNumValues());
}
} // namespace search
diff --git a/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.hpp
index 2c2ac48979d..d3cd338cacb 100644
--- a/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.hpp
@@ -93,7 +93,8 @@ MultiValueStringPostingAttributeT<B, T>::getSearch(QueryTermSimpleUP qTerm,
using BaseSC = attribute::MultiStringEnumSearchContext<T>;
using SC = attribute::StringPostingSearchContext<BaseSC, SelfType, int32_t>;
bool cased = this->get_match_is_cased();
- BaseSC base_sc(std::move(qTerm), cased, *this, this->_mvMapping, this->_enumStore);
+ auto doc_id_limit = this->getCommittedDocIdLimit();
+ BaseSC base_sc(std::move(qTerm), cased, *this, this->_mvMapping.make_read_view(doc_id_limit), this->_enumStore);
return std::make_unique<SC>(std::move(base_sc), params.useBitVector(), *this);
}
diff --git a/searchlib/src/vespa/searchlib/expression/documentfieldnode.cpp b/searchlib/src/vespa/searchlib/expression/documentfieldnode.cpp
index 91e5a36a7cf..f48be061d15 100644
--- a/searchlib/src/vespa/searchlib/expression/documentfieldnode.cpp
+++ b/searchlib/src/vespa/searchlib/expression/documentfieldnode.cpp
@@ -26,7 +26,7 @@ DocumentFieldNode::~DocumentFieldNode() = default;
DocumentFieldNode::DocumentFieldNode(const DocumentFieldNode & rhs) :
DocumentAccessorNode(rhs),
- _fieldPath(rhs._fieldPath),
+ _fieldPath(),
_value(rhs._value),
_fieldName(rhs._fieldName),
_doc(nullptr)
@@ -38,7 +38,7 @@ DocumentFieldNode::operator = (const DocumentFieldNode & rhs)
{
if (this != &rhs) {
DocumentAccessorNode::operator=(rhs);
- _fieldPath = rhs._fieldPath;
+ _fieldPath.clear();
_value = rhs._value;
_fieldName = rhs._fieldName;
_doc = nullptr;
@@ -146,7 +146,7 @@ void DocumentFieldNode::onDocType(const DocumentType & docType)
_fieldPath.clear();
docType.buildFieldPath(_fieldPath, _fieldName);
if (_fieldPath.empty()) {
- throw std::runtime_error(make_string("Field %s could not be loacated in documenttype %s", _fieldName.c_str(), docType.getName().c_str()));
+ throw std::runtime_error(make_string("Field %s could not be located in documenttype %s", _fieldName.c_str(), docType.getName().c_str()));
}
}
diff --git a/searchlib/src/vespa/searchlib/expression/documentfieldnode.h b/searchlib/src/vespa/searchlib/expression/documentfieldnode.h
index fd3923bd4a0..e1038f73fa3 100644
--- a/searchlib/src/vespa/searchlib/expression/documentfieldnode.h
+++ b/searchlib/src/vespa/searchlib/expression/documentfieldnode.h
@@ -32,11 +32,13 @@ public:
DECLARE_NBO_SERIALIZE;
void visitMembers(vespalib::ObjectVisitor &visitor) const override;
DECLARE_EXPRESSIONNODE(DocumentFieldNode);
- DocumentFieldNode() : _fieldPath(), _value(), _fieldName(), _doc(NULL) { }
- ~DocumentFieldNode();
- DocumentFieldNode(vespalib::stringref name) : _fieldPath(), _value(), _fieldName(name), _doc(NULL) { }
+ DocumentFieldNode() : _fieldPath(), _value(), _fieldName(), _doc(nullptr) { }
+ ~DocumentFieldNode() override;
+ DocumentFieldNode(vespalib::stringref name) : _fieldPath(), _value(), _fieldName(name), _doc(nullptr) { }
DocumentFieldNode(const DocumentFieldNode & rhs);
DocumentFieldNode & operator = (const DocumentFieldNode & rhs);
+ DocumentFieldNode(DocumentFieldNode && rhs) noexcept = default;
+ DocumentFieldNode & operator = (DocumentFieldNode && rhs) noexcept = default;
const vespalib::string & getFieldName() const override { return _fieldName; }
private:
class Handler : public document::fieldvalue::IteratorHandler {
diff --git a/searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp b/searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp
index 2a12867dd33..731306d1bea 100644
--- a/searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp
+++ b/searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp
@@ -28,6 +28,10 @@ constexpr int TRACE_SKIP_POS = 10;
using Accept = Blueprint::AcceptInput;
+vespalib::string describe(const vespalib::string &feature_name) {
+ return BlueprintResolver::describe_feature(feature_name);
+}
+
bool is_compatible(bool is_object, Accept accept_type) {
return ((accept_type == Accept::ANY) ||
((accept_type == Accept::OBJECT) == (is_object)));
@@ -122,7 +126,7 @@ struct Compiler : public Blueprint::DependencyHandler {
should_trace |= (i < TRACE_SKIP_POS);
should_trace |= ((end - pos) < (MAX_TRACE_SIZE - TRACE_SKIP_POS));
if (should_trace) {
- trace += fmt(" ... needed by rank feature '%s'\n", pos->parser.featureName().c_str());
+ trace += fmt(" ... needed by %s\n", describe(pos->parser.featureName()).c_str());
} else if (i == TRACE_SKIP_POS) {
trace += fmt(" (skipped %zu entries)\n", (n - MAX_TRACE_SIZE) + 1);
}
@@ -135,9 +139,9 @@ struct Compiler : public Blueprint::DependencyHandler {
failed_set.insert(feature_name);
auto trace = make_trace(skip_self);
if (trace.empty()) {
- LOG(warning, "invalid rank feature '%s': %s", feature_name.c_str(), reason.c_str());
+ LOG(warning, "invalid %s: %s", describe(feature_name).c_str(), reason.c_str());
} else {
- LOG(warning, "invalid rank feature '%s': %s\n%s", feature_name.c_str(), reason.c_str(), trace.c_str());
+ LOG(warning, "invalid %s: %s\n%s", describe(feature_name).c_str(), reason.c_str(), trace.c_str());
}
}
probe_stack();
@@ -264,6 +268,22 @@ BlueprintResolver::BlueprintResolver(const BlueprintFactory &factory,
{
}
+vespalib::string
+BlueprintResolver::describe_feature(const vespalib::string &name)
+{
+ auto parser = std::make_unique<FeatureNameParser>(name);
+ if (parser->valid() &&
+ (parser->baseName() == "rankingExpression") &&
+ (parser->parameters().size() == 1) &&
+ parser->output().empty())
+ {
+ auto param = parser->parameters()[0];
+ param = param.substr(0, param.find("@"));
+ return fmt("function '%s'", param.c_str());
+ }
+ return fmt("rank feature '%s'", name.c_str());
+}
+
void
BlueprintResolver::addSeed(vespalib::stringref feature)
{
diff --git a/searchlib/src/vespa/searchlib/fef/blueprintresolver.h b/searchlib/src/vespa/searchlib/fef/blueprintresolver.h
index 80320ae780a..3e3b5879518 100644
--- a/searchlib/src/vespa/searchlib/fef/blueprintresolver.h
+++ b/searchlib/src/vespa/searchlib/fef/blueprintresolver.h
@@ -100,6 +100,12 @@ public:
BlueprintResolver(const BlueprintFactory &factory,
const IIndexEnvironment &indexEnv);
+ // Describe a feature based on its name (intended for log messages)
+ //
+ // rankingExpression(foo@hash) -> function 'foo'
+ // feature -> rank feature 'feature'
+ static vespalib::string describe_feature(const vespalib::string &name);
+
/**
* Add a feature name to the list of seeds. During compilation,
* blueprints for all seeds and dependencies will be instantiated
diff --git a/searchlib/src/vespa/searchlib/fef/verify_feature.cpp b/searchlib/src/vespa/searchlib/fef/verify_feature.cpp
index d61d7faef0f..85d1daffd01 100644
--- a/searchlib/src/vespa/searchlib/fef/verify_feature.cpp
+++ b/searchlib/src/vespa/searchlib/fef/verify_feature.cpp
@@ -19,8 +19,8 @@ bool verifyFeature(const BlueprintFactory &factory,
resolver.addSeed(featureName);
bool result = resolver.compile();
if (!result) {
- LOG(error, "rank feature verification failed: %s (%s)",
- featureName.c_str(), desc.c_str());
+ LOG(error, "verification failed: %s (%s)",
+ BlueprintResolver::describe_feature(featureName).c_str(), desc.c_str());
}
return result;
}
diff --git a/searchlib/src/vespa/searchlib/tensor/direct_tensor_store.cpp b/searchlib/src/vespa/searchlib/tensor/direct_tensor_store.cpp
index 54f95e1c543..3f2a1bb1969 100644
--- a/searchlib/src/vespa/searchlib/tensor/direct_tensor_store.cpp
+++ b/searchlib/src/vespa/searchlib/tensor/direct_tensor_store.cpp
@@ -21,9 +21,10 @@ void
DirectTensorStore::TensorBufferType::cleanHold(void* buffer, size_t offset, ElemCount num_elems, CleanContext clean_ctx)
{
TensorSP* elem = static_cast<TensorSP*>(buffer) + offset;
+ const auto& empty = empty_entry();
for (size_t i = 0; i < num_elems; ++i) {
clean_ctx.extraBytesCleaned((*elem)->get_memory_usage().allocatedBytes());
- *elem = _emptyEntry;
+ *elem = empty;
++elem;
}
}
diff --git a/searchlib/src/vespa/searchlib/tensor/direct_tensor_store.h b/searchlib/src/vespa/searchlib/tensor/direct_tensor_store.h
index 776920ab930..1f112f1ea28 100644
--- a/searchlib/src/vespa/searchlib/tensor/direct_tensor_store.h
+++ b/searchlib/src/vespa/searchlib/tensor/direct_tensor_store.h
@@ -24,7 +24,7 @@ private:
class TensorBufferType : public vespalib::datastore::BufferType<TensorSP> {
private:
using ParentType = BufferType<TensorSP>;
- using ParentType::_emptyEntry;
+ using ParentType::empty_entry;
using CleanContext = typename ParentType::CleanContext;
public:
TensorBufferType();
diff --git a/searchlib/src/vespa/searchlib/tensor/streamed_value_store.cpp b/searchlib/src/vespa/searchlib/tensor/streamed_value_store.cpp
index 2e6d771a870..a668387e5bd 100644
--- a/searchlib/src/vespa/searchlib/tensor/streamed_value_store.cpp
+++ b/searchlib/src/vespa/searchlib/tensor/streamed_value_store.cpp
@@ -166,9 +166,10 @@ void
StreamedValueStore::TensorBufferType::cleanHold(void* buffer, size_t offset, ElemCount num_elems, CleanContext clean_ctx)
{
TensorEntry::SP* elem = static_cast<TensorEntry::SP*>(buffer) + offset;
+ const auto& empty = empty_entry();
for (size_t i = 0; i < num_elems; ++i) {
clean_ctx.extraBytesCleaned((*elem)->get_memory_usage().allocatedBytes());
- *elem = _emptyEntry;
+ *elem = empty;
++elem;
}
}
diff --git a/searchlib/src/vespa/searchlib/tensor/streamed_value_store.h b/searchlib/src/vespa/searchlib/tensor/streamed_value_store.h
index 7d83e9f3335..29201dc0e61 100644
--- a/searchlib/src/vespa/searchlib/tensor/streamed_value_store.h
+++ b/searchlib/src/vespa/searchlib/tensor/streamed_value_store.h
@@ -51,7 +51,7 @@ private:
class TensorBufferType : public vespalib::datastore::BufferType<TensorEntry::SP> {
private:
using ParentType = BufferType<TensorEntry::SP>;
- using ParentType::_emptyEntry;
+ using ParentType::empty_entry;
using CleanContext = typename ParentType::CleanContext;
public:
TensorBufferType() noexcept;