summaryrefslogtreecommitdiffstats
path: root/searchcore
diff options
context:
space:
mode:
authorArne Juul <arnej@yahoo-inc.com>2018-06-20 09:48:02 +0200
committerArne Juul <arnej@yahoo-inc.com>2018-06-20 09:48:02 +0200
commit44fc1380b66867958f89c47ac8752926b3787a4d (patch)
treeea324d387b055c3ccf0921f9f973c95b16bad2e2 /searchcore
parent016e584f0ad5a071e13d75eb8ad5ddb46b8c54f5 (diff)
parent79e7562d34a20ed28621a9ec0dc296eda0881428 (diff)
Merge branch 'master' into arnej/use-log-abort
Diffstat (limited to 'searchcore')
-rw-r--r--searchcore/src/apps/vespa-transactionlog-inspect/vespa-transactionlog-inspect.cpp3
-rw-r--r--searchcore/src/tests/proton/attribute/attribute_aspect_delayer/attribute_aspect_delayer_test.cpp44
-rw-r--r--searchcore/src/tests/proton/attribute/attribute_manager/attribute_manager_test.cpp44
-rw-r--r--searchcore/src/tests/proton/attribute/attribute_test.cpp6
-rw-r--r--searchcore/src/tests/proton/attribute/attributeflush_test.cpp13
-rw-r--r--searchcore/src/tests/proton/attribute/exclusive_attribute_read_accessor/exclusive_attribute_read_accessor_test.cpp2
-rw-r--r--searchcore/src/tests/proton/common/document_type_inspector/document_type_inspector_test.cpp135
-rw-r--r--searchcore/src/tests/proton/docsummary/docsummary.cpp39
-rw-r--r--searchcore/src/tests/proton/docsummary/summaryfieldconverter_test.cpp2
-rw-r--r--searchcore/src/tests/proton/documentdb/combiningfeedview/combiningfeedview_test.cpp11
-rw-r--r--searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp1
-rw-r--r--searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp2
-rw-r--r--searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp5
-rw-r--r--searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp2
-rw-r--r--searchcore/src/tests/proton/feedoperation/feedoperation_test.cpp5
-rw-r--r--searchcore/src/tests/proton/persistenceengine/persistenceengine_test.cpp4
-rw-r--r--searchcore/src/tests/proton/reprocessing/attribute_reprocessing_initializer/attribute_reprocessing_initializer_test.cpp12
-rw-r--r--searchcore/src/tests/proton/server/feedstates_test.cpp10
-rw-r--r--searchcore/src/vespa/searchcore/config/proton.def2
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/attribute_aspect_delayer.cpp16
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.cpp59
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.h14
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp9
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/exclusive_attribute_read_accessor.cpp8
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp5
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/flushableattribute.cpp7
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/document_type_inspector.cpp29
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/compact_lid_space_operation.cpp4
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/feedoperation.h4
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.cpp1
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.h6
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/newconfigoperation.h29
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.cpp7
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/removedocumentsoperation.cpp9
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.cpp22
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.h17
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.cpp22
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.h4
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.cpp13
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.h9
-rw-r--r--searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.cpp15
-rw-r--r--searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.h49
-rw-r--r--searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_listener.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.cpp6
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/combiningfeedview.cpp10
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/combiningfeedview.h13
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/documentdb.cpp1
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/fast_access_feed_view.cpp3
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp3
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/feedstate.h3
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/feedstates.cpp1
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/feedstates.h24
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/ireplaypackethandler.h22
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.cpp1
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.h8
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp1
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h5
57 files changed, 482 insertions, 321 deletions
diff --git a/searchcore/src/apps/vespa-transactionlog-inspect/vespa-transactionlog-inspect.cpp b/searchcore/src/apps/vespa-transactionlog-inspect/vespa-transactionlog-inspect.cpp
index 17f1faffbba..8ffe4807427 100644
--- a/searchcore/src/apps/vespa-transactionlog-inspect/vespa-transactionlog-inspect.cpp
+++ b/searchcore/src/apps/vespa-transactionlog-inspect/vespa-transactionlog-inspect.cpp
@@ -1,8 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/config/helper/configgetter.h>
-
#include <vespa/searchcore/proton/server/replaypacketdispatcher.h>
+#include <vespa/searchcore/proton/feedoperation/operations.h>
#include <vespa/searchlib/common/fileheadercontext.h>
#include <vespa/searchlib/transactionlog/translogclient.h>
#include <vespa/searchlib/transactionlog/translogserver.h>
diff --git a/searchcore/src/tests/proton/attribute/attribute_aspect_delayer/attribute_aspect_delayer_test.cpp b/searchcore/src/tests/proton/attribute/attribute_aspect_delayer/attribute_aspect_delayer_test.cpp
index b700bf45820..716db497424 100644
--- a/searchcore/src/tests/proton/attribute/attribute_aspect_delayer/attribute_aspect_delayer_test.cpp
+++ b/searchcore/src/tests/proton/attribute/attribute_aspect_delayer/attribute_aspect_delayer_test.cpp
@@ -40,15 +40,24 @@ namespace proton
namespace {
-AttributesConfig::Attribute make_sv_cfg(AttributesConfig::Attribute::Datatype dataType)
+AttributesConfig::Attribute make_sv_cfg(const vespalib::string &name, AttributesConfig::Attribute::Datatype dataType)
{
AttributesConfig::Attribute attr;
- attr.name = "a";
+ attr.name = name;
attr.datatype = dataType;
attr.collectiontype = AttributesConfig::Attribute::Collectiontype::SINGLE;
return attr;
}
+AttributesConfig::Attribute make_sv_cfg(AttributesConfig::Attribute::Datatype dataType)
+{
+ return make_sv_cfg("a", dataType);
+}
+
+AttributesConfig::Attribute make_int32_sv_cfg(const vespalib::string &name) {
+ return make_sv_cfg(name, AttributesConfig::Attribute::Datatype::INT32);
+}
+
AttributesConfig::Attribute make_int32_sv_cfg() {
return make_sv_cfg(AttributesConfig::Attribute::Datatype::INT32);
}
@@ -108,6 +117,14 @@ SummarymapConfig::Override make_geopos_override(const vespalib::string &name)
return override;
}
+SummarymapConfig::Override make_attribute_combiner_override(const vespalib::string &name)
+{
+ SummarymapConfig::Override override;
+ override.field = name;
+ override.command = "attributecombiner";
+ return override;
+}
+
SummarymapConfig smCfg(std::vector<SummarymapConfig::Override> overrides)
{
SummarymapConfigBuilder result;
@@ -310,6 +327,29 @@ TEST_F("require that fast access flag change is not delayed, true->false edge, s
TEST_DO(f.assertSummarymapConfig({make_attribute_override("a")}));
}
+TEST_F("require that adding attribute aspect to struct field is not delayed if field type is changed", Fixture)
+{
+ f.setup(attrCfg({}), smCfg({}), attrCfg({make_int32_sv_cfg("array.a")}), smCfg({make_attribute_combiner_override("array")}));
+ TEST_DO(f.assertAttributeConfig({make_int32_sv_cfg("array.a")}));
+ TEST_DO(f.assertSummarymapConfig({make_attribute_combiner_override("array")}));
+}
+
+TEST_F("require that adding attribute aspect to struct field is delayed if field type is unchanged", Fixture)
+{
+ f.addFields({"array.a"});
+ f.setup(attrCfg({}), smCfg({}), attrCfg({make_int32_sv_cfg("array.a")}), smCfg({make_attribute_combiner_override("array")}));
+ TEST_DO(f.assertAttributeConfig({}));
+ TEST_DO(f.assertSummarymapConfig({}));
+}
+
+TEST_F("require that removing attribute aspect from struct field is not delayed", Fixture)
+{
+ f.addFields({"array.a"});
+ f.setup(attrCfg({make_int32_sv_cfg("array.a")}), smCfg({make_attribute_combiner_override("array")}), attrCfg({}), smCfg({}));
+ TEST_DO(f.assertAttributeConfig({}));
+ TEST_DO(f.assertSummarymapConfig({}));
+}
+
}
TEST_MAIN()
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 9bf4d43fff7..ce09a9a3742 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
@@ -1,7 +1,4 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/log/log.h>
-LOG_SETUP("attribute_manager_test");
-
#include <vespa/config-attributes.h>
#include <vespa/fastos/file.h>
#include <vespa/searchcommon/attribute/attributecontent.h>
@@ -42,6 +39,9 @@ LOG_SETUP("attribute_manager_test");
#include <vespa/vespalib/testkit/testapp.h>
#include <vespa/vespalib/util/threadstackexecutor.h>
+#include <vespa/log/log.h>
+LOG_SETUP("attribute_manager_test");
+
namespace vespa { namespace config { namespace search {}}}
using std::string;
@@ -84,7 +84,7 @@ class MyAttributeFunctor : public proton::IAttributeFunctor
std::vector<vespalib::string> _names;
public:
- virtual void
+ void
operator()(const search::AttributeVector &attributeVector) override {
_names.push_back(attributeVector.getName());
}
@@ -166,13 +166,12 @@ BaseFixture::BaseFixture()
_hwInfo()
{
}
-BaseFixture::~BaseFixture() {}
+BaseFixture::~BaseFixture() = default;
struct AttributeManagerFixture
{
proton::AttributeManager::SP _msp;
proton::AttributeManager &_m;
- AttributeWriter _aw;
ImportedAttributesRepoBuilder _builder;
AttributeManagerFixture(BaseFixture &bf);
~AttributeManagerFixture();
@@ -191,10 +190,9 @@ AttributeManagerFixture::AttributeManagerFixture(BaseFixture &bf)
: _msp(std::make_shared<proton::AttributeManager>(test_dir, "test.subdb", TuneFileAttributes(),
bf._fileHeaderContext, bf._attributeFieldWriter, bf._hwInfo)),
_m(*_msp),
- _aw(_msp),
_builder()
{}
-AttributeManagerFixture::~AttributeManagerFixture() {}
+AttributeManagerFixture::~AttributeManagerFixture() = default;
struct Fixture : public BaseFixture, public AttributeManagerFixture
{
@@ -318,16 +316,21 @@ TEST_F("require that attributes are flushed and loaded", BaseFixture)
fillAttribute(a1, 1, 2, 200);
EXPECT_EQUAL(4u, a1->getNumDocs());
AttributeVector::SP a2 = amf.addAttribute("a2"); // loaded
- EXPECT_EQUAL(5u, a2->getNumDocs());
- EXPECT_EQUAL(4u, a1->getNumDocs());
- amf._aw.onReplayDone(5u);
- EXPECT_EQUAL(5u, a2->getNumDocs());
- EXPECT_EQUAL(5u, a1->getNumDocs());
- fillAttribute(a2, 1, 4, 200);
- EXPECT_EQUAL(6u, a2->getNumDocs());
+ {
+ AttributeWriter aw(amf._msp);
+
+ EXPECT_EQUAL(5u, a2->getNumDocs());
+ EXPECT_EQUAL(4u, a1->getNumDocs());
+ aw.onReplayDone(5u);
+ EXPECT_EQUAL(5u, a2->getNumDocs());
+ EXPECT_EQUAL(5u, a1->getNumDocs());
+ fillAttribute(a2, 1, 4, 200);
+ EXPECT_EQUAL(6u, a2->getNumDocs());
+ }
AttributeVector::SP a3 = amf.addAttribute("a3"); // not-loaded
+ AttributeWriter aw(amf._msp);
EXPECT_EQUAL(1u, a3->getNumDocs());
- amf._aw.onReplayDone(6);
+ aw.onReplayDone(6);
EXPECT_EQUAL(6u, a3->getNumDocs());
fillAttribute(a3, 1, 7, 6, 200);
EXPECT_EQUAL(7u, a3->getNumDocs());
@@ -352,10 +355,11 @@ TEST_F("require that attributes are flushed and loaded", BaseFixture)
EXPECT_EQUAL(6u, a1->getNumDocs());
EXPECT_EQUAL(6u, a2->getNumDocs());
AttributeVector::SP a3 = amf.addAttribute("a3"); // loaded
+ AttributeWriter aw(amf._msp);
EXPECT_EQUAL(6u, a1->getNumDocs());
EXPECT_EQUAL(6u, a2->getNumDocs());
EXPECT_EQUAL(7u, a3->getNumDocs());
- amf._aw.onReplayDone(7);
+ aw.onReplayDone(7);
EXPECT_EQUAL(7u, a1->getNumDocs());
EXPECT_EQUAL(7u, a2->getNumDocs());
EXPECT_EQUAL(7u, a3->getNumDocs());
@@ -559,6 +563,7 @@ TEST_F("require that lid space can be compacted", Fixture)
AttributeVector::SP a2 = f.addAttribute("a2");
AttributeVector::SP ex(new Int32Attribute("ex"));
f._m.addExtraAttribute(ex);
+ AttributeWriter aw(f._msp);
const int64_t attrValue = 33;
fillAttribute(a1, 20, attrValue, 100);
fillAttribute(a2, 20, attrValue, 100);
@@ -571,7 +576,7 @@ TEST_F("require that lid space can be compacted", Fixture)
EXPECT_EQUAL(21u, a2->getCommittedDocIdLimit());
EXPECT_EQUAL(20u, ex->getCommittedDocIdLimit());
- f._aw.compactLidSpace(10, 101);
+ aw.compactLidSpace(10, 101);
EXPECT_EQUAL(21u, a1->getNumDocs());
EXPECT_EQUAL(21u, a2->getNumDocs());
@@ -587,6 +592,7 @@ TEST_F("require that lid space compaction op can be ignored", Fixture)
AttributeVector::SP a2 = f.addAttribute("a2");
AttributeVector::SP ex(new Int32Attribute("ex"));
f._m.addExtraAttribute(ex);
+ AttributeWriter aw(f._msp);
const int64_t attrValue = 33;
fillAttribute(a1, 20, attrValue, 200);
fillAttribute(a2, 20, attrValue, 100);
@@ -599,7 +605,7 @@ TEST_F("require that lid space compaction op can be ignored", Fixture)
EXPECT_EQUAL(21u, a2->getCommittedDocIdLimit());
EXPECT_EQUAL(20u, ex->getCommittedDocIdLimit());
- f._aw.compactLidSpace(10, 101);
+ aw.compactLidSpace(10, 101);
EXPECT_EQUAL(21u, a1->getNumDocs());
EXPECT_EQUAL(21u, a2->getNumDocs());
diff --git a/searchcore/src/tests/proton/attribute/attribute_test.cpp b/searchcore/src/tests/proton/attribute/attribute_test.cpp
index 5954932bbaf..346f94180b5 100644
--- a/searchcore/src/tests/proton/attribute/attribute_test.cpp
+++ b/searchcore/src/tests/proton/attribute/attribute_test.cpp
@@ -445,7 +445,7 @@ TEST_F("require that attribute writer handles update", Fixture)
schema.addAttributeField(Schema::AttributeField("a2", schema::DataType::INT32, CollectionType::SINGLE));
DocBuilder idb(schema);
const document::DocumentType &dt(idb.getDocumentType());
- DocumentUpdate upd(dt, DocumentId("doc::1"));
+ DocumentUpdate upd(*idb.getDocumentTypeRepo(), dt, DocumentId("doc::1"));
upd.addUpdate(FieldUpdate(upd.getType().getField("a1"))
.addUpdate(ArithmeticValueUpdate(ArithmeticValueUpdate::Add, 5)));
upd.addUpdate(FieldUpdate(upd.getType().getField("a2"))
@@ -489,7 +489,7 @@ TEST_F("require that attribute writer handles predicate update", Fixture)
EXPECT_EQUAL(2u, a1->getNumDocs());
const document::DocumentType &dt(idb.getDocumentType());
- DocumentUpdate upd(dt, DocumentId("doc::1"));
+ DocumentUpdate upd(*idb.getDocumentTypeRepo(), dt, DocumentId("doc::1"));
PredicateFieldValue new_value(builder.feature("foo").value("bar").build());
upd.addUpdate(FieldUpdate(upd.getType().getField("a1"))
.addUpdate(AssignValueUpdate(new_value)));
@@ -678,7 +678,7 @@ TEST_F("require that attribute writer handles tensor assign update", Fixture)
EXPECT_TRUE(tensor->equals(*tensor2));
const document::DocumentType &dt(builder.getDocumentType());
- DocumentUpdate upd(dt, DocumentId("doc::1"));
+ DocumentUpdate upd(*builder.getDocumentTypeRepo(), dt, DocumentId("doc::1"));
auto new_tensor = createTensor({ {{{"x", "8"}, {"y", "9"}}, 11} },
{"x", "y"});
TensorFieldValue new_value;
diff --git a/searchcore/src/tests/proton/attribute/attributeflush_test.cpp b/searchcore/src/tests/proton/attribute/attributeflush_test.cpp
index d73cd805af1..8a5f58bd7e0 100644
--- a/searchcore/src/tests/proton/attribute/attributeflush_test.cpp
+++ b/searchcore/src/tests/proton/attribute/attributeflush_test.cpp
@@ -256,13 +256,12 @@ BaseFixture::BaseFixture(const HwInfo &hwInfo)
_attributeFieldWriter(),
_hwInfo(hwInfo)
{}
-BaseFixture::~BaseFixture() {}
+BaseFixture::~BaseFixture() = default;
struct AttributeManagerFixture
{
AttributeManager::SP _msp;
AttributeManager &_m;
- AttributeWriter _aw;
AttributeManagerFixture(BaseFixture &bf);
~AttributeManagerFixture();
AttributeVector::SP addAttribute(const vespalib::string &name) {
@@ -278,10 +277,9 @@ struct AttributeManagerFixture
AttributeManagerFixture::AttributeManagerFixture(BaseFixture &bf)
: _msp(std::make_shared<AttributeManager>(test_dir, "test.subdb", TuneFileAttributes(),
bf._fileHeaderContext, bf._attributeFieldWriter, bf._hwInfo)),
- _m(*_msp),
- _aw(_msp)
+ _m(*_msp)
{}
-AttributeManagerFixture::~AttributeManagerFixture() {}
+AttributeManagerFixture::~AttributeManagerFixture() = default;
struct Fixture : public BaseFixture, public AttributeManagerFixture
{
@@ -530,6 +528,7 @@ Test::requireThatShrinkWorks()
Fixture f;
AttributeManager &am = f._m;
AttributeVector::SP av = f.addAttribute("a10");
+ AttributeWriter aw(f._msp);
av->addDocs(1000 - av->getNumDocs());
av->commit(50, 50);
@@ -546,13 +545,13 @@ Test::requireThatShrinkWorks()
EXPECT_FALSE(av->canShrinkLidSpace());
EXPECT_EQUAL(1000u, av->getNumDocs());
EXPECT_EQUAL(100u, av->getCommittedDocIdLimit());
- f._aw.heartBeat(51);
+ aw.heartBeat(51);
EXPECT_TRUE(av->wantShrinkLidSpace());
EXPECT_FALSE(av->canShrinkLidSpace());
EXPECT_EQUAL(ft->getApproxMemoryGain().getBefore(),
ft->getApproxMemoryGain().getAfter());
g.reset();
- f._aw.heartBeat(52);
+ aw.heartBeat(52);
EXPECT_TRUE(av->wantShrinkLidSpace());
EXPECT_TRUE(av->canShrinkLidSpace());
EXPECT_TRUE(ft->getApproxMemoryGain().getBefore() >
diff --git a/searchcore/src/tests/proton/attribute/exclusive_attribute_read_accessor/exclusive_attribute_read_accessor_test.cpp b/searchcore/src/tests/proton/attribute/exclusive_attribute_read_accessor/exclusive_attribute_read_accessor_test.cpp
index 6d69d9b225b..c5ae0f97875 100644
--- a/searchcore/src/tests/proton/attribute/exclusive_attribute_read_accessor/exclusive_attribute_read_accessor_test.cpp
+++ b/searchcore/src/tests/proton/attribute/exclusive_attribute_read_accessor/exclusive_attribute_read_accessor_test.cpp
@@ -37,7 +37,7 @@ TEST_F("require that attribute write thread is blocked while guard is held", Fix
{
ReadGuard::UP guard = f.accessor.takeGuard();
Gate gate;
- f.writer.execute("myattr", [&gate]() { gate.countDown(); });
+ f.writer.execute(f.writer.getExecutorId(f.attribute->getNamePrefix()), [&gate]() { gate.countDown(); });
bool reachedZero = gate.await(100);
EXPECT_FALSE(reachedZero);
EXPECT_EQUAL(1u, gate.getCount());
diff --git a/searchcore/src/tests/proton/common/document_type_inspector/document_type_inspector_test.cpp b/searchcore/src/tests/proton/common/document_type_inspector/document_type_inspector_test.cpp
index 2dbff7d40dd..167865b5c68 100644
--- a/searchcore/src/tests/proton/common/document_type_inspector/document_type_inspector_test.cpp
+++ b/searchcore/src/tests/proton/common/document_type_inspector/document_type_inspector_test.cpp
@@ -1,78 +1,131 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/searchcore/proton/common/document_type_inspector.h>
#include <vespa/vespalib/testkit/testapp.h>
-#include <vespa/document/repo/configbuilder.h>
-#include <vespa/document/repo/documenttyperepo.h>
+#include <vespa/document/base/field.h>
+#include <vespa/document/datatype/datatypes.h>
using namespace document;
using namespace proton;
-using document::config_builder::DocumenttypesConfigBuilderHelper;
-using document::config_builder::Struct;
-const int32_t doc_type_id = 787121340;
-const vespalib::string type_name = "test";
-const vespalib::string header_name = type_name + ".header";
-const vespalib::string body_name = type_name + ".body";
-
-std::unique_ptr<const DocumentTypeRepo>
-makeOldDocTypeRepo()
+template <class Type>
+void
+addFields(Type &type, bool fieldF3IsString, bool hasFieldF4, bool hasFieldF5)
{
- DocumenttypesConfigBuilderHelper builder;
- builder.document(doc_type_id, type_name,
- Struct(header_name), Struct(body_name).
- addField("f1", DataType::T_STRING).
- addField("f2", DataType::T_STRING).
- addField("f3", DataType::T_STRING).
- addField("f4", DataType::T_STRING));
- return std::unique_ptr<const DocumentTypeRepo>(new DocumentTypeRepo(builder.config()));
+ type.addField(Field("f1", 1, *DataType::STRING, true));
+ type.addField(Field("f2", 2, *DataType::STRING, true));
+ type.addField(Field("f3", 3, fieldF3IsString ? *DataType::STRING : *DataType::INT, true));
+ if (hasFieldF4) {
+ type.addField(Field("f4", 4, *DataType::STRING, true));
+ }
+ if (hasFieldF5) {
+ type.addField(Field("f5", 5, *DataType::STRING, true));
+ }
}
-std::unique_ptr<const DocumentTypeRepo>
-makeNewDocTypeRepo()
+struct DocumentTypeFixture
+{
+ DocumentType _documentType;
+ StructDataType _structFieldType;
+ ArrayDataType _structArrayFieldType;
+ MapDataType _structMapFieldType;
+ MapDataType _mapFieldType;
+
+ DocumentTypeFixture(bool fieldF3IsString, bool hasFieldF4, bool hasFieldF5, bool hasStruct, bool mapKeyIsByte);
+ ~DocumentTypeFixture();
+};
+
+DocumentTypeFixture::DocumentTypeFixture(bool fieldF3IsString, bool hasFieldF4, bool hasFieldF5, bool hasStruct, bool mapKeyIsByte)
+ : _documentType("test"),
+ _structFieldType("struct"),
+ _structArrayFieldType(_structFieldType),
+ _structMapFieldType(mapKeyIsByte ? *DataType::BYTE : *DataType::STRING, _structFieldType),
+ _mapFieldType(mapKeyIsByte ? *DataType::BYTE : *DataType::STRING, *DataType::STRING)
{
- DocumenttypesConfigBuilderHelper builder;
- builder.document(doc_type_id, type_name,
- Struct(header_name), Struct(body_name).
- addField("f1", DataType::T_STRING).
- addField("f2", DataType::T_STRING).
- addField("f3", DataType::T_INT).
- addField("f5", DataType::T_STRING));
- return std::unique_ptr<const DocumentTypeRepo>(new DocumentTypeRepo(builder.config()));
+ addFields(_documentType, fieldF3IsString, hasFieldF4, hasFieldF5);
+ if (hasStruct) {
+ addFields(_structFieldType, fieldF3IsString, hasFieldF4, hasFieldF5);
+ _documentType.addField(Field("sarray", 11, _structArrayFieldType, true));
+ _documentType.addField(Field("smap", 12, _structMapFieldType, true));
+ _documentType.addField(Field("map", 13, _mapFieldType, true));
+ }
}
+DocumentTypeFixture::~DocumentTypeFixture() = default;
+
struct Fixture
{
- std::unique_ptr<const DocumentTypeRepo> _oldRepo;
- std::unique_ptr<const DocumentTypeRepo> _newRepo;
+ DocumentTypeFixture _oldDocType;
+ DocumentTypeFixture _newDocType;
DocumentTypeInspector _inspector;
- Fixture()
- : _oldRepo(makeOldDocTypeRepo()),
- _newRepo(makeNewDocTypeRepo()),
- _inspector(*_oldRepo->getDocumentType("test"), *_newRepo->getDocumentType("test"))
+ Fixture(bool hasStruct = true, bool mapKeyIsByte = false)
+ : _oldDocType(true, true, false, hasStruct, mapKeyIsByte),
+ _newDocType(false, false, true, true, false),
+ _inspector(_oldDocType._documentType, _newDocType._documentType)
{
}
};
TEST_F("require that unchanged fields are known", Fixture)
{
- EXPECT_TRUE(f._inspector.hasUnchangedField("f1"));
- EXPECT_TRUE(f._inspector.hasUnchangedField("f2"));
+ const IDocumentTypeInspector &inspector = f._inspector;
+ EXPECT_TRUE(inspector.hasUnchangedField("f1"));
+ EXPECT_TRUE(inspector.hasUnchangedField("f2"));
+ EXPECT_TRUE(inspector.hasUnchangedField("sarray.f1"));
+ EXPECT_TRUE(inspector.hasUnchangedField("sarray.f2"));
+ EXPECT_TRUE(inspector.hasUnchangedField("smap.key"));
+ EXPECT_TRUE(inspector.hasUnchangedField("smap.value.f1"));
+ EXPECT_TRUE(inspector.hasUnchangedField("smap.value.f2"));
+ EXPECT_TRUE(inspector.hasUnchangedField("map.key"));
+ EXPECT_TRUE(inspector.hasUnchangedField("map.value"));
}
TEST_F("require that changed fields are detected", Fixture)
{
- EXPECT_FALSE(f._inspector.hasUnchangedField("f3"));
+ const IDocumentTypeInspector &inspector = f._inspector;
+ EXPECT_FALSE(inspector.hasUnchangedField("f3"));
+ EXPECT_FALSE(inspector.hasUnchangedField("sarray.f3"));
+ EXPECT_FALSE(inspector.hasUnchangedField("smap.value.f3"));
}
TEST_F("require that partially missing fields are detected", Fixture)
{
- EXPECT_FALSE(f._inspector.hasUnchangedField("f4"));
- EXPECT_FALSE(f._inspector.hasUnchangedField("f5"));
+ const IDocumentTypeInspector &inspector = f._inspector;
+ EXPECT_FALSE(inspector.hasUnchangedField("f4"));
+ EXPECT_FALSE(inspector.hasUnchangedField("f5"));
+ EXPECT_FALSE(inspector.hasUnchangedField("sarray.f4"));
+ EXPECT_FALSE(inspector.hasUnchangedField("sarray.f5"));
+ EXPECT_FALSE(inspector.hasUnchangedField("smap.value.f4"));
+ EXPECT_FALSE(inspector.hasUnchangedField("smap.value.f5"));
}
TEST_F("require that non-existing fields are NOT known", Fixture)
{
- EXPECT_FALSE(f._inspector.hasUnchangedField("not"));
+ const IDocumentTypeInspector &inspector = f._inspector;
+ EXPECT_FALSE(inspector.hasUnchangedField("not"));
+ EXPECT_FALSE(inspector.hasUnchangedField("sarray.not"));
+ EXPECT_FALSE(inspector.hasUnchangedField("smap.not"));
+}
+
+TEST_F("require that map key type change is detected", Fixture(true, true))
+{
+ const IDocumentTypeInspector &inspector = f._inspector;
+ EXPECT_FALSE(inspector.hasUnchangedField("smap.key"));
+ EXPECT_FALSE(inspector.hasUnchangedField("smap.value.f1"));
+ EXPECT_FALSE(inspector.hasUnchangedField("smap.value.f2"));
+ EXPECT_FALSE(inspector.hasUnchangedField("map.key"));
+ EXPECT_FALSE(inspector.hasUnchangedField("map.value"));
+}
+
+TEST_F("require that struct addition is detected", Fixture(false, false))
+{
+ const IDocumentTypeInspector &inspector = f._inspector;
+ EXPECT_FALSE(inspector.hasUnchangedField("sarray.f1"));
+ EXPECT_FALSE(inspector.hasUnchangedField("sarray.f2"));
+ EXPECT_FALSE(inspector.hasUnchangedField("smap.key"));
+ EXPECT_FALSE(inspector.hasUnchangedField("smap.value.f1"));
+ EXPECT_FALSE(inspector.hasUnchangedField("smap.value.f2"));
+ EXPECT_FALSE(inspector.hasUnchangedField("map.key"));
+ EXPECT_FALSE(inspector.hasUnchangedField("map.value"));
}
TEST_MAIN()
diff --git a/searchcore/src/tests/proton/docsummary/docsummary.cpp b/searchcore/src/tests/proton/docsummary/docsummary.cpp
index 79d38e2dc56..1c901097812 100644
--- a/searchcore/src/tests/proton/docsummary/docsummary.cpp
+++ b/searchcore/src/tests/proton/docsummary/docsummary.cpp
@@ -829,20 +829,16 @@ Test::requireThatAttributesAreUsed()
"bi:[]}", *rep, 1, false));
TEST_DO(assertTensor(Tensor::UP(), "bj", *rep, 1, rclass));
- proton::IAttributeManager::SP attributeManager =
- dc._ddb->getReadySubDB()->getAttributeManager();
- search::ISequencedTaskExecutor &attributeFieldWriter =
- attributeManager->getAttributeFieldWriter();
- search::AttributeVector *bjAttr =
- attributeManager->getWritableAttribute("bj");
- search::tensor::TensorAttribute *bjTensorAttr =
- dynamic_cast<search::tensor::TensorAttribute *>(bjAttr);
-
- attributeFieldWriter.
- execute("bj",
- [&]() { bjTensorAttr->setTensor(3,
- *createTensor({ {{{"x", "a"},{"y", "b"}}, 4} }, { "x"}));
- bjTensorAttr->commit(); });
+ proton::IAttributeManager::SP attributeManager = dc._ddb->getReadySubDB()->getAttributeManager();
+ search::ISequencedTaskExecutor &attributeFieldWriter = attributeManager->getAttributeFieldWriter();
+ search::AttributeVector *bjAttr = attributeManager->getWritableAttribute("bj");
+ auto bjTensorAttr = dynamic_cast<search::tensor::TensorAttribute *>(bjAttr);
+
+ attributeFieldWriter.execute(attributeFieldWriter.getExecutorId(bjAttr->getNamePrefix()),
+ [&]() {
+ bjTensorAttr->setTensor(3, *createTensor({ {{{"x", "a"},{"y", "b"}}, 4} }, { "x"}));
+ bjTensorAttr->commit();
+ });
attributeFieldWriter.sync();
DocsumReply::UP rep2 = dc._ddb->getDocsums(req);
@@ -961,8 +957,7 @@ Test::requireThatUrisAreUsed()
Document::UP exp = bc._bld.startDocument("doc::0").
startIndexField("urisingle").
startSubField("all").
- addUrlTokenizedString(
- "http://www.example.com:81/fluke?ab=2#4").
+ addUrlTokenizedString("http://www.example.com:81/fluke?ab=2#4").
endSubField().
startSubField("scheme").
addUrlTokenizedString("http").
@@ -986,8 +981,7 @@ Test::requireThatUrisAreUsed()
startIndexField("uriarray").
startElement(1).
startSubField("all").
- addUrlTokenizedString(
- "http://www.example.com:82/fluke?ab=2#8").
+ addUrlTokenizedString("http://www.example.com:82/fluke?ab=2#8").
endSubField().
startSubField("scheme").
addUrlTokenizedString("http").
@@ -1010,8 +1004,7 @@ Test::requireThatUrisAreUsed()
endElement().
startElement(1).
startSubField("all").
- addUrlTokenizedString(
- "http://www.flickr.com:82/fluke?ab=2#9").
+ addUrlTokenizedString("http://www.flickr.com:82/fluke?ab=2#9").
endSubField().
startSubField("scheme").
addUrlTokenizedString("http").
@@ -1036,8 +1029,7 @@ Test::requireThatUrisAreUsed()
startIndexField("uriwset").
startElement(4).
startSubField("all").
- addUrlTokenizedString(
- "http://www.example.com:83/fluke?ab=2#12").
+ addUrlTokenizedString("http://www.example.com:83/fluke?ab=2#12").
endSubField().
startSubField("scheme").
addUrlTokenizedString("http").
@@ -1060,8 +1052,7 @@ Test::requireThatUrisAreUsed()
endElement().
startElement(7).
startSubField("all").
- addUrlTokenizedString(
- "http://www.flickr.com:85/fluke?ab=2#13").
+ addUrlTokenizedString("http://www.flickr.com:85/fluke?ab=2#13").
endSubField().
startSubField("scheme").
addUrlTokenizedString("http").
diff --git a/searchcore/src/tests/proton/docsummary/summaryfieldconverter_test.cpp b/searchcore/src/tests/proton/docsummary/summaryfieldconverter_test.cpp
index 7f8ce99beb9..73d071be96f 100644
--- a/searchcore/src/tests/proton/docsummary/summaryfieldconverter_test.cpp
+++ b/searchcore/src/tests/proton/docsummary/summaryfieldconverter_test.cpp
@@ -33,7 +33,7 @@
#include <vespa/document/fieldvalue/referencefieldvalue.h>
#include <vespa/document/predicate/predicate.h>
#include <vespa/document/repo/configbuilder.h>
-#include <vespa/document/repo/documenttyperepo.h>
+#include <vespa/document/repo/fixedtyperepo.h>
#include <vespa/searchsummary/docsummary/summaryfieldconverter.h>
#include <vespa/searchsummary/docsummary/linguisticsannotation.h>
#include <vespa/searchsummary/docsummary/searchdatatype.h>
diff --git a/searchcore/src/tests/proton/documentdb/combiningfeedview/combiningfeedview_test.cpp b/searchcore/src/tests/proton/documentdb/combiningfeedview/combiningfeedview_test.cpp
index f06bb124eb8..958be6a4686 100644
--- a/searchcore/src/tests/proton/documentdb/combiningfeedview/combiningfeedview_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/combiningfeedview/combiningfeedview_test.cpp
@@ -1,15 +1,16 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/log/log.h>
-LOG_SETUP("combiningfeedview_test");
#include <vespa/document/test/make_bucket_space.h>
-#include <vespa/searchcore/proton/feedoperation/moveoperation.h>
+#include <vespa/searchcore/proton/feedoperation/operations.h>
#include <vespa/searchcore/proton/server/combiningfeedview.h>
#include <vespa/searchcore/proton/test/test.h>
#include <vespa/searchlib/common/idestructorcallback.h>
#include <vespa/document/update/documentupdate.h>
#include <vespa/vespalib/testkit/testapp.h>
+#include <vespa/log/log.h>
+LOG_SETUP("combiningfeedview_test");
+
using document::DocumentTypeRepo;
using document::DocumentUpdate;
using document::test::makeBucketSpace;
@@ -22,8 +23,8 @@ typedef std::vector<IFeedView::SP> FeedViewVector;
struct MyStreamHandler : public NewConfigOperation::IStreamHandler
{
- virtual void serializeConfig(SerialNum, vespalib::nbostream &) override {}
- virtual void deserializeConfig(SerialNum, vespalib::nbostream &) override {}
+ void serializeConfig(SerialNum, vespalib::nbostream &) override {}
+ void deserializeConfig(SerialNum, vespalib::nbostream &) override {}
};
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 bab6aff821f..760f7457d33 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
@@ -14,6 +14,7 @@
#include <vespa/searchcore/proton/reference/i_document_db_reference_resolver.h>
#include <vespa/searchcore/proton/reprocessing/i_reprocessing_task.h>
#include <vespa/searchcore/proton/reprocessing/reprocessingrunner.h>
+#include <vespa/searchcore/proton/feedoperation/operations.h>
#include <vespa/searchcore/proton/server/bootstrapconfig.h>
#include <vespa/searchcore/proton/server/document_subdb_explorer.h>
#include <vespa/searchcore/proton/server/emptysearchview.h>
diff --git a/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp b/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp
index e774728b41e..a1bce7174bf 100644
--- a/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp
@@ -316,7 +316,7 @@ struct UpdateContext {
DocumentUpdate::SP update;
BucketId bucketId;
UpdateContext(const vespalib::string &docId, DocBuilder &builder) :
- update(new DocumentUpdate(builder.getDocumentType(), DocumentId(docId))),
+ update(new DocumentUpdate(*builder.getDocumentTypeRepo(), builder.getDocumentType(), DocumentId(docId))),
bucketId(BucketFactory::getBucketId(update->getId()))
{
}
diff --git a/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp b/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp
index a9fa79f513c..d21e5abe30b 100644
--- a/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp
@@ -11,6 +11,7 @@
#include <vespa/searchcore/proton/server/isummaryadapter.h>
#include <vespa/searchcore/proton/server/matchview.h>
#include <vespa/searchcore/proton/server/searchable_feed_view.h>
+#include <vespa/searchcore/proton/feedoperation/operations.h>
#include <vespa/searchcore/proton/test/document_meta_store_context_observer.h>
#include <vespa/searchcore/proton/test/dummy_document_store.h>
#include <vespa/searchcore/proton/test/dummy_summary_manager.h>
@@ -478,11 +479,11 @@ struct DocumentContext
DocumentContext::DocumentContext(const vespalib::string &docId, uint64_t timestamp, DocBuilder &builder)
: doc(builder.startDocument(docId).startSummaryField("s1").addStr(docId).endField().endDocument().release()),
- upd(new DocumentUpdate(builder.getDocumentType(), doc->getId())),
+ upd(new DocumentUpdate(*builder.getDocumentTypeRepo(), builder.getDocumentType(), doc->getId())),
bid(BucketFactory::getNumBucketBits(), doc->getId().getGlobalId().convertToBucketId().getRawId()),
ts(timestamp)
{}
-DocumentContext::~DocumentContext() {}
+DocumentContext::~DocumentContext() = default;
struct FeedTokenContext
{
diff --git a/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp b/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp
index e8247a52199..d07c29ead69 100644
--- a/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp
@@ -9,6 +9,8 @@
#include <vespa/searchcore/proton/server/putdonecontext.h>
#include <vespa/searchcore/proton/server/removedonecontext.h>
#include <vespa/searchcore/proton/server/storeonlyfeedview.h>
+#include <vespa/searchcore/proton/feedoperation/moveoperation.h>
+#include <vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.h>
#include <vespa/searchcore/proton/reference/dummy_gid_to_lid_change_handler.h>
#include <vespa/searchcore/proton/test/mock_summary_adapter.h>
#include <vespa/searchcore/proton/test/thread_utils.h>
diff --git a/searchcore/src/tests/proton/feedoperation/feedoperation_test.cpp b/searchcore/src/tests/proton/feedoperation/feedoperation_test.cpp
index 9a9d896f2b9..e87e9209a17 100644
--- a/searchcore/src/tests/proton/feedoperation/feedoperation_test.cpp
+++ b/searchcore/src/tests/proton/feedoperation/feedoperation_test.cpp
@@ -122,7 +122,7 @@ public:
}
auto makeUpdate() {
- auto upd(std::make_shared<DocumentUpdate>(_docType, docId));
+ auto upd(std::make_shared<DocumentUpdate>(*_repo, _docType, docId));
upd->addUpdate(FieldUpdate(upd->getType().getField("string")).
addUpdate(AssignValueUpdate(StringFieldValue("newval"))));
return upd;
@@ -136,6 +136,7 @@ public:
TEST("require that toString() on derived classes are meaningful")
{
+ DocumentTypeRepo repo;
BucketId bucket_id1(42);
BucketId bucket_id2(43);
BucketId bucket_id3(44);
@@ -146,7 +147,7 @@ TEST("require that toString() on derived classes are meaningful")
MyStreamHandler stream_handler;
DocumentIdT doc_id_limit = 15;
DocumentId doc_id("doc:foo:bar");
- DocumentUpdate::SP update(new DocumentUpdate(*DataType::DOCUMENT, doc_id));
+ DocumentUpdate::SP update(new DocumentUpdate(repo, *DataType::DOCUMENT, doc_id));
EXPECT_EQUAL("DeleteBucket(BucketId(0x0000000000000000), serialNum=0)",
DeleteBucketOperation().toString());
diff --git a/searchcore/src/tests/proton/persistenceengine/persistenceengine_test.cpp b/searchcore/src/tests/proton/persistenceengine/persistenceengine_test.cpp
index 73580416e65..7f065d0cc15 100644
--- a/searchcore/src/tests/proton/persistenceengine/persistenceengine_test.cpp
+++ b/searchcore/src/tests/proton/persistenceengine/persistenceengine_test.cpp
@@ -67,7 +67,9 @@ createDoc(const DocumentType &docType, const DocumentId &docId)
document::DocumentUpdate::SP
createUpd(const DocumentType& docType, const DocumentId &docId)
{
- return document::DocumentUpdate::SP(new document::DocumentUpdate(docType, docId));
+ static std::vector<std::unique_ptr<document::DocumentTypeRepo>> repoList;
+ repoList.emplace_back(std::make_unique<document::DocumentTypeRepo>(docType));
+ return std::make_shared<document::DocumentUpdate>(*repoList.back(), docType, docId);
}
storage::spi::ClusterState
diff --git a/searchcore/src/tests/proton/reprocessing/attribute_reprocessing_initializer/attribute_reprocessing_initializer_test.cpp b/searchcore/src/tests/proton/reprocessing/attribute_reprocessing_initializer/attribute_reprocessing_initializer_test.cpp
index 93c192b57e8..7be774f7291 100644
--- a/searchcore/src/tests/proton/reprocessing/attribute_reprocessing_initializer/attribute_reprocessing_initializer_test.cpp
+++ b/searchcore/src/tests/proton/reprocessing/attribute_reprocessing_initializer/attribute_reprocessing_initializer_test.cpp
@@ -306,6 +306,18 @@ TEST("require that added attribute aspect with flushed attribute after interrupt
EXPECT_TRUE(f.assertAttributes({}));
}
+TEST_F("require that removed attribute aspect from struct field does not require document field populate", Fixture)
+{
+ f.addOldConfig({"array.a"}, {"array.a"}).addNewConfig({"array.a"}, {}).init();
+ EXPECT_TRUE(f.assertFields({}));
+}
+
+TEST_F("require that added attribute aspect to struct field requires attribute populate", Fixture)
+{
+ f.addOldConfig({"array.a"}, {}).addNewConfig({"array.a"}, {"array.a"}).init();
+ EXPECT_TRUE(f.assertAttributes({"array.a"}));
+}
+
TEST_MAIN()
{
TEST_RUN_ALL();
diff --git a/searchcore/src/tests/proton/server/feedstates_test.cpp b/searchcore/src/tests/proton/server/feedstates_test.cpp
index dfa461e2b57..f206ffc9b17 100644
--- a/searchcore/src/tests/proton/server/feedstates_test.cpp
+++ b/searchcore/src/tests/proton/server/feedstates_test.cpp
@@ -1,8 +1,6 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
// Unit tests for feedstates.
-#include <vespa/log/log.h>
-LOG_SETUP("feedstates_test");
#include <vespa/document/base/documentid.h>
#include <vespa/document/base/testdocrepo.h>
@@ -11,6 +9,7 @@ LOG_SETUP("feedstates_test");
#include <vespa/searchcore/proton/server/feedstates.h>
#include <vespa/searchcore/proton/server/ireplayconfig.h>
#include <vespa/searchcore/proton/server/memoryconfigstore.h>
+#include <vespa/searchcore/proton/feedoperation/removeoperation.h>
#include <vespa/searchcore/proton/test/dummy_feed_view.h>
#include <vespa/searchlib/common/serialnum.h>
#include <vespa/vespalib/objects/nbostream.h>
@@ -18,6 +17,9 @@ LOG_SETUP("feedstates_test");
#include <vespa/vespalib/util/buffer.h>
#include <vespa/searchcore/proton/bucketdb/bucketdbhandler.h>
+#include <vespa/log/log.h>
+LOG_SETUP("feedstates_test");
+
using document::BucketId;
using document::DocumentId;
using document::DocumentTypeRepo;
@@ -83,7 +85,7 @@ Fixture::Fixture()
state("doctypename", feed_view_ptr, _bucketDBHandler, replay_config, config_store)
{
}
-Fixture::~Fixture() {}
+Fixture::~Fixture() = default;
struct RemoveOperationContext
@@ -107,7 +109,7 @@ RemoveOperationContext::RemoveOperationContext(search::SerialNum serial)
packet.reset(new Packet());
packet->add(Packet::Entry(serial, FeedOperation::REMOVE, buf));
}
-RemoveOperationContext::~RemoveOperationContext() {}
+RemoveOperationContext::~RemoveOperationContext() = default;
TEST_F("require that active FeedView can change during replay", Fixture)
{
RemoveOperationContext opCtx(10);
diff --git a/searchcore/src/vespa/searchcore/config/proton.def b/searchcore/src/vespa/searchcore/config/proton.def
index e66466aa1cb..7578066d93a 100644
--- a/searchcore/src/vespa/searchcore/config/proton.def
+++ b/searchcore/src/vespa/searchcore/config/proton.def
@@ -467,7 +467,7 @@ hwinfo.cpu.cores int default = 0 restart
## max(ceil(hwinfo.cpu.cores * feeding.concurrency), summary.log.numthreads)
## The number of threads in each of pools 2-4 is calculated as:
## max(ceil((hwinfo.cpu.cores * feeding.concurrency)/3), indexing.threads)
-feeding.concurrency double default = 0.5 restart
+feeding.concurrency double default = 0.2 restart
## Adjustment to resource limit when determining if maintenance jobs can run.
##
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attribute_aspect_delayer.cpp b/searchcore/src/vespa/searchcore/proton/attribute/attribute_aspect_delayer.cpp
index 9807faa5021..cf803ec0368 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/attribute_aspect_delayer.cpp
+++ b/searchcore/src/vespa/searchcore/proton/attribute/attribute_aspect_delayer.cpp
@@ -29,11 +29,15 @@ bool fastPartialUpdateAttribute(const search::attribute::Config &cfg) {
(basicType != BasicType::Type::REFERENCE));
}
+bool isStructFieldAttribute(const vespalib::string &name) {
+ return name.find('.') != vespalib::string::npos;
+}
+
bool willTriggerReprocessOnAttributeAspectRemoval(const search::attribute::Config &cfg,
const IIndexschemaInspector &indexschemaInspector,
const vespalib::string &name)
{
- return fastPartialUpdateAttribute(cfg) && !indexschemaInspector.isStringIndex(name);
+ return fastPartialUpdateAttribute(cfg) && !indexschemaInspector.isStringIndex(name) && !isStructFieldAttribute(name);
}
@@ -73,6 +77,7 @@ handleNewAttributes(const AttributesConfig &oldAttributesConfig,
SummarymapConfigBuilder &summarymapConfig)
{
vespalib::hash_set<vespalib::string> delayed;
+ vespalib::hash_set<vespalib::string> delayedStruct;
AttributesConfigHash oldAttrs(oldAttributesConfig.attribute);
for (const auto &newAttr : newAttributesConfig.attribute) {
search::attribute::Config newCfg = ConfigConverter::convert(newAttr);
@@ -102,6 +107,10 @@ handleNewAttributes(const AttributesConfig &oldAttributesConfig,
} else {
// Delay addition of attribute aspect
delayed.insert(newAttr.name);
+ auto pos = newAttr.name.find('.');
+ if (pos != vespalib::string::npos) {
+ delayedStruct.insert(newAttr.name.substr(0, pos));
+ }
}
}
}
@@ -111,6 +120,11 @@ handleNewAttributes(const AttributesConfig &oldAttributesConfig,
if (itr == delayed.end()) {
summarymapConfig.override.emplace_back(override);
}
+ } else if (override.command == "attributecombiner") {
+ auto itr = delayedStruct.find(override.field);
+ if (itr == delayedStruct.end()) {
+ summarymapConfig.override.emplace_back(override);
+ }
} else {
summarymapConfig.override.emplace_back(override);
}
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.cpp b/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.cpp
index 0a0ecbda21c..506f4b5164c 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.cpp
+++ b/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.cpp
@@ -7,16 +7,16 @@ LOG_SETUP(".proton.attribute.attribute_writer");
#include "ifieldupdatecallback.h"
#include "attributemanager.h"
#include "document_field_extractor.h"
-#include <vespa/document/base/exceptions.h>
-#include <vespa/document/datatype/documenttype.h>
-#include <vespa/document/fieldvalue/document.h>
#include <vespa/searchcore/proton/attribute/imported_attributes_repo.h>
#include <vespa/searchcore/proton/common/attrupdate.h>
#include <vespa/searchlib/attribute/attributevector.hpp>
#include <vespa/searchlib/attribute/imported_attribute_vector.h>
#include <vespa/searchlib/common/isequencedtaskexecutor.h>
#include <vespa/searchlib/common/idestructorcallback.h>
-
+#include <vespa/document/base/exceptions.h>
+#include <vespa/document/datatype/documenttype.h>
+#include <vespa/document/fieldvalue/document.h>
+#include <vespa/vespalib/stllike/hash_map.hpp>
using namespace document;
using namespace search;
@@ -47,6 +47,8 @@ AttributeWriter::WriteField::buildFieldPath(const DocumentType &docType)
docType.buildFieldPath(fp, name);
} catch (document::FieldNotFoundException & e) {
fp = FieldPath();
+ } catch (vespalib::IllegalArgumentException &e) {
+ fp = FieldPath();
}
_fieldPath = std::move(fp);
}
@@ -230,7 +232,7 @@ public:
FieldContext::FieldContext(ISequencedTaskExecutor &writer, AttributeVector *attr)
: _name(attr->getName()),
- _executorId(writer.getExecutorId(_name)),
+ _executorId(writer.getExecutorId(attr->getNamePrefix())),
_attr(attr)
{
}
@@ -412,7 +414,7 @@ AttributeWriter::setupWriteContexts()
{
std::vector<FieldContext> fieldContexts;
assert(_writeContexts.empty());
- for (auto attr : _writableAttributes) {
+ for (auto attr : getWritableAttributes()) {
fieldContexts.emplace_back(_attributeFieldWriter, attr);
}
std::sort(fieldContexts.begin(), fieldContexts.end());
@@ -469,14 +471,23 @@ AttributeWriter::internalRemove(SerialNum serialNum, DocumentIdT lid, bool immed
AttributeWriter::AttributeWriter(const proton::IAttributeManager::SP &mgr)
: _mgr(mgr),
_attributeFieldWriter(mgr->getAttributeFieldWriter()),
- _writableAttributes(mgr->getWritableAttributes()),
_writeContexts(),
_dataType(nullptr),
- _hasStructFieldAttribute(false)
+ _hasStructFieldAttribute(false),
+ _attrMap()
{
setupWriteContexts();
+ setupAttriuteMapping();
}
+void AttributeWriter::setupAttriuteMapping() {
+ for (auto attr : getWritableAttributes()) {
+ vespalib::stringref name = attr->getName();
+ _attrMap[name] = AttrWithId(attr, _attributeFieldWriter.getExecutorId(attr->getNamePrefix()));
+ }
+}
+
+
AttributeWriter::~AttributeWriter()
{
_attributeFieldWriter.sync();
@@ -545,7 +556,8 @@ AttributeWriter::update(SerialNum serialNum, const DocumentUpdate &upd, Document
for (const auto &fupd : upd.getUpdates()) {
LOG(debug, "Retrieving guard for attribute vector '%s'.", fupd.getField().getName().c_str());
- AttributeVector *attrp = _mgr->getWritableAttribute(fupd.getField().getName());
+ auto found = _attrMap.find(fupd.getField().getName());
+ AttributeVector * attrp = (found != _attrMap.end()) ? found->second.first : nullptr;
onUpdate.onUpdateField(fupd.getField().getName(), attrp);
if (attrp == nullptr) {
LOG(spam, "Failed to find attribute vector %s", fupd.getField().getName().c_str());
@@ -555,7 +567,7 @@ AttributeWriter::update(SerialNum serialNum, const DocumentUpdate &upd, Document
// document and attribute.
if (attrp->getStatus().getLastSyncToken() >= serialNum)
continue;
- args[_attributeFieldWriter.getExecutorId(attrp->getName()).getId()]->_updates.emplace_back(attrp, &fupd);
+ args[found->second.second.getId()]->_updates.emplace_back(attrp, &fupd);
LOG(debug, "About to apply update for docId %u in attribute vector '%s'.", lid, attrp->getName().c_str());
}
// NOTE: The lifetime of the field update will be ensured by keeping the document update alive
@@ -572,11 +584,10 @@ AttributeWriter::update(SerialNum serialNum, const DocumentUpdate &upd, Document
void
AttributeWriter::heartBeat(SerialNum serialNum)
{
- for (auto attrp : _writableAttributes) {
- auto &attr = *attrp;
- _attributeFieldWriter.execute(attr.getName(),
- [serialNum, &attr]()
- { applyHeartBeat(serialNum, attr); });
+ for (auto entry : _attrMap) {
+ _attributeFieldWriter.execute(entry.second.second,
+ [serialNum, attr=entry.second.first]()
+ { applyHeartBeat(serialNum, *attr); });
}
}
@@ -601,11 +612,10 @@ AttributeWriter::forceCommit(SerialNum serialNum, OnWriteDoneType onWriteDone)
void
AttributeWriter::onReplayDone(uint32_t docIdLimit)
{
- for (auto attrp : _writableAttributes) {
- auto &attr = *attrp;
- _attributeFieldWriter.execute(attr.getName(),
- [docIdLimit, &attr]()
- { applyReplayDone(docIdLimit, attr); });
+ for (auto entry : _attrMap) {
+ _attributeFieldWriter.execute(entry.second.second,
+ [docIdLimit, attr = entry.second.first]()
+ { applyReplayDone(docIdLimit, *attr); });
}
_attributeFieldWriter.sync();
}
@@ -614,12 +624,11 @@ AttributeWriter::onReplayDone(uint32_t docIdLimit)
void
AttributeWriter::compactLidSpace(uint32_t wantedLidLimit, SerialNum serialNum)
{
- for (auto attrp : _writableAttributes) {
- auto &attr = *attrp;
+ for (auto entry : _attrMap) {
_attributeFieldWriter.
- execute(attr.getName(),
- [wantedLidLimit, serialNum, &attr]()
- { applyCompactLidSpace(wantedLidLimit, serialNum, attr); });
+ execute(entry.second.second,
+ [wantedLidLimit, serialNum, attr=entry.second.first]()
+ { applyCompactLidSpace(wantedLidLimit, serialNum, *attr); });
}
_attributeFieldWriter.sync();
}
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.h b/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.h
index f89089ed335..4ea7f3fda6c 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.h
+++ b/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.h
@@ -6,6 +6,7 @@
#include <vespa/searchcore/proton/common/commit_time_tracker.h>
#include <vespa/document/base/fieldpath.h>
#include <vespa/searchlib/common/isequencedtaskexecutor.h>
+#include <vespa/vespalib/stllike/hash_map.h>
namespace document { class DocumentType; }
@@ -25,7 +26,6 @@ private:
typedef document::FieldValue FieldValue;
const IAttributeManager::SP _mgr;
search::ISequencedTaskExecutor &_attributeFieldWriter;
- const std::vector<search::AttributeVector *> &_writableAttributes;
using ExecutorId = search::ISequencedTaskExecutor::ExecutorId;
public:
class WriteField
@@ -58,11 +58,15 @@ public:
bool hasStructFieldAttribute() const { return _hasStructFieldAttribute; }
};
private:
+ using AttrWithId = std::pair<search::AttributeVector *, ExecutorId>;
+ using AttrMap = vespalib::hash_map<vespalib::string, AttrWithId>;
std::vector<WriteContext> _writeContexts;
const DataType *_dataType;
bool _hasStructFieldAttribute;
+ AttrMap _attrMap;
void setupWriteContexts();
+ void setupAttriuteMapping();
void buildFieldPaths(const DocumentType &docType, const DataType *dataType);
void internalPut(SerialNum serialNum, const Document &doc, DocumentIdT lid,
bool immediateCommit, bool allAttributes, OnWriteDoneType onWriteDone);
@@ -73,13 +77,13 @@ public:
AttributeWriter(const proton::IAttributeManager::SP &mgr);
~AttributeWriter();
+ /* Only for in tests that add attributes after AttributeWriter construction. */
+
/**
* Implements IAttributeWriter.
*/
- std::vector<search::AttributeVector *>
- getWritableAttributes() const override;
- search::AttributeVector *
- getWritableAttribute(const vespalib::string &name) const override;
+ std::vector<search::AttributeVector *> getWritableAttributes() const override;
+ search::AttributeVector *getWritableAttribute(const vespalib::string &name) const override;
void put(SerialNum serialNum, const Document &doc, DocumentIdT lid,
bool immediateCommit, OnWriteDoneType onWriteDone) override;
void remove(SerialNum serialNum, DocumentIdT lid,
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp
index ef818f7b407..5faf89aa149 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp
+++ b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp
@@ -78,8 +78,8 @@ std::shared_ptr<ShrinkLidSpaceFlushTarget> allocShrinker(const AttributeVector::
using Type = IFlushTarget::Type;
using Component = IFlushTarget::Component;
+ auto shrinkwrap = std::make_shared<ThreadedCompactableLidSpace>(attr, attributeFieldWriter, attributeFieldWriter.getExecutorId(attr->getNamePrefix()));
const vespalib::string &name = attr->getName();
- auto shrinkwrap = std::make_shared<ThreadedCompactableLidSpace>(attr, attributeFieldWriter, attributeFieldWriter.getExecutorId(name));
auto dir = diskLayout.createAttributeDir(name);
search::SerialNum shrinkSerialNum = estimateShrinkSerialNum(*attr);
return std::make_shared<ShrinkLidSpaceFlushTarget>("attribute.shrink." + name, Type::GC, Component::ATTRIBUTE, shrinkSerialNum, dir->getLastFlushTime(), shrinkwrap);
@@ -569,16 +569,15 @@ AttributeManager::getWritableAttributes() const
void
-AttributeManager::asyncForEachAttribute(std::shared_ptr<IAttributeFunctor>
- func) const
+AttributeManager::asyncForEachAttribute(std::shared_ptr<IAttributeFunctor> func) const
{
for (const auto &attr : _attributes) {
if (attr.second.isExtra()) {
continue;
}
AttributeVector::SP attrsp = attr.second.getAttribute();
- _attributeFieldWriter.
- execute(attr.first, [attrsp, func]() { (*func)(*attrsp); });
+ _attributeFieldWriter.execute(_attributeFieldWriter.getExecutorId(attrsp->getNamePrefix()),
+ [attrsp, func]() { (*func)(*attrsp); });
}
}
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/exclusive_attribute_read_accessor.cpp b/searchcore/src/vespa/searchcore/proton/attribute/exclusive_attribute_read_accessor.cpp
index d9a0ff3d8dd..d1d5b1c9af7 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/exclusive_attribute_read_accessor.cpp
+++ b/searchcore/src/vespa/searchcore/proton/attribute/exclusive_attribute_read_accessor.cpp
@@ -37,8 +37,7 @@ ExclusiveAttributeReadAccessor(const AttributeVector::SP &attribute,
namespace {
void
-attributeWriteBlockingTask(GateSP entranceGate,
- GateSP exitGate)
+attributeWriteBlockingTask(GateSP entranceGate, GateSP exitGate)
{
entranceGate->countDown();
exitGate->await();
@@ -51,9 +50,8 @@ ExclusiveAttributeReadAccessor::takeGuard()
{
GateSP entranceGate = std::make_shared<Gate>();
GateSP exitGate = std::make_shared<Gate>();
- _attributeFieldWriter.execute(_attribute->getName(),
- [entranceGate, exitGate]()
- { attributeWriteBlockingTask(entranceGate, exitGate); });
+ _attributeFieldWriter.execute(_attributeFieldWriter.getExecutorId(_attribute->getNamePrefix()),
+ [entranceGate, exitGate]() { attributeWriteBlockingTask(entranceGate, exitGate); });
entranceGate->await();
return std::make_unique<Guard>(*_attribute, exitGate);
}
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp b/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp
index d3a74bb9a98..8474efb15c9 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp
+++ b/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp
@@ -197,9 +197,8 @@ FilterAttributeManager::asyncForEachAttribute(std::shared_ptr<IAttributeFunctor>
search::AttributeVector::SP attrsp = guard.getSP();
// Name must be extracted in document db master thread or attribute
// writer thread
- vespalib::string attributeName = attrsp->getName();
- attributeFieldWriter.
- execute(attributeName, [attrsp, func]() { (*func)(*attrsp); });
+ attributeFieldWriter.execute(attributeFieldWriter.getExecutorId(attrsp->getNamePrefix()),
+ [attrsp, func]() { (*func)(*attrsp); });
}
}
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/flushableattribute.cpp b/searchcore/src/vespa/searchcore/proton/attribute/flushableattribute.cpp
index a658b11263a..7716fc5ee61 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/flushableattribute.cpp
+++ b/searchcore/src/vespa/searchcore/proton/attribute/flushableattribute.cpp
@@ -243,10 +243,8 @@ FlushableAttribute::initFlush(SerialNum currentSerial)
// Called by document db executor
std::promise<IFlushTarget::Task::UP> promise;
std::future<IFlushTarget::Task::UP> future = promise.get_future();
- _attributeFieldWriter.execute(_attr->getName(),
- [&]() { promise.set_value(
- internalInitFlush(currentSerial));
- });
+ _attributeFieldWriter.execute(_attributeFieldWriter.getExecutorId(_attr->getNamePrefix()),
+ [&]() { promise.set_value(internalInitFlush(currentSerial)); });
return future.get();
}
@@ -257,5 +255,4 @@ FlushableAttribute::getApproxBytesToWriteToDisk() const
return _attr->getEstimatedSaveByteSize();
}
-
} // namespace proton
diff --git a/searchcore/src/vespa/searchcore/proton/common/document_type_inspector.cpp b/searchcore/src/vespa/searchcore/proton/common/document_type_inspector.cpp
index 6cff162ae08..e19fa5351c2 100644
--- a/searchcore/src/vespa/searchcore/proton/common/document_type_inspector.cpp
+++ b/searchcore/src/vespa/searchcore/proton/common/document_type_inspector.cpp
@@ -1,6 +1,11 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "document_type_inspector.h"
+#include <vespa/document/base/exceptions.h>
+#include <vespa/document/base/fieldpath.h>
+
+using document::FieldPath;
+using document::FieldPathEntry;
namespace proton {
@@ -14,12 +19,28 @@ DocumentTypeInspector::DocumentTypeInspector(const document::DocumentType &oldDo
bool
DocumentTypeInspector::hasUnchangedField(const vespalib::string &name) const
{
- if (!_oldDocType.hasField(name) || !_newDocType.hasField(name)) {
+ FieldPath oldPath;
+ FieldPath newPath;
+ try {
+ _oldDocType.buildFieldPath(oldPath, name);
+ _newDocType.buildFieldPath(newPath, name);
+ } catch (document::FieldNotFoundException &e) {
+ return false;
+ } catch (vespalib::IllegalArgumentException &e) {
return false;
}
- const document::Field &oldField = _oldDocType.getField(name);
- const document::Field &newField = _newDocType.getField(name);
- return oldField == newField;
+ if (oldPath.size() != newPath.size()) {
+ return false;
+ }
+ for (uint32_t i = 0; i < oldPath.size(); ++i) {
+ const auto &oldEntry = oldPath[i];
+ const auto &newEntry = newPath[i];
+ if (oldEntry.getType() != newEntry.getType() ||
+ oldEntry.getDataType() != newEntry.getDataType()) {
+ return false;
+ }
+ }
+ return true;
}
} // namespace proton
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/compact_lid_space_operation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/compact_lid_space_operation.cpp
index cd906891b92..c2a3439388a 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/compact_lid_space_operation.cpp
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/compact_lid_space_operation.cpp
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "compact_lid_space_operation.h"
+#include <vespa/vespalib/objects/nbostream.h>
#include <vespa/vespalib/util/stringfmt.h>
namespace proton {
@@ -27,8 +28,7 @@ CompactLidSpaceOperation::serialize(vespalib::nbostream& os) const
}
void
-CompactLidSpaceOperation::deserialize(vespalib::nbostream& is,
- const document::DocumentTypeRepo&)
+CompactLidSpaceOperation::deserialize(vespalib::nbostream& is, const document::DocumentTypeRepo&)
{
is >> _subDbId;
is >> _lidLimit;
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/feedoperation.h b/searchcore/src/vespa/searchcore/proton/feedoperation/feedoperation.h
index 8a00c739126..77b95547bd0 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/feedoperation.h
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/feedoperation.h
@@ -2,10 +2,10 @@
#pragma once
#include <vespa/searchlib/common/serialnum.h>
-#include <vespa/vespalib/objects/nbostream.h>
+#include <vespa/vespalib/stllike/string.h>
namespace document { class DocumentTypeRepo; }
-
+namespace vespalib { class nbostream; }
namespace proton {
class FeedOperation
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.cpp
index 71a701bdb40..67e4d1b4287 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.cpp
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.cpp
@@ -2,6 +2,7 @@
#include "lidvectorcontext.h"
#include <vespa/searchlib/common/bitvector.h>
+#include <vespa/vespalib/objects/nbostream.h>
#include <vespa/log/log.h>
LOG_SETUP(".proton.feedoperation.lidvectorcontext");
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.h b/searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.h
index b432bbcf20a..b307e50da0a 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.h
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.h
@@ -2,9 +2,10 @@
#pragma once
#include <vespa/searchlib/query/base.h>
-#include <vespa/vespalib/objects/nbostream.h>
#include <vector>
+namespace vespalib { class nbostream; }
+
namespace proton {
class LidVectorContext
@@ -29,5 +30,4 @@ public:
size_t getNumLids() const { return _result.size(); }
};
-} // namespace proton
-
+}
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/newconfigoperation.h b/searchcore/src/vespa/searchcore/proton/feedoperation/newconfigoperation.h
index b7b041135d4..144aa534bf7 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/newconfigoperation.h
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/newconfigoperation.h
@@ -2,30 +2,29 @@
#pragma once
#include "feedoperation.h"
-#include <vespa/vespalib/objects/nbostream.h>
namespace proton {
+ namespace feedoperation {
+ struct IStreamHandler {
+ virtual ~IStreamHandler() {}
+ virtual void serializeConfig(search::SerialNum serialNum, vespalib::nbostream &os) = 0;
+ virtual void deserializeConfig(search::SerialNum serialNum, vespalib::nbostream &is) = 0;
+ };
+ }
+
class NewConfigOperation : public FeedOperation
{
public:
- struct IStreamHandler {
- virtual ~IStreamHandler() {}
- virtual void serializeConfig(SerialNum serialNum,
- vespalib::nbostream &os) = 0;
- virtual void deserializeConfig(SerialNum serialNum,
- vespalib::nbostream &is) = 0;
- };
+ using IStreamHandler = feedoperation::IStreamHandler;
private:
IStreamHandler &_streamHandler;
public:
- NewConfigOperation(SerialNum serialNum,
- IStreamHandler &streamHandler);
- virtual ~NewConfigOperation() {}
- virtual void serialize(vespalib::nbostream &os) const override;
- virtual void deserialize(vespalib::nbostream &is,
- const document::DocumentTypeRepo &repo) override;
- virtual vespalib::string toString() const override;
+ NewConfigOperation(SerialNum serialNum, IStreamHandler &streamHandler);
+ ~NewConfigOperation() override {}
+ void serialize(vespalib::nbostream &os) const override;
+ void deserialize(vespalib::nbostream &is, const document::DocumentTypeRepo &repo) override;
+ vespalib::string toString() const override;
};
} // namespace proton
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.cpp
index eea693e4680..69f754cd594 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.cpp
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.cpp
@@ -2,6 +2,7 @@
#include "pruneremoveddocumentsoperation.h"
#include <vespa/vespalib/util/stringfmt.h>
+#include <vespa/vespalib/objects/nbostream.h>
#include <cassert>
#include <vespa/log/log.h>
@@ -22,8 +23,7 @@ PruneRemovedDocumentsOperation::PruneRemovedDocumentsOperation()
PruneRemovedDocumentsOperation::
-PruneRemovedDocumentsOperation(DocumentIdT docIdLimit,
- uint32_t subDbId)
+PruneRemovedDocumentsOperation(DocumentIdT docIdLimit, uint32_t subDbId)
: RemoveDocumentsOperation(FeedOperation::PRUNE_REMOVED_DOCUMENTS),
_subDbId(subDbId)
{
@@ -44,8 +44,7 @@ PruneRemovedDocumentsOperation::serialize(vespalib::nbostream &os) const
void
-PruneRemovedDocumentsOperation::deserialize(vespalib::nbostream &is,
- const DocumentTypeRepo &)
+PruneRemovedDocumentsOperation::deserialize(vespalib::nbostream &is, const DocumentTypeRepo &)
{
is >> _subDbId;
deserializeLidsToRemove(is);
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/removedocumentsoperation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/removedocumentsoperation.cpp
index 6aa479611d1..ef482a19ca3 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/removedocumentsoperation.cpp
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/removedocumentsoperation.cpp
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "removedocumentsoperation.h"
+#include <vespa/vespalib/objects/nbostream.h>
namespace proton {
@@ -16,11 +17,9 @@ RemoveDocumentsOperation::serializeLidsToRemove(vespalib::nbostream &os) const
{
uint32_t mapSize = _lidsToRemoveMap.size();
os << mapSize;
- for (LidsToRemoveMap::const_iterator
- it = _lidsToRemoveMap.begin(), ite = _lidsToRemoveMap.end();
- it != ite; ++it) {
- os << it->first;
- it->second->serialize(os);
+ for (const auto & entry : _lidsToRemoveMap) {
+ os << entry.first;
+ entry.second->serialize(os);
}
}
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.cpp
index f3ef73f4d90..16ddedc4745 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.cpp
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.cpp
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "spoolerreplayoperation.h"
+#include <vespa/vespalib/objects/nbostream.h>
#include <vespa/vespalib/util/stringfmt.h>
using vespalib::make_string;
@@ -14,10 +15,7 @@ SpoolerReplayOperation::SpoolerReplayOperation(Type type)
{
}
-
-SpoolerReplayOperation::SpoolerReplayOperation(Type type,
- SerialNum serialNum,
- SerialNum spoolerSerialNum)
+SpoolerReplayOperation::SpoolerReplayOperation(Type type, SerialNum serialNum, SerialNum spoolerSerialNum)
: FeedOperation(type),
_spoolerSerialNum(spoolerSerialNum)
{
@@ -39,11 +37,8 @@ SpoolerReplayOperation::deserialize(vespalib::nbostream &is)
}
vespalib::string SpoolerReplayOperation::toString() const {
- return make_string(
- "SpoolerReplay%s(spoolerSerialNum=%" PRIu64
- ", serialNum=%" PRIu64 ")",
- getType() == SPOOLER_REPLAY_START ? "Start" : "Complete",
- _spoolerSerialNum, getSerialNum());
+ return make_string("SpoolerReplay%s(spoolerSerialNum=%" PRIu64", serialNum=%" PRIu64 ")",
+ getType() == SPOOLER_REPLAY_START ? "Start" : "Complete", _spoolerSerialNum, getSerialNum());
}
@@ -53,8 +48,7 @@ SpoolerReplayStartOperation::SpoolerReplayStartOperation()
}
-SpoolerReplayStartOperation::SpoolerReplayStartOperation(SerialNum serialNum,
- SerialNum spoolerSerialNum)
+SpoolerReplayStartOperation::SpoolerReplayStartOperation(SerialNum serialNum, SerialNum spoolerSerialNum)
: SpoolerReplayOperation(FeedOperation::SPOOLER_REPLAY_START,
serialNum,
spoolerSerialNum)
@@ -70,12 +64,8 @@ SpoolerReplayCompleteOperation::SpoolerReplayCompleteOperation()
SpoolerReplayCompleteOperation::SpoolerReplayCompleteOperation(SerialNum serialNum,
SerialNum spoolerSerialNum)
- : SpoolerReplayOperation(FeedOperation::SPOOLER_REPLAY_COMPLETE,
- serialNum,
- spoolerSerialNum)
+ : SpoolerReplayOperation(FeedOperation::SPOOLER_REPLAY_COMPLETE, serialNum, spoolerSerialNum)
{
}
-
-
} // namespace proton
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.h b/searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.h
index 028d01dec20..028ad1c6bfa 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.h
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.h
@@ -11,15 +11,12 @@ private:
SerialNum _spoolerSerialNum;
protected:
SpoolerReplayOperation(Type type);
- SpoolerReplayOperation(Type type,
- SerialNum serialNum,
- SerialNum spoolerSerialNum);
+ SpoolerReplayOperation(Type type, SerialNum serialNum, SerialNum spoolerSerialNum);
public:
- virtual ~SpoolerReplayOperation() {}
+ ~SpoolerReplayOperation() override {}
SerialNum getSpoolerSerialNum() const { return _spoolerSerialNum; }
- virtual void serialize(vespalib::nbostream &os) const override;
- virtual void deserialize(vespalib::nbostream &is,
- const document::DocumentTypeRepo &) override {
+ void serialize(vespalib::nbostream &os) const override;
+ void deserialize(vespalib::nbostream &is, const document::DocumentTypeRepo &) override {
deserialize(is);
}
void deserialize(vespalib::nbostream &is);
@@ -38,8 +35,7 @@ public:
* @param serialNum the current serial number of the transaction log.
* @param spoolerSerialNum the serial number of the first entry of the spooler log replay.
*/
- SpoolerReplayStartOperation(SerialNum serialNum,
- SerialNum spoolerSerialNum);
+ SpoolerReplayStartOperation(SerialNum serialNum, SerialNum spoolerSerialNum);
};
@@ -54,8 +50,7 @@ public:
* @param serialNum the current serial number of the transaction log.
* @param spoolerSerialNum the serial number of the last entry of the spooler log replay.
*/
- SpoolerReplayCompleteOperation(SerialNum serialNum,
- SerialNum spoolerSerialNum);
+ SpoolerReplayCompleteOperation(SerialNum serialNum, SerialNum spoolerSerialNum);
};
} // namespace proton
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.cpp
index d31f1faec77..dc83848152c 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.cpp
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.cpp
@@ -51,12 +51,11 @@ UpdateOperation::serializeUpdate(vespalib::nbostream &os) const
}
void
-UpdateOperation::deserializeUpdate(vespalib::nbostream &is, const document::DocumentTypeRepo &repo)
+UpdateOperation::deserializeUpdate(vespalib::nbostream && is, const document::DocumentTypeRepo &repo)
{
- document::ByteBuffer buf(is.peek(), is.size());
- DocumentUpdate::UP update = (getType() == UPDATE_42) ? DocumentUpdate::create42(repo, buf) : DocumentUpdate::createHEAD(repo, buf);
- is.adjustReadPos(buf.getPos());
- _upd = std::move(update);
+ _upd = (getType() == UPDATE_42)
+ ? DocumentUpdate::create42(repo, is)
+ : DocumentUpdate::createHEAD(repo, std::move(is));
}
void
@@ -73,7 +72,7 @@ UpdateOperation::deserialize(vespalib::nbostream &is, const DocumentTypeRepo &re
{
DocumentOperation::deserialize(is, repo);
try {
- deserializeUpdate(is, repo);
+ deserializeUpdate(std::move(is), repo);
} catch (document::DocumentTypeNotFoundException &e) {
LOG(warning, "Failed deserialize update operation using unknown document type '%s'",
e.getDocumentTypeName().c_str());
@@ -83,18 +82,19 @@ UpdateOperation::deserialize(vespalib::nbostream &is, const DocumentTypeRepo &re
}
void
-UpdateOperation::deserializeUpdate(const DocumentTypeRepo &repo)
+UpdateOperation::verifyUpdate(const DocumentTypeRepo &repo)
{
vespalib::nbostream stream;
serializeUpdate(stream);
- deserializeUpdate(stream, repo);
+ deserializeUpdate(std::move(stream), repo);
+ _upd->eagerDeserialize(); // Will trigger exceptions if incompatible
}
-vespalib::string UpdateOperation::toString() const {
+vespalib::string
+UpdateOperation::toString() const {
return make_string("%s(%s, %s)",
((getType() == FeedOperation::UPDATE_42) ? "Update42" : "Update"),
- _upd.get() ?
- _upd->getId().getScheme().toString().c_str() : "NULL",
+ _upd.get() ? _upd->getId().getScheme().toString().c_str() : "NULL",
docArgsToString().c_str());
}
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.h b/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.h
index 99dcbfbce6c..83e87fea096 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.h
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.h
@@ -19,7 +19,7 @@ private:
const storage::spi::Timestamp &timestamp,
const DocumentUpdateSP &upd);
void serializeUpdate(vespalib::nbostream &os) const;
- void deserializeUpdate(vespalib::nbostream &is, const document::DocumentTypeRepo &repo);
+ void deserializeUpdate(vespalib::nbostream && is, const document::DocumentTypeRepo &repo);
public:
UpdateOperation();
UpdateOperation(Type type);
@@ -30,7 +30,7 @@ public:
const DocumentUpdateSP &getUpdate() const { return _upd; }
void serialize(vespalib::nbostream &os) const override;
void deserialize(vespalib::nbostream &is, const document::DocumentTypeRepo &repo) override;
- void deserializeUpdate(const document::DocumentTypeRepo &repo);
+ void verifyUpdate(const document::DocumentTypeRepo &repo);
vespalib::string toString() const override;
};
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.cpp
index d7f38a0cc52..c5e6acd80ed 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.cpp
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.cpp
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "wipehistoryoperation.h"
+#include <vespa/vespalib/objects/nbostream.h>
#include <vespa/vespalib/util/stringfmt.h>
using vespalib::make_string;
@@ -9,29 +10,29 @@ namespace proton {
WipeHistoryOperation::WipeHistoryOperation()
: FeedOperation(FeedOperation::WIPE_HISTORY),
- _wipeTimeLimit(0) {
+ _wipeTimeLimit(0)
+{
}
WipeHistoryOperation::WipeHistoryOperation(SerialNum serialNum,
fastos::TimeStamp wipeTimeLimit)
: FeedOperation(FeedOperation::WIPE_HISTORY),
- _wipeTimeLimit(wipeTimeLimit) {
+ _wipeTimeLimit(wipeTimeLimit)
+{
setSerialNum(serialNum);
}
void WipeHistoryOperation::serialize(vespalib::nbostream &str) const {
str << _wipeTimeLimit;
}
-void WipeHistoryOperation::deserialize(vespalib::nbostream &str,
- const document::DocumentTypeRepo &) {
+void WipeHistoryOperation::deserialize(vespalib::nbostream &str, const document::DocumentTypeRepo &) {
fastos::TimeStamp::TimeT t;
str >> t;
_wipeTimeLimit = t;
}
vespalib::string WipeHistoryOperation::toString() const {
- return make_string("WipeHistory(wipeTimeLimit=%" PRIu64
- ", serialNum=%" PRIu64 ")",
+ return make_string("WipeHistory(wipeTimeLimit=%" PRIu64 ", serialNum=%" PRIu64 ")",
_wipeTimeLimit.ns(), getSerialNum());
}
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.h b/searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.h
index 80b551dbd92..0cf7256bf27 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.h
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.h
@@ -12,14 +12,13 @@ class WipeHistoryOperation : public FeedOperation {
public:
WipeHistoryOperation();
WipeHistoryOperation(SerialNum serialNum, fastos::TimeStamp wipeTimeLimit);
- virtual ~WipeHistoryOperation() {}
+ ~WipeHistoryOperation() override {}
fastos::TimeStamp getWipeTimeLimit() const { return _wipeTimeLimit; }
- virtual void serialize(vespalib::nbostream &str) const override;
- virtual void deserialize(vespalib::nbostream &str,
- const document::DocumentTypeRepo &) override;
- virtual vespalib::string toString() const override;
+ void serialize(vespalib::nbostream &str) const override;
+ void deserialize(vespalib::nbostream &str, const document::DocumentTypeRepo &) override;
+ vespalib::string toString() const override;
};
} // namespace proton
diff --git a/searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.cpp b/searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.cpp
index bab3494ca5c..6475efdaabb 100644
--- a/searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.cpp
+++ b/searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.cpp
@@ -6,7 +6,9 @@
#include <vespa/metrics/loadmetric.h>
#include <vespa/vespalib/stllike/hash_set.h>
#include <vespa/document/fieldvalue/document.h>
+#include <vespa/document/datatype/documenttype.h>
#include <vespa/document/update/documentupdate.h>
+#include <vespa/document/base/exceptions.h>
#include <vespa/log/log.h>
@@ -25,6 +27,7 @@ using storage::spi::Result;
using vespalib::IllegalStateException;
using vespalib::Sequence;
using vespalib::make_string;
+using std::make_unique;
using namespace std::chrono_literals;
@@ -377,6 +380,18 @@ PersistenceEngine::update(const Bucket& b, Timestamp t, const DocumentUpdate::SP
upd->getId().toString().c_str(), state.message().c_str()));
}
}
+ try {
+ upd->eagerDeserialize();
+ } catch (document::FieldNotFoundException & e) {
+ return UpdateResult(Result::TRANSIENT_ERROR,
+ make_string("Update operation rejected for document '%s' of type '%s': 'Field not found'",
+ upd->getId().toString().c_str(), upd->getType().getName().c_str()));
+ } catch (document::DocumentTypeNotFoundException & e) {
+ return UpdateResult(Result::TRANSIENT_ERROR,
+ make_string("Update operation rejected for document '%s' of type '%s'.",
+ upd->getId().toString().c_str(), e.getDocumentTypeName().c_str()));
+
+ }
std::shared_lock<std::shared_timed_mutex> rguard(_rwMutex);
DocTypeName docType(upd->getType());
LOG(spam, "update(%s, %" PRIu64 ", (\"%s\", \"%s\"), createIfNonExistent='%s')",
diff --git a/searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.h b/searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.h
index f2ab35e0ccf..a6c696d08fb 100644
--- a/searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.h
+++ b/searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.h
@@ -87,37 +87,36 @@ public:
PersistenceEngine(IPersistenceEngineOwner &owner, const IResourceWriteFilter &writeFilter,
ssize_t defaultSerializedSize, bool ignoreMaxBytes);
- ~PersistenceEngine();
+ ~PersistenceEngine() override;
IPersistenceHandler::SP putHandler(document::BucketSpace bucketSpace, const DocTypeName &docType,
const IPersistenceHandler::SP &handler);
IPersistenceHandler::SP removeHandler(document::BucketSpace bucketSpace, const DocTypeName &docType);
// Implements PersistenceProvider
- virtual Result initialize() override;
- virtual PartitionStateListResult getPartitionStates() const override;
- virtual BucketIdListResult listBuckets(BucketSpace bucketSpace, PartitionId) const override;
- virtual Result setClusterState(BucketSpace bucketSpace, const ClusterState& calc) override;
- virtual Result setActiveState(const Bucket& bucket, BucketInfo::ActiveState newState) override;
- virtual BucketInfoResult getBucketInfo(const Bucket&) const override;
- virtual Result put(const Bucket&, Timestamp, const std::shared_ptr<document::Document>&, Context&) override;
- virtual RemoveResult remove(const Bucket&, Timestamp, const document::DocumentId&, Context&) override;
- virtual UpdateResult update(const Bucket&, Timestamp,
- const std::shared_ptr<document::DocumentUpdate>&, Context&) override;
- virtual GetResult get(const Bucket&, const document::FieldSet&,
- const document::DocumentId&, Context&) const override;
- virtual CreateIteratorResult createIterator(const Bucket&, const document::FieldSet&, const Selection&,
- IncludedVersions, Context&) override;
- virtual IterateResult iterate(IteratorId, uint64_t maxByteSize, Context&) const override;
- virtual Result destroyIterator(IteratorId, Context&) override;
-
- virtual Result createBucket(const Bucket &bucketId, Context &) override ;
- virtual Result deleteBucket(const Bucket&, Context&) override;
- virtual BucketIdListResult getModifiedBuckets(BucketSpace bucketSpace) const override;
- virtual Result split(const Bucket& source, const Bucket& target1, const Bucket& target2, Context&) override;
- virtual Result join(const Bucket& source1, const Bucket& source2, const Bucket& target, Context&) override;
-
- virtual Result maintain(const Bucket&, MaintenanceLevel) override;
+ Result initialize() override;
+ PartitionStateListResult getPartitionStates() const override;
+ BucketIdListResult listBuckets(BucketSpace bucketSpace, PartitionId) const override;
+ Result setClusterState(BucketSpace bucketSpace, const ClusterState& calc) override;
+ Result setActiveState(const Bucket& bucket, BucketInfo::ActiveState newState) override;
+ BucketInfoResult getBucketInfo(const Bucket&) const override;
+ Result put(const Bucket&, Timestamp, const std::shared_ptr<document::Document>&, Context&) override;
+ RemoveResult remove(const Bucket&, Timestamp, const document::DocumentId&, Context&) override;
+ UpdateResult update(const Bucket&, Timestamp,
+ const std::shared_ptr<document::DocumentUpdate>&, Context&) override;
+ GetResult get(const Bucket&, const document::FieldSet&, const document::DocumentId&, Context&) const override;
+ CreateIteratorResult createIterator(const Bucket&, const document::FieldSet&, const Selection&,
+ IncludedVersions, Context&) override;
+ IterateResult iterate(IteratorId, uint64_t maxByteSize, Context&) const override;
+ Result destroyIterator(IteratorId, Context&) override;
+
+ Result createBucket(const Bucket &bucketId, Context &) override ;
+ Result deleteBucket(const Bucket&, Context&) override;
+ BucketIdListResult getModifiedBuckets(BucketSpace bucketSpace) const override;
+ Result split(const Bucket& source, const Bucket& target1, const Bucket& target2, Context&) override;
+ Result join(const Bucket& source1, const Bucket& source2, const Bucket& target, Context&) override;
+
+ Result maintain(const Bucket&, MaintenanceLevel) override;
void destroyIterators();
void propagateSavedClusterState(BucketSpace bucketSpace, IPersistenceHandler &handler);
diff --git a/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_listener.cpp b/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_listener.cpp
index da03adb3fe4..46096fead05 100644
--- a/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_listener.cpp
+++ b/searchcore/src/vespa/searchcore/proton/reference/gid_to_lid_change_listener.cpp
@@ -12,7 +12,7 @@ GidToLidChangeListener::GidToLidChangeListener(search::ISequencedTaskExecutor &a
const vespalib::string &name,
const vespalib::string &docTypeName)
: _attributeFieldWriter(attributeFieldWriter),
- _executorId(_attributeFieldWriter.getExecutorId(attr->getName())),
+ _executorId(_attributeFieldWriter.getExecutorId(attr->getNamePrefix())),
_attr(std::move(attr)),
_refCount(refCount),
_name(name),
diff --git a/searchcore/src/vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.cpp b/searchcore/src/vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.cpp
index 711f8ebdcaf..1df812b0c61 100644
--- a/searchcore/src/vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.cpp
+++ b/searchcore/src/vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.cpp
@@ -38,6 +38,9 @@ bool fastPartialUpdateAttribute(BasicType::Type attrType) {
(attrType != BasicType::Type::REFERENCE));
}
+bool isStructFieldAttribute(const vespalib::string &name) {
+ return name.find('.') != vespalib::string::npos;
+}
FilterAttributeManager::AttributeSet
getAttributeSetToPopulate(const ARIConfig &newCfg,
@@ -100,7 +103,8 @@ getFieldsToPopulate(const ARIConfig &newCfg,
// keep the original in order to preserve annotations.
bool wasStringIndexField = oldIndexschemaInspector.isStringIndex(name);
bool populateField = !inNewAttrMgr && unchangedField && !wasStringIndexField &&
- fastPartialUpdateAttribute(attrType.type());
+ fastPartialUpdateAttribute(attrType.type()) &&
+ !isStructFieldAttribute(name);
LOG(debug, "getFieldsToPopulate(): name='%s', inNewAttrMgr=%s, unchangedField=%s, "
"wasStringIndexField=%s, dataType=%s, populate=%s",
name.c_str(), toStr(inNewAttrMgr), toStr(unchangedField),
diff --git a/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.cpp b/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.cpp
index 87735dfef5d..6a000973165 100644
--- a/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.cpp
@@ -3,7 +3,7 @@
#include "combiningfeedview.h"
#include <vespa/document/fieldvalue/document.h>
#include <vespa/searchcore/proton/documentmetastore/i_document_meta_store.h>
-#include <vespa/searchcore/proton/feedoperation/moveoperation.h>
+#include <vespa/searchcore/proton/feedoperation/operations.h>
#include <vespa/searchlib/common/idestructorcallback.h>
#include <vespa/log/log.h>
@@ -13,17 +13,15 @@ using document::DocumentTypeRepo;
using document::DocumentId;
using search::IDestructorCallback;
-namespace proton
-{
+namespace proton {
-namespace
-{
+namespace {
std::shared_ptr<const DocumentTypeRepo>
getRepo(const std::vector<IFeedView::SP> &views)
{
for (const auto &view : views) {
- if (view.get() == NULL)
+ if (view.get() == nullptr)
continue;
return view->getDocumentTypeRepo();
}
diff --git a/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.h b/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.h
index 6644f21a3b7..3546fdbea71 100644
--- a/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.h
+++ b/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.h
@@ -3,21 +3,14 @@
#pragma once
#include "ifeedview.h"
-#include <vespa/searchcore/proton/common/feedtoken.h>
-#include <vespa/searchcore/proton/feedoperation/deletebucketoperation.h>
-#include <vespa/searchcore/proton/feedoperation/joinbucketsoperation.h>
-#include <vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.h>
-#include <vespa/searchcore/proton/feedoperation/putoperation.h>
-#include <vespa/searchcore/proton/feedoperation/removeoperation.h>
-#include <vespa/searchcore/proton/feedoperation/splitbucketoperation.h>
-#include <vespa/searchcore/proton/feedoperation/updateoperation.h>
-#include <vespa/searchcore/proton/feedoperation/createbucketoperation.h>
-#include <vespa/searchlib/common/serialnum.h>
#include "replaypacketdispatcher.h"
#include "ibucketstatecalculator.h"
+#include <vespa/searchcore/proton/common/feedtoken.h>
+#include <vespa/searchlib/common/serialnum.h>
namespace proton {
+class DocumentOperation;
class CombiningFeedView : public IFeedView
{
diff --git a/searchcore/src/vespa/searchcore/proton/server/documentdb.cpp b/searchcore/src/vespa/searchcore/proton/server/documentdb.cpp
index 61ce0e6dc6f..ad7a2d57c89 100644
--- a/searchcore/src/vespa/searchcore/proton/server/documentdb.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/documentdb.cpp
@@ -17,6 +17,7 @@
#include <vespa/searchcore/proton/attribute/imported_attributes_repo.h>
#include <vespa/searchcore/proton/common/eventlogger.h>
#include <vespa/searchcore/proton/common/statusreport.h>
+#include <vespa/searchcore/proton/feedoperation/noopoperation.h>
#include <vespa/searchcore/proton/index/index_writer.h>
#include <vespa/searchcore/proton/initializer/task_runner.h>
#include <vespa/searchcore/proton/metrics/attribute_metrics_collection.h>
diff --git a/searchcore/src/vespa/searchcore/proton/server/fast_access_feed_view.cpp b/searchcore/src/vespa/searchcore/proton/server/fast_access_feed_view.cpp
index 6364e772f94..1c2406b2acf 100644
--- a/searchcore/src/vespa/searchcore/proton/server/fast_access_feed_view.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/fast_access_feed_view.cpp
@@ -5,6 +5,7 @@
#include "operationdonecontext.h"
#include "removedonecontext.h"
#include "putdonecontext.h"
+#include <vespa/searchcore/proton/feedoperation/operations.h>
#include <vespa/searchlib/common/isequencedtaskexecutor.h>
using document::Document;
@@ -71,7 +72,7 @@ FastAccessFeedView::FastAccessFeedView(const StoreOnlyFeedView::Context &storeOn
_docIdLimit(ctx._docIdLimit)
{}
-FastAccessFeedView::~FastAccessFeedView() {}
+FastAccessFeedView::~FastAccessFeedView() = default;
void
FastAccessFeedView::handleCompactLidSpace(const CompactLidSpaceOperation &op)
diff --git a/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp b/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp
index 66e721f9222..97cc25e635f 100644
--- a/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp
@@ -14,6 +14,7 @@
#include <vespa/searchcore/proton/bucketdb/ibucketdbhandler.h>
#include <vespa/searchcore/proton/persistenceengine/i_resource_write_filter.h>
#include <vespa/searchcore/proton/persistenceengine/transport_latch.h>
+#include <vespa/searchcore/proton/feedoperation/operations.h>
#include <vespa/searchcore/proton/common/eventlogger.h>
#include <vespa/searchcorespi/index/ithreadingservice.h>
#include <vespa/searchlib/common/gatecallback.h>
@@ -522,7 +523,7 @@ FeedHandler::considerUpdateOperationForRejection(FeedToken &token, UpdateOperati
*/
if (_documentType != &update.getType()) {
try {
- op.deserializeUpdate(*_repo);
+ op.verifyUpdate(*_repo);
} catch (document::FieldNotFoundException &e) {
if (token) {
auto message = make_string("Update operation rejected for document '%s' of type '%s': 'Field not found'",
diff --git a/searchcore/src/vespa/searchcore/proton/server/feedstate.h b/searchcore/src/vespa/searchcore/proton/server/feedstate.h
index 472f5cb224f..fa0a1702499 100644
--- a/searchcore/src/vespa/searchcore/proton/server/feedstate.h
+++ b/searchcore/src/vespa/searchcore/proton/server/feedstate.h
@@ -25,6 +25,7 @@ private:
Type _type;
protected:
+ using FeedOperationUP = std::unique_ptr<FeedOperation>;
void throwExceptionInReceive(const vespalib::string &docType, uint64_t serialRangeFrom,
uint64_t serialRangeTo, size_t packetSize);
void throwExceptionInHandleOperation(const vespalib::string &docType, const FeedOperation &op);
@@ -38,7 +39,7 @@ public:
Type getType() const { return _type; }
vespalib::string getName() const;
- virtual void handleOperation(FeedToken token, std::unique_ptr<FeedOperation> op) = 0;
+ virtual void handleOperation(FeedToken token, FeedOperationUP op) = 0;
virtual void receive(const PacketWrapper::SP &wrap, vespalib::Executor &executor) = 0;
};
diff --git a/searchcore/src/vespa/searchcore/proton/server/feedstates.cpp b/searchcore/src/vespa/searchcore/proton/server/feedstates.cpp
index f0866347f59..ae323bc93df 100644
--- a/searchcore/src/vespa/searchcore/proton/server/feedstates.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/feedstates.cpp
@@ -6,6 +6,7 @@
#include "ireplayconfig.h"
#include "replaypacketdispatcher.h"
#include <vespa/searchcore/proton/bucketdb/ibucketdbhandler.h>
+#include <vespa/searchcore/proton/feedoperation/operations.h>
#include <vespa/searchcore/proton/common/eventlogger.h>
#include <vespa/searchlib/common/idestructorcallback.h>
#include <vespa/vespalib/util/closuretask.h>
diff --git a/searchcore/src/vespa/searchcore/proton/server/feedstates.h b/searchcore/src/vespa/searchcore/proton/server/feedstates.h
index 963a78d0d6b..a9224669d87 100644
--- a/searchcore/src/vespa/searchcore/proton/server/feedstates.h
+++ b/searchcore/src/vespa/searchcore/proton/server/feedstates.h
@@ -28,16 +28,13 @@ public:
{
}
- virtual void handleOperation(FeedToken, FeedOperation::UP op) override {
+ void handleOperation(FeedToken, FeedOperationUP op) override {
throwExceptionInHandleOperation(_doc_type_name, *op);
}
- virtual void
- receive(const PacketWrapper::SP &wrap, vespalib::Executor &) override {
- throwExceptionInReceive(_doc_type_name.c_str(),
- wrap->packet.range().from(),
- wrap->packet.range().to(),
- wrap->packet.size());
+ void receive(const PacketWrapper::SP &wrap, vespalib::Executor &) override {
+ throwExceptionInReceive(_doc_type_name.c_str(), wrap->packet.range().from(),
+ wrap->packet.range().to(), wrap->packet.size());
}
};
@@ -57,12 +54,11 @@ public:
IReplayConfig &replay_config,
FeedConfigStore &config_store);
- virtual void handleOperation(FeedToken, FeedOperation::UP op) override {
+ void handleOperation(FeedToken, FeedOperationUP op) override {
throwExceptionInHandleOperation(_doc_type_name, *op);
}
- virtual void receive(const PacketWrapper::SP &wrap,
- vespalib::Executor &executor) override;
+ void receive(const PacketWrapper::SP &wrap, vespalib::Executor &executor) override;
};
@@ -79,15 +75,13 @@ public:
_handler(handler) {
}
- void handleOperation(FeedToken token, FeedOperation::UP op) override {
+ void handleOperation(FeedToken token, FeedOperationUP op) override {
_handler.performOperation(std::move(token), std::move(op));
}
void receive(const PacketWrapper::SP &wrap, vespalib::Executor &) override {
- throwExceptionInReceive(_handler.getDocTypeName().c_str(),
- wrap->packet.range().from(),
- wrap->packet.range().to(),
- wrap->packet.size());
+ throwExceptionInReceive(_handler.getDocTypeName().c_str(), wrap->packet.range().from(),
+ wrap->packet.range().to(), wrap->packet.size());
}
};
} // namespace proton
diff --git a/searchcore/src/vespa/searchcore/proton/server/ireplaypackethandler.h b/searchcore/src/vespa/searchcore/proton/server/ireplaypackethandler.h
index 210ece3a36a..e93821e2a36 100644
--- a/searchcore/src/vespa/searchcore/proton/server/ireplaypackethandler.h
+++ b/searchcore/src/vespa/searchcore/proton/server/ireplaypackethandler.h
@@ -2,10 +2,28 @@
#pragma once
-#include <vespa/searchcore/proton/feedoperation/operations.h>
+namespace document { class DocumentTypeRepo; }
namespace proton {
+class PutOperation;
+class RemoveOperation;
+class UpdateOperation;
+class NoopOperation;
+class NewConfigOperation;
+class WipeHistoryOperation;
+class DeleteBucketOperation;
+class SplitBucketOperation;
+class JoinBucketsOperation;
+class PruneRemovedDocumentsOperation;
+class SpoolerReplayStartOperation;
+class SpoolerReplayCompleteOperation;
+class MoveOperation;
+class CreateBucketOperation;
+class CompactLidSpaceOperation;
+
+namespace feedoperation { class IStreamHandler; }
+
/**
* Interface used to handle the various feed operations during
* replay of the transaction log.
@@ -29,7 +47,7 @@ struct IReplayPacketHandler
virtual void replay(const CreateBucketOperation &op) = 0;
virtual void replay(const CompactLidSpaceOperation &op) = 0;
- virtual NewConfigOperation::IStreamHandler &getNewConfigStreamHandler() = 0;
+ virtual feedoperation::IStreamHandler &getNewConfigStreamHandler() = 0;
virtual const document::DocumentTypeRepo &getDeserializeRepo() = 0;
};
diff --git a/searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.cpp b/searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.cpp
index cdb42906fc2..42451f08315 100644
--- a/searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.cpp
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "replaypacketdispatcher.h"
+#include <vespa/searchcore/proton/feedoperation/operations.h>
#include <vespa/vespalib/util/exceptions.h>
#include <vespa/document/util/serializableexceptions.h>
diff --git a/searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.h b/searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.h
index fc6f99471d8..771a79ddad9 100644
--- a/searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.h
+++ b/searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.h
@@ -7,6 +7,7 @@
namespace proton {
+class FeedOperation;
/**
* Utility class that deserializes packet entries into feed operations
* during replay from the transaction log and dispatches the feed operations
@@ -22,14 +23,11 @@ private:
void replay(OperationType &op, vespalib::nbostream &is, const Packet::Entry &entry);
protected:
- virtual void
- store(const FeedOperation &op);
+ virtual void store(const FeedOperation &op);
public:
ReplayPacketDispatcher(IReplayPacketHandler &handler);
-
- virtual
- ~ReplayPacketDispatcher();
+ virtual ~ReplayPacketDispatcher();
void replayEntry(const Packet::Entry &entry);
};
diff --git a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp
index 29615b0daf9..22ff1b90de4 100644
--- a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp
@@ -13,6 +13,7 @@
#include <vespa/searchcore/proton/documentmetastore/ilidreusedelayer.h>
#include <vespa/searchcore/proton/reference/i_gid_to_lid_change_handler.h>
#include <vespa/searchcore/proton/attribute/ifieldupdatecallback.h>
+#include <vespa/searchcore/proton/feedoperation/operations.h>
#include <vespa/searchlib/common/isequencedtaskexecutor.h>
#include <vespa/document/datatype/documenttype.h>
diff --git a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h
index 825e14b4368..37f67399f4d 100644
--- a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h
+++ b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h
@@ -13,7 +13,7 @@
#include <vespa/searchcore/proton/common/feeddebugger.h>
#include <vespa/searchcore/proton/documentmetastore/documentmetastore.h>
#include <vespa/searchcore/proton/documentmetastore/documentmetastorecontext.h>
-#include <vespa/searchcore/proton/feedoperation/feedoperation.h>
+#include <vespa/searchcore/proton/feedoperation/lidvectorcontext.h>
#include <vespa/searchcore/proton/persistenceengine/resulthandler.h>
#include <vespa/searchcore/proton/reference/pending_notify_remove_done.h>
#include <vespa/searchcorespi/index/ithreadingservice.h>
@@ -23,7 +23,6 @@
namespace search { class IDestructorCallback; }
-namespace document { class GLobalId; }
namespace proton {
@@ -35,6 +34,8 @@ class RemoveDoneContext;
class CommitTimeTracker;
class IGidToLidChangeHandler;
class IFieldUpdateCallback;
+class RemoveDocumentsOperation;
+class DocumentOperation;
namespace documentmetastore { class ILidReuseDelayer; }