aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeir Storli <geirstorli@yahoo.no>2017-09-12 15:53:35 +0200
committerGitHub <noreply@github.com>2017-09-12 15:53:35 +0200
commit664dc8e147928cd05a16954cbfdd6efb34dd144a (patch)
treea5b985aab6b38f3b955c5b62469a9bcbd8a4c700
parent5ca40d533eabdb8fad2d0951285182b998aaf9df (diff)
parent093d8381783f0acac2b53be4703fd61189d0b470 (diff)
Merge pull request #3390 from vespa-engine/geirst/fix-bitvector-search-cache-for-imported-attributes
Geirst/fix bitvector search cache for imported attributes
-rw-r--r--searchcore/src/tests/proton/attribute/attribute_manager/attribute_manager_test.cpp3
-rw-r--r--searchcore/src/tests/proton/attribute/attribute_test.cpp1
-rw-r--r--searchcore/src/tests/proton/attribute/imported_attributes_context/imported_attributes_context_test.cpp1
-rw-r--r--searchcore/src/tests/proton/attribute/imported_attributes_repo/imported_attributes_repo_test.cpp1
-rw-r--r--searchcore/src/tests/proton/documentdb/configurer/configurer_test.cpp5
-rw-r--r--searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp549
-rw-r--r--searchcore/src/tests/proton/reference/document_db_reference_resolver/document_db_reference_resolver_test.cpp2
-rw-r--r--searchcore/src/tests/proton/server/visibility_handler/visibility_handler_test.cpp30
-rw-r--r--searchcore/src/vespa/searchcore/proton/documentmetastore/i_document_meta_store_context.h27
-rw-r--r--searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.cpp6
-rw-r--r--searchcore/src/vespa/searchcore/proton/reference/document_db_reference_resolver.h5
-rw-r--r--searchcore/src/vespa/searchcore/proton/reference/i_document_db_reference_resolver.h3
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/searchable_doc_subdb_configurer.cpp1
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/visibilityhandler.cpp18
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/visibilityhandler.h4
-rw-r--r--searchlib/src/tests/attribute/bitvector_search_cache/bitvector_search_cache_test.cpp3
-rw-r--r--searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp4
-rw-r--r--searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.h9
-rw-r--r--searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/attribute/imported_attribute_vector.h15
-rw-r--r--searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.cpp4
-rw-r--r--searchlib/src/vespa/searchlib/attribute/imported_attribute_vector_read_guard.h1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/attribute/imported_search_context.h2
-rw-r--r--searchlib/src/vespa/searchlib/common/i_document_meta_store_context.h42
-rw-r--r--searchlib/src/vespa/searchlib/test/imported_attribute_fixture.h30
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);