aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2018-06-06 10:00:59 +0200
committerGitHub <noreply@github.com>2018-06-06 10:00:59 +0200
commit81f6540e0bcedb2636ad5ea62f23cecf0658b4dc (patch)
tree12ea280192a44f26b9718018c7cfb39b0c4c4735 /searchlib
parenta6cefdae2ea7b40e4ea4c157cbb65426458f70b9 (diff)
Revert "Balder/sameelement in streaming"
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/tests/query/query-old.cpp154
-rw-r--r--searchlib/src/vespa/searchlib/query/posocc.h35
-rw-r--r--searchlib/src/vespa/searchlib/query/query.cpp235
-rw-r--r--searchlib/src/vespa/searchlib/query/query.h12
-rw-r--r--searchlib/src/vespa/searchlib/query/querynode.cpp89
-rw-r--r--searchlib/src/vespa/searchlib/query/queryterm.cpp10
-rw-r--r--searchlib/src/vespa/searchlib/query/queryterm.h2
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; }