diff options
author | Tor Egge <Tor.Egge@broadpark.no> | 2018-05-11 17:05:14 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-11 17:05:14 +0200 |
commit | cf80ff1b7ce08cd3fdfd8c789de45da02ffba5c9 (patch) | |
tree | 9f05557299f2298c5ea83aa7bbeb37c68c357786 /searchcore | |
parent | f1f7f139fab32fef7a541402c75039d0794e30eb (diff) | |
parent | 3e602411fe15e1f0ee1058b752f4bfaba309e6d1 (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')
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 +} |