summaryrefslogtreecommitdiffstats
path: root/searchlib/src/tests/aggregator
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /searchlib/src/tests/aggregator
Publish
Diffstat (limited to 'searchlib/src/tests/aggregator')
-rw-r--r--searchlib/src/tests/aggregator/.gitignore7
-rw-r--r--searchlib/src/tests/aggregator/CMakeLists.txt15
-rw-r--r--searchlib/src/tests/aggregator/DESC1
-rw-r--r--searchlib/src/tests/aggregator/FILES1
-rw-r--r--searchlib/src/tests/aggregator/attr_test.cpp285
-rw-r--r--searchlib/src/tests/aggregator/perdocexpr.cpp1693
6 files changed, 2002 insertions, 0 deletions
diff --git a/searchlib/src/tests/aggregator/.gitignore b/searchlib/src/tests/aggregator/.gitignore
new file mode 100644
index 00000000000..fed1175d7cd
--- /dev/null
+++ b/searchlib/src/tests/aggregator/.gitignore
@@ -0,0 +1,7 @@
+*.dat
+.depend
+Makefile
+aggregator_test
+perdocexpr_test
+searchlib_attr_test_app
+searchlib_perdocexpr_test_app
diff --git a/searchlib/src/tests/aggregator/CMakeLists.txt b/searchlib/src/tests/aggregator/CMakeLists.txt
new file mode 100644
index 00000000000..1cc750a8fac
--- /dev/null
+++ b/searchlib/src/tests/aggregator/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+vespa_add_executable(searchlib_perdocexpr_test_app
+ SOURCES
+ perdocexpr.cpp
+ DEPENDS
+ searchlib
+)
+vespa_add_test(NAME searchlib_perdocexpr_test_app COMMAND searchlib_perdocexpr_test_app)
+vespa_add_executable(searchlib_attr_test_app
+ SOURCES
+ attr_test.cpp
+ DEPENDS
+ searchlib
+)
+vespa_add_test(NAME searchlib_attr_test_app COMMAND searchlib_attr_test_app)
diff --git a/searchlib/src/tests/aggregator/DESC b/searchlib/src/tests/aggregator/DESC
new file mode 100644
index 00000000000..74bbb4a99fe
--- /dev/null
+++ b/searchlib/src/tests/aggregator/DESC
@@ -0,0 +1 @@
+This is a test of the aggregator manager interface.
diff --git a/searchlib/src/tests/aggregator/FILES b/searchlib/src/tests/aggregator/FILES
new file mode 100644
index 00000000000..2d49a798a26
--- /dev/null
+++ b/searchlib/src/tests/aggregator/FILES
@@ -0,0 +1 @@
+aggregator.cpp
diff --git a/searchlib/src/tests/aggregator/attr_test.cpp b/searchlib/src/tests/aggregator/attr_test.cpp
new file mode 100644
index 00000000000..5184f61b573
--- /dev/null
+++ b/searchlib/src/tests/aggregator/attr_test.cpp
@@ -0,0 +1,285 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include <vespa/vespalib/testkit/test_kit.h>
+
+#include <vespa/searchlib/aggregation/perdocexpression.h>
+#include <vespa/searchlib/aggregation/aggregation.h>
+#include <vespa/searchlib/attribute/extendableattributes.h>
+#include <vespa/vespalib/objects/objectdumper.h>
+
+using namespace search;
+using namespace search::expression;
+using namespace vespalib;
+
+
+struct AttributeFixture {
+
+ AttributeGuard guard;
+
+ const double doc0attr[11] = {
+ 0.1428571428571428,
+ 0.2539682539682539,
+ 0.3448773448773448,
+ 0.4218004218004217,
+ 0.4884670884670883,
+ 0.5472906178788530,
+ 0.5999221968262214,
+ 0.6475412444452690,
+ 0.6910195053148342,
+ 0.7310195053148342,
+ 0.7680565423518712
+ };
+ const double doc1attr[11] = {
+ 0.1408450704225352,
+ 0.2507351803126450,
+ 0.3408252704027350,
+ 0.4171611482653304,
+ 0.4833863138282443,
+ 0.5418658459919869,
+ 0.5942218669343952,
+ 0.6416152318633051,
+ 0.6849052751533483,
+ 0.7247459126035475,
+ 0.7616462816072375
+ };
+
+ AttributeFixture() : guard()
+ {
+ MultiFloatExtAttribute *attr = new MultiFloatExtAttribute("sortedArrayAttr");
+ DocId d = 0;
+
+ attr->addDoc(d);
+ for (double val : doc0attr) {
+ attr->add(val);
+ }
+ attr->addDoc(d);
+ for (double val : doc1attr) {
+ attr->add(val);
+ }
+ AttributeVector::SP sp(attr);
+ guard = AttributeGuard(sp);
+ }
+};
+
+struct IntAttrFixture {
+ AttributeGuard guard;
+
+ const int64_t doc0attr[11] = {
+ 1,
+ 333,
+ 88888888L,
+ -17
+ };
+ const double doc1attr[11] = {
+ 2,
+ -42,
+ 4444,
+ 999999999L
+ };
+
+ IntAttrFixture() : guard()
+ {
+ MultiIntegerExtAttribute *attr = new MultiIntegerExtAttribute("sortedArrayAttr");
+ DocId d = 0;
+ attr->addDoc(d);
+ for (int64_t val : doc0attr) {
+ attr->add(val);
+ }
+ attr->addDoc(d);
+ for (int64_t val : doc1attr) {
+ attr->add(val);
+ }
+ AttributeVector::SP sp(attr);
+ guard = AttributeGuard(sp);
+ }
+};
+
+struct StringAttrFixture {
+ AttributeGuard guard;
+ StringAttrFixture() : guard()
+ {
+ MultiStringExtAttribute *attr = new MultiStringExtAttribute("sortedArrayAttr");
+ DocId d = 0;
+ attr->addDoc(d);
+ attr->add("1");
+ attr->add("333");
+ attr->add("88888888");
+ attr->addDoc(d);
+ attr->add("2");
+ attr->add("4444");
+ attr->add("999999999");
+ AttributeVector::SP sp(attr);
+ guard = AttributeGuard(sp);
+ }
+};
+
+
+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::Configure treeConf;
+ et.select(treeConf, treeConf);
+ EXPECT_TRUE(et.getResult().getClass().inherits(FloatResultNode::classId));
+
+ EXPECT_TRUE(et.execute(0, HitRank(0.0)));
+ EXPECT_EQUAL(et.getResult().getFloat(), f1.doc0attr[i]);
+ EXPECT_TRUE(et.execute(1, HitRank(0.0)));
+ EXPECT_EQUAL(et.getResult().getFloat(), f1.doc1attr[i]);
+ }
+}
+
+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);
+ *x = *y;
+ delete y;
+ ExpressionNode::CP ln(x);
+
+ ExpressionTree et(ln);
+ ExpressionTree::Configure treeConf;
+ et.select(treeConf, treeConf);
+ EXPECT_TRUE(et.getResult().getClass().inherits(IntegerResultNode::classId));
+
+ EXPECT_TRUE(et.execute(0, HitRank(0.0)));
+ EXPECT_EQUAL(et.getResult().getInteger(), f1.doc0attr[i]);
+ EXPECT_TRUE(et.execute(1, HitRank(0.0)));
+ EXPECT_EQUAL(et.getResult().getInteger(), f1.doc1attr[i]);
+ }
+}
+
+
+TEST_F("testArrayAtString", StringAttrFixture()) {
+ ExpressionNode::CP cn(new ConstantNode(new Int64ResultNode(1)));
+ ExpressionNode::CP ln(new ArrayAtLookup(*f1.guard, cn));
+
+ ExpressionTree et(ln);
+ ExpressionTree::Configure treeConf;
+ et.select(treeConf, treeConf);
+ EXPECT_TRUE(et.getResult().getClass().inherits(StringResultNode::classId));
+
+ char mem[64];
+ ResultNode::BufferRef buf(&mem, sizeof(mem));
+
+ EXPECT_TRUE(et.execute(0, HitRank(0.0)));
+ EXPECT_EQUAL(et.getResult().getString(buf).c_str(), std::string("333"));
+
+ EXPECT_TRUE(et.execute(1, HitRank(0.0)));
+ EXPECT_EQUAL(et.getResult().getString(buf).c_str(), std::string("4444"));
+}
+
+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)
+ {
+ ExpressionTree::Configure treeConf;
+ et.select(treeConf, treeConf);
+ }
+};
+
+
+TEST_F("testArrayAtBelowRange", ArrayAtExpressionFixture(-1)) {
+ EXPECT_TRUE(f1.et.getResult().getClass().inherits(FloatResultNode::classId));
+
+ EXPECT_TRUE(f1.et.execute(0, HitRank(0.0)));
+ EXPECT_EQUAL(f1.et.getResult().getFloat(), f1.doc0attr[0]);
+ EXPECT_TRUE(f1.et.execute(1, HitRank(0.0)));
+ EXPECT_EQUAL(f1.et.getResult().getFloat(), f1.doc1attr[0]);
+}
+
+TEST_F("testArrayAtAboveRange", ArrayAtExpressionFixture(17)) {
+ EXPECT_TRUE(f1.et.getResult().getClass().inherits(FloatResultNode::classId));
+
+ EXPECT_TRUE(f1.et.execute(0, HitRank(0.0)));
+ EXPECT_EQUAL(f1.et.getResult().getFloat(), f1.doc0attr[10]);
+ EXPECT_TRUE(f1.et.execute(1, HitRank(0.0)));
+ EXPECT_EQUAL(f1.et.getResult().getFloat(), f1.doc1attr[10]);
+}
+
+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::Configure treeConf;
+ et.select(treeConf, treeConf);
+
+ EXPECT_TRUE(et.getResult().getClass().inherits(FloatResultNode::classId));
+
+ EXPECT_TRUE(et.execute(0, HitRank(0.0)));
+ EXPECT_EQUAL(et.getResult().getFloat(), 2.0);
+
+ EXPECT_TRUE(et.execute(1, HitRank(0.0)));
+ EXPECT_EQUAL(et.getResult().getFloat(), 2.053082175617388);
+}
+
+TEST_F("testWithRelevance", AttributeFixture()) {
+
+ ExpressionNode::CP r1(new RelevanceNode());
+ ExpressionNode::CP l1(new InterpolatedLookup(*f1.guard, r1));
+
+ ExpressionTree et(l1);
+ ExpressionTree::Configure treeConf;
+ et.select(treeConf, treeConf);
+
+ EXPECT_TRUE(et.getResult().getClass().inherits(FloatResultNode::classId));
+
+ // docid 0
+ double expect0[] = { 0.0, 0.0, 0.0,
+
+ 0.514285714285715012,
+ 1.506349206349207659,
+ 2.716594516594518005,
+
+ 4.19605949605949835,
+ 6.001633866649353166,
+ 8.224512367129145574,
+
+ 10.0, 10.0, 10.0 };
+
+ for (int i = 0; i < 12; i++) {
+ double r = i-1;
+ r *= 0.1;
+ TEST_STATE(vespalib::make_string("i=%d", i).c_str());
+ EXPECT_TRUE(et.execute(0, HitRank(r)));
+ EXPECT_EQUAL(expect0[i], et.getResult().getFloat());
+ }
+
+ EXPECT_TRUE(et.execute(0, HitRank(f1.doc0attr[2])));
+ EXPECT_EQUAL(et.getResult().getFloat(), 2.0);
+
+ // docid 1
+ EXPECT_TRUE(et.execute(1, HitRank(f1.doc1attr[0] - 0.001)));
+ EXPECT_EQUAL(et.getResult().getFloat(), 0.0);
+
+ EXPECT_TRUE(et.execute(1, HitRank(f1.doc1attr[0])));
+ EXPECT_EQUAL(et.getResult().getFloat(), 0.0);
+
+ EXPECT_TRUE(et.execute(1, HitRank(f1.doc1attr[2])));
+ EXPECT_EQUAL(et.getResult().getFloat(), 2.0);
+
+ EXPECT_TRUE(et.execute(1, HitRank(f1.doc1attr[4])));
+ EXPECT_EQUAL(et.getResult().getFloat(), 4.0);
+
+ EXPECT_TRUE(et.execute(1, HitRank(f1.doc1attr[10])));
+ EXPECT_EQUAL(et.getResult().getFloat(), 10.0);
+
+ EXPECT_TRUE(et.execute(1, HitRank(f1.doc1attr[10] + 0.01)));
+ EXPECT_EQUAL(et.getResult().getFloat(), 10.0);
+}
+
+TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/searchlib/src/tests/aggregator/perdocexpr.cpp b/searchlib/src/tests/aggregator/perdocexpr.cpp
new file mode 100644
index 00000000000..8f073187cce
--- /dev/null
+++ b/searchlib/src/tests/aggregator/perdocexpr.cpp
@@ -0,0 +1,1693 @@
+// 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/aggregation/aggregation.h>
+#include <vespa/searchlib/aggregation/expressioncountaggregationresult.h>
+#include <vespa/searchlib/aggregation/perdocexpression.h>
+#include <vespa/searchlib/attribute/extendableattributes.h>
+#include <vespa/vespalib/objects/objectdumper.h>
+#include <vespa/vespalib/testkit/testapp.h>
+#include <stdexcept>
+#include <vespa/document/base/testdocman.h>
+#include <vespa/vespalib/util/md5.h>
+#include <vespa/vespalib/util/stringfmt.h>
+#include <vespa/searchlib/expression/getdocidnamespacespecificfunctionnode.h>
+
+using namespace search;
+using namespace search::expression;
+using namespace search::aggregation;
+using namespace vespalib;
+
+struct AggrGetter {
+ virtual ~AggrGetter() { }
+ virtual const ResultNode &operator()(const AggregationResult &r) const = 0;
+};
+
+AttributeGuard createInt64Attribute();
+AttributeGuard createInt32Attribute();
+AttributeGuard createInt16Attribute();
+AttributeGuard createInt8Attribute();
+template<typename T>
+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();
+ ASSERT_TRUE(func.getResult().cmp(a) == 0);
+
+ MinFunctionNode funcR;
+ funcR.appendArg(ConstantNode(b)).appendArg(ConstantNode(a)).prepare(false)
+ .execute();
+ ASSERT_TRUE(funcR.getResult().cmp(a) == 0);
+}
+
+TEST("testMin") {
+ testMin(Int64ResultNode(67), Int64ResultNode(68));
+ testMin(FloatResultNode(67), FloatResultNode(68));
+ testMin(StringResultNode("67"), StringResultNode("68"));
+ testMin(RawResultNode("67", 2), RawResultNode("68", 2));
+ testMin(RawResultNode("-67", 2), RawResultNode("68", 2));
+}
+
+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)
+ .execute();
+ ASSERT_TRUE(func.getResult().cmp(b) == 0);
+
+ MaxFunctionNode funcR;
+ funcR.appendArg(ConstantNode(b)).appendArg(ConstantNode(a)).prepare(false)
+ .execute();
+ ASSERT_TRUE(funcR.getResult().cmp(b) == 0);
+}
+
+TEST("testMax") {
+ testMax(Int64ResultNode(67), Int64ResultNode(68));
+ testMax(FloatResultNode(67), FloatResultNode(68));
+ testMax(StringResultNode("67"), StringResultNode("68"));
+ testMax(RawResultNode("67", 2), RawResultNode("68", 2));
+ testMax(RawResultNode("-67", 2), RawResultNode("68", 2));
+}
+
+ExpressionCountAggregationResult getExpressionCountWithNormalSketch() {
+ nbostream stream;
+ stream << (uint32_t)ExpressionCountAggregationResult::classId
+ << (char)0 << (uint32_t)0
+ << (uint32_t)NormalSketch<>::classId
+ << NormalSketch<>::BUCKET_COUNT << NormalSketch<>::BUCKET_COUNT;
+ for (size_t i = 0; i < NormalSketch<>::BUCKET_COUNT; ++i) {
+ stream << static_cast<char>(0);
+ }
+ NBOSerializer serializer(stream);
+ ExpressionCountAggregationResult result;
+ serializer >> result;
+ EXPECT_EQUAL(0u, stream.size());
+ EXPECT_EQUAL(NormalSketch<>(), result.getSketch());
+ return result;
+}
+
+void testExpressionCount(const ResultNode &a, uint32_t bucket, uint8_t val) {
+ ExpressionCountAggregationResult func =
+ getExpressionCountWithNormalSketch();
+ func.setExpression(ConstantNode(a));
+ 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());
+ EXPECT_EQUAL(i == bucket? val : 0, (int) normal.bucket[i]);
+ }
+}
+
+TEST("require that expression count can operate on different results") {
+ testExpressionCount(Int64ResultNode(67), 98, 2);
+ testExpressionCount(FloatResultNode(67), 545, 1);
+ testExpressionCount(StringResultNode("67"), 243, 1);
+ testExpressionCount(RawResultNode("67", 2), 243, 1);
+ testExpressionCount(RawResultNode("-67", 2), 434, 1);
+}
+
+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));
+
+ EXPECT_EQUAL(2, func1.getRank().getInteger());
+ func1.merge(func2);
+ EXPECT_EQUAL(3, func1.getRank().getInteger());
+ const auto &sketch = func1.getSketch();
+ auto normal = dynamic_cast<const NormalSketch<>&>(sketch);
+ EXPECT_EQUAL(2, normal.bucket[98]); // from func1
+ EXPECT_EQUAL(1, normal.bucket[545]); // from func2
+}
+
+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));
+
+ nbostream os;
+ NBOSerializer nos(os);
+ nos << func;
+ Identifiable::UP obj = Identifiable::create(nos);
+ auto *func2 = dynamic_cast<ExpressionCountAggregationResult *>(obj.get());
+ ASSERT_TRUE(func2);
+ EXPECT_EQUAL(func.getSketch(), func2->getSketch());
+}
+
+TEST("require that expression count estimates rank") {
+ ExpressionCountAggregationResult func =
+ getExpressionCountWithNormalSketch();
+ EXPECT_EQUAL(0, func.getRank().getInteger());
+ func.setExpression(ConstantNode(Int64ResultNode(67)))
+ .aggregate(DocId(42), HitRank(21));
+ EXPECT_EQUAL(2, func.getRank().getInteger());
+ func.setExpression(ConstantNode(FloatResultNode(67)))
+ .aggregate(DocId(42), HitRank(21));
+ EXPECT_EQUAL(3, func.getRank().getInteger());
+ func.setExpression(ConstantNode(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();
+ EXPECT_EQUAL(func.getResult().asString(), c.asString());
+ EXPECT_EQUAL(func.getResult().cmp(c), 0);
+ EXPECT_EQUAL(c.cmp(func.getResult()), 0);
+}
+
+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));
+}
+
+void testDivide(const ResultNode &a, const ResultNode &b,
+ const ResultNode &c) {
+ DivideFunctionNode func;
+ func.appendArg(ConstantNode(a)).appendArg(ConstantNode(b)).prepare(false)
+ .execute();
+ EXPECT_EQUAL(func.getResult().asString(), c.asString());
+ EXPECT_EQUAL(func.getResult().getFloat(), c.getFloat());
+ EXPECT_EQUAL(func.getResult().cmp(c), 0);
+ EXPECT_EQUAL(c.cmp(func.getResult()), 0);
+}
+
+TEST("testDivide") {
+ 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) {
+ ModuloFunctionNode func;
+ func.appendArg(ConstantNode(a)).appendArg(ConstantNode(b)).prepare(false)
+ .execute();
+ EXPECT_EQUAL(func.getResult().asString(), c.asString());
+ EXPECT_EQUAL(func.getResult().getFloat(), c.getFloat());
+ EXPECT_EQUAL(func.getResult().cmp(c), 0);
+ EXPECT_EQUAL(c.cmp(func.getResult()), 0);
+}
+
+TEST("testModulo") {
+ testModulo(Int64ResultNode(0), Int64ResultNode(6), Int64ResultNode(0));
+ testModulo(Int64ResultNode(1), Int64ResultNode(6), Int64ResultNode(1));
+ testModulo(Int64ResultNode(2), Int64ResultNode(6), Int64ResultNode(2));
+ testModulo(Int64ResultNode(3), Int64ResultNode(6), Int64ResultNode(3));
+ testModulo(Int64ResultNode(4), Int64ResultNode(6), Int64ResultNode(4));
+ testModulo(Int64ResultNode(5), Int64ResultNode(6), Int64ResultNode(5));
+ testModulo(Int64ResultNode(6), Int64ResultNode(6), Int64ResultNode(0));
+
+ testModulo(Int64ResultNode(6), Int64ResultNode(1), Int64ResultNode(0));
+ testModulo(Int64ResultNode(6), Int64ResultNode(0), Int64ResultNode(0));
+
+ testModulo(FloatResultNode(2), Int64ResultNode(6), FloatResultNode(2));
+ testModulo(Int64ResultNode(3), FloatResultNode(6), FloatResultNode(3));
+}
+
+void testNegate(const ResultNode & a, const ResultNode & b) {
+ NegateFunctionNode func;
+ func.appendArg(ConstantNode(a)).prepare(false).execute();
+ EXPECT_EQUAL(func.getResult().asString(), b.asString());
+ EXPECT_EQUAL(func.getResult().cmp(b), 0);
+ EXPECT_EQUAL(b.cmp(func.getResult()), 0);
+}
+
+TEST("testNegate") {
+ testNegate(Int64ResultNode(67), Int64ResultNode(-67));
+ testNegate(FloatResultNode(67.0), FloatResultNode(-67.0));
+
+ char strnorm[4] = { 102, 111, 111, 0 };
+ char strneg[4] = { -102, -111, -111, 0 };
+ testNegate(StringResultNode(strnorm), StringResultNode(strneg));
+ testNegate(RawResultNode(strnorm, 3), RawResultNode(strneg, 3));
+}
+
+template <typename T>
+void testBuckets(const T * b) {
+ EXPECT_TRUE(b[0].cmp(b[1]) < 0);
+ EXPECT_TRUE(b[1].cmp(b[2]) < 0);
+ EXPECT_TRUE(b[2].cmp(b[3]) < 0);
+ EXPECT_TRUE(b[3].cmp(b[4]) < 0);
+ EXPECT_TRUE(b[4].cmp(b[5]) < 0);
+
+ EXPECT_TRUE(b[1].cmp(b[0]) > 0);
+ EXPECT_TRUE(b[2].cmp(b[1]) > 0);
+ EXPECT_TRUE(b[3].cmp(b[2]) > 0);
+ EXPECT_TRUE(b[4].cmp(b[3]) > 0);
+ EXPECT_TRUE(b[5].cmp(b[4]) > 0);
+
+ EXPECT_TRUE(b[1].cmp(b[1]) == 0);
+ EXPECT_TRUE(b[2].cmp(b[2]) == 0);
+ EXPECT_TRUE(b[3].cmp(b[3]) == 0);
+ EXPECT_TRUE(b[4].cmp(b[4]) == 0);
+ EXPECT_TRUE(b[5].cmp(b[5]) == 0);
+
+ EXPECT_TRUE(b[0].contains(b[1]) < 0);
+ EXPECT_TRUE(b[1].contains(b[2]) < 0);
+ EXPECT_TRUE(b[2].contains(b[3]) == 0);
+ EXPECT_TRUE(b[3].contains(b[4]) < 0);
+ EXPECT_TRUE(b[4].contains(b[5]) < 0);
+
+ EXPECT_TRUE(b[1].contains(b[0]) > 0);
+ EXPECT_TRUE(b[2].contains(b[1]) > 0);
+ EXPECT_TRUE(b[3].contains(b[2]) == 0);
+ EXPECT_TRUE(b[4].contains(b[3]) > 0);
+ EXPECT_TRUE(b[5].contains(b[4]) > 0);
+
+ EXPECT_TRUE(b[1].contains(b[1]) == 0);
+ EXPECT_TRUE(b[2].contains(b[2]) == 0);
+ EXPECT_TRUE(b[3].contains(b[3]) == 0);
+ EXPECT_TRUE(b[4].contains(b[4]) == 0);
+ EXPECT_TRUE(b[5].contains(b[5]) == 0);
+}
+
+TEST("testBuckets") {
+ IntegerBucketResultNodeVector iv;
+ IntegerBucketResultNodeVector::Vector & ib = iv.getVector();
+ EXPECT_TRUE(iv.find(Int64ResultNode(6)) == NULL);
+ ib.resize(1);
+ ib[0] = IntegerBucketResultNode(7, 9);
+ EXPECT_TRUE(iv.find(Int64ResultNode(6)) == NULL);
+ EXPECT_TRUE(iv.find(Int64ResultNode(7)) != NULL);
+ EXPECT_TRUE(iv.find(Int64ResultNode(8)) != NULL);
+ EXPECT_TRUE(iv.find(Int64ResultNode(9)) == NULL);
+ EXPECT_TRUE(iv.find(Int64ResultNode(10)) == NULL);
+
+ ib.resize(6);
+ ib[0] = IntegerBucketResultNode(7, 9);
+ ib[1] = IntegerBucketResultNode(13, 17);
+ ib[2] = IntegerBucketResultNode(15, 30);
+ ib[3] = IntegerBucketResultNode(19, 27);
+ ib[4] = IntegerBucketResultNode(20, 33);
+ ib[5] = IntegerBucketResultNode(50, 50);
+ testBuckets(&ib[0]);
+ iv.sort();
+ testBuckets(&ib[0]);
+ EXPECT_TRUE(ib[0].contains(6) > 0);
+ EXPECT_TRUE(ib[0].contains(7) == 0);
+ EXPECT_TRUE(ib[0].contains(8) == 0);
+ EXPECT_TRUE(ib[0].contains(9) < 0);
+ EXPECT_TRUE(ib[0].contains(10) < 0);
+ EXPECT_TRUE(iv.find(Int64ResultNode(6)) == NULL);
+ EXPECT_TRUE(iv.find(Int64ResultNode(7)) != NULL);
+ EXPECT_TRUE(iv.find(Int64ResultNode(8)) != NULL);
+ EXPECT_TRUE(iv.find(Int64ResultNode(9)) == NULL);
+ EXPECT_TRUE(iv.find(Int64ResultNode(10)) == NULL);
+ EXPECT_TRUE(iv.find(Int64ResultNode(14)) != NULL);
+ EXPECT_TRUE(iv.find(Int64ResultNode(27)) != NULL);
+ EXPECT_TRUE(iv.find(Int64ResultNode(32)) != NULL);
+ EXPECT_TRUE(iv.find(Int64ResultNode(33)) == NULL);
+ EXPECT_TRUE(iv.find(Int64ResultNode(50)) == NULL);
+
+ FloatBucketResultNodeVector fv;
+ FloatBucketResultNodeVector::Vector & fb = fv.getVector();
+ fb.resize(6);
+ fb[0] = FloatBucketResultNode(7, 9);
+ fb[1] = FloatBucketResultNode(13, 17);
+ fb[2] = FloatBucketResultNode(15, 30);
+ fb[3] = FloatBucketResultNode(19, 27);
+ fb[4] = FloatBucketResultNode(20, 33);
+ fb[5] = FloatBucketResultNode(50, 50);
+ testBuckets(&fb[0]);
+ fv.sort();
+ testBuckets(&fb[0]);
+ EXPECT_TRUE(fb[0].contains(6) > 0);
+ EXPECT_TRUE(fb[0].contains(7) == 0);
+ EXPECT_TRUE(fb[0].contains(8) == 0);
+ EXPECT_TRUE(fb[0].contains(9) < 0);
+ EXPECT_TRUE(fb[0].contains(10) < 0);
+ EXPECT_TRUE(fv.find(FloatResultNode(6)) == NULL);
+ EXPECT_TRUE(fv.find(FloatResultNode(7)) != NULL);
+ EXPECT_TRUE(fv.find(FloatResultNode(8)) != NULL);
+ EXPECT_TRUE(fv.find(FloatResultNode(9)) == NULL);
+ EXPECT_TRUE(fv.find(FloatResultNode(10)) == NULL);
+ EXPECT_TRUE(fv.find(FloatResultNode(14)) != NULL);
+ EXPECT_TRUE(fv.find(FloatResultNode(27)) != NULL);
+ EXPECT_TRUE(fv.find(FloatResultNode(32)) != NULL);
+ EXPECT_TRUE(fv.find(FloatResultNode(33)) == NULL);
+ EXPECT_TRUE(fv.find(FloatResultNode(50)) == NULL);
+
+ StringBucketResultNodeVector sv;
+ StringBucketResultNodeVector::Vector & sb = sv.getVector();
+ sb.resize(6);
+ sb[0] = StringBucketResultNode("07", "09");
+ sb[1] = StringBucketResultNode("13", "17");
+ sb[2] = StringBucketResultNode("15", "30");
+ sb[3] = StringBucketResultNode("19", "27");
+ sb[4] = StringBucketResultNode("20", "33");
+ sb[5] = StringBucketResultNode("50", "50");
+ testBuckets(&sb[0]);
+ sv.sort();
+ testBuckets(&sb[0]);
+ EXPECT_TRUE(sb[0].contains("06") > 0);
+ EXPECT_TRUE(sb[0].contains("07") == 0);
+ EXPECT_TRUE(sb[0].contains("08") == 0);
+ EXPECT_TRUE(sb[0].contains("09") < 0);
+ EXPECT_TRUE(sb[0].contains("10") < 0);
+ EXPECT_TRUE(sv.find(StringResultNode("06")) == NULL);
+ EXPECT_TRUE(sv.find(StringResultNode("07")) != NULL);
+ EXPECT_TRUE(sv.find(StringResultNode("08")) != NULL);
+ EXPECT_TRUE(sv.find(StringResultNode("09")) == NULL);
+ EXPECT_TRUE(sv.find(StringResultNode("10")) == NULL);
+ EXPECT_TRUE(sv.find(StringResultNode("14")) != NULL);
+ EXPECT_TRUE(sv.find(StringResultNode("27")) != NULL);
+ EXPECT_TRUE(sv.find(StringResultNode("32")) != NULL);
+ EXPECT_TRUE(sv.find(StringResultNode("33")) == NULL);
+ EXPECT_TRUE(sv.find(StringResultNode("50")) == NULL);
+}
+
+template<typename T>
+void testCmp(const T & small, const T & medium, const T & large) {
+ EXPECT_TRUE(small.cmp(medium) < 0);
+ EXPECT_TRUE(small.cmp(large) < 0);
+ EXPECT_TRUE(medium.cmp(large) < 0);
+ EXPECT_TRUE(medium.cmp(small) > 0);
+ EXPECT_TRUE(large.cmp(small) > 0);
+ EXPECT_TRUE(large.cmp(medium) > 0);
+}
+
+TEST("testResultNodes") {
+ Int64ResultNode i(89);
+ char mem[64];
+ ResultNode::BufferRef buf(&mem, sizeof(mem));
+ EXPECT_EQUAL(i.getInteger(), 89);
+ EXPECT_EQUAL(i.getFloat(), 89.0);
+ EXPECT_EQUAL(i.getString(buf).c_str(), std::string("89"));
+ FloatResultNode f(2165.798);
+ EXPECT_EQUAL(f.getInteger(), 2166);
+ EXPECT_EQUAL(f.getFloat(), 2165.798);
+ EXPECT_EQUAL(f.getString(buf).c_str(), std::string("2165.8"));
+ StringResultNode s("17.89hjkljly");
+ EXPECT_EQUAL(s.getInteger(), 17);
+ EXPECT_EQUAL(s.getFloat(), 17.89);
+ EXPECT_EQUAL(s.getString(buf).c_str(), std::string("17.89hjkljly"));
+ RawResultNode r("hjgasfdg", 9);
+ EXPECT_EQUAL(r.getString(buf).c_str(), std::string("hjgasfdg"));
+ int64_t j(789);
+ double d(786324.78);
+ nbostream os;
+ os << j << d;
+ RawResultNode r1(os.c_str(), sizeof(j));
+ EXPECT_EQUAL(r1.getInteger(), 789);
+ RawResultNode r2(os.c_str() + sizeof(j), sizeof(d));
+ EXPECT_EQUAL(r2.getFloat(), 786324.78);
+
+ StringResultNode s1, s2("a"), s3("a"), s4("b"), s5("bb");
+ EXPECT_EQUAL(s1.cmp(s1), 0);
+ EXPECT_EQUAL(s2.cmp(s3), 0);
+ EXPECT_EQUAL(s4.cmp(s4), 0);
+ EXPECT_EQUAL(s5.cmp(s5), 0);
+ testCmp(s1, s2, s4);
+ testCmp(s1, s2, s5);
+ testCmp(s2, s4, s5);
+
+ {
+ Int64ResultNode i1(-1), i2(0), i3(1), i4(0x80000000lu);
+ EXPECT_EQUAL(i1.cmp(i1), 0);
+ EXPECT_EQUAL(i2.cmp(i2), 0);
+ EXPECT_EQUAL(i3.cmp(i3), 0);
+ testCmp(i1, i2, i3);
+ testCmp(i1, i2, i4);
+ }
+
+ {
+ FloatResultNode i1(-1), i2(0), i3(1), notanumber(nan("")),
+ minusInf(-INFINITY), plussInf(INFINITY);
+ EXPECT_EQUAL(i1.cmp(i1), 0);
+ EXPECT_EQUAL(i2.cmp(i2), 0);
+ EXPECT_EQUAL(i3.cmp(i3), 0);
+ EXPECT_EQUAL(minusInf.cmp(minusInf), 0);
+ EXPECT_EQUAL(plussInf.cmp(plussInf), 0);
+ EXPECT_EQUAL(notanumber.cmp(notanumber), 0);
+ testCmp(i1, i2, i3);
+ testCmp(minusInf, i1, plussInf);
+ testCmp(minusInf, i2, plussInf);
+ testCmp(minusInf, i3, plussInf);
+ testCmp(notanumber, i2, i3);
+ testCmp(notanumber, i2, plussInf);
+ testCmp(notanumber, minusInf, plussInf);
+ }
+ {
+ FloatBucketResultNode
+ i1(-1, 3), i2(188000, 188500), i3(1630000, 1630500),
+ notanumber(-nan(""), nan("")), inf(-INFINITY, INFINITY);
+ EXPECT_EQUAL(i1.cmp(i1), 0);
+ EXPECT_EQUAL(i2.cmp(i2), 0);
+ EXPECT_EQUAL(notanumber.cmp(notanumber), 0);
+ EXPECT_EQUAL(inf.cmp(inf), 0);
+
+ testCmp(i1, i2, i3);
+ testCmp(inf, i1, i2);
+ testCmp(notanumber, i2, i3);
+ testCmp(notanumber, i1, i2);
+ testCmp(notanumber, inf, i1);
+ }
+}
+
+void testStreaming(const Identifiable &v) {
+ nbostream os;
+ NBOSerializer nos(os);
+ nos << v;
+ Identifiable::UP s = Identifiable::create(nos);
+ ASSERT_TRUE(s.get() != NULL);
+ ASSERT_TRUE(v.cmp(*s) == 0);
+ nbostream os2, os3;
+ NBOSerializer nos2(os2), nos3(os3);
+ nos2 << v;
+ nos3 << *s;
+
+ EXPECT_EQUAL(os2.size(), os3.size());
+ ASSERT_TRUE(os2.size() == os3.size());
+ EXPECT_EQUAL(0, memcmp(os2.c_str(), os3.c_str(), os3.size()));
+}
+
+TEST("testTimeStamp") {
+ TimeStampFunctionNode t1;
+ testStreaming(t1);
+}
+
+namespace {
+
+std::string
+getVespaChecksumV2(
+ const std::string& ymumid,
+ int fid,
+ const std::string& flags_str)
+{
+ if (fid == 6 || fid == 0 || fid == 5) {
+ return 0;
+ }
+
+ std::list<char> flags_list;
+ flags_list.clear();
+ for (unsigned int i = 0; i< flags_str.length();i++)
+ if (isalpha(flags_str[i]))
+ flags_list.push_back(flags_str[i]);
+ flags_list.sort();
+
+ std::string new_flags_str ="";
+ std::list<char>::iterator it;
+ for (it = flags_list.begin();it!=flags_list.end();it++)
+ new_flags_str += *it;
+
+ uint32_t networkFid = htonl(fid);
+
+ int length = ymumid.length()+
+ sizeof(networkFid)+
+ new_flags_str.length();
+
+ unsigned char buffer[length];
+ memset(buffer, 0x00, length);
+ memcpy(buffer, ymumid.c_str(), ymumid.length());
+ memcpy(buffer + ymumid.length(),
+ (const char*)&networkFid, sizeof(networkFid));
+ memcpy(buffer+ymumid.length()+sizeof(networkFid), new_flags_str.c_str(),
+ new_flags_str.length());
+
+ return std::string((char*)buffer, length);
+}
+} // namespace
+
+TEST("testMailChecksumExpression") {
+ document::TestDocMan testDocMan;
+
+ int folder = 32;
+ 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());
+
+ for (uint32_t i = 0; i < flags.size(); i++) {
+ ws.add(document::ByteFieldValue(flags[i]));
+ }
+ doc->setValue("headerval", document::IntFieldValue(folder));
+ doc->setValue("byteweightedset", ws);
+
+ CatFunctionNode e;
+
+ // YMUMID
+ GetDocIdNamespaceSpecificFunctionNode* ns =
+ new GetDocIdNamespaceSpecificFunctionNode(
+ ResultNode::UP(new StringResultNode));
+ e.appendArg(ExpressionNode::CP(ns));
+
+ // Folder
+ e.appendArg(DocumentFieldNode("headerval"));
+
+ // Flags
+ e.appendArg(SortFunctionNode(DocumentFieldNode("byteweightedset")));
+
+ MD5BitFunctionNode node(e, 32);
+
+ 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());
+ 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();
+ for (uint32_t j = 0; j < se.size(); j++) {
+ DocumentAccessorNode* tf =
+ dynamic_cast<DocumentAccessorNode *>(se[j].get());
+ tf->setDocType(doc->getType());
+ tf->prepare(true);
+ tf->setDoc(*doc);
+ }
+ }
+ }
+ // SortFunctionNode & sfn = static_cast<SortFunctionNode&>(*xe[1]);
+ // sfn.prepare(false);
+ cfn.prepare(false);
+
+ cfn.execute();
+ ConstBufferRef ref =
+ static_cast<const RawResultNode &>(cfn.getResult()).get();
+
+ std::string cmp = getVespaChecksumV2(ymumid, folder, flags);
+
+ EXPECT_EQUAL(ref.size(), 14u);
+ EXPECT_EQUAL(cmp.size(), ref.size());
+
+ for (uint32_t i = 0; i < ref.size(); i++) {
+ std::cerr << i << ": " << (int)ref.c_str()[i] << "/" << (int)cmp[i]
+ << "\n";
+ }
+
+ EXPECT_TRUE(memcmp(cmp.c_str(), ref.c_str(), cmp.size()) == 0);
+
+ node.prepare(true);
+ node.execute();
+
+ ConstBufferRef ref2 =
+ static_cast<const RawResultNode &>(node.getResult()).get();
+
+ for (uint32_t i = 0; i < ref2.size(); i++) {
+ std::cerr << i << ": " << (int)ref2.c_str()[i] << "\n";
+ }
+}
+
+TEST("testDebugFunction") {
+ {
+ AddFunctionNode add;
+ add.appendArg(ConstantNode(Int64ResultNode(3)));
+ add.appendArg(ConstantNode(Int64ResultNode(4)));
+ DebugWaitFunctionNode n(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);
+ }
+ {
+ AddFunctionNode add;
+ add.appendArg(ConstantNode(Int64ResultNode(3)));
+ add.appendArg(ConstantNode(Int64ResultNode(4)));
+ DebugWaitFunctionNode n(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);
+ }
+}
+
+TEST("testDivExpressions") {
+ {
+ StrLenFunctionNode e(ConstantNode(Int64ResultNode(238686)));
+ e.prepare(false);
+ e.execute();
+ EXPECT_EQUAL(static_cast<const Int64ResultNode &>(e.getResult()).get(),
+ 6);
+ }
+ {
+ NormalizeSubjectFunctionNode
+ e(ConstantNode(StringResultNode("Re: Your mail")));
+ e.prepare(false);
+ e.execute();
+ EXPECT_EQUAL(
+ static_cast<const StringResultNode &>(e.getResult()).get(),
+ "Your mail");
+ }
+ {
+ NormalizeSubjectFunctionNode
+ e(ConstantNode(StringResultNode("Your mail")));
+ e.prepare(false);
+ e.execute();
+ EXPECT_EQUAL(
+ static_cast<const StringResultNode &>(e.getResult()).get(),
+ "Your mail");
+ }
+ {
+ StrCatFunctionNode e(ConstantNode(Int64ResultNode(238686)));
+ e.appendArg(ConstantNode(StringResultNode("ARG 2")));
+ e.prepare(false);
+ e.execute();
+ EXPECT_EQUAL(
+ static_cast<const StringResultNode &>(e.getResult()).get(),
+ "238686ARG 2");
+ }
+
+ {
+ ToStringFunctionNode e(ConstantNode(Int64ResultNode(238686)));
+ e.prepare(false);
+ e.execute();
+ EXPECT_EQUAL(strcmp(static_cast<const StringResultNode &>(
+ e.getResult()).get().c_str(), "238686"), 0);
+ }
+
+ {
+ ToRawFunctionNode e(ConstantNode(Int64ResultNode(238686)));
+ e.prepare(false);
+ e.execute();
+ EXPECT_EQUAL(strcmp(static_cast<const RawResultNode &>(
+ e.getResult()).get().c_str(), "238686"), 0);
+ }
+
+ {
+ CatFunctionNode e(ConstantNode(Int64ResultNode(238686)));
+ e.prepare(false);
+ e.execute();
+ EXPECT_EQUAL(
+ static_cast<const RawResultNode &>(e.getResult()).get().size(),
+ 8u);
+ }
+ {
+ CatFunctionNode e(ConstantNode(Int32ResultNode(23886)));
+ e.prepare(false);
+ e.execute();
+ 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);
+ e.prepare(false);
+ e.execute();
+ ASSERT_TRUE(e.getResult().getClass().inherits(RawResultNode::classId));
+ 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);
+ e.prepare(false);
+ e.execute();
+ 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);
+ 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);
+ }
+ {
+ const uint8_t buf[4] = { 6, 0, 7, 7 };
+ XorBitFunctionNode
+ e(ConstantNode(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);
+ }
+ {
+ const uint8_t wantedBuf[14] =
+ { 98, 97, 114, 109, 117, 100, 97, 0, 0, 0, 32, 65, 82, 87 };
+ const uint8_t md5facit[16] =
+ { 0x22, 0x5, 0x22, 0x1c, 0x49, 0xff, 0x90, 0x25, 0xad, 0xbf,
+ 0x4e, 0x51, 0xdb, 0xca, 0x2a, 0xc5 };
+ const uint8_t thomasBuf[22] =
+ { 0, 0, 0, 7, 98, 97, 114, 109, 117, 100, 97, 0, 0, 0, 32, 0,
+ 0, 0, 3, 65, 82, 87 };
+ const uint8_t currentBuf[26] =
+ { 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);
+ e.prepare(false);
+ e.execute();
+ ASSERT_TRUE(e.getResult().getClass().inherits(RawResultNode::classId));
+ 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);
+ EXPECT_TRUE(memcmp(r.get().data(), md5, sizeof(md5)) != 0);
+ fastc_md5sum(wantedBuf, sizeof(wantedBuf), md5);
+ EXPECT_TRUE(memcmp(r.get().data(), md5, sizeof(md5)) == 0);
+ 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);
+ finalCheck.prepare(false);
+ finalCheck.execute();
+ 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)));
+ e.prepare(false);
+ e.execute();
+ EXPECT_EQUAL(
+ static_cast<const RawResultNode &>(e.getResult()).get().size(),
+ 2u);
+ }
+ {
+ CatFunctionNode
+ e(ConstantNode(Int8ResultNodeVector().push_back(Int8ResultNode(86))
+ .push_back(Int8ResultNode(14))));
+ e.prepare(false);
+ e.execute();
+ EXPECT_EQUAL(
+ static_cast<const RawResultNode &>(e.getResult()).get().size(),
+ 1*2u);
+ }
+ {
+ CatFunctionNode
+ e(ConstantNode(Int32ResultNodeVector()
+ .push_back(Int32ResultNode(238686))
+ .push_back(Int32ResultNode(2133214))));
+ e.prepare(false);
+ e.execute();
+ EXPECT_EQUAL(
+ static_cast<const RawResultNode &>(e.getResult()).get().size(),
+ 4*2u);
+ }
+ {
+ NumElemFunctionNode e(ConstantNode(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))));
+ e.prepare(false);
+ e.execute();
+ EXPECT_EQUAL(e.getResult().getInteger(), 2);
+ }
+ {
+ NumElemFunctionNode
+ e(ConstantNode(Int32ResultNodeVector()
+ .push_back(Int32ResultNode(238686))
+ .push_back(Int32ResultNode(2133214))));
+ e.prepare(false);
+ e.execute();
+ EXPECT_EQUAL(e.getResult().getInteger(), 2);
+ }
+}
+
+bool test1MultivalueExpression(const MultiArgFunctionNode &exprConst,
+ const ExpressionNode::CP &mv,
+ const ResultNode & expected) {
+ MultiArgFunctionNode & expr(const_cast<MultiArgFunctionNode &>(exprConst));
+ expr.appendArg(mv);
+ expr.prepare(false);
+ bool ok = EXPECT_TRUE(expr.execute()) &&
+ EXPECT_EQUAL(0, expr.getResult().cmp(expected));
+ if (!ok) {
+ std::cerr << "Expected:" << expected.asString() << std::endl
+ << "Got: " << expr.getResult().asString() << std::endl;
+ }
+ return ok;
+}
+
+bool test1MultivalueExpressionException(const MultiArgFunctionNode & exprConst,
+ const ExpressionNode::CP & mv,
+ const char * expected) {
+ try {
+ test1MultivalueExpression(exprConst, mv, NullResultNode());
+ return EXPECT_TRUE(false);
+ } catch (std::runtime_error & e) {
+ 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));
+
+ EXPECT_TRUE(test1MultivalueExpression(AddFunctionNode(), mv,
+ Int64ResultNode(7 + 17 + 117)));
+ EXPECT_TRUE(test1MultivalueExpression(MultiplyFunctionNode(), mv,
+ Int64ResultNode(7 * 17 * 117)));
+ EXPECT_TRUE(test1MultivalueExpressionException(DivideFunctionNode(), mv,
+ "DivideFunctionNode"));
+ EXPECT_TRUE(test1MultivalueExpressionException(ModuloFunctionNode(), mv,
+ "ModuloFunctionNode"));
+ EXPECT_TRUE(test1MultivalueExpression(MinFunctionNode(), mv,
+ Int64ResultNode(7)));
+ EXPECT_TRUE(test1MultivalueExpression(MaxFunctionNode(), mv,
+ Int64ResultNode(117)));
+
+ EXPECT_TRUE(
+ test1MultivalueExpression(
+ FixedWidthBucketFunctionNode()
+ .setWidth(Int64ResultNode(1)), mv,
+ IntegerBucketResultNodeVector()
+ .push_back(IntegerBucketResultNode(7,8))
+ .push_back(IntegerBucketResultNode(17,18))
+ .push_back(IntegerBucketResultNode(117,118))));
+
+ EXPECT_TRUE(
+ test1MultivalueExpression(
+ RangeBucketPreDefFunctionNode()
+ .setBucketList(
+ IntegerBucketResultNodeVector()
+ .push_back(IntegerBucketResultNode(0,10))
+ .push_back(IntegerBucketResultNode(20,30))
+ .push_back(IntegerBucketResultNode(100,120))),
+ mv,
+ IntegerBucketResultNodeVector()
+ .push_back(IntegerBucketResultNode(0,10))
+ .push_back(IntegerBucketResultNode(0,0))
+ .push_back(IntegerBucketResultNode(100,120))));
+
+ EXPECT_TRUE(
+ test1MultivalueExpression(
+ TimeStampFunctionNode()
+ .setTimePart(TimeStampFunctionNode::Second), mv,
+ IntegerResultNodeVector()
+ .push_back(Int64ResultNode(7))
+ .push_back(Int64ResultNode(17))
+ .push_back(Int64ResultNode(117%60))));
+
+ EXPECT_TRUE(
+ test1MultivalueExpression(NegateFunctionNode(), mv,
+ IntegerResultNodeVector()
+ .push_back(Int64ResultNode(-7))
+ .push_back(Int64ResultNode(-17))
+ .push_back(Int64ResultNode(-117))));
+ EXPECT_TRUE(test1MultivalueExpression(SortFunctionNode(), mv,
+ IntegerResultNodeVector()
+ .push_back(Int64ResultNode(7))
+ .push_back(Int64ResultNode(17))
+ .push_back(Int64ResultNode(117))));
+ EXPECT_TRUE(test1MultivalueExpression(ReverseFunctionNode(), mv,
+ IntegerResultNodeVector()
+ .push_back(Int64ResultNode(117))
+ .push_back(Int64ResultNode(17))
+ .push_back(Int64ResultNode(7))));
+ EXPECT_TRUE(test1MultivalueExpression(SortFunctionNode(),
+ ReverseFunctionNode(mv),
+ IntegerResultNodeVector()
+ .push_back(Int64ResultNode(7))
+ .push_back(Int64ResultNode(17))
+ .push_back(Int64ResultNode(117))));
+ EXPECT_TRUE(test1MultivalueExpression(AndFunctionNode(), mv,
+ Int64ResultNode(7 & 17 & 117)));
+ EXPECT_TRUE(test1MultivalueExpression(OrFunctionNode(), mv,
+ Int64ResultNode(7 | 17 | 117)));
+ EXPECT_TRUE(test1MultivalueExpression(XorFunctionNode(), mv,
+ Int64ResultNode(7 ^ 17 ^ 117)));
+}
+
+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));
+ AddFunctionNode add1;
+ add1.appendArg(i1);
+ add1.appendArg(i2);
+ ExpressionTree et(add1);
+
+ ExpressionTree::Configure treeConf;
+ et.select(treeConf, treeConf);
+
+ 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.prepare(false);
+ EXPECT_TRUE(
+ add2.getResult().getClass().inherits(FloatResultNode::classId));
+ AddFunctionNode add3;
+ add3.appendArg(i1);
+ add3.appendArg(s2);
+ add3.prepare(false);
+ EXPECT_TRUE(
+ add3.getResult().getClass().inherits(IntegerResultNode::classId));
+ AddFunctionNode add4;
+ add4.appendArg(i1);
+ add4.appendArg(r2);
+ add4.prepare(false);
+ EXPECT_TRUE(
+ add4.getResult().getClass().inherits(IntegerResultNode::classId));
+ AddFunctionNode add5;
+ add5.appendArg(i1);
+ add5.appendArg(a1);
+ add5.prepare(false);
+ EXPECT_TRUE(
+ add5.getResult().getClass().inherits(IntegerResultNode::classId));
+ AddFunctionNode add6;
+ add6.appendArg(f1);
+ add6.appendArg(a1);
+ 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());
+}
+
+void testArith2(MultiArgFunctionNode &op, int64_t intResult,
+ double floatResult) {
+ op.prepare(false);
+ op.execute();
+ EXPECT_EQUAL(intResult, op.getResult().getInteger());
+ ASSERT_TRUE(intResult == op.getResult().getInteger());
+ EXPECT_EQUAL(floatResult, op.getResult().getFloat());
+}
+
+void testAdd(const ExpressionNode::CP &arg1,
+ const ExpressionNode::CP &arg2,
+ int64_t intResult, double floatResult){
+ AddFunctionNode add;
+ testArith(add, arg1, arg2, intResult, floatResult);
+}
+
+void testMultiply(const ExpressionNode::CP & arg1,
+ const ExpressionNode::CP & arg2,
+ int64_t intResult, double floatResult) {
+ MultiplyFunctionNode add;
+ testArith(add, arg1, arg2, intResult, floatResult);
+}
+
+void testDivide(const ExpressionNode::CP & arg1,
+ const ExpressionNode::CP & arg2,
+ int64_t intResult, double floatResult) {
+ DivideFunctionNode add;
+ testArith(add, arg1, arg2, intResult, floatResult);
+}
+
+void testModulo(const ExpressionNode::CP & arg1,
+ const ExpressionNode::CP & arg2,
+ int64_t intResult, double floatResult) {
+ ModuloFunctionNode add;
+ testArith(add, arg1, 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])));
+ }
+ 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]));
+ }
+ IntegerResultNodeVector ir;
+ for (size_t i(0), m(result.size()); i<m; i++) {
+ ir.push_back(Int64ResultNode((int64_t)result[i]));
+ }
+ FloatResultNodeVector fr;
+ 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.prepare(false);
+ EXPECT_TRUE(
+ function.getResult().getClass().equal(Int64ResultNode::classId));
+ EXPECT_TRUE(function.execute());
+ EXPECT_EQUAL(function.getResult().getInteger(),
+ static_cast<int64_t>(result[0]));
+
+ function.reset();
+
+ function.appendArg(scalarInt1).appendArg(scalarFloat2);
+ function.prepare(false);
+ 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.prepare(false);
+ 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.prepare(false);
+ 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.prepare(false);
+ EXPECT_TRUE(
+ function.getResult().getClass().equal(Int64ResultNode::classId));
+ EXPECT_TRUE(function.execute());
+ EXPECT_EQUAL(function.getResult().getInteger(),
+ static_cast<int64_t>(flattenResult));
+
+ function.reset();
+
+ function.appendArg(vectorFloat1);
+ function.prepare(false);
+ 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.prepare(false);
+ 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_EQUAL(0, function.getResult().cmp(ir));
+
+ function.reset();
+
+ function.appendArg(vectorFloat1).appendArg(vectorFloat2);
+ function.prepare(false);
+ 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_EQUAL(0, function.getResult().cmp(fr));
+
+ function.reset();
+
+ function.appendArg(vectorInt1).appendArg(vectorFloat2);
+ function.prepare(false);
+ 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_EQUAL(0, function.getResult().cmp(fr));
+
+ function.reset();
+
+ function.appendArg(vectorFloat1).appendArg(vectorInt2);
+ function.prepare(false);
+ 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_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 );
+
+ std::vector<double> a(5), b(7);
+ a[0] = b[0] = 1;
+ a[1] = b[1] = 2;
+ a[2] = b[2] = 3;
+ a[3] = b[3] = 4;
+ a[4] = b[4] = 5;
+ b[5] = 6;
+ b[6] = 7;
+ std::vector<double> r(7);
+ {
+ r[0] = a[0] + b[0];
+ r[1] = a[1] + b[1];
+ r[2] = a[2] + b[2];
+ r[3] = a[3] + b[3];
+ r[4] = a[4] + b[4];
+ r[5] = a[0] + b[5];
+ r[6] = a[1] + b[6];
+ AddFunctionNode f;
+ testArithmeticArguments(f, a, b, r, a[0]+a[1]+a[2]+a[3]+a[4]);
+ }
+ {
+ r[0] = a[0] * b[0];
+ r[1] = a[1] * b[1];
+ r[2] = a[2] * b[2];
+ r[3] = a[3] * b[3];
+ r[4] = a[4] * b[4];
+ r[5] = a[0] * b[5];
+ r[6] = a[1] * b[6];
+ MultiplyFunctionNode f;
+ testArithmeticArguments(f, a, b, r, a[0]*a[1]*a[2]*a[3]*a[4]);
+ }
+}
+
+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)));
+ AggregationResult::Configure conf;
+ s->setExpression(i4).select(conf, conf);
+ s->aggregate(0, 0);
+
+ 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);
+
+ MaxAggregationResult *max = new MaxAggregationResult();
+ max->setResult(r1);
+ ExpressionNode::CP imax(max);
+ testAdd(imin, imax, 29, 29);
+
+ XorAggregationResult *x = new XorAggregationResult();
+ x->setExpression(i4).select(conf, conf);
+ x->aggregate(0, 0);
+ ExpressionNode::CP ix(x);
+ testAdd(ix, i1, 29, 29);
+
+ AverageAggregationResult *avg = new AverageAggregationResult();
+ avg->setExpression(i4).select(conf, conf);
+ avg->aggregate(0, 0);
+ ExpressionNode::CP iavg(avg);
+ testAdd(iavg, 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);
+ EXPECT_TRUE(g(aggr).getClass().equal(i.getClass().id()));
+ EXPECT_EQUAL(0, i.cmp(g(aggr)));
+ aggr.aggregate(0,0);
+ EXPECT_TRUE(g(aggr).getClass().equal(i.getClass().id()));
+ EXPECT_EQUAL(0, m.cmp(g(aggr)));
+ aggr.aggregate(1,0);
+ EXPECT_TRUE(g(aggr).getClass().equal(i.getClass().id()));
+ EXPECT_EQUAL(0, s.cmp(g(aggr)));
+}
+
+TEST("testAggregationResults") {
+ struct SumGetter : AggrGetter {
+ virtual const ResultNode &operator()(const AggregationResult & r) const
+ { return static_cast<const SumAggregationResult &>(r).getSum(); }
+ };
+ SumAggregationResult sum;
+ testAggregationResult(sum, SumGetter(), Int64ResultNode(7),
+ Int64ResultNode(0), Int64ResultNode(7),
+ Int64ResultNode(14));
+ testAggregationResult(sum, SumGetter(), FloatResultNode(7.77),
+ FloatResultNode(0), FloatResultNode(7.77),
+ FloatResultNode(15.54));
+ IntegerResultNodeVector v;
+ v.push_back(Int64ResultNode(7)).push_back(Int64ResultNode(8));
+ testAggregationResult(sum, SumGetter(), v, Int64ResultNode(0),
+ Int64ResultNode(15), Int64ResultNode(30));
+ testAggregationResult(sum, SumGetter(), FloatResultNode(7.77),
+ FloatResultNode(0), FloatResultNode(7.77),
+ FloatResultNode(15.54));
+}
+
+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));
+
+ 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);
+ 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(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(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(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(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(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(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(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(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);
+ testStreaming(grouping);
+}
+
+TEST("testGrouping2") {
+ AttributeGuard attr1 = createInt64Attribute();
+
+ RangeBucketPreDefFunctionNode *predef(
+ new RangeBucketPreDefFunctionNode(AttributeNode(*attr1)));
+ 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
+ predef->setBucketList(prevec);
+ ExpressionNode::CP select1(predef);
+ ExpressionNode::CP result1( new CountAggregationResult());
+ (static_cast<AggregationResult &>(*result1)).setExpression(select1);
+
+ Grouping grouping = Grouping()
+ .setFirstLevel(0)
+ .setLastLevel(1)
+ .addLevel(GroupingLevel()
+ .setExpression(select1)
+ .addResult(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);
+ EXPECT_EQUAL(groups[0]->getId().getInteger(), 0u);
+ 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(groups[2]->getId().getInteger(), 0u);
+ 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(groups[4]->getId().getInteger(), 0u);
+ EXPECT_EQUAL(static_cast<const CountAggregationResult &>(
+ groups[4]->getAggregationResult(0)).getCount(), 2u);
+ testStreaming(grouping);
+}
+
+AttributeGuard createInt64Attribute() {
+ SingleInt64ExtAttribute *selectAttr1(
+ new SingleInt64ExtAttribute("selectAttr1"));
+ DocId docId(0);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(7);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(6);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(13);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(11);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(27);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(17);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(13);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(34);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(67891);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(67892);
+
+ AttributeVector::SP spSelectAttr1(selectAttr1);
+ AttributeGuard attr1( spSelectAttr1 );
+ return attr1;
+}
+
+AttributeGuard createInt32Attribute() {
+ SingleInt32ExtAttribute *selectAttr1(
+ new SingleInt32ExtAttribute("selectAttr1"));
+ DocId docId(0);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(7);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(6);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(13);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(11);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(27);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(17);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(13);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(34);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(67891);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(67892);
+
+ AttributeVector::SP spSelectAttr1(selectAttr1);
+ AttributeGuard attr1( spSelectAttr1 );
+ return attr1;
+}
+
+AttributeGuard createInt16Attribute() {
+ SingleInt16ExtAttribute *selectAttr1(
+ new SingleInt16ExtAttribute("selectAttr1"));
+ DocId docId(0);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(7);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(6);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(13);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(11);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(27);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(17);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(13);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(34);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(67891);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(67892);
+
+ AttributeVector::SP spSelectAttr1(selectAttr1);
+ AttributeGuard attr1( spSelectAttr1 );
+ return attr1;
+}
+
+AttributeGuard createInt8Attribute() {
+ SingleInt8ExtAttribute *selectAttr1(
+ new SingleInt8ExtAttribute("selectAttr1"));
+ DocId docId(0);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(7);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(6);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(13);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(11);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(27);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(17);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(13);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(34);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(67891);
+ selectAttr1->addDoc(docId);
+ selectAttr1->add(67892);
+
+ AttributeVector::SP spSelectAttr1(selectAttr1);
+ AttributeGuard attr1( spSelectAttr1 );
+ return attr1;
+}
+
+TEST("testIntegerTypes") {
+ EXPECT_EQUAL(AttributeNode(*createInt8Attribute()).prepare(false)
+ .getResult().getClass().id(),
+ uint32_t(Int64ResultNode::classId));
+ EXPECT_EQUAL(AttributeNode(*createInt8Attribute())
+ .prepare(true).getResult().getClass().id(),
+ uint32_t(Int8ResultNode::classId));
+ EXPECT_EQUAL(AttributeNode(*createInt16Attribute())
+ .prepare(false).getResult().getClass().id(),
+ uint32_t(Int64ResultNode::classId));
+ EXPECT_EQUAL(AttributeNode(*createInt16Attribute())
+ .prepare(true).getResult().getClass().id(),
+ uint32_t(Int16ResultNode::classId));
+ EXPECT_EQUAL(AttributeNode(*createInt32Attribute())
+ .prepare(false).getResult().getClass().id(),
+ uint32_t(Int64ResultNode::classId));
+ EXPECT_EQUAL(AttributeNode(*createInt32Attribute())
+ .prepare(true).getResult().getClass().id(),
+ uint32_t(Int32ResultNode::classId));
+ EXPECT_EQUAL(AttributeNode(*createInt64Attribute())
+ .prepare(false).getResult().getClass().id(),
+ uint32_t(Int64ResultNode::classId));
+ EXPECT_EQUAL(AttributeNode(*createInt64Attribute())
+ .prepare(true).getResult().getClass().id(),
+ uint32_t(Int64ResultNode::classId));
+
+ 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"))))
+ .prepare(true).getResult().getClass().id(),
+ uint32_t(Int8ResultNodeVector::classId));
+ 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"))))
+ .prepare(true).getResult().getClass().id(),
+ uint32_t(Int16ResultNodeVector::classId));
+ 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"))))
+ .prepare(true).getResult().getClass().id(),
+ uint32_t(Int32ResultNodeVector::classId));
+ 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"))))
+ .prepare(true).getResult().getClass().id(),
+ uint32_t(Int64ResultNodeVector::classId));
+}
+
+TEST("testStreamingAll") {
+ testStreaming(Int64ResultNode(89));
+ testStreaming(FloatResultNode(89.765));
+ testStreaming(StringResultNode("Tester StringResultNode streaming"));
+ testStreaming(RawResultNode("Tester RawResultNode streaming", 30));
+ testStreaming(CountAggregationResult());
+ testStreaming(ExpressionCountAggregationResult());
+ testStreaming(SumAggregationResult());
+ testStreaming(MinAggregationResult());
+ testStreaming(MaxAggregationResult());
+ testStreaming(AverageAggregationResult());
+ testStreaming(Group());
+ testStreaming(Grouping());
+ testStreaming(HitsAggregationResult());
+}
+
+TEST_MAIN() { TEST_RUN_ALL(); }