From 0f20fa13a7ca5e070f1bb40bfe659ed9134a397c Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Mon, 2 Oct 2023 21:32:20 +0000 Subject: Refactor test --- .../multibitvectoriterator_test.cpp | 217 +++++++++------------ 1 file changed, 90 insertions(+), 127 deletions(-) diff --git a/searchlib/src/tests/queryeval/multibitvectoriterator/multibitvectoriterator_test.cpp b/searchlib/src/tests/queryeval/multibitvectoriterator/multibitvectoriterator_test.cpp index d0ccbaeb180..9cb7e1def1c 100644 --- a/searchlib/src/tests/queryeval/multibitvectoriterator/multibitvectoriterator_test.cpp +++ b/searchlib/src/tests/queryeval/multibitvectoriterator/multibitvectoriterator_test.cpp @@ -20,35 +20,20 @@ using namespace search::fef; using namespace search; using vespalib::Trinary; -//----------------------------------------------------------------------------- - -class Test : public vespalib::TestApp -{ -public: - Test(); - ~Test(); - void testAndNot(); - void testAnd(); - void testBug7163266(); - void testOr(); +struct Fixture { + Fixture(); void testAndWith(bool invert); void testEndGuard(bool invert); - void testIteratorConformance(); - void testUnpackOfOr(); - template - void testThatOptimizePreservesUnpack(); + void verifyUnpackOfOr(const UnpackInfo & unpackInfo); template void testOptimizeCommon(bool isAnd, bool invert); template - void testOptimizeAndOr(bool invert); - template void testSearch(bool strict, bool invert); - int Main() override; -private: - void verifyUnpackOfOr(const UnpackInfo & unpackInfo); - void verifySelectiveUnpack(SearchIterator & s, const TermFieldMatchData * tfmd); - void searchAndCompare(SearchIterator::UP s, uint32_t docIdLimit); - void setup(); + template + void testOptimizeAndOr(bool invert); + template + void testThatOptimizePreservesUnpack(); + SearchIterator::UP createIter(size_t index, bool inverted, TermFieldMatchData & tfmd, bool strict) { return BitVectorIterator::create(getBV(index, inverted), tfmd, strict, inverted); } @@ -69,10 +54,9 @@ private: std::vector< BitVector::UP > _bvs_inverted; }; -Test::Test() = default; -Test::~Test() = default; - -void Test::setup() +Fixture::Fixture() + : _bvs(), + _bvs_inverted() { std::minstd_rand rnd(341); for(size_t i(0); i < 3; i++) { @@ -120,7 +104,7 @@ seek(SearchIterator & s, uint32_t docIdLimit) } void -Test::testAndWith(bool invert) +Fixture::testAndWith(bool invert) { TermFieldMatchData tfmd; { @@ -156,54 +140,55 @@ Test::testAndWith(bool invert) } } -void -Test::testAndNot() +TEST_F("testAndNot", Fixture) { for (bool invert : {false, true}) { - testOptimizeCommon(false, invert); - testSearch(false, invert); - testSearch(true, invert); + f.template testOptimizeCommon(false, invert); + f.template testSearch(false, invert); + f.template testSearch(true, invert); } } -void -Test::testAnd() +TEST_F("testAnd", Fixture) { for (bool invert : {false, true}) { - testOptimizeCommon(true, invert); - testOptimizeAndOr(invert); - testSearch(false, invert); - testSearch(true, invert); + f.template testOptimizeCommon(true, invert); + f.template testOptimizeAndOr(invert); + f.template testSearch(false, invert); + f.template testSearch(true, invert); } } -void -Test::testOr() +TEST_F("testOr", Fixture) { for (bool invert : {false, true}) { - testOptimizeCommon< OrSearch >(false, invert); - testOptimizeAndOr< OrSearch >(invert); - testSearch(false, invert); - testSearch(true, invert); + f.template testOptimizeCommon< OrSearch >(false, invert); + f.template testOptimizeAndOr< OrSearch >(invert); + f.template testSearch(false, invert); + f.template testSearch(true, invert); } } -void -Test::testBug7163266() +TEST_F("testAndWith", Fixture) { + f.testAndWith(false); + f.testAndWith(true); +} + +TEST_F("testBug7163266", Fixture) { TermFieldMatchData tfmd[30]; - _bvs[0]->setBit(1); - _bvs[1]->setBit(1); + f._bvs[0]->setBit(1); + f._bvs[1]->setBit(1); MultiSearch::Children children; UnpackInfo unpackInfo; for (size_t i(0); i < 28; i++) { children.emplace_back(new TrueSearch(tfmd[2])); unpackInfo.add(i); } - children.push_back(createIter(0, false, tfmd[0], false)); - children.push_back(createIter(1, false, tfmd[1], false)); + children.push_back(f.createIter(0, false, tfmd[0], false)); + children.push_back(f.createIter(1, false, tfmd[1], false)); SearchIterator::UP s = AndSearch::create(std::move(children), false, unpackInfo); - const MultiSearch * ms = dynamic_cast(s.get()); + const auto * ms = dynamic_cast(s.get()); EXPECT_TRUE(ms != nullptr); EXPECT_EQUAL(30u, ms->getChildren().size()); EXPECT_EQUAL("search::queryeval::AndSearchNoStrict", s->getClassName()); @@ -221,12 +206,26 @@ Test::testBug7163266() EXPECT_TRUE(ms->needUnpack(i)); } EXPECT_TRUE(ms->needUnpack(28)); // NB: force unpack all - fixup_bitvectors(); +} + +void +verifySelectiveUnpack(SearchIterator & s, const TermFieldMatchData * tfmd) +{ + s.seek(1); + EXPECT_EQUAL(0u, tfmd[0].getDocId()); + EXPECT_EQUAL(0u, tfmd[1].getDocId()); + EXPECT_EQUAL(0u, tfmd[2].getDocId()); + EXPECT_EQUAL(0u, tfmd[3].getDocId()); + s.unpack(1); + EXPECT_EQUAL(0u, tfmd[0].getDocId()); + EXPECT_EQUAL(1u, tfmd[1].getDocId()); + EXPECT_EQUAL(1u, tfmd[2].getDocId()); + EXPECT_EQUAL(0u, tfmd[3].getDocId()); } template void -Test::testThatOptimizePreservesUnpack() +Fixture::testThatOptimizePreservesUnpack() { TermFieldMatchData tfmd[4]; _bvs[0]->setBit(1); @@ -242,7 +241,7 @@ Test::testThatOptimizePreservesUnpack() unpackInfo.add(2); SearchIterator::UP s = T::create(std::move(children), false, unpackInfo); s->initFullRange(); - const MultiSearch * ms = dynamic_cast(s.get()); + const auto * ms = dynamic_cast(s.get()); EXPECT_TRUE(ms != nullptr); EXPECT_EQUAL(4u, ms->getChildren().size()); verifySelectiveUnpack(*s, tfmd); @@ -269,25 +268,22 @@ void verifyOrUnpack(SearchIterator & s, TermFieldMatchData tfmd[3]) { EXPECT_EQUAL(0u, tfmd[2].getDocId()); } -void -Test::testUnpackOfOr() { - _bvs[0]->clearBit(1); - _bvs[1]->setBit(1); - _bvs[2]->clearBit(1); +TEST_F("testUnpackOfOr", Fixture) { + f._bvs[0]->clearBit(1); + f._bvs[1]->setBit(1); + f._bvs[2]->clearBit(1); UnpackInfo all; all.forceAll(); - verifyUnpackOfOr(all); + f.verifyUnpackOfOr(all); UnpackInfo unpackInfo; unpackInfo.add(1); unpackInfo.add(2); - verifyUnpackOfOr(unpackInfo); - - fixup_bitvectors(); + f.verifyUnpackOfOr(unpackInfo); } void -Test::verifyUnpackOfOr(const UnpackInfo &unpackInfo) +Fixture::verifyUnpackOfOr(const UnpackInfo &unpackInfo) { TermFieldMatchData tfmdA[3]; MultiSearch::Children children; @@ -301,7 +297,7 @@ Test::verifyUnpackOfOr(const UnpackInfo &unpackInfo) tfmd.resetOnlyDocId(0); } - const MultiSearch * ms = dynamic_cast(s.get()); + const auto * ms = dynamic_cast(s.get()); EXPECT_TRUE(ms != nullptr); EXPECT_EQUAL(3u, ms->getChildren().size()); @@ -315,22 +311,7 @@ Test::verifyUnpackOfOr(const UnpackInfo &unpackInfo) } void -Test::verifySelectiveUnpack(SearchIterator & s, const TermFieldMatchData * tfmd) -{ - s.seek(1); - EXPECT_EQUAL(0u, tfmd[0].getDocId()); - EXPECT_EQUAL(0u, tfmd[1].getDocId()); - EXPECT_EQUAL(0u, tfmd[2].getDocId()); - EXPECT_EQUAL(0u, tfmd[3].getDocId()); - s.unpack(1); - EXPECT_EQUAL(0u, tfmd[0].getDocId()); - EXPECT_EQUAL(1u, tfmd[1].getDocId()); - EXPECT_EQUAL(1u, tfmd[2].getDocId()); - EXPECT_EQUAL(0u, tfmd[3].getDocId()); -} - -void -Test::searchAndCompare(SearchIterator::UP s, uint32_t docIdLimit) +searchAndCompare(SearchIterator::UP s, uint32_t docIdLimit) { H a = seek(*s, docIdLimit); SearchIterator * p = s.get(); @@ -347,7 +328,7 @@ Test::searchAndCompare(SearchIterator::UP s, uint32_t docIdLimit) template void -Test::testSearch(bool strict, bool invert) +Fixture::testSearch(bool strict, bool invert) { TermFieldMatchData tfmd; uint32_t docIdLimit(_bvs[0]->size()); @@ -376,7 +357,7 @@ Test::testSearch(bool strict, bool invert) template void -Test::testOptimizeCommon(bool isAnd, bool invert) +Fixture::testOptimizeCommon(bool isAnd, bool invert) { TermFieldMatchData tfmd; @@ -387,7 +368,7 @@ Test::testOptimizeCommon(bool isAnd, bool invert) SearchIterator::UP s = T::create(std::move(children), false); s = MultiBitVectorIteratorBase::optimize(std::move(s)); EXPECT_TRUE(dynamic_cast(s.get()) != nullptr); - const MultiSearch & m(dynamic_cast(*s)); + const auto & m(dynamic_cast(*s)); EXPECT_EQUAL(1u, m.getChildren().size()); EXPECT_TRUE(dynamic_cast(m.getChildren()[0].get()) != nullptr); } @@ -399,7 +380,7 @@ Test::testOptimizeCommon(bool isAnd, bool invert) SearchIterator::UP s = T::create(std::move(children), false); s = MultiBitVectorIteratorBase::optimize(std::move(s)); EXPECT_TRUE(dynamic_cast(s.get()) != nullptr); - const MultiSearch & m(dynamic_cast(*s)); + const auto & m(dynamic_cast(*s)); EXPECT_EQUAL(2u, m.getChildren().size()); EXPECT_TRUE(dynamic_cast(m.getChildren()[0].get()) != nullptr); EXPECT_TRUE(dynamic_cast(m.getChildren()[1].get()) != nullptr); @@ -412,7 +393,7 @@ Test::testOptimizeCommon(bool isAnd, bool invert) SearchIterator::UP s = T::create(std::move(children), false); s = MultiBitVectorIteratorBase::optimize(std::move(s)); EXPECT_TRUE(dynamic_cast(s.get()) != nullptr); - const MultiSearch & m(dynamic_cast(*s)); + const auto & m(dynamic_cast(*s)); EXPECT_EQUAL(2u, m.getChildren().size()); EXPECT_TRUE(dynamic_cast(m.getChildren()[0].get()) != nullptr); EXPECT_TRUE(dynamic_cast(m.getChildren()[1].get()) != nullptr); @@ -427,7 +408,7 @@ Test::testOptimizeCommon(bool isAnd, bool invert) s = MultiBitVectorIteratorBase::optimize(std::move(s)); EXPECT_TRUE(s); EXPECT_TRUE(dynamic_cast(s.get()) != nullptr); - const MultiSearch & m(dynamic_cast(*s)); + const auto & m(dynamic_cast(*s)); EXPECT_EQUAL(2u, m.getChildren().size()); EXPECT_TRUE(dynamic_cast(m.getChildren()[0].get()) != nullptr); EXPECT_TRUE(dynamic_cast(m.getChildren()[1].get()) != nullptr); @@ -443,7 +424,7 @@ Test::testOptimizeCommon(bool isAnd, bool invert) s = MultiBitVectorIteratorBase::optimize(std::move(s)); EXPECT_TRUE(s); EXPECT_TRUE(dynamic_cast(s.get()) != nullptr); - const MultiSearch & m(dynamic_cast(*s)); + const auto & m(dynamic_cast(*s)); EXPECT_EQUAL(2u, m.getChildren().size()); EXPECT_TRUE(dynamic_cast(m.getChildren()[0].get()) != nullptr); EXPECT_TRUE(dynamic_cast(m.getChildren()[1].get()) != nullptr); @@ -481,7 +462,7 @@ Test::testOptimizeCommon(bool isAnd, bool invert) template void -Test::testOptimizeAndOr(bool invert) +Fixture::testOptimizeAndOr(bool invert) { TermFieldMatchData tfmd; @@ -506,7 +487,7 @@ Test::testOptimizeAndOr(bool invert) s = MultiBitVectorIteratorBase::optimize(std::move(s)); EXPECT_TRUE(s); EXPECT_TRUE(dynamic_cast(s.get()) != nullptr); - const MultiSearch & m(dynamic_cast(*s)); + const auto & m(dynamic_cast(*s)); EXPECT_EQUAL(2u, m.getChildren().size()); EXPECT_TRUE(dynamic_cast(m.getChildren()[0].get()) != nullptr); EXPECT_TRUE(Trinary::False == m.getChildren()[0]->is_strict()); @@ -522,7 +503,7 @@ Test::testOptimizeAndOr(bool invert) s = MultiBitVectorIteratorBase::optimize(std::move(s)); EXPECT_TRUE(s); EXPECT_TRUE(dynamic_cast(s.get()) != nullptr); - const MultiSearch & m(dynamic_cast(*s)); + const auto & m(dynamic_cast(*s)); EXPECT_EQUAL(2u, m.getChildren().size()); EXPECT_TRUE(dynamic_cast(m.getChildren()[0].get()) != nullptr); EXPECT_TRUE(Trinary::False == m.getChildren()[0]->is_strict()); @@ -538,7 +519,7 @@ Test::testOptimizeAndOr(bool invert) s = MultiBitVectorIteratorBase::optimize(std::move(s)); EXPECT_TRUE(s); EXPECT_TRUE(dynamic_cast(s.get()) != nullptr); - const MultiSearch & m(dynamic_cast(*s)); + const auto & m(dynamic_cast(*s)); EXPECT_EQUAL(2u, m.getChildren().size()); EXPECT_TRUE(dynamic_cast(m.getChildren()[0].get()) != nullptr); EXPECT_TRUE(Trinary::True == m.getChildren()[0]->is_strict()); @@ -554,7 +535,7 @@ Test::testOptimizeAndOr(bool invert) s = MultiBitVectorIteratorBase::optimize(std::move(s)); EXPECT_TRUE(s); EXPECT_TRUE(dynamic_cast(s.get()) != nullptr); - const MultiSearch & m(dynamic_cast(*s)); + const auto & m(dynamic_cast(*s)); EXPECT_EQUAL(2u, m.getChildren().size()); EXPECT_TRUE(dynamic_cast(m.getChildren()[0].get()) != nullptr); EXPECT_TRUE(Trinary::True == m.getChildren()[0]->is_strict()); @@ -563,7 +544,7 @@ Test::testOptimizeAndOr(bool invert) } void -Test::testEndGuard(bool invert) +Fixture::testEndGuard(bool invert) { using T = AndSearch; TermFieldMatchData tfmd; @@ -576,16 +557,26 @@ Test::testEndGuard(bool invert) s->initFullRange(); EXPECT_TRUE(s); EXPECT_TRUE(dynamic_cast(s.get()) != nullptr); - MultiSearch & m(dynamic_cast(*s)); + auto & m(dynamic_cast(*s)); EXPECT_TRUE(m.seek(0) || !m.seek(0)); EXPECT_TRUE(m.seek(3) || !m.seek(3)); EXPECT_FALSE(m.seek(_bvs[0]->size()+987)); } +TEST_F("testEndGuard", Fixture) { + f.testEndGuard(false); + f.testEndGuard(true); +} + +TEST_F("testThatOptimizePreservesUnpack", Fixture) { + f.template testThatOptimizePreservesUnpack(); + f.template testThatOptimizePreservesUnpack(); +} + class Verifier : public search::test::SearchIteratorVerifier { public: Verifier(size_t numBv, bool is_and); - ~Verifier(); + ~Verifier() override; SearchIterator::UP create(bool strict) const override; @@ -627,7 +618,7 @@ Verifier::create(bool strict) const { return mbvit; } -void Test::testIteratorConformance() { +TEST("testIteratorConformance") { for (bool is_and : {false, true}) { for (size_t i(1); i < 6; i++) { Verifier searchIteratorVerifier(i, is_and); @@ -636,32 +627,4 @@ void Test::testIteratorConformance() { } } -int -Test::Main() -{ - TEST_INIT("multibitvectoriterator_test"); - setup(); - testBug7163266(); - testThatOptimizePreservesUnpack(); - testThatOptimizePreservesUnpack(); - TEST_FLUSH(); - testUnpackOfOr(); - TEST_FLUSH(); - testEndGuard(false); - testEndGuard(true); - TEST_FLUSH(); - testAndNot(); - TEST_FLUSH(); - testAnd(); - TEST_FLUSH(); - testOr(); - TEST_FLUSH(); - testAndWith(false); - testAndWith(true); - TEST_FLUSH(); - testIteratorConformance(); - TEST_FLUSH(); - TEST_DONE(); -} - -TEST_APPHOOK(Test); +TEST_MAIN() { TEST_RUN_ALL(); } -- cgit v1.2.3 From 9c8ecc24c725d00fb39640d40be32603d8406bf9 Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Tue, 3 Oct 2023 08:57:28 +0000 Subject: Add test counting seeks --- .../multibitvectoriterator_test.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/searchlib/src/tests/queryeval/multibitvectoriterator/multibitvectoriterator_test.cpp b/searchlib/src/tests/queryeval/multibitvectoriterator/multibitvectoriterator_test.cpp index 9cb7e1def1c..42f37df6a29 100644 --- a/searchlib/src/tests/queryeval/multibitvectoriterator/multibitvectoriterator_test.cpp +++ b/searchlib/src/tests/queryeval/multibitvectoriterator/multibitvectoriterator_test.cpp @@ -573,6 +573,22 @@ TEST_F("testThatOptimizePreservesUnpack", Fixture) { f.template testThatOptimizePreservesUnpack(); } +TEST_F("test that short vectors don't spin at end", Fixture) { + TermFieldMatchData tfmd; + MultiSearch::Children children; + children.push_back(f.createIter(0, false, tfmd, true)); + children.push_back(f.createIter(1, false, tfmd, true)); + SearchIterator::UP s = AndSearch::create(std::move(children), false); + s = MultiBitVectorIteratorBase::optimize(std::move(s)); + EXPECT_TRUE(s); + s->initRange(1, f._bvs[0]->size()); + uint32_t seekCount = 0; + for (uint32_t docId = s->seekFirst(1); !s->isAtEnd(); docId = s->seekNext(docId+1)) { + seekCount++; + } + EXPECT_EQUAL(2459u, seekCount); +} + class Verifier : public search::test::SearchIteratorVerifier { public: Verifier(size_t numBv, bool is_and); -- cgit v1.2.3 From 6446b42c81bf21f4bbe2772813a27e426e92f157 Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Tue, 3 Oct 2023 09:20:12 +0000 Subject: Add disabled test to prove eternal loop. --- .../multibitvectoriterator_test.cpp | 39 +++++++++++++++++++--- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/searchlib/src/tests/queryeval/multibitvectoriterator/multibitvectoriterator_test.cpp b/searchlib/src/tests/queryeval/multibitvectoriterator/multibitvectoriterator_test.cpp index 42f37df6a29..dd3394db507 100644 --- a/searchlib/src/tests/queryeval/multibitvectoriterator/multibitvectoriterator_test.cpp +++ b/searchlib/src/tests/queryeval/multibitvectoriterator/multibitvectoriterator_test.cpp @@ -573,22 +573,53 @@ TEST_F("testThatOptimizePreservesUnpack", Fixture) { f.template testThatOptimizePreservesUnpack(); } -TEST_F("test that short vectors don't spin at end", Fixture) { - TermFieldMatchData tfmd; +SearchIterator::UP +createDual(Fixture & f, TermFieldMatchData & tfmd, int32_t docIdLimit) { MultiSearch::Children children; children.push_back(f.createIter(0, false, tfmd, true)); children.push_back(f.createIter(1, false, tfmd, true)); SearchIterator::UP s = AndSearch::create(std::move(children), false); s = MultiBitVectorIteratorBase::optimize(std::move(s)); EXPECT_TRUE(s); - s->initRange(1, f._bvs[0]->size()); + if (docIdLimit < 0) { + s->initFullRange(); + } else { + s->initRange(1, docIdLimit); + } + return s; +} + +void +countUntilEnd(SearchIterator & s) { uint32_t seekCount = 0; - for (uint32_t docId = s->seekFirst(1); !s->isAtEnd(); docId = s->seekNext(docId+1)) { + for (uint32_t docId = s.seekFirst(1); !s.isAtEnd(); docId = s.seekNext(docId+1)) { seekCount++; } EXPECT_EQUAL(2459u, seekCount); } +void +countUntilDocId(SearchIterator & s) { + uint32_t seekCount = 0; + for (uint32_t docId = s.seekFirst(1), endId = s.getEndId(); docId < endId; docId = s.seekNext(docId+1)) { + seekCount++; + } + EXPECT_EQUAL(2459u, seekCount); +} + +TEST_F("test that short vectors don't spin at end", Fixture) { + TermFieldMatchData tfmd; + countUntilEnd(*createDual(f, tfmd, f._bvs[0]->size())); + countUntilDocId(*createDual(f, tfmd, f._bvs[0]->size())); + + // Below fails with eternal loop + //countUntilDocId(*createDual(f, tfmd, f._bvs[0]->size() + 1)); + //countUntilEnd(*createDual(f, tfmd, f._bvs[0]->size() + 1)); + + //countUntilDocId(*createDual(f, tfmd, -1)); + //countUntilEnd(*createDual(f, tfmd, -1)); +} + class Verifier : public search::test::SearchIteratorVerifier { public: Verifier(size_t numBv, bool is_and); -- cgit v1.2.3 From 6b27ae6138a1e924a39806bc1de75ef91c30a5c6 Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Tue, 3 Oct 2023 09:41:13 +0000 Subject: Prevent eternal loop if bit vectors are shorter than docid limit --- .../multibitvectoriterator/multibitvectoriterator_test.cpp | 11 +++++------ .../src/vespa/searchlib/queryeval/multibitvectoriterator.cpp | 4 ++-- .../src/vespa/searchlib/queryeval/multibitvectoriterator.h | 1 + 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/searchlib/src/tests/queryeval/multibitvectoriterator/multibitvectoriterator_test.cpp b/searchlib/src/tests/queryeval/multibitvectoriterator/multibitvectoriterator_test.cpp index dd3394db507..23f77a9d9d9 100644 --- a/searchlib/src/tests/queryeval/multibitvectoriterator/multibitvectoriterator_test.cpp +++ b/searchlib/src/tests/queryeval/multibitvectoriterator/multibitvectoriterator_test.cpp @@ -578,7 +578,7 @@ createDual(Fixture & f, TermFieldMatchData & tfmd, int32_t docIdLimit) { MultiSearch::Children children; children.push_back(f.createIter(0, false, tfmd, true)); children.push_back(f.createIter(1, false, tfmd, true)); - SearchIterator::UP s = AndSearch::create(std::move(children), false); + SearchIterator::UP s = AndSearch::create(std::move(children), true); s = MultiBitVectorIteratorBase::optimize(std::move(s)); EXPECT_TRUE(s); if (docIdLimit < 0) { @@ -612,12 +612,11 @@ TEST_F("test that short vectors don't spin at end", Fixture) { countUntilEnd(*createDual(f, tfmd, f._bvs[0]->size())); countUntilDocId(*createDual(f, tfmd, f._bvs[0]->size())); - // Below fails with eternal loop - //countUntilDocId(*createDual(f, tfmd, f._bvs[0]->size() + 1)); - //countUntilEnd(*createDual(f, tfmd, f._bvs[0]->size() + 1)); + countUntilDocId(*createDual(f, tfmd, f._bvs[0]->size() + 1)); + countUntilEnd(*createDual(f, tfmd, f._bvs[0]->size() + 1)); - //countUntilDocId(*createDual(f, tfmd, -1)); - //countUntilEnd(*createDual(f, tfmd, -1)); + countUntilDocId(*createDual(f, tfmd, -1)); + countUntilEnd(*createDual(f, tfmd, -1)); } class Verifier : public search::test::SearchIteratorVerifier { diff --git a/searchlib/src/vespa/searchlib/queryeval/multibitvectoriterator.cpp b/searchlib/src/vespa/searchlib/queryeval/multibitvectoriterator.cpp index 6408004ea32..563a88e860f 100644 --- a/searchlib/src/vespa/searchlib/queryeval/multibitvectoriterator.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/multibitvectoriterator.cpp @@ -66,7 +66,7 @@ bool MultiBitVector::updateLastValue(uint32_t docId) noexcept { if (docId >= _lastMaxDocIdLimit) { - if (__builtin_expect(docId >= _numDocs, false)) { + if (__builtin_expect(isAtEnd(docId), false)) { return true; } const uint32_t index(BitWord::wordNum(docId)); @@ -147,7 +147,7 @@ public: private: void doSeek(uint32_t docId) override { docId = this->_mbv.strictSeek(docId); - if (__builtin_expect(docId >= this->getEndId(), false)) { + if (__builtin_expect(this->_mbv.isAtEnd(docId), false)) { this->setAtEnd(); } else { this->setDocId(docId); diff --git a/searchlib/src/vespa/searchlib/queryeval/multibitvectoriterator.h b/searchlib/src/vespa/searchlib/queryeval/multibitvectoriterator.h index 5c3d17c6786..855ecfae60c 100644 --- a/searchlib/src/vespa/searchlib/queryeval/multibitvectoriterator.h +++ b/searchlib/src/vespa/searchlib/queryeval/multibitvectoriterator.h @@ -19,6 +19,7 @@ public: _lastMaxDocIdLimit = 0; _lastMaxDocIdLimitRequireFetch = 0; } + bool isAtEnd(uint32_t docId) const noexcept { return docId >= _numDocs; } void addBitVector(Meta bv, uint32_t docIdLimit); protected: uint32_t _numDocs; -- cgit v1.2.3