summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@oath.com>2018-05-22 21:29:12 +0200
committerHenning Baldersheim <balder@oath.com>2018-05-23 23:21:04 +0200
commit69aae49a30dc657dfa5a603701ffe4ad231ea92f (patch)
tree9f2e743a208b1d2751b350f9d7ee5e8e274cb2de
parentff2138aa963c5f7147779057465d97c3d22a7028 (diff)
Refactored to allow iteration over matching elements.
-rw-r--r--searchcommon/src/vespa/searchcommon/attribute/i_search_context.h10
-rw-r--r--searchcore/src/vespa/searchcore/proton/documentmetastore/search_context.cpp49
-rw-r--r--searchcore/src/vespa/searchcore/proton/documentmetastore/search_context.h16
-rw-r--r--searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp14
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attributeiterators.h4
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attributeiterators.hpp14
-rw-r--r--searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp3
-rw-r--r--searchlib/src/vespa/searchlib/attribute/imported_search_context.h14
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multinumericattribute.h60
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.h66
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multistringattribute.h8
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multistringattribute.hpp32
-rw-r--r--searchlib/src/vespa/searchlib/attribute/singlenumericattribute.h18
-rw-r--r--searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.h18
-rw-r--r--searchlib/src/vespa/searchlib/attribute/singlesmallnumericattribute.h31
-rw-r--r--searchlib/src/vespa/searchlib/attribute/singlestringattribute.h9
-rw-r--r--searchlib/src/vespa/searchlib/attribute/stringbase.cpp18
-rw-r--r--searchlib/src/vespa/searchlib/attribute/stringbase.h21
18 files changed, 202 insertions, 203 deletions
diff --git a/searchcommon/src/vespa/searchcommon/attribute/i_search_context.h b/searchcommon/src/vespa/searchcommon/attribute/i_search_context.h
index 4be1f00dcbc..3eede13c42d 100644
--- a/searchcommon/src/vespa/searchcommon/attribute/i_search_context.h
+++ b/searchcommon/src/vespa/searchcommon/attribute/i_search_context.h
@@ -24,8 +24,8 @@ public:
using DocId = uint32_t;
private:
- virtual bool onCmp(DocId docId, int32_t &weight) const = 0;
- virtual bool onCmp(DocId docId) const = 0;
+ virtual int32_t onCmp(DocId docId, int32_t elementId, int32_t &weight) const = 0;
+ virtual int32_t onCmp(DocId docId, int32_t elementId) const = 0;
public:
virtual ~ISearchContext() {}
@@ -57,8 +57,10 @@ public:
virtual const QueryTermBase &queryTerm() const = 0;
virtual const vespalib::string &attributeName() const = 0;
- bool cmp(DocId docId, int32_t &weight) const { return onCmp(docId, weight); }
- bool cmp(DocId docId) const { return onCmp(docId); }
+ int32_t find(DocId docId, int32_t elementId, int32_t &weight) const { return onCmp(docId, elementId, weight); }
+ int32_t find(DocId docId, int32_t elementId) const { return onCmp(docId, elementId); }
+ bool matches(DocId docId, int32_t &weight) const { return find(docId, 0, weight) >= 0; }
+ bool matches(DocId doc) const { return find(doc, 0) >= 0; }
};
diff --git a/searchcore/src/vespa/searchcore/proton/documentmetastore/search_context.cpp b/searchcore/src/vespa/searchcore/proton/documentmetastore/search_context.cpp
index 068b7f4fa00..99865f6bd44 100644
--- a/searchcore/src/vespa/searchcore/proton/documentmetastore/search_context.cpp
+++ b/searchcore/src/vespa/searchcore/proton/documentmetastore/search_context.cpp
@@ -12,15 +12,14 @@ using search::QueryTermSimple;
using search::fef::TermFieldMatchData;
using search::queryeval::SearchIterator;
-namespace proton {
-namespace documentmetastore {
+namespace proton::documentmetastore {
namespace {
class GidAllSearchIterator : public AttributeIteratorBase
{
private:
- virtual void
+ void
doSeek(uint32_t docId) override
{
if (_store.validLidFast(docId)) {
@@ -28,7 +27,7 @@ private:
}
}
- virtual void
+ void
doUnpack(uint32_t docId) override
{
_matchData->reset(docId);
@@ -37,8 +36,7 @@ private:
protected:
const DocumentMetaStore & _store;
public:
- GidAllSearchIterator(TermFieldMatchData *matchData,
- const DocumentMetaStore &store)
+ GidAllSearchIterator(TermFieldMatchData *matchData, const DocumentMetaStore &store)
: AttributeIteratorBase(matchData),
_store(store)
{
@@ -79,7 +77,7 @@ class GidSearchIterator : public GidAllSearchIterator
private:
const GlobalId & _gid;
- virtual void
+ void
doSeek(uint32_t docId) override
{
AttributeVector::DocId lid = 0;
@@ -90,9 +88,7 @@ private:
}
}
public:
- GidSearchIterator(TermFieldMatchData *matchData,
- const DocumentMetaStore &store,
- const GlobalId &gid)
+ GidSearchIterator(TermFieldMatchData *matchData, const DocumentMetaStore &store, const GlobalId &gid)
: GidAllSearchIterator(matchData, store),
_gid(gid)
{
@@ -101,23 +97,16 @@ public:
}
-bool
-SearchContext::onCmp(DocId docId, int32_t &weight) const
+int32_t
+SearchContext::onCmp(DocId, int32_t, int32_t &) const
{
- (void) docId;
- (void) weight;
- throw vespalib::IllegalStateException(
- "The function is not implemented for documentmetastore::SearchContext");
- return false;
+ throw vespalib::IllegalStateException("The function is not implemented for documentmetastore::SearchContext");
}
-bool
-SearchContext::onCmp(DocId docId) const
+int32_t
+SearchContext::onCmp(DocId, int32_t ) const
{
- (void) docId;
- throw vespalib::IllegalStateException(
- "The function is not implemented for documentmetastore::SearchContext");
- return false;
+ throw vespalib::IllegalStateException("The function is not implemented for documentmetastore::SearchContext");
}
unsigned int
@@ -127,15 +116,13 @@ SearchContext::approximateHits() const
}
SearchIterator::UP
-SearchContext::createIterator(TermFieldMatchData *matchData,
- bool strict)
+SearchContext::createIterator(TermFieldMatchData *matchData, bool strict)
{
return _isWord
- ? SearchIterator::UP(new GidSearchIterator(matchData, getStore(), _gid))
+ ? std::make_unique<GidSearchIterator>(matchData, getStore(), _gid)
: strict
- ? SearchIterator::UP(new GidStrictAllSearchIterator(matchData,
- getStore()))
- : SearchIterator::UP(new GidAllSearchIterator(matchData, getStore()));
+ ? std::make_unique<GidStrictAllSearchIterator>(matchData, getStore())
+ : std::make_unique<GidAllSearchIterator>(matchData, getStore());
}
const DocumentMetaStore &
@@ -144,12 +131,10 @@ SearchContext::getStore() const
return static_cast<const DocumentMetaStore &>(attribute());
}
-SearchContext::SearchContext(QueryTermSimple::UP qTerm,
- const DocumentMetaStore &toBeSearched)
+SearchContext::SearchContext(QueryTermSimple::UP qTerm, const DocumentMetaStore &toBeSearched)
: search::AttributeVector::SearchContext(toBeSearched),
_isWord(qTerm->isWord())
{
}
}
-}
diff --git a/searchcore/src/vespa/searchcore/proton/documentmetastore/search_context.h b/searchcore/src/vespa/searchcore/proton/documentmetastore/search_context.h
index afd09be43e9..6e1eaa468c9 100644
--- a/searchcore/src/vespa/searchcore/proton/documentmetastore/search_context.h
+++ b/searchcore/src/vespa/searchcore/proton/documentmetastore/search_context.h
@@ -6,8 +6,7 @@
#include <vespa/searchlib/attribute/attributevector.h>
#include "documentmetastore.h"
-namespace proton {
-namespace documentmetastore {
+namespace proton::documentmetastore {
/**
* Search context used to search the document meta store for all valid documents.
@@ -15,14 +14,14 @@ namespace documentmetastore {
class SearchContext : public search::AttributeVector::SearchContext
{
private:
- typedef search::AttributeVector::DocId DocId;
+ using DocId = search::AttributeVector::DocId;
bool _isWord;
document::GlobalId _gid;
unsigned int approximateHits() const override;
- bool onCmp(DocId docId, int32_t &weight) const override;
- bool onCmp(DocId docId) const override;
+ int32_t onCmp(DocId docId, int32_t elemId, int32_t &weight) const override;
+ int32_t onCmp(DocId docId, int32_t elemId) const override;
search::queryeval::SearchIterator::UP
createIterator(search::fef::TermFieldMatchData *matchData, bool strict) override;
@@ -30,10 +29,7 @@ private:
const DocumentMetaStore &getStore() const;
public:
- SearchContext(std::unique_ptr<search::QueryTermSimple> qTerm,
- const DocumentMetaStore &toBeSearched);
+ SearchContext(std::unique_ptr<search::QueryTermSimple> qTerm, const DocumentMetaStore &toBeSearched);
};
-} // namespace documentmetastore
-} // namespace proton
-
+}
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 e8e16ffcc98..bb9d9960d08 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
@@ -303,22 +303,22 @@ TEST_F("Strict iterator handles seek outside of LID space", ArrayValueFixture) {
TEST_F("cmp() performs GID mapping and forwards to target attribute", SingleValueFixture) {
auto ctx = f.create_context(word_term("5678"));
- EXPECT_FALSE(ctx->cmp(DocId(2)));
- EXPECT_TRUE(ctx->cmp(DocId(3)));
- EXPECT_FALSE(ctx->cmp(DocId(4)));
- EXPECT_TRUE(ctx->cmp(DocId(5)));
+ EXPECT_FALSE(ctx->matches(DocId(2)));
+ EXPECT_TRUE(ctx->matches(DocId(3)));
+ EXPECT_FALSE(ctx->matches(DocId(4)));
+ EXPECT_TRUE(ctx->matches(DocId(5)));
}
TEST_F("cmp(weight) performs GID mapping and forwards to target attribute", WsetValueFixture) {
auto ctx = f.create_context(word_term("foo"));
int32_t weight = 0;
- EXPECT_FALSE(ctx->cmp(DocId(1), weight));
+ EXPECT_FALSE(ctx->matches(DocId(1), weight));
EXPECT_EQUAL(0, weight); // Unchanged
- EXPECT_TRUE(ctx->cmp(DocId(2), weight));
+ EXPECT_TRUE(ctx->matches(DocId(2), weight));
EXPECT_EQUAL(-5, weight);
- EXPECT_TRUE(ctx->cmp(DocId(6), weight));
+ EXPECT_TRUE(ctx->matches(DocId(6), weight));
EXPECT_EQUAL(42, weight);
}
diff --git a/searchlib/src/vespa/searchlib/attribute/attributeiterators.h b/searchlib/src/vespa/searchlib/attribute/attributeiterators.h
index febf7d101a9..e0fa06c5e84 100644
--- a/searchlib/src/vespa/searchlib/attribute/attributeiterators.h
+++ b/searchlib/src/vespa/searchlib/attribute/attributeiterators.h
@@ -82,7 +82,7 @@ protected:
public:
AttributeIteratorT(const SC &searchContext, fef::TermFieldMatchData *matchData);
- bool seekFast(uint32_t docId) const { return _searchContext.cmp(docId); }
+ bool seekFast(uint32_t docId) const { return _searchContext.matches(docId); }
};
template <typename SC>
@@ -100,7 +100,7 @@ protected:
public:
FilterAttributeIteratorT(const SC &searchContext, fef::TermFieldMatchData *matchData);
- bool seekFast(uint32_t docId) const { return _searchContext.cmp(docId); }
+ bool seekFast(uint32_t docId) const { return _searchContext.matches(docId); }
};
diff --git a/searchlib/src/vespa/searchlib/attribute/attributeiterators.hpp b/searchlib/src/vespa/searchlib/attribute/attributeiterators.hpp
index fb47ad0cfcc..9b1e837beac 100644
--- a/searchlib/src/vespa/searchlib/attribute/attributeiterators.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/attributeiterators.hpp
@@ -16,14 +16,14 @@ namespace search {
template <typename SC>
void
AttributeIteratorBase::and_hits_into(const SC & sc, BitVector & result, uint32_t begin_id) const {
- result.foreach_truebit([&](uint32_t key) { if ( ! sc.cmp(key)) { result.clearBit(key); }}, begin_id);
+ result.foreach_truebit([&](uint32_t key) { if ( ! sc.matches(key)) { result.clearBit(key); }}, begin_id);
result.invalidateCachedCount();
}
template <typename SC>
void
AttributeIteratorBase::or_hits_into(const SC & sc, BitVector & result, uint32_t begin_id) const {
- result.foreach_falsebit([&](uint32_t key) { if ( sc.cmp(key)) { result.setBit(key); }}, begin_id);
+ result.foreach_falsebit([&](uint32_t key) { if ( sc.matches(key)) { result.setBit(key); }}, begin_id);
result.invalidateCachedCount();
}
@@ -33,7 +33,7 @@ std::unique_ptr<BitVector>
AttributeIteratorBase::get_hits(const SC & sc, uint32_t begin_id) const {
BitVector::UP result = BitVector::create(begin_id, getEndId());
for (uint32_t docId(std::max(begin_id, getDocId())); docId < getEndId(); docId++) {
- if (sc.cmp(docId)) {
+ if (sc.matches(docId)) {
result->setBit(docId);
}
}
@@ -338,7 +338,7 @@ AttributeIteratorT<SC>::doSeek(uint32_t docId)
{
if (isAtEnd(docId)) {
setAtEnd();
- } else if (_searchContext.cmp(docId, _weight)) {
+ } else if (_searchContext.matches(docId, _weight)) {
setDocId(docId);
}
}
@@ -349,7 +349,7 @@ FilterAttributeIteratorT<SC>::doSeek(uint32_t docId)
{
if (isAtEnd(docId)) {
setAtEnd();
- } else if (_searchContext.cmp(docId)) {
+ } else if (_searchContext.matches(docId)) {
setDocId(docId);
}
}
@@ -359,7 +359,7 @@ void
AttributeIteratorStrict<SC>::doSeek(uint32_t docId)
{
for (uint32_t nextId = docId; !isAtEnd(nextId); ++nextId) {
- if (_searchContext.cmp(nextId, _weight)) {
+ if (_searchContext.matches(nextId, _weight)) {
setDocId(nextId);
return;
}
@@ -372,7 +372,7 @@ void
FilterAttributeIteratorStrict<SC>::doSeek(uint32_t docId)
{
for (uint32_t nextId = docId; !isAtEnd(nextId); ++nextId) {
- if (_searchContext.cmp(nextId)) {
+ if (_searchContext.matches(nextId)) {
setDocId(nextId);
return;
}
diff --git a/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp b/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp
index bfcd7f29f29..c480eec5e88 100644
--- a/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp
@@ -44,8 +44,7 @@ ImportedSearchContext::ImportedSearchContext(
}
-ImportedSearchContext::~ImportedSearchContext() {
-}
+ImportedSearchContext::~ImportedSearchContext() = default;
unsigned int ImportedSearchContext::approximateHits() const {
return _reference_attribute.getNumDocs();
diff --git a/searchlib/src/vespa/searchlib/attribute/imported_search_context.h b/searchlib/src/vespa/searchlib/attribute/imported_search_context.h
index f8b434d4c6c..9573139b91a 100644
--- a/searchlib/src/vespa/searchlib/attribute/imported_search_context.h
+++ b/searchlib/src/vespa/searchlib/attribute/imported_search_context.h
@@ -50,7 +50,7 @@ public:
const SearchContextParams& params,
const ImportedAttributeVector& imported_attribute,
const attribute::IAttributeVector &target_attribute);
- ~ImportedSearchContext();
+ ~ImportedSearchContext() override;
std::unique_ptr<queryeval::SearchIterator>
@@ -64,16 +64,16 @@ public:
using DocId = IAttributeVector::DocId;
- bool cmp(DocId docId, int32_t& weight) const {
- return _target_search_context->cmp(getTargetLid(docId), weight);
+ int32_t find(DocId docId, int32_t elemId, int32_t& weight) const {
+ return _target_search_context->find(getTargetLid(docId), elemId, weight);
}
- bool cmp(DocId docId) const {
- return _target_search_context->cmp(getTargetLid(docId));
+ int32_t find(DocId docId, int32_t elemId) const {
+ return _target_search_context->find(getTargetLid(docId), elemId);
}
- bool onCmp(uint32_t docId, int32_t &weight) const override { return cmp(docId, weight); }
- bool onCmp(uint32_t docId) const override { return cmp(docId); }
+ int32_t onCmp(uint32_t docId, int32_t elemId, int32_t &weight) const override { return find(docId, elemId, weight); }
+ int32_t onCmp(uint32_t docId, int32_t elemId) const override { return find(docId, elemId); }
const ReferenceAttribute& attribute() const noexcept { return _reference_attribute; }
diff --git a/searchlib/src/vespa/searchlib/attribute/multinumericattribute.h b/searchlib/src/vespa/searchlib/attribute/multinumericattribute.h
index 1e02e4d39b0..a03bc74a44a 100644
--- a/searchlib/src/vespa/searchlib/attribute/multinumericattribute.h
+++ b/searchlib/src/vespa/searchlib/attribute/multinumericattribute.h
@@ -71,12 +71,12 @@ public:
private:
const MultiValueNumericAttribute<B, M> & _toBeSearched;
- bool onCmp(DocId docId, int32_t & weight) const override {
- return cmp(docId, weight);
+ int32_t onCmp(DocId docId, int32_t elemId, int32_t & weight) const override {
+ return find(docId, elemId, weight);
}
- bool onCmp(DocId docId) const override {
- return cmp(docId);
+ int32_t onCmp(DocId docId, int32_t elemId) const override {
+ return find(docId, elemId);
}
bool valid() const override;
@@ -86,25 +86,25 @@ public:
Int64Range getAsIntegerTerm() const override;
- bool cmp(DocId doc, int32_t & weight) const {
+ int32_t find(DocId doc, int32_t elemId, int32_t & weight) const {
MultiValueArrayRef values(_toBeSearched._mvMapping.get(doc));
- for (const MultiValueType &mv : values) {
- if (this->match(mv.value())) {
- weight = mv.weight();
- return true;
+ for (uint32_t i(elemId); i < values.size(); i++) {
+ if (this->match(values[i].value())) {
+ weight = values[i].weight();
+ return i;
}
}
- return false;
+ return -1;
}
- bool cmp(DocId doc) const {
+ int32_t find(DocId doc, int32_t elemId) const {
MultiValueArrayRef values(_toBeSearched._mvMapping.get(doc));
- for (const MultiValueType &mv : values) {
- if (this->match(mv.value())) {
- return true;
+ for (uint32_t i(elemId); i < values.size(); i++) {
+ if (this->match(values[i].value())) {
+ return i;
}
}
- return false;
+ return -1;
}
std::unique_ptr<queryeval::SearchIterator>
@@ -119,12 +119,12 @@ public:
private:
const MultiValueNumericAttribute<B, M> & _toBeSearched;
- bool onCmp(DocId docId, int32_t & weight) const override {
- return cmp(docId, weight);
+ int32_t onCmp(DocId docId, int32_t elemId, int32_t & weight) const override {
+ return find(docId, elemId, weight);
}
- bool onCmp(DocId docId) const override {
- return cmp(docId);
+ int32_t onCmp(DocId docId, int32_t elemId) const override {
+ return find(docId, elemId);
}
protected:
@@ -132,27 +132,31 @@ public:
public:
ArraySearchContext(std::unique_ptr<QueryTermSimple> qTerm, const NumericAttribute & toBeSearched);
- bool cmp(DocId doc, int32_t & weight) const {
+ int32_t find(DocId doc, int32_t elemId, int32_t & weight) const {
uint32_t hitCount = 0;
MultiValueArrayRef values(_toBeSearched._mvMapping.get(doc));
- for (const MultiValueType &mv : values) {
- if (this->match(mv.value())) {
+ int32_t firstMatch = -1;
+ for (uint32_t i(elemId); i < values.size(); i++) {
+ if (this->match(values[i].value())) {
+ if (firstMatch == -1) {
+ firstMatch = i;
+ }
hitCount++;
}
}
weight = hitCount;
- return hitCount != 0;
+ return firstMatch;
}
- bool cmp(DocId doc) const {
+ int32_t find(DocId doc, int32_t elemId) const {
MultiValueArrayRef values(_toBeSearched._mvMapping.get(doc));
- for (const MultiValueType &mv : values) {
- if (this->match(mv.value())) {
- return true;
+ for (uint32_t i(elemId); i < values.size(); i++) {
+ if (this->match(values[i].value())) {
+ return i;
}
}
- return false;
+ return -1;
}
Int64Range getAsIntegerTerm() const override;
diff --git a/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.h b/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.h
index 66dbbfeb1da..35a81dafb51 100644
--- a/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.h
+++ b/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.h
@@ -52,12 +52,12 @@ protected:
protected:
const MultiValueNumericEnumAttribute<B, M> & _toBeSearched;
- bool onCmp(DocId docId, int32_t & weight) const override {
- return cmp(docId, weight);
+ int32_t onCmp(DocId docId, int32_t elemId, int32_t & weight) const override {
+ return find(docId, elemId, weight);
}
- bool onCmp(DocId docId) const override {
- return cmp(docId);
+ int32_t onCmp(DocId docId, int32_t elemId) const override {
+ return find(docId, elemId);
}
bool valid() const override { return this->isValid(); }
@@ -65,31 +65,31 @@ protected:
public:
SetSearchContext(QueryTermSimpleUP qTerm, const NumericAttribute & toBeSearched);
- bool
- cmp(DocId doc, int32_t & weight) const
+ int32_t
+ find(DocId doc, int32_t elemId, int32_t & weight) const
{
WeightedIndexArrayRef indices(_toBeSearched._mvMapping.get(doc));
- for (const WeightedIndex &wi : indices) {
- T v = _toBeSearched._enumStore.getValue(wi.value());
+ for (uint32_t i(elemId); i < indices.size(); i++) {
+ T v = _toBeSearched._enumStore.getValue(indices[i].value());
if (this->match(v)) {
- weight = wi.weight();
- return true;
+ weight = indices[i].weight();
+ return elemId;
}
}
- return false;
+ return -1;
}
- bool
- cmp(DocId doc) const
+ int32_t
+ find(DocId doc, int32_t elemId) const
{
WeightedIndexArrayRef indices(_toBeSearched._mvMapping.get(doc));
- for (const WeightedIndex &wi : indices) {
- T v = _toBeSearched._enumStore.getValue(wi.value());
+ for (uint32_t i(elemId); i < indices.size(); i++) {
+ T v = _toBeSearched._enumStore.getValue(indices[i].value());
if (this->match(v)) {
- return true;
+ return i;
}
}
- return false;
+ return -1;
}
Int64Range getAsIntegerTerm() const override;
@@ -105,12 +105,12 @@ protected:
protected:
const MultiValueNumericEnumAttribute<B, M> & _toBeSearched;
- bool onCmp(DocId docId, int32_t & weight) const override {
- return cmp(docId, weight);
+ int32_t onCmp(DocId docId, int32_t elemId, int32_t & weight) const override {
+ return find(docId, elemId, weight);
}
- bool onCmp(DocId docId) const override {
- return cmp(docId);
+ int32_t onCmp(DocId docId, int32_t elemId) const override {
+ return find(docId, elemId);
}
bool valid() const override { return this->isValid(); }
@@ -119,34 +119,38 @@ protected:
ArraySearchContext(QueryTermSimpleUP qTerm, const NumericAttribute & toBeSearched);
Int64Range getAsIntegerTerm() const override;
- bool
- cmp(DocId doc, int32_t & weight) const
+ int32_t
+ find(DocId doc, int32_t elemId, int32_t & weight) const
{
uint32_t hitCount = 0;
WeightedIndexArrayRef indices(_toBeSearched._mvMapping.get(doc));
- for (const WeightedIndex &wi : indices) {
- T v = _toBeSearched._enumStore.getValue(wi.value());
+ int32_t firstMatch = -1;
+ for (uint32_t i(elemId); i < indices.size(); i++) {
+ T v = _toBeSearched._enumStore.getValue(indices[i].value());
if (this->match(v)) {
+ if (firstMatch == -1) {
+ firstMatch = i;
+ }
hitCount++;
}
}
weight = hitCount;
- return hitCount != 0;
+ return firstMatch;
}
bool
- cmp(DocId doc) const
+ find(DocId doc, int32_t elemId) const
{
WeightedIndexArrayRef indices(_toBeSearched._mvMapping.get(doc));
- for (const WeightedIndex &wi : indices) {
- T v = _toBeSearched._enumStore.getValue(wi.value());
+ for (uint32_t i(elemId); i < indices.size(); i++) {
+ T v = _toBeSearched._enumStore.getValue(indices[i].value());
if (this->match(v)) {
- return true;
+ return i;
}
}
- return false;
+ return -1;
}
std::unique_ptr<queryeval::SearchIterator>
diff --git a/searchlib/src/vespa/searchlib/attribute/multistringattribute.h b/searchlib/src/vespa/searchlib/attribute/multistringattribute.h
index 7edbcedcb2e..a03a2a02287 100644
--- a/searchlib/src/vespa/searchlib/attribute/multistringattribute.h
+++ b/searchlib/src/vespa/searchlib/attribute/multistringattribute.h
@@ -119,10 +119,10 @@ public:
const MultiValueStringAttributeT<B, M> & myAttribute() const {
return static_cast< const MultiValueStringAttributeT<B, M> & > (attribute());
}
- bool onCmp(DocId docId) const override;
+ int32_t onCmp(DocId docId, int32_t elemId) const override;
template <typename Collector>
- bool collectWeight(DocId doc, int32_t & weight, Collector & collector) const;
+ int32_t collectWeight(DocId doc, int32_t elemId, int32_t & weight, Collector & collector) const;
};
/*
@@ -134,7 +134,7 @@ public:
StringImplSearchContext(std::move(qTerm), toBeSearched)
{ }
protected:
- bool onCmp(DocId docId, int32_t & weight) const override;
+ int32_t onCmp(DocId docId, int32_t elemId, int32_t & weight) const override;
};
/*
@@ -146,7 +146,7 @@ public:
StringImplSearchContext(std::move(qTerm), toBeSearched)
{ }
protected:
- bool onCmp(DocId docId, int32_t & weight) const override;
+ int32_t onCmp(DocId docId, int32_t elemId, int32_t & weight) const override;
};
template <typename BT>
diff --git a/searchlib/src/vespa/searchlib/attribute/multistringattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multistringattribute.hpp
index a68ac218784..20b9d2ed60b 100644
--- a/searchlib/src/vespa/searchlib/attribute/multistringattribute.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/multistringattribute.hpp
@@ -62,47 +62,47 @@ private:
}
template <typename B, typename M>
-bool
-MultiValueStringAttributeT<B, M>::StringSetImplSearchContext::onCmp(DocId doc, int32_t & weight) const
+int32_t
+MultiValueStringAttributeT<B, M>::StringSetImplSearchContext::onCmp(DocId doc, int32_t elemId, int32_t & weight) const
{
StringAttribute::StringSearchContext::CollectWeight collector;
- return this->collectWeight(doc, weight, collector);
+ return this->collectWeight(doc, elemId, weight, collector);
}
template <typename B, typename M>
-bool
-MultiValueStringAttributeT<B, M>::StringArrayImplSearchContext::onCmp(DocId doc, int32_t & weight) const
+int32_t
+MultiValueStringAttributeT<B, M>::StringArrayImplSearchContext::onCmp(DocId doc, int32_t elemId, int32_t & weight) const
{
StringAttribute::StringSearchContext::CollectHitCount collector;
- return this->collectWeight(doc, weight, collector);
+ return this->collectWeight(doc, elemId, weight, collector);
}
template <typename B, typename M>
template <typename Collector>
-bool
-MultiValueStringAttributeT<B, M>::StringImplSearchContext::collectWeight(DocId doc, int32_t & weight, Collector & collector) const
+int32_t
+MultiValueStringAttributeT<B, M>::StringImplSearchContext::collectWeight(DocId doc, int32_t elemId, int32_t & weight, Collector & collector) const
{
WeightedIndexArrayRef indices(myAttribute()._mvMapping.get(doc));
EnumAccessor<typename B::EnumStore> accessor(myAttribute()._enumStore);
- collectMatches(indices, accessor, collector);
+ int32_t foundElem = collectMatches(indices, elemId, accessor, collector);
weight = collector.getWeight();
- return collector.hasMatch();
+ return foundElem;
}
template <typename B, typename M>
-bool
-MultiValueStringAttributeT<B, M>::StringImplSearchContext::onCmp(DocId doc) const
+int32_t
+MultiValueStringAttributeT<B, M>::StringImplSearchContext::onCmp(DocId doc, int32_t elemId) const
{
const MultiValueStringAttributeT<B, M> & attr(static_cast< const MultiValueStringAttributeT<B, M> & > (attribute()));
WeightedIndexArrayRef indices(attr._mvMapping.get(doc));
- for (const WeightedIndex &wi : indices) {
- if (isMatch(attr._enumStore.getValue(wi.value()))) {
- return true;
+ for (uint32_t i(elemId); i < indices.size(); i++) {
+ if (isMatch(attr._enumStore.getValue(indices[i].value()))) {
+ return i;
}
}
- return false;
+ return -1;
}
template <typename B, typename M>
diff --git a/searchlib/src/vespa/searchlib/attribute/singlenumericattribute.h b/searchlib/src/vespa/searchlib/attribute/singlenumericattribute.h
index 8edbf6cde59..de149564f21 100644
--- a/searchlib/src/vespa/searchlib/attribute/singlenumericattribute.h
+++ b/searchlib/src/vespa/searchlib/attribute/singlenumericattribute.h
@@ -41,27 +41,29 @@ private:
private:
const T * _data;
- bool onCmp(DocId docId, int32_t & weight) const override {
- return cmp(docId, weight);
+ int32_t onCmp(DocId docId, int32_t elemId, int32_t & weight) const override {
+ return find(docId, elemId, weight);
}
- bool onCmp(DocId docId) const override {
- return cmp(docId);
+ int32_t onCmp(DocId docId, int elemId) const override {
+ return find(docId, elemId);
}
bool valid() const override;
public:
SingleSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const NumericAttribute & toBeSearched);
- bool cmp(DocId docId, int32_t & weight) const {
+ int32_t find(DocId docId, int32_t elemId, int32_t & weight) const {
+ if ( elemId != 0) return -1;
const T v = _data[docId];
weight = 1;
- return this->match(v);
+ return this->match(v) ? 0 : -1;
}
- bool cmp(DocId docId) const {
+ int32_t find(DocId docId, int elemId) const {
+ if ( elemId != 0) return -1;
const T v = _data[docId];
- return this->match(v);
+ return this->match(v) ? 0 : -1;
}
Int64Range getAsIntegerTerm() const override;
diff --git a/searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.h b/searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.h
index 7dca10e83e4..f10a6f0f35a 100644
--- a/searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.h
+++ b/searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.h
@@ -58,12 +58,12 @@ protected:
protected:
const SingleValueNumericEnumAttribute<B> & _toBeSearched;
- bool onCmp(DocId docId, int32_t & weight) const override {
- return cmp(docId, weight);
+ int32_t onCmp(DocId docId, int32_t elemId, int32_t & weight) const override {
+ return find(docId, elemId, weight);
}
- bool onCmp(DocId docId) const override {
- return cmp(docId);
+ int32_t onCmp(DocId docId, int32_t elemId) const override {
+ return find(docId, elemId);
}
bool valid() const override;
@@ -72,15 +72,17 @@ protected:
Int64Range getAsIntegerTerm() const override;
- bool cmp(DocId docId, int32_t & weight) const {
+ int32_t find(DocId docId, int32_t elemId, int32_t & weight) const {
+ if ( elemId != 0) return -1;
T v = _toBeSearched._enumStore.getValue(_toBeSearched.getEnumIndex(docId));
weight = 1;
- return this->match(v);
+ return this->match(v) ? 0 : -1;
}
- bool cmp(DocId docId) const {
+ int32_t find(DocId docId, int32_t elemId) const {
+ if ( elemId != 0) return -1;
T v = _toBeSearched._enumStore.getValue(_toBeSearched.getEnumIndex(docId));
- return this->match(v);
+ return this->match(v) ? 0 : -1;
}
std::unique_ptr<queryeval::SearchIterator>
diff --git a/searchlib/src/vespa/searchlib/attribute/singlesmallnumericattribute.h b/searchlib/src/vespa/searchlib/attribute/singlesmallnumericattribute.h
index 9320e248160..2087f74d104 100644
--- a/searchlib/src/vespa/searchlib/attribute/singlesmallnumericattribute.h
+++ b/searchlib/src/vespa/searchlib/attribute/singlesmallnumericattribute.h
@@ -67,12 +67,12 @@ public:
uint32_t _valueShiftMask;
uint32_t _wordShift;
- bool onCmp(DocId docId, int32_t & weight) const override {
- return cmp(docId, weight);
+ int32_t onCmp(DocId docId, int32_t elementId, int32_t & weight) const override {
+ return cmp(docId, elementId, weight);
}
- bool onCmp(DocId docId) const override {
- return cmp(docId);
+ int32_t onCmp(DocId docId, int32_t elementId) const override {
+ return cmp(docId, elementId);
}
bool valid() const override;
@@ -80,19 +80,21 @@ public:
public:
SingleSearchContext(std::unique_ptr<QueryTermSimple> qTerm, const NumericAttribute & toBeSearched);
- bool cmp(DocId docId, int32_t & weight) const {
+ int32_t cmp(DocId docId, int32_t elemId, int32_t & weight) const {
+ if ( elemId != 0) return -1;
const Word &word = _wordData[docId >> _wordShift];
uint32_t valueShift = (docId & _valueShiftMask) << _valueShiftShift;
T v = (word >> valueShift) & _valueMask;
weight = 1;
- return match(v);
+ return match(v) ? 0 : -1;
}
- bool cmp(DocId docId) const {
+ int32_t cmp(DocId docId, int32_t elemId) const {
+ if ( elemId != 0) return -1;
const Word &word = _wordData[docId >> _wordShift];
uint32_t valueShift = (docId & _valueShiftMask) << _valueShiftShift;
T v = (word >> valueShift) & _valueMask;
- return match(v);
+ return match(v) ? 0 : -1;
}
Int64Range getAsIntegerTerm() const override;
@@ -101,14 +103,10 @@ public:
createFilterIterator(fef::TermFieldMatchData * matchData, bool strict) override;
};
- SingleValueSmallNumericAttribute(const vespalib::string & baseFileName,
- const Config &c,
- Word valueMask,
- uint32_t valueShiftShift,
- uint32_t valueShiftMask,
- uint32_t wordShift);
+ SingleValueSmallNumericAttribute(const vespalib::string & baseFileName, const Config &c, Word valueMask,
+ uint32_t valueShiftShift, uint32_t valueShiftMask, uint32_t wordShift);
- ~SingleValueSmallNumericAttribute();
+ ~SingleValueSmallNumericAttribute() override;
uint32_t getValueCount(DocId doc) const override {
if (doc >= B::getNumDocs()) {
@@ -125,7 +123,8 @@ public:
bool onLoad() override;
void onSave(IAttributeSaveTarget &saveTarget) override;
- SearchContext::UP getSearch(std::unique_ptr<QueryTermSimple> term, const attribute::SearchContextParams & params) const override;
+ SearchContext::UP
+ getSearch(std::unique_ptr<QueryTermSimple> term, const attribute::SearchContextParams & params) const override;
T getFast(DocId doc) const {
const Word &word = _wordData[doc >> _wordShift];
diff --git a/searchlib/src/vespa/searchlib/attribute/singlestringattribute.h b/searchlib/src/vespa/searchlib/attribute/singlestringattribute.h
index 227c1d0667c..8d9fd79717c 100644
--- a/searchlib/src/vespa/searchlib/attribute/singlestringattribute.h
+++ b/searchlib/src/vespa/searchlib/attribute/singlestringattribute.h
@@ -89,14 +89,15 @@ public:
StringSearchContext(std::move(qTerm), toBeSearched)
{ }
protected:
- bool onCmp(DocId doc, int32_t & weight) const override {
+ int32_t onCmp(DocId doc, int32_t elemId, int32_t & weight) const override {
weight = 1;
- return onCmp(doc);
+ return onCmp(doc, elemId);
}
- bool onCmp(DocId doc) const override {
+ int32_t onCmp(DocId doc, int32_t elemId) const override {
+ if ( elemId != 0) return -1;
const SingleValueStringAttributeT<B> & attr(static_cast<const SingleValueStringAttributeT<B> &>(attribute()));
- return isMatch(attr._enumStore.getValue(attr._enumIndices[doc]));
+ return isMatch(attr._enumStore.getValue(attr._enumIndices[doc])) ? 0 : -1;
}
};
diff --git a/searchlib/src/vespa/searchlib/attribute/stringbase.cpp b/searchlib/src/vespa/searchlib/attribute/stringbase.cpp
index 5ba936b5f52..3e31c9ca2fa 100644
--- a/searchlib/src/vespa/searchlib/attribute/stringbase.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/stringbase.cpp
@@ -273,31 +273,31 @@ public:
}
-bool
-StringAttribute::StringSearchContext::onCmp(DocId docId, int32_t & weight) const
+int32_t
+StringAttribute::StringSearchContext::onCmp(DocId docId, int32_t elemId, int32_t & weight) const
{
WeightedConstChar * buffer = getBuffer();
uint32_t valueCount = attribute().get(docId, buffer, _bufferLen);
CollectWeight collector;
DirectAccessor accessor;
- collectMatches(vespalib::ConstArrayRef<WeightedConstChar>(buffer, std::min(valueCount, _bufferLen)), accessor, collector);
+ int32_t foundElem = collectMatches(vespalib::ConstArrayRef<WeightedConstChar>(buffer, std::min(valueCount, _bufferLen)), elemId, accessor, collector);
weight = collector.getWeight();
- return collector.hasMatch();
+ return foundElem;
}
-bool
-StringAttribute::StringSearchContext::onCmp(DocId docId) const
+int32_t
+StringAttribute::StringSearchContext::onCmp(DocId docId, int32_t elemId) const
{
WeightedConstChar * buffer = getBuffer();
uint32_t valueCount = attribute().get(docId, buffer, _bufferLen);
- for (uint32_t i = 0, m = std::min(valueCount, _bufferLen); (i < m); i++) {
+ for (uint32_t i = elemId, m = std::min(valueCount, _bufferLen); (i < m); i++) {
if (isMatch(buffer[i].getValue())) {
- return true;
+ return i;
}
}
- return false;
+ return -1;
}
bool StringAttribute::applyWeight(DocId doc, const FieldValue & fv, const ArithmeticValueUpdate & wAdjust)
diff --git a/searchlib/src/vespa/searchlib/attribute/stringbase.h b/searchlib/src/vespa/searchlib/attribute/stringbase.h
index 5e0847f3039..4176d172ab0 100644
--- a/searchlib/src/vespa/searchlib/attribute/stringbase.h
+++ b/searchlib/src/vespa/searchlib/attribute/stringbase.h
@@ -96,7 +96,7 @@ private:
class StringSearchContext : public SearchContext {
public:
StringSearchContext(QueryTermSimpleUP qTerm, const StringAttribute & toBeSearched);
- virtual ~StringSearchContext();
+ ~StringSearchContext() override;
private:
bool _isPrefix;
bool _isRegex;
@@ -147,17 +147,22 @@ private:
};
template<typename WeightedT, typename Accessor, typename Collector>
- void collectMatches(vespalib::ConstArrayRef<WeightedT> w, const Accessor & ac, Collector & collector) const {
- for (const WeightedT &wRef : w) {
- if (isMatch(ac.get(wRef.value()))) {
- collector.addWeight(wRef.weight());
+ int32_t collectMatches(vespalib::ConstArrayRef<WeightedT> w, int32_t elemId, const Accessor & ac, Collector & collector) const {
+ int firstMatch = -1;
+ for (uint32_t i(elemId); i < w.size(); i++) {
+ if (isMatch(ac.get(w[i].value()))) {
+ collector.addWeight(w[i].weight());
+ if (firstMatch == -1) {
+ firstMatch = i;
+ }
}
}
+ return firstMatch;
}
- bool onCmp(DocId docId, int32_t & weight) const override;
- bool onCmp(DocId docId) const override;
+ int32_t onCmp(DocId docId, int32_t elementId, int32_t & weight) const override;
+ int32_t onCmp(DocId docId, int32_t elementId) const override;
bool isPrefix() const { return _isPrefix; }
bool isRegex() const { return _isRegex; }
@@ -166,7 +171,7 @@ private:
const vespalib::Regexp * getRegex() const { return _regex.get(); }
private:
WeightedConstChar * getBuffer() const {
- if (_buffer == NULL) {
+ if (_buffer == nullptr) {
_buffer = new WeightedConstChar[_bufferLen];
}
return _buffer;