diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2018-06-06 10:00:59 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-06 10:00:59 +0200 |
commit | 81f6540e0bcedb2636ad5ea62f23cecf0658b4dc (patch) | |
tree | 12ea280192a44f26b9718018c7cfb39b0c4c4735 /searchlib | |
parent | a6cefdae2ea7b40e4ea4c157cbb65426458f70b9 (diff) |
Revert "Balder/sameelement in streaming"
Diffstat (limited to 'searchlib')
-rw-r--r-- | searchlib/src/tests/query/query-old.cpp | 154 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/query/posocc.h | 35 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/query/query.cpp | 235 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/query/query.h | 12 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/query/querynode.cpp | 89 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/query/queryterm.cpp | 10 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/query/queryterm.h | 2 |
7 files changed, 198 insertions, 339 deletions
diff --git a/searchlib/src/tests/query/query-old.cpp b/searchlib/src/tests/query/query-old.cpp index 2cab4447935..77fe813dda5 100644 --- a/searchlib/src/tests/query/query-old.cpp +++ b/searchlib/src/tests/query/query-old.cpp @@ -364,63 +364,65 @@ TEST("testPhraseEvaluate") { } // field 0 - terms[0]->add(0, 0, 0, 1); - terms[1]->add(1, 0, 0, 1); - terms[2]->add(2, 0, 0, 1); - terms[0]->add(7, 0, 0, 1); - terms[1]->add(8, 0, 1, 1); - terms[2]->add(9, 0, 0, 1); + terms[0]->add(0, 0, 1); + terms[1]->add(1, 0, 1); + terms[2]->add(2, 0, 1); + terms[0]->add(7, 0, 1); + terms[1]->add(8, 0, 1); + terms[2]->add(9, 0, 1); // field 1 - terms[0]->add(4, 1, 0, 1); - terms[1]->add(5, 1, 0, 1); - terms[2]->add(6, 1, 0, 1); + terms[0]->add(4, 1, 1); + terms[1]->add(5, 1, 1); + terms[2]->add(6, 1, 1); // field 2 (not complete match) - terms[0]->add(1, 2, 0, 1); - terms[1]->add(2, 2, 0, 1); - terms[2]->add(4, 2, 0, 1); + terms[0]->add(1, 2, 1); + terms[1]->add(2, 2, 1); + terms[2]->add(4, 2, 1); // field 3 - terms[0]->add(0, 3, 0, 1); - terms[1]->add(1, 3, 0, 1); - terms[2]->add(2, 3, 0, 1); + terms[0]->add(0, 3, 1); + terms[1]->add(1, 3, 1); + terms[2]->add(2, 3, 1); // field 4 (not complete match) - terms[0]->add(1, 4, 0, 1); - terms[1]->add(2, 4, 0, 1); + terms[0]->add(1, 4, 1); + terms[1]->add(2, 4, 1); // field 5 (not complete match) - terms[0]->add(2, 5, 0, 1); - terms[1]->add(1, 5, 0, 1); - terms[2]->add(0, 5, 0, 1); + terms[0]->add(2, 5, 1); + terms[1]->add(1, 5, 1); + terms[2]->add(0, 5, 1); HitList hits; PhraseQueryNode * p = static_cast<PhraseQueryNode *>(phrases[0]); p->evaluateHits(hits); - ASSERT_EQUAL(3u, hits.size()); + ASSERT_TRUE(hits.size() == 4); EXPECT_EQUAL(hits[0].wordpos(), 2u); EXPECT_EQUAL(hits[0].context(), 0u); - EXPECT_EQUAL(hits[1].wordpos(), 6u); - EXPECT_EQUAL(hits[1].context(), 1u); - EXPECT_EQUAL(hits[2].wordpos(), 2u); - EXPECT_EQUAL(hits[2].context(), 3u); - ASSERT_EQUAL(4u, p->getFieldInfoSize()); + EXPECT_EQUAL(hits[1].wordpos(), 9u); + EXPECT_EQUAL(hits[1].context(), 0u); + EXPECT_EQUAL(hits[2].wordpos(), 6u); + EXPECT_EQUAL(hits[2].context(), 1u); + EXPECT_EQUAL(hits[3].wordpos(), 2u); + EXPECT_EQUAL(hits[3].context(), 3u); + ASSERT_TRUE(p->getFieldInfoSize() == 4); EXPECT_EQUAL(p->getFieldInfo(0).getHitOffset(), 0u); - EXPECT_EQUAL(p->getFieldInfo(0).getHitCount(), 1u); - EXPECT_EQUAL(p->getFieldInfo(1).getHitOffset(), 1u); + EXPECT_EQUAL(p->getFieldInfo(0).getHitCount(), 2u); + EXPECT_EQUAL(p->getFieldInfo(1).getHitOffset(), 2u); EXPECT_EQUAL(p->getFieldInfo(1).getHitCount(), 1u); EXPECT_EQUAL(p->getFieldInfo(2).getHitOffset(), 0u); // invalid, but will never be used EXPECT_EQUAL(p->getFieldInfo(2).getHitCount(), 0u); - EXPECT_EQUAL(p->getFieldInfo(3).getHitOffset(), 2u); + EXPECT_EQUAL(p->getFieldInfo(3).getHitOffset(), 3u); EXPECT_EQUAL(p->getFieldInfo(3).getHitCount(), 1u); } TEST("testHit") { // positions (0 - (2^24-1)) - assertHit(Hit(0, 0, 0, 0), 0, 0, 0); - assertHit(Hit(256, 0, 0, 1), 256, 0, 1); - assertHit(Hit(16777215, 0, 0, -1), 16777215, 0, -1); - assertHit(Hit(16777216, 0, 0, 1), 0, 1, 1); // overflow + assertHit(Hit(0, 0, 0), 0, 0, 0); + assertHit(Hit(256, 0, 1), 256, 0, 1); + assertHit(Hit(16777215, 0, -1), 16777215, 0, -1); + assertHit(Hit(16777216, 0, 1), 0, 1, 1); // overflow // contexts (0 - 255) - assertHit(Hit(0, 1, 0, 1), 0, 1, 1); - assertHit(Hit(0, 255, 0, 1), 0, 255, 1); - assertHit(Hit(0, 256, 0, 1), 0, 0, 1); // overflow + assertHit(Hit(0, 1, 1), 0, 1, 1); + assertHit(Hit(0, 255, 1), 0, 255, 1); + assertHit(Hit(0, 256, 1), 0, 0, 1); // overflow } void assertInt8Range(const std::string &term, bool expAdjusted, int64_t expLow, int64_t expHigh) { @@ -651,84 +653,4 @@ TEST("require that we do not break the stack on bad query") { EXPECT_FALSE(term.isValid()); } -namespace { - void verifyQueryTermNode(const vespalib::string & index, const QueryNode *node) { - EXPECT_TRUE(dynamic_cast<const QueryTerm *>(node) != nullptr); - EXPECT_EQUAL(index, node->getIndex()); - } -} -TEST("testSameElementEvaluate") { - QueryBuilder<SimpleQueryNodeTypes> builder; - builder.addSameElement(3, "field"); - { - builder.addStringTerm("a", "f1", 0, Weight(0)); - builder.addStringTerm("b", "f2", 1, Weight(0)); - builder.addStringTerm("c", "f3", 2, Weight(0)); - } - Node::UP node = builder.build(); - vespalib::string stackDump = StackDumpCreator::create(*node); - QueryNodeResultFactory empty; - Query q(empty, stackDump); - SameElementQueryNode * sameElem = dynamic_cast<SameElementQueryNode *>(&q.getRoot()); - EXPECT_TRUE(sameElem != nullptr); - EXPECT_EQUAL("field", sameElem->getIndex()); - EXPECT_EQUAL(3u, sameElem->size()); - verifyQueryTermNode("field.f1", (*sameElem)[0].get()); - verifyQueryTermNode("field.f2", (*sameElem)[1].get()); - verifyQueryTermNode("field.f3", (*sameElem)[2].get()); - - QueryTermList terms; - q.getLeafs(terms); - EXPECT_EQUAL(3u, terms.size()); - for (QueryTerm * qt : terms) { - qt->resizeFieldId(3); - } - - // field 0 - terms[0]->add(1, 0, 0, 10); - terms[0]->add(2, 0, 1, 20); - terms[0]->add(3, 0, 2, 30); - terms[0]->add(4, 0, 3, 40); - terms[0]->add(5, 0, 4, 50); - terms[0]->add(6, 0, 5, 60); - - terms[1]->add(7, 1, 0, 70); - terms[1]->add(8, 1, 1, 80); - terms[1]->add(9, 1, 2, 90); - terms[1]->add(10, 1, 4, 100); - terms[1]->add(11, 1, 5, 110); - terms[1]->add(12, 1, 6, 120); - - terms[2]->add(13, 2, 0, 130); - terms[2]->add(14, 2, 2, 140); - terms[2]->add(15, 2, 4, 150); - terms[2]->add(16, 2, 5, 160); - terms[2]->add(17, 2, 6, 170); - HitList hits; - - sameElem->evaluateHits(hits); - EXPECT_EQUAL(4u, hits.size()); - EXPECT_EQUAL(0u, hits[0].wordpos()); - EXPECT_EQUAL(2u, hits[0].context()); - EXPECT_EQUAL(0u, hits[0].elemId()); - EXPECT_EQUAL(130, hits[0].weight()); - - EXPECT_EQUAL(0u, hits[1].wordpos()); - EXPECT_EQUAL(2u, hits[1].context()); - EXPECT_EQUAL(2u, hits[1].elemId()); - EXPECT_EQUAL(140, hits[1].weight()); - - EXPECT_EQUAL(0u, hits[2].wordpos()); - EXPECT_EQUAL(2u, hits[2].context()); - EXPECT_EQUAL(4u, hits[2].elemId()); - EXPECT_EQUAL(150, hits[2].weight()); - - EXPECT_EQUAL(0u, hits[3].wordpos()); - EXPECT_EQUAL(2u, hits[3].context()); - EXPECT_EQUAL(5u, hits[3].elemId()); - EXPECT_EQUAL(160, hits[3].weight()); - -} - - TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/searchlib/src/vespa/searchlib/query/posocc.h b/searchlib/src/vespa/searchlib/query/posocc.h index fcabef0297f..1b5b6283f88 100644 --- a/searchlib/src/vespa/searchlib/query/posocc.h +++ b/searchlib/src/vespa/searchlib/query/posocc.h @@ -4,29 +4,28 @@ #include <cstdint> #include <vector> -namespace search { +namespace search +{ class Hit { -public: - Hit(uint32_t pos_, uint32_t context_, uint32_t elemId_, int32_t weight_) - : _position(pos_ | (context_<<24)), - _elemId(elemId_), - _weight(weight_) - { } - int32_t weight() const { return _weight; } - uint32_t pos() const { return _position; } - uint32_t wordpos() const { return _position & 0xffffff; } - uint32_t context() const { return _position >> 24; } - uint32_t elemId() const { return _elemId; } - bool operator < (const Hit & b) const { return cmp(b) < 0; } -private: - int cmp(const Hit & b) const { return _position - b._position; } - uint32_t _position; - uint32_t _elemId; - int32_t _weight; + public: + Hit(uint32_t pos_, uint32_t context_, int32_t weight_) : + _position(pos_ | (context_<<24)), + _weight(weight_) + { } + int32_t weight() const { return _weight; } + uint32_t pos() const { return _position; } + uint32_t wordpos() const { return _position & 0xffffff; } + uint32_t context() const { return _position >> 24; } + bool operator < (const Hit & b) const { return cmp(b) < 0; } + private: + int cmp(const Hit & b) const { return _position - b._position; } + uint32_t _position; + int32_t _weight; }; typedef std::vector<Hit> HitList; } + diff --git a/searchlib/src/vespa/searchlib/query/query.cpp b/searchlib/src/vespa/searchlib/query/query.cpp index 659e48a0662..984337f40ba 100644 --- a/searchlib/src/vespa/searchlib/query/query.cpp +++ b/searchlib/src/vespa/searchlib/query/query.cpp @@ -16,90 +16,97 @@ QueryConnector::QueryConnector(const char * opName) : { } -QueryConnector::~QueryConnector() = default; +QueryConnector::~QueryConnector() { } const HitList & QueryConnector::evaluateHits(HitList & hl) const { - if (evaluate()) { - hl.push_back(Hit(1, 0, 0, 1)); - } - return hl; + if (evaluate()) { + hl.push_back(Hit(1, 0, 1)); + } + return hl; } void QueryConnector::reset() { - for(const auto & node : *this) { - node->reset(); - } + for(iterator it=begin(), mt=end(); it != mt; it++) { + QueryNode & qn = **it; + qn.reset(); + } } void QueryConnector::getLeafs(QueryTermList & tl) { - for(const auto & node : *this) { - node->getLeafs(tl); - } + for(iterator it=begin(), mt=end(); it != mt; it++) { + QueryNode & qn = **it; + qn.getLeafs(tl); + } } void QueryConnector::getLeafs(ConstQueryTermList & tl) const { - for(const auto & node : *this) { - node->getLeafs(tl); - } + for(const_iterator it=begin(), mt=end(); it != mt; it++) { + const QueryNode & qn = **it; + qn.getLeafs(tl); + } } void QueryConnector::getPhrases(QueryNodeRefList & tl) { - for(const auto & node : *this) { - node->getPhrases(tl); - } + for(iterator it=begin(), mt=end(); it != mt; it++) { + QueryNode & qn = **it; + qn.getPhrases(tl); + } } void QueryConnector::getPhrases(ConstQueryNodeRefList & tl) const { - for(const auto & node : *this) { - node->getPhrases(tl); - } + for(const_iterator it=begin(), mt=end(); it != mt; it++) { + const QueryNode & qn = **it; + qn.getPhrases(tl); + } } size_t QueryConnector::depth() const { - size_t d(0); - for(const auto & node : *this) { - size_t t = node->depth(); - if (t > d) { - d = t; - } - } - return d+1; + size_t d(0); + for(const_iterator it=begin(), mt=end(); (it!=mt); it++) { + const QueryNode & qn = **it; + size_t t = qn.depth(); + if (t > d) + d = t; + } + return d+1; } size_t QueryConnector::width() const { size_t w(0); - for(const auto & node : *this) { - w += node->width(); + for(const_iterator it=begin(), mt=end(); (it!=mt); it++) { + const QueryNode & qn = **it; + w += qn.width(); } return w; } -std::unique_ptr<QueryConnector> +QueryConnector * QueryConnector::create(ParseItem::ItemType type) { switch (type) { - case search::ParseItem::ITEM_AND: return std::make_unique<AndQueryNode>(); - case search::ParseItem::ITEM_OR: return std::make_unique<OrQueryNode>(); - case search::ParseItem::ITEM_WEAK_AND: return std::make_unique<OrQueryNode>(); - case search::ParseItem::ITEM_EQUIV: return std::make_unique<EquivQueryNode>(); - case search::ParseItem::ITEM_WEIGHTED_SET: return std::make_unique<EquivQueryNode>(); - case search::ParseItem::ITEM_DOT_PRODUCT: return std::make_unique<OrQueryNode>(); - case search::ParseItem::ITEM_WAND: return std::make_unique<OrQueryNode>(); - case search::ParseItem::ITEM_NOT: return std::make_unique<AndNotQueryNode>(); - case search::ParseItem::ITEM_PHRASE: return std::make_unique<PhraseQueryNode>(); - case search::ParseItem::ITEM_SAME_ELEMENT: return std::make_unique<SameElementQueryNode>(); - case search::ParseItem::ITEM_NEAR: return std::make_unique<NearQueryNode>(); - case search::ParseItem::ITEM_ONEAR: return std::make_unique<ONearQueryNode>(); - default: return nullptr; + case search::ParseItem::ITEM_AND: return new AndQueryNode(); + case search::ParseItem::ITEM_OR: return new OrQueryNode(); + case search::ParseItem::ITEM_WEAK_AND: return new OrQueryNode(); + case search::ParseItem::ITEM_EQUIV: return new EquivQueryNode(); + case search::ParseItem::ITEM_WEIGHTED_SET: return new EquivQueryNode(); + case search::ParseItem::ITEM_DOT_PRODUCT: return new OrQueryNode(); + case search::ParseItem::ITEM_WAND: return new OrQueryNode(); + case search::ParseItem::ITEM_NOT: return new AndNotQueryNode(); + case search::ParseItem::ITEM_PHRASE: return new PhraseQueryNode(); + case search::ParseItem::ITEM_SAME_ELEMENT: return new AndQueryNode(); // TODO: This needs a same element operation to work for streaming search too. + case search::ParseItem::ITEM_NEAR: return new NearQueryNode(); + case search::ParseItem::ITEM_ONEAR: return new ONearQueryNode(); + default: + return nullptr; } } @@ -146,116 +153,61 @@ bool EquivQueryNode::evaluate() const return OrQueryNode::evaluate(); } -bool SameElementQueryNode::evaluate() const { - HitList hl; - return evaluateHits(hl).empty(); -} - -const HitList & -SameElementQueryNode::evaluateHits(HitList & hl) const -{ - hl.clear(); - if ( !AndQueryNode::evaluate()) return hl; - - HitList tmpHL; - unsigned int numFields = size(); - unsigned int currMatchCount = 0; - std::vector<unsigned int> indexVector(numFields, 0); - auto curr = static_cast<const QueryTerm *> ((*this)[currMatchCount].get()); - bool exhausted( curr->evaluateHits(tmpHL).empty()); - for (; !exhausted; ) { - auto next = static_cast<const QueryTerm *>((*this)[currMatchCount+1].get()); - unsigned int & currIndex = indexVector[currMatchCount]; - unsigned int & nextIndex = indexVector[currMatchCount+1]; - - const auto & currHit = curr->evaluateHits(tmpHL)[currIndex]; - uint32_t currElemId = currHit.elemId(); - - const HitList & nextHL = next->evaluateHits(tmpHL); - - size_t nextIndexMax = nextHL.size(); - while ((nextIndex < nextIndexMax) && (nextHL[nextIndex].elemId() < currElemId)) { - nextIndex++; - } - if (nextHL[nextIndex].elemId() == currElemId) { - currMatchCount++; - if ((currMatchCount+1) == numFields) { - Hit h = nextHL[indexVector[currMatchCount]]; - hl.emplace_back(0, h.context(), h.elemId(), h.weight()); - currMatchCount = 0; - indexVector[0]++; - } - } else { - currMatchCount = 0; - indexVector[currMatchCount]++; - } - curr = static_cast<const QueryTerm *>((*this)[currMatchCount].get()); - exhausted = (nextIndex >= nextIndexMax) || (indexVector[currMatchCount] >= curr->evaluateHits(tmpHL).size()); - } - return hl; -} bool PhraseQueryNode::evaluate() const { + bool ok(false); HitList hl; - return evaluateHits(hl).empty(); + ok = ! evaluateHits(hl).empty(); + return ok; } void PhraseQueryNode::getPhrases(QueryNodeRefList & tl) { tl.push_back(this); } void PhraseQueryNode::getPhrases(ConstQueryNodeRefList & tl) const { tl.push_back(this); } -const HitList & -PhraseQueryNode::evaluateHits(HitList & hl) const +const HitList & PhraseQueryNode::evaluateHits(HitList & hl) const { - hl.clear(); - _fieldInfo.clear(); - if ( ! AndQueryNode::evaluate()) return hl; - + hl.clear(); + _fieldInfo.clear(); + bool andResult(AndQueryNode::evaluate()); + if (andResult) { HitList tmpHL; unsigned int fullPhraseLen = size(); unsigned int currPhraseLen = 0; std::vector<unsigned int> indexVector(fullPhraseLen, 0); - auto curr = static_cast<const QueryTerm *> ((*this)[currPhraseLen].get()); + const QueryTerm * curr = static_cast<const QueryTerm *> (&(*(*this)[currPhraseLen])); bool exhausted( curr->evaluateHits(tmpHL).empty()); for (; !exhausted; ) { - auto next = static_cast<const QueryTerm *>((*this)[currPhraseLen+1].get()); - unsigned int & currIndex = indexVector[currPhraseLen]; - unsigned int & nextIndex = indexVector[currPhraseLen+1]; - - const auto & currHit = curr->evaluateHits(tmpHL)[currIndex]; - size_t firstPosition = currHit.pos(); - uint32_t currElemId = currHit.elemId(); - uint32_t currContext = currHit.context(); - - const HitList & nextHL = next->evaluateHits(tmpHL); - - int diff(0); - size_t nextIndexMax = nextHL.size(); - while ((nextIndex < nextIndexMax) && - ((nextHL[nextIndex].context() < currContext) || - ((nextHL[nextIndex].context() == currContext) && (nextHL[nextIndex].elemId() <= currElemId))) && - ((diff = nextHL[nextIndex].pos()-firstPosition) < 1)) - { - nextIndex++; - } - if ((diff == 1) && (nextHL[nextIndex].context() == currContext) && (nextHL[nextIndex].elemId() == currElemId)) { - currPhraseLen++; - if ((currPhraseLen+1) == fullPhraseLen) { - Hit h = nextHL[indexVector[currPhraseLen]]; - hl.push_back(h); - const QueryTerm::FieldInfo & fi = next->getFieldInfo(h.context()); - updateFieldInfo(h.context(), hl.size() - 1, fi.getFieldLength()); - currPhraseLen = 0; - indexVector[0]++; - } - } else { - currPhraseLen = 0; - indexVector[currPhraseLen]++; + const QueryTerm & next = static_cast<const QueryTerm &>(*(*this)[currPhraseLen+1]); + unsigned int & currIndex = indexVector[currPhraseLen]; + unsigned int & nextIndex = indexVector[currPhraseLen+1]; + const HitList & nextHL = next.evaluateHits(tmpHL); + + size_t firstPosition = curr->evaluateHits(tmpHL)[currIndex].pos(); + int diff(0); + size_t nextIndexMax = nextHL.size(); + while ((nextIndex < nextIndexMax) && ((diff = nextHL[nextIndex].pos()-firstPosition) < 1)) + nextIndex++; + if (diff == 1) { + currPhraseLen++; + bool ok = ((currPhraseLen+1)==fullPhraseLen); + if (ok) { + Hit h = nextHL[indexVector[currPhraseLen]]; + hl.push_back(h); + const QueryTerm::FieldInfo & fi = next.getFieldInfo(h.context()); + updateFieldInfo(h.context(), hl.size() - 1, fi.getFieldLength()); + currPhraseLen = 0; + indexVector[0]++; } - curr = static_cast<const QueryTerm *>((*this)[currPhraseLen].get()); - exhausted = (nextIndex >= nextIndexMax) || (indexVector[currPhraseLen] >= curr->evaluateHits(tmpHL).size()); + } else { + currPhraseLen = 0; + indexVector[currPhraseLen]++; + } + curr = static_cast<const QueryTerm *>(&*(*this)[currPhraseLen]); + exhausted = (nextIndex >= nextIndexMax) || (indexVector[currPhraseLen] >= curr->evaluateHits(tmpHL).size()); } - return hl; + } + return hl; } void @@ -275,8 +227,9 @@ PhraseQueryNode::updateFieldInfo(size_t fid, size_t offset, size_t fieldLength) bool NotQueryNode::evaluate() const { bool ok(false); - for (const auto & node : *this) { - ok |= ! node->evaluate(); + for (const_iterator it=begin(), mt=end(); it!=mt; it++) { + const QueryNode & qn = **it; + ok |= ! qn.evaluate(); } return ok; } @@ -300,7 +253,9 @@ bool ONearQueryNode::evaluate() const return ok; } -Query::Query() = default; +Query::Query() : + _root() +{ } Query::Query(const QueryNodeResultFactory & factory, const QueryPacketT & queryRep) : _root() @@ -318,7 +273,7 @@ bool Query::build(const QueryNodeResultFactory & factory, const QueryPacketT & q { search::SimpleQueryStackDumpIterator stack(queryRep); if (stack.next()) { - _root = QueryNode::Build(nullptr, factory, stack, true); + _root.reset(QueryNode::Build(NULL, factory, stack, true).release()); } return valid(); } diff --git a/searchlib/src/vespa/searchlib/query/query.h b/searchlib/src/vespa/searchlib/query/query.h index b9bcd76d869..9bb1b29aae5 100644 --- a/searchlib/src/vespa/searchlib/query/query.h +++ b/searchlib/src/vespa/searchlib/query/query.h @@ -28,7 +28,7 @@ public: virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; void setIndex(const vespalib::string & index) override { _index = index; } const vespalib::string & getIndex() const override { return _index; } - static std::unique_ptr<QueryConnector> create(ParseItem::ItemType type); + static QueryConnector * create(ParseItem::ItemType type); virtual bool isFlattenable(ParseItem::ItemType type) const { (void) type; return false; } private: vespalib::string _opName; @@ -123,15 +123,6 @@ private: #endif }; -class SameElementQueryNode : public AndQueryNode -{ -public: - SameElementQueryNode() : AndQueryNode("SAME_ELEMENT") { } - bool evaluate() const override; - const HitList & evaluateHits(HitList & hl) const override; - bool isFlattenable(ParseItem::ItemType type) const override { return type == ParseItem::ITEM_NOT; } -}; - /** Unary Not operator. Just inverts the nodes result. */ @@ -199,7 +190,6 @@ public: size_t width() const; bool valid() const { return _root.get() != NULL; } const QueryNode & getRoot() const { return *_root; } - QueryNode & getRoot() { return *_root; } static QueryNode::UP steal(Query && query) { return std::move(query._root); } private: QueryNode::UP _root; diff --git a/searchlib/src/vespa/searchlib/query/querynode.cpp b/searchlib/src/vespa/searchlib/query/querynode.cpp index fcc539658d0..0d0a06de7af 100644 --- a/searchlib/src/vespa/searchlib/query/querynode.cpp +++ b/searchlib/src/vespa/searchlib/query/querynode.cpp @@ -9,44 +9,38 @@ namespace search { namespace { vespalib::stringref DEFAULT("default"); - bool isPhraseOrNear(const QueryNode * qn) { - return dynamic_cast<const NearQueryNode *> (qn) || dynamic_cast<const PhraseQueryNode *> (qn); - } } -QueryNode::UP -QueryNode::Build(const QueryNode * parent, const QueryNodeResultFactory & factory, - SimpleQueryStackDumpIterator & queryRep, bool allowRewrite) +QueryNode::UP QueryNode::Build(const QueryNode * parent, const QueryNodeResultFactory & factory, search::SimpleQueryStackDumpIterator & queryRep, bool allowRewrite) { unsigned int arity = queryRep.getArity(); - ParseItem::ItemType type = queryRep.getType(); + search::ParseItem::ItemType type = queryRep.getType(); UP qn; switch (type) { - case ParseItem::ITEM_AND: - case ParseItem::ITEM_OR: - case ParseItem::ITEM_WEAK_AND: - case ParseItem::ITEM_EQUIV: - case ParseItem::ITEM_WEIGHTED_SET: - case ParseItem::ITEM_DOT_PRODUCT: - case ParseItem::ITEM_WAND: - case ParseItem::ITEM_NOT: - case ParseItem::ITEM_PHRASE: - case ParseItem::ITEM_SAME_ELEMENT: - case ParseItem::ITEM_NEAR: - case ParseItem::ITEM_ONEAR: + case search::ParseItem::ITEM_AND: + case search::ParseItem::ITEM_OR: + case search::ParseItem::ITEM_WEAK_AND: + case search::ParseItem::ITEM_EQUIV: + case search::ParseItem::ITEM_WEIGHTED_SET: + case search::ParseItem::ITEM_DOT_PRODUCT: + case search::ParseItem::ITEM_WAND: + case search::ParseItem::ITEM_NOT: + case search::ParseItem::ITEM_PHRASE: + case search::ParseItem::ITEM_SAME_ELEMENT: + case search::ParseItem::ITEM_NEAR: + case search::ParseItem::ITEM_ONEAR: { - qn = QueryConnector::create(type); - if (qn) { + qn.reset(QueryConnector::create(type)); + if (qn.get()) { QueryConnector * qc = dynamic_cast<QueryConnector *> (qn.get()); NearQueryNode * nqn = dynamic_cast<NearQueryNode *> (qc); if (nqn) { nqn->distance(queryRep.getArg1()); } - if ((type == ParseItem::ITEM_WEAK_AND) || - (type == ParseItem::ITEM_WEIGHTED_SET) || - (type == ParseItem::ITEM_DOT_PRODUCT) || - (type == ParseItem::ITEM_SAME_ELEMENT) || - (type == ParseItem::ITEM_WAND)) + if ((type == search::ParseItem::ITEM_WEAK_AND) || + (type == search::ParseItem::ITEM_WEIGHTED_SET) || + (type == search::ParseItem::ITEM_DOT_PRODUCT) || + (type == search::ParseItem::ITEM_WAND)) { qn->setIndex(queryRep.getIndexName()); } @@ -55,50 +49,48 @@ QueryNode::Build(const QueryNode * parent, const QueryNodeResultFactory & factor if (qc->isFlattenable(queryRep.getType())) { arity += queryRep.getArity(); } else { - UP child = Build(qc, factory, queryRep, allowRewrite && !isPhraseOrNear(qn.get())); + UP child(Build(qc, factory, queryRep, + allowRewrite && ((dynamic_cast<NearQueryNode *> (qn.get()) == NULL) && (dynamic_cast<PhraseQueryNode *> (qn.get()) == NULL)))); qc->push_back(std::move(child)); } } } } break; - case ParseItem::ITEM_NUMTERM: - case ParseItem::ITEM_TERM: - case ParseItem::ITEM_PREFIXTERM: - case ParseItem::ITEM_REGEXP: - case ParseItem::ITEM_SUBSTRINGTERM: - case ParseItem::ITEM_EXACTSTRINGTERM: - case ParseItem::ITEM_SUFFIXTERM: - case ParseItem::ITEM_PURE_WEIGHTED_STRING: - case ParseItem::ITEM_PURE_WEIGHTED_LONG: + case search::ParseItem::ITEM_NUMTERM: + case search::ParseItem::ITEM_TERM: + case search::ParseItem::ITEM_PREFIXTERM: + case search::ParseItem::ITEM_REGEXP: + case search::ParseItem::ITEM_SUBSTRINGTERM: + case search::ParseItem::ITEM_EXACTSTRINGTERM: + case search::ParseItem::ITEM_SUFFIXTERM: + case search::ParseItem::ITEM_PURE_WEIGHTED_STRING: + case search::ParseItem::ITEM_PURE_WEIGHTED_LONG: { - vespalib::string index = queryRep.getIndexName(); + vespalib::stringref index = queryRep.getIndexName(); if (index.empty()) { - if ((type == ParseItem::ITEM_PURE_WEIGHTED_STRING) || (type == ParseItem::ITEM_PURE_WEIGHTED_LONG)) { + if ((type == search::ParseItem::ITEM_PURE_WEIGHTED_STRING) || (type == search::ParseItem::ITEM_PURE_WEIGHTED_LONG)) { index = parent->getIndex(); } else { index = DEFAULT; } } - if (dynamic_cast<const SameElementQueryNode *>(parent) != nullptr) { - index = parent->getIndex() + "." + index; - } vespalib::stringref term = queryRep.getTerm(); QueryTerm::SearchTerm sTerm(QueryTerm::WORD); switch (type) { - case ParseItem::ITEM_REGEXP: + case search::ParseItem::ITEM_REGEXP: sTerm = QueryTerm::REGEXP; break; - case ParseItem::ITEM_PREFIXTERM: + case search::ParseItem::ITEM_PREFIXTERM: sTerm = QueryTerm::PREFIXTERM; break; - case ParseItem::ITEM_SUBSTRINGTERM: + case search::ParseItem::ITEM_SUBSTRINGTERM: sTerm = QueryTerm::SUBSTRINGTERM; break; - case ParseItem::ITEM_EXACTSTRINGTERM: + case search::ParseItem::ITEM_EXACTSTRINGTERM: sTerm = QueryTerm::EXACTSTRINGTERM; break; - case ParseItem::ITEM_SUFFIXTERM: + case search::ParseItem::ITEM_SUFFIXTERM: sTerm = QueryTerm::SUFFIXTERM; break; default: @@ -115,9 +107,10 @@ QueryNode::Build(const QueryNode * parent, const QueryNodeResultFactory & factor qt->setWeight(queryRep.GetWeight()); qt->setUniqueId(queryRep.getUniqueId()); if ( qt->encoding().isBase10Integer() || ! qt->encoding().isFloat() || ! factory.getRewriteFloatTerms() || !allowRewrite || (ssTerm.find('.') == vespalib::string::npos)) { - qn = std::move(qt); + qn.reset(qt.release()); } else { std::unique_ptr<PhraseQueryNode> phrase(new PhraseQueryNode()); + phrase->push_back(UP(new QueryTerm(factory.create(), ssTerm.substr(0, ssTerm.find('.')), ssIndex, QueryTerm::WORD))); phrase->push_back(UP(new QueryTerm(factory.create(), ssTerm.substr(ssTerm.find('.') + 1), ssIndex, QueryTerm::WORD))); std::unique_ptr<EquivQueryNode> orqn(new EquivQueryNode()); @@ -128,7 +121,7 @@ QueryNode::Build(const QueryNode * parent, const QueryNodeResultFactory & factor } } break; - case ParseItem::ITEM_RANK: + case search::ParseItem::ITEM_RANK: { if (arity >= 1) { queryRep.next(); diff --git a/searchlib/src/vespa/searchlib/query/queryterm.cpp b/searchlib/src/vespa/searchlib/query/queryterm.cpp index ee2e72b41a8..d47d942dc10 100644 --- a/searchlib/src/vespa/searchlib/query/queryterm.cpp +++ b/searchlib/src/vespa/searchlib/query/queryterm.cpp @@ -73,7 +73,7 @@ QueryTermBase::QueryTermBase() : _termUCS4.push_back(0); } -QueryTermBase::~QueryTermBase() = default; +QueryTermBase::~QueryTermBase() { } QueryTermBase::QueryTermBase(const string & termS, SearchTerm type) : QueryTermSimple(termS, type), @@ -104,7 +104,7 @@ QueryTerm & QueryTerm::operator = (const QueryTerm &) = default; QueryTerm::QueryTerm(QueryTerm &&) = default; QueryTerm & QueryTerm::operator = (QueryTerm &&) = default; -QueryTerm::~QueryTerm() = default; +QueryTerm::~QueryTerm() { } void QueryTermSimple::visitMembers(vespalib::ObjectVisitor & visitor) const @@ -301,9 +301,9 @@ void QueryTerm::resizeFieldId(size_t fieldNo) } } -void QueryTerm::add(unsigned pos, unsigned context, uint32_t elemId, int32_t weight_) +void QueryTerm::add(unsigned pos, unsigned context, int32_t weight_) { - _hitList.emplace_back(pos, context, elemId, weight_); + _hitList.emplace_back(pos, context, weight_); } template <int B> @@ -344,7 +344,7 @@ QueryTermSimple::QueryTermSimple() : _diversityAttribute() { } -QueryTermSimple::~QueryTermSimple() = default; +QueryTermSimple::~QueryTermSimple() { } namespace { diff --git a/searchlib/src/vespa/searchlib/query/queryterm.h b/searchlib/src/vespa/searchlib/query/queryterm.h index 457a2feeeed..423b8d28efb 100644 --- a/searchlib/src/vespa/searchlib/query/queryterm.h +++ b/searchlib/src/vespa/searchlib/query/queryterm.h @@ -173,7 +173,7 @@ public: /// Gives you all phrases of this tree. Indicating that they are all const. void getPhrases(ConstQueryNodeRefList & tl) const override; - void add(unsigned pos, unsigned context, uint32_t elemId, int32_t weight); + void add(unsigned pos, unsigned context, int32_t weight); EncodingBitMap encoding() const { return _encoding; } size_t termLen() const { return getTermLen(); } const string & index() const { return _index; } |