diff options
author | Henning Baldersheim <balder@oath.com> | 2018-05-24 13:33:04 +0200 |
---|---|---|
committer | Henning Baldersheim <balder@oath.com> | 2018-05-25 08:49:35 +0200 |
commit | ab2a3c4409320a512fdbf9d87ad80b4577130e69 (patch) | |
tree | 8479af72c9855876c70eec6764db729591f07fd2 /searchlib | |
parent | 4d4c97a77dcabace7e47e7dbe112e382c6fae13f (diff) |
Add initial support for SameElement in backend too.
Diffstat (limited to 'searchlib')
41 files changed, 350 insertions, 374 deletions
diff --git a/searchlib/src/tests/query/customtypevisitor_test.cpp b/searchlib/src/tests/query/customtypevisitor_test.cpp index 5aabb328354..fac60cb0aaf 100644 --- a/searchlib/src/tests/query/customtypevisitor_test.cpp +++ b/searchlib/src/tests/query/customtypevisitor_test.cpp @@ -1,14 +1,14 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. // Unit tests for customtypevisitor. -#include <vespa/log/log.h> -LOG_SETUP("customtypevisitor_test"); - #include <vespa/searchlib/query/tree/customtypevisitor.h> #include <vespa/searchlib/query/tree/intermediatenodes.h> #include <vespa/searchlib/query/tree/termnodes.h> #include <vespa/vespalib/testkit/testapp.h> +#include <vespa/log/log.h> +LOG_SETUP("customtypevisitor_test"); + using std::string; using namespace search::query; @@ -39,6 +39,7 @@ struct MyNear : Near { MyNear() : Near(1) {} }; struct MyONear : ONear { MyONear() : ONear(1) {} }; struct MyOr : Or {}; struct MyPhrase : Phrase { MyPhrase() : Phrase("view", 0, Weight(42)) {} }; +struct MySameElement : SameElement { MySameElement() : SameElement("view", 0, Weight(42)) {} }; struct MyRank : Rank {}; struct MyNumberTerm : InitTerm<NumberTerm> {}; struct MyLocationTerm : InitTerm<LocationTerm> {}; @@ -64,6 +65,7 @@ struct MyQueryNodeTypes { typedef MyONear ONear; typedef MyOr Or; typedef MyPhrase Phrase; + typedef MySameElement SameElement; typedef MyPrefixTerm PrefixTerm; typedef MyRangeTerm RangeTerm; typedef MyRank Rank; @@ -89,27 +91,28 @@ public: template <typename T> void setVisited() { isVisited<T>() = true; } - virtual void visit(MyAnd &) override { setVisited<MyAnd>(); } - virtual void visit(MyAndNot &) override { setVisited<MyAndNot>(); } - virtual void visit(MyEquiv &) override { setVisited<MyEquiv>(); } - virtual void visit(MyNumberTerm &) override { setVisited<MyNumberTerm>(); } - virtual void visit(MyLocationTerm &) override { setVisited<MyLocationTerm>(); } - virtual void visit(MyNear &) override { setVisited<MyNear>(); } - virtual void visit(MyONear &) override { setVisited<MyONear>(); } - virtual void visit(MyOr &) override { setVisited<MyOr>(); } - virtual void visit(MyPhrase &) override { setVisited<MyPhrase>(); } - virtual void visit(MyPrefixTerm &) override { setVisited<MyPrefixTerm>(); } - virtual void visit(MyRangeTerm &) override { setVisited<MyRangeTerm>(); } - virtual void visit(MyRank &) override { setVisited<MyRank>(); } - virtual void visit(MyStringTerm &) override { setVisited<MyStringTerm>(); } - virtual void visit(MySubstrTerm &) override { setVisited<MySubstrTerm>(); } - virtual void visit(MySuffixTerm &) override { setVisited<MySuffixTerm>(); } - virtual void visit(MyWeakAnd &) override { setVisited<MyWeakAnd>(); } - virtual void visit(MyWeightedSetTerm &) override { setVisited<MyWeightedSetTerm>(); } - virtual void visit(MyDotProduct &) override { setVisited<MyDotProduct>(); } - virtual void visit(MyWandTerm &) override { setVisited<MyWandTerm>(); } - virtual void visit(MyPredicateQuery &) override { setVisited<MyPredicateQuery>(); } - virtual void visit(MyRegExpTerm &) override { setVisited<MyRegExpTerm>(); } + void visit(MyAnd &) override { setVisited<MyAnd>(); } + void visit(MyAndNot &) override { setVisited<MyAndNot>(); } + void visit(MyEquiv &) override { setVisited<MyEquiv>(); } + void visit(MyNumberTerm &) override { setVisited<MyNumberTerm>(); } + void visit(MyLocationTerm &) override { setVisited<MyLocationTerm>(); } + void visit(MyNear &) override { setVisited<MyNear>(); } + void visit(MyONear &) override { setVisited<MyONear>(); } + void visit(MyOr &) override { setVisited<MyOr>(); } + void visit(MyPhrase &) override { setVisited<MyPhrase>(); } + void visit(MySameElement &) override { setVisited<MySameElement>(); } + void visit(MyPrefixTerm &) override { setVisited<MyPrefixTerm>(); } + void visit(MyRangeTerm &) override { setVisited<MyRangeTerm>(); } + void visit(MyRank &) override { setVisited<MyRank>(); } + void visit(MyStringTerm &) override { setVisited<MyStringTerm>(); } + void visit(MySubstrTerm &) override { setVisited<MySubstrTerm>(); } + void visit(MySuffixTerm &) override { setVisited<MySuffixTerm>(); } + void visit(MyWeakAnd &) override { setVisited<MyWeakAnd>(); } + void visit(MyWeightedSetTerm &) override { setVisited<MyWeightedSetTerm>(); } + void visit(MyDotProduct &) override { setVisited<MyDotProduct>(); } + void visit(MyWandTerm &) override { setVisited<MyWandTerm>(); } + void visit(MyPredicateQuery &) override { setVisited<MyPredicateQuery>(); } + void visit(MyRegExpTerm &) override { setVisited<MyRegExpTerm>(); } }; template <class T> diff --git a/searchlib/src/tests/query/query_visitor_test.cpp b/searchlib/src/tests/query/query_visitor_test.cpp index 9e82c6ea5ec..7135f69ec09 100644 --- a/searchlib/src/tests/query/query_visitor_test.cpp +++ b/searchlib/src/tests/query/query_visitor_test.cpp @@ -1,9 +1,6 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. // Unit tests for query_visitor. -#include <vespa/log/log.h> -LOG_SETUP("query_visitor_test"); - #include <vespa/searchlib/query/tree/intermediatenodes.h> #include <vespa/searchlib/query/tree/point.h> #include <vespa/searchlib/query/tree/queryvisitor.h> @@ -11,6 +8,9 @@ LOG_SETUP("query_visitor_test"); #include <vespa/searchlib/query/tree/termnodes.h> #include <vespa/vespalib/testkit/testapp.h> +#include <vespa/log/log.h> +LOG_SETUP("query_visitor_test"); + using namespace search::query; namespace { @@ -43,29 +43,28 @@ public: return b; } - virtual void visit(And &) override { isVisited<And>() = true; } - virtual void visit(AndNot &) override { isVisited<AndNot>() = true; } - virtual void visit(Equiv &) override { isVisited<Equiv>() = true; } - virtual void visit(NumberTerm &) override { isVisited<NumberTerm>() = true; } - virtual void visit(LocationTerm &) override { isVisited<LocationTerm>() = true; } - virtual void visit(Near &) override { isVisited<Near>() = true; } - virtual void visit(ONear &) override { isVisited<ONear>() = true; } - virtual void visit(Or &) override { isVisited<Or>() = true; } - virtual void visit(Phrase &) override { isVisited<Phrase>() = true; } - virtual void visit(PrefixTerm &) override { isVisited<PrefixTerm>() = true; } - virtual void visit(RangeTerm &) override { isVisited<RangeTerm>() = true; } - virtual void visit(Rank &) override { isVisited<Rank>() = true; } - virtual void visit(StringTerm &) override { isVisited<StringTerm>() = true; } - virtual void visit(SubstringTerm &) override { isVisited<SubstringTerm>() = true; } - virtual void visit(SuffixTerm &) override { isVisited<SuffixTerm>() = true; } - virtual void visit(WeakAnd &) override { isVisited<WeakAnd>() = true; } - virtual void visit(WeightedSetTerm &) override - { isVisited<WeightedSetTerm>() = true; } - virtual void visit(DotProduct &) override { isVisited<DotProduct>() = true; } - virtual void visit(WandTerm &) override { isVisited<WandTerm>() = true; } - virtual void visit(PredicateQuery &) override - { isVisited<PredicateQuery>() = true; } - virtual void visit(RegExpTerm &) override { isVisited<RegExpTerm>() = true; } + void visit(And &) override { isVisited<And>() = true; } + void visit(AndNot &) override { isVisited<AndNot>() = true; } + void visit(Equiv &) override { isVisited<Equiv>() = true; } + void visit(NumberTerm &) override { isVisited<NumberTerm>() = true; } + void visit(LocationTerm &) override { isVisited<LocationTerm>() = true; } + void visit(Near &) override { isVisited<Near>() = true; } + void visit(ONear &) override { isVisited<ONear>() = true; } + void visit(Or &) override { isVisited<Or>() = true; } + void visit(Phrase &) override { isVisited<Phrase>() = true; } + void visit(SameElement &) override { isVisited<SameElement>() = true; } + void visit(PrefixTerm &) override { isVisited<PrefixTerm>() = true; } + void visit(RangeTerm &) override { isVisited<RangeTerm>() = true; } + void visit(Rank &) override { isVisited<Rank>() = true; } + void visit(StringTerm &) override { isVisited<StringTerm>() = true; } + void visit(SubstringTerm &) override { isVisited<SubstringTerm>() = true; } + void visit(SuffixTerm &) override { isVisited<SuffixTerm>() = true; } + void visit(WeakAnd &) override { isVisited<WeakAnd>() = true; } + void visit(WeightedSetTerm &) override { isVisited<WeightedSetTerm>() = true; } + void visit(DotProduct &) override { isVisited<DotProduct>() = true; } + void visit(WandTerm &) override { isVisited<WandTerm>() = true; } + void visit(PredicateQuery &) override { isVisited<PredicateQuery>() = true; } + void visit(RegExpTerm &) override { isVisited<RegExpTerm>() = true; } }; template <class T> @@ -84,27 +83,20 @@ void Test::requireThatAllNodesCanBeVisited() { checkVisit<ONear>(new SimpleONear(0)); checkVisit<Or>(new SimpleOr); checkVisit<Phrase>(new SimplePhrase("field", 0, Weight(42))); - checkVisit<WeightedSetTerm>( - new SimpleWeightedSetTerm("field", 0, Weight(42))); + checkVisit<SameElement>(new SimpleSameElement("field", 0, Weight(42))); + checkVisit<WeightedSetTerm>(new SimpleWeightedSetTerm("field", 0, Weight(42))); checkVisit<DotProduct>(new SimpleDotProduct("field", 0, Weight(42))); - checkVisit<WandTerm>( - new SimpleWandTerm("field", 0, Weight(42), 57, 67, 77.7)); + checkVisit<WandTerm>(new SimpleWandTerm("field", 0, Weight(42), 57, 67, 77.7)); checkVisit<Rank>(new SimpleRank); - checkVisit<NumberTerm>( - new SimpleNumberTerm("0.42", "field", 0, Weight(0))); + checkVisit<NumberTerm>(new SimpleNumberTerm("0.42", "field", 0, Weight(0))); const Location location(Point(10, 10), 20, 0); - checkVisit<LocationTerm>( - new SimpleLocationTerm(location, "field", 0, Weight(0))); + checkVisit<LocationTerm>(new SimpleLocationTerm(location, "field", 0, Weight(0))); checkVisit<PrefixTerm>(new SimplePrefixTerm("t", "field", 0, Weight(0))); - checkVisit<RangeTerm>( - new SimpleRangeTerm(Range(0, 1), "field", 0, Weight(0))); + checkVisit<RangeTerm>(new SimpleRangeTerm(Range(0, 1), "field", 0, Weight(0))); checkVisit<StringTerm>(new SimpleStringTerm("t", "field", 0, Weight(0))); - checkVisit<SubstringTerm>( - new SimpleSubstringTerm("t", "field", 0, Weight(0))); + checkVisit<SubstringTerm>(new SimpleSubstringTerm("t", "field", 0, Weight(0))); checkVisit<SuffixTerm>(new SimpleSuffixTerm("t", "field", 0, Weight(0))); - checkVisit<PredicateQuery>( - new SimplePredicateQuery(PredicateQueryTerm::UP(), - "field", 0, Weight(0))); + checkVisit<PredicateQuery>(new SimplePredicateQuery(PredicateQueryTerm::UP(), "field", 0, Weight(0))); checkVisit<RegExpTerm>(new SimpleRegExpTerm("t", "field", 0, Weight(0))); } diff --git a/searchlib/src/tests/query/querybuilder_test.cpp b/searchlib/src/tests/query/querybuilder_test.cpp index b968f794833..9f32fd58d82 100644 --- a/searchlib/src/tests/query/querybuilder_test.cpp +++ b/searchlib/src/tests/query/querybuilder_test.cpp @@ -333,9 +333,9 @@ struct MyNear : Near { MyNear(size_t dist) : Near(dist) {} }; struct MyONear : ONear { MyONear(size_t dist) : ONear(dist) {} }; struct MyWeakAnd : WeakAnd { MyWeakAnd(uint32_t minHits, const vespalib::string & v) : WeakAnd(minHits, v) {} }; struct MyOr : Or {}; -struct MyPhrase : Phrase { - MyPhrase(const string &f, int32_t i, Weight w) : Phrase(f, i, w) {} -}; +struct MyPhrase : Phrase { MyPhrase(const string &f, int32_t i, Weight w) : Phrase(f, i, w) {}}; +struct MySameElement : SameElement { MySameElement(const string &f, int32_t i, Weight w) : SameElement(f, i, w) {}}; + struct MyWeightedSetTerm : WeightedSetTerm { MyWeightedSetTerm(const string &f, int32_t i, Weight w) : WeightedSetTerm(f, i, w) {} }; @@ -404,6 +404,7 @@ struct MyQueryNodeTypes { typedef MyONear ONear; typedef MyOr Or; typedef MyPhrase Phrase; + typedef MySameElement SameElement; typedef MyPrefixTerm PrefixTerm; typedef MyRangeTerm RangeTerm; typedef MyRank Rank; diff --git a/searchlib/src/tests/stackdumpiterator/stackdumpiteratortest.cpp b/searchlib/src/tests/stackdumpiterator/stackdumpiteratortest.cpp index d3a99dc439a..8ad4578b6c1 100644 --- a/searchlib/src/tests/stackdumpiterator/stackdumpiteratortest.cpp +++ b/searchlib/src/tests/stackdumpiterator/stackdumpiteratortest.cpp @@ -244,6 +244,7 @@ StackDumpIteratorTest::RunTest(int testno, bool verify) stack.Push(new search::ParseItem(search::ParseItem::ITEM_NUMTERM, "foo", "[0;22]")); stack.Push(new search::ParseItem(search::ParseItem::ITEM_PREFIXTERM, "bar", "baz")); stack.Push(new search::ParseItem(search::ParseItem::ITEM_PHRASE, 3, "bar")); + stack.Push(new search::ParseItem(search::ParseItem::ITEM_SAME_ELEMENT, 3, "bar")); stack.Push(new search::ParseItem(search::ParseItem::ITEM_OR, 2)); stack.Push(new search::ParseItem(search::ParseItem::ITEM_AND, 3)); stack.Push(new search::ParseItem(search::ParseItem::ITEM_RANK, 5)); diff --git a/searchlib/src/vespa/searchlib/parsequery/parse.cpp b/searchlib/src/vespa/searchlib/parsequery/parse.cpp index b189331878c..ec8d80bd4e6 100644 --- a/searchlib/src/vespa/searchlib/parsequery/parse.cpp +++ b/searchlib/src/vespa/searchlib/parsequery/parse.cpp @@ -24,9 +24,8 @@ namespace search { ParseItem::ParseItem(ItemType type, int arity) : PARSEITEM_DEFAULT_CONSTRUCTOR_LIST { - assert(type==ITEM_OR || type==ITEM_WEAK_AND || type==ITEM_EQUIV || - type==ITEM_AND || type==ITEM_NOT || type==ITEM_RANK || - type==ITEM_PHRASE || type==ITEM_ANY || type==ITEM_NEAR || type==ITEM_ONEAR); + assert(type==ITEM_OR || type==ITEM_WEAK_AND || type==ITEM_EQUIV || type==ITEM_AND || type==ITEM_NOT + || type==ITEM_RANK || type==ITEM_ANY || type==ITEM_NEAR || type==ITEM_ONEAR); SetType(type); _arity = arity; } @@ -34,7 +33,8 @@ ParseItem::ParseItem(ItemType type, int arity) ParseItem::ParseItem(ItemType type, int arity, const char *idx) : PARSEITEM_DEFAULT_CONSTRUCTOR_LIST { - assert(type == ITEM_PHRASE || type==ITEM_WEIGHTED_SET || type==ITEM_DOT_PRODUCT || type==ITEM_WAND); + assert(type==ITEM_PHRASE || type==ITEM_SAME_ELEMENT || type==ITEM_WEIGHTED_SET + || type==ITEM_DOT_PRODUCT || type==ITEM_WAND); SetType(type); _arity = arity; SetIndex(idx); @@ -124,6 +124,7 @@ ParseItem::AppendBuffer(RawBuf *buf) const case ITEM_DOT_PRODUCT: case ITEM_WAND: case ITEM_PHRASE: + case ITEM_SAME_ELEMENT: buf->appendCompressedPositiveNumber(_arity); buf->appendCompressedPositiveNumber(indexLen); if (indexLen != 0) { @@ -197,6 +198,7 @@ ParseItem::GetBufferLen() const case ITEM_WEIGHTED_SET: case ITEM_DOT_PRODUCT: case ITEM_PHRASE: + case ITEM_SAME_ELEMENT: len += sizeof(uint32_t) * 2 + indexLen; break; case ITEM_WAND: diff --git a/searchlib/src/vespa/searchlib/parsequery/parse.h b/searchlib/src/vespa/searchlib/parsequery/parse.h index 3d5a1a5e2bb..d8cbdc696a5 100644 --- a/searchlib/src/vespa/searchlib/parsequery/parse.h +++ b/searchlib/src/vespa/searchlib/parsequery/parse.h @@ -52,7 +52,7 @@ public: ITEM_WEIGHTED_SET = 15, ITEM_WEAK_AND = 16, ITEM_EXACTSTRINGTERM = 17, - UNUSED_LEGACY_ITEM_RISE_QUERY = 18, + ITEM_SAME_ELEMENT = 18, ITEM_PURE_WEIGHTED_STRING = 19, ITEM_PURE_WEIGHTED_LONG = 20, ITEM_DOT_PRODUCT = 21, diff --git a/searchlib/src/vespa/searchlib/parsequery/simplequerystack.cpp b/searchlib/src/vespa/searchlib/parsequery/simplequerystack.cpp index a7b41476ec6..cf8f176a1a0 100644 --- a/searchlib/src/vespa/searchlib/parsequery/simplequerystack.cpp +++ b/searchlib/src/vespa/searchlib/parsequery/simplequerystack.cpp @@ -25,12 +25,12 @@ SimpleQueryStack::~SimpleQueryStack() } void -SimpleQueryStack::Push(search::ParseItem *item) +SimpleQueryStack::Push(ParseItem *item) { // Check if query OK for FirstPage _FP_queryOK &= - ( item->Type() != search::ParseItem::ITEM_UNDEF - && item->Type() != search::ParseItem::ITEM_PAREN + ( item->Type() != ParseItem::ITEM_UNDEF + && item->Type() != ParseItem::ITEM_PAREN ); @@ -40,10 +40,10 @@ SimpleQueryStack::Push(search::ParseItem *item) _numItems++; } -search::ParseItem * +ParseItem * SimpleQueryStack::Pop() { - search::ParseItem *item = _stack; + ParseItem *item = _stack; if (_stack != NULL) { _numItems--; _stack = _stack->_next; @@ -53,9 +53,9 @@ SimpleQueryStack::Pop() } void -SimpleQueryStack::AppendBuffer(search::RawBuf *buf) const +SimpleQueryStack::AppendBuffer(RawBuf *buf) const { - for (search::ParseItem *item = _stack; item != NULL; item = item->_next) { + for (ParseItem *item = _stack; item != NULL; item = item->_next) { item->AppendBuffer(buf); } } @@ -66,7 +66,7 @@ SimpleQueryStack::GetBufferLen() const size_t result; result = 0; - for (const search::ParseItem *item = _stack; + for (const ParseItem *item = _stack; item != NULL; item = item->_next) { result += item->GetBufferLen(); } @@ -90,34 +90,35 @@ class ItemName { public: ItemName() { memset(_name, 'X', sizeof(_name)); - _name[search::ParseItem::ITEM_OR] = '|'; - _name[search::ParseItem::ITEM_WEAK_AND] = 'w'; - _name[search::ParseItem::ITEM_EQUIV] = 'E'; - _name[search::ParseItem::ITEM_AND] = '&'; - _name[search::ParseItem::ITEM_NOT] = '-'; - _name[search::ParseItem::ITEM_ANY] = '?'; - _name[search::ParseItem::ITEM_RANK] = '%'; - _name[search::ParseItem::ITEM_NEAR] = 'N'; - _name[search::ParseItem::ITEM_ONEAR] = 'O'; - _name[search::ParseItem::ITEM_NUMTERM] = '#'; - _name[search::ParseItem::ITEM_TERM] = 't'; - _name[search::ParseItem::ITEM_PURE_WEIGHTED_STRING] = 'T'; - _name[search::ParseItem::ITEM_PURE_WEIGHTED_LONG] = 'L'; - _name[search::ParseItem::ITEM_PREFIXTERM] = '*'; - _name[search::ParseItem::ITEM_SUBSTRINGTERM] = 's'; - _name[search::ParseItem::ITEM_EXACTSTRINGTERM] = 'e'; - _name[search::ParseItem::ITEM_SUFFIXTERM] = 'S'; - _name[search::ParseItem::ITEM_PHRASE] = '"'; - _name[search::ParseItem::ITEM_WEIGHTED_SET] = 'W'; - _name[search::ParseItem::ITEM_DOT_PRODUCT] = 'D'; - _name[search::ParseItem::ITEM_WAND] = 'A'; - _name[search::ParseItem::ITEM_PREDICATE_QUERY] = 'P'; - _name[search::ParseItem::ITEM_REGEXP] = '^'; + _name[ParseItem::ITEM_OR] = '|'; + _name[ParseItem::ITEM_WEAK_AND] = 'w'; + _name[ParseItem::ITEM_EQUIV] = 'E'; + _name[ParseItem::ITEM_AND] = '&'; + _name[ParseItem::ITEM_NOT] = '-'; + _name[ParseItem::ITEM_ANY] = '?'; + _name[ParseItem::ITEM_RANK] = '%'; + _name[ParseItem::ITEM_NEAR] = 'N'; + _name[ParseItem::ITEM_ONEAR] = 'O'; + _name[ParseItem::ITEM_NUMTERM] = '#'; + _name[ParseItem::ITEM_TERM] = 't'; + _name[ParseItem::ITEM_PURE_WEIGHTED_STRING] = 'T'; + _name[ParseItem::ITEM_PURE_WEIGHTED_LONG] = 'L'; + _name[ParseItem::ITEM_PREFIXTERM] = '*'; + _name[ParseItem::ITEM_SUBSTRINGTERM] = 's'; + _name[ParseItem::ITEM_EXACTSTRINGTERM] = 'e'; + _name[ParseItem::ITEM_SUFFIXTERM] = 'S'; + _name[ParseItem::ITEM_PHRASE] = '"'; + _name[ParseItem::ITEM_SAME_ELEMENT] = 'M'; + _name[ParseItem::ITEM_WEIGHTED_SET] = 'W'; + _name[ParseItem::ITEM_DOT_PRODUCT] = 'D'; + _name[ParseItem::ITEM_WAND] = 'A'; + _name[ParseItem::ITEM_PREDICATE_QUERY] = 'P'; + _name[ParseItem::ITEM_REGEXP] = '^'; } - char operator[] (search::ParseItem::ItemType i) const { return _name[i]; } + char operator[] (ParseItem::ItemType i) const { return _name[i]; } char operator[] (size_t i) const { return _name[i]; } private: - char _name[search::ParseItem::ITEM_MAX]; + char _name[ParseItem::ITEM_MAX]; }; static ItemName _G_ItemName; @@ -162,29 +163,29 @@ SimpleQueryStack::StackbufToString(const vespalib::stringref &theBuf) while (p < ep) { vespalib::string metaStr; rawtype = *p++; - type = search::ParseItem::GetType(rawtype); - if (search::ParseItem::GetFeature_Weight(rawtype)) { + type = ParseItem::GetType(rawtype); + if (ParseItem::GetFeature_Weight(rawtype)) { int64_t tmpLong(0); p += vespalib::compress::Integer::decompress(tmpLong, p); metaStr.append("(w:"); metaStr.append(make_string("%ld", tmpLong)); metaStr.append(")"); } - if (search::ParseItem::getFeature_UniqueId(rawtype)) { + if (ParseItem::getFeature_UniqueId(rawtype)) { p += vespalib::compress::Integer::decompressPositive(tmp, p); metaStr.append("(u:"); metaStr.append(make_string("%ld", tmp)); metaStr.append(")"); } - if (search::ParseItem::getFeature_Flags(rawtype)) { + if (ParseItem::getFeature_Flags(rawtype)) { flags = *p++; metaStr.append("(f:"); metaStr.append(make_string("%d", flags)); metaStr.append(")"); } - if (search::ParseItem::GetCreator(flags) != search::ParseItem::CREA_ORIG) { + if (ParseItem::GetCreator(flags) != ParseItem::CREA_ORIG) { metaStr.append("(c:"); - metaStr.append(make_string("%d", search::ParseItem::GetCreator(flags))); + metaStr.append(make_string("%d", ParseItem::GetCreator(flags))); metaStr.append(")"); } @@ -192,24 +193,24 @@ SimpleQueryStack::StackbufToString(const vespalib::stringref &theBuf) result.append(metaStr); switch (type) { - case search::ParseItem::ITEM_OR: - case search::ParseItem::ITEM_AND: - case search::ParseItem::ITEM_EQUIV: - case search::ParseItem::ITEM_NOT: - case search::ParseItem::ITEM_RANK: - case search::ParseItem::ITEM_ANY: + case ParseItem::ITEM_OR: + case ParseItem::ITEM_AND: + case ParseItem::ITEM_EQUIV: + case ParseItem::ITEM_NOT: + case ParseItem::ITEM_RANK: + case ParseItem::ITEM_ANY: p += vespalib::compress::Integer::decompressPositive(tmp, p); arity = tmp; result.append(make_string("%c/%d~", _G_ItemName[type], arity)); break; - case search::ParseItem::ITEM_WEAK_AND: - case search::ParseItem::ITEM_NEAR: - case search::ParseItem::ITEM_ONEAR: + case ParseItem::ITEM_WEAK_AND: + case ParseItem::ITEM_NEAR: + case ParseItem::ITEM_ONEAR: p += vespalib::compress::Integer::decompressPositive(tmp, p); arity = tmp; p += vespalib::compress::Integer::decompressPositive(tmp, p); arg1 = tmp; - if (type == search::ParseItem::ITEM_WEAK_AND) { + if (type == ParseItem::ITEM_WEAK_AND) { p += vespalib::compress::Integer::decompressPositive(tmp, p); idxRefLen = tmp; idxRef = p; @@ -220,13 +221,13 @@ SimpleQueryStack::StackbufToString(const vespalib::stringref &theBuf) } break; - case search::ParseItem::ITEM_NUMTERM: - case search::ParseItem::ITEM_TERM: - case search::ParseItem::ITEM_PREFIXTERM: - case search::ParseItem::ITEM_SUBSTRINGTERM: - case search::ParseItem::ITEM_EXACTSTRINGTERM: - case search::ParseItem::ITEM_SUFFIXTERM: - case search::ParseItem::ITEM_REGEXP: + case ParseItem::ITEM_NUMTERM: + case ParseItem::ITEM_TERM: + case ParseItem::ITEM_PREFIXTERM: + case ParseItem::ITEM_SUBSTRINGTERM: + case ParseItem::ITEM_EXACTSTRINGTERM: + case ParseItem::ITEM_SUFFIXTERM: + case ParseItem::ITEM_REGEXP: p += vespalib::compress::Integer::decompressPositive(tmp, p); idxRefLen = tmp; idxRef = p; @@ -239,7 +240,7 @@ SimpleQueryStack::StackbufToString(const vespalib::stringref &theBuf) idxRefLen, idxRefLen, idxRef, termRefLen, termRefLen, termRef)); break; - case search::ParseItem::ITEM_PURE_WEIGHTED_STRING: + case ParseItem::ITEM_PURE_WEIGHTED_STRING: p += vespalib::compress::Integer::decompressPositive(tmp, p); termRefLen = tmp; termRef = p; @@ -248,23 +249,24 @@ SimpleQueryStack::StackbufToString(const vespalib::stringref &theBuf) termRefLen, termRefLen, termRef)); break; - case search::ParseItem::ITEM_PURE_WEIGHTED_LONG: + case ParseItem::ITEM_PURE_WEIGHTED_LONG: tmp = vespalib::nbo::n2h(*reinterpret_cast<const uint64_t *>(p)); p += sizeof(uint64_t); result.append(make_string("%c/%lu", _G_ItemName[type], tmp)); break; - case search::ParseItem::ITEM_PHRASE: - case search::ParseItem::ITEM_WEIGHTED_SET: - case search::ParseItem::ITEM_DOT_PRODUCT: - case search::ParseItem::ITEM_WAND: + case ParseItem::ITEM_PHRASE: + case ParseItem::ITEM_SAME_ELEMENT: + case ParseItem::ITEM_WEIGHTED_SET: + case ParseItem::ITEM_DOT_PRODUCT: + case ParseItem::ITEM_WAND: p += vespalib::compress::Integer::decompressPositive(tmp, p); arity = tmp; p += vespalib::compress::Integer::decompressPositive(tmp, p); idxRefLen = tmp; idxRef = p; p += idxRefLen; - if (type == search::ParseItem::ITEM_WAND) { + if (type == ParseItem::ITEM_WAND) { p += vespalib::compress::Integer::decompressPositive(tmp, p); uint32_t targetNumHits = tmp; double scoreThreshold = vespalib::nbo::n2h(*reinterpret_cast<const double *>(p)); @@ -279,7 +281,7 @@ SimpleQueryStack::StackbufToString(const vespalib::stringref &theBuf) } break; - case search::ParseItem::ITEM_PREDICATE_QUERY: + case ParseItem::ITEM_PREDICATE_QUERY: { idxRefLen = static_cast<uint32_t>(ReadCompressedPositiveInt(p)); idxRef = p; diff --git a/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp b/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp index ec34b2d3a84..829b043fa02 100644 --- a/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp +++ b/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp @@ -250,6 +250,7 @@ SimpleQueryStackDumpIterator::next() case ParseItem::ITEM_DOT_PRODUCT: case ParseItem::ITEM_WAND: case ParseItem::ITEM_PHRASE: + case ParseItem::ITEM_SAME_ELEMENT: p += vespalib::compress::Integer::decompressPositive(tmp, p); _currArity = tmp; if (p > _bufEnd) return false; diff --git a/searchlib/src/vespa/searchlib/query/query.cpp b/searchlib/src/vespa/searchlib/query/query.cpp index d380c273d02..cdce017e5fe 100644 --- a/searchlib/src/vespa/searchlib/query/query.cpp +++ b/searchlib/src/vespa/searchlib/query/query.cpp @@ -102,10 +102,11 @@ QueryConnector::create(ParseItem::ItemType type) 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 PhraseQueryNode(); // 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 NULL; + return nullptr; } } diff --git a/searchlib/src/vespa/searchlib/query/querynode.cpp b/searchlib/src/vespa/searchlib/query/querynode.cpp index 2e9d8be95f4..0d0a06de7af 100644 --- a/searchlib/src/vespa/searchlib/query/querynode.cpp +++ b/searchlib/src/vespa/searchlib/query/querynode.cpp @@ -26,6 +26,7 @@ QueryNode::UP QueryNode::Build(const QueryNode * parent, const QueryNodeResultFa 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: { diff --git a/searchlib/src/vespa/searchlib/query/tree/customtypetermvisitor.h b/searchlib/src/vespa/searchlib/query/tree/customtypetermvisitor.h index 72763839b95..5b69001573e 100644 --- a/searchlib/src/vespa/searchlib/query/tree/customtypetermvisitor.h +++ b/searchlib/src/vespa/searchlib/query/tree/customtypetermvisitor.h @@ -5,8 +5,7 @@ #include "customtypevisitor.h" #include "intermediate.h" -namespace search { -namespace query { +namespace search::query { template <class NodeTypes> class CustomTypeTermVisitor : public CustomTypeVisitor<NodeTypes> @@ -32,5 +31,4 @@ private: // should be handled that way. }; -} // namespace query -} // namespace search +} diff --git a/searchlib/src/vespa/searchlib/query/tree/customtypevisitor.h b/searchlib/src/vespa/searchlib/query/tree/customtypevisitor.h index 83e6343e223..cdeebcaf9e5 100644 --- a/searchlib/src/vespa/searchlib/query/tree/customtypevisitor.h +++ b/searchlib/src/vespa/searchlib/query/tree/customtypevisitor.h @@ -4,8 +4,7 @@ #include "queryvisitor.h" -namespace search { -namespace query { +namespace search::query { /** * By typedefing a (complete) set of subclasses to the query nodes in @@ -37,6 +36,7 @@ public: virtual void visit(typename NodeTypes::ONear &) = 0; virtual void visit(typename NodeTypes::Or &) = 0; virtual void visit(typename NodeTypes::Phrase &) = 0; + virtual void visit(typename NodeTypes::SameElement &) = 0; virtual void visit(typename NodeTypes::PrefixTerm &) = 0; virtual void visit(typename NodeTypes::RangeTerm &) = 0; virtual void visit(typename NodeTypes::Rank &) = 0; @@ -62,6 +62,7 @@ private: typedef typename NodeTypes::ONear TONear; typedef typename NodeTypes::Or TOr; typedef typename NodeTypes::Phrase TPhrase; + typedef typename NodeTypes::SameElement TSameElement; typedef typename NodeTypes::PrefixTerm TPrefixTerm; typedef typename NodeTypes::RangeTerm TRangeTerm; typedef typename NodeTypes::Rank TRank; @@ -84,6 +85,7 @@ private: void visit(ONear &n) override { visit(static_cast<TONear&>(n)); } void visit(Or &n) override { visit(static_cast<TOr&>(n)); } void visit(Phrase &n) override { visit(static_cast<TPhrase&>(n)); } + void visit(SameElement &n) override { visit(static_cast<TSameElement &>(n)); } void visit(PrefixTerm &n) override { visit(static_cast<TPrefixTerm&>(n)); } void visit(RangeTerm &n) override { visit(static_cast<TRangeTerm&>(n)); } void visit(Rank &n) override { visit(static_cast<TRank&>(n)); } @@ -98,5 +100,4 @@ private: void visit(RegExpTerm &n) override { visit(static_cast<TRegExpTerm&>(n)); } }; -} // namespace query -} // namespace search +} diff --git a/searchlib/src/vespa/searchlib/query/tree/intermediate.cpp b/searchlib/src/vespa/searchlib/query/tree/intermediate.cpp index 1274777dc74..f56da9c2cf9 100644 --- a/searchlib/src/vespa/searchlib/query/tree/intermediate.cpp +++ b/searchlib/src/vespa/searchlib/query/tree/intermediate.cpp @@ -1,8 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "intermediate.h" -namespace search { -namespace query { +namespace search::query { Intermediate::~Intermediate() { for (size_t i = 0; i < _children.size(); ++i) { @@ -16,5 +15,4 @@ Intermediate &Intermediate::append(Node::UP child) return *this; } -} // namespace query -} // namespace search +} diff --git a/searchlib/src/vespa/searchlib/query/tree/intermediate.h b/searchlib/src/vespa/searchlib/query/tree/intermediate.h index c28ab8241e0..9fac7345436 100644 --- a/searchlib/src/vespa/searchlib/query/tree/intermediate.h +++ b/searchlib/src/vespa/searchlib/query/tree/intermediate.h @@ -4,8 +4,7 @@ #include <vector> #include <vespa/searchlib/query/tree/node.h> -namespace search { -namespace query { +namespace search::query { class Intermediate : public Node { @@ -24,6 +23,4 @@ class Intermediate : public Node Intermediate &append(Node::UP child); }; -} // namespace query -} // namespace search - +} diff --git a/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.cpp b/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.cpp index 9fabbe58a19..4a4b606ef8f 100644 --- a/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.cpp +++ b/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.cpp @@ -1,32 +1,20 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "intermediatenodes.h" -namespace search { -namespace query { - -And::~And() {} - -AndNot::~AndNot() {} - -Or::~Or() {} - -WeakAnd::~WeakAnd() {} - -Equiv::~Equiv() {} - -Rank::~Rank() {} - -Near::~Near() {} - -ONear::~ONear() {} - -Phrase::~Phrase() {} - -WeightedSetTerm::~WeightedSetTerm() {} - -DotProduct::~DotProduct() {} - -WandTerm::~WandTerm() {} - -} // namespace query -} // namespace search +namespace search::query { + +And::~And() = default; +AndNot::~AndNot() = default; +Or::~Or() = default; +WeakAnd::~WeakAnd() = default; +Equiv::~Equiv() = default; +Rank::~Rank() = default; +Near::~Near() = default; +ONear::~ONear() = default; +Phrase::~Phrase() = default; +SameElement::~SameElement() = default; +WeightedSetTerm::~WeightedSetTerm() = default; +DotProduct::~DotProduct() = default; +WandTerm::~WandTerm() = default; + +} diff --git a/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.h b/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.h index e358c7d7bef..f53e5aed031 100644 --- a/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.h +++ b/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.h @@ -7,8 +7,7 @@ #include "term.h" #include <vespa/searchlib/query/weight.h> -namespace search { -namespace query { +namespace search::query { class And : public QueryNodeMixin<And, Intermediate> { public: @@ -105,6 +104,13 @@ public: virtual ~Phrase() = 0; }; +class SameElement : public QueryNodeMixin<SameElement, Intermediate>, public Term { +public: + SameElement(const vespalib::string &view, int32_t id, Weight weight) + : Term(view, id, weight) {} + virtual ~SameElement() = 0; +}; + class WeightedSetTerm : public QueryNodeMixin<WeightedSetTerm, Intermediate>, public Term { public: WeightedSetTerm(const vespalib::string &view, int32_t id, Weight weight) @@ -137,6 +143,4 @@ public: double getThresholdBoostFactor() const { return _thresholdBoostFactor; } }; -} // namespace query -} // namespace search - +} diff --git a/searchlib/src/vespa/searchlib/query/tree/location.cpp b/searchlib/src/vespa/searchlib/query/tree/location.cpp index 5817b93a2fb..216c5ec5ad0 100644 --- a/searchlib/src/vespa/searchlib/query/tree/location.cpp +++ b/searchlib/src/vespa/searchlib/query/tree/location.cpp @@ -7,8 +7,7 @@ using vespalib::asciistream; -namespace search { -namespace query { +namespace search::query { Location::Location(const Point &point, uint32_t max_dist, uint32_t x_aspect) { asciistream loc; @@ -61,5 +60,4 @@ vespalib::asciistream &operator<<(vespalib::asciistream &out, const Location &lo return out << loc.getLocationString(); } -} // namespace query -} // namespace search +} diff --git a/searchlib/src/vespa/searchlib/query/tree/location.h b/searchlib/src/vespa/searchlib/query/tree/location.h index 0abad19b696..5ed717c87d6 100644 --- a/searchlib/src/vespa/searchlib/query/tree/location.h +++ b/searchlib/src/vespa/searchlib/query/tree/location.h @@ -4,11 +4,8 @@ #include <vespa/vespalib/stllike/string.h> -namespace vespalib { - class asciistream; -} -namespace search { -namespace query { +namespace vespalib { class asciistream; } +namespace search::query { class Point; class Rectangle; @@ -32,6 +29,4 @@ public: vespalib::asciistream &operator<<(vespalib::asciistream &out, const Location &loc); -} // namespace query -} // namespace search - +} diff --git a/searchlib/src/vespa/searchlib/query/tree/point.h b/searchlib/src/vespa/searchlib/query/tree/point.h index af9b958a474..89d0bc1db44 100644 --- a/searchlib/src/vespa/searchlib/query/tree/point.h +++ b/searchlib/src/vespa/searchlib/query/tree/point.h @@ -2,10 +2,9 @@ #pragma once -#include <stdint.h> +#include <cstdint> -namespace search { -namespace query { +namespace search::query { struct Point { int64_t x; @@ -18,6 +17,4 @@ inline bool operator==(const Point &p1, const Point &p2) { return p1.x == p2.x && p1.y == p2.y; } -} // namespace query -} // namespace search - +} diff --git a/searchlib/src/vespa/searchlib/query/tree/predicate_query_term.h b/searchlib/src/vespa/searchlib/query/tree/predicate_query_term.h index b851563e198..0a92546e414 100644 --- a/searchlib/src/vespa/searchlib/query/tree/predicate_query_term.h +++ b/searchlib/src/vespa/searchlib/query/tree/predicate_query_term.h @@ -6,8 +6,7 @@ #include <memory> #include <vector> -namespace search { -namespace query { +namespace search::query { /** * Represents a predicate query, with features and range features. @@ -71,6 +70,4 @@ public: } }; -} // namespace query -} // namespace search - +} diff --git a/searchlib/src/vespa/searchlib/query/tree/querybuilder.h b/searchlib/src/vespa/searchlib/query/tree/querybuilder.h index 2732d7895a5..583966bcfc5 100644 --- a/searchlib/src/vespa/searchlib/query/tree/querybuilder.h +++ b/searchlib/src/vespa/searchlib/query/tree/querybuilder.h @@ -25,8 +25,7 @@ #include <vespa/searchlib/query/weight.h> #include "node.h" -namespace search { -namespace query { +namespace search::query { class Intermediate; class Location; @@ -124,6 +123,10 @@ typename NodeTypes::Phrase *createPhrase(const vespalib::stringref &view, int32_ return new typename NodeTypes::Phrase(view, id, weight); } template <class NodeTypes> +typename NodeTypes::SameElement *createSameElement(const vespalib::stringref &view, int32_t id, Weight weight) { + return new typename NodeTypes::SameElement(view, id, weight); +} +template <class NodeTypes> typename NodeTypes::WeightedSetTerm *createWeightedSetTerm(const vespalib::stringref &view, int32_t id, Weight weight) { return new typename NodeTypes::WeightedSetTerm(view, id, weight); } @@ -243,6 +246,12 @@ public: setWeightOverride(weight); return node; } + typename NodeTypes::SameElement &addSameElement(int child_count, const stringref &view, int32_t id, Weight weight) { + adjustWeight(weight); + typename NodeTypes::SameElement &node = addIntermediate(createSameElement<NodeTypes>(view, id, weight), child_count); + setWeightOverride(weight); + return node; + } typename NodeTypes::WeightedSetTerm &addWeightedSetTerm( int child_count, const stringref &view, int32_t id, Weight weight) { adjustWeight(weight); typename NodeTypes::WeightedSetTerm &node = addIntermediate(createWeightedSetTerm<NodeTypes>(view, id, weight), child_count); @@ -306,6 +315,4 @@ public: } }; -} // namespace query -} // namespace search - +} diff --git a/searchlib/src/vespa/searchlib/query/tree/querynodemixin.h b/searchlib/src/vespa/searchlib/query/tree/querynodemixin.h index d6e0950dea2..9e8c97cff94 100644 --- a/searchlib/src/vespa/searchlib/query/tree/querynodemixin.h +++ b/searchlib/src/vespa/searchlib/query/tree/querynodemixin.h @@ -4,8 +4,7 @@ #include "queryvisitor.h" -namespace search { -namespace query { +namespace search::query { template <typename T, typename Base> struct QueryNodeMixin : Base { @@ -21,8 +20,6 @@ protected: }; template <typename T, typename Base> -QueryNodeMixin<T, Base>::~QueryNodeMixin() {} - -} // namespace query -} // namespace search +QueryNodeMixin<T, Base>::~QueryNodeMixin() = default; +} diff --git a/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h b/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h index aad85d9b28c..a8d6596dc37 100644 --- a/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h +++ b/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h @@ -7,8 +7,7 @@ #include "queryvisitor.h" #include "termnodes.h" -namespace search { -namespace query { +namespace search::query { /** * Creates a new query tree based on an existing one. The traits class @@ -70,22 +69,25 @@ private: } void visit(Phrase &node) override { - replicate(node, _builder.addPhrase(node.getChildren().size(), - node.getView(), + replicate(node, _builder.addPhrase(node.getChildren().size(), node.getView(), node.getId(), node.getWeight())); visitNodes(node.getChildren()); } + void visit(SameElement &node) override { + replicate(node, _builder.addSameElement(node.getChildren().size(), node.getView(), + node.getId(), node.getWeight())); + visitNodes(node.getChildren()); + } + void visit(WeightedSetTerm &node) override { - replicate(node, _builder.addWeightedSetTerm(node.getChildren().size(), - node.getView(), + replicate(node, _builder.addWeightedSetTerm(node.getChildren().size(), node.getView(), node.getId(), node.getWeight())); visitNodes(node.getChildren()); } void visit(DotProduct &node) override { - replicate(node, _builder.addDotProduct(node.getChildren().size(), - node.getView(), + replicate(node, _builder.addDotProduct(node.getChildren().size(), node.getView(), node.getId(), node.getWeight())); visitNodes(node.getChildren()); } @@ -165,5 +167,4 @@ private: } }; -} // namespace query -} // namespace search +} diff --git a/searchlib/src/vespa/searchlib/query/tree/querytreecreator.h b/searchlib/src/vespa/searchlib/query/tree/querytreecreator.h index a3e6ac523ae..c42a16d8ab3 100644 --- a/searchlib/src/vespa/searchlib/query/tree/querytreecreator.h +++ b/searchlib/src/vespa/searchlib/query/tree/querytreecreator.h @@ -5,8 +5,7 @@ #include "queryreplicator.h" #include "stackdumpquerycreator.h" -namespace search { -namespace query { +namespace search::query { /** * Holds functions for creating query trees, either from a stack dump @@ -27,6 +26,4 @@ private: QueryTreeCreator(); }; -} // namespace query -} // namespace search - +} diff --git a/searchlib/src/vespa/searchlib/query/tree/queryvisitor.h b/searchlib/src/vespa/searchlib/query/tree/queryvisitor.h index 4596359201b..0cb56f9127a 100644 --- a/searchlib/src/vespa/searchlib/query/tree/queryvisitor.h +++ b/searchlib/src/vespa/searchlib/query/tree/queryvisitor.h @@ -2,8 +2,7 @@ #pragma once -namespace search { -namespace query { +namespace search::query { class And; class AndNot; @@ -26,6 +25,7 @@ class DotProduct; class WandTerm; class PredicateQuery; class RegExpTerm; +class SameElement; struct QueryVisitor { virtual ~QueryVisitor() {} @@ -39,6 +39,7 @@ struct QueryVisitor { virtual void visit(ONear &) = 0; virtual void visit(Or &) = 0; virtual void visit(Phrase &) = 0; + virtual void visit(SameElement &node) = 0; virtual void visit(PrefixTerm &) = 0; virtual void visit(RangeTerm &) = 0; virtual void visit(Rank &) = 0; @@ -53,6 +54,5 @@ struct QueryVisitor { virtual void visit(RegExpTerm &) = 0; }; -} // namespace query -} // namespace search +} diff --git a/searchlib/src/vespa/searchlib/query/tree/range.cpp b/searchlib/src/vespa/searchlib/query/tree/range.cpp index 583d57bb74d..202b80d98a2 100644 --- a/searchlib/src/vespa/searchlib/query/tree/range.cpp +++ b/searchlib/src/vespa/searchlib/query/tree/range.cpp @@ -3,8 +3,7 @@ #include "range.h" #include <vespa/vespalib/stllike/asciistream.h> -namespace search { -namespace query { +namespace search::query { Range::Range(int64_t f, int64_t t) { @@ -18,5 +17,4 @@ vespalib::asciistream &operator<<(vespalib::asciistream &out, const Range &range return out << range.getRangeString(); } -} // namespace query -} // namespace search +} diff --git a/searchlib/src/vespa/searchlib/query/tree/range.h b/searchlib/src/vespa/searchlib/query/tree/range.h index 862258873e6..e55ddf7f14b 100644 --- a/searchlib/src/vespa/searchlib/query/tree/range.h +++ b/searchlib/src/vespa/searchlib/query/tree/range.h @@ -3,12 +3,9 @@ #pragma once #include <vespa/vespalib/stllike/string.h> -namespace vespalib { - class asciistream; -} +namespace vespalib { class asciistream; } -namespace search { -namespace query { +namespace search::query { class Range { vespalib::string _range; @@ -27,6 +24,4 @@ inline bool operator==(const Range &r1, const Range &r2) { vespalib::asciistream &operator<<(vespalib::asciistream &out, const Range &range); -} // namespace query -} // namespace search - +} diff --git a/searchlib/src/vespa/searchlib/query/tree/rectangle.h b/searchlib/src/vespa/searchlib/query/tree/rectangle.h index 29b144ac5dc..97be9ddeb32 100644 --- a/searchlib/src/vespa/searchlib/query/tree/rectangle.h +++ b/searchlib/src/vespa/searchlib/query/tree/rectangle.h @@ -2,8 +2,7 @@ #pragma once -namespace search { -namespace query { +namespace search::query { struct Rectangle { int64_t left; @@ -21,6 +20,5 @@ inline bool operator==(const Rectangle &r1, const Rectangle &r2) { && r1.top == r2.top && r1.bottom == r2.bottom; } -} // namespace query -} // namespace search +} diff --git a/searchlib/src/vespa/searchlib/query/tree/simplequery.h b/searchlib/src/vespa/searchlib/query/tree/simplequery.h index 28791dafe53..18d97a26046 100644 --- a/searchlib/src/vespa/searchlib/query/tree/simplequery.h +++ b/searchlib/src/vespa/searchlib/query/tree/simplequery.h @@ -10,8 +10,7 @@ #include "intermediatenodes.h" #include "termnodes.h" -namespace search { -namespace query { +namespace search::query { struct SimpleAnd : And {}; struct SimpleAndNot : AndNot {}; @@ -31,6 +30,11 @@ struct SimplePhrase : Phrase { SimplePhrase(const vespalib::stringref &view, int32_t id, Weight weight) : Phrase(view, id, weight) {} }; + +struct SimpleSameElement : SameElement { + SimpleSameElement(const vespalib::stringref &view, int32_t id, Weight weight) + : SameElement(view, id, weight) {} +}; struct SimpleWeightedSetTerm : WeightedSetTerm { SimpleWeightedSetTerm(const vespalib::stringref &view, int32_t id, Weight weight) : WeightedSetTerm(view, id, weight) {} @@ -112,6 +116,7 @@ struct SimpleQueryNodeTypes { typedef SimpleONear ONear; typedef SimpleOr Or; typedef SimplePhrase Phrase; + typedef SimpleSameElement SameElement; typedef SimplePrefixTerm PrefixTerm; typedef SimpleRangeTerm RangeTerm; typedef SimpleRank Rank; @@ -126,6 +131,4 @@ struct SimpleQueryNodeTypes { typedef SimpleRegExpTerm RegExpTerm; }; -} // namespace query -} // namespace search - +} diff --git a/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.cpp b/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.cpp index 771830c0b03..b75f4553f72 100644 --- a/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.cpp +++ b/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.cpp @@ -64,23 +64,41 @@ class QueryNodeConverter : public QueryVisitor { template <typename V> void appendPredicateQueryTermVector(const V& v); + void createComplexIntermediate(const Term &node, const std::vector<Node *> & children, size_t type) { + uint8_t flags = 0; + if (!node.isRanked()) { + flags |= ParseItem::IFLAG_NORANK; + } + if (!node.usePositionData()) { + flags |= ParseItem::IFLAG_NOPOSITIONDATA; + } + if (flags != 0) { + type |= ParseItem::IF_FLAGS; + } + appendByte(type); + appendCompressedNumber(node.getWeight().percent()); + if (type & ParseItem::IF_FLAGS) { + appendByte(flags); + } + appendCompressedPositiveNumber(children.size()); + appendString(node.getView()); + visitNodes(children); + } + void createIntermediate(const Intermediate &node, size_t type) { appendByte(type); appendCompressedPositiveNumber(node.getChildren().size()); visitNodes(node.getChildren()); } - void createIntermediate(const Intermediate &node, size_t type, - size_t distance) { + void createIntermediate(const Intermediate &node, size_t type, size_t distance) { appendByte(type); appendCompressedPositiveNumber(node.getChildren().size()); appendCompressedPositiveNumber(distance); visitNodes(node.getChildren()); } - void createIntermediate(const Intermediate &node, size_t type, - size_t distance, - const vespalib::string & view) { + void createIntermediate(const Intermediate &node, size_t type, size_t distance, const vespalib::string & view) { appendByte(type); appendCompressedPositiveNumber(node.getChildren().size()); appendCompressedPositiveNumber(distance); @@ -116,26 +134,12 @@ class QueryNodeConverter : public QueryVisitor { createIntermediate(node, ParseItem::ITEM_EQUIV); } + void visit(SameElement &node) override { + createComplexIntermediate(node, node.getChildren(), (ParseItem::ITEM_SAME_ELEMENT | ParseItem::IF_WEIGHT)); + } + void visit(Phrase &node) override { - uint8_t typefield = (ParseItem::ITEM_PHRASE | ParseItem::IF_WEIGHT); - uint8_t flags = 0; - if (!node.isRanked()) { - flags |= ParseItem::IFLAG_NORANK; - } - if (!node.usePositionData()) { - flags |= ParseItem::IFLAG_NOPOSITIONDATA; - } - if (flags != 0) { - typefield |= ParseItem::IF_FLAGS; - } - appendByte(typefield); - appendCompressedNumber(node.getWeight().percent()); - if (typefield & ParseItem::IF_FLAGS) { - appendByte(flags); - } - appendCompressedPositiveNumber(node.getChildren().size()); - appendString(node.getView()); - visitNodes(node.getChildren()); + createComplexIntermediate(node, node.getChildren(), (ParseItem::ITEM_PHRASE | ParseItem::IF_WEIGHT)); } template <typename NODE> @@ -187,9 +191,7 @@ class QueryNodeConverter : public QueryVisitor { template <class Term> void createTerm(const Term &node, size_t type) { - uint8_t typefield = type | - ParseItem::IF_WEIGHT | - ParseItem::IF_UNIQUEID; + uint8_t typefield = type | ParseItem::IF_WEIGHT | ParseItem::IF_UNIQUEID; uint8_t flags = 0; if (!node.isRanked()) { flags |= ParseItem::IFLAG_NORANK; diff --git a/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.h b/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.h index 448f1c9bd08..4e1556d05e6 100644 --- a/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.h +++ b/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.h @@ -4,8 +4,7 @@ #include <vespa/vespalib/stllike/string.h> -namespace search { -namespace query { +namespace search::query { class Node; @@ -14,6 +13,4 @@ struct StackDumpCreator { static vespalib::string create(const Node &node); }; -} // namespace query -} // namespace search - +} diff --git a/searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h b/searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h index f9c66965cc4..acf2e0482f6 100644 --- a/searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h +++ b/searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h @@ -9,8 +9,7 @@ #include <vespa/searchlib/parsequery/simplequerystack.h> #include <vespa/vespalib/objects/hexdump.h> -namespace search { -namespace query { +namespace search::query { /** * Creates a query tree from a stack dump. @@ -90,6 +89,12 @@ private: Weight weight = queryStack.GetWeight(); t = &builder.addPhrase(arity, view, id, weight); pureTermView = view; + } else if (type == ParseItem::ITEM_SAME_ELEMENT) { + vespalib::stringref view = queryStack.getIndexName(); + int32_t id = queryStack.getUniqueId(); + Weight weight = queryStack.GetWeight(); + t = &builder.addPhrase(arity, view, id, weight); + pureTermView = view; } else if (type == ParseItem::ITEM_WEIGHTED_SET) { vespalib::stringref view = queryStack.getIndexName(); int32_t id = queryStack.getUniqueId(); @@ -152,6 +157,4 @@ private: } }; -} // namespace query -} // namespace search - +} diff --git a/searchlib/src/vespa/searchlib/query/tree/templatetermvisitor.h b/searchlib/src/vespa/searchlib/query/tree/templatetermvisitor.h index e4ce4ccf807..3a9c56166e9 100644 --- a/searchlib/src/vespa/searchlib/query/tree/templatetermvisitor.h +++ b/searchlib/src/vespa/searchlib/query/tree/templatetermvisitor.h @@ -4,8 +4,7 @@ #include "customtypetermvisitor.h" -namespace search { -namespace query { +namespace search::query { /** * Use this class to visit all term nodes by deriving from this class @@ -38,6 +37,8 @@ class TemplateTermVisitor : public CustomTypeTermVisitor<NodeTypes> { // overridden to do so. void visit(typename NodeTypes::Phrase &n) override { myVisit(n); } + void visit(typename NodeTypes::SameElement &n) override { myVisit(n); } + // WeightedSetTerms are terms with children. This visitor will not visit // the weighted set's children, unless this member function is // overridden to do so. @@ -54,5 +55,4 @@ class TemplateTermVisitor : public CustomTypeTermVisitor<NodeTypes> { void visit(typename NodeTypes::WandTerm &n) override { myVisit(n); } }; -} // namespace query -} // namespace search +} diff --git a/searchlib/src/vespa/searchlib/query/tree/term.cpp b/searchlib/src/vespa/searchlib/query/tree/term.cpp index 54def08afe8..924f562760a 100644 --- a/searchlib/src/vespa/searchlib/query/tree/term.cpp +++ b/searchlib/src/vespa/searchlib/query/tree/term.cpp @@ -2,10 +2,9 @@ #include "term.h" -namespace search { -namespace query { +namespace search::query { -Term::~Term() { } +Term::~Term() = default; Term::Term(const vespalib::stringref &view, int32_t id, Weight weight) : _view(view), @@ -16,5 +15,4 @@ Term::Term(const vespalib::stringref &view, int32_t id, Weight weight) : _position_data(true) { } -} // namespace query -} // namespace search +} diff --git a/searchlib/src/vespa/searchlib/query/tree/term.h b/searchlib/src/vespa/searchlib/query/tree/term.h index f8c0d98ac22..f172267ee98 100644 --- a/searchlib/src/vespa/searchlib/query/tree/term.h +++ b/searchlib/src/vespa/searchlib/query/tree/term.h @@ -6,8 +6,7 @@ #include <vespa/searchlib/query/weight.h> #include <cassert> -namespace search { -namespace query { +namespace search::query { /** * This is a leaf in the Query tree. Sort of. Phrases are both terms @@ -16,11 +15,11 @@ namespace query { class Term { vespalib::string _view; - int32_t _id; - Weight _weight; - int32_t _term_index; - bool _ranked; - bool _position_data; + int32_t _id; + Weight _weight; + int32_t _term_index; + bool _ranked; + bool _position_data; public: virtual ~Term() = 0; @@ -60,7 +59,7 @@ class TermBase : public Node, public Term { public: typedef T Type; - virtual ~TermBase() = 0; + ~TermBase() override = 0; const T &getTerm() const { return _term; } protected: @@ -71,8 +70,6 @@ protected: }; template <typename T> -TermBase<T>::~TermBase() {} - -} // namespace query -} // namespace search +TermBase<T>::~TermBase() = default; +} diff --git a/searchlib/src/vespa/searchlib/query/tree/termnodes.cpp b/searchlib/src/vespa/searchlib/query/tree/termnodes.cpp index 8e8ae16827b..0a6a6af62b5 100644 --- a/searchlib/src/vespa/searchlib/query/tree/termnodes.cpp +++ b/searchlib/src/vespa/searchlib/query/tree/termnodes.cpp @@ -2,27 +2,25 @@ #include "termnodes.h" -namespace search { -namespace query { +namespace search::query { -NumberTerm::~NumberTerm() {} +NumberTerm::~NumberTerm() = default; -PrefixTerm::~PrefixTerm() {} +PrefixTerm::~PrefixTerm() = default; -RangeTerm::~RangeTerm() {} +RangeTerm::~RangeTerm() = default; StringTerm::StringTerm(const Type &term, const vespalib::stringref &view, int32_t id, Weight weight) : QueryNodeMixinType(term, view, id, weight) {} -StringTerm::~StringTerm() {} +StringTerm::~StringTerm() = default; -SubstringTerm::~SubstringTerm() {} +SubstringTerm::~SubstringTerm() = default; -SuffixTerm::~SuffixTerm() {} +SuffixTerm::~SuffixTerm() = default; -LocationTerm::~LocationTerm() {} +LocationTerm::~LocationTerm() = default; -RegExpTerm::~RegExpTerm() {} +RegExpTerm::~RegExpTerm() = default; -} // namespace query -} // namespace search +} diff --git a/searchlib/src/vespa/searchlib/query/tree/termnodes.h b/searchlib/src/vespa/searchlib/query/tree/termnodes.h index 4c98ba92ff5..8d4882fb393 100644 --- a/searchlib/src/vespa/searchlib/query/tree/termnodes.h +++ b/searchlib/src/vespa/searchlib/query/tree/termnodes.h @@ -8,8 +8,7 @@ #include "range.h" #include "term.h" -namespace search { -namespace query { +namespace search::query { typedef TermBase<vespalib::string> StringBase; @@ -117,6 +116,4 @@ public: }; -} // namespace query -} // namespace search - +} diff --git a/searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.cpp b/searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.cpp index 8e6429aaa90..09d99a77d39 100644 --- a/searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.cpp @@ -19,7 +19,7 @@ CreateBlueprintVisitorHelper::CreateBlueprintVisitorHelper(Searchable &searchabl _result() {} -CreateBlueprintVisitorHelper::~CreateBlueprintVisitorHelper() {} +CreateBlueprintVisitorHelper::~CreateBlueprintVisitorHelper() = default; Blueprint::UP CreateBlueprintVisitorHelper::getResult() @@ -30,7 +30,7 @@ CreateBlueprintVisitorHelper::getResult() } void -CreateBlueprintVisitorHelper::visitPhrase(search::query::Phrase &n) { +CreateBlueprintVisitorHelper::visitPhrase(query::Phrase &n) { SimplePhraseBlueprint *phrase = new SimplePhraseBlueprint(_field, _requestContext); Blueprint::UP result(phrase); for (size_t i = 0; i < n.getChildren().size(); ++i) { @@ -42,7 +42,13 @@ CreateBlueprintVisitorHelper::visitPhrase(search::query::Phrase &n) { } void -CreateBlueprintVisitorHelper::handleNumberTermAsText(search::query::NumberTerm &n) +CreateBlueprintVisitorHelper::visitSameElement(query::SameElement &n) { + (void) n; + //TODO Implement Blueprint creation. +} + +void +CreateBlueprintVisitorHelper::handleNumberTermAsText(query::NumberTerm &n) { vespalib::string termStr = termAsString(n); queryeval::SplitFloat splitter(termStr); @@ -73,24 +79,24 @@ CreateBlueprintVisitorHelper::createWeightedSet(WS *bp, NODE &n) { for (size_t i = 0; i < n.getChildren().size(); ++i) { fields.clear(); fields.add(bp->getNextChildField(_field)); - const search::query::Node &node = *n.getChildren()[i]; + const query::Node &node = *n.getChildren()[i]; uint32_t weight = getWeightFromNode(node).percent(); bp->addTerm(_searchable.createBlueprint(_requestContext, fields, node), weight); } setResult(std::move(result)); } void -CreateBlueprintVisitorHelper::visitWeightedSetTerm(search::query::WeightedSetTerm &n) { +CreateBlueprintVisitorHelper::visitWeightedSetTerm(query::WeightedSetTerm &n) { WeightedSetTermBlueprint *bp = new WeightedSetTermBlueprint(_field); createWeightedSet(bp, n); } void -CreateBlueprintVisitorHelper::visitDotProduct(search::query::DotProduct &n) { +CreateBlueprintVisitorHelper::visitDotProduct(query::DotProduct &n) { DotProductBlueprint *bp = new DotProductBlueprint(_field); createWeightedSet(bp, n); } void -CreateBlueprintVisitorHelper::visitWandTerm(search::query::WandTerm &n) { +CreateBlueprintVisitorHelper::visitWandTerm(query::WandTerm &n) { ParallelWeakAndBlueprint *bp = new ParallelWeakAndBlueprint(_field, n.getTargetNumHits(), n.getScoreThreshold(), diff --git a/searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.h b/searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.h index cded9c103dc..cc271d80793 100644 --- a/searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.h +++ b/searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.h @@ -12,7 +12,7 @@ namespace search::queryeval { -class CreateBlueprintVisitorHelper : public search::query::QueryVisitor +class CreateBlueprintVisitorHelper : public query::QueryVisitor { private: const IRequestContext & _requestContext; @@ -37,42 +37,46 @@ public: const FieldSpec &getField() const { return _field; } - void visitPhrase(search::query::Phrase &n); + void visitPhrase(query::Phrase &n); + void visitSameElement(query::SameElement &n); template <typename WS, typename NODE> void createWeightedSet(WS *bp, NODE &n); - void visitWeightedSetTerm(search::query::WeightedSetTerm &n); - void visitDotProduct(search::query::DotProduct &n); - void visitWandTerm(search::query::WandTerm &n); + void visitWeightedSetTerm(query::WeightedSetTerm &n); + void visitDotProduct(query::DotProduct &n); + void visitWandTerm(query::WandTerm &n); - void handleNumberTermAsText(search::query::NumberTerm &n); + void handleNumberTermAsText(query::NumberTerm &n); void illegalVisit() {} - void visit(search::query::And &) override { illegalVisit(); } - void visit(search::query::AndNot &) override { illegalVisit(); } - void visit(search::query::Equiv &) override { illegalVisit(); } - void visit(search::query::Near &) override { illegalVisit(); } - void visit(search::query::ONear &) override { illegalVisit(); } - void visit(search::query::Or &) override { illegalVisit(); } - void visit(search::query::Rank &) override { illegalVisit(); } - void visit(search::query::WeakAnd &) override { illegalVisit(); } + void visit(query::And &) override { illegalVisit(); } + void visit(query::AndNot &) override { illegalVisit(); } + void visit(query::Equiv &) override { illegalVisit(); } + void visit(query::Near &) override { illegalVisit(); } + void visit(query::ONear &) override { illegalVisit(); } + void visit(query::Or &) override { illegalVisit(); } + void visit(query::Rank &) override { illegalVisit(); } + void visit(query::WeakAnd &) override { illegalVisit(); } - void visit(search::query::Phrase &n) override { + void visit(query::Phrase &n) override { visitPhrase(n); } - void visit(search::query::WeightedSetTerm &n) override { visitWeightedSetTerm(n); } - void visit(search::query::DotProduct &n) override { visitDotProduct(n); } - void visit(search::query::WandTerm &n) override { visitWandTerm(n); } - - void visit(search::query::NumberTerm &n) override = 0; - void visit(search::query::LocationTerm &n) override = 0; - void visit(search::query::PrefixTerm &n) override = 0; - void visit(search::query::RangeTerm &n) override = 0; - void visit(search::query::StringTerm &n) override = 0; - void visit(search::query::SubstringTerm &n) override = 0; - void visit(search::query::SuffixTerm &n) override = 0; - void visit(search::query::RegExpTerm &n) override = 0; + void visit(query::SameElement &n) override { + visitSameElement(n); + } + void visit(query::WeightedSetTerm &n) override { visitWeightedSetTerm(n); } + void visit(query::DotProduct &n) override { visitDotProduct(n); } + void visit(query::WandTerm &n) override { visitWandTerm(n); } + + void visit(query::NumberTerm &n) override = 0; + void visit(query::LocationTerm &n) override = 0; + void visit(query::PrefixTerm &n) override = 0; + void visit(query::RangeTerm &n) override = 0; + void visit(query::StringTerm &n) override = 0; + void visit(query::SubstringTerm &n) override = 0; + void visit(query::SuffixTerm &n) override = 0; + void visit(query::RegExpTerm &n) override = 0; }; } diff --git a/searchlib/src/vespa/searchlib/queryeval/get_weight_from_node.cpp b/searchlib/src/vespa/searchlib/queryeval/get_weight_from_node.cpp index 8fa6af74ae2..bd9de0a1762 100644 --- a/searchlib/src/vespa/searchlib/queryeval/get_weight_from_node.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/get_weight_from_node.cpp @@ -13,8 +13,7 @@ using search::query::Weight; namespace search::queryeval { namespace { -struct WeightExtractor : public TemplateTermVisitor<WeightExtractor, - SimpleQueryNodeTypes> { +struct WeightExtractor : public TemplateTermVisitor<WeightExtractor, SimpleQueryNodeTypes> { Weight weight; WeightExtractor() : weight(0) {} diff --git a/searchlib/src/vespa/searchlib/queryeval/termasstring.cpp b/searchlib/src/vespa/searchlib/queryeval/termasstring.cpp index 14a6cefaf1b..3829ea45e2b 100644 --- a/searchlib/src/vespa/searchlib/queryeval/termasstring.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/termasstring.cpp @@ -22,6 +22,7 @@ using search::query::Node; using search::query::ONear; using search::query::Or; using search::query::Phrase; +using search::query::SameElement; using search::query::PredicateQuery; using search::query::PrefixTerm; using search::query::QueryVisitor; @@ -84,6 +85,7 @@ struct TermAsStringVisitor : public QueryVisitor { void visit(ONear &) override {illegalVisit(); } void visit(Or &) override {illegalVisit(); } void visit(Phrase &) override {illegalVisit(); } + void visit(SameElement &) override {illegalVisit(); } void visit(Rank &) override {illegalVisit(); } void visit(WeakAnd &) override {illegalVisit(); } void visit(WeightedSetTerm &) override {illegalVisit(); } |