diff options
author | Geir Storli <geirstorli@yahoo.no> | 2017-09-12 15:53:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-12 15:53:35 +0200 |
commit | 664dc8e147928cd05a16954cbfdd6efb34dd144a (patch) | |
tree | a5b985aab6b38f3b955c5b62469a9bcbd8a4c700 | |
parent | 5ca40d533eabdb8fad2d0951285182b998aaf9df (diff) | |
parent | 093d8381783f0acac2b53be4703fd61189d0b470 (diff) |
Merge pull request #3390 from vespa-engine/geirst/fix-bitvector-search-cache-for-imported-attributes
Geirst/fix bitvector search cache for imported attributes
26 files changed, 445 insertions, 333 deletions
diff --git a/searchcore/src/tests/proton/attribute/attribute_manager/attribute_manager_test.cpp b/searchcore/src/tests/proton/attribute/attribute_manager/attribute_manager_test.cpp index 07af0d2ace5..0bbbdabd0aa 100644 --- a/searchcore/src/tests/proton/attribute/attribute_manager/attribute_manager_test.cpp +++ b/searchcore/src/tests/proton/attribute/attribute_manager/attribute_manager_test.cpp @@ -136,7 +136,8 @@ struct ImportedAttributesRepoBuilder { auto refAttr = std::make_shared<ReferenceAttribute>(name + "_ref", AVConfig(BasicType::REFERENCE)); refAttr->setGidToLidMapperFactory(std::make_shared<MockGidToLidMapperFactory>()); auto targetAttr = search::AttributeFactory::createAttribute(name + "_target", INT32_SINGLE); - auto importedAttr = std::make_shared<ImportedAttributeVector>(name, refAttr, targetAttr, false); + auto documentMetaStore = std::shared_ptr<search::IDocumentMetaStoreContext>(); + auto importedAttr = std::make_shared<ImportedAttributeVector>(name, refAttr, targetAttr, documentMetaStore, false); _repo->add(name, importedAttr); } ImportedAttributesRepo::UP build() { diff --git a/searchcore/src/tests/proton/attribute/attribute_test.cpp b/searchcore/src/tests/proton/attribute/attribute_test.cpp index 1112cf75570..badb42d4be4 100644 --- a/searchcore/src/tests/proton/attribute/attribute_test.cpp +++ b/searchcore/src/tests/proton/attribute/attribute_test.cpp @@ -723,6 +723,7 @@ createImportedAttribute(const vespalib::string &name) auto result = std::make_shared<ImportedAttributeVector>(name, ReferenceAttribute::SP(), AttributeVector::SP(), + std::shared_ptr<search::IDocumentMetaStoreContext>(), true); result->getSearchCache()->insert("foo", BitVectorSearchCache::Entry::SP()); return result; diff --git a/searchcore/src/tests/proton/attribute/imported_attributes_context/imported_attributes_context_test.cpp b/searchcore/src/tests/proton/attribute/imported_attributes_context/imported_attributes_context_test.cpp index afbaabd9fc3..aac74e1583d 100644 --- a/searchcore/src/tests/proton/attribute/imported_attributes_context/imported_attributes_context_test.cpp +++ b/searchcore/src/tests/proton/attribute/imported_attributes_context/imported_attributes_context_test.cpp @@ -75,6 +75,7 @@ struct Fixture { auto attr = std::make_shared<ImportedAttributeVector>(name, createReferenceAttribute(name + "_ref"), createTargetAttribute(name + "_target"), + std::shared_ptr<search::IDocumentMetaStoreContext>(), false); repo.add(name, attr); return *this; diff --git a/searchcore/src/tests/proton/attribute/imported_attributes_repo/imported_attributes_repo_test.cpp b/searchcore/src/tests/proton/attribute/imported_attributes_repo/imported_attributes_repo_test.cpp index c41b88be2b4..e23c308050b 100644 --- a/searchcore/src/tests/proton/attribute/imported_attributes_repo/imported_attributes_repo_test.cpp +++ b/searchcore/src/tests/proton/attribute/imported_attributes_repo/imported_attributes_repo_test.cpp @@ -22,6 +22,7 @@ createAttr(const vespalib::string &name) return std::make_shared<ImportedAttributeVector>(name, ReferenceAttribute::SP(), AttributeVector::SP(), + std::shared_ptr<search::IDocumentMetaStoreContext>(), false); } diff --git a/searchcore/src/tests/proton/documentdb/configurer/configurer_test.cpp b/searchcore/src/tests/proton/documentdb/configurer/configurer_test.cpp index 45bda8c69cc..412c7abac5b 100644 --- a/searchcore/src/tests/proton/documentdb/configurer/configurer_test.cpp +++ b/searchcore/src/tests/proton/documentdb/configurer/configurer_test.cpp @@ -95,7 +95,7 @@ struct ViewSet DocIdLimit _docIdLimit; search::transactionlog::NoSyncProxy _noTlSyncer; ISummaryManager::SP _summaryMgr; - IDocumentMetaStoreContext::SP _dmsc; + proton::IDocumentMetaStoreContext::SP _dmsc; std::shared_ptr<IGidToLidChangeHandler> _gidToLidChangeHandler; std::unique_ptr<documentmetastore::ILidReuseDelayer> _lidReuseDelayer; CommitTimeTracker _commitTimeTracker; @@ -143,6 +143,7 @@ struct EmptyConstantValueFactory : public vespalib::eval::ConstantValueFactory { struct MyDocumentDBReferenceResolver : public IDocumentDBReferenceResolver { std::unique_ptr<ImportedAttributesRepo> resolve(const search::IAttributeManager &, const search::IAttributeManager &, + const std::shared_ptr<search::IDocumentMetaStoreContext> &, fastos::TimeStamp) override { return std::make_unique<ImportedAttributesRepo>(); } @@ -268,7 +269,7 @@ struct MyFastAccessFeedView IThreadingService &_writeService; HwInfo _hwInfo; - IDocumentMetaStoreContext::SP _dmsc; + proton::IDocumentMetaStoreContext::SP _dmsc; std::shared_ptr<IGidToLidChangeHandler> _gidToLidChangeHandler; std::unique_ptr<documentmetastore::ILidReuseDelayer> _lidReuseDelayer; CommitTimeTracker _commitTimeTracker; diff --git a/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp b/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp index 8cd57b1b0cb..9eddef36436 100644 --- a/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp +++ b/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp @@ -84,7 +84,7 @@ struct MySubDBOwner : public IDocumentSubDBOwner struct MySyncProxy : public SyncProxy { - virtual void sync(SerialNum) override {} + virtual void sync(SerialNum) override {} }; @@ -95,59 +95,60 @@ struct MyGetSerialNum : public IGetSerialNum struct MyFileHeaderContext : public FileHeaderContext { - virtual void addTags(vespalib::GenericHeader &, const vespalib::string &) const override {} + virtual void addTags(vespalib::GenericHeader &, const vespalib::string &) const override {} }; struct MyMetricsWireService : public DummyWireService { - std::set<vespalib::string> _attributes; - MyMetricsWireService() : _attributes() {} - virtual void addAttribute(const AttributeMetricsCollection &, LegacyAttributeMetrics *, const std::string &name) override { - _attributes.insert(name); - } + std::set<vespalib::string> _attributes; + MyMetricsWireService() : _attributes() {} + virtual void addAttribute(const AttributeMetricsCollection &, LegacyAttributeMetrics *, const std::string &name) override { + _attributes.insert(name); + } }; struct MyDocumentDBReferenceResolver : public IDocumentDBReferenceResolver { std::unique_ptr<ImportedAttributesRepo> resolve(const search::IAttributeManager &, - const search::IAttributeManager &, + const search::IAttributeManager &, + const std::shared_ptr<search::IDocumentMetaStoreContext> &, fastos::TimeStamp) override { return std::make_unique<ImportedAttributesRepo>(); - } + } void teardown(const search::IAttributeManager &) override { } }; struct MyStoreOnlyConfig { - StoreOnlyConfig _cfg; - MyStoreOnlyConfig() - : _cfg(DocTypeName(DOCTYPE_NAME), - SUB_NAME, - BASE_DIR, - GrowStrategy(), + StoreOnlyConfig _cfg; + MyStoreOnlyConfig() + : _cfg(DocTypeName(DOCTYPE_NAME), + SUB_NAME, + BASE_DIR, + GrowStrategy(), 0, 0, SubDbType::READY) - { - } + { + } }; struct MyStoreOnlyContext { - MySubDBOwner _owner; - MySyncProxy _syncProxy; - MyGetSerialNum _getSerialNum; - MyFileHeaderContext _fileHeader; - LegacyDocumentDBMetrics _metrics; - std::mutex _configMutex; - HwInfo _hwInfo; - StoreOnlyContext _ctx; - MyStoreOnlyContext(IThreadingService &writeService, - ThreadStackExecutorBase &summaryExecutor, + MySubDBOwner _owner; + MySyncProxy _syncProxy; + MyGetSerialNum _getSerialNum; + MyFileHeaderContext _fileHeader; + LegacyDocumentDBMetrics _metrics; + std::mutex _configMutex; + HwInfo _hwInfo; + StoreOnlyContext _ctx; + MyStoreOnlyContext(IThreadingService &writeService, + ThreadStackExecutorBase &summaryExecutor, std::shared_ptr<BucketDBOwner> bucketDB, IBucketDBHandlerInitializer & bucketDBHandlerInitializer); - ~MyStoreOnlyContext(); - const MySubDBOwner &getOwner() const { - return _owner; - } + ~MyStoreOnlyContext(); + const MySubDBOwner &getOwner() const { + return _owner; + } }; MyStoreOnlyContext::MyStoreOnlyContext(IThreadingService &writeService, ThreadStackExecutorBase &summaryExecutor, @@ -164,32 +165,32 @@ MyStoreOnlyContext::~MyStoreOnlyContext() {} template <bool FastAccessAttributesOnly> struct MyFastAccessConfig { - FastAccessConfig _cfg; - MyFastAccessConfig() - : _cfg(MyStoreOnlyConfig()._cfg, true, true, FastAccessAttributesOnly) - { - } + FastAccessConfig _cfg; + MyFastAccessConfig() + : _cfg(MyStoreOnlyConfig()._cfg, true, true, FastAccessAttributesOnly) + { + } }; struct MyFastAccessContext { - MyStoreOnlyContext _storeOnlyCtx; - AttributeMetrics _attributeMetrics; - LegacyAttributeMetrics _legacyAttributeMetrics; - AttributeMetricsCollection _attributeMetricsCollection; - MyMetricsWireService _wireService; - FastAccessContext _ctx; - MyFastAccessContext(IThreadingService &writeService, - ThreadStackExecutorBase &summaryExecutor, + MyStoreOnlyContext _storeOnlyCtx; + AttributeMetrics _attributeMetrics; + LegacyAttributeMetrics _legacyAttributeMetrics; + AttributeMetricsCollection _attributeMetricsCollection; + MyMetricsWireService _wireService; + FastAccessContext _ctx; + MyFastAccessContext(IThreadingService &writeService, + ThreadStackExecutorBase &summaryExecutor, std::shared_ptr<BucketDBOwner> bucketDB, IBucketDBHandlerInitializer & bucketDBHandlerInitializer); ~MyFastAccessContext(); - const MyMetricsWireService &getWireService() const { - return _wireService; - } - const MySubDBOwner &getOwner() const { - return _storeOnlyCtx.getOwner(); - } + const MyMetricsWireService &getWireService() const { + return _wireService; + } + const MySubDBOwner &getOwner() const { + return _storeOnlyCtx.getOwner(); + } }; MyFastAccessContext::MyFastAccessContext(IThreadingService &writeService, ThreadStackExecutorBase &summaryExecutor, @@ -205,30 +206,30 @@ MyFastAccessContext::~MyFastAccessContext() {} struct MySearchableConfig { - SearchableConfig _cfg; - MySearchableConfig() - : _cfg(MyFastAccessConfig<false>()._cfg, 1) - { - } + SearchableConfig _cfg; + MySearchableConfig() + : _cfg(MyFastAccessConfig<false>()._cfg, 1) + { + } }; struct MySearchableContext { - MyFastAccessContext _fastUpdCtx; - QueryLimiter _queryLimiter; - vespalib::Clock _clock; - SearchableContext _ctx; - MySearchableContext(IThreadingService &writeService, - ThreadStackExecutorBase &executor, + MyFastAccessContext _fastUpdCtx; + QueryLimiter _queryLimiter; + vespalib::Clock _clock; + SearchableContext _ctx; + MySearchableContext(IThreadingService &writeService, + ThreadStackExecutorBase &executor, std::shared_ptr<BucketDBOwner> bucketDB, IBucketDBHandlerInitializer & bucketDBHandlerInitializer); ~MySearchableContext(); - const MyMetricsWireService &getWireService() const { - return _fastUpdCtx.getWireService(); - } - const MySubDBOwner &getOwner() const { - return _fastUpdCtx.getOwner(); - } + const MyMetricsWireService &getWireService() const { + return _fastUpdCtx.getWireService(); + } + const MySubDBOwner &getOwner() const { + return _fastUpdCtx.getOwner(); + } }; @@ -243,88 +244,88 @@ MySearchableContext::~MySearchableContext() {} struct OneAttrSchema : public Schema { - OneAttrSchema() { - addAttributeField(Schema::AttributeField("attr1", Schema::DataType::INT32)); - } + OneAttrSchema() { + addAttributeField(Schema::AttributeField("attr1", Schema::DataType::INT32)); + } }; struct TwoAttrSchema : public OneAttrSchema { - TwoAttrSchema() { - addAttributeField(Schema::AttributeField("attr2", Schema::DataType::INT32)); - } + TwoAttrSchema() { + addAttributeField(Schema::AttributeField("attr2", Schema::DataType::INT32)); + } }; struct MyConfigSnapshot { typedef std::unique_ptr<MyConfigSnapshot> UP; Schema _schema; - DocBuilder _builder; - DocumentDBConfig::SP _cfg; - MyConfigSnapshot(const Schema &schema, - const vespalib::string &cfgDir) - : _schema(schema), - _builder(_schema), - _cfg() - { - DocumentDBConfig::DocumenttypesConfigSP documenttypesConfig - (new DocumenttypesConfig(_builder.getDocumenttypesConfig())); - TuneFileDocumentDB::SP tuneFileDocumentDB(new TuneFileDocumentDB()); - BootstrapConfig::SP bootstrap - (new BootstrapConfig(1, + DocBuilder _builder; + DocumentDBConfig::SP _cfg; + MyConfigSnapshot(const Schema &schema, + const vespalib::string &cfgDir) + : _schema(schema), + _builder(_schema), + _cfg() + { + DocumentDBConfig::DocumenttypesConfigSP documenttypesConfig + (new DocumenttypesConfig(_builder.getDocumenttypesConfig())); + TuneFileDocumentDB::SP tuneFileDocumentDB(new TuneFileDocumentDB()); + BootstrapConfig::SP bootstrap + (new BootstrapConfig(1, documenttypesConfig, _builder.getDocumentTypeRepo(), std::make_shared<ProtonConfig>(), std::make_shared<FiledistributorrpcConfig>(), tuneFileDocumentDB)); - config::DirSpec spec(cfgDir); - DocumentDBConfigHelper mgr(spec, "searchdocument"); - mgr.forwardConfig(bootstrap); - mgr.nextGeneration(1); - _cfg = mgr.getConfig(); - } + config::DirSpec spec(cfgDir); + DocumentDBConfigHelper mgr(spec, "searchdocument"); + mgr.forwardConfig(bootstrap); + mgr.nextGeneration(1); + _cfg = mgr.getConfig(); + } }; template <typename Traits> struct FixtureBase { - ExecutorThreadingService _writeService; - ThreadStackExecutor _summaryExecutor; - typename Traits::Config _cfg; + ExecutorThreadingService _writeService; + ThreadStackExecutor _summaryExecutor; + typename Traits::Config _cfg; std::shared_ptr<BucketDBOwner> _bucketDB; BucketDBHandler _bucketDBHandler; - typename Traits::Context _ctx; - typename Traits::Schema _baseSchema; - MyConfigSnapshot::UP _snapshot; - DirectoryHandler _baseDir; - typename Traits::SubDB _subDb; - IFeedView::SP _tmpFeedView; - FixtureBase() - : _writeService(), - _summaryExecutor(1, 64 * 1024), - _cfg(), + typename Traits::Context _ctx; + typename Traits::Schema _baseSchema; + MyConfigSnapshot::UP _snapshot; + DirectoryHandler _baseDir; + typename Traits::SubDB _subDb; + IFeedView::SP _tmpFeedView; + FixtureBase() + : _writeService(), + _summaryExecutor(1, 64 * 1024), + _cfg(), _bucketDB(std::make_shared<BucketDBOwner>()), _bucketDBHandler(*_bucketDB), - _ctx(_writeService, _summaryExecutor, _bucketDB, + _ctx(_writeService, _summaryExecutor, _bucketDB, _bucketDBHandler), - _baseSchema(), - _snapshot(new MyConfigSnapshot(_baseSchema, Traits::ConfigDir::dir())), - _baseDir(BASE_DIR + "/" + SUB_NAME, BASE_DIR), - _subDb(_cfg._cfg, _ctx._ctx), + _baseSchema(), + _snapshot(new MyConfigSnapshot(_baseSchema, Traits::ConfigDir::dir())), + _baseDir(BASE_DIR + "/" + SUB_NAME, BASE_DIR), + _subDb(_cfg._cfg, _ctx._ctx), _tmpFeedView() - { - init(); - } - ~FixtureBase() { - _writeService.sync(); + { + init(); + } + ~FixtureBase() { + _writeService.sync(); _writeService.master().execute(makeLambdaTask([this]() { _subDb.close(); })); - _writeService.sync(); - } + _writeService.sync(); + } template <typename FunctionType> void runInMaster(FunctionType func) { proton::test::runInMaster(_writeService, func); } - void init() { + void init() { DocumentSubDbInitializer::SP task = _subDb.createInitializer(*_snapshot->_cfg, Traits::configSerial(), @@ -333,59 +334,59 @@ struct FixtureBase vespalib::ThreadStackExecutor executor(1, 1024 * 1024); initializer::TaskRunner taskRunner(executor); taskRunner.runTask(task); - SessionManager::SP sessionMgr(new SessionManager(1)); - runInMaster([&] () { _subDb.initViews(*_snapshot->_cfg, sessionMgr); }); - } - void basicReconfig(SerialNum serialNum) { - runInMaster([&] () { performReconfig(serialNum, TwoAttrSchema(), ConfigDir2::dir()); }); - } - void reconfig(SerialNum serialNum, - const Schema &reconfigSchema, - const vespalib::string &reconfigConfigDir) { - runInMaster([&] () { performReconfig(serialNum, reconfigSchema, reconfigConfigDir); }); + SessionManager::SP sessionMgr(new SessionManager(1)); + runInMaster([&] () { _subDb.initViews(*_snapshot->_cfg, sessionMgr); }); + } + void basicReconfig(SerialNum serialNum) { + runInMaster([&] () { performReconfig(serialNum, TwoAttrSchema(), ConfigDir2::dir()); }); + } + void reconfig(SerialNum serialNum, + const Schema &reconfigSchema, + const vespalib::string &reconfigConfigDir) { + runInMaster([&] () { performReconfig(serialNum, reconfigSchema, reconfigConfigDir); }); } - void performReconfig(SerialNum serialNum, - const Schema &reconfigSchema, - const vespalib::string &reconfigConfigDir) { - MyConfigSnapshot::UP newCfg(new MyConfigSnapshot(reconfigSchema, reconfigConfigDir)); - DocumentDBConfig::ComparisonResult cmpResult; - cmpResult.attributesChanged = true; - cmpResult.documenttypesChanged = true; - cmpResult.documentTypeRepoChanged = true; - MyDocumentDBReferenceResolver resolver; - IReprocessingTask::List tasks = - _subDb.applyConfig(*newCfg->_cfg, - *_snapshot->_cfg, - serialNum, - ReconfigParams(cmpResult), - resolver); - _snapshot = std::move(newCfg); - if (!tasks.empty()) { - ReprocessingRunner runner; - runner.addTasks(tasks); - runner.run(); - } - _subDb.onReprocessDone(serialNum); - } - void sync() { - _writeService.master().sync(); - } - proton::IAttributeManager::SP getAttributeManager() { - return _subDb.getAttributeManager(); - } - const typename Traits::FeedView *getFeedView() { - _tmpFeedView = _subDb.getFeedView(); - const typename Traits::FeedView *retval = - dynamic_cast<typename Traits::FeedView *>(_tmpFeedView.get()); - ASSERT_TRUE(retval != NULL); - return retval; - } - const MyMetricsWireService &getWireService() const { - return _ctx.getWireService(); - } - const MySubDBOwner &getOwner() const { - return _ctx.getOwner(); - } + void performReconfig(SerialNum serialNum, + const Schema &reconfigSchema, + const vespalib::string &reconfigConfigDir) { + MyConfigSnapshot::UP newCfg(new MyConfigSnapshot(reconfigSchema, reconfigConfigDir)); + DocumentDBConfig::ComparisonResult cmpResult; + cmpResult.attributesChanged = true; + cmpResult.documenttypesChanged = true; + cmpResult.documentTypeRepoChanged = true; + MyDocumentDBReferenceResolver resolver; + IReprocessingTask::List tasks = + _subDb.applyConfig(*newCfg->_cfg, + *_snapshot->_cfg, + serialNum, + ReconfigParams(cmpResult), + resolver); + _snapshot = std::move(newCfg); + if (!tasks.empty()) { + ReprocessingRunner runner; + runner.addTasks(tasks); + runner.run(); + } + _subDb.onReprocessDone(serialNum); + } + void sync() { + _writeService.master().sync(); + } + proton::IAttributeManager::SP getAttributeManager() { + return _subDb.getAttributeManager(); + } + const typename Traits::FeedView *getFeedView() { + _tmpFeedView = _subDb.getFeedView(); + const typename Traits::FeedView *retval = + dynamic_cast<typename Traits::FeedView *>(_tmpFeedView.get()); + ASSERT_TRUE(retval != NULL); + return retval; + } + const MyMetricsWireService &getWireService() const { + return _ctx.getWireService(); + } + const MySubDBOwner &getOwner() const { + return _ctx.getOwner(); + } }; template <typename SchemaT, typename ConfigDirT, uint32_t ConfigSerial = CFG_SERIAL> @@ -446,82 +447,82 @@ typedef FixtureBase<SearchableTraits> SearchableFixture; void assertAttributes1(const AttributeGuardList &attributes) { - EXPECT_EQUAL(1u, attributes.size()); - EXPECT_EQUAL("attr1", attributes[0]->getName()); + EXPECT_EQUAL(1u, attributes.size()); + EXPECT_EQUAL("attr1", attributes[0]->getName()); } void assertAttributes1(const std::vector<search::AttributeVector *> &attributes) { - EXPECT_EQUAL(1u, attributes.size()); - EXPECT_EQUAL("attr1", attributes[0]->getName()); + EXPECT_EQUAL(1u, attributes.size()); + EXPECT_EQUAL("attr1", attributes[0]->getName()); } void assertAttributes2(const AttributeGuardList &attributes) { - EXPECT_EQUAL(2u, attributes.size()); - EXPECT_EQUAL("attr1", attributes[0]->getName()); - EXPECT_EQUAL("attr2", attributes[1]->getName()); + EXPECT_EQUAL(2u, attributes.size()); + EXPECT_EQUAL("attr1", attributes[0]->getName()); + EXPECT_EQUAL("attr2", attributes[1]->getName()); } void assertAttributes2(const std::vector<search::AttributeVector *> &attributes) { - EXPECT_EQUAL(2u, attributes.size()); - EXPECT_EQUAL("attr1", attributes[0]->getName()); - EXPECT_EQUAL("attr2", attributes[1]->getName()); + EXPECT_EQUAL(2u, attributes.size()); + EXPECT_EQUAL("attr1", attributes[0]->getName()); + EXPECT_EQUAL("attr2", attributes[1]->getName()); } TEST_F("require that managers and components are instantiated", StoreOnlyFixture) { - EXPECT_TRUE(f._subDb.getSummaryManager().get() != NULL); - EXPECT_TRUE(f._subDb.getSummaryAdapter().get() != NULL); - EXPECT_TRUE(f._subDb.getAttributeManager().get() == NULL); - EXPECT_TRUE(f._subDb.getIndexManager().get() == NULL); - EXPECT_TRUE(f._subDb.getIndexWriter().get() == NULL); - EXPECT_TRUE(f._subDb.getFeedView().get() != NULL); - EXPECT_TRUE(f._subDb.getSearchView().get() != NULL); - EXPECT_TRUE(dynamic_cast<StoreOnlyFeedView *>(f._subDb.getFeedView().get()) != NULL); - EXPECT_TRUE(dynamic_cast<EmptySearchView *>(f._subDb.getSearchView().get()) != NULL); - EXPECT_TRUE(dynamic_cast<MinimalDocumentRetriever *>(f._subDb.getDocumentRetriever().get()) != NULL); + EXPECT_TRUE(f._subDb.getSummaryManager().get() != NULL); + EXPECT_TRUE(f._subDb.getSummaryAdapter().get() != NULL); + EXPECT_TRUE(f._subDb.getAttributeManager().get() == NULL); + EXPECT_TRUE(f._subDb.getIndexManager().get() == NULL); + EXPECT_TRUE(f._subDb.getIndexWriter().get() == NULL); + EXPECT_TRUE(f._subDb.getFeedView().get() != NULL); + EXPECT_TRUE(f._subDb.getSearchView().get() != NULL); + EXPECT_TRUE(dynamic_cast<StoreOnlyFeedView *>(f._subDb.getFeedView().get()) != NULL); + EXPECT_TRUE(dynamic_cast<EmptySearchView *>(f._subDb.getSearchView().get()) != NULL); + EXPECT_TRUE(dynamic_cast<MinimalDocumentRetriever *>(f._subDb.getDocumentRetriever().get()) != NULL); } TEST_F("require that managers and components are instantiated", FastAccessFixture) { - EXPECT_TRUE(f._subDb.getSummaryManager().get() != NULL); - EXPECT_TRUE(f._subDb.getSummaryAdapter().get() != NULL); - EXPECT_TRUE(f._subDb.getAttributeManager().get() != NULL); - EXPECT_TRUE(f._subDb.getIndexManager().get() == NULL); - EXPECT_TRUE(f._subDb.getIndexWriter().get() == NULL); - EXPECT_TRUE(f._subDb.getFeedView().get() != NULL); - EXPECT_TRUE(f._subDb.getSearchView().get() != NULL); - EXPECT_TRUE(dynamic_cast<FastAccessFeedView *>(f._subDb.getFeedView().get()) != NULL); - EXPECT_TRUE(dynamic_cast<EmptySearchView *>(f._subDb.getSearchView().get()) != NULL); - EXPECT_TRUE(dynamic_cast<FastAccessDocumentRetriever *>(f._subDb.getDocumentRetriever().get()) != NULL); + EXPECT_TRUE(f._subDb.getSummaryManager().get() != NULL); + EXPECT_TRUE(f._subDb.getSummaryAdapter().get() != NULL); + EXPECT_TRUE(f._subDb.getAttributeManager().get() != NULL); + EXPECT_TRUE(f._subDb.getIndexManager().get() == NULL); + EXPECT_TRUE(f._subDb.getIndexWriter().get() == NULL); + EXPECT_TRUE(f._subDb.getFeedView().get() != NULL); + EXPECT_TRUE(f._subDb.getSearchView().get() != NULL); + EXPECT_TRUE(dynamic_cast<FastAccessFeedView *>(f._subDb.getFeedView().get()) != NULL); + EXPECT_TRUE(dynamic_cast<EmptySearchView *>(f._subDb.getSearchView().get()) != NULL); + EXPECT_TRUE(dynamic_cast<FastAccessDocumentRetriever *>(f._subDb.getDocumentRetriever().get()) != NULL); } TEST_F("require that managers and components are instantiated", SearchableFixture) { - EXPECT_TRUE(f._subDb.getSummaryManager().get() != NULL); - EXPECT_TRUE(f._subDb.getSummaryAdapter().get() != NULL); - EXPECT_TRUE(f._subDb.getAttributeManager().get() != NULL); - EXPECT_TRUE(f._subDb.getIndexManager().get() != NULL); - EXPECT_TRUE(f._subDb.getIndexWriter().get() != NULL); - EXPECT_TRUE(f._subDb.getFeedView().get() != NULL); - EXPECT_TRUE(f._subDb.getSearchView().get() != NULL); - EXPECT_TRUE(dynamic_cast<SearchableFeedView *>(f._subDb.getFeedView().get()) != NULL); - EXPECT_TRUE(dynamic_cast<SearchView *>(f._subDb.getSearchView().get()) != NULL); - EXPECT_TRUE(dynamic_cast<FastAccessDocumentRetriever *>(f._subDb.getDocumentRetriever().get()) != NULL); + EXPECT_TRUE(f._subDb.getSummaryManager().get() != NULL); + EXPECT_TRUE(f._subDb.getSummaryAdapter().get() != NULL); + EXPECT_TRUE(f._subDb.getAttributeManager().get() != NULL); + EXPECT_TRUE(f._subDb.getIndexManager().get() != NULL); + EXPECT_TRUE(f._subDb.getIndexWriter().get() != NULL); + EXPECT_TRUE(f._subDb.getFeedView().get() != NULL); + EXPECT_TRUE(f._subDb.getSearchView().get() != NULL); + EXPECT_TRUE(dynamic_cast<SearchableFeedView *>(f._subDb.getFeedView().get()) != NULL); + EXPECT_TRUE(dynamic_cast<SearchView *>(f._subDb.getSearchView().get()) != NULL); + EXPECT_TRUE(dynamic_cast<FastAccessDocumentRetriever *>(f._subDb.getDocumentRetriever().get()) != NULL); } template<typename Fixture> void requireThatAttributeManagerIsInstantiated(Fixture &f) { - std::vector<AttributeGuard> attributes; - f.getAttributeManager()->getAttributeList(attributes); - assertAttributes1(attributes); + std::vector<AttributeGuard> attributes; + f.getAttributeManager()->getAttributeList(attributes); + assertAttributes1(attributes); } TEST_F("require that attribute manager is instantiated", FastAccessFixture) @@ -538,7 +539,7 @@ template <typename Fixture> void requireThatAttributesAreAccessibleViaFeedView(Fixture &f) { - assertAttributes1(f.getFeedView()->getAttributeWriter()->getWritableAttributes()); + assertAttributes1(f.getFeedView()->getAttributeWriter()->getWritableAttributes()); } TEST_F("require that attributes are accessible via feed view", FastAccessFixture) @@ -555,10 +556,10 @@ template <typename Fixture> void requireThatAttributeManagerCanBeReconfigured(Fixture &f) { - f.basicReconfig(10); - std::vector<AttributeGuard> attributes; - f.getAttributeManager()->getAttributeList(attributes); - assertAttributes2(attributes); + f.basicReconfig(10); + std::vector<AttributeGuard> attributes; + f.getAttributeManager()->getAttributeList(attributes); + assertAttributes2(attributes); } TEST_F("require that attribute manager can be reconfigured", FastAccessFixture) @@ -575,8 +576,8 @@ template <typename Fixture> void requireThatReconfiguredAttributesAreAccessibleViaFeedView(Fixture &f) { - f.basicReconfig(10); - assertAttributes2(f.getFeedView()->getAttributeWriter()->getWritableAttributes()); + f.basicReconfig(10); + assertAttributes2(f.getFeedView()->getAttributeWriter()->getWritableAttributes()); } TEST_F("require that reconfigured attributes are accessible via feed view", FastAccessFixture) @@ -593,9 +594,9 @@ template <typename Fixture> void requireThatOwnerIsNotifiedWhenFeedViewChanges(Fixture &f) { - EXPECT_EQUAL(0u, f.getOwner()._syncCnt); - f.basicReconfig(10); - EXPECT_EQUAL(1u, f.getOwner()._syncCnt); + EXPECT_EQUAL(0u, f.getOwner()._syncCnt); + f.basicReconfig(10); + EXPECT_EQUAL(1u, f.getOwner()._syncCnt); } TEST_F("require that owner is noticed when feed view changes", StoreOnlyFixture) @@ -610,19 +611,19 @@ TEST_F("require that owner is noticed when feed view changes", FastAccessFixture TEST_F("require that owner is noticed when feed view changes", SearchableFixture) { - EXPECT_EQUAL(1u, f.getOwner()._syncCnt); // NOTE: init also notifies owner - f.basicReconfig(10); - EXPECT_EQUAL(2u, f.getOwner()._syncCnt); + EXPECT_EQUAL(1u, f.getOwner()._syncCnt); // NOTE: init also notifies owner + f.basicReconfig(10); + EXPECT_EQUAL(2u, f.getOwner()._syncCnt); } template <typename Fixture> void requireThatAttributeMetricsAreRegistered(Fixture &f) { - EXPECT_EQUAL(2u, f.getWireService()._attributes.size()); - auto itr = f.getWireService()._attributes.begin(); - EXPECT_EQUAL("[documentmetastore]", *itr++); - EXPECT_EQUAL("attr1", *itr); + EXPECT_EQUAL(2u, f.getWireService()._attributes.size()); + auto itr = f.getWireService()._attributes.begin(); + EXPECT_EQUAL("[documentmetastore]", *itr++); + EXPECT_EQUAL("attr1", *itr); } TEST_F("require that attribute metrics are registered", FastAccessFixture) @@ -639,12 +640,12 @@ template <typename Fixture> void requireThatAttributeMetricsCanBeReconfigured(Fixture &f) { - f.basicReconfig(10); - EXPECT_EQUAL(3u, f.getWireService()._attributes.size()); - auto itr = f.getWireService()._attributes.begin(); - EXPECT_EQUAL("[documentmetastore]", *itr++); - EXPECT_EQUAL("attr1", *itr++); - EXPECT_EQUAL("attr2", *itr); + f.basicReconfig(10); + EXPECT_EQUAL(3u, f.getWireService()._attributes.size()); + auto itr = f.getWireService()._attributes.begin(); + EXPECT_EQUAL("[documentmetastore]", *itr++); + EXPECT_EQUAL("attr1", *itr++); + EXPECT_EQUAL("attr2", *itr); } TEST_F("require that attribute metrics can be reconfigured", FastAccessFixture) @@ -661,11 +662,11 @@ template <typename Fixture> IFlushTarget::List getFlushTargets(Fixture &f) { - IFlushTarget::List targets = (static_cast<IDocumentSubDB &>(f._subDb)).getFlushTargets(); - std::sort(targets.begin(), targets.end(), - [](const IFlushTarget::SP &lhs, const IFlushTarget::SP &rhs) { - return lhs->getName() < rhs->getName(); }); - return targets; + IFlushTarget::List targets = (static_cast<IDocumentSubDB &>(f._subDb)).getFlushTargets(); + std::sort(targets.begin(), targets.end(), + [](const IFlushTarget::SP &lhs, const IFlushTarget::SP &rhs) { + return lhs->getName() < rhs->getName(); }); + return targets; } typedef IFlushTarget::Type FType; @@ -685,38 +686,38 @@ assertTarget(const vespalib::string &name, TEST_F("require that flush targets can be retrieved", FastAccessFixture) { - IFlushTarget::List targets = getFlushTargets(f); - EXPECT_EQUAL(7u, targets.size()); - EXPECT_EQUAL("subdb.attribute.flush.attr1", targets[0]->getName()); - EXPECT_EQUAL("subdb.attribute.shrink.attr1", targets[1]->getName()); - EXPECT_EQUAL("subdb.documentmetastore.flush", targets[2]->getName()); - EXPECT_EQUAL("subdb.documentmetastore.shrink", targets[3]->getName()); - EXPECT_EQUAL("subdb.summary.compact", targets[4]->getName()); - EXPECT_EQUAL("subdb.summary.flush", targets[5]->getName()); - EXPECT_EQUAL("subdb.summary.shrink", targets[6]->getName()); + IFlushTarget::List targets = getFlushTargets(f); + EXPECT_EQUAL(7u, targets.size()); + EXPECT_EQUAL("subdb.attribute.flush.attr1", targets[0]->getName()); + EXPECT_EQUAL("subdb.attribute.shrink.attr1", targets[1]->getName()); + EXPECT_EQUAL("subdb.documentmetastore.flush", targets[2]->getName()); + EXPECT_EQUAL("subdb.documentmetastore.shrink", targets[3]->getName()); + EXPECT_EQUAL("subdb.summary.compact", targets[4]->getName()); + EXPECT_EQUAL("subdb.summary.flush", targets[5]->getName()); + EXPECT_EQUAL("subdb.summary.shrink", targets[6]->getName()); } TEST_F("require that flush targets can be retrieved", SearchableFixture) { - IFlushTarget::List targets = getFlushTargets(f); - EXPECT_EQUAL(9u, targets.size()); - EXPECT_TRUE(assertTarget("subdb.attribute.flush.attr1", FType::SYNC, FComponent::ATTRIBUTE, *targets[0])); - EXPECT_TRUE(assertTarget("subdb.attribute.shrink.attr1", FType::GC, FComponent::ATTRIBUTE, *targets[1])); - EXPECT_TRUE(assertTarget("subdb.documentmetastore.flush", FType::SYNC, FComponent::ATTRIBUTE, *targets[2])); - EXPECT_TRUE(assertTarget("subdb.documentmetastore.shrink", FType::GC, FComponent::ATTRIBUTE, *targets[3])); - EXPECT_TRUE(assertTarget("subdb.memoryindex.flush", FType::FLUSH, FComponent::INDEX, *targets[4])); - EXPECT_TRUE(assertTarget("subdb.memoryindex.fusion", FType::GC, FComponent::INDEX, *targets[5])); - EXPECT_TRUE(assertTarget("subdb.summary.compact", FType::GC, FComponent::DOCUMENT_STORE, *targets[6])); - EXPECT_TRUE(assertTarget("subdb.summary.flush", FType::SYNC, FComponent::DOCUMENT_STORE, *targets[7])); - EXPECT_TRUE(assertTarget("subdb.summary.shrink", FType::GC, FComponent::DOCUMENT_STORE, *targets[8])); + IFlushTarget::List targets = getFlushTargets(f); + EXPECT_EQUAL(9u, targets.size()); + EXPECT_TRUE(assertTarget("subdb.attribute.flush.attr1", FType::SYNC, FComponent::ATTRIBUTE, *targets[0])); + EXPECT_TRUE(assertTarget("subdb.attribute.shrink.attr1", FType::GC, FComponent::ATTRIBUTE, *targets[1])); + EXPECT_TRUE(assertTarget("subdb.documentmetastore.flush", FType::SYNC, FComponent::ATTRIBUTE, *targets[2])); + EXPECT_TRUE(assertTarget("subdb.documentmetastore.shrink", FType::GC, FComponent::ATTRIBUTE, *targets[3])); + EXPECT_TRUE(assertTarget("subdb.memoryindex.flush", FType::FLUSH, FComponent::INDEX, *targets[4])); + EXPECT_TRUE(assertTarget("subdb.memoryindex.fusion", FType::GC, FComponent::INDEX, *targets[5])); + EXPECT_TRUE(assertTarget("subdb.summary.compact", FType::GC, FComponent::DOCUMENT_STORE, *targets[6])); + EXPECT_TRUE(assertTarget("subdb.summary.flush", FType::SYNC, FComponent::DOCUMENT_STORE, *targets[7])); + EXPECT_TRUE(assertTarget("subdb.summary.shrink", FType::GC, FComponent::DOCUMENT_STORE, *targets[8])); } TEST_F("require that only fast-access attributes are instantiated", FastAccessOnlyFixture) { - std::vector<AttributeGuard> attrs; - f.getAttributeManager()->getAttributeList(attrs); - EXPECT_EQUAL(1u, attrs.size()); - EXPECT_EQUAL("attr1", attrs[0]->getName()); + std::vector<AttributeGuard> attrs; + f.getAttributeManager()->getAttributeList(attrs); + EXPECT_EQUAL(1u, attrs.size()); + EXPECT_EQUAL("attr1", attrs[0]->getName()); } template <typename FixtureType> @@ -803,12 +804,12 @@ assertAttribute(const AttributeGuard &attr, SerialNum createSerialNum, SerialNum lastSerialNum) { - EXPECT_EQUAL(name, attr->getName()); - EXPECT_EQUAL(numDocs, attr->getNumDocs()); - EXPECT_EQUAL(doc1Value, attr->getInt(1)); - EXPECT_EQUAL(doc2Value, attr->getInt(2)); - EXPECT_EQUAL(createSerialNum, attr->getCreateSerialNum()); - EXPECT_EQUAL(lastSerialNum, attr->getStatus().getLastSyncToken()); + EXPECT_EQUAL(name, attr->getName()); + EXPECT_EQUAL(numDocs, attr->getNumDocs()); + EXPECT_EQUAL(doc1Value, attr->getInt(1)); + EXPECT_EQUAL(doc2Value, attr->getInt(2)); + EXPECT_EQUAL(createSerialNum, attr->getCreateSerialNum()); + EXPECT_EQUAL(lastSerialNum, attr->getStatus().getLastSyncToken()); } void @@ -833,9 +834,9 @@ TEST_F("require that fast-access attributes are populated during feed", FastAcce DocumentHandler<FastAccessOnlyFixture> handler(f); handler.putDocs(); - std::vector<AttributeGuard> attrs; - f.getAttributeManager()->getAttributeList(attrs); - EXPECT_EQUAL(1u, attrs.size()); + std::vector<AttributeGuard> attrs; + f.getAttributeManager()->getAttributeList(attrs); + EXPECT_EQUAL(1u, attrs.size()); assertAttribute1(attrs[0], CFG_SERIAL, 20); } 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 index a6576d11279..40f9ed9b749 100644 --- 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 @@ -226,7 +226,7 @@ struct Fixture { } ImportedAttributesRepo::UP resolve(fastos::TimeStamp visibilityDelay) { DocumentDBReferenceResolver resolver(registry, docModel.childDocType, importedFieldsCfg, docModel.childDocType, _gidToLidChangeListenerRefCount, _attributeFieldWriter); - return resolver.resolve(attrMgr, oldAttrMgr, visibilityDelay); + return resolver.resolve(attrMgr, oldAttrMgr, std::shared_ptr<search::IDocumentMetaStoreContext>(), visibilityDelay); } ImportedAttributesRepo::UP resolve() { return resolve(fastos::TimeStamp(0)); diff --git a/searchcore/src/tests/proton/server/visibility_handler/visibility_handler_test.cpp b/searchcore/src/tests/proton/server/visibility_handler/visibility_handler_test.cpp index 350c88ae0e5..69b8a482476 100644 --- a/searchcore/src/tests/proton/server/visibility_handler/visibility_handler_test.cpp +++ b/searchcore/src/tests/proton/server/visibility_handler/visibility_handler_test.cpp @@ -99,9 +99,10 @@ public: testCommit(double visibilityDelay, bool internal, uint32_t expForceCommitCount, SerialNum expCommittedSerialNum, uint32_t expMasterExecuteCnt, - uint32_t expAttributeFieldWriterSyncCnt) + uint32_t expAttributeFieldWriterSyncCnt, + SerialNum currSerialNum = 10u) { - _getSerialNum.setSerialNum(10u); + _getSerialNum.setSerialNum(currSerialNum); _visibilityHandler.setVisibilityDelay(TimeStamp::Seconds(visibilityDelay)); if (internal) { VisibilityHandler *visibilityHandler = &_visibilityHandler; @@ -122,9 +123,10 @@ public: uint32_t expForceCommitCount, SerialNum expCommittedSerialNum, uint32_t expMasterExecuteCnt, - uint32_t expAttributeFieldWriterSyncCnt) + uint32_t expAttributeFieldWriterSyncCnt, + SerialNum currSerialNum = 10u) { - _getSerialNum.setSerialNum(10u); + _getSerialNum.setSerialNum(currSerialNum); _visibilityHandler.setVisibilityDelay(TimeStamp::Seconds(visibilityDelay)); if (internal) { VisibilityHandler *visibilityHandler = &_visibilityHandler; @@ -154,6 +156,11 @@ TEST_F("Check external commit with nonzero visibility delay", Fixture) f.testCommit(1.0, false, 1u, 10u, 1u, 0u); } +TEST_F("Check external commit with nonzero visibility delay and no new feed operation", Fixture) +{ + f.testCommit(1.0, false, 1u, 0u, 1u, 0u, 0u); +} + TEST_F("Check internal commit with zero visibility delay", Fixture) { f.testCommit(0.0, true, 0u, 0u, 1u, 0u); @@ -164,6 +171,11 @@ TEST_F("Check internal commit with nonzero visibility delay", Fixture) f.testCommit(1.0, true, 1u, 10u, 1u, 0u); } +TEST_F("Check internal commit with nonzero visibility delay and no new feed operation", Fixture) +{ + f.testCommit(1.0, true, 1u, 0u, 1u, 0u, 0u); +} + TEST_F("Check external commitAndWait with zero visibility delay", Fixture) { f.testCommitAndWait(0.0, false, 0u, 0u, 0u, 1u); @@ -174,6 +186,11 @@ TEST_F("Check external commitAndWait with nonzero visibility delay", Fixture) f.testCommitAndWait(1.0, false, 1u, 10u, 1u, 1u); } +TEST_F("Check external commitAndWait with nonzero visibility delay and no new feed operation", Fixture) +{ + f.testCommitAndWait(1.0, false, 0u, 0u, 0u, 1u, 0u); +} + TEST_F("Check internal commitAndWait with zero visibility delay", Fixture) { f.testCommitAndWait(0.0, true, 0u, 0u, 1u, 1u); @@ -184,4 +201,9 @@ TEST_F("Check internal commitAndWait with nonzero visibility delay", Fixture) f.testCommitAndWait(1.0, true, 1u, 10u, 1u, 1u); } +TEST_F("Check internal commitAndWait with nonzero visibility delay and no new feed operation", Fixture) +{ + f.testCommitAndWait(1.0, true, 0u, 0u, 1u, 1u, 0u); +} + TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/searchcore/src/vespa/searchcore/proton/documentmetastore/i_document_meta_store_context.h b/searchcore/src/vespa/searchcore/proton/documentmetastore/i_document_meta_store_context.h index 2d2b734ca40..df03212683b 100644 --- a/searchcore/src/vespa/searchcore/proton/documentmetastore/i_document_meta_store_context.h +++ b/searchcore/src/vespa/searchcore/proton/documentmetastore/i_document_meta_store_context.h @@ -3,29 +3,14 @@ #pragma once #include "i_document_meta_store.h" +#include <vespa/searchlib/common/i_document_meta_store_context.h> namespace proton { /** * API for providing write and read interface to the document meta store. */ -struct IDocumentMetaStoreContext { - - /** - * Guard for access to the read interface. - * This guard should be alive as long as read interface is used. - */ - struct IReadGuard { - - typedef std::unique_ptr<IReadGuard> UP; - - virtual ~IReadGuard() {} - - /** - * Access to read interface. - */ - virtual const search::IDocumentMetaStore &get() const = 0; - }; +struct IDocumentMetaStoreContext : public search::IDocumentMetaStoreContext { typedef std::shared_ptr<IDocumentMetaStoreContext> SP; @@ -35,16 +20,10 @@ struct IDocumentMetaStoreContext { * Access to write interface. * Should only be used by the writer thread. */ - virtual proton::IDocumentMetaStore & get() = 0; + virtual proton::IDocumentMetaStore &get() = 0; virtual proton::IDocumentMetaStore::SP getSP() const = 0; /** - * Access to read interface. - * Should be used by all reader threads. - */ - virtual IReadGuard::UP getReadGuard() const = 0; - - /** * Construct free lists of underlying meta store. */ virtual void constructFreeList() = 0; 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 index c56aa18c1f7..5932742baf9 100644 --- a/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.cpp +++ b/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.cpp @@ -136,6 +136,7 @@ DocumentDBReferenceResolver::listenToGidToLidChanges(const IAttributeManager &at ImportedAttributesRepo::UP DocumentDBReferenceResolver::createImportedAttributesRepo(const IAttributeManager &attrMgr, + const std::shared_ptr<search::IDocumentMetaStoreContext> &documentMetaStore, bool useSearchCache) { auto result = std::make_unique<ImportedAttributesRepo>(); @@ -143,7 +144,7 @@ DocumentDBReferenceResolver::createImportedAttributesRepo(const IAttributeManage ReferenceAttribute::SP refAttr = getReferenceAttribute(attr.referencefield, attrMgr); AttributeVector::SP targetAttr = getTargetDocumentDB(refAttr->getName())->getAttribute(attr.targetfield); ImportedAttributeVector::SP importedAttr = - std::make_shared<ImportedAttributeVector>(attr.name, refAttr, targetAttr, useSearchCache); + std::make_shared<ImportedAttributeVector>(attr.name, refAttr, targetAttr, documentMetaStore, useSearchCache); result->add(importedAttr->getName(), importedAttr); } return result; @@ -173,12 +174,13 @@ DocumentDBReferenceResolver::~DocumentDBReferenceResolver() ImportedAttributesRepo::UP DocumentDBReferenceResolver::resolve(const IAttributeManager &newAttrMgr, const IAttributeManager &oldAttrMgr, + const std::shared_ptr<search::IDocumentMetaStoreContext> &documentMetaStore, fastos::TimeStamp visibilityDelay) { connectReferenceAttributesToGidMapper(newAttrMgr); detectOldListeners(oldAttrMgr); listenToGidToLidChanges(newAttrMgr); - return createImportedAttributesRepo(newAttrMgr, (visibilityDelay > 0)); + return createImportedAttributesRepo(newAttrMgr, documentMetaStore, (visibilityDelay > 0)); } void 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 index 8e0a4178622..fc8b3751ea2 100644 --- a/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.h +++ b/searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.h @@ -7,7 +7,8 @@ #include <map> namespace document { class DocumentType; class DocumentTypeRepo; } -namespace search { class ISequencedTaskExecutor; class IAttributeManager; namespace attribute { class IAttributeVector; class ReferenceAttribute; } } +namespace search { class ISequencedTaskExecutor; class IAttributeManager; class IDocumentMetaStoreContext; + namespace attribute { class IAttributeVector; class ReferenceAttribute; } } namespace vespa { namespace config { namespace search { namespace internal { class InternalImportedFieldsType; } } } } namespace proton { @@ -37,6 +38,7 @@ private: std::shared_ptr<IDocumentDBReference> getTargetDocumentDB(const vespalib::string &refAttrName) const; void connectReferenceAttributesToGidMapper(const search::IAttributeManager &attrMgr); std::unique_ptr<ImportedAttributesRepo> createImportedAttributesRepo(const search::IAttributeManager &attrMgr, + const std::shared_ptr<search::IDocumentMetaStoreContext> &documentMetaStore, bool useSearchCache); void detectOldListeners(const search::IAttributeManager &attrMgr); void listenToGidToLidChanges(const search::IAttributeManager &attrMgr); @@ -52,6 +54,7 @@ public: virtual std::unique_ptr<ImportedAttributesRepo> resolve(const search::IAttributeManager &newAttrMgr, const search::IAttributeManager &oldAttrMgr, + const std::shared_ptr<search::IDocumentMetaStoreContext> &documentMetaStore, fastos::TimeStamp visibilityDelay) override; virtual void teardown(const search::IAttributeManager &oldAttrMgr) override; }; diff --git a/searchcore/src/vespa/searchcore/proton/reference/i_document_db_reference_resolver.h b/searchcore/src/vespa/searchcore/proton/reference/i_document_db_reference_resolver.h index 7e5b26ac34c..0aa44539f22 100644 --- a/searchcore/src/vespa/searchcore/proton/reference/i_document_db_reference_resolver.h +++ b/searchcore/src/vespa/searchcore/proton/reference/i_document_db_reference_resolver.h @@ -4,7 +4,7 @@ #include <vespa/fastos/timestamp.h> #include <memory> -namespace search { class IAttributeManager; } +namespace search { class IAttributeManager; class IDocumentMetaStoreContext; } namespace proton { @@ -17,6 +17,7 @@ struct IDocumentDBReferenceResolver { virtual ~IDocumentDBReferenceResolver() {} virtual std::unique_ptr<ImportedAttributesRepo> resolve(const search::IAttributeManager &newAttrMgr, const search::IAttributeManager &oldAttrMgr, + const std::shared_ptr<search::IDocumentMetaStoreContext> &documentMetaStore, fastos::TimeStamp visibilityDelay) = 0; virtual void teardown(const search::IAttributeManager &oldAttrMgr) = 0; }; diff --git a/searchcore/src/vespa/searchcore/proton/server/searchable_doc_subdb_configurer.cpp b/searchcore/src/vespa/searchcore/proton/server/searchable_doc_subdb_configurer.cpp index 03ada12c4f2..e7e6c213eb2 100644 --- a/searchcore/src/vespa/searchcore/proton/server/searchable_doc_subdb_configurer.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/searchable_doc_subdb_configurer.cpp @@ -211,6 +211,7 @@ SearchableDocSubDBConfigurer::reconfigure(const DocumentDBConfig &newConfig, if (params.shouldAttributeManagerChange()) { IAttributeManager::SP newAttrMgr = attrMgr->create(attrSpec); newAttrMgr->setImportedAttributes(resolver.resolve(*newAttrMgr, *attrMgr, + searchView->getDocumentMetaStore(), newConfig.getMaintenanceConfigSP()->getVisibilityDelay())); IAttributeManager::SP oldAttrMgr = attrMgr; attrMgr = newAttrMgr; diff --git a/searchcore/src/vespa/searchcore/proton/server/visibilityhandler.cpp b/searchcore/src/vespa/searchcore/proton/server/visibilityhandler.cpp index 517f2c90514..430f61eed1d 100644 --- a/searchcore/src/vespa/searchcore/proton/server/visibilityhandler.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/visibilityhandler.cpp @@ -24,10 +24,10 @@ void VisibilityHandler::commit() { if (_visibilityDelay != 0) { if (_writeService.master().isCurrentThread()) { - performCommit(); + performCommit(true); } else { LockGuard guard(_lock); - startCommit(guard); + startCommit(guard, true); } } } @@ -36,10 +36,10 @@ void VisibilityHandler::commitAndWait() { if (_visibilityDelay != 0) { if (_writeService.master().isCurrentThread()) { - performCommit(); + performCommit(false); } else { LockGuard guard(_lock); - if (startCommit(guard)) { + if (startCommit(guard, false)) { _writeService.master().sync(); } } @@ -50,23 +50,23 @@ void VisibilityHandler::commitAndWait() _writeService.summary().sync(); } -bool VisibilityHandler::startCommit(const LockGuard & unused) +bool VisibilityHandler::startCommit(const LockGuard &unused, bool force) { (void) unused; SerialNum current = _serial.getSerialNum(); - if (current > _lastCommitSerialNum) { + if ((current > _lastCommitSerialNum) || force) { _writeService.master().execute(makeTask(makeClosure(this, - &VisibilityHandler::performCommit))); + &VisibilityHandler::performCommit, force))); return true; } return false; } -void VisibilityHandler::performCommit() +void VisibilityHandler::performCommit(bool force) { // Called by master thread SerialNum current = _serial.getSerialNum(); - if (current > _lastCommitSerialNum) { + if ((current > _lastCommitSerialNum) || force) { IFeedView::SP feedView(_feedView.get()); feedView->forceCommit(current); _lastCommitSerialNum = current; diff --git a/searchcore/src/vespa/searchcore/proton/server/visibilityhandler.h b/searchcore/src/vespa/searchcore/proton/server/visibilityhandler.h index a6f160babaf..6de6b0721d6 100644 --- a/searchcore/src/vespa/searchcore/proton/server/visibilityhandler.h +++ b/searchcore/src/vespa/searchcore/proton/server/visibilityhandler.h @@ -32,8 +32,8 @@ public: void commit() override; virtual void commitAndWait() override; private: - bool startCommit(const LockGuard & unused); - void performCommit(); + bool startCommit(const LockGuard &unused, bool force); + void performCommit(bool force); const IGetSerialNum & _serial; IThreadingService & _writeService; const FeedViewHolder & _feedView; diff --git a/searchlib/src/tests/attribute/bitvector_search_cache/bitvector_search_cache_test.cpp b/searchlib/src/tests/attribute/bitvector_search_cache/bitvector_search_cache_test.cpp index 1f738a209df..0072f83bc54 100644 --- a/searchlib/src/tests/attribute/bitvector_search_cache/bitvector_search_cache_test.cpp +++ b/searchlib/src/tests/attribute/bitvector_search_cache/bitvector_search_cache_test.cpp @@ -3,6 +3,7 @@ #include <vespa/vespalib/testkit/test_kit.h> #include <vespa/searchlib/attribute/bitvector_search_cache.h> #include <vespa/searchlib/common/bitvector.h> +#include <vespa/searchlib/common/i_document_meta_store_context.h> using namespace search; using namespace search::attribute; @@ -13,7 +14,7 @@ using Entry = BitVectorSearchCache::Entry; Entry::SP makeEntry() { - return std::make_shared<Entry>(BitVector::create(5), 10); + return std::make_shared<Entry>(IDocumentMetaStoreContext::IReadGuard::UP(), BitVector::create(5), 10); } struct Fixture { diff --git a/searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp b/searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp index f6ab6bb50bf..4ab0ed878cf 100644 --- a/searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp +++ b/searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp @@ -370,7 +370,7 @@ makeSearchCacheEntry(const std::vector<uint32_t> docIds, uint32_t docIdLimit) for (uint32_t docId : docIds) { bitVector->setBit(docId); } - return std::make_shared<BitVectorSearchCache::Entry>(bitVector, docIdLimit); + return std::make_shared<BitVectorSearchCache::Entry>(IDocumentMetaStoreContext::IReadGuard::UP(), bitVector, docIdLimit); } TEST_F("Bit vector from search cache is used if found", SearchCacheFixture) @@ -382,6 +382,7 @@ TEST_F("Bit vector from search cache is used if found", SearchCacheFixture) TermFieldMatchData match; auto iter = f.create_strict_iterator(*ctx, match); TEST_DO(f.assertSearch({2, 6}, *iter)); // Note: would be {3, 5} if cache was not used + EXPECT_EQUAL(0u, f.document_meta_store->get_read_guard_cnt); } void @@ -405,6 +406,7 @@ TEST_F("Entry is inserted into search cache if bit vector posting list is used", auto cacheEntry = f.imported_attr->getSearchCache()->find("5678"); EXPECT_EQUAL(cacheEntry->docIdLimit, f.imported_attr->getNumDocs()); TEST_DO(assertBitVector({3, 5}, *cacheEntry->bitVector)); + EXPECT_EQUAL(1u, f.document_meta_store->get_read_guard_cnt); } } diff --git a/searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.h b/searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.h index 73fb95e1752..a889120f8df 100644 --- a/searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.h +++ b/searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.h @@ -2,6 +2,7 @@ #pragma once +#include <vespa/searchlib/common/i_document_meta_store_context.h> #include <vespa/vespalib/stllike/hash_map.h> #include <vespa/vespalib/stllike/string.h> #include <memory> @@ -21,13 +22,17 @@ namespace attribute { class BitVectorSearchCache { public: using BitVectorSP = std::shared_ptr<BitVector>; + using ReadGuardUP = IDocumentMetaStoreContext::IReadGuard::UP; struct Entry { using SP = std::shared_ptr<Entry>; + // We need to keep a document meta store read guard to ensure that no lids that are cached + // in the bit vector are re-used until the guard is released. + ReadGuardUP dmsReadGuard; BitVectorSP bitVector; uint32_t docIdLimit; - Entry(BitVectorSP bitVector_, uint32_t docIdLimit_) - : bitVector(std::move(bitVector_)), docIdLimit(docIdLimit_) {} + Entry(ReadGuardUP dmsReadGuard_, BitVectorSP bitVector_, uint32_t docIdLimit_) + : dmsReadGuard(std::move(dmsReadGuard_)), bitVector(std::move(bitVector_)), docIdLimit(docIdLimit_) {} }; private: diff --git a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.cpp b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.cpp index 9efac9ce541..a085e21d6ae 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.cpp +++ b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.cpp @@ -14,10 +14,12 @@ ImportedAttributeVector::ImportedAttributeVector( vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, bool use_search_cache) : _name(name), _reference_attribute(std::move(reference_attribute)), _target_attribute(std::move(target_attribute)), + _document_meta_store(std::move(document_meta_store)), _search_cache(use_search_cache ? std::make_shared<BitVectorSearchCache>() : std::shared_ptr<BitVectorSearchCache>()) { @@ -26,10 +28,12 @@ ImportedAttributeVector::ImportedAttributeVector( ImportedAttributeVector::ImportedAttributeVector(vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, std::shared_ptr<BitVectorSearchCache> search_cache) : _name(name), _reference_attribute(std::move(reference_attribute)), _target_attribute(std::move(target_attribute)), + _document_meta_store(std::move(document_meta_store)), _search_cache(std::move(search_cache)) { } @@ -41,7 +45,7 @@ std::unique_ptr<ImportedAttributeVector> ImportedAttributeVector::makeReadGuard(bool stableEnumGuard) const { return std::make_unique<ImportedAttributeVectorReadGuard> - (getName(), getReferenceAttribute(), getTargetAttribute(), getSearchCache(), stableEnumGuard); + (getName(), getReferenceAttribute(), getTargetAttribute(), getDocumentMetaStore(), getSearchCache(), stableEnumGuard); } const vespalib::string& search::attribute::ImportedAttributeVector::getName() const { diff --git a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.h b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.h index c94eda3d4db..7d272c42d9e 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.h +++ b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.h @@ -11,6 +11,7 @@ namespace search { class AttributeGuard; class AttributeEnumGuard; +class IDocumentMetaStoreContext; namespace attribute { @@ -32,10 +33,12 @@ public: ImportedAttributeVector(vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, bool use_search_cache); ImportedAttributeVector(vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, std::shared_ptr<BitVectorSearchCache> search_cache); ~ImportedAttributeVector(); @@ -72,6 +75,9 @@ public: const std::shared_ptr<AttributeVector>& getTargetAttribute() const noexcept { return _target_attribute; } + const std::shared_ptr<IDocumentMetaStoreContext> &getDocumentMetaStore() const { + return _document_meta_store; + } const std::shared_ptr<BitVectorSearchCache> &getSearchCache() const { return _search_cache; } @@ -88,10 +94,11 @@ protected: const common::BlobConverter * bc) const override; - vespalib::string _name; - std::shared_ptr<ReferenceAttribute> _reference_attribute; - std::shared_ptr<AttributeVector> _target_attribute; - std::shared_ptr<BitVectorSearchCache> _search_cache; + vespalib::string _name; + std::shared_ptr<ReferenceAttribute> _reference_attribute; + std::shared_ptr<AttributeVector> _target_attribute; + std::shared_ptr<IDocumentMetaStoreContext> _document_meta_store; + std::shared_ptr<BitVectorSearchCache> _search_cache; }; } // attribute diff --git a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.cpp b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.cpp index 4ce0f8d340c..c954c34aee8 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.cpp +++ b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.cpp @@ -11,9 +11,11 @@ ImportedAttributeVectorReadGuard::ImportedAttributeVectorReadGuard( vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, std::shared_ptr<BitVectorSearchCache> search_cache, bool stableEnumGuard) - : ImportedAttributeVector(name, std::move(reference_attribute), std::move(target_attribute), std::move(search_cache)), + : ImportedAttributeVector(name, std::move(reference_attribute), std::move(target_attribute), + std::move(document_meta_store), std::move(search_cache)), _referencedLids(), _reference_attribute_guard(_reference_attribute), _target_attribute_guard(stableEnumGuard ? std::shared_ptr<AttributeVector>() : _target_attribute), diff --git a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.h b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.h index 27d83614a39..2ca8680f4b8 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.h +++ b/searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.h @@ -34,6 +34,7 @@ public: ImportedAttributeVectorReadGuard(vespalib::stringref name, std::shared_ptr<ReferenceAttribute> reference_attribute, std::shared_ptr<AttributeVector> target_attribute, + std::shared_ptr<IDocumentMetaStoreContext> document_meta_store, std::shared_ptr<BitVectorSearchCache> search_cache, bool stableEnumGuard); ~ImportedAttributeVectorReadGuard(); diff --git a/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp b/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp index d2dc52ec2c7..a21ecacccdb 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp +++ b/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp @@ -29,6 +29,8 @@ ImportedSearchContext::ImportedSearchContext( _useSearchCache(_imported_attribute.getSearchCache().get() != nullptr), _searchCacheLookup((_useSearchCache ? _imported_attribute.getSearchCache()->find(_queryTerm) : std::shared_ptr<BitVectorSearchCache::Entry>())), + _dmsReadGuard((_useSearchCache && !_searchCacheLookup) ? imported_attribute.getDocumentMetaStore()->getReadGuard() : + std::unique_ptr<IDocumentMetaStoreContext::IReadGuard>()), _reference_attribute(*_imported_attribute.getReferenceAttribute()), _target_attribute(*_imported_attribute.getTargetAttribute()), _target_search_context(_target_attribute.getSearch(std::move(term), params)), @@ -36,6 +38,7 @@ ImportedSearchContext::ImportedSearchContext( _merger(_reference_attribute.getCommittedDocIdLimit()), _fetchPostingsDone(false) { + } ImportedSearchContext::~ImportedSearchContext() { @@ -215,7 +218,8 @@ void ImportedSearchContext::considerAddSearchCacheEntry() { if (_useSearchCache && _merger.hasBitVector()) { - auto cacheEntry = std::make_shared<BitVectorSearchCache::Entry>(_merger.getBitVectorSP(), _merger.getDocIdLimit()); + assert(_dmsReadGuard); + auto cacheEntry = std::make_shared<BitVectorSearchCache::Entry>(std::move(_dmsReadGuard), _merger.getBitVectorSP(), _merger.getDocIdLimit()); _imported_attribute.getSearchCache()->insert(_queryTerm, std::move(cacheEntry)); } } diff --git a/searchlib/src/vespa/searchlib/attribute/imported_search_context.h b/searchlib/src/vespa/searchlib/attribute/imported_search_context.h index 0f6f8125cf8..0ddca8c9fe5 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_search_context.h +++ b/searchlib/src/vespa/searchlib/attribute/imported_search_context.h @@ -6,6 +6,7 @@ #include "bitvector_search_cache.h" #include <vespa/searchcommon/attribute/i_search_context.h> #include <vespa/searchlib/attribute/posting_list_merger.h> +#include <vespa/searchlib/common/i_document_meta_store_context.h> #include <vespa/vespalib/util/arrayref.h> namespace search::fef { class TermFieldMatchData; } @@ -30,6 +31,7 @@ class ImportedSearchContext : public ISearchContext { vespalib::string _queryTerm; bool _useSearchCache; BitVectorSearchCache::Entry::SP _searchCacheLookup; + IDocumentMetaStoreContext::IReadGuard::UP _dmsReadGuard; const ReferenceAttribute& _reference_attribute; const AttributeVector& _target_attribute; std::unique_ptr<AttributeVector::SearchContext> _target_search_context; diff --git a/searchlib/src/vespa/searchlib/common/i_document_meta_store_context.h b/searchlib/src/vespa/searchlib/common/i_document_meta_store_context.h new file mode 100644 index 00000000000..7e2e3def0d2 --- /dev/null +++ b/searchlib/src/vespa/searchlib/common/i_document_meta_store_context.h @@ -0,0 +1,42 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <memory> + +namespace search { + +class IDocumentMetaStore; + +/** + * API for providing read interface to the document meta store. + */ +struct IDocumentMetaStoreContext { + + /** + * Guard for access to the read interface. + * This guard should be alive as long as read interface is used. + */ + struct IReadGuard { + + typedef std::unique_ptr<IReadGuard> UP; + + virtual ~IReadGuard() {} + + /** + * Access to read interface. + */ + virtual const search::IDocumentMetaStore &get() const = 0; + }; + + virtual ~IDocumentMetaStoreContext() {} + + /** + * Access to read interface. + * Should be used by all reader threads. + */ + virtual IReadGuard::UP getReadGuard() const = 0; + +}; + +} diff --git a/searchlib/src/vespa/searchlib/test/imported_attribute_fixture.h b/searchlib/src/vespa/searchlib/test/imported_attribute_fixture.h index 3620a1df725..f9e3de79144 100644 --- a/searchlib/src/vespa/searchlib/test/imported_attribute_fixture.h +++ b/searchlib/src/vespa/searchlib/test/imported_attribute_fixture.h @@ -12,6 +12,7 @@ #include <vespa/searchlib/attribute/integerbase.h> #include <vespa/searchlib/attribute/not_implemented_attribute.h> #include <vespa/searchlib/attribute/stringbase.h> +#include <vespa/searchlib/common/i_document_meta_store_context.h> #include <vespa/searchlib/query/queryterm.h> #include <vespa/searchcommon/attribute/attributecontent.h> #include <vespa/vespalib/testkit/testapp.h> @@ -23,6 +24,27 @@ #include <vector> namespace search { + +struct MockDocumentMetaStoreContext : public IDocumentMetaStoreContext { + + struct MockReadGuard : public IDocumentMetaStoreContext::IReadGuard { + virtual const search::IDocumentMetaStore &get() const override { + search::IDocumentMetaStore *nullStore = nullptr; + return static_cast<search::IDocumentMetaStore &>(*nullStore); + } + }; + + mutable size_t get_read_guard_cnt; + + using SP = std::shared_ptr<MockDocumentMetaStoreContext>; + MockDocumentMetaStoreContext() : get_read_guard_cnt(0) {} + + virtual IReadGuard::UP getReadGuard() const override { + ++get_read_guard_cnt; + return std::make_unique<MockReadGuard>(); + } +}; + namespace attribute { using document::DocumentId; @@ -39,6 +61,10 @@ std::shared_ptr<ReferenceAttribute> create_reference_attribute(vespalib::stringr return std::make_shared<ReferenceAttribute>(name, Config(BasicType::REFERENCE)); } +MockDocumentMetaStoreContext::SP create_document_meta_store() { + return std::make_shared<MockDocumentMetaStoreContext>(); +} + enum class FastSearchConfig { ExplicitlyEnabled, Default @@ -105,6 +131,7 @@ struct ImportedAttributeFixture { bool use_search_cache; std::shared_ptr<AttributeVector> target_attr; std::shared_ptr<ReferenceAttribute> reference_attr; + MockDocumentMetaStoreContext::SP document_meta_store; std::shared_ptr<ImportedAttributeVector> imported_attr; std::shared_ptr<MockGidToLidMapperFactory> mapper_factory; @@ -130,7 +157,7 @@ struct ImportedAttributeFixture { std::shared_ptr<ImportedAttributeVector> create_attribute_vector_from_members(vespalib::stringref name = default_imported_attr_name()) { - return std::make_shared<ImportedAttributeVector>(name, reference_attr, target_attr, use_search_cache); + return std::make_shared<ImportedAttributeVector>(name, reference_attr, target_attr, document_meta_store, use_search_cache); } template<typename AttrVecType> @@ -225,6 +252,7 @@ ImportedAttributeFixture::ImportedAttributeFixture(bool use_search_cache_) : use_search_cache(use_search_cache_), target_attr(create_single_attribute<IntegerAttribute>(BasicType::INT32)), reference_attr(create_reference_attribute()), + document_meta_store(create_document_meta_store()), imported_attr(create_attribute_vector_from_members()), mapper_factory(std::make_shared<MockGidToLidMapperFactory>()) { reference_attr->setGidToLidMapperFactory(mapper_factory); |