aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.cpp
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@online.no>2024-01-23 13:39:51 +0100
committerTor Egge <Tor.Egge@online.no>2024-01-23 13:39:51 +0100
commite7988189f70b0a39fe3856768a62b36e290c7ad3 (patch)
treec75a019bb3c311723abda2c6efe57836fe3c0ecd /searchlib/src/vespa/searchlib/query/streaming/same_element_query_node.cpp
parent056a486a55fd66c39b9b30065865d29655f338f7 (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.cpp65
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;
+}
+
+}