diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2017-02-23 00:08:21 +0100 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2017-02-23 00:08:21 +0100 |
commit | 163ba724c52eb4d7364baa85cbd55c82f6594cad (patch) | |
tree | 1c71d2ab02455d7df09cd918b61adceae55fe559 | |
parent | 53f09660891181825dbd3364c63b0da304a21968 (diff) |
Avoid creating objects not needed.
16 files changed, 114 insertions, 126 deletions
diff --git a/searchlib/src/tests/query/query-old-large.cpp b/searchlib/src/tests/query/query-old-large.cpp index 4e0d0fb85de..cfe1949991b 100644 --- a/searchlib/src/tests/query/query-old-large.cpp +++ b/searchlib/src/tests/query/query-old-large.cpp @@ -1,5 +1,4 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/fastos/fastos.h> #include <vespa/searchlib/query/query.h> #include <vespa/searchlib/query/tree/querybuilder.h> #include <vespa/searchlib/query/tree/simplequery.h> @@ -40,8 +39,8 @@ TEST("testveryLongQueryResultingInBug6850778") { Node::UP node = builder.build(); vespalib::string stackDump = StackDumpCreator::create(*node); - EmptyQueryNodeResult empty; - Query q(empty, stackDump); + QueryNodeResultFactory factory; + Query q(factory, stackDump); QueryTermList terms; QueryNodeRefList phrases; q.getLeafs(terms); diff --git a/searchlib/src/tests/query/query-old.cpp b/searchlib/src/tests/query/query-old.cpp index c2eb1847c36..528a39712a4 100644 --- a/searchlib/src/tests/query/query-old.cpp +++ b/searchlib/src/tests/query/query-old.cpp @@ -1,5 +1,5 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/fastos/fastos.h> + #include <vespa/searchlib/query/query.h> #include <vespa/searchlib/query/tree/querybuilder.h> #include <vespa/searchlib/query/tree/simplequery.h> @@ -18,11 +18,11 @@ void assertHit(const Hit & h, size_t expWordpos, size_t expContext, int32_t weig } TEST("testQueryLanguage") { - EmptyQueryNodeResult eqnr; + QueryNodeResultFactory factory; int64_t ia(0), ib(0); double da(0), db(0); - QueryTerm q(eqnr, "7", "index", QueryTerm::WORD); + QueryTerm q(factory.create(), "7", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, 7); EXPECT_EQUAL(ib, 7); @@ -30,7 +30,7 @@ TEST("testQueryLanguage") { EXPECT_EQUAL(da, 7); EXPECT_EQUAL(db, 7); - q = QueryTerm(eqnr, "-7", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "-7", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, -7); EXPECT_EQUAL(ib, -7); @@ -38,19 +38,19 @@ TEST("testQueryLanguage") { EXPECT_EQUAL(da, -7); EXPECT_EQUAL(db, -7); - q = QueryTerm(eqnr, "7.5", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "7.5", "index", QueryTerm::WORD); EXPECT_TRUE(!q.getAsIntegerTerm(ia, ib)); EXPECT_TRUE(q.getAsDoubleTerm(da, db)); EXPECT_EQUAL(da, 7.5); EXPECT_EQUAL(db, 7.5); - q = QueryTerm(eqnr, "-7.5", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "-7.5", "index", QueryTerm::WORD); EXPECT_TRUE(!q.getAsIntegerTerm(ia, ib)); EXPECT_TRUE(q.getAsDoubleTerm(da, db)); EXPECT_EQUAL(da, -7.5); EXPECT_EQUAL(db, -7.5); - q = QueryTerm(eqnr, "<7", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "<7", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, std::numeric_limits<int64_t>::min()); EXPECT_EQUAL(ib, 6); @@ -59,7 +59,7 @@ TEST("testQueryLanguage") { EXPECT_LESS(db, 7); EXPECT_GREATER(db, 6.99); - q = QueryTerm(eqnr, "[;7]", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "[;7]", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, std::numeric_limits<int64_t>::min()); EXPECT_EQUAL(ib, 7); @@ -67,7 +67,7 @@ TEST("testQueryLanguage") { EXPECT_EQUAL(da, -std::numeric_limits<double>::max()); EXPECT_EQUAL(db, 7); - q = QueryTerm(eqnr, ">7", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), ">7", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, 8); EXPECT_EQUAL(ib, std::numeric_limits<int64_t>::max()); @@ -76,7 +76,7 @@ TEST("testQueryLanguage") { EXPECT_LESS(da, 7.01); EXPECT_EQUAL(db, std::numeric_limits<double>::max()); - q = QueryTerm(eqnr, "[7;]", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "[7;]", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, 7); EXPECT_EQUAL(ib, std::numeric_limits<int64_t>::max()); @@ -84,7 +84,7 @@ TEST("testQueryLanguage") { EXPECT_EQUAL(da, 7); EXPECT_EQUAL(db, std::numeric_limits<double>::max()); - q = QueryTerm(eqnr, "[-7;7]", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "[-7;7]", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, -7); EXPECT_EQUAL(ib, 7); @@ -92,7 +92,7 @@ TEST("testQueryLanguage") { EXPECT_EQUAL(da, -7); EXPECT_EQUAL(db, 7); - q = QueryTerm(eqnr, "[-7.1;7.1]", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "[-7.1;7.1]", "index", QueryTerm::WORD); EXPECT_FALSE(q.getAsIntegerTerm(ia, ib)); // This is dubious and perhaps a regression. EXPECT_EQUAL(ia, std::numeric_limits<int64_t>::min()); EXPECT_EQUAL(ib, std::numeric_limits<int64_t>::max()); @@ -100,7 +100,7 @@ TEST("testQueryLanguage") { EXPECT_EQUAL(da, -7.1); EXPECT_EQUAL(db, 7.1); - q = QueryTerm(eqnr, "[500.0;1.7976931348623157E308]", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "[500.0;1.7976931348623157E308]", "index", QueryTerm::WORD); EXPECT_FALSE(q.getAsIntegerTerm(ia, ib)); // This is dubious and perhaps a regression. EXPECT_EQUAL(ia, std::numeric_limits<int64_t>::min()); EXPECT_EQUAL(ib, std::numeric_limits<int64_t>::max()); @@ -109,7 +109,7 @@ TEST("testQueryLanguage") { EXPECT_EQUAL(db, std::numeric_limits<double>::max()); const double minusSeven(-7), seven(7); - q = QueryTerm(eqnr, "<-7;7]", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "<-7;7]", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, -6); EXPECT_EQUAL(ib, 7); @@ -117,7 +117,7 @@ TEST("testQueryLanguage") { EXPECT_EQUAL(da, std::nextafterf(minusSeven, seven)); EXPECT_EQUAL(db, seven); - q = QueryTerm(eqnr, "<-7;7>", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "<-7;7>", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, -6); EXPECT_EQUAL(ib, 6); @@ -125,12 +125,12 @@ TEST("testQueryLanguage") { EXPECT_EQUAL(da, std::nextafterf(minusSeven, seven)); EXPECT_EQUAL(db, std::nextafterf(seven, minusSeven)); - q = QueryTerm(eqnr, "<1;2>", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "<1;2>", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, 2); EXPECT_EQUAL(ib, 1); - q = QueryTerm(eqnr, "[-7;7>", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "[-7;7>", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, -7); EXPECT_EQUAL(ib, 6); @@ -138,7 +138,7 @@ TEST("testQueryLanguage") { EXPECT_EQUAL(da, minusSeven); EXPECT_EQUAL(db, std::nextafterf(seven, minusSeven)); - q = QueryTerm(eqnr, "<-7", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "<-7", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, std::numeric_limits<int64_t>::min()); EXPECT_EQUAL(ib, -8); @@ -147,7 +147,7 @@ TEST("testQueryLanguage") { EXPECT_LESS(db, -7); EXPECT_GREATER(db, -7.01); - q = QueryTerm(eqnr, "[;-7]", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "[;-7]", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, std::numeric_limits<int64_t>::min()); EXPECT_EQUAL(ib, -7); @@ -155,7 +155,7 @@ TEST("testQueryLanguage") { EXPECT_EQUAL(da, -std::numeric_limits<double>::max()); EXPECT_EQUAL(db, -7); - q = QueryTerm(eqnr, "<;-7]", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "<;-7]", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, std::numeric_limits<int64_t>::min()); EXPECT_EQUAL(ib, -7); @@ -163,7 +163,7 @@ TEST("testQueryLanguage") { EXPECT_EQUAL(da, -std::numeric_limits<double>::max()); EXPECT_EQUAL(db, -7); - q = QueryTerm(eqnr, ">-7", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), ">-7", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, -6); EXPECT_EQUAL(ib, std::numeric_limits<int64_t>::max()); @@ -172,7 +172,7 @@ TEST("testQueryLanguage") { EXPECT_LESS(da, -6.99); EXPECT_EQUAL(db, std::numeric_limits<double>::max()); - q = QueryTerm(eqnr, "[-7;]", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "[-7;]", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, -7); EXPECT_EQUAL(ib, std::numeric_limits<int64_t>::max()); @@ -180,7 +180,7 @@ TEST("testQueryLanguage") { EXPECT_EQUAL(da, -7); EXPECT_EQUAL(db, std::numeric_limits<double>::max()); - q = QueryTerm(eqnr, "[-7;>", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "[-7;>", "index", QueryTerm::WORD); EXPECT_TRUE(q.getAsIntegerTerm(ia, ib)); EXPECT_EQUAL(ia, -7); EXPECT_EQUAL(ib, std::numeric_limits<int64_t>::max()); @@ -188,55 +188,51 @@ TEST("testQueryLanguage") { EXPECT_EQUAL(da, -7); EXPECT_EQUAL(db, std::numeric_limits<double>::max()); - q = QueryTerm(eqnr, "a", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "a", "index", QueryTerm::WORD); EXPECT_TRUE(!q.getAsIntegerTerm(ia, ib)); EXPECT_TRUE(!q.getAsDoubleTerm(da, db)); - q = QueryTerm(eqnr, "word", "index", QueryTerm::WORD); + q = QueryTerm(factory.create(), "word", "index", QueryTerm::WORD); EXPECT_TRUE(!q.isPrefix()); EXPECT_TRUE(!q.isSubstring()); EXPECT_TRUE(!q.isSuffix()); - q = QueryTerm(eqnr, "prefix", "index", QueryTerm::PREFIXTERM); + q = QueryTerm(factory.create(), "prefix", "index", QueryTerm::PREFIXTERM); EXPECT_TRUE(q.isPrefix()); EXPECT_TRUE(!q.isSubstring()); EXPECT_TRUE(!q.isSuffix()); - q = QueryTerm(eqnr, "substring", "index", QueryTerm::SUBSTRINGTERM); + q = QueryTerm(factory.create(), "substring", "index", QueryTerm::SUBSTRINGTERM); EXPECT_TRUE(!q.isPrefix()); EXPECT_TRUE(q.isSubstring()); EXPECT_TRUE(!q.isSuffix()); - q = QueryTerm(eqnr, "suffix", "index", QueryTerm::SUFFIXTERM); + q = QueryTerm(factory.create(), "suffix", "index", QueryTerm::SUFFIXTERM); EXPECT_TRUE(!q.isPrefix()); EXPECT_TRUE(!q.isSubstring()); EXPECT_TRUE(q.isSuffix()); - q = QueryTerm(eqnr, "regexp", "index", QueryTerm::REGEXP); + q = QueryTerm(factory.create(), "regexp", "index", QueryTerm::REGEXP); EXPECT_TRUE(!q.isPrefix()); EXPECT_TRUE(!q.isSubstring()); EXPECT_TRUE(!q.isSuffix()); EXPECT_TRUE(q.isRegex()); } -class AllowRewrite : public EmptyQueryNodeResult +class AllowRewrite : public QueryNodeResultFactory { public: - DUPLICATE(AllowRewrite); // create duplicate function - virtual bool getRewriteFloatTerms() const { return true; } }; -IMPLEMENT_DUPLICATE(AllowRewrite); - const char TERM_UNIQ = ParseItem::ITEM_TERM | ParseItem::IF_UNIQUEID; TEST("e is not rewritten even if allowed") { const char term[6] = {TERM_UNIQ, 3, 1, 'c', 1, 'e'}; vespalib::stringref stackDump(term, sizeof(term)); EXPECT_EQUAL(6u, stackDump.size()); - AllowRewrite empty; - Query q(empty, stackDump); + AllowRewrite allowRewrite; + Query q(allowRewrite, stackDump); EXPECT_TRUE(q.valid()); const QueryNode::LP & root = q.getRoot(); EXPECT_EQUAL(QueryTerm::classId, root->getClass().id()); @@ -250,7 +246,7 @@ TEST("1.0e is not rewritten by default") { const char term[9] = {TERM_UNIQ, 3, 1, 'c', 4, '1', '.', '0', 'e'}; vespalib::stringref stackDump(term, sizeof(term)); EXPECT_EQUAL(9u, stackDump.size()); - EmptyQueryNodeResult empty; + QueryNodeResultFactory empty; Query q(empty, stackDump); EXPECT_TRUE(q.valid()); const QueryNode::LP & root = q.getRoot(); @@ -321,7 +317,7 @@ TEST("testGetQueryParts") { Node::UP node = builder.build(); vespalib::string stackDump = StackDumpCreator::create(*node); - EmptyQueryNodeResult empty; + QueryNodeResultFactory empty; Query q(empty, stackDump); QueryTermList terms; QueryNodeRefList phrases; @@ -357,7 +353,7 @@ TEST("testPhraseEvaluate") { } Node::UP node = builder.build(); vespalib::string stackDump = StackDumpCreator::create(*node); - EmptyQueryNodeResult empty; + QueryNodeResultFactory empty; Query q(empty, stackDump); QueryNodeRefList phrases; q.getPhrases(phrases); @@ -546,8 +542,8 @@ TEST("require that ascending range can be specified with limit only") { double low_double = 0.0; double high_double = 0.0; - EmptyQueryNodeResult eqnr; - QueryTerm ascending_query(eqnr, "[;;500]", "index", QueryTerm::WORD); + QueryNodeResultFactory eqnr; + QueryTerm ascending_query(eqnr.create(), "[;;500]", "index", QueryTerm::WORD); EXPECT_TRUE(ascending_query.getAsIntegerTerm(low_integer, high_integer)); EXPECT_TRUE(ascending_query.getAsDoubleTerm(low_double, high_double)); @@ -564,8 +560,8 @@ TEST("require that descending range can be specified with limit only") { double low_double = 0.0; double high_double = 0.0; - EmptyQueryNodeResult eqnr; - QueryTerm descending_query(eqnr, "[;;-500]", "index", QueryTerm::WORD); + QueryNodeResultFactory eqnr; + QueryTerm descending_query(eqnr.create(), "[;;-500]", "index", QueryTerm::WORD); EXPECT_TRUE(descending_query.getAsIntegerTerm(low_integer, high_integer)); EXPECT_TRUE(descending_query.getAsDoubleTerm(low_double, high_double)); @@ -577,8 +573,8 @@ TEST("require that descending range can be specified with limit only") { } TEST("require that correctly specified diversity can be parsed") { - EmptyQueryNodeResult eqnr; - QueryTerm descending_query(eqnr, "[;;-500;ab56;78]", "index", QueryTerm::WORD); + QueryNodeResultFactory eqnr; + QueryTerm descending_query(eqnr.create(), "[;;-500;ab56;78]", "index", QueryTerm::WORD); EXPECT_TRUE(descending_query.isValid()); EXPECT_EQUAL(-500, descending_query.getRangeLimit()); EXPECT_EQUAL("ab56", descending_query.getDiversityAttribute()); @@ -588,8 +584,8 @@ TEST("require that correctly specified diversity can be parsed") { } TEST("require that correctly specified diversity with cutoff groups can be parsed") { - EmptyQueryNodeResult eqnr; - QueryTerm descending_query(eqnr, "[;;-500;ab56;78;93]", "index", QueryTerm::WORD); + QueryNodeResultFactory eqnr; + QueryTerm descending_query(eqnr.create(), "[;;-500;ab56;78;93]", "index", QueryTerm::WORD); EXPECT_TRUE(descending_query.isValid()); EXPECT_EQUAL(-500, descending_query.getRangeLimit()); EXPECT_EQUAL("ab56", descending_query.getDiversityAttribute()); @@ -599,8 +595,8 @@ TEST("require that correctly specified diversity with cutoff groups can be parse } TEST("require that correctly specified diversity with cutoff groups can be parsed") { - EmptyQueryNodeResult eqnr; - QueryTerm descending_query(eqnr, "[;;-500;ab56;78;13]", "index", QueryTerm::WORD); + QueryNodeResultFactory eqnr; + QueryTerm descending_query(eqnr.create(), "[;;-500;ab56;78;13]", "index", QueryTerm::WORD); EXPECT_TRUE(descending_query.isValid()); EXPECT_EQUAL(-500, descending_query.getRangeLimit()); EXPECT_EQUAL("ab56", descending_query.getDiversityAttribute()); @@ -610,8 +606,8 @@ TEST("require that correctly specified diversity with cutoff groups can be parse } TEST("require that correctly specified diversity with incorrect cutoff groups can be parsed") { - EmptyQueryNodeResult eqnr; - QueryTerm descending_query(eqnr, "[;;-500;ab56;78;a13.9]", "index", QueryTerm::WORD); + QueryNodeResultFactory eqnr; + QueryTerm descending_query(eqnr.create(), "[;;-500;ab56;78;a13.9]", "index", QueryTerm::WORD); EXPECT_TRUE(descending_query.isValid()); EXPECT_EQUAL(-500, descending_query.getRangeLimit()); EXPECT_EQUAL("ab56", descending_query.getDiversityAttribute()); @@ -621,8 +617,8 @@ TEST("require that correctly specified diversity with incorrect cutoff groups ca } TEST("require that correctly specified diversity with cutoff strategy can be parsed") { - EmptyQueryNodeResult eqnr; - QueryTerm descending_query(eqnr, "[;;-500;ab56;78;93;anything but strict]", "index", QueryTerm::WORD); + QueryNodeResultFactory eqnr; + QueryTerm descending_query(eqnr.create(), "[;;-500;ab56;78;93;anything but strict]", "index", QueryTerm::WORD); EXPECT_TRUE(descending_query.isValid()); EXPECT_EQUAL(-500, descending_query.getRangeLimit()); EXPECT_EQUAL("ab56", descending_query.getDiversityAttribute()); @@ -632,8 +628,8 @@ TEST("require that correctly specified diversity with cutoff strategy can be par } TEST("require that correctly specified diversity with strict cutoff strategy can be parsed") { - EmptyQueryNodeResult eqnr; - QueryTerm descending_query(eqnr, "[;;-500;ab56;78;93;strict]", "index", QueryTerm::WORD); + QueryNodeResultFactory eqnr; + QueryTerm descending_query(eqnr.create(), "[;;-500;ab56;78;93;strict]", "index", QueryTerm::WORD); EXPECT_TRUE(descending_query.isValid()); EXPECT_EQUAL(-500, descending_query.getRangeLimit()); EXPECT_EQUAL("ab56", descending_query.getDiversityAttribute()); @@ -643,8 +639,8 @@ TEST("require that correctly specified diversity with strict cutoff strategy can } TEST("require that incorrectly specified diversity can be parsed") { - EmptyQueryNodeResult eqnr; - QueryTerm descending_query(eqnr, "[;;-500;ab56]", "index", QueryTerm::WORD); + QueryNodeResultFactory eqnr; + QueryTerm descending_query(eqnr.create(), "[;;-500;ab56]", "index", QueryTerm::WORD); EXPECT_FALSE(descending_query.isValid()); } diff --git a/searchlib/src/vespa/searchlib/attribute/attributevector.cpp b/searchlib/src/vespa/searchlib/attribute/attributevector.cpp index 342ad4358ce..9e75ae89e2f 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributevector.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attributevector.cpp @@ -573,8 +573,8 @@ QueryTermSimple::UP AttributeVector::SearchContext::decodeQuery(QueryPacketT searchSpec) { QueryTermSimple::UP qt; - EmptyQueryNodeResult qnb; - Query q(qnb, searchSpec); + QueryNodeResultFactory factory; + Query q(factory, searchSpec); if (q.valid() && (dynamic_cast<QueryTerm *>(q.getRoot().get()))) { qt.reset(static_cast<QueryTerm *>(q.getRoot().release())); } else { diff --git a/searchlib/src/vespa/searchlib/query/query.cpp b/searchlib/src/vespa/searchlib/query/query.cpp index 1d3db75df62..13723fdcd1a 100644 --- a/searchlib/src/vespa/searchlib/query/query.cpp +++ b/searchlib/src/vespa/searchlib/query/query.cpp @@ -270,11 +270,11 @@ Query::Query() : _root() { } -Query::Query(const QueryNodeResultBase & org, const QueryPacketT & queryRep) : +Query::Query(const QueryNodeResultFactory & factory, const QueryPacketT & queryRep) : Identifiable(), _root() { - build(org, queryRep); + build(factory, queryRep); } void Query::visitMembers(vespalib::ObjectVisitor &visitor) const @@ -288,11 +288,11 @@ bool Query::evaluate() const return ok; } -bool Query::build(const QueryNodeResultBase & org, const QueryPacketT & queryRep) +bool Query::build(const QueryNodeResultFactory & factory, const QueryPacketT & queryRep) { search::SimpleQueryStackDumpIterator stack(queryRep); if (stack.next()) { - _root.reset(QueryNode::Build(NULL, org, stack, true).release()); + _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 50c4e4a2b4b..5da46d3b4b1 100644 --- a/searchlib/src/vespa/searchlib/query/query.h +++ b/searchlib/src/vespa/searchlib/query/query.h @@ -2,6 +2,7 @@ #pragma once #include "queryterm.h" +#include "base.h" #include <vespa/searchlib/parsequery/stackdumpiterator.h> namespace search @@ -186,10 +187,10 @@ class Query : public vespalib::Identifiable public: DECLARE_IDENTIFIABLE_NS(search, Query); Query(); - Query(const QueryNodeResultBase & org, const QueryPacketT & queryRep); + Query(const QueryNodeResultFactory & factory, const QueryPacketT & queryRep); virtual ~Query() { } /// Will build the query tree - bool build(const QueryNodeResultBase & org, const QueryPacketT & queryRep); + bool build(const QueryNodeResultFactory & factory, const QueryPacketT & queryRep); /// Will clear the results from the querytree. void reset(); /// Will get all leafnodes. diff --git a/searchlib/src/vespa/searchlib/query/querynode.cpp b/searchlib/src/vespa/searchlib/query/querynode.cpp index 3b9fbea64e1..b408c7acd5c 100644 --- a/searchlib/src/vespa/searchlib/query/querynode.cpp +++ b/searchlib/src/vespa/searchlib/query/querynode.cpp @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + #include "query.h" -#include "querynoderesultbase.h" -#include <vespa/searchlib/parsequery/stackdumpiterator.h> + #include <vespa/log/log.h> LOG_SETUP(".vsm.querynode"); @@ -32,7 +32,7 @@ namespace { } #define CASE(c, q) case c: { qn.reset(new q()); } break; -QueryNode::UP QueryNode::Build(const QueryNode * parent, const QueryNodeResultBase & org, search::SimpleQueryStackDumpIterator & queryRep, bool allowRewrite) +QueryNode::UP QueryNode::Build(const QueryNode * parent, const QueryNodeResultFactory & factory, search::SimpleQueryStackDumpIterator & queryRep, bool allowRewrite) { unsigned int arity = queryRep.getArity(); search::ParseItem::ItemType type = queryRep.getType(); @@ -69,9 +69,7 @@ QueryNode::UP QueryNode::Build(const QueryNode * parent, const QueryNodeResultBa if (qc->isFlattenable(queryRep.getType())) { arity += queryRep.getArity(); } else { - LP child(Build(qc, - org, - queryRep, + LP child(Build(qc, factory, queryRep, allowRewrite && ((dynamic_cast<NearQueryNode *> (qn.get()) == NULL) && (dynamic_cast<PhraseQueryNode *> (qn.get()) == NULL))).release()); qc->push_back(child); } @@ -125,16 +123,16 @@ QueryNode::UP QueryNode::Build(const QueryNode * parent, const QueryNodeResultBa // But it will do for now as only correct sddocname queries are sent down. qn.reset(new TrueNode()); } else { - std::unique_ptr<QueryTerm> qt(new QueryTerm(org, ssTerm, ssIndex, sTerm)); + std::unique_ptr<QueryTerm> qt(new QueryTerm(factory.create(), ssTerm, ssIndex, sTerm)); qt->setWeight(queryRep.GetWeight()); qt->setUniqueId(queryRep.getUniqueId()); - if ( qt->encoding().isBase10Integer() || ! qt->encoding().isFloat() || ! org.getRewriteFloatTerms() || !allowRewrite || (ssTerm.find('.') == vespalib::string::npos)) { + if ( qt->encoding().isBase10Integer() || ! qt->encoding().isFloat() || ! factory.getRewriteFloatTerms() || !allowRewrite || (ssTerm.find('.') == vespalib::string::npos)) { qn.reset(qt.release()); } else { std::unique_ptr<PhraseQueryNode> phrase(new PhraseQueryNode()); - phrase->push_back(LP(new QueryTerm(org, ssTerm.substr(0, ssTerm.find('.')), ssIndex, QueryTerm::WORD))); - phrase->push_back(LP(new QueryTerm(org, ssTerm.substr(ssTerm.find('.') + 1), ssIndex, QueryTerm::WORD))); + phrase->push_back(LP(new QueryTerm(factory.create(), ssTerm.substr(0, ssTerm.find('.')), ssIndex, QueryTerm::WORD))); + phrase->push_back(LP(new QueryTerm(factory.create(), ssTerm.substr(ssTerm.find('.') + 1), ssIndex, QueryTerm::WORD))); std::unique_ptr<EquivQueryNode> orqn(new EquivQueryNode()); orqn->push_back(LP(qt.release())); orqn->push_back(LP(phrase.release())); @@ -147,7 +145,7 @@ QueryNode::UP QueryNode::Build(const QueryNode * parent, const QueryNodeResultBa { if (arity >= 1) { queryRep.next(); - qn = Build(parent, org, queryRep, false); + qn = Build(parent, factory, queryRep, false); for (uint32_t skipCount = arity-1; (skipCount > 0) && queryRep.next(); skipCount--) { skipCount += queryRep.getArity(); } diff --git a/searchlib/src/vespa/searchlib/query/querynode.h b/searchlib/src/vespa/searchlib/query/querynode.h index 285fc3ed0ec..3989d593139 100644 --- a/searchlib/src/vespa/searchlib/query/querynode.h +++ b/searchlib/src/vespa/searchlib/query/querynode.h @@ -10,7 +10,7 @@ namespace search { class SimpleQueryStackDumpIterator; class QueryTerm; class QueryNode; -class QueryNodeResultBase; +class QueryNodeResultFactory; /// Typedef a simple list that contains references to QueryNodes. typedef std::vector<QueryNode *> QueryNodeRefList; @@ -55,7 +55,7 @@ class QueryNode : public vespalib::Identifiable virtual size_t depth() const { return 1; } /// Return the width of this tree. virtual size_t width() const { return 1; } - static UP Build(const QueryNode * parent, const QueryNodeResultBase & org, SimpleQueryStackDumpIterator & queryRep, bool allowRewrite); + static UP Build(const QueryNode * parent, const QueryNodeResultFactory & org, SimpleQueryStackDumpIterator & queryRep, bool allowRewrite); }; /// A list conating the QuerNode objects. With copy/assignment. diff --git a/searchlib/src/vespa/searchlib/query/querynoderesultbase.cpp b/searchlib/src/vespa/searchlib/query/querynoderesultbase.cpp index 48d056cce80..39055fa47fa 100644 --- a/searchlib/src/vespa/searchlib/query/querynoderesultbase.cpp +++ b/searchlib/src/vespa/searchlib/query/querynoderesultbase.cpp @@ -3,6 +3,4 @@ namespace search { -IMPLEMENT_DUPLICATE(EmptyQueryNodeResult); - } diff --git a/searchlib/src/vespa/searchlib/query/querynoderesultbase.h b/searchlib/src/vespa/searchlib/query/querynoderesultbase.h index 98d6e92d821..d52b32ff5ac 100644 --- a/searchlib/src/vespa/searchlib/query/querynoderesultbase.h +++ b/searchlib/src/vespa/searchlib/query/querynoderesultbase.h @@ -1,35 +1,27 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include "base.h" +#include <vespa/vespalib/objects/cloneable.h> -namespace search -{ +namespace search { /** This is the base of any item that can be attached to the leafs in a querytree. The intention is to put stuff here that are search specific. Fx to differentiate between streamed and indexed variants. */ -class QueryNodeResultBase : public Object +class QueryNodeResultBase : public vespalib::Cloneable { - public: - virtual bool evaluate() const = 0; - virtual void reset() = 0; - virtual bool getRewriteFloatTerms() const { return false; } +public: + virtual bool evaluate() const = 0; + virtual void reset() = 0; }; -class EmptyQueryNodeResult : public QueryNodeResultBase -{ - public: - DUPLICATE(EmptyQueryNodeResult); - virtual ~EmptyQueryNodeResult() { } - virtual bool evaluate() const { return true; } - virtual void reset() { } - private: +class QueryNodeResultFactory { +public: + virtual ~QueryNodeResultFactory() { } + virtual bool getRewriteFloatTerms() const { return false; } + virtual std::unique_ptr<QueryNodeResultBase> create() const { return std::unique_ptr<QueryNodeResultBase>(); } }; - - -typedef ObjectContainer<QueryNodeResultBase> QueryNodeResultBaseContainer; } diff --git a/searchlib/src/vespa/searchlib/query/queryterm.cpp b/searchlib/src/vespa/searchlib/query/queryterm.cpp index 527ee4d7e01..1a0e49ce769 100644 --- a/searchlib/src/vespa/searchlib/query/queryterm.cpp +++ b/searchlib/src/vespa/searchlib/query/queryterm.cpp @@ -1,10 +1,10 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "queryterm.h" +#include "base.h" #include <vespa/vespalib/objects/visit.h> #include <vespa/vespalib/text/utf8.h> #include <vespa/vespalib/util/classname.h> #include <cmath> -#include <limits> namespace { @@ -261,11 +261,11 @@ QueryTerm::visitMembers(vespalib::ObjectVisitor & visitor) const } -QueryTerm::QueryTerm(const QueryNodeResultBase & org, const string & termS, const string & indexS, SearchTerm type) : +QueryTerm::QueryTerm(std::unique_ptr<QueryNodeResultBase> org, const string & termS, const string & indexS, SearchTerm type) : QueryTermBase(termS, type), _index(indexS), _encoding(0x01), - _result(org), + _result(org.release()), _hitList(), _weight(100), _uniqueId(0), @@ -286,7 +286,7 @@ void QueryTerm::getLeafs(QueryTermList & tl) { tl.push_back(this void QueryTerm::getLeafs(ConstQueryTermList & tl) const { tl.push_back(this); } bool QueryTerm::evaluate() const { return !_hitList.empty() && _result->evaluate(); } void QueryTerm::reset() { _hitList.clear(); _result->reset(); } -const HitList & QueryTerm::evaluateHits(HitList & UNUSED_PARAM(hl)) const { return _hitList; } +const HitList & QueryTerm::evaluateHits(HitList &) const { return _hitList; } void QueryTerm::resizeFieldId(size_t fieldNo) { diff --git a/searchlib/src/vespa/searchlib/query/queryterm.h b/searchlib/src/vespa/searchlib/query/queryterm.h index afb851f7628..17d2bc64972 100644 --- a/searchlib/src/vespa/searchlib/query/queryterm.h +++ b/searchlib/src/vespa/searchlib/query/queryterm.h @@ -156,7 +156,7 @@ public: }; DECLARE_IDENTIFIABLE_NS(search, QueryTerm); QueryTerm(); - QueryTerm(const QueryNodeResultBase & org, const string & term, const string & index, SearchTerm type); + QueryTerm(std::unique_ptr<QueryNodeResultBase> resultBase, const string & term, const string & index, SearchTerm type); QueryTerm(const QueryTerm &) = default; QueryTerm & operator = (const QueryTerm &) = default; QueryTerm(QueryTerm &&) = default; @@ -184,13 +184,13 @@ public: const FieldInfo & getFieldInfo(size_t fid) const { return _fieldInfo[fid]; } FieldInfo & getFieldInfo(size_t fid) { return _fieldInfo[fid]; } size_t getFieldInfoSize() const { return _fieldInfo.size(); } - const QueryNodeResultBase & getQueryItem() const { return *_result; } QueryNodeResultBase & getQueryItem() { return *_result; } const HitList & getHitList() const { return _hitList; } virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; virtual void setIndex(const string & index_) { _index = index_; } virtual const string & getIndex() const { return _index; } protected: + using QueryNodeResultBaseContainer = vespalib::CloneablePtr<QueryNodeResultBase>; string _index; EncodingBitMap _encoding; QueryNodeResultBaseContainer _result; diff --git a/streamingvisitors/src/tests/querywrapper/querywrapper.cpp b/streamingvisitors/src/tests/querywrapper/querywrapper.cpp index 741ef31ca3a..46fb90a51e8 100644 --- a/streamingvisitors/src/tests/querywrapper/querywrapper.cpp +++ b/streamingvisitors/src/tests/querywrapper/querywrapper.cpp @@ -1,4 +1,5 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + #include <vespa/vespalib/testkit/testapp.h> #include <vespa/searchlib/query/tree/querybuilder.h> #include <vespa/searchlib/query/tree/simplequery.h> @@ -23,7 +24,7 @@ public: void QueryWrapperTest::testQueryWrapper() { - EmptyQueryNodeResult empty; + QueryNodeResultFactory empty; PhraseQueryNode * null = NULL; { QueryBuilder<SimpleQueryNodeTypes> builder; diff --git a/streamingvisitors/src/vespa/searchvisitor/querytermdata.cpp b/streamingvisitors/src/vespa/searchvisitor/querytermdata.cpp index 2cabc36ea96..0f40277bb86 100644 --- a/streamingvisitors/src/vespa/searchvisitor/querytermdata.cpp +++ b/streamingvisitors/src/vespa/searchvisitor/querytermdata.cpp @@ -6,7 +6,5 @@ using namespace search::fef; namespace storage { -IMPLEMENT_DUPLICATE(QueryTermData); - } // namespace storage diff --git a/streamingvisitors/src/vespa/searchvisitor/querytermdata.h b/streamingvisitors/src/vespa/searchvisitor/querytermdata.h index ef6d96e6e39..5f54146ede1 100644 --- a/streamingvisitors/src/vespa/searchvisitor/querytermdata.h +++ b/streamingvisitors/src/vespa/searchvisitor/querytermdata.h @@ -15,16 +15,21 @@ class QueryTermData : public search::QueryNodeResultBase { private: search::fef::SimpleTermData _termData; - public: - DUPLICATE(QueryTermData); // create duplicate function - - virtual bool evaluate() const { return true; } - virtual void reset() {} - virtual bool getRewriteFloatTerms() const { return true; } - + QueryTermData * clone() const override { return new QueryTermData(); } + bool evaluate() const override { return true; } + void reset() override { } search::fef::SimpleTermData &getTermData() { return _termData; } }; +class QueryTermDataFactory final : public search::QueryNodeResultFactory { +public: + std::unique_ptr<search::QueryNodeResultBase> create() const override { + return std::make_unique<QueryTermData>(); + } + bool getRewriteFloatTerms() const override { return true; } +}; + + } // namespace storage diff --git a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp index cf39afff088..c2bac2f6820 100644 --- a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp +++ b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp @@ -286,8 +286,8 @@ void SearchVisitor::init(const Parameters & params) Parameters::ValueRef queryBlob; if ( params.get("query", queryBlob) ) { LOG(spam, "Received query blob of %zd bytes", queryBlob.size()); - QueryTermData resultAddOn; - _query = search::Query(resultAddOn, search::QueryPacketT(queryBlob.data(), queryBlob.size())); + QueryTermDataFactory addOnFactory; + _query = search::Query(addOnFactory, search::QueryPacketT(queryBlob.data(), queryBlob.size())); LOG(debug, "Query tree: '%s'", _query.asString().c_str()); _searchBuffer->reserve(0x10000); diff --git a/vsm/src/tests/searcher/searcher.cpp b/vsm/src/tests/searcher/searcher.cpp index 5bb47b7d2ae..d1c1cd2060b 100644 --- a/vsm/src/tests/searcher/searcher.cpp +++ b/vsm/src/tests/searcher/searcher.cpp @@ -16,7 +16,7 @@ #include <vespa/document/fieldvalue/fieldvalues.h> using namespace document; -using search::EmptyQueryNodeResult; +using search::QueryNodeResultFactory; using search::QueryTerm; using search::QueryTermList; using namespace vsm; @@ -56,7 +56,7 @@ private: for (size_t i = 0; i < terms.size(); ++i) { ParsedQueryTerm pqt = parseQueryTerm(terms[i]); ParsedTerm pt = parseTerm(pqt.second); - qtv.push_back(QueryTerm(eqnr, pt.first, pqt.first.empty() ? "index" : pqt.first, pt.second)); + qtv.push_back(QueryTerm(eqnr.create(), pt.first, pqt.first.empty() ? "index" : pqt.first, pt.second)); } for (size_t i = 0; i < qtv.size(); ++i) { qtl.push_back(&qtv[i]); @@ -65,7 +65,7 @@ private: public: typedef std::pair<std::string, std::string> ParsedQueryTerm; typedef std::pair<std::string, QueryTerm::SearchTerm> ParsedTerm; - EmptyQueryNodeResult eqnr; + QueryNodeResultFactory eqnr; std::vector<QueryTerm> qtv; QueryTermList qtl; Query(const StringList & terms) : eqnr(), qtv(), qtl() { @@ -268,9 +268,9 @@ getFieldValue(const FloatList & fv) bool assertMatchTermSuffix(const std::string & term, const std::string & word) { - EmptyQueryNodeResult eqnr; - QueryTerm qa(eqnr, term, "index", QueryTerm::WORD); - QueryTerm qb(eqnr, word, "index", QueryTerm::WORD); + QueryNodeResultFactory eqnr; + QueryTerm qa(eqnr.create(), term, "index", QueryTerm::WORD); + QueryTerm qb(eqnr.create(), word, "index", QueryTerm::WORD); const ucs4_t * a; size_t alen = qa.term(a); const ucs4_t * b; |