diff options
11 files changed, 257 insertions, 0 deletions
diff --git a/searchcore/CMakeLists.txt b/searchcore/CMakeLists.txt index 7546389aeb6..14a06f4abd7 100644 --- a/searchcore/CMakeLists.txt +++ b/searchcore/CMakeLists.txt @@ -118,6 +118,7 @@ vespa_define_module( src/tests/proton/persistenceengine src/tests/proton/proton src/tests/proton/reference/gid_to_lid_mapper + src/tests/proton/reference/document_db_reference_resolver src/tests/proton/reference/document_db_referent_registry src/tests/proton/reprocessing/attribute_reprocessing_initializer src/tests/proton/reprocessing/document_reprocessing_handler diff --git a/searchcore/src/tests/proton/reference/document_db_reference_resolver/CMakeLists.txt b/searchcore/src/tests/proton/reference/document_db_reference_resolver/CMakeLists.txt new file mode 100644 index 00000000000..1a2aa573ad1 --- /dev/null +++ b/searchcore/src/tests/proton/reference/document_db_reference_resolver/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(searchcore_document_db_reference_resolver_test_app TEST + SOURCES + document_db_reference_resolver_test.cpp + DEPENDS + searchcore_reference +) +vespa_add_test(NAME searchcore_document_db_reference_resolver_test_app COMMAND searchcore_document_db_reference_resolver_test_app) diff --git a/searchcore/src/tests/proton/reference/document_db_reference_resolver/DESC b/searchcore/src/tests/proton/reference/document_db_reference_resolver/DESC new file mode 100644 index 00000000000..3a8fe966966 --- /dev/null +++ b/searchcore/src/tests/proton/reference/document_db_reference_resolver/DESC @@ -0,0 +1 @@ +document_db_reference_resolver test. Take a look at document_db_reference_resolver_test.cpp for details. diff --git a/searchcore/src/tests/proton/reference/document_db_reference_resolver/FILES b/searchcore/src/tests/proton/reference/document_db_reference_resolver/FILES new file mode 100644 index 00000000000..15233d66c94 --- /dev/null +++ b/searchcore/src/tests/proton/reference/document_db_reference_resolver/FILES @@ -0,0 +1 @@ +document_db_reference_resolver_test.cpp diff --git a/searchcore/src/tests/proton/reference/document_db_reference_resolver/document_db_reference_resolver_test.cpp b/searchcore/src/tests/proton/reference/document_db_reference_resolver/document_db_reference_resolver_test.cpp new file mode 100644 index 00000000000..c8158d7d8c5 --- /dev/null +++ b/searchcore/src/tests/proton/reference/document_db_reference_resolver/document_db_reference_resolver_test.cpp @@ -0,0 +1,130 @@ +// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <vespa/vespalib/testkit/testapp.h> + +#include <vespa/document/datatype/documenttype.h> +#include <vespa/document/datatype/referencedatatype.h> +#include <vespa/log/log.h> +#include <vespa/searchcore/proton/reference/document_db_reference_resolver.h> +#include <vespa/searchcore/proton/reference/i_document_db_referent.h> +#include <vespa/searchcore/proton/reference/i_document_db_referent_registry.h> +#include <vespa/searchlib/attribute/attributefactory.h> +#include <vespa/searchlib/attribute/reference_attribute.h> +#include <vespa/searchlib/common/i_gid_to_lid_mapper.h> +#include <vespa/searchlib/common/i_gid_to_lid_mapper_factory.h> +#include <vespa/searchlib/test/mock_attribute_manager.h> + +LOG_SETUP("document_db_reference_resolver_test"); + +using namespace document; +using namespace proton; +using namespace search::attribute; +using namespace search; + +struct MyGidToLidMapperFactory : public IGidToLidMapperFactory { + using SP = std::shared_ptr<MyGidToLidMapperFactory>; + virtual std::unique_ptr<IGidToLidMapper> getMapper() const override { + return std::unique_ptr<IGidToLidMapper>(); + } +}; + +struct MyDocumentDBReferent : public IDocumentDBReferent { + MyGidToLidMapperFactory::SP factory; + MyDocumentDBReferent(MyGidToLidMapperFactory::SP factory_) : factory(factory_) {} + virtual AttributeVector::SP getAttribute(vespalib::stringref) override { + return AttributeVector::SP(); + } + virtual IGidToLidMapperFactory::SP getGidToLidMapperFactory() override { + return factory; + } +}; + +struct MyReferentRegistry : public IDocumentDBReferentRegistry { + using ReferentMap = std::map<vespalib::string, IDocumentDBReferent::SP>; + ReferentMap map; + virtual IDocumentDBReferent::SP get(vespalib::stringref name) const override { + auto itr = map.find(name); + if (itr != map.end()) { + return itr->second; + } + return IDocumentDBReferent::SP(); + } + virtual void add(vespalib::stringref name, IDocumentDBReferent::SP referent) override { + map[name] = referent; + } + virtual void remove(vespalib::stringref) override {} +}; + +struct MyAttributeManager : public test::MockAttributeManager { + void addIntAttribute(const vespalib::string &name) { + addAttribute(name, AttributeFactory::createAttribute(name, Config(BasicType::INT32))); + } + void addReferenceAttribute(const vespalib::string &name) { + addAttribute(name, std::make_shared<ReferenceAttribute>(name, Config(BasicType::REFERENCE))); + } + const ReferenceAttribute *getReferenceAttribute(const vespalib::string &name) const { + AttributeGuard::UP guard = getAttribute(name); + const ReferenceAttribute *result = dynamic_cast<const ReferenceAttribute *>(&guard->get()); + ASSERT_TRUE(result != nullptr); + return result; + } +}; + +struct DocumentModel { + DocumentType parentDocType; + ReferenceDataType refDataType; + DocumentType childDocType; + DocumentModel() + : parentDocType("parent"), + refDataType(parentDocType, 1234), + childDocType("child") + { + initChildDocType(); + } + void initChildDocType() { + childDocType.addField(Field("ref", refDataType, true)); + childDocType.addField(Field("other_ref", refDataType, true)); + } +}; + +struct Fixture { + MyGidToLidMapperFactory::SP factory; + MyDocumentDBReferent::SP parentReferent; + MyReferentRegistry registry; + MyAttributeManager attrMgr; + DocumentModel docModel; + DocumentDBReferenceResolver resolver; + Fixture() : + factory(std::make_shared<MyGidToLidMapperFactory>()), + parentReferent(std::make_shared<MyDocumentDBReferent>(factory)), + registry(), + attrMgr(), + docModel(), + resolver(registry, attrMgr, docModel.childDocType) + { + registry.add("parent", parentReferent); + populateAttributeManager(); + } + void populateAttributeManager() { + attrMgr.addReferenceAttribute("ref"); + attrMgr.addReferenceAttribute("other_ref"); + attrMgr.addIntAttribute("int_attr"); + } + void resolve() { + resolver.resolve(); + } + const IGidToLidMapperFactory *getMapperFactoryPtr(const vespalib::string &attrName) { + return attrMgr.getReferenceAttribute(attrName)->getGidToLidMapperFactory().get(); + } +}; + +TEST_F("require that reference attributes are connected to gid mapper", Fixture) +{ + f.resolve(); + EXPECT_EQUAL(f.factory.get(), f.getMapperFactoryPtr("ref")); + EXPECT_EQUAL(f.factory.get(), f.getMapperFactoryPtr("other_ref")); +} + +TEST_MAIN() +{ + TEST_RUN_ALL(); +} diff --git a/searchcore/src/vespa/searchcore/proton/reference/CMakeLists.txt b/searchcore/src/vespa/searchcore/proton/reference/CMakeLists.txt index f2528a93853..bd0abef9809 100644 --- a/searchcore/src/vespa/searchcore/proton/reference/CMakeLists.txt +++ b/searchcore/src/vespa/searchcore/proton/reference/CMakeLists.txt @@ -1,6 +1,7 @@ # Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. vespa_add_library(searchcore_reference STATIC SOURCES + document_db_reference_resolver.cpp document_db_referent.cpp document_db_referent_registry.cpp gid_to_lid_mapper.cpp diff --git a/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.cpp b/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.cpp new file mode 100644 index 00000000000..244bfcc6218 --- /dev/null +++ b/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.cpp @@ -0,0 +1,78 @@ +// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/fastos/fastos.h> +#include "document_db_reference_resolver.h" +#include "i_document_db_referent_registry.h" +#include "i_document_db_referent.h" +#include <vespa/document/datatype/documenttype.h> +#include <vespa/document/repo/documenttyperepo.h> +#include <vespa/searchlib/attribute/attributevector.h> +#include <vespa/searchlib/attribute/iattributemanager.h> +#include <vespa/searchlib/attribute/reference_attribute.h> +#include <vespa/document/datatype/referencedatatype.h> + +using document::DataType; +using document::DocumentType; +using document::DocumentTypeRepo; +using document::ReferenceDataType; +using search::attribute::BasicType; +using search::attribute::ReferenceAttribute; +using search::AttributeGuard; +using search::AttributeVector; +using search::IAttributeManager; + +namespace proton { + +namespace { + +vespalib::string +getTargetDocTypeName(const vespalib::string &attrName, + const DocumentType &thisDocType) +{ + const DataType &attrType = thisDocType.getField(attrName).getDataType(); + const ReferenceDataType *refType = dynamic_cast<const ReferenceDataType *>(&attrType); + assert(refType != nullptr); + return refType->getTargetType().getName(); +} + +ReferenceAttribute & +asReferenceAttribute(AttributeVector &attr) +{ + ReferenceAttribute *result = dynamic_cast<ReferenceAttribute *>(&attr); + assert(result != nullptr); + return *result; +} + +} + +void +DocumentDBReferenceResolver::connectReferenceAttributesToGidMapper() +{ + std::vector<AttributeGuard> attributeList; + _attrMgr.getAttributeList(attributeList); + for (auto &guard : attributeList) { + AttributeVector &attr = guard.get(); + if (attr.getBasicType() == BasicType::REFERENCE) { + IDocumentDBReferent::SP targetDB = _registry.get(getTargetDocTypeName(attr.getName(), + _thisDocType)); + asReferenceAttribute(attr).setGidToLidMapperFactory(targetDB->getGidToLidMapperFactory()); + } + } +} + +DocumentDBReferenceResolver::DocumentDBReferenceResolver(const IDocumentDBReferentRegistry ®istry, + const IAttributeManager &attrMgr, + const DocumentType &thisDocType) + : _registry(registry), + _attrMgr(attrMgr), + _thisDocType(thisDocType) +{ +} + +void +DocumentDBReferenceResolver::resolve() +{ + connectReferenceAttributesToGidMapper(); +} + +} diff --git a/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.h b/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.h new file mode 100644 index 00000000000..efb6ef6a76c --- /dev/null +++ b/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.h @@ -0,0 +1,34 @@ +// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#pragma once + +namespace document { +class DocumentType; +class DocumentTypeRepo; +} +namespace search { class IAttributeManager; } + +namespace proton { + +class IDocumentDBReferentRegistry; + +/** + * Class that for a given document db resolves all references to parent document dbs: + * 1) Connects all reference attributes to gid mappers of parent document dbs. + */ +class DocumentDBReferenceResolver { +private: + const IDocumentDBReferentRegistry &_registry; + const search::IAttributeManager &_attrMgr; + const document::DocumentType &_thisDocType; + + void connectReferenceAttributesToGidMapper(); + +public: + DocumentDBReferenceResolver(const IDocumentDBReferentRegistry ®istry, + const search::IAttributeManager &attrMgr, + const document::DocumentType &thisDocType); + + void resolve(); +}; + +} diff --git a/searchcore/src/vespa/searchcore/proton/reference/i_document_db_referent.h b/searchcore/src/vespa/searchcore/proton/reference/i_document_db_referent.h index 695539bf591..8ae4a28b185 100644 --- a/searchcore/src/vespa/searchcore/proton/reference/i_document_db_referent.h +++ b/searchcore/src/vespa/searchcore/proton/reference/i_document_db_referent.h @@ -20,6 +20,7 @@ namespace proton { class IDocumentDBReferent { public: + using SP = std::shared_ptr<IDocumentDBReferent>; virtual ~IDocumentDBReferent() { } virtual std::shared_ptr<search::AttributeVector> getAttribute(vespalib::stringref name) = 0; virtual std::shared_ptr<search::IGidToLidMapperFactory> getGidToLidMapperFactory() = 0; diff --git a/searchlib/src/vespa/searchlib/attribute/reference_attribute.h b/searchlib/src/vespa/searchlib/attribute/reference_attribute.h index 091d5c2bcab..dfec2dbed97 100644 --- a/searchlib/src/vespa/searchlib/attribute/reference_attribute.h +++ b/searchlib/src/vespa/searchlib/attribute/reference_attribute.h @@ -73,6 +73,7 @@ public: void update(DocId doc, const GlobalId &gid); const Reference *getReference(DocId doc); void setGidToLidMapperFactory(std::shared_ptr<IGidToLidMapperFactory> gidToLidMapperFactory); + std::shared_ptr<IGidToLidMapperFactory> getGidToLidMapperFactory() const { return _gidToLidMapperFactory; } DocId getReferencedLid(DocId doc) const; }; diff --git a/searchlib/src/vespa/searchlib/common/i_gid_to_lid_mapper_factory.h b/searchlib/src/vespa/searchlib/common/i_gid_to_lid_mapper_factory.h index fadd0b74020..5f57ada4486 100644 --- a/searchlib/src/vespa/searchlib/common/i_gid_to_lid_mapper_factory.h +++ b/searchlib/src/vespa/searchlib/common/i_gid_to_lid_mapper_factory.h @@ -12,6 +12,7 @@ class IGidToLidMapper; class IGidToLidMapperFactory { public: + using SP = std::shared_ptr<IGidToLidMapperFactory>; virtual ~IGidToLidMapperFactory() { } virtual std::unique_ptr<IGidToLidMapper> getMapper() const = 0; }; |