diff options
author | Tor Egge <Tor.Egge@online.no> | 2024-01-23 13:39:51 +0100 |
---|---|---|
committer | Tor Egge <Tor.Egge@online.no> | 2024-01-23 13:39:51 +0100 |
commit | e7988189f70b0a39fe3856768a62b36e290c7ad3 (patch) | |
tree | c75a019bb3c311723abda2c6efe57836fe3c0ecd /searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.cpp | |
parent | 056a486a55fd66c39b9b30065865d29655f338f7 (diff) |
Move out NearQueryNode, ONearQueryNode, PhraseQueryNode and
SameElementQueryNode to separate files.
Diffstat (limited to 'searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.cpp')
-rw-r--r-- | searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.cpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.cpp b/searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.cpp new file mode 100644 index 00000000000..49d5fb0f9fb --- /dev/null +++ b/searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.cpp @@ -0,0 +1,65 @@ +// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "same_element_query_node.h" +#include <cassert> + +namespace search::streaming { + +bool +SameElementQueryNode::evaluate() const { + HitList hl; + return ! evaluateHits(hl).empty(); +} + +void +SameElementQueryNode::addChild(QueryNode::UP child) { + assert(dynamic_cast<const QueryTerm *>(child.get()) != nullptr); + AndQueryNode::addChild(std::move(child)); +} + +const HitList & +SameElementQueryNode::evaluateHits(HitList & hl) const +{ + hl.clear(); + if ( !AndQueryNode::evaluate()) return hl; + + HitList tmpHL; + const auto & children = getChildren(); + unsigned int numFields = children.size(); + unsigned int currMatchCount = 0; + std::vector<unsigned int> indexVector(numFields, 0); + auto curr = static_cast<const QueryTerm *> (children[currMatchCount].get()); + bool exhausted( curr->evaluateHits(tmpHL).empty()); + for (; !exhausted; ) { + auto next = static_cast<const QueryTerm *>(children[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.element_id(); + + const HitList & nextHL = next->evaluateHits(tmpHL); + + size_t nextIndexMax = nextHL.size(); + while ((nextIndex < nextIndexMax) && (nextHL[nextIndex].element_id() < currElemId)) { + nextIndex++; + } + if ((nextIndex < nextIndexMax) && (nextHL[nextIndex].element_id() == currElemId)) { + currMatchCount++; + if ((currMatchCount+1) == numFields) { + Hit h = nextHL[indexVector[currMatchCount]]; + hl.emplace_back(h.field_id(), h.element_id(), h.element_weight(), 0); + currMatchCount = 0; + indexVector[0]++; + } + } else { + currMatchCount = 0; + indexVector[currMatchCount]++; + } + curr = static_cast<const QueryTerm *>(children[currMatchCount].get()); + exhausted = (nextIndex >= nextIndexMax) || (indexVector[currMatchCount] >= curr->evaluateHits(tmpHL).size()); + } + return hl; +} + +} |