diff options
author | HÃ¥vard Pettersen <havardpe@gmail.com> | 2017-03-30 15:37:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-30 15:37:36 +0200 |
commit | 7b478602d33afdfb53f5c95e880db14f02b3707f (patch) | |
tree | d1193254eb49cfc05cf597d4d82ea77e7b0942c7 /searchlib | |
parent | 8ba178cec0ea2cafa912a3e27373e9ebdfd6fcee (diff) | |
parent | f371a3f68e1b0418d98b805420954e1319afdde7 (diff) |
Merge pull request #2086 from yahoo/balder/remove-lp-3-rebased
Balder/remove lp 3 rebased
Diffstat (limited to 'searchlib')
62 files changed, 1983 insertions, 1929 deletions
diff --git a/searchlib/src/tests/aggregator/attr_test.cpp b/searchlib/src/tests/aggregator/attr_test.cpp index 49ec52274f9..874e79495c8 100644 --- a/searchlib/src/tests/aggregator/attr_test.cpp +++ b/searchlib/src/tests/aggregator/attr_test.cpp @@ -114,13 +114,11 @@ struct StringAttrFixture { } }; +#define MU std::make_unique TEST_F("testArrayAt", AttributeFixture()) { for (int i = 0; i < 11; i++) { - ExpressionNode::CP cn(new ConstantNode(new Int64ResultNode(i))); - ExpressionNode::CP ln(new ArrayAtLookup(*f1.guard, cn)); - - ExpressionTree et(ln); + ExpressionTree et(MU<ArrayAtLookup>(*f1.guard, MU<ConstantNode>(MU<Int64ResultNode>(i)))); ExpressionTree::Configure treeConf; et.select(treeConf, treeConf); EXPECT_TRUE(et.getResult().getClass().inherits(FloatResultNode::classId)); @@ -134,15 +132,11 @@ TEST_F("testArrayAt", AttributeFixture()) { TEST_F("testArrayAtInt", IntAttrFixture()) { for (int i = 0; i < 3; i++) { - ExpressionNode::CP othercn(new ConstantNode(new Int64ResultNode(4567))); - ArrayAtLookup *x = new ArrayAtLookup(*f1.guard, othercn); - ExpressionNode::CP cn(new ConstantNode(new Int64ResultNode(i))); - ArrayAtLookup *y = new ArrayAtLookup(*f1.guard, cn); + auto x = MU<ArrayAtLookup>(*f1.guard, MU<ConstantNode>(MU<Int64ResultNode>(4567))); + auto y = MU<ArrayAtLookup>(*f1.guard, MU<ConstantNode>(MU<Int64ResultNode>(i))); *x = *y; - delete y; - ExpressionNode::CP ln(x); - ExpressionTree et(ln); + ExpressionTree et(std::move(x)); ExpressionTree::Configure treeConf; et.select(treeConf, treeConf); EXPECT_TRUE(et.getResult().getClass().inherits(IntegerResultNode::classId)); @@ -156,10 +150,7 @@ TEST_F("testArrayAtInt", IntAttrFixture()) { TEST_F("testArrayAtString", StringAttrFixture()) { - ExpressionNode::CP cn(new ConstantNode(new Int64ResultNode(1))); - ExpressionNode::CP ln(new ArrayAtLookup(*f1.guard, cn)); - - ExpressionTree et(ln); + ExpressionTree et(MU<ArrayAtLookup>(*f1.guard, MU<ConstantNode>(MU<Int64ResultNode>(1)))); ExpressionTree::Configure treeConf; et.select(treeConf, treeConf); EXPECT_TRUE(et.getResult().getClass().inherits(StringResultNode::classId)); @@ -177,15 +168,11 @@ TEST_F("testArrayAtString", StringAttrFixture()) { struct ArrayAtExpressionFixture : public AttributeFixture { - ExpressionNode::CP cn; - ExpressionNode::CP ln; ExpressionTree et; ArrayAtExpressionFixture(int i) : AttributeFixture(), - cn(new ConstantNode(new Int64ResultNode(i))), - ln(new ArrayAtLookup(*guard, cn)), - et(ln) + et(MU<ArrayAtLookup>(*guard, MU<ConstantNode>(MU<Int64ResultNode>(i)))) { ExpressionTree::Configure treeConf; et.select(treeConf, treeConf); @@ -212,11 +199,7 @@ TEST_F("testArrayAtAboveRange", ArrayAtExpressionFixture(17)) { } TEST_F("testInterpolatedLookup", AttributeFixture()) { - - ExpressionNode::CP c1(new ConstantNode(new FloatResultNode(f1.doc0attr[2]))); - ExpressionNode::CP l1(new InterpolatedLookup(*f1.guard, c1)); - - ExpressionTree et(l1); + ExpressionTree et(MU<InterpolatedLookup>(*f1.guard, MU<ConstantNode>(MU<FloatResultNode>(f1.doc0attr[2])))); ExpressionTree::Configure treeConf; et.select(treeConf, treeConf); @@ -230,11 +213,7 @@ TEST_F("testInterpolatedLookup", AttributeFixture()) { } TEST_F("testWithRelevance", AttributeFixture()) { - - ExpressionNode::CP r1(new RelevanceNode()); - ExpressionNode::CP l1(new InterpolatedLookup(*f1.guard, r1)); - - ExpressionTree et(l1); + ExpressionTree et(MU<InterpolatedLookup>(*f1.guard, MU<RelevanceNode>())); ExpressionTree::Configure treeConf; et.select(treeConf, treeConf); diff --git a/searchlib/src/tests/aggregator/perdocexpr.cpp b/searchlib/src/tests/aggregator/perdocexpr.cpp index c4c08e4de8f..81fbc964d9e 100644 --- a/searchlib/src/tests/aggregator/perdocexpr.cpp +++ b/searchlib/src/tests/aggregator/perdocexpr.cpp @@ -14,6 +14,8 @@ #include <cmath> #include <iostream> +#define MU std::make_unique + using namespace search; using namespace search::expression; using namespace search::aggregation; @@ -34,13 +36,13 @@ void testCmp(const T & small, const T & medium, const T & large); void testMin(const ResultNode & a, const ResultNode & b) { ASSERT_TRUE(a.cmp(b) < 0); MinFunctionNode func; - func.appendArg(ConstantNode(a)).appendArg(ConstantNode(b)).prepare(false) - .execute(); + func.appendArg(MU<ConstantNode>(ResultNode::UP(a.clone()))) + .appendArg(MU<ConstantNode>(ResultNode::UP(b.clone()))).prepare(false).execute(); ASSERT_TRUE(func.getResult().cmp(a) == 0); MinFunctionNode funcR; - funcR.appendArg(ConstantNode(b)).appendArg(ConstantNode(a)).prepare(false) - .execute(); + funcR.appendArg(MU<ConstantNode>(ResultNode::UP(b.clone()))) + .appendArg(MU<ConstantNode>(ResultNode::UP(a.clone()))).prepare(false).execute(); ASSERT_TRUE(funcR.getResult().cmp(a) == 0); } @@ -55,13 +57,15 @@ TEST("testMin") { void testMax(const ResultNode & a, const ResultNode & b) { ASSERT_TRUE(a.cmp(b) < 0); MaxFunctionNode func; - func.appendArg(ConstantNode(a)).appendArg(ConstantNode(b)).prepare(false) + func.appendArg(MU<ConstantNode>(ResultNode::UP(a.clone()))) + .appendArg(MU<ConstantNode>(ResultNode::UP(b.clone()))).prepare(false) .execute(); ASSERT_TRUE(func.getResult().cmp(b) == 0); MaxFunctionNode funcR; - funcR.appendArg(ConstantNode(b)).appendArg(ConstantNode(a)).prepare(false) - .execute(); + funcR.appendArg(MU<ConstantNode>(ResultNode::UP(a.clone()))) + .appendArg(MU<ConstantNode>(ResultNode::UP(b.clone()))).prepare(false) + .execute(); ASSERT_TRUE(funcR.getResult().cmp(b) == 0); } @@ -91,16 +95,14 @@ ExpressionCountAggregationResult getExpressionCountWithNormalSketch() { } void testExpressionCount(const ResultNode &a, uint32_t bucket, uint8_t val) { - ExpressionCountAggregationResult func = - getExpressionCountWithNormalSketch(); - func.setExpression(ConstantNode(a)); + ExpressionCountAggregationResult func = getExpressionCountWithNormalSketch(); + func.setExpression(MU<ConstantNode>(ResultNode::UP(a.clone()))); func.aggregate(DocId(42), HitRank(21)); const auto &sketch = func.getSketch(); auto normal = dynamic_cast<const NormalSketch<>&>(sketch); for (uint32_t i = 0; i < sketch.BUCKET_COUNT; ++i) { - TEST_STATE(make_string("Bucket %u. Expected bucket %u=%u", - i, bucket, val).c_str()); + TEST_STATE(make_string("Bucket %u. Expected bucket %u=%u", i, bucket, val).c_str()); EXPECT_EQUAL(i == bucket? val : 0, (int) normal.bucket[i]); } } @@ -114,14 +116,10 @@ TEST("require that expression count can operate on different results") { } TEST("require that expression counts can be merged") { - ExpressionCountAggregationResult func1 = - getExpressionCountWithNormalSketch(); - func1.setExpression(ConstantNode(Int64ResultNode(67))) - .aggregate(DocId(42), HitRank(21)); - ExpressionCountAggregationResult func2 = - getExpressionCountWithNormalSketch(); - func2.setExpression(ConstantNode(FloatResultNode(67))) - .aggregate(DocId(42), HitRank(21)); + ExpressionCountAggregationResult func1 = getExpressionCountWithNormalSketch(); + func1.setExpression(MU<ConstantNode>(MU<Int64ResultNode>(67))).aggregate(DocId(42), HitRank(21)); + ExpressionCountAggregationResult func2 = getExpressionCountWithNormalSketch(); + func2.setExpression(MU<ConstantNode>(MU<FloatResultNode>(67))).aggregate(DocId(42), HitRank(21)); EXPECT_EQUAL(2, func1.getRank().getInteger()); func1.merge(func2); @@ -134,10 +132,8 @@ TEST("require that expression counts can be merged") { TEST("require that expression counts can be serialized") { ExpressionCountAggregationResult func; - func.setExpression(ConstantNode(Int64ResultNode(67))) - .aggregate(DocId(42), HitRank(21)); - func.setExpression(ConstantNode(Int64ResultNode(68))) - .aggregate(DocId(42), HitRank(21)); + func.setExpression(MU<ConstantNode>(MU<Int64ResultNode>(67))).aggregate(DocId(42), HitRank(21)); + func.setExpression(MU<ConstantNode>(MU<Int64ResultNode>(68))).aggregate(DocId(42), HitRank(21)); nbostream os; NBOSerializer nos(os); @@ -149,24 +145,20 @@ TEST("require that expression counts can be serialized") { } TEST("require that expression count estimates rank") { - ExpressionCountAggregationResult func = - getExpressionCountWithNormalSketch(); + ExpressionCountAggregationResult func = getExpressionCountWithNormalSketch(); EXPECT_EQUAL(0, func.getRank().getInteger()); - func.setExpression(ConstantNode(Int64ResultNode(67))) - .aggregate(DocId(42), HitRank(21)); + func.setExpression(MU<ConstantNode>(MU<Int64ResultNode>(67))).aggregate(DocId(42), HitRank(21)); EXPECT_EQUAL(2, func.getRank().getInteger()); - func.setExpression(ConstantNode(FloatResultNode(67))) - .aggregate(DocId(42), HitRank(21)); + func.setExpression(MU<ConstantNode>(MU<FloatResultNode>(67))).aggregate(DocId(42), HitRank(21)); EXPECT_EQUAL(3, func.getRank().getInteger()); - func.setExpression(ConstantNode(FloatResultNode(67))) - .aggregate(DocId(42), HitRank(21)); + func.setExpression(MU<ConstantNode>(MU<FloatResultNode>(67))).aggregate(DocId(42), HitRank(21)); EXPECT_EQUAL(3, func.getRank().getInteger()); } void testAdd(const ResultNode &a, const ResultNode &b, const ResultNode &c) { AddFunctionNode func; - func.appendArg(ConstantNode(a)).appendArg(ConstantNode(b)).prepare(false) - .execute(); + func.appendArg(MU<ConstantNode>(ResultNode::UP(a.clone()))) + .appendArg(MU<ConstantNode>(ResultNode::UP(b.clone()))).prepare(false).execute(); EXPECT_EQUAL(func.getResult().asString(), c.asString()); EXPECT_EQUAL(func.getResult().cmp(c), 0); EXPECT_EQUAL(c.cmp(func.getResult()), 0); @@ -175,17 +167,14 @@ void testAdd(const ResultNode &a, const ResultNode &b, const ResultNode &c) { TEST("testAdd") { testAdd(Int64ResultNode(67), Int64ResultNode(68), Int64ResultNode(67+68)); testAdd(FloatResultNode(67), FloatResultNode(68), FloatResultNode(67+68)); - testAdd(StringResultNode("67"), StringResultNode("68"), - StringResultNode("lo")); - testAdd(RawResultNode("67", 2), RawResultNode("68", 2), - RawResultNode("lo", 2)); + testAdd(StringResultNode("67"), StringResultNode("68"), StringResultNode("lo")); + testAdd(RawResultNode("67", 2), RawResultNode("68", 2), RawResultNode("lo", 2)); } -void testDivide(const ResultNode &a, const ResultNode &b, - const ResultNode &c) { +void testDivide(const ResultNode &a, const ResultNode &b, const ResultNode &c) { DivideFunctionNode func; - func.appendArg(ConstantNode(a)).appendArg(ConstantNode(b)).prepare(false) - .execute(); + func.appendArg(MU<ConstantNode>(ResultNode::UP(a.clone()))) + .appendArg(MU<ConstantNode>(ResultNode::UP(b.clone()))).prepare(false).execute(); EXPECT_EQUAL(func.getResult().asString(), c.asString()); EXPECT_EQUAL(func.getResult().getFloat(), c.getFloat()); EXPECT_EQUAL(func.getResult().cmp(c), 0); @@ -193,17 +182,15 @@ void testDivide(const ResultNode &a, const ResultNode &b, } TEST("testDivide") { - testDivide(Int64ResultNode(6), FloatResultNode(12.0), - FloatResultNode(0.5)); + testDivide(Int64ResultNode(6), FloatResultNode(12.0), FloatResultNode(0.5)); testDivide(Int64ResultNode(6), Int64ResultNode(1), Int64ResultNode(6)); testDivide(Int64ResultNode(6), Int64ResultNode(0), Int64ResultNode(0)); } -void testModulo(const ResultNode &a, const ResultNode &b, - const ResultNode &c) { +void testModulo(const ResultNode &a, const ResultNode &b, const ResultNode &c) { ModuloFunctionNode func; - func.appendArg(ConstantNode(a)).appendArg(ConstantNode(b)).prepare(false) - .execute(); + func.appendArg(MU<ConstantNode>(ResultNode::UP(a.clone()))) + .appendArg(MU<ConstantNode>(ResultNode::UP(b.clone()))).prepare(false).execute(); EXPECT_EQUAL(func.getResult().asString(), c.asString()); EXPECT_EQUAL(func.getResult().getFloat(), c.getFloat()); EXPECT_EQUAL(func.getResult().cmp(c), 0); @@ -228,7 +215,7 @@ TEST("testModulo") { void testNegate(const ResultNode & a, const ResultNode & b) { NegateFunctionNode func; - func.appendArg(ConstantNode(a)).prepare(false).execute(); + func.appendArg(MU<ConstantNode>(ResultNode::UP(a.clone()))).prepare(false).execute(); EXPECT_EQUAL(func.getResult().asString(), b.asString()); EXPECT_EQUAL(func.getResult().cmp(b), 0); EXPECT_EQUAL(b.cmp(func.getResult()), 0); @@ -491,10 +478,7 @@ TEST("testTimeStamp") { namespace { std::string -getVespaChecksumV2( - const std::string& ymumid, - int fid, - const std::string& flags_str) +getVespaChecksumV2(const std::string& ymumid, int fid, const std::string& flags_str) { if (fid == 6 || fid == 0 || fid == 5) { return 0; @@ -537,10 +521,8 @@ TEST("testMailChecksumExpression") { std::string flags = "RWA"; std::string ymumid = "barmuda"; - document::Document::UP doc = - testDocMan.createDocument("foo", "userdoc:footype:1234:" + ymumid); - document::WeightedSetFieldValue - ws(doc->getField("byteweightedset").getDataType()); + document::Document::UP doc = testDocMan.createDocument("foo", "userdoc:footype:1234:" + ymumid); + document::WeightedSetFieldValue ws(doc->getField("byteweightedset").getDataType()); for (uint32_t i = 0; i < flags.size(); i++) { ws.add(document::ByteFieldValue(flags[i])); @@ -548,42 +530,33 @@ TEST("testMailChecksumExpression") { doc->setValue("headerval", document::IntFieldValue(folder)); doc->setValue("byteweightedset", ws); - CatFunctionNode e; + std::unique_ptr<CatFunctionNode> e = MU<CatFunctionNode>(); // YMUMID - GetDocIdNamespaceSpecificFunctionNode* ns = - new GetDocIdNamespaceSpecificFunctionNode( - ResultNode::UP(new StringResultNode)); - e.appendArg(ExpressionNode::CP(ns)); + e->appendArg(MU<GetDocIdNamespaceSpecificFunctionNode>(MU<StringResultNode>())); // Folder - e.appendArg(DocumentFieldNode("headerval")); + e->appendArg(MU<DocumentFieldNode>("headerval")); // Flags - e.appendArg(SortFunctionNode(DocumentFieldNode("byteweightedset"))); + e->appendArg(MU<SortFunctionNode>(MU<DocumentFieldNode>("byteweightedset"))); - MD5BitFunctionNode node(e, 32); + MD5BitFunctionNode node(std::move(e), 32); - CatFunctionNode &cfn = - static_cast<CatFunctionNode&>(*node.expressionNodeVector()[0]); - MultiArgFunctionNode::ExpressionNodeVector &xe = - cfn.expressionNodeVector(); + CatFunctionNode &cfn = static_cast<CatFunctionNode&>(*node.expressionNodeVector()[0]); + MultiArgFunctionNode::ExpressionNodeVector &xe = cfn.expressionNodeVector(); for (uint32_t i = 0; i < xe.size(); i++) { - DocumentAccessorNode* rf = - dynamic_cast<DocumentAccessorNode *>(xe[i].get()); + DocumentAccessorNode* rf = dynamic_cast<DocumentAccessorNode *>(xe[i].get()); if (rf) { rf->setDocType(doc->getType()); rf->prepare(true); rf->setDoc(*doc); } else { - MultiArgFunctionNode * mf = - dynamic_cast<MultiArgFunctionNode *>(xe[i].get()); - MultiArgFunctionNode::ExpressionNodeVector& se = - mf->expressionNodeVector(); + MultiArgFunctionNode * mf = dynamic_cast<MultiArgFunctionNode *>(xe[i].get()); + MultiArgFunctionNode::ExpressionNodeVector& se = mf->expressionNodeVector(); for (uint32_t j = 0; j < se.size(); j++) { - DocumentAccessorNode* tf = - dynamic_cast<DocumentAccessorNode *>(se[j].get()); + DocumentAccessorNode* tf = dynamic_cast<DocumentAccessorNode *>(se[j].get()); tf->setDocType(doc->getType()); tf->prepare(true); tf->setDoc(*doc); @@ -595,8 +568,7 @@ TEST("testMailChecksumExpression") { cfn.prepare(false); cfn.execute(); - ConstBufferRef ref = - static_cast<const RawResultNode &>(cfn.getResult()).get(); + ConstBufferRef ref = static_cast<const RawResultNode &>(cfn.getResult()).get(); std::string cmp = getVespaChecksumV2(ymumid, folder, flags); @@ -623,152 +595,129 @@ TEST("testMailChecksumExpression") { TEST("testDebugFunction") { { - AddFunctionNode add; - add.appendArg(ConstantNode(Int64ResultNode(3))); - add.appendArg(ConstantNode(Int64ResultNode(4))); - DebugWaitFunctionNode n(add, 1.3, false); + std::unique_ptr<AddFunctionNode> add = MU<AddFunctionNode>(); + add->appendArg(MU<ConstantNode>(MU<Int64ResultNode>(3))); + add->appendArg(MU<ConstantNode>(MU<Int64ResultNode>(4))); + DebugWaitFunctionNode n(std::move(add), 1.3, false); n.prepare(false); FastOS_Time time; time.SetNow(); n.execute(); EXPECT_TRUE(time.MilliSecsToNow() > 1000.0); - EXPECT_EQUAL(static_cast<const Int64ResultNode &>(n.getResult()).get(), - 7); + EXPECT_EQUAL(static_cast<const Int64ResultNode &>(n.getResult()).get(), 7); } { - AddFunctionNode add; - add.appendArg(ConstantNode(Int64ResultNode(3))); - add.appendArg(ConstantNode(Int64ResultNode(4))); - DebugWaitFunctionNode n(add, 1.3, true); + std::unique_ptr<AddFunctionNode> add = MU<AddFunctionNode>(); + add->appendArg(MU<ConstantNode>(MU<Int64ResultNode>(3))); + add->appendArg(MU<ConstantNode>(MU<Int64ResultNode>(4))); + DebugWaitFunctionNode n(std::move(add), 1.3, true); n.prepare(false); FastOS_Time time; time.SetNow(); n.execute(); EXPECT_TRUE(time.MilliSecsToNow() > 1000.0); - EXPECT_EQUAL(static_cast<const Int64ResultNode &>(n.getResult()).get(), - 7); + EXPECT_EQUAL(static_cast<const Int64ResultNode &>(n.getResult()).get(), 7); } } +template<typename V> +ResultNode::UP +createIntRV(std::vector<int64_t> values) { + using T = typename V::BaseType; + std::unique_ptr<V> r = MU<V>(); + for (int64_t v : values) { + r->push_back(T(v)); + } + return r; +} + TEST("testDivExpressions") { { - StrLenFunctionNode e(ConstantNode(Int64ResultNode(238686))); + StrLenFunctionNode e(MU<ConstantNode>(MU<Int64ResultNode>(238686))); e.prepare(false); e.execute(); - EXPECT_EQUAL(static_cast<const Int64ResultNode &>(e.getResult()).get(), - 6); + EXPECT_EQUAL(static_cast<const Int64ResultNode &>(e.getResult()).get(), 6); } { - NormalizeSubjectFunctionNode - e(ConstantNode(StringResultNode("Re: Your mail"))); + NormalizeSubjectFunctionNode e(MU<ConstantNode>(MU<StringResultNode>("Re: Your mail"))); e.prepare(false); e.execute(); - EXPECT_EQUAL( - static_cast<const StringResultNode &>(e.getResult()).get(), - "Your mail"); + EXPECT_EQUAL(static_cast<const StringResultNode &>(e.getResult()).get(), "Your mail"); } { - NormalizeSubjectFunctionNode - e(ConstantNode(StringResultNode("Your mail"))); + NormalizeSubjectFunctionNode e(MU<ConstantNode>(MU<StringResultNode>("Your mail"))); e.prepare(false); e.execute(); - EXPECT_EQUAL( - static_cast<const StringResultNode &>(e.getResult()).get(), - "Your mail"); + EXPECT_EQUAL(static_cast<const StringResultNode &>(e.getResult()).get(), "Your mail"); } { - StrCatFunctionNode e(ConstantNode(Int64ResultNode(238686))); - e.appendArg(ConstantNode(StringResultNode("ARG 2"))); + StrCatFunctionNode e(MU<ConstantNode>(MU<Int64ResultNode>(238686))); + e.appendArg(MU<ConstantNode>(MU<StringResultNode>("ARG 2"))); e.prepare(false); e.execute(); - EXPECT_EQUAL( - static_cast<const StringResultNode &>(e.getResult()).get(), - "238686ARG 2"); + EXPECT_EQUAL(static_cast<const StringResultNode &>(e.getResult()).get(), "238686ARG 2"); } { - ToStringFunctionNode e(ConstantNode(Int64ResultNode(238686))); + ToStringFunctionNode e(MU<ConstantNode>(MU<Int64ResultNode>(238686))); e.prepare(false); e.execute(); - EXPECT_EQUAL(strcmp(static_cast<const StringResultNode &>( - e.getResult()).get().c_str(), "238686"), 0); + EXPECT_EQUAL(strcmp(static_cast<const StringResultNode &>(e.getResult()).get().c_str(), "238686"), 0); } { - ToRawFunctionNode e(ConstantNode(Int64ResultNode(238686))); + ToRawFunctionNode e(MU<ConstantNode>(MU<Int64ResultNode>(238686))); e.prepare(false); e.execute(); - EXPECT_EQUAL(strcmp(static_cast<const RawResultNode &>( - e.getResult()).get().c_str(), "238686"), 0); + EXPECT_EQUAL(strcmp(static_cast<const RawResultNode &>(e.getResult()).get().c_str(), "238686"), 0); } { - CatFunctionNode e(ConstantNode(Int64ResultNode(238686))); + CatFunctionNode e(MU<ConstantNode>(MU<Int64ResultNode>(238686))); e.prepare(false); e.execute(); - EXPECT_EQUAL( - static_cast<const RawResultNode &>(e.getResult()).get().size(), - 8u); + EXPECT_EQUAL(static_cast<const RawResultNode &>(e.getResult()).get().size(), 8u); } { - CatFunctionNode e(ConstantNode(Int32ResultNode(23886))); + CatFunctionNode e(MU<ConstantNode>(MU<Int32ResultNode>(23886))); e.prepare(false); e.execute(); - EXPECT_EQUAL( - static_cast<const RawResultNode &>(e.getResult()).get().size(), - 4u); + EXPECT_EQUAL(static_cast<const RawResultNode &>(e.getResult()).get().size(), 4u); } { const uint8_t buf[4] = { 0, 0, 0, 7 }; - MD5BitFunctionNode - e(ConstantNode(RawResultNode(buf, sizeof(buf))), 16*8); + MD5BitFunctionNode e(MU<ConstantNode>(MU<RawResultNode>(buf, sizeof(buf))), 16*8); e.prepare(false); e.execute(); ASSERT_TRUE(e.getResult().getClass().inherits(RawResultNode::classId)); - const RawResultNode & - r(static_cast<const RawResultNode &>(e.getResult())); + const RawResultNode &r(static_cast<const RawResultNode &>(e.getResult())); EXPECT_EQUAL(r.get().size(), 16u); } { const uint8_t buf[4] = { 0, 0, 0, 7 }; - MD5BitFunctionNode - e(ConstantNode(RawResultNode(buf, sizeof(buf))), 2*8); + MD5BitFunctionNode e(MU<ConstantNode>(MU<RawResultNode>(buf, sizeof(buf))), 2*8); e.prepare(false); e.execute(); - EXPECT_EQUAL( - static_cast<const RawResultNode &>(e.getResult()).get().size(), - 2u); + EXPECT_EQUAL(static_cast<const RawResultNode &>(e.getResult()).get().size(), 2u); } { const uint8_t buf[4] = { 0, 0, 0, 7 }; - XorBitFunctionNode - e(ConstantNode(RawResultNode(buf, sizeof(buf))), 1*8); + XorBitFunctionNode e(MU<ConstantNode>(MU<RawResultNode>(buf, sizeof(buf))), 1*8); e.prepare(false); e.execute(); - EXPECT_EQUAL( - static_cast<const RawResultNode &>(e.getResult()).get().size(), - 1u); - EXPECT_EQUAL(static_cast<const RawResultNode &>( - e.getResult()).get().c_str()[0], - 0x7); + EXPECT_EQUAL(static_cast<const RawResultNode &>(e.getResult()).get().size(), 1u); + EXPECT_EQUAL(static_cast<const RawResultNode &>(e.getResult()).get().c_str()[0], 0x7); } { const uint8_t buf[4] = { 6, 0, 7, 7 }; - XorBitFunctionNode - e(ConstantNode(RawResultNode(buf, sizeof(buf))), 2*8); + XorBitFunctionNode e(MU<ConstantNode>(MU<RawResultNode>(buf, sizeof(buf))), 2*8); e.prepare(false); e.execute(); - EXPECT_EQUAL( - static_cast<const RawResultNode &>(e.getResult()).get().size(), - 2u); - EXPECT_EQUAL((int)static_cast<const RawResultNode &>( - e.getResult()).get().c_str()[0], - 0x1); - EXPECT_EQUAL((int)static_cast<const RawResultNode &>( - e.getResult()).get().c_str()[1], - 0x7); + EXPECT_EQUAL(static_cast<const RawResultNode &>(e.getResult()).get().size(), 2u); + EXPECT_EQUAL((int)static_cast<const RawResultNode &>(e.getResult()).get().c_str()[0], 0x1); + EXPECT_EQUAL((int)static_cast<const RawResultNode &>(e.getResult()).get().c_str()[1], 0x7); } { const uint8_t wantedBuf[14] = @@ -783,13 +732,11 @@ TEST("testDivExpressions") { { 0, 0, 0, 22, 0, 0, 0, 7, 98, 97, 114, 109, 117, 100, 97, 0, 0, 0, 32, 0 , 0, 0, 3, 65, 82, 87 }; - MD5BitFunctionNode - e(ConstantNode(RawResultNode(wantedBuf, sizeof(wantedBuf))), 16*8); + MD5BitFunctionNode e(MU<ConstantNode>(MU<RawResultNode>(wantedBuf, sizeof(wantedBuf))), 16*8); e.prepare(false); e.execute(); ASSERT_TRUE(e.getResult().getClass().inherits(RawResultNode::classId)); - const RawResultNode & - r(static_cast<const RawResultNode &>(e.getResult())); + const RawResultNode &r(static_cast<const RawResultNode &>(e.getResult())); EXPECT_EQUAL(r.get().size(), 16u); uint8_t md5[16]; fastc_md5sum(currentBuf, sizeof(currentBuf), md5); @@ -799,87 +746,62 @@ TEST("testDivExpressions") { fastc_md5sum(thomasBuf, sizeof(thomasBuf), md5); EXPECT_TRUE(memcmp(r.get().data(), md5, sizeof(md5)) != 0); - MD5BitFunctionNode - finalCheck( - CatFunctionNode(ConstantNode(StringResultNode("barmuda"))) - .appendArg(ConstantNode(Int32ResultNode(32))) - .appendArg(SortFunctionNode( - ConstantNode(Int8ResultNodeVector() - .push_back(Int8ResultNode(87)) - .push_back(Int8ResultNode(65)) - .push_back(Int8ResultNode(82)) - ) - ) - ), 32); + std::unique_ptr<CatFunctionNode> cat = MU<CatFunctionNode>(MU<ConstantNode>(MU<StringResultNode>("barmuda"))); + cat->appendArg(MU<ConstantNode>(MU<Int32ResultNode>(32))); + cat->appendArg(MU<SortFunctionNode>(MU<ConstantNode>(createIntRV<Int8ResultNodeVector>({87, 65, 82})))); + + MD5BitFunctionNode finalCheck(std::move(cat), 32); finalCheck.prepare(false); finalCheck.execute(); - const RawResultNode & - rr(static_cast<const RawResultNode &>(finalCheck.getResult())); + const RawResultNode &rr(static_cast<const RawResultNode &>(finalCheck.getResult())); EXPECT_EQUAL(rr.get().size(), 4u); fastc_md5sum(wantedBuf, sizeof(wantedBuf), md5); EXPECT_TRUE(memcmp(md5facit, md5, sizeof(md5)) == 0); EXPECT_TRUE(memcmp(rr.get().data(), md5, rr.get().size()) == 0); } { - CatFunctionNode e(ConstantNode(Int16ResultNode(23886))); + CatFunctionNode e(MU<ConstantNode>(MU<Int16ResultNode>(23886))); e.prepare(false); e.execute(); - EXPECT_EQUAL( - static_cast<const RawResultNode &>(e.getResult()).get().size(), - 2u); + EXPECT_EQUAL(static_cast<const RawResultNode &>(e.getResult()).get().size(), 2u); } { - CatFunctionNode - e(ConstantNode(Int8ResultNodeVector().push_back(Int8ResultNode(86)) - .push_back(Int8ResultNode(14)))); + CatFunctionNode e(MU<ConstantNode>(createIntRV<Int8ResultNodeVector>({86, 14}))); e.prepare(false); e.execute(); - EXPECT_EQUAL( - static_cast<const RawResultNode &>(e.getResult()).get().size(), - 1*2u); + EXPECT_EQUAL(static_cast<const RawResultNode &>(e.getResult()).get().size(), 1*2u); } { - CatFunctionNode - e(ConstantNode(Int32ResultNodeVector() - .push_back(Int32ResultNode(238686)) - .push_back(Int32ResultNode(2133214)))); + CatFunctionNode e(MU<ConstantNode>(createIntRV<Int32ResultNodeVector>({238686,2133214}))); e.prepare(false); e.execute(); - EXPECT_EQUAL( - static_cast<const RawResultNode &>(e.getResult()).get().size(), - 4*2u); + EXPECT_EQUAL(static_cast<const RawResultNode &>(e.getResult()).get().size(), 4*2u); } { - NumElemFunctionNode e(ConstantNode(Int64ResultNode(238686))); + NumElemFunctionNode e(MU<ConstantNode>(MU<Int64ResultNode>(238686))); e.prepare(false); e.execute(); EXPECT_EQUAL(e.getResult().getInteger(), 1); } { - NumElemFunctionNode - e(ConstantNode(Int32ResultNodeVector() - .push_back(Int32ResultNode(238686)) - .push_back(Int32ResultNode(2133214)))); + NumElemFunctionNode e(MU<ConstantNode>(createIntRV<Int32ResultNodeVector>({238686,2133214}))); e.prepare(false); e.execute(); EXPECT_EQUAL(e.getResult().getInteger(), 2); } { - NumElemFunctionNode - e(ConstantNode(Int32ResultNodeVector() - .push_back(Int32ResultNode(238686)) - .push_back(Int32ResultNode(2133214)))); + NumElemFunctionNode e(MU<ConstantNode>(createIntRV<Int32ResultNodeVector>({238686,2133214}))); e.prepare(false); e.execute(); EXPECT_EQUAL(e.getResult().getInteger(), 2); } } -bool test1MultivalueExpression(const MultiArgFunctionNode &exprConst, - const ExpressionNode::CP &mv, - const ResultNode & expected) { +bool test1MultivalueExpression(const MultiArgFunctionNode &exprConst, ExpressionNode::UP mv, + const ResultNode & expected) +{ MultiArgFunctionNode & expr(const_cast<MultiArgFunctionNode &>(exprConst)); - expr.appendArg(mv); + expr.appendArg(std::move(mv)); expr.prepare(false); bool ok = EXPECT_TRUE(expr.execute()) && EXPECT_EQUAL(0, expr.getResult().cmp(expected)); @@ -891,40 +813,43 @@ bool test1MultivalueExpression(const MultiArgFunctionNode &exprConst, } bool test1MultivalueExpressionException(const MultiArgFunctionNode & exprConst, - const ExpressionNode::CP & mv, + ExpressionNode::UP mv, const char * expected) { try { - test1MultivalueExpression(exprConst, mv, NullResultNode()); + test1MultivalueExpression(exprConst, std::move(mv), NullResultNode()); return EXPECT_TRUE(false); } catch (std::runtime_error & e) { - return EXPECT_TRUE(std::string(e.what()).find(expected) - != std::string::npos); + return EXPECT_TRUE(std::string(e.what()).find(expected) != std::string::npos); } } TEST("testMultivalueExpression") { - IntegerResultNodeVector iv; - iv.push_back(Int64ResultNode(7)) - .push_back(Int64ResultNode(17)).push_back(Int64ResultNode(117)); - ExpressionNode::CP mv(new ConstantNode(iv)); + std::vector<int64_t> IV = {7, 17, 117}; - EXPECT_TRUE(test1MultivalueExpression(AddFunctionNode(), mv, + EXPECT_TRUE(test1MultivalueExpression(AddFunctionNode(), + MU<ConstantNode>(createIntRV<Int64ResultNodeVector>(IV)), Int64ResultNode(7 + 17 + 117))); - EXPECT_TRUE(test1MultivalueExpression(MultiplyFunctionNode(), mv, + EXPECT_TRUE(test1MultivalueExpression(MultiplyFunctionNode(), + MU<ConstantNode>(createIntRV<Int64ResultNodeVector>(IV)), Int64ResultNode(7 * 17 * 117))); - EXPECT_TRUE(test1MultivalueExpressionException(DivideFunctionNode(), mv, + EXPECT_TRUE(test1MultivalueExpressionException(DivideFunctionNode(), + MU<ConstantNode>(createIntRV<Int64ResultNodeVector>(IV)), "DivideFunctionNode")); - EXPECT_TRUE(test1MultivalueExpressionException(ModuloFunctionNode(), mv, + EXPECT_TRUE(test1MultivalueExpressionException(ModuloFunctionNode(), + MU<ConstantNode>(createIntRV<Int64ResultNodeVector>(IV)), "ModuloFunctionNode")); - EXPECT_TRUE(test1MultivalueExpression(MinFunctionNode(), mv, + EXPECT_TRUE(test1MultivalueExpression(MinFunctionNode(), + MU<ConstantNode>(createIntRV<Int64ResultNodeVector>(IV)), Int64ResultNode(7))); - EXPECT_TRUE(test1MultivalueExpression(MaxFunctionNode(), mv, + EXPECT_TRUE(test1MultivalueExpression(MaxFunctionNode(), + MU<ConstantNode>(createIntRV<Int64ResultNodeVector>(IV)), Int64ResultNode(117))); EXPECT_TRUE( test1MultivalueExpression( FixedWidthBucketFunctionNode() - .setWidth(Int64ResultNode(1)), mv, + .setWidth(Int64ResultNode(1)), + MU<ConstantNode>(createIntRV<Int64ResultNodeVector>(IV)), IntegerBucketResultNodeVector() .push_back(IntegerBucketResultNode(7,8)) .push_back(IntegerBucketResultNode(17,18)) @@ -938,7 +863,7 @@ TEST("testMultivalueExpression") { .push_back(IntegerBucketResultNode(0,10)) .push_back(IntegerBucketResultNode(20,30)) .push_back(IntegerBucketResultNode(100,120))), - mv, + MU<ConstantNode>(createIntRV<Int64ResultNodeVector>(IV)), IntegerBucketResultNodeVector() .push_back(IntegerBucketResultNode(0,10)) .push_back(IntegerBucketResultNode(0,0)) @@ -947,114 +872,105 @@ TEST("testMultivalueExpression") { EXPECT_TRUE( test1MultivalueExpression( TimeStampFunctionNode() - .setTimePart(TimeStampFunctionNode::Second), mv, + .setTimePart(TimeStampFunctionNode::Second), + MU<ConstantNode>(createIntRV<Int64ResultNodeVector>(IV)), IntegerResultNodeVector() .push_back(Int64ResultNode(7)) .push_back(Int64ResultNode(17)) .push_back(Int64ResultNode(117%60)))); EXPECT_TRUE( - test1MultivalueExpression(NegateFunctionNode(), mv, + test1MultivalueExpression(NegateFunctionNode(), + MU<ConstantNode>(createIntRV<Int64ResultNodeVector>(IV)), IntegerResultNodeVector() .push_back(Int64ResultNode(-7)) .push_back(Int64ResultNode(-17)) .push_back(Int64ResultNode(-117)))); - EXPECT_TRUE(test1MultivalueExpression(SortFunctionNode(), mv, + EXPECT_TRUE(test1MultivalueExpression(SortFunctionNode(), + MU<ConstantNode>(createIntRV<Int64ResultNodeVector>(IV)), IntegerResultNodeVector() .push_back(Int64ResultNode(7)) .push_back(Int64ResultNode(17)) .push_back(Int64ResultNode(117)))); - EXPECT_TRUE(test1MultivalueExpression(ReverseFunctionNode(), mv, + EXPECT_TRUE(test1MultivalueExpression(ReverseFunctionNode(), + MU<ConstantNode>(createIntRV<Int64ResultNodeVector>(IV)), IntegerResultNodeVector() .push_back(Int64ResultNode(117)) .push_back(Int64ResultNode(17)) .push_back(Int64ResultNode(7)))); EXPECT_TRUE(test1MultivalueExpression(SortFunctionNode(), - ReverseFunctionNode(mv), + MU<ReverseFunctionNode>(MU<ConstantNode>(createIntRV<Int64ResultNodeVector>(IV))), IntegerResultNodeVector() .push_back(Int64ResultNode(7)) .push_back(Int64ResultNode(17)) .push_back(Int64ResultNode(117)))); - EXPECT_TRUE(test1MultivalueExpression(AndFunctionNode(), mv, + EXPECT_TRUE(test1MultivalueExpression(AndFunctionNode(), + MU<ConstantNode>(createIntRV<Int64ResultNodeVector>(IV)), Int64ResultNode(7 & 17 & 117))); - EXPECT_TRUE(test1MultivalueExpression(OrFunctionNode(), mv, + EXPECT_TRUE(test1MultivalueExpression(OrFunctionNode(), + MU<ConstantNode>(createIntRV<Int64ResultNodeVector>(IV)), Int64ResultNode(7 | 17 | 117))); - EXPECT_TRUE(test1MultivalueExpression(XorFunctionNode(), mv, + EXPECT_TRUE(test1MultivalueExpression(XorFunctionNode(), + MU<ConstantNode>(createIntRV<Int64ResultNodeVector>(IV)), Int64ResultNode(7 ^ 17 ^ 117))); } +ExpressionNode::UP createScalarInt(int64_t v) { return MU<ConstantNode>(MU<Int64ResultNode>(v)); } +ExpressionNode::UP createScalarFloat(double v) { return MU<ConstantNode>(MU<FloatResultNode>(v)); } +ExpressionNode::UP createScalarString(const char * v) { return MU<ConstantNode>(MU<StringResultNode>(v)); } +ExpressionNode::UP createScalarRaw(const char * v) { return MU<ConstantNode>(MU<RawResultNode>(v, strlen(v))); } + TEST("testArithmeticNodes") { AttributeGuard attr1 = createInt64Attribute(); - ExpressionNode::CP i1(new ConstantNode(new Int64ResultNode(1))); - ExpressionNode::CP i2(new ConstantNode(new Int64ResultNode(2))); - ExpressionNode::CP f1(new ConstantNode(new FloatResultNode(1.1))); - ExpressionNode::CP f2(new ConstantNode(new FloatResultNode(9.9))); - ExpressionNode::CP s1(new ConstantNode(new StringResultNode("1"))); - ExpressionNode::CP s2(new ConstantNode(new StringResultNode("2"))); - ExpressionNode::CP r1(new ConstantNode(new RawResultNode("1", 1))); - ExpressionNode::CP r2(new ConstantNode(new RawResultNode("2", 1))); - ExpressionNode::CP a1(new AttributeNode(*attr1)); - ExpressionNode::CP a2(new AttributeNode(*attr1)); + constexpr int64_t I1 = 1, I2 = 2; + constexpr double F1 = 1.1, F2 = 9.9; + constexpr const char * S2 = "2"; + AddFunctionNode add1; - add1.appendArg(i1); - add1.appendArg(i2); + add1.appendArg(createScalarInt(I1)); + add1.appendArg(createScalarInt(I2)); ExpressionTree et(add1); ExpressionTree::Configure treeConf; et.select(treeConf, treeConf); - EXPECT_TRUE( - et.getResult().getClass().inherits(IntegerResultNode::classId)); + EXPECT_TRUE(et.getResult().getClass().inherits(IntegerResultNode::classId)); EXPECT_TRUE(et.ExpressionNode::execute()); EXPECT_EQUAL(et.getResult().getInteger(), 3); EXPECT_TRUE(et.ExpressionNode::execute()); EXPECT_EQUAL(et.getResult().getInteger(), 3); AddFunctionNode add2; - add2.appendArg(i1); - add2.appendArg(f2); + add2.appendArg(createScalarInt(I1)); + add2.appendArg(createScalarFloat(F2)); add2.prepare(false); - EXPECT_TRUE( - add2.getResult().getClass().inherits(FloatResultNode::classId)); + EXPECT_TRUE(add2.getResult().getClass().inherits(FloatResultNode::classId)); AddFunctionNode add3; - add3.appendArg(i1); - add3.appendArg(s2); + add3.appendArg(createScalarInt(I1)); + add3.appendArg(createScalarString(S2)); add3.prepare(false); - EXPECT_TRUE( - add3.getResult().getClass().inherits(IntegerResultNode::classId)); + EXPECT_TRUE(add3.getResult().getClass().inherits(IntegerResultNode::classId)); AddFunctionNode add4; - add4.appendArg(i1); - add4.appendArg(r2); + add4.appendArg(createScalarInt(I1)); + add4.appendArg(createScalarRaw(S2)); add4.prepare(false); - EXPECT_TRUE( - add4.getResult().getClass().inherits(IntegerResultNode::classId)); + EXPECT_TRUE(add4.getResult().getClass().inherits(IntegerResultNode::classId)); AddFunctionNode add5; - add5.appendArg(i1); - add5.appendArg(a1); + add5.appendArg(createScalarInt(I1)); + add5.appendArg(MU<AttributeNode>(*attr1)); add5.prepare(false); - EXPECT_TRUE( - add5.getResult().getClass().inherits(IntegerResultNode::classId)); + EXPECT_TRUE(add5.getResult().getClass().inherits(IntegerResultNode::classId)); AddFunctionNode add6; - add6.appendArg(f1); - add6.appendArg(a1); + add6.appendArg(createScalarFloat(F1)); + add6.appendArg(MU<AttributeNode>(*attr1)); add6.prepare(false); - EXPECT_TRUE( - add6.getResult().getClass().inherits(FloatResultNode::classId)); -} - -void testArith(MultiArgFunctionNode &op, const ExpressionNode::CP &arg1, - const ExpressionNode::CP & arg2, int64_t intResult, - double floatResult) { - op.appendArg(arg1); - op.appendArg(arg2); - op.prepare(false); - op.execute(); - EXPECT_EQUAL(intResult, op.getResult().getInteger()); - ASSERT_TRUE(intResult == op.getResult().getInteger()); - EXPECT_EQUAL(floatResult, op.getResult().getFloat()); + EXPECT_TRUE(add6.getResult().getClass().inherits(FloatResultNode::classId)); } -void testArith2(MultiArgFunctionNode &op, int64_t intResult, - double floatResult) { +void testArith(MultiArgFunctionNode &op, ExpressionNode::UP arg1, ExpressionNode::UP arg2, + int64_t intResult, double floatResult) +{ + op.appendArg(std::move(arg1)); + op.appendArg(std::move(arg2)); op.prepare(false); op.execute(); EXPECT_EQUAL(intResult, op.getResult().getInteger()); @@ -1062,64 +978,57 @@ void testArith2(MultiArgFunctionNode &op, int64_t intResult, EXPECT_EQUAL(floatResult, op.getResult().getFloat()); } -void testAdd(const ExpressionNode::CP &arg1, - const ExpressionNode::CP &arg2, - int64_t intResult, double floatResult){ +void testAdd(ExpressionNode::UP arg1, ExpressionNode::UP arg2, + int64_t intResult, double floatResult) +{ AddFunctionNode add; - testArith(add, arg1, arg2, intResult, floatResult); + testArith(add, std::move(arg1), std::move(arg2), intResult, floatResult); } -void testMultiply(const ExpressionNode::CP & arg1, - const ExpressionNode::CP & arg2, - int64_t intResult, double floatResult) { +void testMultiply(ExpressionNode::UP arg1, ExpressionNode::UP arg2, + int64_t intResult, double floatResult) +{ MultiplyFunctionNode add; - testArith(add, arg1, arg2, intResult, floatResult); + testArith(add, std::move(arg1), std::move(arg2), intResult, floatResult); } -void testDivide(const ExpressionNode::CP & arg1, - const ExpressionNode::CP & arg2, - int64_t intResult, double floatResult) { +void testDivide(ExpressionNode::UP arg1, ExpressionNode::UP arg2, + int64_t intResult, double floatResult) +{ DivideFunctionNode add; - testArith(add, arg1, arg2, intResult, floatResult); + testArith(add, std::move(arg1), std::move(arg2), intResult, floatResult); } -void testModulo(const ExpressionNode::CP & arg1, - const ExpressionNode::CP & arg2, - int64_t intResult, double floatResult) { +void testModulo(ExpressionNode::UP arg1, ExpressionNode::UP arg2, + int64_t intResult, double floatResult) +{ ModuloFunctionNode add; - testArith(add, arg1, arg2, intResult, floatResult); + testArith(add, std::move(arg1), std::move(arg2), intResult, floatResult); } -void testArithmeticArguments(NumericFunctionNode &function, - std::vector<double> & arg1, - std::vector<double> & arg2, - const std::vector<double> & result, - double flattenResult) { - ExpressionNode::CP scalarInt1(new ConstantNode(new Int64ResultNode( - static_cast<int64_t>(arg1[0])))); - ExpressionNode::CP scalarInt2(new ConstantNode(new Int64ResultNode( - static_cast<int64_t>(arg2[0])))); - ExpressionNode::CP scalarFloat1(new ConstantNode(new FloatResultNode( - arg1[0]))); - ExpressionNode::CP scalarFloat2(new ConstantNode(new FloatResultNode( - arg2[0]))); - - IntegerResultNodeVector iv1; - for (size_t i(0), m(arg1.size()); i<m; i++) { - iv1.push_back(Int64ResultNode(static_cast<int64_t>(arg1[i]))); +ExpressionNode::UP +createVectorInt(const std::vector<double> & v) { + std::unique_ptr<IntegerResultNodeVector> r = MU<IntegerResultNodeVector>(); + for (double d : v) { + r->push_back(Int64ResultNode(static_cast<int64_t>(d))); } - IntegerResultNodeVector iv2; - for (size_t i(0), m(arg2.size()); i<m; i++) { - iv2.push_back(Int64ResultNode(static_cast<int64_t>(arg2[i]))); - } - FloatResultNodeVector fv1; - for (size_t i(0), m(arg1.size()); i<m; i++) { - fv1.push_back(FloatResultNode(arg1[i])); - } - FloatResultNodeVector fv2; - for (size_t i(0), m(arg2.size()); i<m; i++) { - fv2.push_back(FloatResultNode(arg2[i])); + return MU<ConstantNode>(std::move(r)); +} +ExpressionNode::UP +createVectorFloat(const std::vector<double> & v) { + std::unique_ptr<FloatResultNodeVector> r = MU<FloatResultNodeVector>(); + for (double d : v) { + r->push_back(FloatResultNode(d)); } + return MU<ConstantNode>(std::move(r)); +} + +void testArithmeticArguments(NumericFunctionNode &function, + const std::vector<double> & arg1, + const std::vector<double> & arg2, + const std::vector<double> & result, + double flattenResult) +{ IntegerResultNodeVector ir; for (size_t i(0), m(result.size()); i<m; i++) { ir.push_back(Int64ResultNode((int64_t)result[i])); @@ -1128,128 +1037,105 @@ void testArithmeticArguments(NumericFunctionNode &function, for (size_t i(0), m(result.size()); i<m; i++) { fr.push_back(FloatResultNode(result[i])); } - ExpressionNode::CP vectorInt1(new ConstantNode(iv1)); - ExpressionNode::CP vectorInt2(new ConstantNode(iv2)); - ExpressionNode::CP vectorFloat1(new ConstantNode(fv1)); - ExpressionNode::CP vectorFloat2(new ConstantNode(fv2)); - function.appendArg(scalarInt1).appendArg(scalarInt2); + function.appendArg(createScalarInt(arg1[0])).appendArg(createScalarInt(arg2[0])); function.prepare(false); - EXPECT_TRUE( - function.getResult().getClass().equal(Int64ResultNode::classId)); + EXPECT_TRUE(function.getResult().getClass().equal(Int64ResultNode::classId)); EXPECT_TRUE(function.execute()); - EXPECT_EQUAL(function.getResult().getInteger(), - static_cast<int64_t>(result[0])); + EXPECT_EQUAL(function.getResult().getInteger(), static_cast<int64_t>(result[0])); function.reset(); - function.appendArg(scalarInt1).appendArg(scalarFloat2); + function.appendArg(createScalarInt(arg1[0])).appendArg(createScalarFloat(arg2[0])); function.prepare(false); - EXPECT_TRUE( - function.getResult().getClass().equal(FloatResultNode::classId)); + EXPECT_TRUE(function.getResult().getClass().equal(FloatResultNode::classId)); EXPECT_TRUE(function.execute()); EXPECT_EQUAL(function.getResult().getFloat(), result[0]); function.reset(); - function.appendArg(scalarFloat1).appendArg(scalarInt2); + function.appendArg(createScalarFloat(arg1[0])).appendArg(createScalarInt(arg2[0])); function.prepare(false); - EXPECT_TRUE( - function.getResult().getClass().equal(FloatResultNode::classId)); + EXPECT_TRUE(function.getResult().getClass().equal(FloatResultNode::classId)); EXPECT_TRUE(function.execute()); EXPECT_EQUAL(function.getResult().getFloat(), result[0]); function.reset(); - function.appendArg(scalarFloat1).appendArg(scalarFloat2); + function.appendArg(createScalarFloat(arg1[0])).appendArg(createScalarFloat(arg2[0])); function.prepare(false); - EXPECT_TRUE( - function.getResult().getClass().equal(FloatResultNode::classId)); + EXPECT_TRUE(function.getResult().getClass().equal(FloatResultNode::classId)); EXPECT_TRUE(function.execute()); EXPECT_EQUAL(function.getResult().getFloat(), result[0]); function.reset(); - function.appendArg(vectorInt1); + function.appendArg(createVectorInt(arg1)); function.prepare(false); - EXPECT_TRUE( - function.getResult().getClass().equal(Int64ResultNode::classId)); + EXPECT_TRUE(function.getResult().getClass().equal(Int64ResultNode::classId)); EXPECT_TRUE(function.execute()); - EXPECT_EQUAL(function.getResult().getInteger(), - static_cast<int64_t>(flattenResult)); + EXPECT_EQUAL(function.getResult().getInteger(), static_cast<int64_t>(flattenResult)); function.reset(); - function.appendArg(vectorFloat1); + function.appendArg(createVectorFloat(arg1)); function.prepare(false); - EXPECT_TRUE( - function.getResult().getClass().equal(FloatResultNode::classId)); + EXPECT_TRUE(function.getResult().getClass().equal(FloatResultNode::classId)); EXPECT_TRUE(function.execute()); EXPECT_EQUAL(function.getResult().getFloat(), flattenResult); function.reset(); - function.appendArg(vectorInt1).appendArg(vectorInt2); + function.appendArg(createVectorInt(arg1)).appendArg(createVectorInt(arg2)); function.prepare(false); - EXPECT_TRUE(function.getResult().getClass() - .equal(IntegerResultNodeVector::classId)); + EXPECT_TRUE(function.getResult().getClass().equal(IntegerResultNodeVector::classId)); EXPECT_TRUE(function.execute()); - EXPECT_TRUE(function.getResult().getClass() - .equal(IntegerResultNodeVector::classId)); - EXPECT_EQUAL(static_cast<const IntegerResultNodeVector &>( - function.getResult()).size(), 7u); + EXPECT_TRUE(function.getResult().getClass().equal(IntegerResultNodeVector::classId)); + EXPECT_EQUAL(static_cast<const IntegerResultNodeVector &>(function.getResult()).size(), 7u); EXPECT_EQUAL(0, function.getResult().cmp(ir)); function.reset(); - function.appendArg(vectorFloat1).appendArg(vectorFloat2); + function.appendArg(createVectorFloat(arg1)).appendArg(createVectorFloat(arg2)); function.prepare(false); - EXPECT_TRUE(function.getResult().getClass() - .equal(FloatResultNodeVector::classId)); + EXPECT_TRUE(function.getResult().getClass().equal(FloatResultNodeVector::classId)); EXPECT_TRUE(function.execute()); - EXPECT_TRUE(function.getResult().getClass() - .equal(FloatResultNodeVector::classId)); - EXPECT_EQUAL(static_cast<const FloatResultNodeVector &>( - function.getResult()).size(), 7u); + EXPECT_TRUE(function.getResult().getClass().equal(FloatResultNodeVector::classId)); + EXPECT_EQUAL(static_cast<const FloatResultNodeVector &>(function.getResult()).size(), 7u); EXPECT_EQUAL(0, function.getResult().cmp(fr)); function.reset(); - function.appendArg(vectorInt1).appendArg(vectorFloat2); + function.appendArg(createVectorInt(arg1)).appendArg(createVectorFloat(arg2)); function.prepare(false); - EXPECT_TRUE(function.getResult().getClass() - .equal(FloatResultNodeVector::classId)); + EXPECT_TRUE(function.getResult().getClass().equal(FloatResultNodeVector::classId)); EXPECT_TRUE(function.execute()); - EXPECT_TRUE(function.getResult().getClass() - .equal(FloatResultNodeVector::classId)); - EXPECT_EQUAL(static_cast<const FloatResultNodeVector &>( - function.getResult()).size(), 7u); + EXPECT_TRUE(function.getResult().getClass().equal(FloatResultNodeVector::classId)); + EXPECT_EQUAL(static_cast<const FloatResultNodeVector &>(function.getResult()).size(), 7u); EXPECT_EQUAL(0, function.getResult().cmp(fr)); function.reset(); - function.appendArg(vectorFloat1).appendArg(vectorInt2); + function.appendArg(createVectorFloat(arg1)).appendArg(createVectorInt(arg2)); function.prepare(false); - EXPECT_TRUE(function.getResult().getClass() - .equal(FloatResultNodeVector::classId)); + EXPECT_TRUE(function.getResult().getClass().equal(FloatResultNodeVector::classId)); EXPECT_TRUE(function.execute()); - EXPECT_TRUE(function.getResult().getClass() - .equal(FloatResultNodeVector::classId)); - EXPECT_EQUAL(static_cast<const FloatResultNodeVector &>( - function.getResult()).size(), 7u); + EXPECT_TRUE(function.getResult().getClass().equal(FloatResultNodeVector::classId)); + EXPECT_EQUAL(static_cast<const FloatResultNodeVector &>(function.getResult()).size(), 7u); EXPECT_EQUAL(0, function.getResult().cmp(fr)); } TEST("testArithmeticOperations") { - ExpressionNode::CP i1(new ConstantNode(new Int64ResultNode(1793253241))); - ExpressionNode::CP i2(new ConstantNode(new Int64ResultNode(1676521321))); - ExpressionNode::CP f1(new ConstantNode(new FloatResultNode(1.1109876))); - ExpressionNode::CP f2(new ConstantNode(new FloatResultNode(9.767681239))); - testAdd(i1, i2, 3469774562ull, 3469774562ull); - testAdd(i1, f2, 1793253251ull, 1793253250.767681239); - testAdd(f1, f2, 11, 10.878668839 ); - testMultiply(i1, i2, 3006427292488851361ull, 3006427292488851361ull); - testMultiply(i1, f2, 17515926039ull, 1793253241.0*9.767681239); - testMultiply(f1, f2, 11, 10.8517727372816364 ); + constexpr int64_t I1 = 1793253241; + constexpr int64_t I2 = 1676521321; + constexpr double F1 = 1.1109876; + constexpr double F2 = 9.767681239; + + testAdd(createScalarInt(I1), createScalarInt(I2), 3469774562ull, 3469774562ull); + testAdd(createScalarInt(I1), createScalarFloat(F2), 1793253251ull, 1793253250.767681239); + testAdd(createScalarFloat(F1), createScalarFloat(F2), 11, 10.878668839 ); + testMultiply(createScalarInt(I1), createScalarInt(I2), 3006427292488851361ull, 3006427292488851361ull); + testMultiply(createScalarInt(I1), createScalarFloat(F2), 17515926039ull, 1793253241.0*9.767681239); + testMultiply(createScalarFloat(F1), createScalarFloat(F2), 11, 10.8517727372816364 ); std::vector<double> a(5), b(7); a[0] = b[0] = 1; @@ -1284,57 +1170,52 @@ TEST("testArithmeticOperations") { } } -TEST("testAggregatorsInExpressions") { - CountAggregationResult *c = new CountAggregationResult(); - c->setCount(3); - SumAggregationResult *s = new SumAggregationResult(); - ResultNode::CP r1(new Int64ResultNode(7)), - r2(new Int64ResultNode(22)); - ExpressionNode::CP i1(new ConstantNode(new Int64ResultNode(7))), - i2(c), - i3(s), - i4(new ConstantNode(new Int64ResultNode(22))); +ExpressionNode::UP createCountAggr(int64_t initial) { return MU<CountAggregationResult>(initial); } +ExpressionNode::UP createMinAggr(const ResultNode & initial) { return MU<MinAggregationResult>(initial); } + +constexpr int64_t I1 = 7, I2 = 3, I4 = 22; + +ExpressionNode::UP createSumAggr() { + std::unique_ptr<SumAggregationResult> s = MU<SumAggregationResult>(); AggregationResult::Configure conf; - s->setExpression(i4).select(conf, conf); + s->setExpression(createScalarInt(I4)).select(conf, conf); s->aggregate(0, 0); + return s; +} + +TEST("testAggregatorsInExpressions") { + Int64ResultNode r1(I1); + Int64ResultNode r2(I4); - testAdd(i1, i2, 10, 10); - testMultiply(i1, i2, 21, 21); - testMultiply(i2, i3, 66, 66); - testDivide(i3, i2, 7, 7); - testDivide(i3, i1, 3, 3); - testModulo(i3, i2, 1, 1); - testModulo(i3, i1, 1, 1); - MinAggregationResult *min = new MinAggregationResult(); - min->setResult(r2); - ExpressionNode::CP imin(min); - testAdd(imin, i1, 29, 29); + testAdd(createScalarInt(I1), createCountAggr(I2), 10, 10); + testMultiply(createScalarInt(I1), createCountAggr(I2), 21, 21); + testMultiply(createCountAggr(I2), createSumAggr(), 66, 66); + testDivide(createSumAggr(), createCountAggr(I2), 7, 7); + testDivide(createSumAggr(), createScalarInt(I1), 3, 3); + testModulo(createSumAggr(), createCountAggr(I2), 1, 1); + testModulo(createSumAggr(), createScalarInt(I1), 1, 1); - MaxAggregationResult *max = new MaxAggregationResult(); - max->setResult(r1); - ExpressionNode::CP imax(max); - testAdd(imin, imax, 29, 29); + testAdd(MU<MinAggregationResult>(r2), createScalarInt(I1), 29, 29); + testAdd(MU<MinAggregationResult>(r2), MU<MaxAggregationResult>(r1), 29, 29); + AggregationResult::Configure conf; XorAggregationResult *x = new XorAggregationResult(); - x->setExpression(i4).select(conf, conf); + x->setExpression(createScalarInt(I4)).select(conf, conf); x->aggregate(0, 0); - ExpressionNode::CP ix(x); - testAdd(ix, i1, 29, 29); + testAdd(ExpressionNode::UP(x), createScalarInt(I1), 29, 29); AverageAggregationResult *avg = new AverageAggregationResult(); - avg->setExpression(i4).select(conf, conf); + avg->setExpression(createScalarInt(I4)).select(conf, conf); avg->aggregate(0, 0); - ExpressionNode::CP iavg(avg); - testAdd(iavg, i1, 29, 29); + testAdd(ExpressionNode::UP(avg), createScalarInt(I1), 29, 29); } void testAggregationResult(AggregationResult & aggr, const AggrGetter & g, const ResultNode & v, const ResultNode & i, const ResultNode & m, const ResultNode & s) { - ExpressionNode::CP scalarInt1(new ConstantNode(v)); AggregationResult::Configure conf; - aggr.setExpression(scalarInt1).select(conf, conf); + aggr.setExpression(MU<ConstantNode>(ResultNode::UP(v.clone()))).select(conf, conf); EXPECT_TRUE(g(aggr).getClass().equal(i.getClass().id())); EXPECT_EQUAL(0, i.cmp(g(aggr))); aggr.aggregate(0,0); @@ -1368,135 +1249,100 @@ TEST("testAggregationResults") { TEST("testGrouping") { AttributeGuard attr1 = createInt64Attribute(); - ExpressionNode::CP select1(new AttributeNode(*attr1)); - ExpressionNode::CP result1(new CountAggregationResult()); - (static_cast<AggregationResult &>(*result1)).setExpression(select1); - ExpressionNode::CP result2( new SumAggregationResult()); - (static_cast<AggregationResult &>(*result2)).setExpression(select1); - - Grouping grouping = Grouping() - .setFirstLevel(0) - .setLastLevel(1) - .addLevel(GroupingLevel() - .setExpression(select1) - .addResult(result1) - .addResult(result2)); + ExpressionNode::UP result1(new CountAggregationResult()); + (static_cast<AggregationResult &>(*result1)).setExpression(MU<AttributeNode>(*attr1)); + ExpressionNode::UP result2( new SumAggregationResult()); + (static_cast<AggregationResult &>(*result2)).setExpression(MU<AttributeNode>(*attr1)); + + Grouping grouping; + grouping.setFirstLevel(0) + .setLastLevel(1) + .addLevel(std::move(GroupingLevel() + .setExpression(MU<AttributeNode>(*attr1)) + .addResult(std::move(result1)) + .addResult(std::move(result2)))); grouping.configureStaticStuff(ConfigureStaticParams(0, 0)); grouping.aggregate(0u, 10u); const Group::GroupList &groups = grouping.getRoot().groups(); EXPECT_EQUAL(grouping.getRoot().getChildrenSize(), 9u); - ASSERT_TRUE(groups[0]->getAggregationResult(0).getClass().id() == - CountAggregationResult::classId); - ASSERT_TRUE(groups[0]->getAggregationResult(1).getClass().id() == - SumAggregationResult::classId); + ASSERT_TRUE(groups[0]->getAggregationResult(0).getClass().id() == CountAggregationResult::classId); + ASSERT_TRUE(groups[0]->getAggregationResult(1).getClass().id() == SumAggregationResult::classId); EXPECT_EQUAL(groups[0]->getId().getInteger(), 6u); - EXPECT_EQUAL(static_cast<const CountAggregationResult &>( - groups[0]->getAggregationResult(0)).getCount(), 1u); - EXPECT_EQUAL(static_cast<const SumAggregationResult &>( - groups[0]->getAggregationResult(1)).getSum().getInteger(), - 6); + EXPECT_EQUAL(static_cast<const CountAggregationResult &>(groups[0]->getAggregationResult(0)).getCount(), 1u); + EXPECT_EQUAL(static_cast<const SumAggregationResult &>(groups[0]->getAggregationResult(1)).getSum().getInteger(), 6); EXPECT_EQUAL(groups[1]->getId().getInteger(), 7u); - EXPECT_EQUAL(static_cast<const CountAggregationResult &>( - groups[1]->getAggregationResult(0)).getCount(), 1u); - EXPECT_EQUAL(static_cast<const SumAggregationResult &>( - groups[1]->getAggregationResult(1)).getSum().getInteger(), - 7); + EXPECT_EQUAL(static_cast<const CountAggregationResult &>(groups[1]->getAggregationResult(0)).getCount(), 1u); + EXPECT_EQUAL(static_cast<const SumAggregationResult &>(groups[1]->getAggregationResult(1)).getSum().getInteger(), 7); EXPECT_EQUAL(groups[2]->getId().getInteger(), 11u); - EXPECT_EQUAL(static_cast<const CountAggregationResult &>( - groups[2]->getAggregationResult(0)).getCount(), 1u); - EXPECT_EQUAL(static_cast<const SumAggregationResult &>( - groups[2]->getAggregationResult(1)).getSum().getInteger(), - 11); + EXPECT_EQUAL(static_cast<const CountAggregationResult &>(groups[2]->getAggregationResult(0)).getCount(), 1u); + EXPECT_EQUAL(static_cast<const SumAggregationResult &>(groups[2]->getAggregationResult(1)).getSum().getInteger(), 11); EXPECT_EQUAL(groups[3]->getId().getInteger(), 13u); - EXPECT_EQUAL(static_cast<const CountAggregationResult &>( - groups[3]->getAggregationResult(0)).getCount(), 2u); - EXPECT_EQUAL(static_cast<const SumAggregationResult &>( - groups[3]->getAggregationResult(1)).getSum().getInteger(), - 26); + EXPECT_EQUAL(static_cast<const CountAggregationResult &>(groups[3]->getAggregationResult(0)).getCount(), 2u); + EXPECT_EQUAL(static_cast<const SumAggregationResult &>(groups[3]->getAggregationResult(1)).getSum().getInteger(), 26); EXPECT_EQUAL(groups[4]->getId().getInteger(), 17u); - EXPECT_EQUAL(static_cast<const CountAggregationResult &>( - groups[4]->getAggregationResult(0)).getCount(), 1u); - EXPECT_EQUAL(static_cast<const SumAggregationResult &>( - groups[4]->getAggregationResult(1)).getSum().getInteger(), - 17); + EXPECT_EQUAL(static_cast<const CountAggregationResult &>(groups[4]->getAggregationResult(0)).getCount(), 1u); + EXPECT_EQUAL(static_cast<const SumAggregationResult &>(groups[4]->getAggregationResult(1)).getSum().getInteger(), 17); EXPECT_EQUAL(groups[5]->getId().getInteger(), 27u); - EXPECT_EQUAL(static_cast<const CountAggregationResult &>( - groups[5]->getAggregationResult(0)).getCount(), 1u); - EXPECT_EQUAL(static_cast<const SumAggregationResult &>( - groups[5]->getAggregationResult(1)).getSum().getInteger(), - 27); + EXPECT_EQUAL(static_cast<const CountAggregationResult &>(groups[5]->getAggregationResult(0)).getCount(), 1u); + EXPECT_EQUAL(static_cast<const SumAggregationResult &>(groups[5]->getAggregationResult(1)).getSum().getInteger(), 27); EXPECT_EQUAL(groups[6]->getId().getInteger(), 34u); - EXPECT_EQUAL(static_cast<const CountAggregationResult &>( - groups[6]->getAggregationResult(0)).getCount(), 1u); - EXPECT_EQUAL(static_cast<const SumAggregationResult &>( - groups[6]->getAggregationResult(1)).getSum().getInteger(), - 34); + EXPECT_EQUAL(static_cast<const CountAggregationResult &>(groups[6]->getAggregationResult(0)).getCount(), 1u); + EXPECT_EQUAL(static_cast<const SumAggregationResult &>(groups[6]->getAggregationResult(1)).getSum().getInteger(), 34); EXPECT_EQUAL(groups[7]->getId().getInteger(), 67891u); - EXPECT_EQUAL(static_cast<const CountAggregationResult &>( - groups[7]->getAggregationResult(0)).getCount(), 1u); - EXPECT_EQUAL(static_cast<const SumAggregationResult &>( - groups[7]->getAggregationResult(1)).getSum().getInteger(), - 67891); + EXPECT_EQUAL(static_cast<const CountAggregationResult &>(groups[7]->getAggregationResult(0)).getCount(), 1u); + EXPECT_EQUAL(static_cast<const SumAggregationResult &>(groups[7]->getAggregationResult(1)).getSum().getInteger(), 67891); EXPECT_EQUAL(groups[8]->getId().getInteger(), 67892u); - EXPECT_EQUAL(static_cast<const CountAggregationResult &>( - groups[8]->getAggregationResult(0)).getCount(), 1u); - EXPECT_EQUAL(static_cast<const SumAggregationResult &>( - groups[8]->getAggregationResult(1)).getSum().getInteger(), - 67892); + EXPECT_EQUAL(static_cast<const CountAggregationResult &>(groups[8]->getAggregationResult(0)).getCount(), 1u); + EXPECT_EQUAL(static_cast<const SumAggregationResult &>(groups[8]->getAggregationResult(1)).getSum().getInteger(), 67892); testStreaming(grouping); } -TEST("testGrouping2") { - AttributeGuard attr1 = createInt64Attribute(); - RangeBucketPreDefFunctionNode *predef( - new RangeBucketPreDefFunctionNode(AttributeNode(*attr1))); +ExpressionNode::UP +createPredefRangeBucket(const AttributeGuard & guard) { + RangeBucketPreDefFunctionNode *predef(new RangeBucketPreDefFunctionNode(MU<AttributeNode>(*guard))); IntegerBucketResultNodeVector prevec; prevec.getVector().push_back(IntegerBucketResultNode(6,7)); prevec.getVector().push_back(IntegerBucketResultNode(7,14)); prevec.getVector().push_back(IntegerBucketResultNode(18,50)); //30 - prevec.getVector() - .push_back(IntegerBucketResultNode(80,50000000000ull)); //30 + prevec.getVector().push_back(IntegerBucketResultNode(80,50000000000ull)); //30 predef->setBucketList(prevec); - ExpressionNode::CP select1(predef); - ExpressionNode::CP result1( new CountAggregationResult()); - (static_cast<AggregationResult &>(*result1)).setExpression(select1); + return ExpressionNode::UP(predef); +} + +TEST("testGrouping2") { + AttributeGuard attr1 = createInt64Attribute(); + ExpressionNode::UP result1( new CountAggregationResult()); + (static_cast<AggregationResult &>(*result1)).setExpression(createPredefRangeBucket(attr1)); - Grouping grouping = Grouping() - .setFirstLevel(0) - .setLastLevel(1) - .addLevel(GroupingLevel() - .setExpression(select1) - .addResult(result1)); + Grouping grouping; + grouping.setFirstLevel(0) + .setLastLevel(1) + .addLevel(std::move(GroupingLevel() + .setExpression(createPredefRangeBucket(attr1)) + .addResult(std::move(result1)))); grouping.configureStaticStuff(ConfigureStaticParams(0, 0)); grouping.aggregate(0u, 10u); const Group::GroupList &groups = grouping.getRoot().groups(); EXPECT_EQUAL(grouping.getRoot().getChildrenSize(), 5u); - ASSERT_TRUE(groups[0]->getAggregationResult(0).getClass().id() - == CountAggregationResult::classId); + ASSERT_TRUE(groups[0]->getAggregationResult(0).getClass().id() == CountAggregationResult::classId); EXPECT_EQUAL(groups[0]->getId().getInteger(), 0u); - EXPECT_EQUAL(static_cast<const CountAggregationResult &>( - groups[0]->getAggregationResult(0)).getCount(), 1u); + EXPECT_EQUAL(static_cast<const CountAggregationResult &>(groups[0]->getAggregationResult(0)).getCount(), 1u); EXPECT_EQUAL(groups[1]->getId().getInteger(), 0u); - EXPECT_EQUAL(static_cast<const CountAggregationResult &>( - groups[1]->getAggregationResult(0)).getCount(), 1u); + EXPECT_EQUAL(static_cast<const CountAggregationResult &>(groups[1]->getAggregationResult(0)).getCount(), 1u); EXPECT_EQUAL(groups[2]->getId().getInteger(), 0u); - EXPECT_EQUAL(static_cast<const CountAggregationResult &>( - groups[2]->getAggregationResult(0)).getCount(), 4u); + EXPECT_EQUAL(static_cast<const CountAggregationResult &>(groups[2]->getAggregationResult(0)).getCount(), 4u); EXPECT_EQUAL(groups[3]->getId().getInteger(), 0u); - EXPECT_EQUAL(static_cast<const CountAggregationResult &>( - groups[3]->getAggregationResult(0)).getCount(), 2u); + EXPECT_EQUAL(static_cast<const CountAggregationResult &>(groups[3]->getAggregationResult(0)).getCount(), 2u); EXPECT_EQUAL(groups[4]->getId().getInteger(), 0u); - EXPECT_EQUAL(static_cast<const CountAggregationResult &>( - groups[4]->getAggregationResult(0)).getCount(), 2u); + EXPECT_EQUAL(static_cast<const CountAggregationResult &>(groups[4]->getAggregationResult(0)).getCount(), 2u); testStreaming(grouping); } AttributeGuard createInt64Attribute() { - SingleInt64ExtAttribute *selectAttr1( - new SingleInt64ExtAttribute("selectAttr1")); + SingleInt64ExtAttribute *selectAttr1(new SingleInt64ExtAttribute("selectAttr1")); DocId docId(0); selectAttr1->addDoc(docId); selectAttr1->add(7); @@ -1525,8 +1371,7 @@ AttributeGuard createInt64Attribute() { } AttributeGuard createInt32Attribute() { - SingleInt32ExtAttribute *selectAttr1( - new SingleInt32ExtAttribute("selectAttr1")); + SingleInt32ExtAttribute *selectAttr1(new SingleInt32ExtAttribute("selectAttr1")); DocId docId(0); selectAttr1->addDoc(docId); selectAttr1->add(7); @@ -1555,8 +1400,7 @@ AttributeGuard createInt32Attribute() { } AttributeGuard createInt16Attribute() { - SingleInt16ExtAttribute *selectAttr1( - new SingleInt16ExtAttribute("selectAttr1")); + SingleInt16ExtAttribute *selectAttr1(new SingleInt16ExtAttribute("selectAttr1")); DocId docId(0); selectAttr1->addDoc(docId); selectAttr1->add(7); @@ -1585,8 +1429,7 @@ AttributeGuard createInt16Attribute() { } AttributeGuard createInt8Attribute() { - SingleInt8ExtAttribute *selectAttr1( - new SingleInt8ExtAttribute("selectAttr1")); + SingleInt8ExtAttribute *selectAttr1(new SingleInt8ExtAttribute("selectAttr1")); DocId docId(0); selectAttr1->addDoc(docId); selectAttr1->add(7); @@ -1640,38 +1483,28 @@ TEST("testIntegerTypes") { .prepare(true).getResult().getClass().id(), uint32_t(Int64ResultNode::classId)); - EXPECT_EQUAL( - AttributeNode(*AttributeGuard(AttributeVector::SP( - new MultiInt8ExtAttribute("test")))) + EXPECT_EQUAL(AttributeNode(*AttributeGuard(AttributeVector::SP(new MultiInt8ExtAttribute("test")))) .prepare(false).getResult().getClass().id(), uint32_t(Int64ResultNodeVector::classId)); - EXPECT_EQUAL( - AttributeNode(*AttributeGuard(AttributeVector::SP( - new MultiInt8ExtAttribute("test")))) + EXPECT_EQUAL(AttributeNode(*AttributeGuard(AttributeVector::SP(new MultiInt8ExtAttribute("test")))) .prepare(true).getResult().getClass().id(), uint32_t(Int8ResultNodeVector::classId)); - EXPECT_EQUAL(AttributeNode(*AttributeGuard(AttributeVector::SP( - new MultiInt16ExtAttribute("test")))) + EXPECT_EQUAL(AttributeNode(*AttributeGuard(AttributeVector::SP(new MultiInt16ExtAttribute("test")))) .prepare(false).getResult().getClass().id(), uint32_t(Int64ResultNodeVector::classId)); - EXPECT_EQUAL(AttributeNode(*AttributeGuard(AttributeVector::SP( - new MultiInt16ExtAttribute("test")))) + EXPECT_EQUAL(AttributeNode(*AttributeGuard(AttributeVector::SP(new MultiInt16ExtAttribute("test")))) .prepare(true).getResult().getClass().id(), uint32_t(Int16ResultNodeVector::classId)); - EXPECT_EQUAL(AttributeNode(*AttributeGuard(AttributeVector::SP( - new MultiInt32ExtAttribute("test")))) + EXPECT_EQUAL(AttributeNode(*AttributeGuard(AttributeVector::SP(new MultiInt32ExtAttribute("test")))) .prepare(false).getResult().getClass().id(), uint32_t(Int64ResultNodeVector::classId)); - EXPECT_EQUAL(AttributeNode(*AttributeGuard(AttributeVector::SP( - new MultiInt32ExtAttribute("test")))) + EXPECT_EQUAL(AttributeNode(*AttributeGuard(AttributeVector::SP(new MultiInt32ExtAttribute("test")))) .prepare(true).getResult().getClass().id(), uint32_t(Int32ResultNodeVector::classId)); - EXPECT_EQUAL(AttributeNode(*AttributeGuard(AttributeVector::SP( - new MultiInt64ExtAttribute("test")))) + EXPECT_EQUAL(AttributeNode(*AttributeGuard(AttributeVector::SP(new MultiInt64ExtAttribute("test")))) .prepare(false).getResult().getClass().id(), uint32_t(Int64ResultNodeVector::classId)); - EXPECT_EQUAL(AttributeNode(*AttributeGuard(AttributeVector::SP( - new MultiInt64ExtAttribute("test")))) + EXPECT_EQUAL(AttributeNode(*AttributeGuard(AttributeVector::SP(new MultiInt64ExtAttribute("test")))) .prepare(true).getResult().getClass().id(), uint32_t(Int64ResultNodeVector::classId)); } diff --git a/searchlib/src/tests/grouping/grouping_serialization_test.cpp b/searchlib/src/tests/grouping/grouping_serialization_test.cpp index a7a197d44d5..8592995915c 100644 --- a/searchlib/src/tests/grouping/grouping_serialization_test.cpp +++ b/searchlib/src/tests/grouping/grouping_serialization_test.cpp @@ -27,6 +27,8 @@ document::GlobalId getGlobalId(uint32_t docId) { .getGlobalId(); } +#define MU std::make_unique + struct Fixture { // Set WRITE_FILES to true to generate new expected serialization files. const bool WRITE_FILES = false; @@ -69,28 +71,27 @@ struct Fixture { Identifiable::UP newObj = Identifiable::create(stream); if (!EXPECT_TRUE(newObj.get() != 0)) { - LOG(error, "object of class '%s' resulted in empty echo", - obj.getClass().name()); + LOG(error, "object of class '%s' resulted in empty echo", obj.getClass().name()); return; } if (EXPECT_EQUAL(obj.asString(), newObj->asString()) && EXPECT_TRUE(newObj->cmp(obj) == 0) && EXPECT_TRUE(obj.cmp(*newObj) == 0)) { - LOG(info, "object of class '%s' passed echo test : %s", - obj.getClass().name(), newObj->asString().c_str()); + LOG(debug, "object of class '%s' passed echo test : %s", obj.getClass().name(), newObj->asString().c_str()); } else { - LOG(error, "object of class '%s' FAILED echo test", - obj.getClass().name()); + LOG(error, "object of class '%s' FAILED echo test", obj.getClass().name()); } } }; //----------------------------------------------------------------------------- -ExpressionNode::CP createDummyExpression() { - return AddFunctionNode().addArg(ConstantNode(Int64ResultNode(2))) - .addArg(ConstantNode(Int64ResultNode(2))); +ExpressionNode::UP +createDummyExpression() { + std::unique_ptr<AddFunctionNode> f = MU<AddFunctionNode>(); + f->addArg(MU<ConstantNode>(MU<Int64ResultNode>(2))).addArg(MU<ConstantNode>(MU<Int64ResultNode>(2))); + return f; } //----------------------------------------------------------------------------- @@ -150,83 +151,82 @@ TEST_F("testSpecialNodes", Fixture("testSpecialNodes")) { TEST_F("testFunctionNodes", Fixture("testFunctionNodes")) { f.checkObject(AddFunctionNode() - .addArg(ConstantNode(Int64ResultNode(7))) - .addArg(ConstantNode(Int64ResultNode(8))) - .addArg(ConstantNode(Int64ResultNode(9)))); + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(7))) + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(8))) + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(9)))); f.checkObject(XorFunctionNode() - .addArg(ConstantNode(Int64ResultNode(7))) - .addArg(ConstantNode(Int64ResultNode(8))) - .addArg(ConstantNode(Int64ResultNode(9)))); + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(7))) + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(8))) + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(9)))); f.checkObject(MultiplyFunctionNode() - .addArg(ConstantNode(Int64ResultNode(7))) - .addArg(ConstantNode(Int64ResultNode(8))) - .addArg(ConstantNode(Int64ResultNode(9)))); + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(7))) + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(8))) + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(9)))); f.checkObject(DivideFunctionNode() - .addArg(ConstantNode(Int64ResultNode(7))) - .addArg(ConstantNode(Int64ResultNode(8))) - .addArg(ConstantNode(Int64ResultNode(9)))); + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(7))) + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(8))) + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(9)))); f.checkObject(ModuloFunctionNode() - .addArg(ConstantNode(Int64ResultNode(7))) - .addArg(ConstantNode(Int64ResultNode(8))) - .addArg(ConstantNode(Int64ResultNode(9)))); + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(7))) + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(8))) + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(9)))); f.checkObject(MinFunctionNode() - .addArg(ConstantNode(Int64ResultNode(7))) - .addArg(ConstantNode(Int64ResultNode(8))) - .addArg(ConstantNode(Int64ResultNode(9)))); + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(7))) + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(8))) + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(9)))); f.checkObject(MaxFunctionNode() - .addArg(ConstantNode(Int64ResultNode(7))) - .addArg(ConstantNode(Int64ResultNode(8))) - .addArg(ConstantNode(Int64ResultNode(9)))); - f.checkObject(TimeStampFunctionNode(ConstantNode(Int64ResultNode(7)), + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(7))) + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(8))) + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(9)))); + f.checkObject(TimeStampFunctionNode(MU<ConstantNode>(MU<Int64ResultNode>(7)), TimeStampFunctionNode::Hour, true)); - f.checkObject(ZCurveFunctionNode(ConstantNode(Int64ResultNode(7)), + f.checkObject(ZCurveFunctionNode(MU<ConstantNode>(MU<Int64ResultNode>(7)), ZCurveFunctionNode::X)); - f.checkObject(ZCurveFunctionNode(ConstantNode(Int64ResultNode(7)), + f.checkObject(ZCurveFunctionNode(MU<ConstantNode>(MU<Int64ResultNode>(7)), ZCurveFunctionNode::Y)); - f.checkObject(NegateFunctionNode(ConstantNode(Int64ResultNode(7)))); - f.checkObject(SortFunctionNode(ConstantNode(Int64ResultNode(7)))); - f.checkObject(NormalizeSubjectFunctionNode(ConstantNode( - StringResultNode("foo")))); - f.checkObject(ReverseFunctionNode(ConstantNode(Int64ResultNode(7)))); - f.checkObject(MD5BitFunctionNode(ConstantNode(Int64ResultNode(7)), 64)); - f.checkObject(XorBitFunctionNode(ConstantNode(Int64ResultNode(7)), 64)); + f.checkObject(NegateFunctionNode(MU<ConstantNode>(MU<Int64ResultNode>(7)))); + f.checkObject(SortFunctionNode(MU<ConstantNode>(MU<Int64ResultNode>(7)))); + f.checkObject(NormalizeSubjectFunctionNode(MU<ConstantNode>(MU<StringResultNode>("foo")))); + f.checkObject(ReverseFunctionNode(MU<ConstantNode>(MU<Int64ResultNode>(7)))); + f.checkObject(MD5BitFunctionNode(MU<ConstantNode>(MU<Int64ResultNode>(7)), 64)); + f.checkObject(XorBitFunctionNode(MU<ConstantNode>(MU<Int64ResultNode>(7)), 64)); f.checkObject(CatFunctionNode() - .addArg(ConstantNode(Int64ResultNode(7))) - .addArg(ConstantNode(Int64ResultNode(8))) - .addArg(ConstantNode(Int64ResultNode(9)))); + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(7))) + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(8))) + .addArg(MU<ConstantNode>(MU<Int64ResultNode>(9)))); f.checkObject(FixedWidthBucketFunctionNode()); - f.checkObject(FixedWidthBucketFunctionNode(AttributeNode("foo"))); - f.checkObject(FixedWidthBucketFunctionNode(AttributeNode("foo")) + f.checkObject(FixedWidthBucketFunctionNode(MU<AttributeNode>("foo"))); + f.checkObject(FixedWidthBucketFunctionNode(MU<AttributeNode>("foo")) .setWidth(Int64ResultNode(10))); - f.checkObject(FixedWidthBucketFunctionNode(AttributeNode("foo")) + f.checkObject(FixedWidthBucketFunctionNode(MU<AttributeNode>("foo")) .setWidth(FloatResultNode(10.0))); f.checkObject(RangeBucketPreDefFunctionNode()); - f.checkObject(RangeBucketPreDefFunctionNode(AttributeNode("foo"))); - f.checkObject(DebugWaitFunctionNode(ConstantNode(Int64ResultNode(5)), + f.checkObject(RangeBucketPreDefFunctionNode(MU<AttributeNode>("foo"))); + f.checkObject(DebugWaitFunctionNode(MU<ConstantNode>(MU<Int64ResultNode>(5)), 3.3, false)); } TEST_F("testAggregatorResults", Fixture("testAggregatorResults")) { f.checkObject(SumAggregationResult() - .setExpression(AttributeNode("attributeA")) + .setExpression(MU<AttributeNode>("attributeA")) .setResult(Int64ResultNode(7))); f.checkObject(XorAggregationResult() .setXor(Int64ResultNode(7)) - .setExpression(AttributeNode("attributeA"))); + .setExpression(MU<AttributeNode>("attributeA"))); f.checkObject(CountAggregationResult() .setCount(7) - .setExpression(AttributeNode("attributeA"))); + .setExpression(MU<AttributeNode>("attributeA"))); f.checkObject(MinAggregationResult() - .setExpression(AttributeNode("attributeA")) + .setExpression(MU<AttributeNode>("attributeA")) .setResult(Int64ResultNode(7))); f.checkObject(MaxAggregationResult() - .setExpression(AttributeNode("attributeA")) + .setExpression(MU<AttributeNode>("attributeA")) .setResult(Int64ResultNode(7))); f.checkObject(AverageAggregationResult() - .setExpression(AttributeNode("attributeA")) + .setExpression(MU<AttributeNode>("attributeA")) .setResult(Int64ResultNode(7))); ExpressionCountAggregationResult expression_count; - expression_count.setExpression(ConstantNode(Int64ResultNode(67))) + expression_count.setExpression(MU<ConstantNode>(MU<Int64ResultNode>(67))) .aggregate(DocId(42), HitRank(21)); f.checkObject(expression_count); } @@ -245,7 +245,7 @@ TEST_F("testHitCollection", Fixture("testHitCollection")) { .addHit(FS4Hit(0, 3.0).setGlobalId(getGlobalId(30))) .addHit(FS4Hit(0, 4.0).setGlobalId(getGlobalId(40))) .addHit(FS4Hit(0, 5.0).setGlobalId(getGlobalId(50))) - .setExpression(ConstantNode(Int64ResultNode(5)))); + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(5)))); f.checkObject(HitsAggregationResult() .setMaxHits(3) .addHit(FS4Hit(0, 1.0).setGlobalId(getGlobalId(10)) @@ -254,21 +254,28 @@ TEST_F("testHitCollection", Fixture("testHitCollection")) { .setDistributionKey(200)) .addHit(FS4Hit(0, 3.0).setGlobalId(getGlobalId(30)) .setDistributionKey(300)) - .setExpression(ConstantNode(Int64ResultNode(5)))); + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(5)))); f.checkObject(HitsAggregationResult() .setMaxHits(3) .addHit(VdsHit("10", 1.0).setSummary("100", 3)) .addHit(VdsHit("20", 2.0).setSummary("200", 3)) .addHit(VdsHit("30", 3.0).setSummary("300", 3)) - .setExpression(ConstantNode(Int64ResultNode(5)))); + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(5)))); +} + +template<typename T> +ExpressionNode::UP +createAggr(ExpressionNode::UP e) { + std::unique_ptr<T> aggr = MU<T>(); + aggr->setExpression(std::move(e)); + return aggr; } TEST_F("testGroupingLevel", Fixture("testGroupingLevel")) { f.checkObject(GroupingLevel() .setMaxGroups(100) .setExpression(createDummyExpression()) - .addAggregationResult(SumAggregationResult() - .setExpression(createDummyExpression()))); + .addAggregationResult(createAggr<SumAggregationResult>(createDummyExpression()))); } TEST_F("testGroup", Fixture("testGroup")) { @@ -279,46 +286,47 @@ TEST_F("testGroup", Fixture("testGroup")) { .addChild(Group().setId(Int64ResultNode(110))) .addChild(Group().setId(Int64ResultNode(120)) .setRank(20.5) - .addAggregationResult(SumAggregationResult() - .setExpression(createDummyExpression())) - .addAggregationResult(SumAggregationResult() - .setExpression(createDummyExpression()))) + .addAggregationResult(createAggr<SumAggregationResult>(createDummyExpression())) + .addAggregationResult(createAggr<SumAggregationResult>(createDummyExpression()))) .addChild(Group().setId(Int64ResultNode(130)) .addChild(Group().setId(Int64ResultNode(131))))); } +GroupingLevel +createDummyLevel(size_t maxGroups, size_t numAggr) { + GroupingLevel l; + l.setMaxGroups(maxGroups); + l.setExpression(createDummyExpression()); + for (size_t i(0); i < numAggr; i++) { + l.addAggregationResult(createAggr<SumAggregationResult>(createDummyExpression())); + } + return l; +} + +GroupingLevel +createLargeLevel() { + GroupingLevel l; + l.setExpression(MU<AttributeNode>("folder")); + l.addAggregationResult(createAggr<XorAggregationResult>(MU<MD5BitFunctionNode>(MU<AttributeNode>("docid"), 64))); + l.addAggregationResult(createAggr<SumAggregationResult>( + ExpressionNode::UP(MinFunctionNode() + .addArg(MU<AttributeNode>("attribute1")) + .addArg(MU<AttributeNode>("attribute2")).clone()))); + l.addAggregationResult(createAggr<XorAggregationResult>( + ExpressionNode::UP(XorBitFunctionNode( + ExpressionNode::UP(CatFunctionNode() + .addArg(MU<GetDocIdNamespaceSpecificFunctionNode>()) + .addArg(MU<DocumentFieldNode>("folder")) + .addArg(MU<DocumentFieldNode>("flags")).clone()) + , 64).clone()))); + return l; +} TEST_F("testGrouping", Fixture("testGrouping")) { + f.checkObject(Grouping()); - f.checkObject(Grouping() - .addLevel(GroupingLevel() - .setMaxGroups(100) - .setExpression(createDummyExpression()) - .addAggregationResult(SumAggregationResult() - .setExpression(createDummyExpression()))) - .addLevel(GroupingLevel() - .setMaxGroups(10) - .setExpression(createDummyExpression()) - .addAggregationResult(SumAggregationResult() - .setExpression(createDummyExpression())) - .addAggregationResult(SumAggregationResult() - .setExpression(createDummyExpression())))); - f.checkObject(Grouping() - .addLevel(GroupingLevel() - .setExpression(AttributeNode("folder")) - .addAggregationResult(XorAggregationResult() - .setExpression(MD5BitFunctionNode( - AttributeNode("docid"), 64))) - .addAggregationResult(SumAggregationResult() - .setExpression(MinFunctionNode() - .addArg(AttributeNode("attribute1")) - .addArg(AttributeNode("attribute2"))) - ) - .addAggregationResult(XorAggregationResult() - .setExpression( - XorBitFunctionNode(CatFunctionNode() - .addArg(GetDocIdNamespaceSpecificFunctionNode()) - .addArg(DocumentFieldNode("folder")) - .addArg(DocumentFieldNode("flags")), 64))))); + f.checkObject(Grouping().addLevel(createDummyLevel(100, 1)) + .addLevel(createDummyLevel(10, 2))); + f.checkObject(Grouping().addLevel(createLargeLevel())); } } // namespace diff --git a/searchlib/src/tests/grouping/grouping_test.cpp b/searchlib/src/tests/grouping/grouping_test.cpp index 10fa3267c09..fec91a62d17 100644 --- a/searchlib/src/tests/grouping/grouping_test.cpp +++ b/searchlib/src/tests/grouping/grouping_test.cpp @@ -1,7 +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/log/log.h> -LOG_SETUP("grouping_test"); + #include <vespa/vespalib/testkit/testapp.h> #include <vespa/searchlib/aggregation/perdocexpression.h> #include <vespa/searchlib/aggregation/aggregation.h> @@ -39,7 +37,7 @@ public: for (uint32_t docid = 0; docid < numDocs; ++docid) { T val; uint32_t res = rhs._attr->get(docid, &val, 1); - LOG_ASSERT(res == 1); + assert(res == 1); add(val); } } @@ -283,6 +281,7 @@ Test::testMerge(const Grouping &a, const Grouping &b, const Grouping &c, void Test::testAggregationSimple() { + EXPECT_EQUAL(64u, sizeof(Group)); AggregationContext ctx; ctx.result().add(0).add(1).add(2); ctx.add(IntAttrBuilder("int").add(3).add(7).add(15).sp()); @@ -295,24 +294,69 @@ Test::testAggregationSimple() testAggregationSimpleSum(ctx, MaxAggregationResult(), Int64ResultNode(15), FloatResultNode(15), StringResultNode("7")); } +#define MU std::make_unique +using EUP = ExpressionNode::UP; + +std::unique_ptr<AggregationResult> +prepareAggr(const AggregationResult & aggr, ExpressionNode::UP expr) { + std::unique_ptr<AggregationResult> clone(aggr.clone()); + clone->setExpression(std::move(expr)); + return clone; +} + +ExpressionNode::UP +prepareAggr(const AggregationResult & aggr, ExpressionNode::UP expr, const ResultNode & r) { + auto prepared = prepareAggr(aggr, std::move(expr)); + prepared->setResult(r); + return prepared; +} void Test::testAggregationSimpleSum(AggregationContext & ctx, const AggregationResult & aggr, const ResultNode & ir, const ResultNode & fr, const ResultNode & sr) { ExpressionNode::CP clone(aggr); - Grouping request = Grouping() - .setRoot(Group() - .addResult(static_cast<AggregationResult &>(*clone).setExpression(AttributeNode("int"))) - .addResult(static_cast<AggregationResult &>(*clone).setExpression(AttributeNode("float"))) - .addResult(static_cast<AggregationResult &>(*clone).setExpression(AttributeNode("string"))) - ); + Grouping request; + request.setRoot(Group().addResult(prepareAggr(aggr, MU<AttributeNode>("int"))) + .addResult(prepareAggr(aggr, MU<AttributeNode>("float"))) + .addResult(prepareAggr(aggr, MU<AttributeNode>("string")))); - Group expect = Group() - .addResult(static_cast<AggregationResult &>(*clone).setExpression(AttributeNode("int")).setResult(ir)) - .addResult(static_cast<AggregationResult &>(*clone).setExpression(AttributeNode("float")).setResult(fr)) - .addResult(static_cast<AggregationResult &>(*clone).setExpression(AttributeNode("string")).setResult(sr)); + Group expect; + expect.addResult(prepareAggr(aggr, MU<AttributeNode>("int"), ir)) + .addResult(prepareAggr(aggr, MU<AttributeNode>("float"), fr)) + .addResult(prepareAggr(aggr, MU<AttributeNode>("string"), sr)); EXPECT_TRUE(testAggregation(ctx, request, expect)); } +GroupingLevel +createGL(ExpressionNode::UP expr, ExpressionNode::UP resultExpr) { + GroupingLevel l; + l.setExpression(std::move(expr)); + l.addResult(SumAggregationResult().setExpression(std::move(resultExpr))); + return l; +} + +GroupingLevel +createGL(ExpressionNode::UP expr) { + GroupingLevel l; + l.setExpression(std::move(expr)); + return l; +} + +GroupingLevel +createGL(size_t maxGroups, ExpressionNode::UP expr) { + GroupingLevel l; + l.setMaxGroups(maxGroups); + l.setExpression(std::move(expr)); + return l; +} + +GroupingLevel +createGL(size_t maxGroups, ExpressionNode::UP expr, ExpressionNode::UP result) { + GroupingLevel l; + l.setMaxGroups(maxGroups); + l.setExpression(std::move(expr)); + l.addResult(SumAggregationResult().setExpression(std::move(result))); + return l; +} /** * Verify that the backend aggregation will classify and collect on * the appropriate levels, as indicated by the firstLevel and @@ -328,91 +372,70 @@ Test::testAggregationLevels() ctx.add(IntAttrBuilder("attr3").add(13).add(13).sp()); ctx.result().add(0).add(1); - Grouping baseRequest = Grouping() - .setRoot(Group() - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr0")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr1")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr2")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr2")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr3")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr3")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr1")))); - - Group notDone = Group() - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr0"))); + Grouping baseRequest; + baseRequest + .setRoot(Group().addResult(SumAggregationResult().setExpression(MU<AttributeNode>("attr0")))) + .addLevel(createGL(MU<AttributeNode>("attr1"), MU<AttributeNode>("attr2"))) + .addLevel(createGL(MU<AttributeNode>("attr2"), MU<AttributeNode>("attr3"))) + .addLevel(createGL(MU<AttributeNode>("attr3"), MU<AttributeNode>("attr1"))); + + Group notDone; + notDone.addResult(SumAggregationResult().setExpression(MU<AttributeNode>("attr0"))); // Hmm, do not need to prepare more than the levels needed. .setResult(Int64ResultNode(0))); - Group done0 = Group() - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr0")) - .setResult(Int64ResultNode(20))) - .addChild(Group() - .setId(Int64ResultNode(11)) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr2")) + Group done0; + done0.addResult(SumAggregationResult().setExpression(MU<AttributeNode>("attr0")).setResult(Int64ResultNode(20))) + .addChild(Group().setId(Int64ResultNode(11)).addResult(SumAggregationResult().setExpression(MU<AttributeNode>("attr2")) .setResult(Int64ResultNode(0)))); - Group done1 = Group() - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr0")) - .setResult(Int64ResultNode(20))) - .addChild(Group() - .setId(Int64ResultNode(11)) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr2")) - .setResult(Int64ResultNode(24))) - .addChild(Group() - .setId(Int64ResultNode(12)) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr3")) - .setResult(Int64ResultNode(0))))); - - Group done2 = Group() - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr0")) - .setResult(Int64ResultNode(20))) - .addChild(Group() - .setId(Int64ResultNode(11)) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr2")) - .setResult(Int64ResultNode(24))) - .addChild(Group() - .setId(Int64ResultNode(12)) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr3")) - .setResult(Int64ResultNode(26))) - .addChild(Group() - .setId(Int64ResultNode(13)) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr1")) - .setResult(Int64ResultNode(0)))))); - - Group done3 = Group() - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr0")) - .setResult(Int64ResultNode(20))) + Group done1; + done1.addResult(SumAggregationResult() + .setExpression(MU<AttributeNode>("attr0")) + .setResult(Int64ResultNode(20))) + .addChild(Group().setId(Int64ResultNode(11)) + .addResult(SumAggregationResult() + .setExpression(MU<AttributeNode>("attr2")) + .setResult(Int64ResultNode(24))) + .addChild(Group().setId(Int64ResultNode(12)) + .addResult(SumAggregationResult() + .setExpression(MU<AttributeNode>("attr3")) + .setResult(Int64ResultNode(0))))); + + Group done2; + done2.addResult(SumAggregationResult() + .setExpression(MU<AttributeNode>("attr0")) + .setResult(Int64ResultNode(20))) + .addChild(Group().setId(Int64ResultNode(11)) + .addResult(SumAggregationResult() + .setExpression(MU<AttributeNode>("attr2")) + .setResult(Int64ResultNode(24))) + .addChild(Group().setId(Int64ResultNode(12)) + .addResult(SumAggregationResult() + .setExpression(MU<AttributeNode>("attr3")) + .setResult(Int64ResultNode(26))) + .addChild(Group().setId(Int64ResultNode(13)) + .addResult(SumAggregationResult() + .setExpression(MU<AttributeNode>("attr1")) + .setResult(Int64ResultNode(0)))))); + + Group done3; + done3.addResult(SumAggregationResult() + .setExpression(MU<AttributeNode>("attr0")) + .setResult(Int64ResultNode(20))) .addChild(Group() .setId(Int64ResultNode(11)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr2")) + .setExpression(MU<AttributeNode>("attr2")) .setResult(Int64ResultNode(24))) .addChild(Group() .setId(Int64ResultNode(12)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr3")) + .setExpression(MU<AttributeNode>("attr3")) .setResult(Int64ResultNode(26))) .addChild(Group() .setId(Int64ResultNode(13)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr1")) + .setExpression(MU<AttributeNode>("attr1")) .setResult(Int64ResultNode(22)))))); { // level 0 only @@ -464,9 +487,7 @@ Test::testAggregationMaxGroups() ctx.add(IntAttrBuilder("attr").add(5).add(10).add(15).sp()); ctx.result().add(0).add(1).add(2); - Grouping baseRequest = Grouping() - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr"))); + Grouping baseRequest = Grouping().addLevel(createGL(MU<AttributeNode>("attr"))); Group empty = Group(); Group grp1 = empty.unchain().addChild(Group().setId(Int64ResultNode(5))); @@ -515,18 +536,17 @@ Test::testAggregationGroupOrder() ctx.add(IntAttrBuilder("attr").add(10).add(25).add(35).add(5).add(20).add(15).add(30).sp()); ctx.result().add(0).add(1).add(2).add(3).add(4).add(5).add(6); - Grouping request = Grouping() - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr"))); + Grouping request; + request.addLevel(createGL(MU<AttributeNode>("attr"))); - Group expect = Group() - .addChild(Group().setId(Int64ResultNode(5))) - .addChild(Group().setId(Int64ResultNode(10))) - .addChild(Group().setId(Int64ResultNode(15))) - .addChild(Group().setId(Int64ResultNode(20))) - .addChild(Group().setId(Int64ResultNode(25))) - .addChild(Group().setId(Int64ResultNode(30))) - .addChild(Group().setId(Int64ResultNode(35))); + Group expect; + expect.addChild(Group().setId(Int64ResultNode(5))) + .addChild(Group().setId(Int64ResultNode(10))) + .addChild(Group().setId(Int64ResultNode(15))) + .addChild(Group().setId(Int64ResultNode(20))) + .addChild(Group().setId(Int64ResultNode(25))) + .addChild(Group().setId(Int64ResultNode(30))) + .addChild(Group().setId(Int64ResultNode(35))); EXPECT_TRUE(testAggregation(ctx, request, expect)); } @@ -547,8 +567,7 @@ Test::testAggregationGroupRank() .add(3, 10).add(4, 15).add(5, 5) .add(6, 15).add(7, 5).add(8, 10); - Grouping request = Grouping().addLevel( - GroupingLevel().setExpression(AttributeNode("attr"))); + Grouping request = Grouping().addLevel(createGL(MU<AttributeNode>("attr"))); Group expect = Group() .addChild(Group().setId(Int64ResultNode(1)).setRank(RawRank(15))) @@ -558,6 +577,22 @@ Test::testAggregationGroupRank() EXPECT_TRUE(testAggregation(ctx, request, expect)); } +template<typename T> +ExpressionNode::UP +createAggr(ExpressionNode::UP e) { + std::unique_ptr<T> aggr = MU<T>(); + aggr->setExpression(std::move(e)); + return aggr; +} + +template<typename T> +ExpressionNode::UP +createAggr(SingleResultNode::UP r, ExpressionNode::UP e) { + std::unique_ptr<T> aggr = MU<T>(std::move(r)); + aggr->setExpression(std::move(e)); + return aggr; +} + void Test::testAggregationGroupCapping() { @@ -572,81 +607,96 @@ Test::testAggregationGroupCapping() .add(6, 7).add(7, 8).add(8, 9); { - Grouping request = Grouping().addLevel( - GroupingLevel().setExpression(AttributeNode("attr"))); - - Group expect = Group() - .addChild(Group().setId(Int64ResultNode(1)).setRank(RawRank(1))) - .addChild(Group().setId(Int64ResultNode(2)).setRank(RawRank(2))) - .addChild(Group().setId(Int64ResultNode(3)).setRank(RawRank(3))) - .addChild(Group().setId(Int64ResultNode(4)).setRank(RawRank(4))) - .addChild(Group().setId(Int64ResultNode(5)).setRank(RawRank(5))) - .addChild(Group().setId(Int64ResultNode(6)).setRank(RawRank(6))) - .addChild(Group().setId(Int64ResultNode(7)).setRank(RawRank(7))) - .addChild(Group().setId(Int64ResultNode(8)).setRank(RawRank(8))) - .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(9))); + Grouping request = Grouping().addLevel(createGL(MU<AttributeNode>("attr"))); + + Group expect; + expect.addChild(Group().setId(Int64ResultNode(1)).setRank(RawRank(1))) + .addChild(Group().setId(Int64ResultNode(2)).setRank(RawRank(2))) + .addChild(Group().setId(Int64ResultNode(3)).setRank(RawRank(3))) + .addChild(Group().setId(Int64ResultNode(4)).setRank(RawRank(4))) + .addChild(Group().setId(Int64ResultNode(5)).setRank(RawRank(5))) + .addChild(Group().setId(Int64ResultNode(6)).setRank(RawRank(6))) + .addChild(Group().setId(Int64ResultNode(7)).setRank(RawRank(7))) + .addChild(Group().setId(Int64ResultNode(8)).setRank(RawRank(8))) + .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(9))); EXPECT_TRUE(testAggregation(ctx, request, expect)); } { - Grouping request = Grouping().addLevel( - GroupingLevel().setMaxGroups(3).setExpression(AttributeNode("attr"))); + Grouping request; + request.addLevel(createGL(3, MU<AttributeNode>("attr"))); - Group expect = Group() - .addChild(Group().setId(Int64ResultNode(7)).setRank(RawRank(7))) - .addChild(Group().setId(Int64ResultNode(8)).setRank(RawRank(8))) - .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(9))); + Group expect; + expect.addChild(Group().setId(Int64ResultNode(7)).setRank(RawRank(7))) + .addChild(Group().setId(Int64ResultNode(8)).setRank(RawRank(8))) + .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(9))); EXPECT_TRUE(testAggregation(ctx, request, expect)); } { - Grouping request = Grouping(). - setFirstLevel(0). - setLastLevel(1). - addLevel( - GroupingLevel().setMaxGroups(3).setExpression(AttributeNode("attr")). - addAggregationResult(SumAggregationResult().setExpression(AttributeNode("attr"))). - addOrderBy(AggregationRefNode(0), false)); - - Group expect = Group() - .addChild(Group().setId(Int64ResultNode(7)).setRank(RawRank(7)).addAggregationResult(SumAggregationResult(Int64ResultNode(7)).setExpression(AttributeNode("attr"))).addOrderBy(AggregationRefNode(0), false)) - .addChild(Group().setId(Int64ResultNode(8)).setRank(RawRank(8)).addAggregationResult(SumAggregationResult(Int64ResultNode(8)).setExpression(AttributeNode("attr"))).addOrderBy(AggregationRefNode(0), false)) - .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(9)).addAggregationResult(SumAggregationResult(Int64ResultNode(9)).setExpression(AttributeNode("attr"))).addOrderBy(AggregationRefNode(0), false)); + Grouping request; + request.setFirstLevel(0) + .setLastLevel(1) + .addLevel(std::move(GroupingLevel().setMaxGroups(3).setExpression(MU<AttributeNode>("attr")) + .addAggregationResult(createAggr<SumAggregationResult>(MU<AttributeNode>("attr"))) + .addOrderBy(MU<AggregationRefNode>(0), false))); + + Group expect; + expect.addChild(Group().setId(Int64ResultNode(7)).setRank(RawRank(7)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(7), MU<AttributeNode>("attr"))) + .addOrderBy(MU<AggregationRefNode>(0), false)) + .addChild(Group().setId(Int64ResultNode(8)).setRank(RawRank(8)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(8), MU<AttributeNode>("attr"))) + .addOrderBy(MU<AggregationRefNode>(0), false)) + .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(9)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(9), MU<AttributeNode>("attr"))) + .addOrderBy(MU<AggregationRefNode>(0), false)); EXPECT_TRUE(testAggregation(ctx, request, expect)); } { - Grouping request = Grouping(). - setFirstLevel(0). - setLastLevel(1). - addLevel( - GroupingLevel().setMaxGroups(3).setExpression(AttributeNode("attr")). - addAggregationResult(SumAggregationResult().setExpression(AttributeNode("attr"))).addOrderBy(AggregationRefNode(0), true)); + Grouping request; + request.setFirstLevel(0) + .setLastLevel(1) + .addLevel(std::move(GroupingLevel().setMaxGroups(3).setExpression(MU<AttributeNode>("attr")) + .addAggregationResult(createAggr<SumAggregationResult>(MU<AttributeNode>("attr"))) + .addOrderBy(MU<AggregationRefNode>(0), true))); Group expect = Group() - .addChild(Group().setId(Int64ResultNode(1)).setRank(RawRank(1)).addAggregationResult(SumAggregationResult(Int64ResultNode(1)).setExpression(AttributeNode("attr"))).addOrderBy(AggregationRefNode(0), true)) - .addChild(Group().setId(Int64ResultNode(2)).setRank(RawRank(2)).addAggregationResult(SumAggregationResult(Int64ResultNode(2)).setExpression(AttributeNode("attr"))).addOrderBy(AggregationRefNode(0), true)) - .addChild(Group().setId(Int64ResultNode(3)).setRank(RawRank(3)).addAggregationResult(SumAggregationResult(Int64ResultNode(3)).setExpression(AttributeNode("attr"))).addOrderBy(AggregationRefNode(0), true)); + .addChild(Group().setId(Int64ResultNode(1)).setRank(RawRank(1)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(1), MU<AttributeNode>("attr"))) + .addOrderBy(MU<AggregationRefNode>(0), true)) + .addChild(Group().setId(Int64ResultNode(2)).setRank(RawRank(2)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(2), MU<AttributeNode>("attr"))) + .addOrderBy(MU<AggregationRefNode>(0), true)) + .addChild(Group().setId(Int64ResultNode(3)).setRank(RawRank(3)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(3), MU<AttributeNode>("attr"))) + .addOrderBy(MU<AggregationRefNode>(0), true)); EXPECT_TRUE(testAggregation(ctx, request, expect)); } { AddFunctionNode *add = new AddFunctionNode(); - add->addArg(AggregationRefNode(0)); - add->appendArg(ConstantNode(Int64ResultNode(3))); - ExpressionNode::CP i1(add); - Grouping request = Grouping(). - setFirstLevel(0). - setLastLevel(1). - addLevel( - GroupingLevel().setMaxGroups(3).setExpression(AttributeNode("attr")). - addAggregationResult(SumAggregationResult().setExpression(AttributeNode("attr"))). - addOrderBy(i1, false)); - - Group expect = Group() - .addChild(Group().setId(Int64ResultNode(7)).setRank(RawRank(7)).addAggregationResult(SumAggregationResult(Int64ResultNode(7)).setExpression(AttributeNode("attr"))).addOrderBy(AddFunctionNode().appendArg(AggregationRefNode(0)).appendArg(ConstantNode(Int64ResultNode(3))).setResult(Int64ResultNode(10)), false)) - .addChild(Group().setId(Int64ResultNode(8)).setRank(RawRank(8)).addAggregationResult(SumAggregationResult(Int64ResultNode(8)).setExpression(AttributeNode("attr"))).addOrderBy(AddFunctionNode().appendArg(AggregationRefNode(0)).appendArg(ConstantNode(Int64ResultNode(3))).setResult(Int64ResultNode(11)), false)) - .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(9)).addAggregationResult(SumAggregationResult(Int64ResultNode(9)).setExpression(AttributeNode("attr"))).addOrderBy(AddFunctionNode().appendArg(AggregationRefNode(0)).appendArg(ConstantNode(Int64ResultNode(3))).setResult(Int64ResultNode(12)), false)); + add->addArg(MU<AggregationRefNode>(0)); + add->appendArg(MU<ConstantNode>(MU<Int64ResultNode>(3))); + + Grouping request; + request.setFirstLevel(0) + .setLastLevel(1) + .addLevel(std::move(GroupingLevel().setMaxGroups(3).setExpression(MU<AttributeNode>("attr")) + .addAggregationResult(createAggr<SumAggregationResult>(MU<AttributeNode>("attr"))) + .addOrderBy(ExpressionNode::UP(add), false))); + + Group expect; + expect.addChild(Group().setId(Int64ResultNode(7)).setRank(RawRank(7)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(7), MU<AttributeNode>("attr"))) + .addOrderBy(AddFunctionNode().appendArg(MU<AggregationRefNode>(0)).appendArg(MU<ConstantNode>(MU<Int64ResultNode>(3))).setResult(Int64ResultNode(10)), false)) + .addChild(Group().setId(Int64ResultNode(8)).setRank(RawRank(8)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(8), MU<AttributeNode>("attr"))) + .addOrderBy(AddFunctionNode().appendArg(MU<AggregationRefNode>(0)).appendArg(MU<ConstantNode>(MU<Int64ResultNode>(3))).setResult(Int64ResultNode(11)), false)) + .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(9)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(9), MU<AttributeNode>("attr"))) + .addOrderBy(AddFunctionNode().appendArg(MU<AggregationRefNode>(0)).appendArg(MU<ConstantNode>(MU<Int64ResultNode>(3))).setResult(Int64ResultNode(12)), false)); EXPECT_TRUE(testAggregation(ctx, request, expect)); } @@ -667,20 +717,20 @@ Test::testMergeSimpleSum() .setRoot(Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("foo")) + .setExpression(MU<AttributeNode>("foo")) .setResult(Int64ResultNode(20)))); Grouping b = Grouping() .setRoot(Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("foo")) + .setExpression(MU<AttributeNode>("foo")) .setResult(Int64ResultNode(30)))); Group expect = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("foo")) + .setExpression(MU<AttributeNode>("foo")) .setResult(Int64ResultNode(50))); EXPECT_TRUE(testMerge(a, b, expect)); @@ -692,168 +742,159 @@ Test::testMergeSimpleSum() void Test::testMergeLevels() { - Grouping request = Grouping() - .addLevel(GroupingLevel() - .setExpression(AttributeNode("c1")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("c2")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("c3")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")))); + Grouping request; + request.addLevel(createGL(MU<AttributeNode>("c1"), MU<AttributeNode>("s1"))) + .addLevel(createGL(MU<AttributeNode>("c2"), MU<AttributeNode>("s2"))) + .addLevel(createGL(MU<AttributeNode>("c3"), MU<AttributeNode>("s3"))); Group a = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(5))) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(10))) .addChild(Group() .setId(Int64ResultNode(20)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(15))) .addChild(Group() .setId(Int64ResultNode(30)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(20)))))); Group b = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(5))) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(10))) .addChild(Group() .setId(Int64ResultNode(20)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(15))) .addChild(Group() .setId(Int64ResultNode(30)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(20)))))); Group expect_all = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(10))) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(20))) .addChild(Group() .setId(Int64ResultNode(20)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(30))) .addChild(Group() .setId(Int64ResultNode(30)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(40)))))); Group expect_0 = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(5))) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(20))) .addChild(Group() .setId(Int64ResultNode(20)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(30))) .addChild(Group() .setId(Int64ResultNode(30)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(40)))))); Group expect_1 = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(5))) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(10))) .addChild(Group() .setId(Int64ResultNode(20)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(30))) .addChild(Group() .setId(Int64ResultNode(30)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(40)))))); Group expect_2 = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(5))) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(10))) .addChild(Group() .setId(Int64ResultNode(20)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(15))) .addChild(Group() .setId(Int64ResultNode(30)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(40)))))); Group expect_3 = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(5))) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(10))) .addChild(Group() .setId(Int64ResultNode(20)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(15))) .addChild(Group() .setId(Int64ResultNode(30)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(20)))))); EXPECT_TRUE(testMerge(request.unchain().setFirstLevel(0).setLastLevel(3).setRoot(a), @@ -881,9 +922,8 @@ Test::testMergeLevels() void Test::testMergeGroups() { - Grouping request = Grouping() - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr"))); + Grouping request; + request.addLevel(createGL(MU<AttributeNode>("attr"))); Group a = Group() .setId(NullResultNode()) @@ -944,48 +984,36 @@ Test::testMergeGroups() void Test::testMergeTrees() { - Grouping request = Grouping() - .addLevel(GroupingLevel() - .setMaxGroups(3) - .setExpression(AttributeNode("c1")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")))) - .addLevel(GroupingLevel() - .setMaxGroups(2) - .setExpression(AttributeNode("c2")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")))) - .addLevel(GroupingLevel() - .setMaxGroups(1) - .setExpression(AttributeNode("c3")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")))); + Grouping request; + request.addLevel(createGL(3, MU<AttributeNode>("c1"), MU<AttributeNode>("s1"))) + .addLevel(createGL(2, MU<AttributeNode>("c2"), MU<AttributeNode>("s2"))) + .addLevel(createGL(1, MU<AttributeNode>("c3"), MU<AttributeNode>("s3"))); Group a = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(4)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(5)) .setRank(RawRank(5)) // merged with 200 rank node .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(4)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(5)) .setRank(RawRank(500)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(4)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(5)) .setRank(RawRank(200)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -995,21 +1023,21 @@ Test::testMergeTrees() .setId(Int64ResultNode(10)) .setRank(RawRank(100)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(100))) // dummy child would be picked up here .addChild(Group() .setId(Int64ResultNode(15)) .setRank(RawRank(200)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(14)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(15)) .setRank(RawRank(300)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1019,14 +1047,14 @@ Test::testMergeTrees() .setId(Int64ResultNode(15)) .setRank(RawRank(300)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(19)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(20)) .setRank(RawRank(100)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) ) ); @@ -1034,28 +1062,28 @@ Test::testMergeTrees() Group b = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(4)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(5)) .setRank(RawRank(200)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(10)) .setRank(RawRank(400)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(10)) .setRank(RawRank(100)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1065,14 +1093,14 @@ Test::testMergeTrees() .setId(Int64ResultNode(10)) .setRank(RawRank(100)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(100))) // dummy child would be picket up here .addChild(Group() .setId(Int64ResultNode(15)) .setRank(RawRank(200)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) ) ) @@ -1081,21 +1109,21 @@ Test::testMergeTrees() .setId(Int64ResultNode(15)) .setRank(RawRank(5)) // merged with 300 rank node .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(19)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(20)) .setRank(RawRank(5)) // merged with 100 rank node .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(19)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(20)) .setRank(RawRank(500)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1104,14 +1132,14 @@ Test::testMergeTrees() .setId(Int64ResultNode(25)) .setRank(RawRank(300)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(24)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(25)) .setRank(RawRank(400)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1120,25 +1148,25 @@ Test::testMergeTrees() Group expect = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(200))) .addChild(Group() .setId(Int64ResultNode(5)) .setRank(RawRank(200)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(200))) .addChild(Group() .setId(Int64ResultNode(5)) .setRank(RawRank(500)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group() .setId(Int64ResultNode(5)) .setRank(RawRank(200)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1146,13 +1174,13 @@ Test::testMergeTrees() .setId(Int64ResultNode(10)) .setRank(RawRank(400)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group() .setId(Int64ResultNode(10)) .setRank(RawRank(100)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1161,19 +1189,19 @@ Test::testMergeTrees() .setId(Int64ResultNode(10)) .setRank(RawRank(100)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(200))) .addChild(Group() .setId(Int64ResultNode(15)) .setRank(RawRank(200)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(200))) .addChild(Group() .setId(Int64ResultNode(15)) .setRank(RawRank(300)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1182,19 +1210,19 @@ Test::testMergeTrees() .setId(Int64ResultNode(15)) .setRank(RawRank(300)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(200))) .addChild(Group() .setId(Int64ResultNode(20)) .setRank(RawRank(100)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(200))) .addChild(Group() .setId(Int64ResultNode(20)) .setRank(RawRank(500)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1202,13 +1230,13 @@ Test::testMergeTrees() .setId(Int64ResultNode(25)) .setRank(RawRank(300)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group() .setId(Int64ResultNode(25)) .setRank(RawRank(400)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1361,39 +1389,30 @@ Test::testPruneComplex() void Test::testPartialMerging() { - Grouping baseRequest = Grouping() - .addLevel(GroupingLevel() - .setExpression(AttributeNode("c1")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("c2")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("c3")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")))); + Grouping baseRequest; + baseRequest.addLevel(createGL(MU<AttributeNode>("c1"), MU<AttributeNode>("s1"))) + .addLevel(createGL(MU<AttributeNode>("c2"), MU<AttributeNode>("s2"))) + .addLevel(createGL(MU<AttributeNode>("c3"), MU<AttributeNode>("s3"))); // Cached result Group cached = Group() .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(110))) .addChild(Group() .setId(Int64ResultNode(5)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(10))) .addChild(Group() .setId(Int64ResultNode(13)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group() .setId(Int64ResultNode(14)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1401,17 +1420,17 @@ Test::testPartialMerging() .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(100))) .addChild(Group() .setId(Int64ResultNode(15)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group() .setId(Int64ResultNode(22)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1422,23 +1441,23 @@ Test::testPartialMerging() Grouping request = baseRequest.unchain().setFirstLevel(0).setLastLevel(0); Group incoming = Group() .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(0))); Group expected = Group() .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(110))) .addChild(Group() .setId(Int64ResultNode(5)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ); EXPECT_TRUE(testPartialMerge(request.unchain().setRoot(incoming), request.unchain().setLastLevel(3).setRoot(cached), expected)); @@ -1448,81 +1467,81 @@ Test::testPartialMerging() Grouping request = baseRequest.unchain().setFirstLevel(1).setLastLevel(1); Group incoming = Group() .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(200))) .addChild(Group() .setId(Int64ResultNode(3)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ) .addChild(Group() .setId(Int64ResultNode(5)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ) .addChild(Group() .setId(Int64ResultNode(7)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0)))) .addChild(Group() .setId(Int64ResultNode(33)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ); Group expected = Group() .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(200))) .addChild(Group() .setId(Int64ResultNode(3)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ) .addChild(Group() .setId(Int64ResultNode(5)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(10))) .addChild(Group() .setId(Int64ResultNode(13)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(0))) ) ) .addChild(Group() .setId(Int64ResultNode(7)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(100))) .addChild(Group() .setId(Int64ResultNode(15)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(0))) ) ) .addChild(Group() .setId(Int64ResultNode(33)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ); EXPECT_TRUE(testPartialMerge(request.unchain().setRoot(incoming), request.unchain().setFirstLevel(0).setLastLevel(3).setRoot(cached), expected)); @@ -1536,22 +1555,17 @@ void Test::testPruneSimple() { { - Grouping request = Grouping() - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr"))) - .setFirstLevel(1) - .setLastLevel(1); + Grouping request; + request.addLevel(createGL(MU<AttributeNode>("attr"))).setFirstLevel(1).setLastLevel(1); Group a = Group() .addChild(Group().setId(StringResultNode("foo"))) .addChild(Group().setId(StringResultNode("bar"))) .addChild(Group().setId(StringResultNode("baz"))); - Group b = Group() - .addChild(Group().setId(StringResultNode("foo"))); + Group b = Group().addChild(Group().setId(StringResultNode("foo"))); - Group expect = Group() - .addChild(Group().setId(StringResultNode("foo"))); + Group expect = Group().addChild(Group().setId(StringResultNode("foo"))); EXPECT_TRUE(testPrune(request.unchain().setFirstLevel(0).setRoot(a), request.unchain().setRoot(b), expect)); } @@ -1568,33 +1582,26 @@ Test::testTopN() ctx.result().add(0).add(1).add(2); ctx.add(IntAttrBuilder("foo").add(3).add(7).add(15).sp()); - Grouping request = Grouping() - .setRoot(Group() - .addResult(CountAggregationResult() - .setExpression(ConstantNode(Int64ResultNode(0))) - ) - ); + Grouping request; + request.setRoot(Group().addResult(CountAggregationResult().setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0))))); { - Group expect = Group() - .addResult(CountAggregationResult().setCount(3) - .setExpression(ConstantNode(Int64ResultNode(0))) - ); + Group expect; + expect.addResult(CountAggregationResult().setCount(3).setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))); EXPECT_TRUE(testAggregation(ctx, request, expect)); } { - Group expect = Group() - .addResult(CountAggregationResult().setCount(1) - .setExpression(ConstantNode(Int64ResultNode(0))) - ); + Group expect = Group().addResult(CountAggregationResult() + .setCount(1) + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))); EXPECT_TRUE(testAggregation(ctx, request.setTopN(1), expect)); } { - Grouping request2 = Grouping() - .addLevel(GroupingLevel() - .addAggregationResult(SumAggregationResult()) - .addOrderBy(AggregationRefNode(0), false)); + Grouping request2; + request2.addLevel(std::move(GroupingLevel() + .addAggregationResult(MU<SumAggregationResult>()) + .addOrderBy(MU<AggregationRefNode>(0), false))); EXPECT_TRUE(request2.needResort()); request2.setTopN(0); EXPECT_TRUE(request2.needResort()); @@ -1616,17 +1623,11 @@ Test::testCount() ctx.result().add(0).add(1).add(2); ctx.add(IntAttrBuilder("foo").add(3).add(7).add(15).sp()); - Grouping request = Grouping() - .setRoot(Group() - .addResult(CountAggregationResult() - .setExpression(ConstantNode(Int64ResultNode(0))) - ) - ); + Grouping request; + request.setRoot(Group().addResult(CountAggregationResult().setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0))))); - Group expect = Group() - .addResult(CountAggregationResult().setCount(3) - .setExpression(ConstantNode(Int64ResultNode(0))) - ); + Group expect; + expect.addResult(CountAggregationResult().setCount(3).setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))); EXPECT_TRUE(testAggregation(ctx, request, expect)); } @@ -1653,7 +1654,7 @@ Test::testFS4HitCollection() .setRoot(Group() .addResult(HitsAggregationResult() .setMaxHits(3) - .setExpression(ConstantNode(Int64ResultNode(0)))) + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))) ); Group expect = Group() @@ -1663,7 +1664,7 @@ Test::testFS4HitCollection() .addHit(FS4Hit(25, 25.0)) .addHit(FS4Hit(20, 20.0)) .sort() - .setExpression(ConstantNode(Int64ResultNode(0)))); + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))); EXPECT_TRUE(testAggregation(ctx, request, expect)); } @@ -1673,7 +1674,7 @@ Test::testFS4HitCollection() .setRoot(Group() .addResult(HitsAggregationResult() .setMaxHits(3) - .setExpression(ConstantNode(Int64ResultNode(0)))) + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))) ); Group expect = Group() @@ -1684,7 +1685,7 @@ Test::testFS4HitCollection() .addHit(FS4Hit(20, 20.0)) .addHit(FS4Hit(10, 10.0)) .sort() - .setExpression(ConstantNode(Int64ResultNode(0)))); + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))); Group a = Group() .setId(NullResultNode()) @@ -1694,7 +1695,7 @@ Test::testFS4HitCollection() .addHit(FS4Hit(1, 5.0)) .addHit(FS4Hit(2, 4.0)) .sort() - .setExpression(ConstantNode(Int64ResultNode(0)))); + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))); Group b = Group() .setId(NullResultNode()) @@ -1704,7 +1705,7 @@ Test::testFS4HitCollection() .addHit(FS4Hit(3, 7.0)) .addHit(FS4Hit(4, 6.0)) .sort() - .setExpression(ConstantNode(Int64ResultNode(0)))); + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))); Group c = Group() .setId(NullResultNode()) @@ -1714,7 +1715,7 @@ Test::testFS4HitCollection() .addHit(FS4Hit(5, 9.0)) .addHit(FS4Hit(6, 8.0)) .sort() - .setExpression(ConstantNode(Int64ResultNode(0)))); + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))); EXPECT_TRUE(testMerge(request.unchain().setRoot(a), request.unchain().setRoot(b), request.unchain().setRoot(c), expect)); EXPECT_TRUE(testMerge(request.unchain().setRoot(b), request.unchain().setRoot(c), request.unchain().setRoot(a), expect)); @@ -1770,9 +1771,9 @@ Test::checkBucket(const NumericResultNode &width, const NumericResultNode &value } else { return EXPECT_TRUE(false); } - Grouping request = Grouping() - .addLevel(GroupingLevel() - .setExpression(FixedWidthBucketFunctionNode(AttributeNode("attr")).setWidth(width))); + std::unique_ptr<FixedWidthBucketFunctionNode> fixed = MU<FixedWidthBucketFunctionNode>(MU<AttributeNode>("attr")); + fixed->setWidth(width); + Grouping request = Grouping().addLevel(createGL(std::move(fixed))); Group expect = Group().addChild(Group().setId(bucket)); return testAggregation(ctx, request, expect); } @@ -1889,11 +1890,11 @@ struct RunDiff { ~RunDiff() { system("diff -u lhs.out rhs.out > diff.txt"); }}; int Test::Main() { - RunDiff runDiff; - (void) runDiff; - TEST_DEBUG("lhs.out", "rhs.out"); + //RunDiff runDiff; + //(void) runDiff; + //TEST_DEBUG("lhs.out", "rhs.out"); TEST_INIT("grouping_test"); - testAggregationSimple(); + TEST_DO(testAggregationSimple()); testAggregationLevels(); testAggregationMaxGroups(); testAggregationGroupOrder(); diff --git a/searchlib/src/tests/groupingengine/groupingengine_benchmark.cpp b/searchlib/src/tests/groupingengine/groupingengine_benchmark.cpp index 4b65477224d..24eda69ea84 100644 --- a/searchlib/src/tests/groupingengine/groupingengine_benchmark.cpp +++ b/searchlib/src/tests/groupingengine/groupingengine_benchmark.cpp @@ -1,6 +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/log/log.h> + #include <vespa/vespalib/testkit/testapp.h> #include <vespa/searchlib/aggregation/perdocexpression.h> #include <vespa/searchlib/aggregation/aggregation.h> @@ -14,6 +13,7 @@ #include <vespa/vespalib/objects/objectpredicate.h> #include <vespa/vespalib/objects/objectoperation.h> #include <vespa/vespalib/util/rusage.h> +#include <vespa/log/log.h> LOG_SETUP("grouping_benchmark"); using namespace vespalib; @@ -41,7 +41,7 @@ public: for (uint32_t docid = 0; docid < numDocs; ++docid) { T val; uint32_t res = rhs._attr->get(docid, &val, 1); - LOG_ASSERT(res == 1); + assert(res == 1); add(val); } } @@ -180,6 +180,8 @@ Test::testAggregation(AggregationContext &ctx, const Grouping &request, bool use return true; } +#define MU std::make_unique + void Test::benchmarkIntegerSum(bool useEngine, size_t numDocs, size_t numQueries, int64_t maxGroups) { @@ -193,18 +195,16 @@ Test::benchmarkIntegerSum(bool useEngine, size_t numDocs, size_t numQueries, int } ctx.add(attrB.sp()); GroupingLevel level; - level.setExpression(AttributeNode("attr0")).setMaxGroups(maxGroups); - level.addResult(SumAggregationResult().setExpression(AttributeNode("attr0"))); + level.setExpression(MU<AttributeNode>("attr0")).setMaxGroups(maxGroups); + level.addResult(SumAggregationResult().setExpression(MU<AttributeNode>("attr0"))); if (maxGroups >= 0) { - level.addOrderBy(AggregationRefNode(0), false); + level.addOrderBy(MU<AggregationRefNode>(0), false); } - Grouping baseRequest = Grouping() - .setFirstLevel(0) - .setLastLevel(1) - .setRoot(Group() - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr0")))) - .addLevel(level); + Grouping baseRequest; + baseRequest.setFirstLevel(0) + .setLastLevel(1) + .setRoot(Group().addResult(SumAggregationResult().setExpression(MU<AttributeNode>("attr0")))) + .addLevel(std::move(level)); for (size_t i(0); i < numQueries; i++) { testAggregation(ctx, baseRequest, useEngine); @@ -224,18 +224,16 @@ Test::benchmarkIntegerCount(bool useEngine, size_t numDocs, size_t numQueries, i } ctx.add(attrB.sp()); GroupingLevel level; - level.setExpression(AttributeNode("attr0")).setMaxGroups(maxGroups); - level.addResult(CountAggregationResult().setExpression(AttributeNode("attr0"))); + level.setExpression(MU<AttributeNode>("attr0")).setMaxGroups(maxGroups); + level.addResult(CountAggregationResult().setExpression(MU<AttributeNode>("attr0"))); if (maxGroups >= 0) { - level.addOrderBy(AggregationRefNode(0), false); + level.addOrderBy(MU<AggregationRefNode>(0), false); } - Grouping baseRequest = Grouping() - .setFirstLevel(0) - .setLastLevel(1) - .setRoot(Group() - .addResult(CountAggregationResult() - .setExpression(AttributeNode("attr0")))) - .addLevel(level); + Grouping baseRequest; + baseRequest.setFirstLevel(0) + .setLastLevel(1) + .setRoot(Group().addResult(CountAggregationResult().setExpression(MU<AttributeNode>("attr0")))) + .addLevel(std::move(level)); for (size_t i(0); i < numQueries; i++) { testAggregation(ctx, baseRequest, useEngine); @@ -277,7 +275,6 @@ Test::Main() LOG(info, "sizeof(CountAggregationResult) = %ld", sizeof(CountAggregationResult)); LOG(info, "sizeof(Int64ResultNode) = %ld", sizeof(Int64ResultNode)); - LOG(info, "sizeof(Group::ExpressionVector) = %ld", sizeof(Group::ExpressionVector)); fastos::TimeStamp start(fastos::ClockSystem::now()); if (idType == "int") { if (aggrType == "sum") { diff --git a/searchlib/src/tests/groupingengine/groupingengine_test.cpp b/searchlib/src/tests/groupingengine/groupingengine_test.cpp index 4b2cf6a708a..d3f1df8c501 100644 --- a/searchlib/src/tests/groupingengine/groupingengine_test.cpp +++ b/searchlib/src/tests/groupingengine/groupingengine_test.cpp @@ -1,7 +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/log/log.h> -LOG_SETUP("groupingengine_test"); + #include <vespa/vespalib/testkit/testapp.h> #include <vespa/searchlib/aggregation/perdocexpression.h> #include <vespa/searchlib/aggregation/aggregation.h> @@ -41,7 +39,7 @@ public: for (uint32_t docid = 0; docid < numDocs; ++docid) { T val; uint32_t res = rhs._attr->get(docid, &val, 1); - LOG_ASSERT(res == 1); + assert(res == 1); add(val); } } @@ -316,26 +314,57 @@ Test::testAggregationSimple() testAggregationSimpleSum(ctx, MaxAggregationResult(), Int64ResultNode(15), FloatResultNode(15), StringResultNode("7")); } +#define MU std::make_unique + void Test::testAggregationSimpleSum(AggregationContext & ctx, const AggregationResult & aggr, const ResultNode & ir, const ResultNode & fr, const ResultNode & sr) { ExpressionNode::CP clone(aggr); - Grouping request = Grouping() - .setRoot(Group() - .setId(NullResultNode()) - .addResult(static_cast<AggregationResult &>(*clone).setExpression(AttributeNode("int"))) - .addResult(static_cast<AggregationResult &>(*clone).setExpression(AttributeNode("float"))) - .addResult(static_cast<AggregationResult &>(*clone).setExpression(AttributeNode("string"))) - ); - - Group expect = Group() - .setId(NullResultNode()) - .addResult(static_cast<AggregationResult &>(*clone).setExpression(AttributeNode("int")).setResult(ir)) - .addResult(static_cast<AggregationResult &>(*clone).setExpression(AttributeNode("float")).setResult(fr)) - .addResult(static_cast<AggregationResult &>(*clone).setExpression(AttributeNode("string")).setResult(sr)); + Grouping request; + request.setRoot(Group().setId(NullResultNode()) + .addResult(static_cast<AggregationResult &>(*clone).setExpression(MU<AttributeNode>("int"))) + .addResult(static_cast<AggregationResult &>(*clone).setExpression(MU<AttributeNode>("float"))) + .addResult(static_cast<AggregationResult &>(*clone).setExpression(MU<AttributeNode>("string")))); + + Group expect; + expect.setId(NullResultNode()) + .addResult(static_cast<AggregationResult &>(*clone).setExpression(MU<AttributeNode>("int")).setResult(ir)) + .addResult(static_cast<AggregationResult &>(*clone).setExpression(MU<AttributeNode>("float")).setResult(fr)) + .addResult(static_cast<AggregationResult &>(*clone).setExpression(MU<AttributeNode>("string")).setResult(sr)); EXPECT_TRUE(testAggregation(ctx, request, expect)); } +GroupingLevel +createGL(ExpressionNode::UP expr, ExpressionNode::UP result) { + GroupingLevel l; + l.setExpression(std::move(expr)); + l.addResult(SumAggregationResult().setExpression(std::move(result))); + return l; +} + +GroupingLevel +createGL(ExpressionNode::UP expr) { + GroupingLevel l; + l.setExpression(std::move(expr)); + return l; +} + +GroupingLevel +createGL(size_t maxGroups, ExpressionNode::UP expr) { + GroupingLevel l; + l.setMaxGroups(maxGroups); + l.setExpression(std::move(expr)); + return l; +} + +GroupingLevel +createGL(size_t maxGroups, ExpressionNode::UP expr, ExpressionNode::UP result) { + GroupingLevel l; + l.setMaxGroups(maxGroups); + l.setExpression(std::move(expr)); + l.addResult(SumAggregationResult().setExpression(std::move(result))); + return l; +} /** * Verify that the backend aggregation will classify and collect on * the appropriate levels, as indicated by the firstLevel and @@ -351,97 +380,71 @@ Test::testAggregationLevels() ctx.add(IntAttrBuilder("attr3").add(13).add(13).sp()); ctx.result().add(0).add(1); - Grouping baseRequest = Grouping() - .setRoot(Group() - .setId(NullResultNode()) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr0")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr1")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr2")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr2")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr3")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr3")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr1")))); - - Group notDone = Group() - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr0"))); -// Hmm, do not need to prepare more than the levels needed. .setResult(Int64ResultNode(0))); - - Group done0 = Group() - .setId(NullResultNode()) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr0")) - .setResult(Int64ResultNode(20))) - .addChild(Group() - .setId(Int64ResultNode(11)) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr2")) - .setResult(Int64ResultNode(0)))); + Grouping baseRequest; + baseRequest.setRoot(Group().setId(NullResultNode()) + .addResult(SumAggregationResult().setExpression(MU<AttributeNode>("attr0")))) + .addLevel(createGL(MU<AttributeNode>("attr1"), MU<AttributeNode>("attr2"))) + .addLevel(createGL(MU<AttributeNode>("attr2"), MU<AttributeNode>("attr3"))) + .addLevel(createGL(MU<AttributeNode>("attr3"), MU<AttributeNode>("attr1"))); - Group done1 = Group() - .setId(NullResultNode()) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr0")) - .setResult(Int64ResultNode(20))) - .addChild(Group() - .setId(Int64ResultNode(11)) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr2")) - .setResult(Int64ResultNode(24))) - .addChild(Group() - .setId(Int64ResultNode(12)) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr3")) - .setResult(Int64ResultNode(0))))); + Group notDone; + notDone.addResult(SumAggregationResult().setExpression(MU<AttributeNode>("attr0"))); +// Hmm, do not need to prepare more than the levels needed. .setResult(Int64ResultNode(0))); - Group done2 = Group() - .setId(NullResultNode()) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr0")) - .setResult(Int64ResultNode(20))) - .addChild(Group() - .setId(Int64ResultNode(11)) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr2")) - .setResult(Int64ResultNode(24))) - .addChild(Group() + Group done0; + done0.setId(NullResultNode()) + .addResult(SumAggregationResult().setExpression(MU<AttributeNode>("attr0")) + .setResult(Int64ResultNode(20))) + .addChild(Group().setId(Int64ResultNode(11)) + .addResult(SumAggregationResult().setExpression(MU<AttributeNode>("attr2")) + .setResult(Int64ResultNode(0)))); + + Group done1; + done1.setId(NullResultNode()) + .addResult(SumAggregationResult().setExpression(MU<AttributeNode>("attr0")) + .setResult(Int64ResultNode(20))) + .addChild(Group().setId(Int64ResultNode(11)) + .addResult(SumAggregationResult().setExpression(MU<AttributeNode>("attr2")) + .setResult(Int64ResultNode(24))) + .addChild(Group().setId(Int64ResultNode(12)) + .addResult(SumAggregationResult().setExpression(MU<AttributeNode>("attr3")) + .setResult(Int64ResultNode(0))))); + + Group done2; + done2.setId(NullResultNode()) + .addResult(SumAggregationResult().setExpression(MU<AttributeNode>("attr0")) + .setResult(Int64ResultNode(20))) + .addChild(Group().setId(Int64ResultNode(11)) + .addResult(SumAggregationResult().setExpression(MU<AttributeNode>("attr2")) + .setResult(Int64ResultNode(24))) + .addChild(Group() .setId(Int64ResultNode(12)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr3")) + .setExpression(MU<AttributeNode>("attr3")) .setResult(Int64ResultNode(26))) .addChild(Group() .setId(Int64ResultNode(13)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr1")) + .setExpression(MU<AttributeNode>("attr1")) .setResult(Int64ResultNode(0)))))); - Group done3 = Group() - .setId(NullResultNode()) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr0")) - .setResult(Int64ResultNode(20))) - .addChild(Group() - .setId(Int64ResultNode(11)) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr2")) - .setResult(Int64ResultNode(24))) - .addChild(Group() - .setId(Int64ResultNode(12)) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr3")) - .setResult(Int64ResultNode(26))) - .addChild(Group() - .setId(Int64ResultNode(13)) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr1")) - .setResult(Int64ResultNode(22)))))); + Group done3; + done3.setId(NullResultNode()) + .addResult(SumAggregationResult() + .setExpression(MU<AttributeNode>("attr0")) + .setResult(Int64ResultNode(20))) + .addChild(Group().setId(Int64ResultNode(11)) + .addResult(SumAggregationResult() + .setExpression(MU<AttributeNode>("attr2")) + .setResult(Int64ResultNode(24))) + .addChild(Group().setId(Int64ResultNode(12)) + .addResult(SumAggregationResult() + .setExpression(MU<AttributeNode>("attr3")) + .setResult(Int64ResultNode(26))) + .addChild(Group().setId(Int64ResultNode(13)) + .addResult(SumAggregationResult() + .setExpression(MU<AttributeNode>("attr1")) + .setResult(Int64ResultNode(22)))))); { // level 0 only Grouping request = baseRequest.unchain().setFirstLevel(0).setLastLevel(0); @@ -498,8 +501,7 @@ Test::testAggregationMaxGroups() Grouping baseRequest = Grouping() .setRoot(Group().setId(NullResultNode())) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr"))); + .addLevel(createGL(MU<AttributeNode>("attr"))); Group empty = Group().setId(NullResultNode()); Group grp1 = empty.unchain().addChild(Group().setId(Int64ResultNode(5))); @@ -550,18 +552,17 @@ Test::testAggregationGroupOrder() Grouping request = Grouping() .setRoot(Group().setId(NullResultNode())) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr"))); - - Group expect = Group() - .setId(NullResultNode()) - .addChild(Group().setId(Int64ResultNode(5))) - .addChild(Group().setId(Int64ResultNode(10))) - .addChild(Group().setId(Int64ResultNode(15))) - .addChild(Group().setId(Int64ResultNode(20))) - .addChild(Group().setId(Int64ResultNode(25))) - .addChild(Group().setId(Int64ResultNode(30))) - .addChild(Group().setId(Int64ResultNode(35))); + .addLevel(createGL(MU<AttributeNode>("attr"))); + + Group expect; + expect.setId(NullResultNode()) + .addChild(Group().setId(Int64ResultNode(5))) + .addChild(Group().setId(Int64ResultNode(10))) + .addChild(Group().setId(Int64ResultNode(15))) + .addChild(Group().setId(Int64ResultNode(20))) + .addChild(Group().setId(Int64ResultNode(25))) + .addChild(Group().setId(Int64ResultNode(30))) + .addChild(Group().setId(Int64ResultNode(35))); EXPECT_TRUE(testAggregation(ctx, request, expect)); } @@ -584,7 +585,7 @@ Test::testAggregationGroupRank() Grouping request = Grouping() .setRoot(Group().setId(NullResultNode())) - .addLevel(GroupingLevel().setExpression(AttributeNode("attr"))); + .addLevel(createGL(MU<AttributeNode>("attr"))); Group expect = Group() .setId(NullResultNode()) @@ -595,6 +596,22 @@ Test::testAggregationGroupRank() EXPECT_TRUE(testAggregation(ctx, request, expect)); } +template<typename T> +ExpressionNode::UP +createAggr(ExpressionNode::UP e) { + std::unique_ptr<T> aggr = MU<T>(); + aggr->setExpression(std::move(e)); + return aggr; +} + +template<typename T> +ExpressionNode::UP +createAggr(SingleResultNode::UP r, ExpressionNode::UP e) { + std::unique_ptr<T> aggr = MU<T>(std::move(r)); + aggr->setExpression(std::move(e)); + return aggr; +} + void Test::testAggregationGroupCapping() { @@ -609,8 +626,8 @@ Test::testAggregationGroupCapping() .add(6, 7).add(7, 8).add(8, 9); { - Grouping request = Grouping().setRoot(Group().setId(NullResultNode())).addLevel( - GroupingLevel().setExpression(AttributeNode("attr"))); + Grouping request; + request.setRoot(Group().setId(NullResultNode())).addLevel(createGL(MU<AttributeNode>("attr"))); Group expect = Group().setId(NullResultNode()) .addChild(Group().setId(Int64ResultNode(1)).setRank(RawRank(1))) @@ -626,66 +643,86 @@ Test::testAggregationGroupCapping() EXPECT_TRUE(testAggregation(ctx, request, expect)); } { - Grouping request = Grouping().setRoot(Group().setId(NullResultNode())).addLevel( - GroupingLevel().setMaxGroups(3).setExpression(AttributeNode("attr"))); + Grouping request; + request.setRoot(Group().setId(NullResultNode())).addLevel( + createGL(3, MU<AttributeNode>("attr"))); - Group expect = Group().setId(NullResultNode()) - .addChild(Group().setId(Int64ResultNode(7)).setRank(RawRank(7))) - .addChild(Group().setId(Int64ResultNode(8)).setRank(RawRank(8))) - .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(9))); + Group expect; + expect.setId(NullResultNode()) + .addChild(Group().setId(Int64ResultNode(7)).setRank(RawRank(7))) + .addChild(Group().setId(Int64ResultNode(8)).setRank(RawRank(8))) + .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(9))); EXPECT_TRUE(testAggregation(ctx, request, expect)); } { - Grouping request = Grouping(). - setRoot(Group().setId(NullResultNode())). - setFirstLevel(0). - setLastLevel(1). - addLevel( - GroupingLevel().setMaxGroups(3).setExpression(AttributeNode("attr")). - addAggregationResult(SumAggregationResult().setExpression(AttributeNode("attr"))). - addOrderBy(AggregationRefNode(0), false)); - - Group expect = Group().setId(NullResultNode()) - .addChild(Group().setId(Int64ResultNode(7)).setRank(RawRank(7)).addAggregationResult(SumAggregationResult(Int64ResultNode(7)).setExpression(AttributeNode("attr"))).addOrderBy(AggregationRefNode(0), false)) - .addChild(Group().setId(Int64ResultNode(8)).setRank(RawRank(8)).addAggregationResult(SumAggregationResult(Int64ResultNode(8)).setExpression(AttributeNode("attr"))).addOrderBy(AggregationRefNode(0), false)) - .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(9)).addAggregationResult(SumAggregationResult(Int64ResultNode(9)).setExpression(AttributeNode("attr"))).addOrderBy(AggregationRefNode(0), false)); + Grouping request; + request.setRoot(Group().setId(NullResultNode())) + .setFirstLevel(0) + .setLastLevel(1) + .addLevel(std::move(GroupingLevel().setMaxGroups(3).setExpression(MU<AttributeNode>("attr")) + .addAggregationResult(createAggr<SumAggregationResult>(MU<AttributeNode>("attr"))) + .addOrderBy(MU<AggregationRefNode>(0), false))); + + Group expect; + expect.setId(NullResultNode()) + .addChild(Group().setId(Int64ResultNode(7)).setRank(RawRank(7)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(7), MU<AttributeNode>("attr"))) + .addOrderBy(MU<AggregationRefNode>(0), false)) + .addChild(Group().setId(Int64ResultNode(8)).setRank(RawRank(8)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(8), MU<AttributeNode>("attr"))) + .addOrderBy(MU<AggregationRefNode>(0), false)) + .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(9)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(9), MU<AttributeNode>("attr"))) + .addOrderBy(MU<AggregationRefNode>(0), false)); EXPECT_TRUE(testAggregation(ctx, request, expect)); } { - Grouping request = Grouping(). - setRoot(Group().setId(NullResultNode())). - setFirstLevel(0). - setLastLevel(1). - addLevel( - GroupingLevel().setMaxGroups(3).setExpression(AttributeNode("attr")). - addAggregationResult(SumAggregationResult().setExpression(AttributeNode("attr"))).addOrderBy(AggregationRefNode(0), true)); - - Group expect = Group().setId(NullResultNode()) - .addChild(Group().setId(Int64ResultNode(1)).setRank(RawRank(1)).addAggregationResult(SumAggregationResult(Int64ResultNode(1)).setExpression(AttributeNode("attr"))).addOrderBy(AggregationRefNode(0), true)) - .addChild(Group().setId(Int64ResultNode(2)).setRank(RawRank(2)).addAggregationResult(SumAggregationResult(Int64ResultNode(2)).setExpression(AttributeNode("attr"))).addOrderBy(AggregationRefNode(0), true)) - .addChild(Group().setId(Int64ResultNode(3)).setRank(RawRank(3)).addAggregationResult(SumAggregationResult(Int64ResultNode(3)).setExpression(AttributeNode("attr"))).addOrderBy(AggregationRefNode(0), true)); + Grouping request; + request.setRoot(Group().setId(NullResultNode())) + .setFirstLevel(0) + .setLastLevel(1) + .addLevel(std::move(GroupingLevel().setMaxGroups(3).setExpression(MU<AttributeNode>("attr")) + .addAggregationResult(createAggr<SumAggregationResult>(MU<AttributeNode>("attr"))) + .addOrderBy(MU<AggregationRefNode>(0), true))); + + Group expect; + expect.setId(NullResultNode()) + .addChild(Group().setId(Int64ResultNode(1)).setRank(RawRank(1)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(1), MU<AttributeNode>("attr"))) + .addOrderBy(MU<AggregationRefNode>(0), true)) + .addChild(Group().setId(Int64ResultNode(2)).setRank(RawRank(2)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(2), MU<AttributeNode>("attr"))) + .addOrderBy(MU<AggregationRefNode>(0), true)) + .addChild(Group().setId(Int64ResultNode(3)).setRank(RawRank(3)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(3), MU<AttributeNode>("attr"))) + .addOrderBy(MU<AggregationRefNode>(0), true)); EXPECT_TRUE(testAggregation(ctx, request, expect)); } { AddFunctionNode *add = new AddFunctionNode(); - add->addArg(AggregationRefNode(0)); - add->appendArg(ConstantNode(Int64ResultNode(3))); - ExpressionNode::CP i1(add); - Grouping request = Grouping(). - setFirstLevel(0). - setLastLevel(1). - addLevel( - GroupingLevel().setMaxGroups(3).setExpression(AttributeNode("attr")). - addAggregationResult(SumAggregationResult().setExpression(AttributeNode("attr"))). - addOrderBy(i1, false)); + add->addArg(MU<AggregationRefNode>(0)); + add->appendArg(MU<ConstantNode>(MU<Int64ResultNode>(3))); + ExpressionNode::UP i1(add); + Grouping request; + request.setFirstLevel(0) + .setLastLevel(1) + .addLevel(std::move(GroupingLevel().setMaxGroups(3).setExpression(MU<AttributeNode>("attr")). + addResult(createAggr<SumAggregationResult>(MU<AttributeNode>("attr"))). + addOrderBy(std::move(i1), false))); Group expect = Group() - .addChild(Group().setId(Int64ResultNode(7)).setRank(RawRank(7)).addAggregationResult(SumAggregationResult(Int64ResultNode(7)).setExpression(AttributeNode("attr"))).addOrderBy(AddFunctionNode().appendArg(AggregationRefNode(0)).appendArg(ConstantNode(Int64ResultNode(3))).setResult(Int64ResultNode(10)), false)) - .addChild(Group().setId(Int64ResultNode(8)).setRank(RawRank(8)).addAggregationResult(SumAggregationResult(Int64ResultNode(8)).setExpression(AttributeNode("attr"))).addOrderBy(AddFunctionNode().appendArg(AggregationRefNode(0)).appendArg(ConstantNode(Int64ResultNode(3))).setResult(Int64ResultNode(11)), false)) - .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(9)).addAggregationResult(SumAggregationResult(Int64ResultNode(9)).setExpression(AttributeNode("attr"))).addOrderBy(AddFunctionNode().appendArg(AggregationRefNode(0)).appendArg(ConstantNode(Int64ResultNode(3))).setResult(Int64ResultNode(12)), false)); + .addChild(Group().setId(Int64ResultNode(7)).setRank(RawRank(7)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(7), MU<AttributeNode>("attr"))) + .addOrderBy(AddFunctionNode().appendArg(MU<AggregationRefNode>(0)).appendArg(MU<ConstantNode>(MU<Int64ResultNode>(3))).setResult(Int64ResultNode(10)), false)) + .addChild(Group().setId(Int64ResultNode(8)).setRank(RawRank(8)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(8), MU<AttributeNode>("attr"))) + .addOrderBy(AddFunctionNode().appendArg(MU<AggregationRefNode>(0)).appendArg(MU<ConstantNode>(MU<Int64ResultNode>(3))).setResult(Int64ResultNode(11)), false)) + .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(9)) + .addAggregationResult(createAggr<SumAggregationResult>(MU<Int64ResultNode>(9), MU<AttributeNode>("attr"))) + .addOrderBy(AddFunctionNode().appendArg(MU<AggregationRefNode>(0)).appendArg(MU<ConstantNode>(MU<Int64ResultNode>(3))).setResult(Int64ResultNode(12)), false)); EXPECT_TRUE(testAggregation(ctx, request, expect)); } @@ -706,20 +743,20 @@ Test::testMergeSimpleSum() .setRoot(Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("foo")) + .setExpression(MU<AttributeNode>("foo")) .setResult(Int64ResultNode(20)))); Grouping b = Grouping() .setRoot(Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("foo")) + .setExpression(MU<AttributeNode>("foo")) .setResult(Int64ResultNode(30)))); Group expect = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("foo")) + .setExpression(MU<AttributeNode>("foo")) .setResult(Int64ResultNode(50))); EXPECT_TRUE(testMerge(a, b, expect)); @@ -732,167 +769,158 @@ void Test::testMergeLevels() { Grouping request = Grouping() - .addLevel(GroupingLevel() - .setExpression(AttributeNode("c1")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("c2")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("c3")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")))); + .addLevel(createGL(MU<AttributeNode>("c1"), MU<AttributeNode>("s1"))) + .addLevel(createGL(MU<AttributeNode>("c2"), MU<AttributeNode>("s2"))) + .addLevel(createGL(MU<AttributeNode>("c3"), MU<AttributeNode>("s3"))); Group a = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(5))) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(10))) .addChild(Group() .setId(Int64ResultNode(20)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(15))) .addChild(Group() .setId(Int64ResultNode(30)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(20)))))); Group b = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(5))) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(10))) .addChild(Group() .setId(Int64ResultNode(20)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(15))) .addChild(Group() .setId(Int64ResultNode(30)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(20)))))); Group expect_all = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(10))) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(20))) .addChild(Group() .setId(Int64ResultNode(20)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(30))) .addChild(Group() .setId(Int64ResultNode(30)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(40)))))); Group expect_0 = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(5))) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(20))) .addChild(Group() .setId(Int64ResultNode(20)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(30))) .addChild(Group() .setId(Int64ResultNode(30)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(40)))))); Group expect_1 = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(5))) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(10))) .addChild(Group() .setId(Int64ResultNode(20)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(30))) .addChild(Group() .setId(Int64ResultNode(30)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(40)))))); Group expect_2 = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(5))) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(10))) .addChild(Group() .setId(Int64ResultNode(20)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(15))) .addChild(Group() .setId(Int64ResultNode(30)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(40)))))); Group expect_3 = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(5))) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(10))) .addChild(Group() .setId(Int64ResultNode(20)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(15))) .addChild(Group() .setId(Int64ResultNode(30)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(20)))))); EXPECT_TRUE(testMerge(request.unchain().setFirstLevel(0).setLastLevel(3).setRoot(a), @@ -920,9 +948,7 @@ Test::testMergeLevels() void Test::testMergeGroups() { - Grouping request = Grouping() - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr"))); + Grouping request = Grouping().addLevel(createGL(MU<AttributeNode>("attr"))); Group a = Group() .setId(NullResultNode()) @@ -983,48 +1009,36 @@ Test::testMergeGroups() void Test::testMergeTrees() { - Grouping request = Grouping() - .addLevel(GroupingLevel() - .setMaxGroups(3) - .setExpression(AttributeNode("c1")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")))) - .addLevel(GroupingLevel() - .setMaxGroups(2) - .setExpression(AttributeNode("c2")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")))) - .addLevel(GroupingLevel() - .setMaxGroups(1) - .setExpression(AttributeNode("c3")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")))); + Grouping request; + request.addLevel(createGL(3, MU<AttributeNode>("c1"), MU<AttributeNode>("s1"))) + .addLevel(createGL(2, MU<AttributeNode>("c2"), MU<AttributeNode>("s2"))) + .addLevel(createGL(1, MU<AttributeNode>("c3"), MU<AttributeNode>("s3"))); Group a = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(4)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(5)) .setRank(RawRank(5)) // merged with 200 rank node .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(4)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(5)) .setRank(RawRank(500)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(4)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(5)) .setRank(RawRank(200)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1034,21 +1048,21 @@ Test::testMergeTrees() .setId(Int64ResultNode(10)) .setRank(RawRank(100)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(100))) // dummy child would be picked up here .addChild(Group() .setId(Int64ResultNode(15)) .setRank(RawRank(200)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(14)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(15)) .setRank(RawRank(300)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1058,14 +1072,14 @@ Test::testMergeTrees() .setId(Int64ResultNode(15)) .setRank(RawRank(300)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(19)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(20)) .setRank(RawRank(100)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) ) ); @@ -1073,28 +1087,28 @@ Test::testMergeTrees() Group b = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(4)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(5)) .setRank(RawRank(200)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(10)) .setRank(RawRank(400)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(9)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(10)) .setRank(RawRank(100)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1104,14 +1118,14 @@ Test::testMergeTrees() .setId(Int64ResultNode(10)) .setRank(RawRank(100)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(100))) // dummy child would be picket up here .addChild(Group() .setId(Int64ResultNode(15)) .setRank(RawRank(200)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) ) ) @@ -1120,21 +1134,21 @@ Test::testMergeTrees() .setId(Int64ResultNode(15)) .setRank(RawRank(5)) // merged with 300 rank node .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(19)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(20)) .setRank(RawRank(5)) // merged with 100 rank node .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(19)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(20)) .setRank(RawRank(500)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1143,14 +1157,14 @@ Test::testMergeTrees() .setId(Int64ResultNode(25)) .setRank(RawRank(300)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group().setId(Int64ResultNode(24)).setRank(RawRank(10))) .addChild(Group() .setId(Int64ResultNode(25)) .setRank(RawRank(400)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1159,25 +1173,25 @@ Test::testMergeTrees() Group expect = Group() .setId(NullResultNode()) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(200))) .addChild(Group() .setId(Int64ResultNode(5)) .setRank(RawRank(200)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(200))) .addChild(Group() .setId(Int64ResultNode(5)) .setRank(RawRank(500)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group() .setId(Int64ResultNode(5)) .setRank(RawRank(200)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1185,13 +1199,13 @@ Test::testMergeTrees() .setId(Int64ResultNode(10)) .setRank(RawRank(400)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group() .setId(Int64ResultNode(10)) .setRank(RawRank(100)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1200,19 +1214,19 @@ Test::testMergeTrees() .setId(Int64ResultNode(10)) .setRank(RawRank(100)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(200))) .addChild(Group() .setId(Int64ResultNode(15)) .setRank(RawRank(200)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(200))) .addChild(Group() .setId(Int64ResultNode(15)) .setRank(RawRank(300)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1221,19 +1235,19 @@ Test::testMergeTrees() .setId(Int64ResultNode(15)) .setRank(RawRank(300)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(200))) .addChild(Group() .setId(Int64ResultNode(20)) .setRank(RawRank(100)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(200))) .addChild(Group() .setId(Int64ResultNode(20)) .setRank(RawRank(500)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1241,13 +1255,13 @@ Test::testMergeTrees() .setId(Int64ResultNode(25)) .setRank(RawRank(300)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group() .setId(Int64ResultNode(25)) .setRank(RawRank(400)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1400,39 +1414,30 @@ Test::testPruneComplex() void Test::testPartialMerging() { - Grouping baseRequest = Grouping() - .addLevel(GroupingLevel() - .setExpression(AttributeNode("c1")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("c2")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("c3")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")))); + Grouping baseRequest; + baseRequest.addLevel(createGL(MU<AttributeNode>("c1"), MU<AttributeNode>("s1"))) + .addLevel(createGL(MU<AttributeNode>("c2"), MU<AttributeNode>("s2"))) + .addLevel(createGL(MU<AttributeNode>("c3"), MU<AttributeNode>("s3"))); // Cached result Group cached = Group() .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(110))) .addChild(Group() .setId(Int64ResultNode(5)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(10))) .addChild(Group() .setId(Int64ResultNode(13)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group() .setId(Int64ResultNode(14)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1440,17 +1445,17 @@ Test::testPartialMerging() .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(100))) .addChild(Group() .setId(Int64ResultNode(15)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(100))) .addChild(Group() .setId(Int64ResultNode(22)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s3")) + .setExpression(MU<AttributeNode>("s3")) .setResult(Int64ResultNode(100))) ) ) @@ -1461,23 +1466,23 @@ Test::testPartialMerging() Grouping request = baseRequest.unchain().setFirstLevel(0).setLastLevel(0); Group incoming = Group() .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(0))); Group expected = Group() .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(110))) .addChild(Group() .setId(Int64ResultNode(5)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ); EXPECT_TRUE(testPartialMerge(request.unchain().setRoot(incoming), request.unchain().setLastLevel(3).setRoot(cached), expected)); @@ -1487,81 +1492,81 @@ Test::testPartialMerging() Grouping request = baseRequest.unchain().setFirstLevel(1).setLastLevel(1); Group incoming = Group() .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(200))) .addChild(Group() .setId(Int64ResultNode(3)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ) .addChild(Group() .setId(Int64ResultNode(5)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ) .addChild(Group() .setId(Int64ResultNode(7)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0)))) .addChild(Group() .setId(Int64ResultNode(33)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ); Group expected = Group() .addResult(SumAggregationResult() - .setExpression(AttributeNode("s0")) + .setExpression(MU<AttributeNode>("s0")) .setResult(Int64ResultNode(200))) .addChild(Group() .setId(Int64ResultNode(3)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ) .addChild(Group() .setId(Int64ResultNode(5)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(10))) .addChild(Group() .setId(Int64ResultNode(13)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(0))) ) ) .addChild(Group() .setId(Int64ResultNode(7)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ) .addChild(Group() .setId(Int64ResultNode(10)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(100))) .addChild(Group() .setId(Int64ResultNode(15)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s2")) + .setExpression(MU<AttributeNode>("s2")) .setResult(Int64ResultNode(0))) ) ) .addChild(Group() .setId(Int64ResultNode(33)) .addResult(SumAggregationResult() - .setExpression(AttributeNode("s1")) + .setExpression(MU<AttributeNode>("s1")) .setResult(Int64ResultNode(0))) ); EXPECT_TRUE(testPartialMerge(request.unchain().setRoot(incoming), request.unchain().setFirstLevel(0).setLastLevel(3).setRoot(cached), expected)); @@ -1575,11 +1580,8 @@ void Test::testPruneSimple() { { - Grouping request = Grouping() - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr"))) - .setFirstLevel(1) - .setLastLevel(1); + Grouping request; + request.addLevel(createGL(MU<AttributeNode>("attr"))).setFirstLevel(1).setLastLevel(1); Group a = Group() .addChild(Group().setId(StringResultNode("foo"))) @@ -1607,34 +1609,26 @@ Test::testTopN() ctx.result().add(0).add(1).add(2); ctx.add(IntAttrBuilder("foo").add(3).add(7).add(15).sp()); - Grouping request = Grouping() - .setRoot(Group().setId(NullResultNode()) - .addResult(CountAggregationResult() - .setExpression(ConstantNode(Int64ResultNode(0))) - ) - ); + Grouping request; + request.setRoot(Group().setId(NullResultNode()).addResult(CountAggregationResult().setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0))))); { - Group expect = Group().setId(NullResultNode()) - .addResult(CountAggregationResult().setCount(3) - .setExpression(ConstantNode(Int64ResultNode(0))) - ); + Group expect; + expect.setId(NullResultNode()).addResult(CountAggregationResult().setCount(3).setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))); EXPECT_TRUE(testAggregation(ctx, request, expect)); } { - Group expect = Group().setId(NullResultNode()) - .addResult(CountAggregationResult().setCount(1) - .setExpression(ConstantNode(Int64ResultNode(0))) - ); + Group expect; + expect.setId(NullResultNode()).addResult(CountAggregationResult().setCount(1).setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))); EXPECT_TRUE(testAggregation(ctx, request.setTopN(1), expect)); } { Grouping request2 = Grouping() .setRoot(Group().setId(NullResultNode())) - .addLevel(GroupingLevel() - .addAggregationResult(SumAggregationResult()) - .addOrderBy(AggregationRefNode(0), false)); + .addLevel(std::move(GroupingLevel() + .addAggregationResult(MU<SumAggregationResult>()) + .addOrderBy(MU<AggregationRefNode>(0), false))); EXPECT_TRUE(request2.needResort()); request2.setTopN(0); EXPECT_TRUE(request2.needResort()); @@ -1659,14 +1653,11 @@ Test::testCount() Grouping request = Grouping() .setRoot(Group().setId(NullResultNode()) .addResult(CountAggregationResult() - .setExpression(ConstantNode(Int64ResultNode(0))) + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0))) ) ); - Group expect = Group().setId(NullResultNode()) - .addResult(CountAggregationResult().setCount(3) - .setExpression(ConstantNode(Int64ResultNode(0))) - ); + Group expect = Group().setId(NullResultNode()).addResult(CountAggregationResult().setCount(3).setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))); EXPECT_TRUE(testAggregation(ctx, request, expect)); } @@ -1693,7 +1684,7 @@ Test::testFS4HitCollection() .setRoot(Group().setId(NullResultNode()) .addResult(HitsAggregationResult() .setMaxHits(3) - .setExpression(ConstantNode(Int64ResultNode(0)))) + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))) ); Group expect = Group().setId(NullResultNode()) @@ -1703,7 +1694,7 @@ Test::testFS4HitCollection() .addHit(FS4Hit(25, 25.0)) .addHit(FS4Hit(20, 20.0)) .sort() - .setExpression(ConstantNode(Int64ResultNode(0)))); + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))); EXPECT_TRUE(testAggregation(ctx, request, expect)); } @@ -1713,7 +1704,7 @@ Test::testFS4HitCollection() .setRoot(Group() .addResult(HitsAggregationResult() .setMaxHits(3) - .setExpression(ConstantNode(Int64ResultNode(0)))) + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))) ); Group expect = Group() @@ -1724,7 +1715,7 @@ Test::testFS4HitCollection() .addHit(FS4Hit(20, 20.0)) .addHit(FS4Hit(10, 10.0)) .sort() - .setExpression(ConstantNode(Int64ResultNode(0)))); + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))); Group a = Group() .setId(NullResultNode()) @@ -1734,7 +1725,7 @@ Test::testFS4HitCollection() .addHit(FS4Hit(1, 5.0)) .addHit(FS4Hit(2, 4.0)) .sort() - .setExpression(ConstantNode(Int64ResultNode(0)))); + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))); Group b = Group() .setId(NullResultNode()) @@ -1744,7 +1735,7 @@ Test::testFS4HitCollection() .addHit(FS4Hit(3, 7.0)) .addHit(FS4Hit(4, 6.0)) .sort() - .setExpression(ConstantNode(Int64ResultNode(0)))); + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))); Group c = Group() .setId(NullResultNode()) @@ -1754,7 +1745,7 @@ Test::testFS4HitCollection() .addHit(FS4Hit(5, 9.0)) .addHit(FS4Hit(6, 8.0)) .sort() - .setExpression(ConstantNode(Int64ResultNode(0)))); + .setExpression(MU<ConstantNode>(MU<Int64ResultNode>(0)))); EXPECT_TRUE(testMerge(request.unchain().setRoot(a), request.unchain().setRoot(b), request.unchain().setRoot(c), expect)); EXPECT_TRUE(testMerge(request.unchain().setRoot(b), request.unchain().setRoot(c), request.unchain().setRoot(a), expect)); @@ -1810,9 +1801,10 @@ Test::checkBucket(const NumericResultNode &width, const NumericResultNode &value } else { return EXPECT_TRUE(false); } + std::unique_ptr<FixedWidthBucketFunctionNode> fixed = MU<FixedWidthBucketFunctionNode>(MU<AttributeNode>("attr")); + fixed->setWidth(width); Grouping request = Grouping().setRoot(Group().setId(NullResultNode())) - .addLevel(GroupingLevel() - .setExpression(FixedWidthBucketFunctionNode(AttributeNode("attr")).setWidth(width))); + .addLevel(createGL(std::move(fixed))); Group expect = Group().setId(NullResultNode()).addChild(Group().setId(bucket)); return testAggregation(ctx, request, expect); } @@ -1929,22 +1921,11 @@ Test::testGroupingEngineFromRequest() ctx.add(IntAttrBuilder("attr2").add(12).add(12).sp()); ctx.add(IntAttrBuilder("attr3").add(13).add(13).sp()); ctx.result().add(0).add(1); - Grouping baseRequest = Grouping() - .setRoot(Group() - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr0")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr1")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr2")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr2")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr3")))) - .addLevel(GroupingLevel() - .setExpression(AttributeNode("attr3")) - .addResult(SumAggregationResult() - .setExpression(AttributeNode("attr1")))); + Grouping baseRequest; + baseRequest.setRoot(Group().addResult(SumAggregationResult().setExpression(MU<AttributeNode>("attr0")))) + .addLevel(createGL(MU<AttributeNode>("attr1"), MU<AttributeNode>("attr2"))) + .addLevel(createGL(MU<AttributeNode>("attr2"), MU<AttributeNode>("attr3"))) + .addLevel(createGL(MU<AttributeNode>("attr3"), MU<AttributeNode>("attr1"))); ctx.setup(baseRequest); GroupingEngine engine(baseRequest.setFirstLevel(0).setLastLevel(2)); EXPECT_EQUAL(4u, engine.getEngines().size()); diff --git a/searchlib/src/vespa/searchlib/aggregation/aggregation.cpp b/searchlib/src/vespa/searchlib/aggregation/aggregation.cpp index 5db2611f0d7..45224242e32 100644 --- a/searchlib/src/vespa/searchlib/aggregation/aggregation.cpp +++ b/searchlib/src/vespa/searchlib/aggregation/aggregation.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 "aggregation.h" #include "expressioncountaggregationresult.h" #include <vespa/searchlib/expression/resultvector.h> @@ -42,6 +43,9 @@ AggregationResult::AggregationResult() : _tag(-1) { } +AggregationResult::AggregationResult(const AggregationResult &) = default; +AggregationResult & AggregationResult::operator = (const AggregationResult &) = default; + AggregationResult::~AggregationResult() { } void @@ -75,9 +79,9 @@ void AggregationResult::Configure::execute(vespalib::Identifiable &obj) } AggregationResult & -AggregationResult::setExpression(const ExpressionNode::CP &expr) +AggregationResult::setExpression(ExpressionNode::UP expr) { - _expressionTree.reset(new ExpressionTree(expr)); + _expressionTree.reset(new ExpressionTree(std::move(expr))); prepare(&_expressionTree->getResult(), false); return *this; } @@ -99,6 +103,14 @@ void SumAggregationResult::onPrepare(const ResultNode & result, bool useForInit) } } +MinAggregationResult::MinAggregationResult() : AggregationResult() { } +MinAggregationResult::MinAggregationResult(const ResultNode::CP &result) + : AggregationResult() +{ + setResult(result); +} +MinAggregationResult::~MinAggregationResult() { } + void MinAggregationResult::onPrepare(const ResultNode & result, bool useForInit) { if (isReady(_min.get(), result)) { @@ -112,6 +124,13 @@ void MinAggregationResult::onPrepare(const ResultNode & result, bool useForInit) } } +MaxAggregationResult::MaxAggregationResult() : AggregationResult(), _max() { } +MaxAggregationResult::MaxAggregationResult(const SingleResultNode & max) + : AggregationResult(), + _max(max) +{ } +MaxAggregationResult::~MaxAggregationResult() { } + void MaxAggregationResult::onPrepare(const ResultNode & result, bool useForInit) { if (isReady(_max.get(), result)) { diff --git a/searchlib/src/vespa/searchlib/aggregation/aggregationresult.h b/searchlib/src/vespa/searchlib/aggregation/aggregationresult.h index 87689ae81d6..1665da12d31 100644 --- a/searchlib/src/vespa/searchlib/aggregation/aggregationresult.h +++ b/searchlib/src/vespa/searchlib/aggregation/aggregationresult.h @@ -33,6 +33,10 @@ public: using ResultNode = expression::ResultNode; DECLARE_NBO_SERIALIZE; DECLARE_ABSTRACT_AGGREGATIONRESULT(AggregationResult); + AggregationResult(const AggregationResult &); + AggregationResult & operator = (const AggregationResult &); + AggregationResult(AggregationResult &&) = default; + AggregationResult & operator = (AggregationResult &&) = default; ~AggregationResult(); class Configure : public vespalib::ObjectOperation, public vespalib::ObjectPredicate { @@ -49,7 +53,7 @@ public: virtual void postMerge() {} void aggregate(const document::Document & doc, HitRank rank); void aggregate(DocId docId, HitRank rank); - AggregationResult &setExpression(const ExpressionNode::CP &expr); + AggregationResult &setExpression(ExpressionNode::UP expr); AggregationResult &setResult(const ResultNode::CP &result) { prepare(result.get(), true); return *this; diff --git a/searchlib/src/vespa/searchlib/aggregation/countaggregationresult.h b/searchlib/src/vespa/searchlib/aggregation/countaggregationresult.h index 06321c99b84..27d950dbecf 100644 --- a/searchlib/src/vespa/searchlib/aggregation/countaggregationresult.h +++ b/searchlib/src/vespa/searchlib/aggregation/countaggregationresult.h @@ -4,7 +4,6 @@ #include "aggregationresult.h" #include <vespa/searchlib/expression/integerresultnode.h> - namespace search { namespace aggregation { @@ -12,16 +11,16 @@ class CountAggregationResult : public AggregationResult { public: DECLARE_AGGREGATIONRESULT(CountAggregationResult); - CountAggregationResult() : AggregationResult(), _count(0) { } - virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; + CountAggregationResult(uint64_t count=0) : AggregationResult(), _count(count) { } + void visitMembers(vespalib::ObjectVisitor &visitor) const override; uint64_t getCount() const { return _count.get(); } CountAggregationResult &setCount(uint64_t c) { _count = c; return *this; } private: - virtual const ResultNode & onGetRank() const { return _count; } - virtual void onPrepare(const ResultNode & result, bool useForInit); + const ResultNode & onGetRank() const override { return _count; } + void onPrepare(const ResultNode & result, bool useForInit) override; expression::Int64ResultNode _count; }; diff --git a/searchlib/src/vespa/searchlib/aggregation/group.cpp b/searchlib/src/vespa/searchlib/aggregation/group.cpp index d256035db4b..cc8e362b05b 100644 --- a/searchlib/src/vespa/searchlib/aggregation/group.cpp +++ b/searchlib/src/vespa/searchlib/aggregation/group.cpp @@ -33,11 +33,11 @@ struct SortByGroupRank { } }; -} - -IMPLEMENT_IDENTIFIABLE_NS2(search, aggregation, Group, vespalib::Identifiable); +void reset(Group * & v) { v = NULL; } +void destruct(Group * v) { if (v) { delete v; } } -void Group::destruct(GroupList & l, size_t m) +void +destruct(Group::GroupList & l, size_t m) { for (size_t i(0); i < m; i++) { destruct(l[i]); @@ -46,13 +46,14 @@ void Group::destruct(GroupList & l, size_t m) l = NULL; } -int Group::cmpRank(const Group &rhs) const +} + +IMPLEMENT_IDENTIFIABLE_NS2(search, aggregation, Group, vespalib::Identifiable); + +int +Group::cmpRank(const Group &rhs) const { - int diff(0); - for(size_t i(0), m(getOrderBySize()); (diff == 0) && (i < m); i++) { - uint32_t index = std::abs(getOrderBy(i)) - 1; - diff = expr(index).getResult().cmp(rhs.expr(index).getResult())*getOrderBy(i); - } + int diff(_aggr.cmp(rhs._aggr)); return diff ? diff : ((_rank > rhs._rank) @@ -60,66 +61,233 @@ int Group::cmpRank(const Group &rhs) const : ((_rank < rhs._rank) ? 1 : 0)); } -Group & Group::addOrderBy(const ExpressionNode::CP & orderBy, bool ascending) +void +Group::selectMembers(const vespalib::ObjectPredicate &predicate, vespalib::ObjectOperation &operation) { + if (_id.get()) { + _id->select(predicate, operation); + } + _aggr.select(predicate, operation); +} + +template <typename Doc> +void +Group::aggregate(const Grouping & grouping, uint32_t currentLevel, const Doc & doc, HitRank rank) { - assert(getOrderBySize() < sizeof(_orderBy)*2-1); - assert(getExprSize() < 15); - addExpressionResult(orderBy); - setOrderBy(getOrderBySize(), (ascending ? getExprSize() : -getExprSize())); - setOrderBySize(getOrderBySize() + 1); - setupAggregationReferences(); + if (currentLevel >= grouping.getFirstLevel()) { + collect(doc, rank); + } + if (currentLevel < grouping.getLevels().size()) { + groupNext(grouping.getLevels()[currentLevel], doc, rank); + } +} + +template <typename Doc> +void +Group::groupNext(const GroupingLevel & level, const Doc & doc, HitRank rank) +{ + const ExpressionTree &selector = level.getExpression(); + if (!selector.execute(doc, rank)) { + throw std::runtime_error("Does not know how to handle failed select statements"); + } + const ResultNode &selectResult = selector.getResult(); + level.group(*this, selectResult, doc, rank); +} + +Group * +Group::Value::groupSingle(const ResultNode & selectResult, HitRank rank, const GroupingLevel & level) +{ + if (_childInfo._childMap == NULL) { + assert(getChildrenSize() == 0); + _childInfo._childMap = new GroupHash(1, GroupHasher(&_children), GroupEqual(&_children)); + } + GroupHash & childMap = *_childInfo._childMap; + Group * group(NULL); + GroupHash::iterator found = childMap.find<ResultNode, GroupResult, ResultHash, ResultEqual>(selectResult, GroupResult(&_children)); + if (found == childMap.end()) { // group not present in child map + if (level.allowMoreGroups(childMap.size())) { + group = new Group(level.getGroupPrototype()); + group->setId(selectResult); + group->setRank(rank); + addChild(group); + childMap.insert(getChildrenSize() - 1); + } + } else { + group = _children[(*found)]; + if ( ! level.isFrozen()) { + group->updateRank(rank); + } + } + return group; +} + +void +Group::merge(const GroupingLevelList &levels, uint32_t firstLevel, uint32_t currentLevel, Group &b) { + bool frozen = (currentLevel < firstLevel); // is this level frozen ? + _rank = std::max(_rank, b._rank); + + if (!frozen) { // should we merge collectors for this level ? + _aggr.mergeCollectors(b._aggr); + } + _aggr.merge(levels, firstLevel, currentLevel, b._aggr); +} + +void +Group::prune(const Group & b, uint32_t lastLevel, uint32_t currentLevel) { + if (currentLevel >= lastLevel) { + return; + } + _aggr.prune(b._aggr, lastLevel, currentLevel); +} + +void +Group::mergePartial(const GroupingLevelList &levels, uint32_t firstLevel, uint32_t lastLevel, + uint32_t currentLevel, const Group & b) { + bool frozen = (currentLevel < firstLevel); + + if (!frozen) { + _aggr.mergeCollectors(b._aggr); + _aggr.execute(); + + // At this level, we must create a copy of the other nodes children. + if (currentLevel >= lastLevel) { + _aggr.mergeLevel(levels[currentLevel].getGroupPrototype(), b._aggr); + return; + } + } + _aggr.mergePartial(levels, firstLevel, lastLevel, currentLevel, b._aggr); +} + +Group & +Group::setRank(RawRank r) +{ + _rank = std::isnan(r) ? -HUGE_VAL : r; return *this; } -Group & Group::addAggregationResult(const ExpressionNode::CP & aggr) +Group & +Group::updateRank(RawRank r) +{ + return setRank(std::max(_rank, r)); +} + +Serializer & +Group::onSerialize(Serializer & os) const { + _aggr.assertIdOrder(); + os << _id << _rank; + _aggr.serialize(os); + return os; +} + +Deserializer & +Group::onDeserialize(Deserializer & is) { + is >> _id >> _rank; + _aggr.deserialize(is); + _aggr.assertIdOrder(); + return is; +} + +void +Group::visitMembers(vespalib::ObjectVisitor &visitor) const { + visit(visitor, "id", _id); + visit(visitor, "rank", _rank); + _aggr.visitMembers(visitor); +} + +Group::Group() : + _id(), + _rank(0), + _aggr() +{ } + +Group::Group(const Group & rhs) = default; +Group & Group::operator = (const Group & rhs) = default; + +Group::~Group() { } + +Group & +Group::partialCopy(const Group & rhs) { + setId(*rhs._id); + _rank = rhs._rank; + _aggr.partialCopy(rhs._aggr); + return *this; +} + +template void Group::aggregate(const Grouping & grouping, uint32_t currentLevel, const DocId & doc, HitRank rank); +template void Group::aggregate(const Grouping & grouping, uint32_t currentLevel, const document::Document & doc, HitRank rank); + +int +Group::Value::cmp(const Value & rhs) const { + int diff(0); + for (size_t i(0), m(getOrderBySize()); (diff == 0) && (i < m); i++) { + uint32_t index = std::abs(getOrderBy(i)) - 1; + diff = expr(index).getResult().cmp(rhs.expr(index).getResult()) * getOrderBy(i); + } + return diff; +} + +void +Group::Value::addExpressionResult(ExpressionNode::UP expressionNode) +{ + uint32_t newSize = getAggrSize() + getExprSize() + 1; + ExpressionVector n = new ExpressionNode::CP[newSize]; + for (uint32_t i(0); i < (newSize - 1); i++) { + n[i] = std::move(_aggregationResults[i]); + } + n[newSize - 1].reset(expressionNode.release()); + delete [] _aggregationResults; + _aggregationResults = n; + setExprSize(getExprSize()+1); + setupAggregationReferences(); +} + +void +Group::Value::addAggregationResult(ExpressionNode::UP aggr) { assert(getAggrSize() < 15); size_t newSize = getAggrSize() + 1 + getExprSize(); ExpressionVector n = new ExpressionNode::CP[newSize]; for (size_t i(0), m(getAggrSize()); i < m; i++) { - n[i] = _aggregationResults[i]; + n[i] = std::move(_aggregationResults[i]); } - n[getAggrSize()] = aggr; + n[getAggrSize()].reset(aggr.release()); // Copy expressions after aggregationresults for (size_t i(getAggrSize()); i < newSize - 1; i++) { - n[i + 1] = _aggregationResults[i]; + n[i + 1] = std::move(_aggregationResults[i]); } delete [] _aggregationResults; _aggregationResults = n; setAggrSize(getAggrSize() + 1); - return *this; } -Group & Group::addExpressionResult(const ExpressionNode::CP & expressionNode) +template <typename Doc> +void Group::Value::collect(const Doc & doc, HitRank rank) { - uint32_t newSize = getAggrSize() + getExprSize() + 1; - ExpressionVector n = new ExpressionNode::CP[newSize]; - for (uint32_t i(0); i < (newSize - 1); i++) { - n[i] = _aggregationResults[i]; + for(size_t i(0), m(getAggrSize()); i < m; i++) { + getAggr(i)->aggregate(doc, rank); } - n[newSize - 1] = expressionNode; - delete [] _aggregationResults; - _aggregationResults = n; - setExprSize(getExprSize()+1); - return *this; } -void Group::setupAggregationReferences() +void +Group::Value::addResult(ExpressionNode::UP aggr) { - AggregationRefNode::Configure exprRefSetup(_aggregationResults); - select(exprRefSetup, exprRefSetup); + assert(getExprSize() < 15); + addAggregationResult(std::move(aggr)); + addExpressionResult(ExpressionNode::UP(new AggregationRefNode(getAggrSize() - 1))); + setupAggregationReferences(); } -Group & Group::addResult(const ExpressionNode::CP & aggr) +void +Group::Value::addOrderBy(ExpressionNode::UP orderBy, bool ascending) { + assert(getOrderBySize() < sizeof(_orderBy)*2-1); assert(getExprSize() < 15); - addAggregationResult(aggr); - addExpressionResult(ExpressionNode::CP(new AggregationRefNode(getAggrSize() - 1))); - setupAggregationReferences(); - return *this; + addExpressionResult(std::move(orderBy)); + setOrderBy(getOrderBySize(), (ascending ? getExprSize() : -getExprSize())); + setOrderBySize(getOrderBySize() + 1); } -void Group::addChild(Group * child) +void +Group::Value::addChild(Group * child) { const size_t sz(getChildrenSize()); assert(sz < 0xffffff); @@ -138,12 +306,7 @@ void Group::addChild(Group * child) } void -Group::selectMembers(const vespalib::ObjectPredicate &predicate, - vespalib::ObjectOperation &operation) -{ - if (_id.get()) { - _id->select(predicate, operation); - } +Group::Value::select(const vespalib::ObjectPredicate &predicate, vespalib::ObjectOperation &operation) { uint32_t totalSize = getAggrSize() + getExprSize(); for (uint32_t i(0); i < totalSize; i++) { _aggregationResults[i]->select(predicate, operation); @@ -151,7 +314,7 @@ Group::selectMembers(const vespalib::ObjectPredicate &predicate, } void -Group::preAggregate() +Group::Value::preAggregate() { assert(_childInfo._childMap == NULL); _childInfo._childMap = new GroupHash(getChildrenSize()*2, GroupHasher(&_children), GroupEqual(&_children)); @@ -162,66 +325,8 @@ Group::preAggregate() } } -template <typename Doc> -void Group::collect(const Doc & doc, HitRank rank) -{ - for(size_t i(0), m(getAggrSize()); i < m; i++) { - getAggr(i)->aggregate(doc, rank); - } -} - -template <typename Doc> -void -Group::aggregate(const Grouping & grouping, uint32_t currentLevel, const Doc & doc, HitRank rank) -{ - if (currentLevel >= grouping.getFirstLevel()) { - collect(doc, rank); - } - if (currentLevel < grouping.getLevels().size()) { - groupNext(grouping.getLevels()[currentLevel], doc, rank); - } -} - -template <typename Doc> -void -Group::groupNext(const GroupingLevel & level, const Doc & doc, HitRank rank) -{ - const ExpressionTree &selector = level.getExpression(); - if (!selector.execute(doc, rank)) { - throw std::runtime_error("Does not know how to handle failed select statements"); - } - const ResultNode &selectResult = selector.getResult(); - level.group(*this, selectResult, doc, rank); -} - -Group * Group::groupSingle(const ResultNode & selectResult, HitRank rank, const GroupingLevel & level) -{ - if (_childInfo._childMap == NULL) { - assert(getChildrenSize() == 0); - _childInfo._childMap = new GroupHash(1, GroupHasher(&_children), GroupEqual(&_children)); - } - GroupHash & childMap = *_childInfo._childMap; - Group * group(NULL); - GroupHash::iterator found = childMap.find<ResultNode, GroupResult, ResultHash, ResultEqual>(selectResult, GroupResult(&_children)); - if (found == childMap.end()) { // group not present in child map - if (level.allowMoreGroups(childMap.size())) { - group = new Group(level.getGroupPrototype()); - group->setId(selectResult); - group->setRank(rank); - addChild(group); - childMap.insert(getChildrenSize() - 1); - } - } else { - group = _children[(*found)]; - if ( ! level.isFrozen()) { - group->updateRank(rank); - } - } - return group; -} - void -Group::postAggregate() +Group::Value::postAggregate() { delete _childInfo._childMap; _childInfo._childMap = NULL; @@ -231,7 +336,7 @@ Group::postAggregate() } void -Group::executeOrderBy() +Group::Value::executeOrderBy() { for (size_t i(0), m(getExprSize()); i < m; i++) { ExpressionNode & e(expr(i)); @@ -240,7 +345,8 @@ Group::executeOrderBy() } } -void Group::sortById() +void +Group::Value::sortById() { std::sort(_children, _children + getChildrenSize(), SortByGroupId()); for (ChildP *it(_children), *mt(_children + getChildrenSize()); it != mt; ++it) { @@ -249,17 +355,32 @@ void Group::sortById() } void -Group::merge(const std::vector<GroupingLevel> &levels, - uint32_t firstLevel, uint32_t currentLevel, Group &b) -{ - bool frozen = (currentLevel < firstLevel); // is this level frozen ? - _rank = std::max(_rank, b._rank); +Group::Value::mergeCollectors(const Value &rhs) { + for(size_t i(0), m(getAggrSize()); i < m; i++) { + getAggr(i)->merge(rhs.getAggr(i)); + } +} - if (!frozen) { // should we merge collectors for this level ? - for(size_t i(0), m(getAggrSize()); i < m; i++) { - getAggr(i)->merge(*b.getAggr(i)); - } +void +Group::Value::execute() { + for (size_t i(0), m(getExprSize()); i < m; i++) { + expr(i).execute(); } +} + +void +Group::Value::mergeLevel(const Group & protoType, const Value & b) { + for (ChildP *it(b._children), *mt(b._children + b.getChildrenSize()); it != mt; ++it) { + ChildP g(new Group(protoType)); + g->partialCopy(**it); + addChild(g); + } +} + +void +Group::Value::merge(const std::vector<GroupingLevel> &levels, + uint32_t firstLevel, uint32_t currentLevel, const Value &b) +{ GroupList z = new ChildP[getChildrenSize() + b.getChildrenSize()]; size_t kept(0); ChildP * px = _children; @@ -299,12 +420,7 @@ Group::merge(const std::vector<GroupingLevel> &levels, } void -Group::prune(const Group & b, uint32_t lastLevel, uint32_t currentLevel) -{ - if (currentLevel >= lastLevel) { - return; - } - +Group::Value::prune(const Value & b, uint32_t lastLevel, uint32_t currentLevel) { GroupList keep = new ChildP[b.getChildrenSize()]; size_t kept(0); ChildP * px = _children; @@ -332,34 +448,9 @@ Group::prune(const Group & b, uint32_t lastLevel, uint32_t currentLevel) } void -Group::mergePartial(const std::vector<GroupingLevel> &levels, - uint32_t firstLevel, - uint32_t lastLevel, - uint32_t currentLevel, - const Group & b) +Group::Value::mergePartial(const GroupingLevelList &levels, uint32_t firstLevel, uint32_t lastLevel, + uint32_t currentLevel, const Value & b) { - bool frozen = (currentLevel < firstLevel); - - if (!frozen) { - for(size_t i(0), m(getAggrSize()); i < m; i++) { - getAggr(i)->merge(b.getAggr(i)); - } - for(size_t i(0), m(getExprSize()); i < m; i++) { - expr(i).execute(); - } - - - // At this level, we must create a copy of the other nodes children. - if (currentLevel >= lastLevel) { - for (ChildP *it(b._children), *mt(b._children + b.getChildrenSize()); it != mt; ++it) { - ChildP g(new Group(levels[currentLevel].getGroupPrototype())); - g->partialCopy(**it); - addChild(g); - } - return; - } - } - ChildP * px = _children; ChildP * ex = _children + getChildrenSize(); const ChildP * py = b._children; @@ -379,9 +470,7 @@ Group::mergePartial(const std::vector<GroupingLevel> &levels, } void -Group::postMerge(const std::vector<GroupingLevel> &levels, - uint32_t firstLevel, - uint32_t currentLevel) +Group::Value::postMerge(const std::vector<GroupingLevel> &levels, uint32_t firstLevel, uint32_t currentLevel) { bool frozen = (currentLevel < firstLevel); // is this level frozen ? @@ -412,18 +501,8 @@ Group::postMerge(const std::vector<GroupingLevel> &levels, } } -Group & Group::setRank(RawRank r) -{ - _rank = std::isnan(r) ? -HUGE_VAL : r; - return *this; -} - -Group & Group::updateRank(RawRank r) -{ - return setRank(std::max(_rank, r)); -} - -bool Group::needResort() const +bool +Group::Value::needResort() const { bool resort(needFullRank()); for (const ChildP *it(_children), *mt(_children + getChildrenSize()); !resort && (it != mt); ++it) { @@ -432,14 +511,18 @@ bool Group::needResort() const return resort; } -Serializer & Group::onSerialize(Serializer & os) const -{ +void +Group::Value::assertIdOrder() const { if (getChildrenSize() > 1) { for (size_t i(1), m(getChildrenSize()); i < m; i++) { assert(_children[i]->cmpId(*_children[i-1]) > 0); } } - os << _id << _rank; +} + +Serializer & +Group::Value::serialize(Serializer & os) const { + os << uint32_t(getOrderBySize()); for (size_t i(0), m(getOrderBySize()); i < m; i++) { os << int32_t(getOrderBy(i)); @@ -459,10 +542,10 @@ Serializer & Group::onSerialize(Serializer & os) const return os << _tag; } -Deserializer & Group::onDeserialize(Deserializer & is) -{ +Deserializer & +Group::Value::deserialize(Deserializer & is) { uint32_t count(0); - is >> _id >> _rank >> count; + is >> count; assert(count < sizeof(_orderBy)*2); setOrderBySize(count); for(uint32_t i(0); i < count; i++) { @@ -492,13 +575,13 @@ Deserializer & Group::onDeserialize(Deserializer & is) _aggregationResults[i] = tmpAggregationResults[i]; } delete [] tmpAggregationResults; + setupAggregationReferences(); assert(exprSize < 16); setExprSize(exprSize); for (uint32_t i(aggrSize); i < aggrSize + exprSize; i++) { is >> _aggregationResults[i]; } - setupAggregationReferences(); is >> count; destruct(_children, getAllChildrenSize()); _childInfo._allChildren = 0; @@ -510,19 +593,11 @@ Deserializer & Group::onDeserialize(Deserializer & is) _children[i] = group; } is >> _tag; - if (getChildrenSize() > 1) { - for (size_t i(1), m(getChildrenSize()); i < m; i++) { - assert(_children[i]->cmpId(*_children[i-1]) > 0); - } - } return is; } void -Group::visitMembers(vespalib::ObjectVisitor &visitor) const -{ - visit(visitor, "id", _id); - visit(visitor, "rank", _rank); +Group::Value::visitMembers(vespalib::ObjectVisitor &visitor) const { // visit(visitor, "orderBy", _orderBy); visitor.openStruct("orderBy", "[]"); visit(visitor, "size", getOrderBySize()); @@ -554,30 +629,25 @@ Group::visitMembers(vespalib::ObjectVisitor &visitor) const visit(visitor, "tag", _tag); } -Group::Group() : - _id(), - _rank(0), +Group::Value::Value() : _packedLength(0), _tag(-1), _aggregationResults(NULL), - _orderBy(), _children(NULL), - _childInfo() + _childInfo(), + _orderBy() { memset(_orderBy, 0, sizeof(_orderBy)); _childInfo._childMap = NULL; } -Group::Group(const Group & rhs) : - Identifiable(rhs), - _id(rhs._id), - _rank(rhs._rank), +Group::Value::Value(const Value & rhs) : _packedLength(rhs._packedLength), _tag(rhs._tag), _aggregationResults(NULL), - _orderBy(), _children(NULL), - _childInfo() + _childInfo(), + _orderBy() { _childInfo._childMap = NULL; memcpy(_orderBy, rhs._orderBy, sizeof(_orderBy)); @@ -599,7 +669,46 @@ Group::Group(const Group & rhs) : } } -Group::~Group() +Group::Value::Value(Value && rhs) noexcept : + _packedLength(std::move(rhs._packedLength)), + _tag(std::move(rhs._tag)), + _aggregationResults(std::move(rhs._aggregationResults)), + _children(std::move(rhs._children)), + _childInfo(std::move(rhs._childInfo)), + _orderBy() +{ + memcpy(_orderBy, rhs._orderBy, sizeof(_orderBy)); + + rhs.setChildrenSize(0); + rhs._aggregationResults = nullptr; + rhs._childInfo._allChildren = 0; + rhs._children = nullptr; +} + +Group::Value & +Group::Value::operator =(Value && rhs) noexcept { + _packedLength = std::move(rhs._packedLength); + _tag = std::move(rhs._tag); + _aggregationResults = std::move(rhs._aggregationResults); + _children = std::move(rhs._children); + _childInfo = std::move(rhs._childInfo); + memcpy(_orderBy, rhs._orderBy, sizeof(_orderBy)); + + rhs.setChildrenSize(0); + rhs._aggregationResults = nullptr; + rhs._childInfo._allChildren = 0; + rhs._children = nullptr; + return *this; +} + +Group::Value & +Group::Value::operator =(const Value & rhs) { + Value tmp(rhs); + tmp.swap(*this); + return *this; +} + +Group::Value::~Value() { destruct(_children, getAllChildrenSize()); setChildrenSize(0); @@ -607,20 +716,25 @@ Group::~Group() delete [] _aggregationResults; } -Group & Group::operator =(const Group & rhs) +void +Group::Value::swap(Value & rhs) { - if (&rhs != this) { - Group g(rhs); - swap(g); + std::swap(_aggregationResults, rhs._aggregationResults); + std::swap(_children, rhs._children); + std::swap(_childInfo._childMap, rhs._childInfo._childMap); + { + int8_t tmp[sizeof(_orderBy)]; + memcpy(tmp, _orderBy, sizeof(_orderBy)); + memcpy(_orderBy, rhs._orderBy, sizeof(_orderBy)); + memcpy(rhs._orderBy, tmp, sizeof(_orderBy)); } - return *this; + std::swap(_tag, rhs._tag); + std::swap(_packedLength, rhs._packedLength); } -Group & -Group::partialCopy(const Group & rhs) -{ - setId(*rhs._id); - _rank = rhs._rank; + +void +Group::Value::partialCopy(const Value & rhs) { uint32_t totalAggrSize = getAggrSize() + getExprSize(); for(size_t i(0), m(totalAggrSize); i < m; i++) { _aggregationResults[i] = rhs._aggregationResults[i]; @@ -633,29 +747,15 @@ Group::partialCopy(const Group & rhs) setExprSize(rhs.getExprSize()); setupAggregationReferences(); memcpy(_orderBy, rhs._orderBy, sizeof(_orderBy)); - return *this; } -void Group::swap(Group & rhs) +void +Group::Value::setupAggregationReferences() { - _id.swap(rhs._id); - std::swap(_rank, rhs._rank); - std::swap(_aggregationResults, rhs._aggregationResults); - std::swap(_children, rhs._children); - std::swap(_childInfo._childMap, rhs._childInfo._childMap); - { - int8_t tmp[sizeof(_orderBy)]; - memcpy(tmp, _orderBy, sizeof(_orderBy)); - memcpy(_orderBy, rhs._orderBy, sizeof(_orderBy)); - memcpy(rhs._orderBy, tmp, sizeof(_orderBy)); - } - std::swap(_tag, rhs._tag); - std::swap(_packedLength, rhs._packedLength); + AggregationRefNode::Configure exprRefSetup(_aggregationResults); + select(exprRefSetup, exprRefSetup); } -template void Group::aggregate(const Grouping & grouping, uint32_t currentLevel, const DocId & doc, HitRank rank); -template void Group::aggregate(const Grouping & grouping, uint32_t currentLevel, const document::Document & doc, HitRank rank); - } } diff --git a/searchlib/src/vespa/searchlib/aggregation/group.h b/searchlib/src/vespa/searchlib/aggregation/group.h index c7fe98fb487..87fd1794150 100644 --- a/searchlib/src/vespa/searchlib/aggregation/group.h +++ b/searchlib/src/vespa/searchlib/aggregation/group.h @@ -65,54 +65,111 @@ public: size_t operator() (const ResultNode & arg) const { return arg.hash(); } }; - typedef ExpressionNode::CP * ExpressionVector; - typedef vespalib::hash_set<uint32_t, GroupHasher, GroupEqual > GroupHash; typedef std::vector<GroupingLevel> GroupingLevelList; private: + + class Value { + public: + Value(); + Value(const Value & rhs); + Value & operator =(const Value & rhs); + Value(Value &&) noexcept; + Value & operator = (Value &&) noexcept; + ~Value() noexcept; + void swap(Value & rhs); + + VESPA_DLL_LOCAL int cmp(const Value & rhs) const; + void addExpressionResult(ExpressionNode::UP expressionNode); + void addAggregationResult(ExpressionNode::UP aggr); + void addResult(ExpressionNode::UP aggr); + void setupAggregationReferences(); + void addOrderBy(ExpressionNode::UP orderBy, bool ascending); + void select(const vespalib::ObjectPredicate &predicate, vespalib::ObjectOperation &operation); + void preAggregate(); + void postAggregate(); + void executeOrderBy(); + void sortById(); + void mergeCollectors(const Value & rhs); + void execute(); + bool needResort() const; + void assertIdOrder() const; + void visitMembers(vespalib::ObjectVisitor &visitor) const; + vespalib::Serializer & serialize(vespalib::Serializer & os) const; + vespalib::Deserializer & deserialize(vespalib::Deserializer & is); + void mergeLevel(const Group & protoType, const Value & b); + void mergePartial(const GroupingLevelList &levels, uint32_t firstLevel, uint32_t lastLevel, + uint32_t currentLevel, const Value & b); + void merge(const GroupingLevelList & levels, uint32_t firstLevel, uint32_t currentLevel, const Value & rhs); + void prune(const Value & b, uint32_t lastLevel, uint32_t currentLevel); + void postMerge(const std::vector<GroupingLevel> &levels, uint32_t firstLevel, uint32_t currentLevel); + void partialCopy(const Value & rhs); + VESPA_DLL_LOCAL Group * groupSingle(const ResultNode & selectResult, HitRank rank, const GroupingLevel & level); + + GroupList groups() const { return _children; } + void addChild(Group * child); + uint32_t getAggrSize() const { return _packedLength & 0x0f; } + uint32_t getOrderBySize() const { return (_packedLength >> 6) & 0x03; } + uint32_t getChildrenSize() const { return (_packedLength >> 8); } + uint32_t getExpr(uint32_t i) const { return getAggrSize() + i; } + int32_t getOrderBy(uint32_t i) const { + int32_t v((_orderBy[i/2] >> (4*(i%2))) & 0x0f); + return (v & 0x8) ? -(v&0x7) : v; + } + + const AggregationResult & getAggregationResult(size_t i) const { return static_cast<const AggregationResult &>(*_aggregationResults[i]); } + AggregationResult & getAggregationResult(size_t i) { return static_cast<AggregationResult &>(*_aggregationResults[i]); } + uint32_t getExprSize() const { return (_packedLength >> 4) & 0x03; } + const Group & getChild(size_t i) const { return *_children[i]; } + + template <typename Doc> + void collect(const Doc & docId, HitRank rank); + private: + + using ExpressionVector = ExpressionNode::CP *; + using GroupHash = vespalib::hash_set<uint32_t, GroupHasher, GroupEqual >; + void setAggrSize(uint32_t v) { _packedLength = (_packedLength & ~0x0f) | v; } + void setExprSize(uint32_t v) { _packedLength = (_packedLength & ~0x30) | (v << 4); } + void setOrderBySize(uint32_t v) { _packedLength = (_packedLength & ~0xc0) | (v << 6); } + void setChildrenSize(uint32_t v) { _packedLength = (_packedLength & ~0xffffff00) | (v << 8); } + AggregationResult * getAggr(size_t i) { return static_cast<AggregationResult *>(_aggregationResults[i].get()); } + const AggregationResult & getAggr(size_t i) const { return static_cast<const AggregationResult &>(*_aggregationResults[i]); } + const ExpressionNode::CP & getAggrCP(size_t i) const { return _aggregationResults[i]; } + const ExpressionNode::CP & getExprCP(size_t i) const { return _aggregationResults[getExpr(i)]; } + ExpressionNode & expr(size_t i) { return *_aggregationResults[getExpr(i)]; } + const ExpressionNode & expr(size_t i) const { return *_aggregationResults[getExpr(i)]; } + size_t getAllChildrenSize() const { return std::max(static_cast<size_t>(getChildrenSize()), _childInfo._allChildren); } + void setOrderBy(uint32_t i, int32_t v) { + if (v < 0) { + v = -v; + v = v | 0x8; + } + _orderBy[i/2] = (_orderBy[i/2] & (0xf0 >> (4*(i%2)))) | (v << (4*(i%2))); + } + bool needFullRank() const { return getOrderBySize() != 0; } + + uint32_t _packedLength; // Length of the 3 vectors below + uint32_t _tag; // Opaque tag used to identify the group by the client. + + // The collectors and expressions stored by this group. Currently, both aggregation results and expressions used by orderby() are stored in this + // array to save 8 bytes in the Group size. This makes it important to use the getAggr() and expr() methods for accessing elements, + // as they will correctly offset the index to the correct place in the array. + ExpressionVector _aggregationResults; + + ChildP *_children; // the sub-groups of this group. Great care must be taken to ensure proper destruct. + union ChildInfo { + GroupHash *_childMap; // child map used during aggregation + size_t _allChildren; // Keep real number of children. + } _childInfo; + uint8_t _orderBy[2]; // How this group is ranked, negative means reverse rank. + }; + ResultNode::CP _id; // the label of this group, separating it from other groups RawRank _rank; // The default rank taken from the highest hit relevance. - uint32_t _packedLength; // Length of the 3 vectors below - uint32_t _tag; // Opaque tag used to identify the group by the client. - - // The collectors and expressions stored by this group. Currently, both aggregation results and expressions used by orderby() are stored in this - // array to save 8 bytes in the Group size. This makes it important to use the getAggr() and expr() methods for accessing elements, - // as they will correctly offset the index to the correct place in the array. - ExpressionVector _aggregationResults; - - uint8_t _orderBy[2]; // How this group is ranked, negative means reverse rank. - ChildP *_children; // the sub-groups of this group. Great care must be taken to ensure proper destruct. - union ChildInfo { - GroupHash *_childMap; // child map used during aggregation - size_t _allChildren; // Keep real number of children. - } _childInfo; - - bool needFullRank() const { return getOrderBySize() != 0; } + Value _aggr; + Group & partialCopy(const Group & rhs); - void setOrderBy(uint32_t i, int32_t v) { - if (v < 0) { - v = -v; - v = v | 0x8; - } - _orderBy[i/2] = (_orderBy[i/2] & (0xf0 >> (4*(i%2)))) | (v << (4*(i%2))); - } - uint32_t getExprSize() const { return (_packedLength >> 4) & 0x03; } - void setAggrSize(uint32_t v) { _packedLength = (_packedLength & ~0x0f) | v; } - void setExprSize(uint32_t v) { _packedLength = (_packedLength & ~0x30) | (v << 4); } - void setOrderBySize(uint32_t v) { _packedLength = (_packedLength & ~0xc0) | (v << 6); } - void setChildrenSize(uint32_t v) { _packedLength = (_packedLength & ~0xffffff00) | (v << 8); } - AggregationResult * getAggr(size_t i) { return static_cast<AggregationResult *>(_aggregationResults[i].get()); } - const AggregationResult & getAggr(size_t i) const { return static_cast<const AggregationResult &>(*_aggregationResults[i]); } - const ExpressionNode::CP & getAggrCP(size_t i) const { return _aggregationResults[i]; } - const ExpressionNode::CP & getExprCP(size_t i) const { return _aggregationResults[getExpr(i)]; } - ExpressionNode & expr(size_t i) { return *_aggregationResults[getExpr(i)]; } - const ExpressionNode & expr(size_t i) const { return *_aggregationResults[getExpr(i)]; } - static void reset(Group * & v) { v = NULL; } - static void destruct(Group * v) { if (v) { delete v; } } - static void destruct(GroupList & l, size_t sz); - void addChild(Group * child); - void setupAggregationReferences(); - size_t getAllChildrenSize() const { return std::max(static_cast<size_t>(getChildrenSize()), _childInfo._allChildren); } + template <typename Doc> VESPA_DLL_LOCAL void groupNext(const GroupingLevel & level, const Doc & docId, HitRank rank); public: @@ -122,8 +179,9 @@ public: Group(); Group(const Group & rhs); Group & operator =(const Group & rhs); - virtual ~Group(); - void swap(Group & rhs); + Group(Group &&) = default; + Group & operator = (Group &&) = default; + ~Group(); int cmpId(const Group &rhs) const { return _id->cmpFast(*rhs._id); } int cmpRank(const Group &rhs) const; @@ -131,7 +189,9 @@ public: Group & updateRank(RawRank r); RawRank getRank() const { return _rank; } - VESPA_DLL_LOCAL Group * groupSingle(const ResultNode & result, HitRank rank, const GroupingLevel & level); + Group * groupSingle(const ResultNode & result, HitRank rank, const GroupingLevel & level) { + return _aggr.groupSingle(result, rank, level); + } bool hasId() const { return (_id.get() != NULL); } const ResultNode &getId() const { return *_id; } @@ -139,12 +199,35 @@ public: Group unchain() const { return *this; } Group &setId(const ResultNode &id) { _id.reset(static_cast<ResultNode *>(id.clone())); return *this; } - Group &addAggregationResult(const ExpressionNode::CP &result); - Group &addResult(const ExpressionNode::CP &aggr); - Group &addExpressionResult(const ExpressionNode::CP &expressionNode); - Group &addOrderBy(const ExpressionNode::CP & orderBy, bool ascending); - Group &addChild(const Group &child) { addChild(new Group(child)); return *this; } - Group &addChild(Group::UP child) { addChild(child.release()); return *this; } + Group &addAggregationResult(ExpressionNode::UP result) { + _aggr.addAggregationResult(std::move(result)); + return *this; + } + Group &addResult(ExpressionNode::UP aggr) { + _aggr.addResult(std::move(aggr)); + return *this; + } + Group &addResult(const ExpressionNode & aggr) { return addResult(ExpressionNode::UP(aggr.clone())); } + + Group &addOrderBy(ExpressionNode::UP orderBy, bool ascending) { + _aggr.addOrderBy(std::move(orderBy), ascending); return *this; + } + Group &addOrderBy(const ExpressionNode & orderBy, bool ascending) { + return addOrderBy(ExpressionNode::UP(orderBy.clone()), ascending); + } + Group &addChild(const Group &child) { _aggr.addChild(new Group(child)); return *this; } + Group &addChild(Group::UP child) { _aggr.addChild(child.release()); return *this; } + + GroupList groups() const { return _aggr.groups(); } + uint32_t getAggrSize() const { return _aggr.getAggrSize(); } + uint32_t getOrderBySize() const { return _aggr.getOrderBySize(); } + uint32_t getExpr(uint32_t i) const { return _aggr.getExpr(i); } + int32_t getOrderBy(uint32_t i) const { return _aggr.getOrderBy(i); } + uint32_t getChildrenSize() const { return _aggr.getChildrenSize(); } + const Group & getChild(size_t i) const { return _aggr.getChild(i); } + + const AggregationResult & getAggregationResult(size_t i) const { return _aggr.getAggregationResult(i); } + AggregationResult & getAggregationResult(size_t i) { return _aggr.getAggregationResult(i); } /** * Prunes this tree, keeping only the nodes found in another @@ -160,20 +243,20 @@ public: * Recursively checks if any itself or any children needs a full resort. * Then all hits must be processed and should be doen before any hit sorting. */ - bool needResort() const; + bool needResort() const { return _aggr.needResort(); } - virtual void selectMembers(const vespalib::ObjectPredicate &predicate, - vespalib::ObjectOperation &operation); + void selectMembers(const vespalib::ObjectPredicate &predicate, vespalib::ObjectOperation &operation) override; - void preAggregate(); + void preAggregate() { return _aggr.preAggregate(); } template <typename Doc> VESPA_DLL_LOCAL void aggregate(const Grouping & grouping, uint32_t currentLevel, const Doc & docId, HitRank rank); template <typename Doc> - void collect(const Doc & docId, HitRank rank); - void postAggregate(); + void collect(const Doc & docId, HitRank rank) { _aggr.collect(docId, rank); } + void postAggregate() { _aggr.postAggregate(); } void merge(const std::vector<GroupingLevel> &levels, uint32_t firstLevel, uint32_t currentLevel, Group &b); - void executeOrderBy(); + void executeOrderBy() { _aggr.executeOrderBy(); } + void sortById() { _aggr.sortById(); } /** * Merge children and results of another tree within the unfrozen parts of @@ -184,20 +267,10 @@ public: * @param lastLevel The last level to merge. * @param currentLevel The current level on which merging should be done. **/ - void mergePartial(const std::vector<GroupingLevel> &levels, uint32_t firstLevel, uint32_t lastLevel, uint32_t currentLevel, const Group & b); - void postMerge(const std::vector<GroupingLevel> &levels, uint32_t firstLevel, uint32_t currentLevel); - void sortById(); - uint32_t getChildrenSize() const { return (_packedLength >> 8); } - const Group & getChild(size_t i) const { return *_children[i]; } - GroupList groups() const { return _children; } - const AggregationResult & getAggregationResult(size_t i) const { return static_cast<const AggregationResult &>(*_aggregationResults[i]); } - AggregationResult & getAggregationResult(size_t i) { return static_cast<AggregationResult &>(*_aggregationResults[i]); } - uint32_t getAggrSize() const { return _packedLength & 0x0f; } - uint32_t getOrderBySize() const { return (_packedLength >> 6) & 0x03; } - uint32_t getExpr(uint32_t i) const { return getAggrSize() + i; } - int32_t getOrderBy(uint32_t i) const { - int32_t v((_orderBy[i/2] >> (4*(i%2))) & 0x0f); - return (v & 0x8) ? -(v&0x7) : v; + void mergePartial(const std::vector<GroupingLevel> &levels, uint32_t firstLevel, uint32_t lastLevel, + uint32_t currentLevel, const Group & b); + void postMerge(const std::vector<GroupingLevel> &levels, uint32_t firstLevel, uint32_t currentLevel) { + _aggr.postMerge(levels, firstLevel, currentLevel); } }; diff --git a/searchlib/src/vespa/searchlib/aggregation/grouping.cpp b/searchlib/src/vespa/searchlib/aggregation/grouping.cpp index 11b354b4e9b..098d7ad1b40 100644 --- a/searchlib/src/vespa/searchlib/aggregation/grouping.cpp +++ b/searchlib/src/vespa/searchlib/aggregation/grouping.cpp @@ -121,6 +121,11 @@ Grouping::Grouping() { } +Grouping::Grouping(const Grouping &) = default; +Grouping & Grouping::operator = (const Grouping &) = default; + +Grouping::~Grouping() { } + void Grouping::selectMembers(const vespalib::ObjectPredicate &predicate, vespalib::ObjectOperation &operation) diff --git a/searchlib/src/vespa/searchlib/aggregation/grouping.h b/searchlib/src/vespa/searchlib/aggregation/grouping.h index 279d475a7d2..687e26b7fcd 100644 --- a/searchlib/src/vespa/searchlib/aggregation/grouping.h +++ b/searchlib/src/vespa/searchlib/aggregation/grouping.h @@ -42,17 +42,22 @@ public: DECLARE_NBO_SERIALIZE; virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; Grouping(); + Grouping(const Grouping &); + Grouping & operator = (const Grouping &); + Grouping(Grouping &&) = default; + Grouping & operator = (Grouping &&) = default; + ~Grouping(); Grouping unchain() const { return *this; } - Grouping &setId(unsigned int i) { _id = i; return *this; } - Grouping &invalidate() { _valid = false; return *this; } - Grouping &setAll(bool v) { _all = v; return *this; } - Grouping &setTopN(int64_t v) { _topN = v; return *this; } - Grouping &setFirstLevel(unsigned int level) { _firstLevel = level; return *this; } - Grouping &setLastLevel(unsigned int level) { _lastLevel = level; return *this; } - Grouping &addLevel(const GroupingLevel &level) { _levels.push_back(level); return *this; } - Grouping &setRoot(const Group &root_) { _root = root_; return *this; } + Grouping &setId(unsigned int i) { _id = i; return *this; } + Grouping &invalidate() { _valid = false; return *this; } + Grouping &setAll(bool v) { _all = v; return *this; } + Grouping &setTopN(int64_t v) { _topN = v; return *this; } + Grouping &setFirstLevel(unsigned int level) { _firstLevel = level; return *this; } + Grouping &setLastLevel(unsigned int level) { _lastLevel = level; return *this; } + Grouping &addLevel(GroupingLevel && level) { _levels.push_back(std::move(level)); return *this; } + Grouping &setRoot(const Group &root_) { _root = root_; return *this; } Grouping &setClock(const vespalib::Clock * clock) { _clock = clock; return *this; } Grouping &setTimeOfDoom(fastos::TimeStamp timeOfDoom) { _timeOfDoom = timeOfDoom; return *this; } @@ -70,8 +75,8 @@ public: GroupingLevelList &levels() { return _levels; } Group &root() { return _root; } - virtual void selectMembers(const vespalib::ObjectPredicate &predicate, - vespalib::ObjectOperation &operation); + void selectMembers(const vespalib::ObjectPredicate &predicate, + vespalib::ObjectOperation &operation) override; void merge(Grouping & b); void mergePartial(const Grouping & b); diff --git a/searchlib/src/vespa/searchlib/aggregation/groupinglevel.cpp b/searchlib/src/vespa/searchlib/aggregation/groupinglevel.cpp index 1811261ec9b..cc67d522c63 100644 --- a/searchlib/src/vespa/searchlib/aggregation/groupinglevel.cpp +++ b/searchlib/src/vespa/searchlib/aggregation/groupinglevel.cpp @@ -22,15 +22,21 @@ GroupingLevel::GroupingLevel() : _classify(), _collect(), _grouper(NULL) -{ -} +{ } + +GroupingLevel::~GroupingLevel() { } + +GroupingLevel::GroupingLevel(const GroupingLevel &) = default; +GroupingLevel & GroupingLevel::operator =(const GroupingLevel &) = default; -Serializer & GroupingLevel::onSerialize(Serializer & os) const +Serializer & +GroupingLevel::onSerialize(Serializer & os) const { return os << _maxGroups << _precision << _classify << _collect; } -Deserializer & GroupingLevel::onDeserialize(Deserializer & is) +Deserializer & +GroupingLevel::onDeserialize(Deserializer & is) { return is >> _maxGroups >> _precision >> _classify >> _collect; } diff --git a/searchlib/src/vespa/searchlib/aggregation/groupinglevel.h b/searchlib/src/vespa/searchlib/aggregation/groupinglevel.h index 03528965b90..3c49b98e16a 100644 --- a/searchlib/src/vespa/searchlib/aggregation/groupinglevel.h +++ b/searchlib/src/vespa/searchlib/aggregation/groupinglevel.h @@ -46,13 +46,13 @@ private: protected: template<typename Doc> void groupDoc(Group & group, const ResultNode & result, const Doc & doc, HitRank rank) const; - virtual void group(Group & g, const ResultNode & result, DocId doc, HitRank rank) const { + void group(Group & g, const ResultNode & result, DocId doc, HitRank rank) const override { groupDoc(g, result, doc, rank); } - virtual void group(Group & g, const ResultNode & result, const document::Document & doc, HitRank rank) const { + void group(Group & g, const ResultNode & result, const document::Document & doc, HitRank rank) const override { groupDoc(g, result, doc, rank); } - virtual SingleValueGrouper * clone() const { return new SingleValueGrouper(*this); } + SingleValueGrouper * clone() const override { return new SingleValueGrouper(*this); } }; class MultiValueGrouper : public SingleValueGrouper { public: @@ -60,10 +60,10 @@ private: private: template<typename Doc> void groupDoc(Group & group, const ResultNode & result, const Doc & doc, HitRank rank) const; - virtual void group(Group & g, const ResultNode & result, DocId doc, HitRank rank) const { + void group(Group & g, const ResultNode & result, DocId doc, HitRank rank) const override { groupDoc(g, result, doc, rank); } - virtual void group(Group & g, const ResultNode & result, const document::Document & doc, HitRank rank) const { + void group(Group & g, const ResultNode & result, const document::Document & doc, HitRank rank) const override { groupDoc(g, result, doc, rank); } virtual MultiValueGrouper * clone() const { return new MultiValueGrouper(*this); } @@ -77,8 +77,12 @@ private: vespalib::CloneablePtr<Grouper> _grouper; public: - GroupingLevel(); + GroupingLevel(GroupingLevel &&) = default; + GroupingLevel & operator =(GroupingLevel &&) = default; + GroupingLevel(const GroupingLevel &); + GroupingLevel & operator =(const GroupingLevel &); + ~GroupingLevel(); DECLARE_IDENTIFIABLE_NS2(search, aggregation, GroupingLevel); DECLARE_NBO_SERIALIZE; @@ -93,10 +97,11 @@ public: } GroupingLevel & freeze() { _frozen = true; return *this; } GroupingLevel &setPresicion(int64_t precision) { _precision = precision; return *this; } - GroupingLevel &setExpression(const ExpressionNode::CP &root) { _classify = root; return *this; } - GroupingLevel &addResult(const ExpressionNode::CP &result) { _collect.addResult(result); return *this; } - GroupingLevel &addAggregationResult(const ExpressionNode::CP &aggr) { _collect.addAggregationResult(aggr); return *this; } - GroupingLevel &addOrderBy(const ExpressionNode::CP & orderBy, bool ascending) { _collect.addOrderBy(orderBy, ascending); return *this; } + GroupingLevel &setExpression(ExpressionNode::UP root) { _classify = std::move(root); return *this; } + GroupingLevel &addResult(ExpressionNode::UP result) { _collect.addResult(std::move(result)); return *this; } + GroupingLevel &addResult(const ExpressionNode & result) { return addResult(ExpressionNode::UP(result.clone())); } + GroupingLevel &addAggregationResult(ExpressionNode::UP aggr) { _collect.addAggregationResult(std::move(aggr)); return *this; } + GroupingLevel &addOrderBy(ExpressionNode::UP orderBy, bool ascending) { _collect.addOrderBy(std::move(orderBy), ascending); return *this; } bool needResort() const { return _collect.needResort(); } int64_t getMaxGroups() const { return _maxGroups; } @@ -116,8 +121,8 @@ public: _grouper->group(g, result, doc, rank); } - virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; - virtual void selectMembers(const vespalib::ObjectPredicate &predicate, vespalib::ObjectOperation &operation); + void visitMembers(vespalib::ObjectVisitor &visitor) const override; + void selectMembers(const vespalib::ObjectPredicate &predicate, vespalib::ObjectOperation &operation) override; }; } diff --git a/searchlib/src/vespa/searchlib/aggregation/maxaggregationresult.h b/searchlib/src/vespa/searchlib/aggregation/maxaggregationresult.h index bc18293ab1a..85d0b906ed1 100644 --- a/searchlib/src/vespa/searchlib/aggregation/maxaggregationresult.h +++ b/searchlib/src/vespa/searchlib/aggregation/maxaggregationresult.h @@ -12,13 +12,14 @@ class MaxAggregationResult : public AggregationResult public: using SingleResultNode = expression::SingleResultNode; DECLARE_AGGREGATIONRESULT(MaxAggregationResult); - MaxAggregationResult() : AggregationResult(), _max() { } - MaxAggregationResult(const SingleResultNode & max) : AggregationResult(), _max(max) { } - virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; + MaxAggregationResult(); + MaxAggregationResult(const SingleResultNode & max); + ~MaxAggregationResult(); + void visitMembers(vespalib::ObjectVisitor &visitor) const override; const SingleResultNode & getMax() const { return *_max; } private: - virtual const ResultNode & onGetRank() const { return getMax(); } - virtual void onPrepare(const ResultNode & result, bool useForInit); + const ResultNode & onGetRank() const override { return getMax(); } + void onPrepare(const ResultNode & result, bool useForInit) override; SingleResultNode::CP _max; }; diff --git a/searchlib/src/vespa/searchlib/aggregation/minaggregationresult.h b/searchlib/src/vespa/searchlib/aggregation/minaggregationresult.h index c3c2a688cc4..8afd16fc44d 100644 --- a/searchlib/src/vespa/searchlib/aggregation/minaggregationresult.h +++ b/searchlib/src/vespa/searchlib/aggregation/minaggregationresult.h @@ -12,11 +12,14 @@ class MinAggregationResult : public AggregationResult public: using SingleResultNode = expression::SingleResultNode; DECLARE_AGGREGATIONRESULT(MinAggregationResult); - virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; + void visitMembers(vespalib::ObjectVisitor &visitor) const override; const SingleResultNode & getMin() const { return *_min; } + MinAggregationResult(); + MinAggregationResult(const ResultNode::CP &result); + ~MinAggregationResult(); private: - virtual const ResultNode & onGetRank() const { return getMin(); } - virtual void onPrepare(const ResultNode & result, bool useForInit); + const ResultNode & onGetRank() const override { return getMin(); } + void onPrepare(const ResultNode & result, bool useForInit) override; SingleResultNode::CP _min; }; diff --git a/searchlib/src/vespa/searchlib/aggregation/modifiers.cpp b/searchlib/src/vespa/searchlib/aggregation/modifiers.cpp index 7e80dff295d..4a87198fa99 100644 --- a/searchlib/src/vespa/searchlib/aggregation/modifiers.cpp +++ b/searchlib/src/vespa/searchlib/aggregation/modifiers.cpp @@ -21,7 +21,7 @@ void Attribute2DocumentAccessor::execute(vespalib::Identifiable &obj) if (obj.getClass().inherits(GroupingLevel::classId)) { GroupingLevel & g(static_cast<GroupingLevel &>(obj)); if (g.getExpression().getRoot()->inherits(AttributeNode::classId)) { - g.setExpression(new DocumentFieldNode(static_cast<const AttributeNode &>(*g.getExpression().getRoot()).getAttributeName())); + g.setExpression(std::make_unique<DocumentFieldNode>(static_cast<const AttributeNode &>(*g.getExpression().getRoot()).getAttributeName())); } else { g.getExpression().getRoot()->select(*this, *this); } @@ -31,7 +31,7 @@ void Attribute2DocumentAccessor::execute(vespalib::Identifiable &obj) ExpressionNode * e(a.getExpression()); if (e) { if (e->inherits(AttributeNode::classId)) { - a.setExpression(new DocumentFieldNode(static_cast<const AttributeNode &>(*e).getAttributeName())); + a.setExpression(std::make_unique<DocumentFieldNode>(static_cast<const AttributeNode &>(*e).getAttributeName())); } else { e->select(*this, *this); } diff --git a/searchlib/src/vespa/searchlib/aggregation/sumaggregationresult.h b/searchlib/src/vespa/searchlib/aggregation/sumaggregationresult.h index a976cc1e355..0916dc75ff9 100644 --- a/searchlib/src/vespa/searchlib/aggregation/sumaggregationresult.h +++ b/searchlib/src/vespa/searchlib/aggregation/sumaggregationresult.h @@ -14,7 +14,7 @@ public: using SingleResultNode = expression::SingleResultNode; DECLARE_AGGREGATIONRESULT(SumAggregationResult); SumAggregationResult() : AggregationResult(), _sum() { } - SumAggregationResult(const SingleResultNode & sum) : AggregationResult(), _sum(sum) { } + SumAggregationResult(SingleResultNode::UP sum) : AggregationResult(), _sum(sum.release()) { } virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; const SingleResultNode & getSum() const { return *_sum; } private: diff --git a/searchlib/src/vespa/searchlib/expression/aggregationrefnode.h b/searchlib/src/vespa/searchlib/expression/aggregationrefnode.h index 5ee42b7d789..03ee085c647 100644 --- a/searchlib/src/vespa/searchlib/expression/aggregationrefnode.h +++ b/searchlib/src/vespa/searchlib/expression/aggregationrefnode.h @@ -18,8 +18,8 @@ public: public: Configure(ExpressionNodeArray & exprVec) : _exprVec(exprVec) { } private: - virtual void execute(vespalib::Identifiable &obj) { static_cast<AggregationRefNode&>(obj).locateExpression(_exprVec); } - virtual bool check(const vespalib::Identifiable &obj) const { return obj.inherits(AggregationRefNode::classId); } + virtual void execute(vespalib::Identifiable &obj) override { static_cast<AggregationRefNode&>(obj).locateExpression(_exprVec); } + virtual bool check(const vespalib::Identifiable &obj) const override { return obj.inherits(AggregationRefNode::classId); } ExpressionNodeArray & _exprVec; }; virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; @@ -31,9 +31,9 @@ public: AggregationRefNode & operator = (const AggregationRefNode & exprref); ExpressionNode *getExpression() { return _expressionNode; } - virtual const ResultNode & getResult() const { return _expressionNode->getResult(); } - virtual void onPrepare(bool preserveAccurateTypes) { _expressionNode->prepare(preserveAccurateTypes); } - virtual bool onExecute() const; + const ResultNode & getResult() const override { return _expressionNode->getResult(); } + void onPrepare(bool preserveAccurateTypes) override { _expressionNode->prepare(preserveAccurateTypes); } + bool onExecute() const override; private: void locateExpression(ExpressionNodeArray & exprVec) const; diff --git a/searchlib/src/vespa/searchlib/expression/arrayatlookupfunctionnode.cpp b/searchlib/src/vespa/searchlib/expression/arrayatlookupfunctionnode.cpp index b112aa90969..7d443219f29 100644 --- a/searchlib/src/vespa/searchlib/expression/arrayatlookupfunctionnode.cpp +++ b/searchlib/src/vespa/searchlib/expression/arrayatlookupfunctionnode.cpp @@ -1,12 +1,10 @@ // 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/expression/arrayatlookupfunctionnode.h> -#include <vespa/searchlib/expression/floatresultnode.h> -#include <vespa/searchlib/expression/integerresultnode.h> -#include <vespa/searchlib/expression/stringresultnode.h> +#include "arrayatlookupfunctionnode.h" +#include "floatresultnode.h" +#include "integerresultnode.h" +#include "stringresultnode.h" #include <vespa/searchcommon/attribute/iattributecontext.h> -#include <vespa/searchlib/common/converters.h> -#include <vespa/vespalib/util/stringfmt.h> + namespace search { namespace expression { @@ -24,16 +22,15 @@ ArrayAtLookup::~ArrayAtLookup() { } -ArrayAtLookup::ArrayAtLookup(const vespalib::string &attribute, - const ExpressionNode::CP &arg) - : UnaryFunctionNode(arg), +ArrayAtLookup::ArrayAtLookup(const vespalib::string &attribute, ExpressionNode::UP arg) + : UnaryFunctionNode(std::move(arg)), _attributeName(attribute) { } ArrayAtLookup::ArrayAtLookup(const search::attribute::IAttributeVector &attr, - const ExpressionNode::CP &indexArg) - : UnaryFunctionNode(indexArg), + ExpressionNode::UP indexArg) + : UnaryFunctionNode(std::move(indexArg)), _attributeName(attr.getName()), _attribute(&attr) { diff --git a/searchlib/src/vespa/searchlib/expression/arrayatlookupfunctionnode.h b/searchlib/src/vespa/searchlib/expression/arrayatlookupfunctionnode.h index 692f2d36764..54b4a88a559 100644 --- a/searchlib/src/vespa/searchlib/expression/arrayatlookupfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/arrayatlookupfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/unaryfunctionnode.h> +#include "unaryfunctionnode.h" namespace search { namespace attribute { @@ -20,10 +20,10 @@ public: ~ArrayAtLookup(); ArrayAtLookup(const vespalib::string &attribute, - const ExpressionNode::CP & arg); + ExpressionNode::UP arg); ArrayAtLookup(const search::attribute::IAttributeVector &attr, - const ExpressionNode::CP &indexArg); + ExpressionNode::UP indexArg); ArrayAtLookup(const ArrayAtLookup &rhs); diff --git a/searchlib/src/vespa/searchlib/expression/attributenode.cpp b/searchlib/src/vespa/searchlib/expression/attributenode.cpp index 558177a7972..3800f0bac50 100644 --- a/searchlib/src/vespa/searchlib/expression/attributenode.cpp +++ b/searchlib/src/vespa/searchlib/expression/attributenode.cpp @@ -1,8 +1,7 @@ // 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/expression/attributenode.h> + +#include "attributenode.h" #include <vespa/searchlib/attribute/singleenumattribute.h> -#include <stdexcept> namespace search { namespace expression { diff --git a/searchlib/src/vespa/searchlib/expression/attributenode.h b/searchlib/src/vespa/searchlib/expression/attributenode.h index c55acff2808..a88881afbb8 100644 --- a/searchlib/src/vespa/searchlib/expression/attributenode.h +++ b/searchlib/src/vespa/searchlib/expression/attributenode.h @@ -1,8 +1,8 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/functionnode.h> -#include <vespa/searchlib/expression/resultvector.h> +#include "functionnode.h" +#include "resultvector.h" #include <vespa/searchcommon/attribute/iattributecontext.h> #include <vespa/vespalib/objects/objectoperation.h> #include <vespa/vespalib/objects/objectpredicate.h> @@ -24,16 +24,16 @@ public: const search::attribute::IAttributeVector *getAttribute() const { return _attribute; } DocId getDocId() const { return _docId; } private: - virtual int64_t onGetInteger(size_t index) const { (void) index; return _attribute->getInt(_docId); } - virtual double onGetFloat(size_t index) const { (void) index; return _attribute->getFloat(_docId); } - virtual ConstBufferRef onGetString(size_t index, BufferRef buf) const { + int64_t onGetInteger(size_t index) const override { (void) index; return _attribute->getInt(_docId); } + double onGetFloat(size_t index) const override { (void) index; return _attribute->getFloat(_docId); } + ConstBufferRef onGetString(size_t index, BufferRef buf) const override { (void) index; const char * t = _attribute->getString(_docId, buf.str(), buf.size()); return ConstBufferRef(t, strlen(t)); } int64_t onGetEnum(size_t index) const override { (void) index; return (static_cast<int64_t>(_attribute->getEnum(_docId))); } - virtual void set(const search::expression::ResultNode&) { } - virtual size_t hash() const { return _docId; } + void set(const search::expression::ResultNode&) override { } + size_t hash() const override { return _docId; } const search::attribute::IAttributeVector * _attribute; DocId _docId; @@ -50,11 +50,11 @@ public: public: Configure(const search::attribute::IAttributeContext & attrCtx) : _attrCtx(attrCtx) { } private: - virtual void execute(vespalib::Identifiable &obj) { + void execute(vespalib::Identifiable &obj) override { static_cast<ExpressionNode &>(obj).wireAttributes(_attrCtx); obj.selectMembers(*this, *this); } - virtual bool check(const vespalib::Identifiable &obj) const { + bool check(const vespalib::Identifiable &obj) const override { return obj.inherits(ExpressionNode::classId); } const search::attribute::IAttributeContext & _attrCtx; @@ -63,8 +63,8 @@ public: class CleanupAttributeReferences : public vespalib::ObjectOperation, public vespalib::ObjectPredicate { private: - virtual void execute(vespalib::Identifiable &obj) { static_cast<AttributeNode &>(obj).cleanup(); } - virtual bool check(const vespalib::Identifiable &obj) const { return obj.inherits(AttributeNode::classId); } + void execute(vespalib::Identifiable &obj) override { static_cast<AttributeNode &>(obj).cleanup(); } + bool check(const vespalib::Identifiable &obj) const override { return obj.inherits(AttributeNode::classId); } }; virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; @@ -84,9 +84,9 @@ public: bool hasMultiValue() const { return _hasMultiValue; } private: void cleanup(); - virtual void wireAttributes(const search::attribute::IAttributeContext & attrCtx); - virtual void onPrepare(bool preserveAccurateTypes); - virtual bool onExecute() const; + void wireAttributes(const search::attribute::IAttributeContext & attrCtx) override; + void onPrepare(bool preserveAccurateTypes) override; + bool onExecute() const override; class Handler { public: @@ -101,7 +101,7 @@ private: _vector(((IntegerResultNodeVector &)result).getVector()), _wVector() { } - virtual void handle(const AttributeResult & r); + void handle(const AttributeResult & r) override; private: IntegerResultNodeVector::Vector & _vector; mutable std::vector<search::attribute::IAttributeVector::WeightedInt> _wVector; @@ -114,7 +114,7 @@ private: _vector(((FloatResultNodeVector &)result).getVector()), _wVector() { } - virtual void handle(const AttributeResult & r); + void handle(const AttributeResult & r) override; private: FloatResultNodeVector::Vector & _vector; mutable std::vector<search::attribute::IAttributeVector::WeightedFloat> _wVector; @@ -127,7 +127,7 @@ private: _vector(((StringResultNodeVector &)result).getVector()), _wVector() { } - virtual void handle(const AttributeResult & r); + void handle(const AttributeResult & r) override; private: StringResultNodeVector::Vector & _vector; mutable std::vector<search::attribute::IAttributeVector::WeightedConstChar> _wVector; @@ -140,7 +140,7 @@ private: _vector(((EnumResultNodeVector &)result).getVector()), _wVector() { } - virtual void handle(const AttributeResult & r); + void handle(const AttributeResult & r) override; private: EnumResultNodeVector::Vector &_vector; mutable std::vector<search::attribute::IAttributeVector::WeightedEnum> _wVector; diff --git a/searchlib/src/vespa/searchlib/expression/binaryfunctionnode.h b/searchlib/src/vespa/searchlib/expression/binaryfunctionnode.h index b3872bf4a92..837c54942c3 100644 --- a/searchlib/src/vespa/searchlib/expression/binaryfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/binaryfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/multiargfunctionnode.h> +#include "multiargfunctionnode.h" namespace search { namespace expression { @@ -11,11 +11,11 @@ class BinaryFunctionNode : public MultiArgFunctionNode public: DECLARE_ABSTRACT_EXPRESSIONNODE(BinaryFunctionNode); BinaryFunctionNode() { } - BinaryFunctionNode(const ExpressionNode::CP & arg1, const ExpressionNode::CP & arg2) : + BinaryFunctionNode(ExpressionNode::UP arg1, ExpressionNode::UP arg2) : MultiArgFunctionNode() { - appendArg(arg1); - appendArg(arg2); + appendArg(std::move(arg1)); + appendArg(std::move(arg2)); } }; diff --git a/searchlib/src/vespa/searchlib/expression/catfunctionnode.h b/searchlib/src/vespa/searchlib/expression/catfunctionnode.h index 375bf6f84b1..c6acf32826e 100644 --- a/searchlib/src/vespa/searchlib/expression/catfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/catfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/multiargfunctionnode.h> +#include "multiargfunctionnode.h" namespace search { namespace expression { @@ -11,11 +11,11 @@ class CatFunctionNode : public MultiArgFunctionNode public: DECLARE_EXPRESSIONNODE(CatFunctionNode); CatFunctionNode() { } - CatFunctionNode(const ExpressionNode & arg) { addArg(arg); } + CatFunctionNode(ExpressionNode::UP arg) { addArg(std::move(arg)); } private: - virtual void onPrepare(bool preserveAccurateTypes); - virtual void onPrepareResult(); - virtual bool onExecute() const; + void onPrepare(bool preserveAccurateTypes) override; + void onPrepareResult() override; + bool onExecute() const override; }; } diff --git a/searchlib/src/vespa/searchlib/expression/constantnode.h b/searchlib/src/vespa/searchlib/expression/constantnode.h index b461af01319..f5f556a5312 100644 --- a/searchlib/src/vespa/searchlib/expression/constantnode.h +++ b/searchlib/src/vespa/searchlib/expression/constantnode.h @@ -1,8 +1,8 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/expressionnode.h> -#include <vespa/searchlib/expression/resultnode.h> +#include "expressionnode.h" +#include "resultnode.h" namespace search { namespace expression { @@ -13,7 +13,7 @@ public: DECLARE_NBO_SERIALIZE; DECLARE_EXPRESSIONNODE(ConstantNode); ConstantNode() : ExpressionNode(), _result() { } - ConstantNode(const ResultNode::CP & r) : ExpressionNode(), _result(r) { } + ConstantNode(ResultNode::UP r) : ExpressionNode(), _result(r.release()) { } virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; virtual const ResultNode & getResult() const { return *_result; } private: diff --git a/searchlib/src/vespa/searchlib/expression/debugwaitfunctionnode.cpp b/searchlib/src/vespa/searchlib/expression/debugwaitfunctionnode.cpp index 73ddc5c2d0a..506a8983994 100644 --- a/searchlib/src/vespa/searchlib/expression/debugwaitfunctionnode.cpp +++ b/searchlib/src/vespa/searchlib/expression/debugwaitfunctionnode.cpp @@ -20,8 +20,8 @@ DebugWaitFunctionNode::~DebugWaitFunctionNode() { } -DebugWaitFunctionNode::DebugWaitFunctionNode(const ExpressionNode::CP & arg, double waitTime, bool busyWait) - : UnaryFunctionNode(arg), +DebugWaitFunctionNode::DebugWaitFunctionNode(ExpressionNode::UP arg, double waitTime, bool busyWait) + : UnaryFunctionNode(std::move(arg)), _waitTime(waitTime), _busyWait(busyWait) { diff --git a/searchlib/src/vespa/searchlib/expression/debugwaitfunctionnode.h b/searchlib/src/vespa/searchlib/expression/debugwaitfunctionnode.h index 13b171e3135..be4d9770dbb 100644 --- a/searchlib/src/vespa/searchlib/expression/debugwaitfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/debugwaitfunctionnode.h @@ -1,10 +1,10 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/unaryfunctionnode.h> +#include "unaryfunctionnode.h" #include <vespa/searchlib/common/sortspec.h> -#include <vespa/searchlib/expression/stringresultnode.h> -#include <vespa/searchlib/expression/resultvector.h> +#include "stringresultnode.h" +#include "resultvector.h" namespace search { @@ -17,7 +17,7 @@ public: DECLARE_NBO_SERIALIZE; DebugWaitFunctionNode(); ~DebugWaitFunctionNode(); - DebugWaitFunctionNode(const ExpressionNode::CP & arg, double waitTime, bool busyWait); + DebugWaitFunctionNode(ExpressionNode::UP arg, double waitTime, bool busyWait); virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; private: virtual bool onExecute() const; diff --git a/searchlib/src/vespa/searchlib/expression/expressionnode.h b/searchlib/src/vespa/searchlib/expression/expressionnode.h index f29630b9fd6..62f8869397b 100644 --- a/searchlib/src/vespa/searchlib/expression/expressionnode.h +++ b/searchlib/src/vespa/searchlib/expression/expressionnode.h @@ -37,8 +37,8 @@ class ExpressionNode : public vespalib::Identifiable { public: DECLARE_ABSTRACT_EXPRESSIONNODE(ExpressionNode); - typedef std::unique_ptr<ExpressionNode> UP; - typedef vespalib::IdentifiablePtr<ExpressionNode> CP; + using UP = std::unique_ptr<ExpressionNode>; + using CP = vespalib::IdentifiablePtr<ExpressionNode>; virtual const ResultNode & getResult() const = 0; bool execute() const { return onExecute(); } ExpressionNode & prepare(bool preserveAccurateTypes) { onPrepare(preserveAccurateTypes); return *this; } diff --git a/searchlib/src/vespa/searchlib/expression/expressiontree.cpp b/searchlib/src/vespa/searchlib/expression/expressiontree.cpp index ad6090ab53d..3510b7f5e0c 100644 --- a/searchlib/src/vespa/searchlib/expression/expressiontree.cpp +++ b/searchlib/src/vespa/searchlib/expression/expressiontree.cpp @@ -15,9 +15,9 @@ using vespalib::Deserializer; IMPLEMENT_EXPRESSIONNODE(ExpressionTree, ExpressionNode); -void ExpressionTree::Configure::execute(vespalib::Identifiable &obj) -{ - ExpressionTree & e(static_cast<ExpressionTree &>(obj)); +void +ExpressionTree::Configure::execute(vespalib::Identifiable &obj) { + ExpressionTree &e(static_cast<ExpressionTree &>(obj)); if (e.getRoot()) { e.getRoot()->prepare(false); } @@ -35,7 +35,7 @@ ExpressionTree::ExpressionTree() : prepare(false); } -ExpressionTree::ExpressionTree(const ExpressionNode & root) : +ExpressionTree::ExpressionTree(const ExpressionNode &root) : _root(root.clone()), _attributeNodes(), _documentAccessorNodes(), @@ -46,21 +46,24 @@ ExpressionTree::ExpressionTree(const ExpressionNode & root) : prepare(false); } +namespace { + template<typename NODE> -class Gather : public vespalib::ObjectOperation, public vespalib::ObjectPredicate -{ +class Gather : public vespalib::ObjectOperation, public vespalib::ObjectPredicate { std::vector<NODE *> &_list; public: Gather(std::vector<NODE *> &list) : _list(list) { _list.clear(); } - void from(ExpressionNode & root) { + void from(ExpressionNode &root) { root.select(*this, *this); } + private: - virtual void execute(vespalib::Identifiable &obj) { + void execute(vespalib::Identifiable &obj) override { _list.push_back(&static_cast<NODE &>(obj)); } - virtual bool check(const vespalib::Identifiable &obj) const { + + bool check(const vespalib::Identifiable &obj) const override { return obj.inherits(NODE::classId); } }; @@ -71,8 +74,10 @@ gather(std::vector<NODE *> &list) { return Gather<NODE>(list); } +} -void ExpressionTree::onPrepare(bool preserveAccurateTypes) +void +ExpressionTree::onPrepare(bool preserveAccurateTypes) { (void) preserveAccurateTypes; if (_root.get() != NULL) { @@ -84,8 +89,9 @@ void ExpressionTree::onPrepare(bool preserveAccurateTypes) } } -ExpressionTree::ExpressionTree(const ExpressionNode::CP & root) : - _root(root->clone()), +ExpressionTree::ExpressionTree(ExpressionNode::UP root) : + ExpressionNode(), + _root(root.release()), _attributeNodes(), _documentAccessorNodes(), _relevanceNodes(), @@ -101,12 +107,14 @@ ExpressionTree::ExpressionTree(const ExpressionTree & rhs) : _attributeNodes(), _documentAccessorNodes(), _relevanceNodes(), - _interpolatedLookupNodes() + _interpolatedLookupNodes(), + _arrayAtLookupNodes() { prepare(false); } -ExpressionTree & ExpressionTree::operator = (const ExpressionTree & rhs) +ExpressionTree & +ExpressionTree::operator = (const ExpressionTree & rhs) { if (this != & rhs) { ExpressionTree eTree(rhs); @@ -115,20 +123,31 @@ ExpressionTree & ExpressionTree::operator = (const ExpressionTree & rhs) return *this; } -void ExpressionTree::swap(ExpressionTree & e) +ExpressionTree & +ExpressionTree::operator = (ExpressionNode::UP rhs) +{ + ExpressionTree eTree(std::move(rhs)); + swap(eTree); + return *this; +} + +void +ExpressionTree::swap(ExpressionTree & e) { std::swap(_root, e._root); _attributeNodes.swap(e._attributeNodes); _documentAccessorNodes.swap(e._documentAccessorNodes); _relevanceNodes.swap(e._relevanceNodes); _interpolatedLookupNodes.swap(e._interpolatedLookupNodes); + _arrayAtLookupNodes.swap(_arrayAtLookupNodes); } ExpressionTree::~ExpressionTree() { } -bool ExpressionTree::execute(const document::Document & doc, HitRank rank) const +bool +ExpressionTree::execute(const document::Document & doc, HitRank rank) const { for(DocumentAccessorNodeList::const_iterator it(_documentAccessorNodes.begin()), mt(_documentAccessorNodes.end()); it != mt; it++) { (*it)->setDoc(doc); @@ -162,7 +181,8 @@ struct RankSetter { }; -bool ExpressionTree::execute(DocId docId, HitRank rank) const +bool +ExpressionTree::execute(DocId docId, HitRank rank) const { DocIdSetter setDocId(docId); RankSetter setHitRank(rank); @@ -180,7 +200,8 @@ ExpressionTree::visitMembers(vespalib::ObjectVisitor &visitor) const visit(visitor, "root", _root.get()); } -void ExpressionTree::selectMembers(const vespalib::ObjectPredicate & predicate, vespalib::ObjectOperation & operation) +void +ExpressionTree::selectMembers(const vespalib::ObjectPredicate & predicate, vespalib::ObjectOperation & operation) { if (_root.get()) { _root->select(predicate, operation); @@ -188,12 +209,14 @@ void ExpressionTree::selectMembers(const vespalib::ObjectPredicate & predicate, } -Serializer & operator << (Serializer & os, const ExpressionTree & et) +Serializer & +operator << (Serializer & os, const ExpressionTree & et) { return os << et._root; } -Deserializer & operator >> (Deserializer & is, ExpressionTree & et) +Deserializer & +operator >> (Deserializer & is, ExpressionTree & et) { is >> et._root; et.prepare(false); diff --git a/searchlib/src/vespa/searchlib/expression/expressiontree.h b/searchlib/src/vespa/searchlib/expression/expressiontree.h index 2a920d421c2..235feff7edc 100644 --- a/searchlib/src/vespa/searchlib/expression/expressiontree.h +++ b/searchlib/src/vespa/searchlib/expression/expressiontree.h @@ -1,10 +1,10 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once +#include "expressionnode.h" #include <vespa/vespalib/objects/objectoperation.h> #include <vespa/vespalib/objects/objectpredicate.h> #include <vespa/searchlib/common/hitrank.h> -#include <vespa/searchlib/expression/expressionnode.h> namespace document { class DocumentType; @@ -34,33 +34,36 @@ class ExpressionTree : public ExpressionNode { public: DECLARE_EXPRESSIONNODE(ExpressionTree); - typedef vespalib::LinkedPtr<ExpressionTree> LP; class Configure : public vespalib::ObjectOperation, public vespalib::ObjectPredicate { private: - virtual void execute(vespalib::Identifiable &obj); - virtual bool check(const vespalib::Identifiable &obj) const { return obj.inherits(ExpressionTree::classId); } + void execute(vespalib::Identifiable &obj) override; + bool check(const vespalib::Identifiable &obj) const override { return obj.inherits(ExpressionTree::classId); } }; ExpressionTree(); ExpressionTree(const ExpressionNode & root); - ExpressionTree(const ExpressionNode::CP & root); + ExpressionTree(ExpressionNode::UP root); ExpressionTree(const ExpressionTree & rhs); + ExpressionTree(ExpressionTree &&) = default; ~ExpressionTree(); + ExpressionTree & operator = (ExpressionNode::UP rhs); ExpressionTree & operator = (const ExpressionTree & rhs); + ExpressionTree & operator = (ExpressionTree &&) = default; + bool execute(DocId docId, HitRank rank) const; bool execute(const document::Document & doc, HitRank rank) const; const ExpressionNode * getRoot() const { return _root.get(); } ExpressionNode * getRoot() { return _root.get(); } - virtual const ResultNode & getResult() const { return _root->getResult(); } + const ResultNode & getResult() const override { return _root->getResult(); } friend vespalib::Serializer & operator << (vespalib::Serializer & os, const ExpressionTree & et); friend vespalib::Deserializer & operator >> (vespalib::Deserializer & is, ExpressionTree & et); void swap(ExpressionTree &); private: - virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; - virtual void selectMembers(const vespalib::ObjectPredicate &predicate, vespalib::ObjectOperation &operation); - virtual bool onExecute() const { return _root->execute(); } - virtual void onPrepare(bool preserveAccurateTypes); + void visitMembers(vespalib::ObjectVisitor &visitor) const override; + void selectMembers(const vespalib::ObjectPredicate &predicate, vespalib::ObjectOperation &operation) override; + bool onExecute() const override { return _root->execute(); } + void onPrepare(bool preserveAccurateTypes) override; typedef std::vector<AttributeNode *> AttributeNodeList; typedef std::vector<DocumentAccessorNode *> DocumentAccessorNodeList; @@ -68,15 +71,13 @@ private: typedef std::vector<InterpolatedLookup *> InterpolatedLookupList; typedef std::vector<ArrayAtLookup *> ArrayAtLookupList; - vespalib::IdentifiableLinkedPtr<ExpressionNode> _root; - AttributeNodeList _attributeNodes; - DocumentAccessorNodeList _documentAccessorNodes; - RelevanceNodeList _relevanceNodes; - InterpolatedLookupList _interpolatedLookupNodes; - ArrayAtLookupList _arrayAtLookupNodes; + vespalib::IdentifiableLinkedPtr<ExpressionNode> _root; + AttributeNodeList _attributeNodes; + DocumentAccessorNodeList _documentAccessorNodes; + RelevanceNodeList _relevanceNodes; + InterpolatedLookupList _interpolatedLookupNodes; + ArrayAtLookupList _arrayAtLookupNodes; }; - } // namespace expression } // namespace search - diff --git a/searchlib/src/vespa/searchlib/expression/fixedwidthbucketfunctionnode.h b/searchlib/src/vespa/searchlib/expression/fixedwidthbucketfunctionnode.h index cf7b4561450..c7c81ff536a 100644 --- a/searchlib/src/vespa/searchlib/expression/fixedwidthbucketfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/fixedwidthbucketfunctionnode.h @@ -59,7 +59,7 @@ public: DECLARE_EXPRESSIONNODE(FixedWidthBucketFunctionNode); DECLARE_NBO_SERIALIZE; FixedWidthBucketFunctionNode() : UnaryFunctionNode(), _width(), _bucketHandler() {} - FixedWidthBucketFunctionNode(const ExpressionNode::CP &arg) : UnaryFunctionNode(arg), _width(), _bucketHandler() {} + FixedWidthBucketFunctionNode(ExpressionNode::UP arg) : UnaryFunctionNode(std::move(arg)), _width(), _bucketHandler() {} FixedWidthBucketFunctionNode &setWidth(const NumericResultNode::CP &width) { _width = width; return *this; diff --git a/searchlib/src/vespa/searchlib/expression/functionnode.h b/searchlib/src/vespa/searchlib/expression/functionnode.h index b2486ce9c88..4188190d9b9 100644 --- a/searchlib/src/vespa/searchlib/expression/functionnode.h +++ b/searchlib/src/vespa/searchlib/expression/functionnode.h @@ -1,8 +1,8 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/expressionnode.h> -#include <vespa/searchlib/expression/resultnode.h> +#include "expressionnode.h" +#include "resultnode.h" namespace search { namespace expression { @@ -11,16 +11,16 @@ class FunctionNode : public ExpressionNode { public: DECLARE_NBO_SERIALIZE; - virtual void visitMembers(vespalib::ObjectVisitor & visitor) const; + void visitMembers(vespalib::ObjectVisitor & visitor) const override; DECLARE_ABSTRACT_EXPRESSIONNODE(FunctionNode); - virtual const ResultNode & getResult() const { return *_tmpResult; } + const ResultNode & getResult() const override { return *_tmpResult; } ResultNode & updateResult() const { return *_tmpResult; } virtual void reset() { _tmpResult.reset(NULL); } FunctionNode &setResult(const ResultNode::CP res) { _tmpResult = res; return *this; } protected: void setResultType(ResultNode::UP res) { _tmpResult.reset(res.release()); } - virtual void selectMembers(const vespalib::ObjectPredicate & predicate, vespalib::ObjectOperation & operation); + void selectMembers(const vespalib::ObjectPredicate & predicate, vespalib::ObjectOperation & operation) override; private: mutable ResultNode::CP _tmpResult; }; diff --git a/searchlib/src/vespa/searchlib/expression/functionnodes.cpp b/searchlib/src/vespa/searchlib/expression/functionnodes.cpp index 955055a7cfa..bbb79d36e66 100644 --- a/searchlib/src/vespa/searchlib/expression/functionnodes.cpp +++ b/searchlib/src/vespa/searchlib/expression/functionnodes.cpp @@ -1,41 +1,41 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/searchlib/expression/integerresultnode.h> -#include <vespa/searchlib/expression/floatresultnode.h> -#include <vespa/searchlib/expression/stringresultnode.h> -#include <vespa/searchlib/expression/rawresultnode.h> -#include <vespa/searchlib/expression/enumresultnode.h> -#include <vespa/searchlib/expression/constantnode.h> -#include <vespa/searchlib/expression/relevancenode.h> -#include <vespa/searchlib/expression/addfunctionnode.h> -#include <vespa/searchlib/expression/dividefunctionnode.h> -#include <vespa/searchlib/expression/multiplyfunctionnode.h> -#include <vespa/searchlib/expression/modulofunctionnode.h> -#include <vespa/searchlib/expression/minfunctionnode.h> -#include <vespa/searchlib/expression/maxfunctionnode.h> -#include <vespa/searchlib/expression/andfunctionnode.h> -#include <vespa/searchlib/expression/orfunctionnode.h> -#include <vespa/searchlib/expression/xorfunctionnode.h> -#include <vespa/searchlib/expression/negatefunctionnode.h> -#include <vespa/searchlib/expression/sortfunctionnode.h> -#include <vespa/searchlib/expression/reversefunctionnode.h> -#include <vespa/searchlib/expression/strlenfunctionnode.h> -#include <vespa/searchlib/expression/numelemfunctionnode.h> -#include <vespa/searchlib/expression/tostringfunctionnode.h> -#include <vespa/searchlib/expression/torawfunctionnode.h> -#include <vespa/searchlib/expression/catfunctionnode.h> -#include <vespa/searchlib/expression/tointfunctionnode.h> -#include <vespa/searchlib/expression/tofloatfunctionnode.h> -#include <vespa/searchlib/expression/strcatfunctionnode.h> -#include <vespa/searchlib/expression/xorbitfunctionnode.h> -#include <vespa/searchlib/expression/md5bitfunctionnode.h> -#include <vespa/searchlib/expression/binaryfunctionnode.h> -#include <vespa/searchlib/expression/nullresultnode.h> -#include <vespa/searchlib/expression/positiveinfinityresultnode.h> -#include <vespa/searchlib/expression/resultvector.h> -#include <vespa/searchlib/expression/catserializer.h> -#include <vespa/searchlib/expression/strcatserializer.h> -#include <vespa/searchlib/expression/normalizesubjectfunctionnode.h> -#include <vespa/searchlib/expression/arrayoperationnode.h> +#include "integerresultnode.h" +#include "floatresultnode.h" +#include "stringresultnode.h" +#include "rawresultnode.h" +#include "enumresultnode.h" +#include "constantnode.h" +#include "relevancenode.h" +#include "addfunctionnode.h" +#include "dividefunctionnode.h" +#include "multiplyfunctionnode.h" +#include "modulofunctionnode.h" +#include "minfunctionnode.h" +#include "maxfunctionnode.h" +#include "andfunctionnode.h" +#include "orfunctionnode.h" +#include "xorfunctionnode.h" +#include "negatefunctionnode.h" +#include "sortfunctionnode.h" +#include "reversefunctionnode.h" +#include "strlenfunctionnode.h" +#include "numelemfunctionnode.h" +#include "tostringfunctionnode.h" +#include "torawfunctionnode.h" +#include "catfunctionnode.h" +#include "tointfunctionnode.h" +#include "tofloatfunctionnode.h" +#include "strcatfunctionnode.h" +#include "xorbitfunctionnode.h" +#include "md5bitfunctionnode.h" +#include "binaryfunctionnode.h" +#include "nullresultnode.h" +#include "positiveinfinityresultnode.h" +#include "resultvector.h" +#include "catserializer.h" +#include "strcatserializer.h" +#include "normalizesubjectfunctionnode.h" +#include "arrayoperationnode.h" #include <vespa/vespalib/objects/serializer.hpp> #include <vespa/vespalib/objects/deserializer.hpp> #include <vespa/vespalib/stllike/asciistream.h> @@ -487,8 +487,8 @@ bool CatFunctionNode::onExecute() const return true; } -XorBitFunctionNode::XorBitFunctionNode(const ExpressionNode::CP & arg, unsigned numBits) : - UnaryBitFunctionNode(arg, numBits), +XorBitFunctionNode::XorBitFunctionNode(ExpressionNode::UP arg, unsigned numBits) : + UnaryBitFunctionNode(std::move(arg), numBits), _tmpXor(getNumBytes(), 0) { } @@ -593,6 +593,12 @@ Deserializer & MultiArgFunctionNode::onDeserialize(Deserializer & is) return is >> _args; } +MultiArgFunctionNode::MultiArgFunctionNode() : FunctionNode() { } +MultiArgFunctionNode::MultiArgFunctionNode(const MultiArgFunctionNode &) = default; +MultiArgFunctionNode & MultiArgFunctionNode::operator = (const MultiArgFunctionNode &) = default; + +MultiArgFunctionNode::~MultiArgFunctionNode() {} + void MultiArgFunctionNode::visitMembers(vespalib::ObjectVisitor &visitor) const { diff --git a/searchlib/src/vespa/searchlib/expression/integerresultnode.h b/searchlib/src/vespa/searchlib/expression/integerresultnode.h index 79c7ef21558..3954031f17a 100644 --- a/searchlib/src/vespa/searchlib/expression/integerresultnode.h +++ b/searchlib/src/vespa/searchlib/expression/integerresultnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/numericresultnode.h> +#include "numericresultnode.h" #include <vespa/vespalib/util/sort.h> #include <limits> diff --git a/searchlib/src/vespa/searchlib/expression/interpolatedlookupfunctionnode.cpp b/searchlib/src/vespa/searchlib/expression/interpolatedlookupfunctionnode.cpp index bd42ee61eb5..d135be103e6 100644 --- a/searchlib/src/vespa/searchlib/expression/interpolatedlookupfunctionnode.cpp +++ b/searchlib/src/vespa/searchlib/expression/interpolatedlookupfunctionnode.cpp @@ -24,18 +24,16 @@ InterpolatedLookup::~InterpolatedLookup() { } -InterpolatedLookup::InterpolatedLookup(const vespalib::string &attribute, - const ExpressionNode::CP &arg) - : UnaryFunctionNode(arg), +InterpolatedLookup::InterpolatedLookup(const vespalib::string &attribute, ExpressionNode::UP arg) + : UnaryFunctionNode(std::move(arg)), _attributeName(attribute), _attribute(0), _docId(0) { } -InterpolatedLookup::InterpolatedLookup(const search::attribute::IAttributeVector &attr, - const ExpressionNode::CP &lookupArg) - : UnaryFunctionNode(lookupArg), +InterpolatedLookup::InterpolatedLookup(const attribute::IAttributeVector &attr, ExpressionNode::UP lookupArg) + : UnaryFunctionNode(std::move(lookupArg)), _attributeName(attr.getName()), _attribute(&attr), _docId(0) @@ -53,7 +51,8 @@ InterpolatedLookup::InterpolatedLookup(const InterpolatedLookup &rhs) : _docId = 0; } -InterpolatedLookup & InterpolatedLookup::operator= (const InterpolatedLookup &rhs) +InterpolatedLookup & +InterpolatedLookup::operator= (const InterpolatedLookup &rhs) { if (this != &rhs) { UnaryFunctionNode::operator =(rhs); diff --git a/searchlib/src/vespa/searchlib/expression/interpolatedlookupfunctionnode.h b/searchlib/src/vespa/searchlib/expression/interpolatedlookupfunctionnode.h index c5e62937490..50e03e615a2 100644 --- a/searchlib/src/vespa/searchlib/expression/interpolatedlookupfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/interpolatedlookupfunctionnode.h @@ -18,10 +18,10 @@ public: ~InterpolatedLookup(); InterpolatedLookup(const vespalib::string &attribute, - const ExpressionNode::CP & arg); + ExpressionNode::UP arg); InterpolatedLookup(const search::attribute::IAttributeVector &attr, - const ExpressionNode::CP &lookupArg); + ExpressionNode::UP lookupArg); InterpolatedLookup(const InterpolatedLookup &rhs); diff --git a/searchlib/src/vespa/searchlib/expression/md5bitfunctionnode.h b/searchlib/src/vespa/searchlib/expression/md5bitfunctionnode.h index 038a26f2cac..2a1da409c8b 100644 --- a/searchlib/src/vespa/searchlib/expression/md5bitfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/md5bitfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/unarybitfunctionnode.h> +#include "unarybitfunctionnode.h" namespace search { namespace expression { @@ -11,9 +11,9 @@ class MD5BitFunctionNode : public UnaryBitFunctionNode public: DECLARE_EXPRESSIONNODE(MD5BitFunctionNode); MD5BitFunctionNode() { } - MD5BitFunctionNode(const ExpressionNode::CP & arg, unsigned numBits) : UnaryBitFunctionNode(arg, numBits) { } + MD5BitFunctionNode(ExpressionNode::UP arg, unsigned numBits) : UnaryBitFunctionNode(std::move(arg), numBits) { } private: - virtual bool internalExecute(const vespalib::nbostream & os) const; + bool internalExecute(const vespalib::nbostream & os) const override; }; } diff --git a/searchlib/src/vespa/searchlib/expression/multiargfunctionnode.h b/searchlib/src/vespa/searchlib/expression/multiargfunctionnode.h index 349d448d753..71ab5052ccf 100644 --- a/searchlib/src/vespa/searchlib/expression/multiargfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/multiargfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/functionnode.h> +#include "functionnode.h" namespace search { namespace expression { @@ -13,23 +13,28 @@ public: DECLARE_NBO_SERIALIZE; virtual void visitMembers(vespalib::ObjectVisitor & visitor) const; DECLARE_ABSTRACT_EXPRESSIONNODE(MultiArgFunctionNode); - MultiArgFunctionNode() : FunctionNode() { } - MultiArgFunctionNode & appendArg(const ExpressionNode::CP & arg) { return addArg(arg); } - MultiArgFunctionNode &addArg(const ExpressionNode::CP & arg) { - _args.push_back(arg); + MultiArgFunctionNode(); + MultiArgFunctionNode(const MultiArgFunctionNode &); + MultiArgFunctionNode & operator = (const MultiArgFunctionNode &); + MultiArgFunctionNode(MultiArgFunctionNode &&) = default; + MultiArgFunctionNode & operator = (MultiArgFunctionNode &&) = default; + ~MultiArgFunctionNode(); + MultiArgFunctionNode & appendArg(ExpressionNode::UP arg) { return addArg(std::move(arg)); } + MultiArgFunctionNode & addArg(ExpressionNode::UP arg) { + _args.emplace_back(arg.release()); return *this; } - virtual void reset() { _args.clear(); FunctionNode::reset(); } + void reset() override { _args.clear(); FunctionNode::reset(); } ExpressionNodeVector & expressionNodeVector() { return _args; } protected: virtual bool onCalculate(const ExpressionNodeVector & args, ResultNode & result) const; - virtual bool onExecute() const; - virtual void onPrepare(bool preserveAccurateTypes); + bool onExecute() const override; + void onPrepare(bool preserveAccurateTypes) override; size_t getNumArgs() const { return _args.size(); } const ExpressionNode & getArg(size_t n) const { return *_args[n]; } ExpressionNode & getArg(size_t n) { return *_args[n]; } private: - virtual void selectMembers(const vespalib::ObjectPredicate & predicate, vespalib::ObjectOperation & operation); + void selectMembers(const vespalib::ObjectPredicate & predicate, vespalib::ObjectOperation & operation) override; bool calculate(const ExpressionNodeVector & args, ResultNode & result) const { return onCalculate(args, result); } void prepareResult() { onPrepareResult(); } virtual void onPrepareResult(); diff --git a/searchlib/src/vespa/searchlib/expression/negatefunctionnode.h b/searchlib/src/vespa/searchlib/expression/negatefunctionnode.h index 564317d4fa4..63cd028c87c 100644 --- a/searchlib/src/vespa/searchlib/expression/negatefunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/negatefunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/unaryfunctionnode.h> +#include "unaryfunctionnode.h" namespace search { namespace expression { @@ -11,7 +11,7 @@ class NegateFunctionNode : public UnaryFunctionNode public: DECLARE_EXPRESSIONNODE(NegateFunctionNode); NegateFunctionNode() { } - NegateFunctionNode(const ExpressionNode::CP & arg) : UnaryFunctionNode(arg) { } + NegateFunctionNode(ExpressionNode::UP arg) : UnaryFunctionNode(std::move(arg)) { } private: virtual bool onExecute() const; }; diff --git a/searchlib/src/vespa/searchlib/expression/normalizesubjectfunctionnode.h b/searchlib/src/vespa/searchlib/expression/normalizesubjectfunctionnode.h index 3e64946e7fb..a91d2dde0bf 100644 --- a/searchlib/src/vespa/searchlib/expression/normalizesubjectfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/normalizesubjectfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/unaryfunctionnode.h> +#include "unaryfunctionnode.h" namespace search { namespace expression { @@ -11,10 +11,10 @@ class NormalizeSubjectFunctionNode : public UnaryFunctionNode public: DECLARE_EXPRESSIONNODE(NormalizeSubjectFunctionNode); NormalizeSubjectFunctionNode() { } - NormalizeSubjectFunctionNode(const ExpressionNode::CP & arg) : UnaryFunctionNode(arg) { } + NormalizeSubjectFunctionNode(ExpressionNode::UP arg) : UnaryFunctionNode(std::move(arg)) { } private: - virtual bool onExecute() const; - virtual void onPrepareResult(); + bool onExecute() const override; + void onPrepareResult() override; }; } diff --git a/searchlib/src/vespa/searchlib/expression/numelemfunctionnode.h b/searchlib/src/vespa/searchlib/expression/numelemfunctionnode.h index 00ca2fcf75a..9b8b05b0eed 100644 --- a/searchlib/src/vespa/searchlib/expression/numelemfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/numelemfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/unaryfunctionnode.h> +#include "unaryfunctionnode.h" namespace search { namespace expression { @@ -11,10 +11,10 @@ class NumElemFunctionNode : public UnaryFunctionNode public: DECLARE_EXPRESSIONNODE(NumElemFunctionNode); NumElemFunctionNode() { } - NumElemFunctionNode(const ExpressionNode::CP & arg) : UnaryFunctionNode(arg) { } + NumElemFunctionNode(ExpressionNode::UP arg) : UnaryFunctionNode(std::move(arg)) { } private: - virtual bool onExecute() const; - virtual void onPrepareResult(); + bool onExecute() const override; + void onPrepareResult() override; }; } diff --git a/searchlib/src/vespa/searchlib/expression/rangebucketpredef.h b/searchlib/src/vespa/searchlib/expression/rangebucketpredef.h index de9c5e69879..06a4a9e2b52 100644 --- a/searchlib/src/vespa/searchlib/expression/rangebucketpredef.h +++ b/searchlib/src/vespa/searchlib/expression/rangebucketpredef.h @@ -58,7 +58,7 @@ public: DECLARE_EXPRESSIONNODE(RangeBucketPreDefFunctionNode); DECLARE_NBO_SERIALIZE; RangeBucketPreDefFunctionNode() : UnaryFunctionNode(), _predef(), _result(NULL), _nullResult(NULL) {} - RangeBucketPreDefFunctionNode(const ExpressionNode::CP &arg) : UnaryFunctionNode(arg), _predef(), _result(NULL), _nullResult(NULL) {} + RangeBucketPreDefFunctionNode(ExpressionNode::UP arg) : UnaryFunctionNode(std::move(arg)), _predef(), _result(NULL), _nullResult(NULL) {} RangeBucketPreDefFunctionNode(const RangeBucketPreDefFunctionNode & rhs); RangeBucketPreDefFunctionNode & operator = (const RangeBucketPreDefFunctionNode & rhs); virtual const ResultNode & getResult() const { return *_result; } diff --git a/searchlib/src/vespa/searchlib/expression/resultvector.h b/searchlib/src/vespa/searchlib/expression/resultvector.h index 019a9d694a8..7eaa268682a 100644 --- a/searchlib/src/vespa/searchlib/expression/resultvector.h +++ b/searchlib/src/vespa/searchlib/expression/resultvector.h @@ -78,7 +78,8 @@ class ResultNodeVectorT : public ResultNodeVector { public: DECLARE_NBO_SERIALIZE; - typedef std::vector<B> Vector; + using Vector = std::vector<B>; + using BaseType = B; const Vector & getVector() const { return _result; } Vector & getVector() { return _result; } virtual const ResultNode * find(const ResultNode & key) const; diff --git a/searchlib/src/vespa/searchlib/expression/reversefunctionnode.h b/searchlib/src/vespa/searchlib/expression/reversefunctionnode.h index 2cc788d1424..205dcc594f2 100644 --- a/searchlib/src/vespa/searchlib/expression/reversefunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/reversefunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/unaryfunctionnode.h> +#include "unaryfunctionnode.h" namespace search { namespace expression { @@ -11,9 +11,9 @@ class ReverseFunctionNode : public UnaryFunctionNode public: DECLARE_EXPRESSIONNODE(ReverseFunctionNode); ReverseFunctionNode() { } - ReverseFunctionNode(const ExpressionNode::CP & arg) : UnaryFunctionNode(arg) { } + ReverseFunctionNode(ExpressionNode::UP arg) : UnaryFunctionNode(std::move(arg)) { } private: - virtual bool onExecute() const; + bool onExecute() const override; }; } diff --git a/searchlib/src/vespa/searchlib/expression/sortfunctionnode.h b/searchlib/src/vespa/searchlib/expression/sortfunctionnode.h index 837563b6ee2..4d7ae46fb5b 100644 --- a/searchlib/src/vespa/searchlib/expression/sortfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/sortfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/unaryfunctionnode.h> +#include "unaryfunctionnode.h" namespace search { namespace expression { @@ -11,9 +11,9 @@ class SortFunctionNode : public UnaryFunctionNode public: DECLARE_EXPRESSIONNODE(SortFunctionNode); SortFunctionNode() { } - SortFunctionNode(const ExpressionNode::CP & arg) : UnaryFunctionNode(arg) { } + SortFunctionNode(ExpressionNode::UP arg) : UnaryFunctionNode(std::move(arg)) { } private: - virtual bool onExecute() const; + bool onExecute() const override; }; } diff --git a/searchlib/src/vespa/searchlib/expression/strcatfunctionnode.h b/searchlib/src/vespa/searchlib/expression/strcatfunctionnode.h index 8ceebd95bb0..260c51ef359 100644 --- a/searchlib/src/vespa/searchlib/expression/strcatfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/strcatfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/multiargfunctionnode.h> +#include "multiargfunctionnode.h" namespace search { namespace expression { @@ -11,10 +11,10 @@ class StrCatFunctionNode : public MultiArgFunctionNode public: DECLARE_EXPRESSIONNODE(StrCatFunctionNode); StrCatFunctionNode() { } - StrCatFunctionNode(const ExpressionNode & arg) { addArg(arg); } + StrCatFunctionNode(ExpressionNode::UP arg) { addArg(std::move(arg)); } private: - virtual void onPrepareResult(); - virtual bool onExecute() const; + void onPrepareResult() override; + bool onExecute() const override; }; } diff --git a/searchlib/src/vespa/searchlib/expression/strlenfunctionnode.h b/searchlib/src/vespa/searchlib/expression/strlenfunctionnode.h index 294b69a8172..617f0745a3d 100644 --- a/searchlib/src/vespa/searchlib/expression/strlenfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/strlenfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/unaryfunctionnode.h> +#include "unaryfunctionnode.h" namespace search { namespace expression { @@ -11,10 +11,10 @@ class StrLenFunctionNode : public UnaryFunctionNode public: DECLARE_EXPRESSIONNODE(StrLenFunctionNode); StrLenFunctionNode() { } - StrLenFunctionNode(const ExpressionNode::CP & arg) : UnaryFunctionNode(arg) { } + StrLenFunctionNode(ExpressionNode::UP arg) : UnaryFunctionNode(std::move(arg)) { } private: - virtual bool onExecute() const; - virtual void onPrepareResult(); + bool onExecute() const override; + void onPrepareResult() override; }; } diff --git a/searchlib/src/vespa/searchlib/expression/timestamp.h b/searchlib/src/vespa/searchlib/expression/timestamp.h index 16f92e233a4..c17d746ee00 100644 --- a/searchlib/src/vespa/searchlib/expression/timestamp.h +++ b/searchlib/src/vespa/searchlib/expression/timestamp.h @@ -15,7 +15,11 @@ public: DECLARE_EXPRESSIONNODE(TimeStampFunctionNode); DECLARE_NBO_SERIALIZE; TimeStampFunctionNode() : _timePart(Year), _isGmt(true) { } - TimeStampFunctionNode(const ExpressionNode::CP & arg, TimePart timePart, bool gmt=true) : UnaryFunctionNode(arg), _timePart(timePart), _isGmt(gmt) { } + TimeStampFunctionNode(ExpressionNode::UP arg, TimePart timePart, bool gmt=true) + : UnaryFunctionNode(std::move(arg)), + _timePart(timePart), + _isGmt(gmt) + { } TimeStampFunctionNode(const TimeStampFunctionNode & rhs); TimeStampFunctionNode & operator = (const TimeStampFunctionNode & rhs); unsigned int getTime() const { return getResult().getInteger(); } // Not valid until after node has been prepared diff --git a/searchlib/src/vespa/searchlib/expression/tofloatfunctionnode.h b/searchlib/src/vespa/searchlib/expression/tofloatfunctionnode.h index 48d93ee282c..41c77965a41 100644 --- a/searchlib/src/vespa/searchlib/expression/tofloatfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/tofloatfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/unaryfunctionnode.h> +#include "unaryfunctionnode.h" namespace search { namespace expression { @@ -11,10 +11,10 @@ class ToFloatFunctionNode : public UnaryFunctionNode public: DECLARE_EXPRESSIONNODE(ToFloatFunctionNode); ToFloatFunctionNode() { } - ToFloatFunctionNode(const ExpressionNode::CP & arg) : UnaryFunctionNode(arg) { } + ToFloatFunctionNode(ExpressionNode::UP arg) : UnaryFunctionNode(std::move(arg)) { } private: - virtual bool onExecute() const; - virtual void onPrepareResult(); + bool onExecute() const override; + void onPrepareResult() override; }; } diff --git a/searchlib/src/vespa/searchlib/expression/tointfunctionnode.h b/searchlib/src/vespa/searchlib/expression/tointfunctionnode.h index 420d6707215..435e053d0e6 100644 --- a/searchlib/src/vespa/searchlib/expression/tointfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/tointfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/unaryfunctionnode.h> +#include "unaryfunctionnode.h" namespace search { namespace expression { @@ -11,10 +11,10 @@ class ToIntFunctionNode : public UnaryFunctionNode public: DECLARE_EXPRESSIONNODE(ToIntFunctionNode); ToIntFunctionNode() { } - ToIntFunctionNode(const ExpressionNode::CP & arg) : UnaryFunctionNode(arg) { } + ToIntFunctionNode(ExpressionNode::UP arg) : UnaryFunctionNode(std::move(arg)) { } private: - virtual bool onExecute() const; - virtual void onPrepareResult(); + bool onExecute() const override; + void onPrepareResult() override; }; } diff --git a/searchlib/src/vespa/searchlib/expression/torawfunctionnode.h b/searchlib/src/vespa/searchlib/expression/torawfunctionnode.h index 4c80bbab7d4..0ca0c0a6bd9 100644 --- a/searchlib/src/vespa/searchlib/expression/torawfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/torawfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/unaryfunctionnode.h> +#include "unaryfunctionnode.h" namespace search { namespace expression { @@ -11,10 +11,10 @@ class ToRawFunctionNode : public UnaryFunctionNode public: DECLARE_EXPRESSIONNODE(ToRawFunctionNode); ToRawFunctionNode() { } - ToRawFunctionNode(const ExpressionNode::CP & arg) : UnaryFunctionNode(arg) { } + ToRawFunctionNode(ExpressionNode::UP arg) : UnaryFunctionNode(std::move(arg)) { } private: - virtual bool onExecute() const; - virtual void onPrepareResult(); + bool onExecute() const override; + void onPrepareResult() override; }; } diff --git a/searchlib/src/vespa/searchlib/expression/tostringfunctionnode.h b/searchlib/src/vespa/searchlib/expression/tostringfunctionnode.h index fd6d80d850e..da8e7d7f7b4 100644 --- a/searchlib/src/vespa/searchlib/expression/tostringfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/tostringfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/unaryfunctionnode.h> +#include "unaryfunctionnode.h" namespace search { namespace expression { @@ -11,10 +11,10 @@ class ToStringFunctionNode : public UnaryFunctionNode public: DECLARE_EXPRESSIONNODE(ToStringFunctionNode); ToStringFunctionNode() { } - ToStringFunctionNode(const ExpressionNode::CP & arg) : UnaryFunctionNode(arg) { } + ToStringFunctionNode(ExpressionNode::UP arg) : UnaryFunctionNode(std::move(arg)) { } private: - virtual bool onExecute() const; - virtual void onPrepareResult(); + bool onExecute() const override; + void onPrepareResult() override; }; } diff --git a/searchlib/src/vespa/searchlib/expression/unarybitfunctionnode.h b/searchlib/src/vespa/searchlib/expression/unarybitfunctionnode.h index 144bf6ff47e..8482c7fe2ba 100644 --- a/searchlib/src/vespa/searchlib/expression/unarybitfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/unarybitfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/unaryfunctionnode.h> +#include "unaryfunctionnode.h" #include <vespa/vespalib/objects/nbostream.h> namespace search { @@ -11,18 +11,18 @@ class UnaryBitFunctionNode : public UnaryFunctionNode { public: DECLARE_NBO_SERIALIZE; - virtual void visitMembers(vespalib::ObjectVisitor &visitor) const; + void visitMembers(vespalib::ObjectVisitor &visitor) const override; DECLARE_ABSTRACT_EXPRESSIONNODE(UnaryBitFunctionNode); UnaryBitFunctionNode() : _numBits(0) { } - UnaryBitFunctionNode(const ExpressionNode::CP & arg, unsigned numBits) : UnaryFunctionNode(arg), _numBits(numBits) { } + UnaryBitFunctionNode(ExpressionNode::UP arg, unsigned numBits) : UnaryFunctionNode(std::move(arg)), _numBits(numBits) { } protected: size_t getNumBits() const { return _numBits; } size_t getNumBytes() const { return (_numBits+7)/8; } - virtual void onPrepareResult(); + void onPrepareResult() override; private: - virtual void onPrepare(bool preserveAccurateTypes); + void onPrepare(bool preserveAccurateTypes) override; virtual bool internalExecute(const vespalib::nbostream & os) const = 0; - virtual bool onExecute() const; + bool onExecute() const override; uint32_t _numBits; mutable vespalib::nbostream _tmpOs; }; diff --git a/searchlib/src/vespa/searchlib/expression/unaryfunctionnode.h b/searchlib/src/vespa/searchlib/expression/unaryfunctionnode.h index 366e7d9191f..ae1d58d95dd 100644 --- a/searchlib/src/vespa/searchlib/expression/unaryfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/unaryfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/multiargfunctionnode.h> +#include "multiargfunctionnode.h" namespace search { namespace expression { @@ -11,10 +11,10 @@ class UnaryFunctionNode : public MultiArgFunctionNode public: DECLARE_ABSTRACT_EXPRESSIONNODE(UnaryFunctionNode); UnaryFunctionNode() { } - UnaryFunctionNode(const ExpressionNode::CP & arg) : + UnaryFunctionNode(ExpressionNode::UP arg) : MultiArgFunctionNode() { - appendArg(arg); + appendArg(std::move(arg)); } protected: const ExpressionNode & getArg() const { return MultiArgFunctionNode::getArg(0); } diff --git a/searchlib/src/vespa/searchlib/expression/xorbitfunctionnode.h b/searchlib/src/vespa/searchlib/expression/xorbitfunctionnode.h index b8d00b6ebdb..4ddc5bd7d7b 100644 --- a/searchlib/src/vespa/searchlib/expression/xorbitfunctionnode.h +++ b/searchlib/src/vespa/searchlib/expression/xorbitfunctionnode.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/expression/unarybitfunctionnode.h> +#include "unarybitfunctionnode.h" namespace search { namespace expression { @@ -11,11 +11,11 @@ class XorBitFunctionNode : public UnaryBitFunctionNode public: DECLARE_EXPRESSIONNODE(XorBitFunctionNode); XorBitFunctionNode() { } - XorBitFunctionNode(const ExpressionNode::CP & arg, unsigned numBits); + XorBitFunctionNode(ExpressionNode::UP arg, unsigned numBits); private: mutable std::vector<uint8_t> _tmpXor; - virtual bool internalExecute(const vespalib::nbostream & os) const; - virtual void onPrepareResult(); + bool internalExecute(const vespalib::nbostream & os) const override; + void onPrepareResult() override; }; } diff --git a/searchlib/src/vespa/searchlib/expression/zcurve.h b/searchlib/src/vespa/searchlib/expression/zcurve.h index 88d2a7938a7..1f570405025 100644 --- a/searchlib/src/vespa/searchlib/expression/zcurve.h +++ b/searchlib/src/vespa/searchlib/expression/zcurve.h @@ -15,7 +15,7 @@ public: DECLARE_EXPRESSIONNODE(ZCurveFunctionNode); DECLARE_NBO_SERIALIZE; ZCurveFunctionNode() : _dim(X) { } - ZCurveFunctionNode(const ExpressionNode::CP & arg, Dimension dim) : UnaryFunctionNode(arg), _dim(dim) { } + ZCurveFunctionNode(ExpressionNode::UP arg, Dimension dim) : UnaryFunctionNode(std::move(arg)), _dim(dim) { } ZCurveFunctionNode(const ZCurveFunctionNode & rhs); ZCurveFunctionNode & operator = (const ZCurveFunctionNode & rhs); Dimension getDim() const { return _dim; } diff --git a/searchlib/src/vespa/searchlib/grouping/collect.h b/searchlib/src/vespa/searchlib/grouping/collect.h index 63b0950c460..a3bee9e9630 100644 --- a/searchlib/src/vespa/searchlib/grouping/collect.h +++ b/searchlib/src/vespa/searchlib/grouping/collect.h @@ -1,7 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/grouping/groupref.h> +#include "groupref.h" #include <vespa/searchlib/aggregation/group.h> namespace search { diff --git a/searchlib/src/vespa/searchlib/grouping/groupingengine.cpp b/searchlib/src/vespa/searchlib/grouping/groupingengine.cpp index ec34af16662..a8f12ce9fd4 100644 --- a/searchlib/src/vespa/searchlib/grouping/groupingengine.cpp +++ b/searchlib/src/vespa/searchlib/grouping/groupingengine.cpp @@ -65,7 +65,7 @@ GroupingEngine::fillRootRequest(const Group & r) { _rootRequestLevel.setMaxGroups(1).setPresicion(1).freeze(); for (size_t i(0), m(r.getAggrSize()); i < m; i++) { - _rootRequestLevel.addResult(r.getAggregationResult(i)); + _rootRequestLevel.addResult(ExpressionNode::UP(r.getAggregationResult(i).clone())); } } diff --git a/searchlib/src/vespa/searchlib/uca/ucafunctionnode.cpp b/searchlib/src/vespa/searchlib/uca/ucafunctionnode.cpp index fa29f6f1547..59e990f6df0 100644 --- a/searchlib/src/vespa/searchlib/uca/ucafunctionnode.cpp +++ b/searchlib/src/vespa/searchlib/uca/ucafunctionnode.cpp @@ -20,8 +20,8 @@ UcaFunctionNode::~UcaFunctionNode() { } -UcaFunctionNode::UcaFunctionNode(const ExpressionNode::CP & arg, const vespalib::string & locale, const vespalib::string & strength) : - UnaryFunctionNode(arg), +UcaFunctionNode::UcaFunctionNode(ExpressionNode::UP arg, const vespalib::string & locale, const vespalib::string & strength) : + UnaryFunctionNode(std::move(arg)), _locale(locale), _strength(strength), _collator(new uca::UcaConverter(locale, strength)) diff --git a/searchlib/src/vespa/searchlib/uca/ucafunctionnode.h b/searchlib/src/vespa/searchlib/uca/ucafunctionnode.h index 38fc6471efa..4485caeb24d 100644 --- a/searchlib/src/vespa/searchlib/uca/ucafunctionnode.h +++ b/searchlib/src/vespa/searchlib/uca/ucafunctionnode.h @@ -17,7 +17,7 @@ public: DECLARE_NBO_SERIALIZE; UcaFunctionNode(); ~UcaFunctionNode(); - UcaFunctionNode(const ExpressionNode::CP & arg, const vespalib::string & locale, const vespalib::string & strength); + UcaFunctionNode(ExpressionNode::UP arg, const vespalib::string & locale, const vespalib::string & strength); UcaFunctionNode(const UcaFunctionNode & rhs); UcaFunctionNode & operator = (const UcaFunctionNode & rhs); private: |