aboutsummaryrefslogtreecommitdiffstats
path: root/searchcore
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@broadpark.no>2018-05-11 17:05:14 +0200
committerGitHub <noreply@github.com>2018-05-11 17:05:14 +0200
commitcf80ff1b7ce08cd3fdfd8c789de45da02ffba5c9 (patch)
tree9f05557299f2298c5ea83aa7bbeb37c68c357786 /searchcore
parentf1f7f139fab32fef7a541402c75039d0794e30eb (diff)
parent3e602411fe15e1f0ee1058b752f4bfaba309e6d1 (diff)
Merge pull request #5849 from vespa-engine/geirst/refactor-document-selection-integration-in-searchcore
Geirst/refactor document selection integration in searchcore
Diffstat (limited to 'searchcore')
-rw-r--r--searchcore/src/tests/proton/common/cachedselect_test.cpp266
-rw-r--r--searchcore/src/tests/proton/common/selectpruner_test.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/CMakeLists.txt1
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/cachedselect.cpp60
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/cachedselect.h58
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/select_utils.cpp24
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/select_utils.h22
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/selectcontext.cpp6
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/selectpruner.cpp13
-rw-r--r--searchcore/src/vespa/searchcore/proton/persistenceengine/document_iterator.cpp55
10 files changed, 298 insertions, 209 deletions
diff --git a/searchcore/src/tests/proton/common/cachedselect_test.cpp b/searchcore/src/tests/proton/common/cachedselect_test.cpp
index a955bd60cf8..80b80fa4338 100644
--- a/searchcore/src/tests/proton/common/cachedselect_test.cpp
+++ b/searchcore/src/tests/proton/common/cachedselect_test.cpp
@@ -1,29 +1,29 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/vespalib/stllike/string.h>
-#include <vespa/vespalib/testkit/testapp.h>
+#include <vespa/document/base/documentid.h>
+#include <vespa/document/datatype/documenttype.h>
+#include <vespa/document/fieldvalue/document.h>
+#include <vespa/document/fieldvalue/intfieldvalue.h>
+#include <vespa/document/fieldvalue/stringfieldvalue.h>
#include <vespa/document/repo/configbuilder.h>
#include <vespa/document/repo/documenttyperepo.h>
+#include <vespa/document/select/cloningvisitor.h>
+#include <vespa/document/select/parser.h>
#include <vespa/searchcore/proton/common/cachedselect.h>
#include <vespa/searchcore/proton/common/selectcontext.h>
#include <vespa/searchlib/attribute/attributecontext.h>
+#include <vespa/searchlib/attribute/attributefactory.h>
+#include <vespa/searchlib/attribute/attributevector.hpp>
+#include <vespa/searchlib/attribute/enumcomparator.h>
#include <vespa/searchlib/attribute/integerbase.h>
#include <vespa/searchlib/attribute/postinglistattribute.h>
-#include <vespa/searchlib/attribute/enumcomparator.h>
-#include <vespa/searchlib/attribute/singlenumericpostattribute.h>
#include <vespa/searchlib/attribute/singleenumattribute.hpp>
#include <vespa/searchlib/attribute/singlenumericenumattribute.hpp>
+#include <vespa/searchlib/attribute/singlenumericpostattribute.h>
#include <vespa/searchlib/attribute/singlenumericpostattribute.hpp>
-#include <vespa/searchlib/attribute/attributevector.hpp>
-#include <vespa/searchlib/attribute/attributefactory.h>
#include <vespa/searchlib/test/mock_attribute_manager.h>
-#include <vespa/document/select/parser.h>
-#include <vespa/document/select/cloningvisitor.h>
-#include <vespa/document/base/documentid.h>
-#include <vespa/document/fieldvalue/stringfieldvalue.h>
-#include <vespa/document/fieldvalue/intfieldvalue.h>
-#include <vespa/document/fieldvalue/document.h>
-#include <vespa/document/datatype/documenttype.h>
+#include <vespa/vespalib/stllike/string.h>
+#include <vespa/vespalib/testkit/testapp.h>
#include <vespa/log/log.h>
LOG_SETUP("cachedselect_test");
@@ -158,7 +158,7 @@ checkSelect(const CachedSelect::SP &cs,
const Context &ctx,
const Result &exp)
{
- return checkSelect(cs->_select, ctx, exp);
+ return checkSelect(cs->select(), ctx, exp);
}
@@ -170,7 +170,7 @@ checkSelect(const CachedSelect::SP &cs,
SelectContext ctx(*cs);
ctx._docId = docId;
ctx.getAttributeGuards();
- return checkSelect(cs->_attrSelect, ctx, exp);
+ return checkSelect(cs->attrSelect(), ctx, exp);
}
@@ -344,7 +344,7 @@ TestFixture::testParse(const string &selection,
&_amgr,
_hasFields);
- ASSERT_TRUE(res->_select.get() != NULL);
+ ASSERT_TRUE(res->select().get() != NULL);
return res;
}
@@ -377,27 +377,27 @@ TEST_F("Test that const is flagged", TestFixture)
CachedSelect::SP cs;
cs = f.testParse("false", "test");
- EXPECT_TRUE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_FALSE(cs->_allInvalid);
- EXPECT_EQUAL(0u, cs->_fieldNodes);
+ EXPECT_TRUE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_FALSE(cs->allInvalid());
+ EXPECT_EQUAL(0u, cs->fieldNodes());
cs = f.testParse("true", "test");
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_TRUE(cs->_allTrue);
- EXPECT_FALSE(cs->_allInvalid);
- EXPECT_EQUAL(0u, cs->_fieldNodes);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_TRUE(cs->allTrue());
+ EXPECT_FALSE(cs->allInvalid());
+ EXPECT_EQUAL(0u, cs->fieldNodes());
cs = f.testParse("test_2.ac > 4999", "test");
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_TRUE(cs->_allInvalid);
- EXPECT_EQUAL(0u, cs->_fieldNodes);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_TRUE(cs->allInvalid());
+ EXPECT_EQUAL(0u, cs->fieldNodes());
cs = f.testParse("test.aa > 4999", "test");
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_FALSE(cs->_allInvalid);
- EXPECT_EQUAL(1u, cs->_fieldNodes);
- EXPECT_EQUAL(1u, cs->_attrFieldNodes);
- EXPECT_EQUAL(1u, cs->_svAttrFieldNodes);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_FALSE(cs->allInvalid());
+ EXPECT_EQUAL(1u, cs->fieldNodes());
+ EXPECT_EQUAL(1u, cs->attrFieldNodes());
+ EXPECT_EQUAL(1u, cs->svAttrFieldNodes());
}
@@ -413,78 +413,78 @@ TEST_F("Test that basic select works", TestFixture)
CachedSelect::SP cs;
cs = f.testParse("test.ia == \"hello\"", "test");
- EXPECT_FALSE(cs->_attrSelect.get() != NULL);
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_FALSE(cs->_allInvalid);
- EXPECT_EQUAL(1u, cs->_fieldNodes);
- EXPECT_EQUAL(0u, cs->_attrFieldNodes);
- EXPECT_EQUAL(0u, cs->_svAttrFieldNodes);
+ EXPECT_FALSE(cs->attrSelect().get() != NULL);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_FALSE(cs->allInvalid());
+ EXPECT_EQUAL(1u, cs->fieldNodes());
+ EXPECT_EQUAL(0u, cs->attrFieldNodes());
+ EXPECT_EQUAL(0u, cs->svAttrFieldNodes());
TEST_DO(checkSelect(cs, db.getDoc(1u), Result::True));
TEST_DO(checkSelect(cs, db.getDoc(2u), Result::False));
TEST_DO(checkSelect(cs, db.getDoc(3u), Result::False));
TEST_DO(checkSelect(cs, db.getDoc(4u), Result::False));
cs = f.testParse("test.ia.foo == \"hello\"", "test");
- EXPECT_FALSE(cs->_attrSelect.get() != NULL);
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_TRUE(cs->_allInvalid);
- EXPECT_EQUAL(0u, cs->_fieldNodes);
- EXPECT_EQUAL(0u, cs->_attrFieldNodes);
- EXPECT_EQUAL(0u, cs->_svAttrFieldNodes);
+ EXPECT_FALSE(cs->attrSelect().get() != NULL);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_TRUE(cs->allInvalid());
+ EXPECT_EQUAL(0u, cs->fieldNodes());
+ EXPECT_EQUAL(0u, cs->attrFieldNodes());
+ EXPECT_EQUAL(0u, cs->svAttrFieldNodes());
TEST_DO(checkSelect(cs, db.getDoc(1u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(2u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(3u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(4u), Result::Invalid));
cs = f.testParse("test.ia[2] == \"hello\"", "test");
- EXPECT_FALSE(cs->_attrSelect.get() != NULL);
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_TRUE(cs->_allInvalid);
- EXPECT_EQUAL(0u, cs->_fieldNodes);
- EXPECT_EQUAL(0u, cs->_attrFieldNodes);
- EXPECT_EQUAL(0u, cs->_svAttrFieldNodes);
+ EXPECT_FALSE(cs->attrSelect().get() != NULL);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_TRUE(cs->allInvalid());
+ EXPECT_EQUAL(0u, cs->fieldNodes());
+ EXPECT_EQUAL(0u, cs->attrFieldNodes());
+ EXPECT_EQUAL(0u, cs->svAttrFieldNodes());
TEST_DO(checkSelect(cs, db.getDoc(1u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(2u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(3u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(4u), Result::Invalid));
cs = f.testParse("test.ia{foo} == \"hello\"", "test");
- EXPECT_FALSE(cs->_attrSelect.get() != NULL);
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_TRUE(cs->_allInvalid);
- EXPECT_EQUAL(0u, cs->_fieldNodes);
- EXPECT_EQUAL(0u, cs->_attrFieldNodes);
- EXPECT_EQUAL(0u, cs->_svAttrFieldNodes);
+ EXPECT_FALSE(cs->attrSelect().get() != NULL);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_TRUE(cs->allInvalid());
+ EXPECT_EQUAL(0u, cs->fieldNodes());
+ EXPECT_EQUAL(0u, cs->attrFieldNodes());
+ EXPECT_EQUAL(0u, cs->svAttrFieldNodes());
TEST_DO(checkSelect(cs, db.getDoc(1u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(2u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(3u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(4u), Result::Invalid));
cs = f.testParse("test.ia < \"hello\"", "test");
- EXPECT_FALSE(cs->_attrSelect.get() != NULL);
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_FALSE(cs->_allInvalid);
- EXPECT_EQUAL(1u, cs->_fieldNodes);
- EXPECT_EQUAL(0u, cs->_attrFieldNodes);
- EXPECT_EQUAL(0u, cs->_svAttrFieldNodes);
+ EXPECT_FALSE(cs->attrSelect().get() != NULL);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_FALSE(cs->allInvalid());
+ EXPECT_EQUAL(1u, cs->fieldNodes());
+ EXPECT_EQUAL(0u, cs->attrFieldNodes());
+ EXPECT_EQUAL(0u, cs->svAttrFieldNodes());
TEST_DO(checkSelect(cs, db.getDoc(1u), Result::False));
TEST_DO(checkSelect(cs, db.getDoc(2u), Result::True));
TEST_DO(checkSelect(cs, db.getDoc(3u), Result::True));
TEST_DO(checkSelect(cs, db.getDoc(4u), Result::Invalid));
cs = f.testParse("test.aa == 3", "test");
- EXPECT_TRUE(cs->_attrSelect.get() != NULL);
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_FALSE(cs->_allInvalid);
- EXPECT_EQUAL(1u, cs->_fieldNodes);
- EXPECT_EQUAL(1u, cs->_attrFieldNodes);
- EXPECT_EQUAL(1u, cs->_svAttrFieldNodes);
+ EXPECT_TRUE(cs->attrSelect().get() != NULL);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_FALSE(cs->allInvalid());
+ EXPECT_EQUAL(1u, cs->fieldNodes());
+ EXPECT_EQUAL(1u, cs->attrFieldNodes());
+ EXPECT_EQUAL(1u, cs->svAttrFieldNodes());
TEST_DO(checkSelect(cs, db.getDoc(1u), Result::False));
TEST_DO(checkSelect(cs, db.getDoc(2u), Result::True));
TEST_DO(checkSelect(cs, db.getDoc(3u), Result::False));
@@ -495,13 +495,13 @@ TEST_F("Test that basic select works", TestFixture)
TEST_DO(checkSelect(cs, 4u, Result::False));
cs = f.testParse("test.aa == 3", "test");
- EXPECT_TRUE(cs->_attrSelect.get() != NULL);
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_FALSE(cs->_allInvalid);
- EXPECT_EQUAL(1u, cs->_fieldNodes);
- EXPECT_EQUAL(1u, cs->_attrFieldNodes);
- EXPECT_EQUAL(1u, cs->_svAttrFieldNodes);
+ EXPECT_TRUE(cs->attrSelect().get() != NULL);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_FALSE(cs->allInvalid());
+ EXPECT_EQUAL(1u, cs->fieldNodes());
+ EXPECT_EQUAL(1u, cs->attrFieldNodes());
+ EXPECT_EQUAL(1u, cs->svAttrFieldNodes());
TEST_DO(checkSelect(cs, db.getDoc(1u), Result::False));
TEST_DO(checkSelect(cs, db.getDoc(2u), Result::True));
TEST_DO(checkSelect(cs, db.getDoc(3u), Result::False));
@@ -512,70 +512,70 @@ TEST_F("Test that basic select works", TestFixture)
TEST_DO(checkSelect(cs, 4u, Result::False));
cs = f.testParse("test.aa.foo == 3", "test");
- EXPECT_TRUE(cs->_attrSelect.get() == NULL);
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_TRUE(cs->_allInvalid);
- EXPECT_EQUAL(0u, cs->_fieldNodes);
- EXPECT_EQUAL(0u, cs->_attrFieldNodes);
- EXPECT_EQUAL(0u, cs->_svAttrFieldNodes);
+ EXPECT_TRUE(cs->attrSelect().get() == NULL);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_TRUE(cs->allInvalid());
+ EXPECT_EQUAL(0u, cs->fieldNodes());
+ EXPECT_EQUAL(0u, cs->attrFieldNodes());
+ EXPECT_EQUAL(0u, cs->svAttrFieldNodes());
TEST_DO(checkSelect(cs, db.getDoc(1u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(2u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(3u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(4u), Result::Invalid));
cs = f.testParse("test.aa[2] == 3", "test");
- EXPECT_TRUE(cs->_attrSelect.get() == NULL);
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_TRUE(cs->_allInvalid);
- EXPECT_EQUAL(0u, cs->_fieldNodes);
- EXPECT_EQUAL(0u, cs->_attrFieldNodes);
- EXPECT_EQUAL(0u, cs->_svAttrFieldNodes);
+ EXPECT_TRUE(cs->attrSelect().get() == NULL);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_TRUE(cs->allInvalid());
+ EXPECT_EQUAL(0u, cs->fieldNodes());
+ EXPECT_EQUAL(0u, cs->attrFieldNodes());
+ EXPECT_EQUAL(0u, cs->svAttrFieldNodes());
TEST_DO(checkSelect(cs, db.getDoc(1u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(2u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(3u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(4u), Result::Invalid));
cs = f.testParse("test.aa{4} > 3", "test");
- EXPECT_TRUE(cs->_attrSelect.get() == NULL);
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_TRUE(cs->_allInvalid);
- EXPECT_EQUAL(0u, cs->_fieldNodes);
- EXPECT_EQUAL(0u, cs->_attrFieldNodes);
- EXPECT_EQUAL(0u, cs->_svAttrFieldNodes);
+ EXPECT_TRUE(cs->attrSelect().get() == NULL);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_TRUE(cs->allInvalid());
+ EXPECT_EQUAL(0u, cs->fieldNodes());
+ EXPECT_EQUAL(0u, cs->attrFieldNodes());
+ EXPECT_EQUAL(0u, cs->svAttrFieldNodes());
TEST_DO(checkSelect(cs, db.getDoc(1u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(2u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(3u), Result::Invalid));
TEST_DO(checkSelect(cs, db.getDoc(4u), Result::Invalid));
cs = f.testParse("test.aaa[2] == 3", "test");
- EXPECT_TRUE(cs->_attrSelect.get() == NULL);
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_FALSE(cs->_allInvalid);
- EXPECT_EQUAL(1u, cs->_fieldNodes);
- EXPECT_EQUAL(1u, cs->_attrFieldNodes);
- EXPECT_EQUAL(0u, cs->_svAttrFieldNodes);
+ EXPECT_TRUE(cs->attrSelect().get() == NULL);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_FALSE(cs->allInvalid());
+ EXPECT_EQUAL(1u, cs->fieldNodes());
+ EXPECT_EQUAL(1u, cs->attrFieldNodes());
+ EXPECT_EQUAL(0u, cs->svAttrFieldNodes());
cs = f.testParse("test.aaw{4} > 3", "test");
- EXPECT_TRUE(cs->_attrSelect.get() == NULL);
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_FALSE(cs->_allInvalid);
- EXPECT_EQUAL(1u, cs->_fieldNodes);
- EXPECT_EQUAL(1u, cs->_attrFieldNodes);
- EXPECT_EQUAL(0u, cs->_svAttrFieldNodes);
+ EXPECT_TRUE(cs->attrSelect().get() == NULL);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_FALSE(cs->allInvalid());
+ EXPECT_EQUAL(1u, cs->fieldNodes());
+ EXPECT_EQUAL(1u, cs->attrFieldNodes());
+ EXPECT_EQUAL(0u, cs->svAttrFieldNodes());
cs = f.testParse("test.aa < 45", "test");
- EXPECT_TRUE(cs->_attrSelect.get() != NULL);
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_FALSE(cs->_allInvalid);
- EXPECT_EQUAL(1u, cs->_fieldNodes);
- EXPECT_EQUAL(1u, cs->_attrFieldNodes);
- EXPECT_EQUAL(1u, cs->_svAttrFieldNodes);
+ EXPECT_TRUE(cs->attrSelect().get() != NULL);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_FALSE(cs->allInvalid());
+ EXPECT_EQUAL(1u, cs->fieldNodes());
+ EXPECT_EQUAL(1u, cs->attrFieldNodes());
+ EXPECT_EQUAL(1u, cs->svAttrFieldNodes());
TEST_DO(checkSelect(cs, db.getDoc(1u), Result::False));
TEST_DO(checkSelect(cs, db.getDoc(2u), Result::True));
TEST_DO(checkSelect(cs, db.getDoc(3u), Result::Invalid));
@@ -602,16 +602,16 @@ TEST_F("Test performance when using attributes", TestFixture)
CachedSelect::SP cs;
cs = f.testParse("test.aa < 45", "test");
- EXPECT_TRUE(cs->_attrSelect.get() != NULL);
- EXPECT_FALSE(cs->_allFalse);
- EXPECT_FALSE(cs->_allTrue);
- EXPECT_FALSE(cs->_allInvalid);
- EXPECT_EQUAL(1u, cs->_fieldNodes);
- EXPECT_EQUAL(1u, cs->_attrFieldNodes);
- EXPECT_EQUAL(1u, cs->_svAttrFieldNodes);
+ EXPECT_TRUE(cs->attrSelect().get() != NULL);
+ EXPECT_FALSE(cs->allFalse());
+ EXPECT_FALSE(cs->allTrue());
+ EXPECT_FALSE(cs->allInvalid());
+ EXPECT_EQUAL(1u, cs->fieldNodes());
+ EXPECT_EQUAL(1u, cs->attrFieldNodes());
+ EXPECT_EQUAL(1u, cs->svAttrFieldNodes());
SelectContext ctx(*cs);
ctx.getAttributeGuards();
- const NodeUP &sel(cs->_attrSelect);
+ const NodeUP &sel(cs->attrSelect());
uint32_t i;
const uint32_t loopcnt = 30000;
LOG(info, "Starting minibm loop, %u ierations of 4 docs each", loopcnt);
diff --git a/searchcore/src/tests/proton/common/selectpruner_test.cpp b/searchcore/src/tests/proton/common/selectpruner_test.cpp
index a4c47b78e9f..a7feb865d96 100644
--- a/searchcore/src/tests/proton/common/selectpruner_test.cpp
+++ b/searchcore/src/tests/proton/common/selectpruner_test.cpp
@@ -257,7 +257,7 @@ TestFixture::testPrune(const string &selection,
pruner.getNode()->print(pos, true, "");
EXPECT_EQUAL(exp, pos.str());
LOG(info,
- "Pruned ParseTree: '%s', fieldNodes=%u,%u, %s, rs=%s",
+ "Pruned ParseTree: '%s', fieldNodes=%u, attrFieldNodes=%u, cs=%s, rs=%s",
pos.str().c_str(),
pruner.getFieldNodes(),
pruner.getAttrFieldNodes(),
diff --git a/searchcore/src/vespa/searchcore/proton/common/CMakeLists.txt b/searchcore/src/vespa/searchcore/proton/common/CMakeLists.txt
index 9aa6a87ea6c..c2f74c01c2f 100644
--- a/searchcore/src/vespa/searchcore/proton/common/CMakeLists.txt
+++ b/searchcore/src/vespa/searchcore/proton/common/CMakeLists.txt
@@ -14,6 +14,7 @@ vespa_add_library(searchcore_pcommon STATIC
hw_info_sampler.cpp
indexschema_inspector.cpp
monitored_refcount.cpp
+ select_utils.cpp
selectpruner.cpp
selectcontext.cpp
state_reporter_utils.cpp
diff --git a/searchcore/src/vespa/searchcore/proton/common/cachedselect.cpp b/searchcore/src/vespa/searchcore/proton/common/cachedselect.cpp
index 8a7bc690e40..2d4001226c8 100644
--- a/searchcore/src/vespa/searchcore/proton/common/cachedselect.cpp
+++ b/searchcore/src/vespa/searchcore/proton/common/cachedselect.cpp
@@ -1,11 +1,13 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include "cachedselect.h"
#include "attributefieldvaluenode.h"
+#include "cachedselect.h"
+#include "select_utils.h"
+#include "selectcontext.h"
#include "selectpruner.h"
-#include <vespa/searchlib/attribute/iattributemanager.h>
-#include <vespa/searchlib/attribute/attributevector.h>
#include <vespa/document/select/parser.h>
+#include <vespa/searchlib/attribute/attributevector.h>
+#include <vespa/searchlib/attribute/iattributemanager.h>
#include <vespa/log/log.h>
LOG_SETUP(".proton.common.cachedselect");
@@ -26,7 +28,7 @@ public:
AttrMap _amap;
const search::IAttributeManager &_amgr;
- CachedSelect &_cached;
+ CachedSelect::AttributeVectors &_attributes;
uint32_t _svAttrs;
uint32_t _mvAttrs;
uint32_t _complexAttrs;
@@ -37,7 +39,7 @@ public:
return std::numeric_limits<uint32_t>::max();
}
- AttrVisitor(const search::IAttributeManager &amgr, CachedSelect &cachedSelect);
+ AttrVisitor(const search::IAttributeManager &amgr, CachedSelect::AttributeVectors &attributes);
~AttrVisitor();
/*
@@ -48,11 +50,11 @@ public:
};
-AttrVisitor::AttrVisitor(const search::IAttributeManager &amgr, CachedSelect &cachedSelect)
+AttrVisitor::AttrVisitor(const search::IAttributeManager &amgr, CachedSelect::AttributeVectors &attributes)
: CloningVisitor(),
_amap(),
_amgr(amgr),
- _cached(cachedSelect),
+ _attributes(attributes),
_svAttrs(0u),
_mvAttrs(0u),
_complexAttrs(0u)
@@ -66,16 +68,9 @@ AttrVisitor::visitFieldValueNode(const FieldValueNode &expr)
++_fieldNodes;
// Expression has survived select pruner, thus we know that field is
// valid for document type.
- vespalib::string name(expr.getFieldName());
bool complex = false;
- for (uint32_t i = 0; i < name.size(); ++i) {
- if (name[i] == '.' || name[i] == '{' || name[i] == '[') {
- // TODO: Check for struct, array, map or weigthed set
- name = expr.getFieldName().substr(0, i);
- complex = true;
- break;
- }
- }
+ vespalib::string name = SelectUtils::extractFieldName(expr, complex);
+
AttributeGuard::UP ag(_amgr.getAttribute(name));
if (ag->valid()) {
if (complex) {
@@ -91,9 +86,9 @@ AttrVisitor::visitFieldValueNode(const FieldValueNode &expr)
uint32_t idx(invalidIdx());
if (it == _amap.end()) {
// Allocate new location for guard
- idx = _cached._attributes.size();
+ idx = _attributes.size();
_amap[name] = idx;
- _cached._attributes.push_back(av);
+ _attributes.push_back(av);
} else {
// Already allocated location for guard
idx = it->second;
@@ -112,6 +107,25 @@ AttrVisitor::visitFieldValueNode(const FieldValueNode &expr)
}
+CachedSelect::Session::Session(std::unique_ptr<document::select::Node> select, bool isAttrSelect)
+ : _select(std::move(select)),
+ _isAttrSelect(isAttrSelect)
+{
+}
+
+bool
+CachedSelect::Session::contains(const SelectContext &context) const
+{
+ return (!_isAttrSelect) ||
+ (_isAttrSelect && (_select->contains(context) == document::select::Result::True));
+}
+
+bool
+CachedSelect::Session::contains(const document::Document &doc) const
+{
+ return (_isAttrSelect || (_select->contains(doc) == document::select::Result::True));
+}
+
CachedSelect::CachedSelect()
: _attributes(),
_select(),
@@ -173,7 +187,7 @@ CachedSelect::set(const vespalib::string &selection,
_attrFieldNodes = pruner.getAttrFieldNodes();
if (amgr == NULL || _attrFieldNodes == 0u)
return;
- AttrVisitor av(*amgr, *this);
+ AttrVisitor av(*amgr, _attributes);
_select->visit(av);
assert(_fieldNodes == av.getFieldNodes());
assert(_attrFieldNodes == av._mvAttrs + av._svAttrs + av._complexAttrs);
@@ -183,6 +197,12 @@ CachedSelect::set(const vespalib::string &selection,
}
}
+std::unique_ptr<CachedSelect::Session>
+CachedSelect::createSession() const
+{
+ return (_attrSelect ? std::make_unique<Session>(_attrSelect->clone(), true) :
+ std::make_unique<Session>(_select->clone(), false));
+}
-} // namespace proton
+}
diff --git a/searchcore/src/vespa/searchcore/proton/common/cachedselect.h b/searchcore/src/vespa/searchcore/proton/common/cachedselect.h
index 014dbe5db5f..ac9983ab735 100644
--- a/searchcore/src/vespa/searchcore/proton/common/cachedselect.h
+++ b/searchcore/src/vespa/searchcore/proton/common/cachedselect.h
@@ -17,6 +17,8 @@ namespace search {
namespace proton {
+class SelectContext;
+
/**
* Cached selection expression, to avoid pruning expression for each
* new bucket.
@@ -25,8 +27,24 @@ class CachedSelect
{
public:
typedef std::shared_ptr<CachedSelect> SP;
+
+ class Session {
+ private:
+ std::unique_ptr<document::select::Node> _select;
+ bool _isAttrSelect;
+
+ public:
+ Session(std::unique_ptr<document::select::Node> select, bool isAttrSelect);
+ bool contains(const SelectContext &context) const;
+ bool contains(const document::Document &doc) const;
+ const document::select::Node &selectNode() const { return *_select; }
+ };
+
+ using AttributeVectors = std::vector<std::shared_ptr<search::AttributeVector>>;
+
+private:
// Single value attributes referenced from selection expression
- std::vector<std::shared_ptr<search::AttributeVector>> _attributes;
+ AttributeVectors _attributes;
// Pruned selection expression, specific for a document type
std::unique_ptr<document::select::Node> _select;
@@ -45,22 +63,36 @@ public:
* SelectContext class and populate _docId instead).
*/
std::unique_ptr<document::select::Node> _attrSelect;
-
+
+public:
CachedSelect();
~CachedSelect();
- void
- set(const vespalib::string &selection,
- const document::DocumentTypeRepo &repo);
+ const AttributeVectors &attributes() const { return _attributes; }
+ uint32_t fieldNodes() const { return _fieldNodes; }
+ uint32_t attrFieldNodes() const { return _attrFieldNodes; }
+ uint32_t svAttrFieldNodes() const { return _svAttrFieldNodes; }
+ bool allFalse() const { return _allFalse; }
+ bool allTrue() const { return _allTrue; }
+ bool allInvalid() const { return _allInvalid; }
+
+ // Should only be used for unit testing
+ const std::unique_ptr<document::select::Node> &select() const { return _select; }
+ const std::unique_ptr<document::select::Node> &attrSelect() const { return _attrSelect; }
+
+ void set(const vespalib::string &selection,
+ const document::DocumentTypeRepo &repo);
- void
- set(const vespalib::string &selection,
- const vespalib::string &docTypeName,
- const document::Document &emptyDoc,
- const document::DocumentTypeRepo &repo,
- const search::IAttributeManager *amgr,
- bool hasFields);
+ void set(const vespalib::string &selection,
+ const vespalib::string &docTypeName,
+ const document::Document &emptyDoc,
+ const document::DocumentTypeRepo &repo,
+ const search::IAttributeManager *amgr,
+ bool hasFields);
+
+ std::unique_ptr<Session> createSession() const;
+
};
-} // namespace proton
+}
diff --git a/searchcore/src/vespa/searchcore/proton/common/select_utils.cpp b/searchcore/src/vespa/searchcore/proton/common/select_utils.cpp
new file mode 100644
index 00000000000..148c4ae9a46
--- /dev/null
+++ b/searchcore/src/vespa/searchcore/proton/common/select_utils.cpp
@@ -0,0 +1,24 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "select_utils.h"
+#include <vespa/document/select/valuenodes.h>
+
+namespace proton {
+
+vespalib::string
+SelectUtils::extractFieldName(const document::select::FieldValueNode &expr, bool &isComplex)
+{
+ vespalib::string result = expr.getFieldName();
+ isComplex = false;
+ for (uint32_t i = 0; i < result.size(); ++i) {
+ if (result[i] == '.' || result[i] == '{' || result[i] == '[') {
+ // TODO: Check for struct, array, map or weigthed set
+ result = expr.getFieldName().substr(0, i);
+ isComplex = true;
+ break;
+ }
+ }
+ return result;
+}
+
+}
diff --git a/searchcore/src/vespa/searchcore/proton/common/select_utils.h b/searchcore/src/vespa/searchcore/proton/common/select_utils.h
new file mode 100644
index 00000000000..62ba377d46a
--- /dev/null
+++ b/searchcore/src/vespa/searchcore/proton/common/select_utils.h
@@ -0,0 +1,22 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+#include <vespa/vespalib/stllike/string.h>
+
+namespace document::select { class FieldValueNode; }
+
+namespace proton {
+
+/**
+ * Utility functions used as part of document selection integration in searchcore.
+ */
+struct SelectUtils {
+
+ /**
+ * Extracts the field name of the FieldValueNode and signals whether it is complex or not.
+ */
+ static vespalib::string extractFieldName(const document::select::FieldValueNode &expr, bool &isComplex);
+
+};
+
+}
diff --git a/searchcore/src/vespa/searchcore/proton/common/selectcontext.cpp b/searchcore/src/vespa/searchcore/proton/common/selectcontext.cpp
index 84ff6874d33..3275fbe06d4 100644
--- a/searchcore/src/vespa/searchcore/proton/common/selectcontext.cpp
+++ b/searchcore/src/vespa/searchcore/proton/common/selectcontext.cpp
@@ -22,7 +22,7 @@ namespace select {
SelectContext::SelectContext(const CachedSelect &cachedSelect)
: Context(),
_docId(0u),
- _guards(std::make_unique<select::Guards>(cachedSelect._attributes.size())),
+ _guards(std::make_unique<select::Guards>(cachedSelect.attributes().size())),
_cachedSelect(cachedSelect)
{ }
@@ -31,8 +31,8 @@ SelectContext::~SelectContext() { }
void
SelectContext::getAttributeGuards()
{
- _guards->resize(_cachedSelect._attributes.size());
- auto j(_cachedSelect._attributes.begin());
+ _guards->resize(_cachedSelect.attributes().size());
+ auto j(_cachedSelect.attributes().begin());
for (std::vector<AttributeGuard>::iterator i(_guards->begin()), ie(_guards->end()); i != ie; ++i, ++j) {
*i = AttributeGuard(*j);
}
diff --git a/searchcore/src/vespa/searchcore/proton/common/selectpruner.cpp b/searchcore/src/vespa/searchcore/proton/common/selectpruner.cpp
index 3e9075607f6..5ade1fbcec7 100644
--- a/searchcore/src/vespa/searchcore/proton/common/selectpruner.cpp
+++ b/searchcore/src/vespa/searchcore/proton/common/selectpruner.cpp
@@ -1,12 +1,13 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include "select_utils.h"
#include "selectpruner.h"
#include <vespa/document/base/exceptions.h>
#include <vespa/document/datatype/documenttype.h>
#include <vespa/document/repo/documenttyperepo.h>
+#include <vespa/document/select/branch.h>
#include <vespa/document/select/compare.h>
#include <vespa/document/select/constant.h>
-#include <vespa/document/select/branch.h>
#include <vespa/document/select/doctype.h>
#include <vespa/document/select/invalidconstant.h>
#include <vespa/document/select/valuenodes.h>
@@ -396,15 +397,7 @@ SelectPruner::visitFieldValueNode(const FieldValueNode &expr)
}
const document::DocumentType *docType = _repo.getDocumentType(_docType);
bool complex = false; // Cannot handle attribute if complex expression
- vespalib::string name(expr.getFieldName());
- for (uint32_t i = 0; i < name.size(); ++i) {
- if (name[i] == '.' || name[i] == '{' || name[i] == '[') {
- // TODO: Check for struct, array, map or weigthed set
- name = expr.getFieldName().substr(0, i);
- complex = true;
- break;
- }
- }
+ vespalib::string name = SelectUtils::extractFieldName(expr, complex);
try {
std::unique_ptr<Field> fp(new Field(docType->getField(name)));
if (fp.get() == NULL) {
diff --git a/searchcore/src/vespa/searchcore/proton/persistenceengine/document_iterator.cpp b/searchcore/src/vespa/searchcore/proton/persistenceengine/document_iterator.cpp
index 0ef3b0e2aab..3a695e6d5f9 100644
--- a/searchcore/src/vespa/searchcore/proton/persistenceengine/document_iterator.cpp
+++ b/searchcore/src/vespa/searchcore/proton/persistenceengine/document_iterator.cpp
@@ -124,9 +124,9 @@ DocumentIterator::iterate(size_t maxBytes)
namespace {
-class Match {
+class Matcher {
public:
- Match(const IDocumentRetriever & source, bool metaOnly, const vespalib::string & selection) :
+ Matcher(const IDocumentRetriever &source, bool metaOnly, const vespalib::string &selection) :
_dscTrue(true),
_metaOnly(metaOnly),
_willAlwaysFail(false),
@@ -134,29 +134,28 @@ public:
{
if (!(_metaOnly || selection.empty())) {
LOG(spam, "ParseSelect: %s", selection.c_str());
- _cs = source.parseSelect(selection);
- CachedSelect &cs(*_cs);
- _dscTrue = cs._allTrue;
- if (cs._allFalse || cs._allInvalid) {
+ _cachedSelect = source.parseSelect(selection);
+ _dscTrue = _cachedSelect->allTrue();
+ if (_cachedSelect->allFalse() || _cachedSelect->allInvalid()) {
assert(!_dscTrue);
- LOG(debug, "Nothing will ever match cs._allFalse = '%d' cs._allInvalid = '%d'", cs._allFalse, cs._allInvalid);
+ LOG(debug, "Nothing will ever match cs.allFalse = '%d', cs.allInvalid = '%d'",
+ _cachedSelect->allFalse(), _cachedSelect->allInvalid());
_willAlwaysFail = true;
} else {
- _select = (cs._attrSelect ? cs._attrSelect->clone()
- : cs._select->clone());
+ _selectSession = _cachedSelect->createSession();
using document::select::GidFilter;
- _gidFilter = GidFilter::for_selection_root_node(*_select);
- _sc.reset(new SelectContext(*_cs));
- _sc->getAttributeGuards();
+ _gidFilter = GidFilter::for_selection_root_node(_selectSession->selectNode());
+ _selectCxt.reset(new SelectContext(*_cachedSelect));
+ _selectCxt->getAttributeGuards();
}
} else {
_dscTrue = true;
}
}
- ~Match() {
- if (_sc) {
- _sc->dropAttributeGuards();
+ ~Matcher() {
+ if (_selectCxt) {
+ _selectCxt->dropAttributeGuards();
}
}
@@ -169,31 +168,29 @@ public:
if (_dscTrue || _metaOnly) {
return true;
}
- if (_sc) {
- _sc->_docId = meta.lid;
+ if (_selectCxt) {
+ _selectCxt->_docId = meta.lid;
}
if (!_gidFilter.gid_might_match_selection(meta.gid)) {
return false;
}
- return (! _cs->_attrSelect) ||
- (_cs->_attrSelect && (_select->contains(*_sc) == document::select::Result::True));
+ return _selectSession->contains(*_selectCxt);
}
bool match(const search::DocumentMetaData & meta, const Document * doc) const {
if (_dscTrue || _metaOnly) {
return true;
}
- return (doc && (doc->getId().getGlobalId() == meta.gid) &&
- (_cs->_attrSelect || (_select->contains(*doc) == document::select::Result::True)));
+ return (doc && (doc->getId().getGlobalId() == meta.gid) && _selectSession->contains(*doc));
}
private:
bool _dscTrue;
bool _metaOnly;
bool _willAlwaysFail;
uint32_t _docidLimit;
- CachedSelect::SP _cs;
- document::select::Node::UP _select;
+ CachedSelect::SP _cachedSelect;
+ std::unique_ptr<CachedSelect::Session> _selectSession;
document::select::GidFilter _gidFilter;
- std::unique_ptr<SelectContext> _sc;
+ std::unique_ptr<SelectContext> _selectCxt;
};
typedef vespalib::hash_map<uint32_t, uint32_t> LidIndexMap;
@@ -201,8 +198,8 @@ typedef vespalib::hash_map<uint32_t, uint32_t> LidIndexMap;
class MatchVisitor : public search::IDocumentVisitor
{
public:
- MatchVisitor(const Match & matcher, const search::DocumentMetaData::Vector & metaData,
- const LidIndexMap & lidIndexMap, const document::FieldSet * fields, IterateResult::List & list,
+ MatchVisitor(const Matcher &matcher, const search::DocumentMetaData::Vector &metaData,
+ const LidIndexMap &lidIndexMap, const document::FieldSet *fields, IterateResult::List &list,
ssize_t defaultSerializedSize) :
_matcher(matcher),
_metaData(metaData),
@@ -229,7 +226,7 @@ public:
}
private:
- const Match & _matcher;
+ const Matcher & _matcher;
const search::DocumentMetaData::Vector & _metaData;
const LidIndexMap & _lidIndexMap;
const document::FieldSet * _fields;
@@ -251,7 +248,7 @@ DocumentIterator::fetchCompleteSource(const IDocumentRetriever & source, Iterate
}
LOG(debug, "metadata count before filtering: %zu", metaData.size());
- Match matcher(source, _metaOnly, _selection.getDocumentSelection().getDocumentSelection());
+ Matcher matcher(source, _metaOnly, _selection.getDocumentSelection().getDocumentSelection());
if (matcher.willAlwaysFail()) {
return;
}
@@ -284,4 +281,4 @@ DocumentIterator::fetchCompleteSource(const IDocumentRetriever & source, Iterate
}
-} // namespace proton
+}