summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeir Storli <geirstorli@yahoo.no>2018-05-31 14:50:12 +0200
committerGitHub <noreply@github.com>2018-05-31 14:50:12 +0200
commit721180812680b7a5dd8bae87e1a114ff8ef5ed98 (patch)
treea40ffd1ee5d233763edf3f69adc6201e72d42641
parentac9c5c9f7656c55a8d2a014a4e1dc02c1b2caf5f (diff)
parent28ff792377209e754e730dfac77c9d95767b44a2 (diff)
Merge pull request #6021 from vespa-engine/balder/compute-updatescope-inline-rebased
Balder/compute updatescope inline rebased
-rw-r--r--searchcore/src/tests/proton/attribute/attribute_test.cpp28
-rw-r--r--searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp53
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.cpp16
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.h6
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/i_attribute_writer.h18
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/ifieldupdatecallback.h20
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/fast_access_feed_view.cpp36
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/fast_access_feed_view.h6
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/searchable_feed_view.cpp23
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/searchable_feed_view.h49
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp50
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h17
12 files changed, 154 insertions, 168 deletions
diff --git a/searchcore/src/tests/proton/attribute/attribute_test.cpp b/searchcore/src/tests/proton/attribute/attribute_test.cpp
index f7777ece4ac..98a76023c47 100644
--- a/searchcore/src/tests/proton/attribute/attribute_test.cpp
+++ b/searchcore/src/tests/proton/attribute/attribute_test.cpp
@@ -1,6 +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_test");
#include <vespa/config-attributes.h>
#include <vespa/document/fieldvalue/document.h>
@@ -15,6 +13,7 @@ LOG_SETUP("attribute_test");
#include <vespa/searchcommon/attribute/attributecontent.h>
#include <vespa/searchcore/proton/attribute/attribute_collection_spec_factory.h>
#include <vespa/searchcore/proton/attribute/attribute_writer.h>
+#include <vespa/searchcore/proton/attribute/ifieldupdatecallback.h>
#include <vespa/searchcore/proton/attribute/attributemanager.h>
#include <vespa/searchcore/proton/attribute/filter_attribute_manager.h>
#include <vespa/searchcore/proton/attribute/imported_attributes_repo.h>
@@ -44,6 +43,9 @@ LOG_SETUP("attribute_test");
#include <vespa/vespalib/testkit/testapp.h>
#include <vespa/searchcommon/attribute/iattributevector.h>
+#include <vespa/log/log.h>
+LOG_SETUP("attribute_test");
+
namespace vespa { namespace config { namespace search {}}}
using namespace config;
@@ -156,8 +158,8 @@ struct Fixture
_aw->put(serialNum, doc, lid, immediateCommit, emptyCallback);
}
void update(SerialNum serialNum, const DocumentUpdate &upd,
- DocumentIdT lid, bool immediateCommit) {
- _aw->update(serialNum, upd, lid, immediateCommit, emptyCallback);
+ DocumentIdT lid, bool immediateCommit, IFieldUpdateCallback & onUpdate) {
+ _aw->update(serialNum, upd, lid, immediateCommit, emptyCallback, onUpdate);
}
void update(SerialNum serialNum, const Document &doc,
DocumentIdT lid, bool immediateCommit) {
@@ -448,8 +450,9 @@ TEST_F("require that attribute writer handles update", Fixture)
upd.addUpdate(FieldUpdate(upd.getType().getField("a2"))
.addUpdate(ArithmeticValueUpdate(ArithmeticValueUpdate::Add, 10)));
+ DummyFieldUpdateCallback onUpdate;
bool immediateCommit = true;
- f.update(2, upd, 1, immediateCommit);
+ f.update(2, upd, 1, immediateCommit, onUpdate);
attribute::IntegerContent ibuf;
ibuf.fill(*a1, 1);
@@ -459,9 +462,9 @@ TEST_F("require that attribute writer handles update", Fixture)
EXPECT_EQUAL(1u, ibuf.size());
EXPECT_EQUAL(30u, ibuf[0]);
- f.update(2, upd, 1, immediateCommit); // same sync token as previous
+ f.update(2, upd, 1, immediateCommit, onUpdate); // same sync token as previous
try {
- f.update(1, upd, 1, immediateCommit); // lower sync token than previous
+ f.update(1, upd, 1, immediateCommit, onUpdate); // lower sync token than previous
EXPECT_TRUE(true); // update is ignored
} catch (vespalib::IllegalStateException & e) {
LOG(info, "Got expected exception: '%s'", e.getMessage().c_str());
@@ -494,7 +497,8 @@ TEST_F("require that attribute writer handles predicate update", Fixture)
EXPECT_EQUAL(1u, index.getZeroConstraintDocs().size());
EXPECT_FALSE(index.getIntervalIndex().lookup(PredicateHash::hash64("foo=bar")).valid());
bool immediateCommit = true;
- f.update(2, upd, 1, immediateCommit);
+ DummyFieldUpdateCallback onUpdate;
+ f.update(2, upd, 1, immediateCommit, onUpdate);
EXPECT_EQUAL(0u, index.getZeroConstraintDocs().size());
EXPECT_TRUE(index.getIntervalIndex().lookup(PredicateHash::hash64("foo=bar")).valid());
}
@@ -681,7 +685,8 @@ TEST_F("require that attribute writer handles tensor assign update", Fixture)
upd.addUpdate(FieldUpdate(upd.getType().getField("a1"))
.addUpdate(AssignValueUpdate(new_value)));
bool immediateCommit = true;
- f.update(2, upd, 1, immediateCommit);
+ DummyFieldUpdateCallback onUpdate;
+ f.update(2, upd, 1, immediateCommit, onUpdate);
EXPECT_EQUAL(2u, a1->getNumDocs());
EXPECT_TRUE(tensorAttribute != nullptr);
tensor2 = tensorAttribute->getTensor(1);
@@ -795,6 +800,7 @@ struct StructFixtureBase : public Fixture
_type.addField(_valueField);
_structFieldType.addField(_valueField);
}
+ ~StructFixtureBase();
std::unique_ptr<StructFieldValue>
makeStruct()
@@ -817,6 +823,7 @@ struct StructFixtureBase : public Fixture
}
};
+StructFixtureBase::~StructFixtureBase() = default;
struct StructArrayFixture : public StructFixtureBase
{
@@ -832,6 +839,7 @@ struct StructArrayFixture : public StructFixtureBase
addAttribute({"array.value", AVConfig(AVBasicType::INT32, AVCollectionType::ARRAY)}, createSerialNum);
_type.addField(_structArrayField);
}
+ ~StructArrayFixture();
std::unique_ptr<Document>
makeDoc(int32_t value, const std::vector<int32_t> &arrayValues)
@@ -858,6 +866,8 @@ struct StructArrayFixture : public StructFixtureBase
}
};
+StructArrayFixture::~StructArrayFixture() = default;
+
TEST_F("require that update with doc argument only updates compound attributes", StructArrayFixture)
{
auto doc = f.makeDoc(10, {11, 12});
diff --git a/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp b/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp
index 6b27141a315..5d040024e63 100644
--- a/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/feedview/feedview_test.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 <vespa/searchcore/proton/attribute/i_attribute_writer.h>
+#include <vespa/searchcore/proton/attribute/ifieldupdatecallback.h>
#include <vespa/searchcore/proton/test/bucketfactory.h>
#include <vespa/searchcore/proton/common/commit_time_tracker.h>
#include <vespa/searchcore/proton/common/feedtoken.h>
@@ -316,21 +317,23 @@ struct MyAttributeWriter : public IAttributeWriter
std::set<vespalib::string> _attrs;
proton::IAttributeManager::SP _mgr;
MyTracer &_tracer;
+
MyAttributeWriter(MyTracer &tracer);
~MyAttributeWriter();
- virtual std::vector<AttributeVector *>
+
+ std::vector<AttributeVector *>
getWritableAttributes() const override {
return std::vector<AttributeVector *>();
}
- virtual AttributeVector *getWritableAttribute(const vespalib::string &attrName) const override {
+ AttributeVector *getWritableAttribute(const vespalib::string &attrName) const override {
if (_attrs.count(attrName) == 0) {
return nullptr;
}
AttrMap::const_iterator itr = _attrMap.find(attrName);
return ((itr == _attrMap.end()) ? nullptr : itr->second.get());
}
- virtual void put(SerialNum serialNum, const document::Document &doc, DocumentIdT lid,
- bool immediateCommit, OnWriteDoneType) override {
+ void put(SerialNum serialNum, const document::Document &doc, DocumentIdT lid,
+ bool immediateCommit, OnWriteDoneType) override {
_putSerial = serialNum;
_putDocId = doc.getId();
_putLid = lid;
@@ -339,8 +342,8 @@ struct MyAttributeWriter : public IAttributeWriter
++_commitCount;
}
}
- virtual void remove(SerialNum serialNum, DocumentIdT lid,
- bool immediateCommit, OnWriteDoneType) override {
+ void remove(SerialNum serialNum, DocumentIdT lid,
+ bool immediateCommit, OnWriteDoneType) override {
_removeSerial = serialNum;
_removeLid = lid;
_tracer.traceRemove(attributeAdapterTypeName, serialNum, lid, immediateCommit);
@@ -348,45 +351,45 @@ struct MyAttributeWriter : public IAttributeWriter
++_commitCount;
}
}
- virtual void remove(const LidVector & lidsToRemove, SerialNum serialNum,
- bool immediateCommit, OnWriteDoneType) override {
+ void remove(const LidVector & lidsToRemove, SerialNum serialNum,
+ bool immediateCommit, OnWriteDoneType) override {
for (uint32_t lid : lidsToRemove) {
LOG(info, "MyAttributeAdapter::remove(): serialNum(%" PRIu64 "), docId(%u)", serialNum, lid);
_removes.push_back(lid);
_tracer.traceRemove(attributeAdapterTypeName, serialNum, lid, immediateCommit);
}
}
- virtual void update(SerialNum serialNum, const document::DocumentUpdate &upd,
- DocumentIdT lid, bool, OnWriteDoneType) override {
+ void update(SerialNum serialNum, const document::DocumentUpdate &upd,
+ DocumentIdT lid, bool, OnWriteDoneType, IFieldUpdateCallback & onUpdate) override {
_updateSerial = serialNum;
_updateDocId = upd.getId();
_updateLid = lid;
+ for (const auto & fieldUpdate : upd.getUpdates()) {
+ search::AttributeVector * attr = getWritableAttribute(fieldUpdate.getField().getName());
+ onUpdate.onUpdateField(fieldUpdate.getField().getName(), attr);
+ }
}
- virtual void update(SerialNum serialNum, const document::Document &doc, DocumentIdT lid,
- bool immediateCommit, OnWriteDoneType) override {
+ void update(SerialNum serialNum, const document::Document &doc, DocumentIdT lid,
+ bool immediateCommit, OnWriteDoneType) override {
(void) serialNum;
(void) doc;
(void) lid;
(void) immediateCommit;
}
- virtual void heartBeat(SerialNum) override { ++_heartBeatCount; }
- virtual void compactLidSpace(uint32_t wantedLidLimit, SerialNum serialNum) override {
- (void) serialNum;
+ void heartBeat(SerialNum) override { ++_heartBeatCount; }
+ void compactLidSpace(uint32_t wantedLidLimit, SerialNum ) override {
_wantedLidLimit = wantedLidLimit;
}
- virtual const proton::IAttributeManager::SP &getAttributeManager() const override {
+ const proton::IAttributeManager::SP &getAttributeManager() const override {
return _mgr;
}
void forceCommit(SerialNum serialNum, OnWriteDoneType) override {
- (void) serialNum; ++_commitCount;
+ ++_commitCount;
_tracer.traceCommit(attributeAdapterTypeName, serialNum);
}
- virtual void onReplayDone(uint32_t docIdLimit) override
- {
- (void) docIdLimit;
- }
- virtual bool getHasCompoundAttribute() const override { return false; }
+ void onReplayDone(uint32_t ) override { }
+ bool getHasCompoundAttribute() const override { return false; }
};
MyAttributeWriter::MyAttributeWriter(MyTracer &tracer)
@@ -404,7 +407,7 @@ MyAttributeWriter::MyAttributeWriter(MyTracer &tracer)
cfg3.setTensorType(ValueType::from_spec("tensor(x[10])"));
_attrMap["a3"] = search::AttributeFactory::createAttribute("test3", cfg3);
}
-MyAttributeWriter::~MyAttributeWriter() {}
+MyAttributeWriter::~MyAttributeWriter() = default;
struct MyTransport : public feedtoken::ITransport
{
@@ -428,7 +431,7 @@ struct MyResultHandler : public IGenericResultHandler
{
vespalib::Gate _gate;
MyResultHandler() : _gate() {}
- virtual void handle(const storage::spi::Result &) override {
+ void handle(const storage::spi::Result &) override {
_gate.countDown();
}
void await() { _gate.await(); }
@@ -454,7 +457,7 @@ SchemaContext::SchemaContext() :
_schema->addSummaryField(Schema::SummaryField("s1", DataType::STRING, CollectionType::SINGLE));
_builder.reset(new DocBuilder(*_schema));
}
-SchemaContext::~SchemaContext() {}
+SchemaContext::~SchemaContext() = default;
struct DocumentContext
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.cpp b/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.cpp
index f2ab6e1f287..4d38288e9aa 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.cpp
+++ b/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.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 "attribute_writer.h"
+#include "ifieldupdatecallback.h"
#include "attributemanager.h"
#include "document_field_extractor.h"
#include <vespa/document/base/exceptions.h>
@@ -500,17 +501,15 @@ AttributeWriter::remove(const LidVector &lidsToRemove, SerialNum serialNum,
void
AttributeWriter::update(SerialNum serialNum, const DocumentUpdate &upd, DocumentIdT lid,
- bool immediateCommit, OnWriteDoneType onWriteDone)
+ bool immediateCommit, OnWriteDoneType onWriteDone, IFieldUpdateCallback & onUpdate)
{
LOG(debug, "Inspecting update for document %d.", lid);
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());
+ LOG(debug, "Retrieving guard for attribute vector '%s'.", fupd.getField().getName().c_str());
+ AttributeVector *attrp = _mgr->getWritableAttribute(fupd.getField().getName());
+ onUpdate.onUpdateField(fupd.getField().getName(), attrp);
if (attrp == nullptr) {
- LOG(spam, "Failed to find attribute vector %s",
- fupd.getField().getName().c_str());
+ LOG(spam, "Failed to find attribute vector %s", fupd.getField().getName().c_str());
continue;
}
AttributeVector &attr = *attrp;
@@ -519,8 +518,7 @@ AttributeWriter::update(SerialNum serialNum, const DocumentUpdate &upd, Document
if (attr.getStatus().getLastSyncToken() >= serialNum)
continue;
- LOG(debug, "About to apply update for docId %u in attribute vector '%s'.",
- lid, attr.getName().c_str());
+ LOG(debug, "About to apply update for docId %u in attribute vector '%s'.", lid, attr.getName().c_str());
// NOTE: The lifetime of the field update will be ensured by keeping the document update alive
// in a operation done context object.
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.h b/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.h
index 1820eeb4690..295f873567a 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.h
+++ b/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.h
@@ -82,7 +82,7 @@ public:
void remove(const LidVector &lidVector, SerialNum serialNum,
bool immediateCommit, OnWriteDoneType onWriteDone) override;
void update(SerialNum serialNum, const DocumentUpdate &upd, DocumentIdT lid,
- bool immediateCommit, OnWriteDoneType onWriteDone) override;
+ bool immediateCommit, OnWriteDoneType onWriteDone, IFieldUpdateCallback & onUpdate) override;
void update(SerialNum serialNum, const Document &doc, DocumentIdT lid,
bool immediateCommit, OnWriteDoneType onWriteDone) override;
void heartBeat(SerialNum serialNum) override;
@@ -92,8 +92,8 @@ public:
}
void forceCommit(SerialNum serialNum, OnWriteDoneType onWriteDone) override;
- virtual void onReplayDone(uint32_t docIdLimit) override;
- virtual bool getHasCompoundAttribute() const override;
+ void onReplayDone(uint32_t docIdLimit) override;
+ bool getHasCompoundAttribute() const override;
};
} // namespace proton
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_writer.h b/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_writer.h
index 34d827a6d84..7a557b17964 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_writer.h
+++ b/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_writer.h
@@ -1,18 +1,20 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
-#include <vespa/document/fieldvalue/document.h>
-#include <vespa/document/update/documentupdate.h>
+#include "i_attribute_manager.h"
+#include <vespa/searchcore/proton/feedoperation/lidvectorcontext.h>
#include <vespa/searchlib/attribute/attributeguard.h>
#include <vespa/searchlib/query/base.h>
#include <vespa/searchlib/common/serialnum.h>
-#include <vespa/searchcore/proton/attribute/i_attribute_manager.h>
-#include <vespa/searchcore/proton/feedoperation/lidvectorcontext.h>
+#include <vespa/document/fieldvalue/document.h>
+#include <vespa/document/update/documentupdate.h>
namespace search { class IDestructorCallback; }
namespace proton {
+class IFieldUpdateCallback;
+
/**
* Interface for an attribute writer that handles writes in form of put, update and remove
* to an underlying set of attribute vectors.
@@ -31,10 +33,8 @@ public:
virtual ~IAttributeWriter() {}
- virtual std::vector<search::AttributeVector *>
- getWritableAttributes() const = 0;
- virtual search::AttributeVector *
- getWritableAttribute(const vespalib::string &attrName) const = 0;
+ virtual std::vector<search::AttributeVector *> getWritableAttributes() const = 0;
+ virtual search::AttributeVector *getWritableAttribute(const vespalib::string &attrName) const = 0;
virtual void put(SerialNum serialNum, const Document &doc, DocumentIdT lid,
bool immediateCommit, OnWriteDoneType onWriteDone) = 0;
virtual void remove(SerialNum serialNum, DocumentIdT lid, bool immediateCommit,
@@ -46,7 +46,7 @@ public:
* The OnWriteDoneType instance should ensure the lifetime of the given DocumentUpdate instance.
*/
virtual void update(SerialNum serialNum, const DocumentUpdate &upd, DocumentIdT lid,
- bool immediateCommit, OnWriteDoneType onWriteDone) = 0;
+ bool immediateCommit, OnWriteDoneType onWriteDone, IFieldUpdateCallback & onUpdate) = 0;
/*
* Update the underlying compound attributes based on updated document.
*/
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/ifieldupdatecallback.h b/searchcore/src/vespa/searchcore/proton/attribute/ifieldupdatecallback.h
new file mode 100644
index 00000000000..ffb8555cd2c
--- /dev/null
+++ b/searchcore/src/vespa/searchcore/proton/attribute/ifieldupdatecallback.h
@@ -0,0 +1,20 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include <vespa/vespalib/stllike/string.h>
+
+namespace search { class AttributeVector; }
+
+namespace proton {
+
+struct IFieldUpdateCallback {
+ virtual ~IFieldUpdateCallback() { }
+ virtual void onUpdateField(vespalib::stringref fieldName, const search::AttributeVector * attr) = 0;
+};
+
+struct DummyFieldUpdateCallback : IFieldUpdateCallback {
+ void onUpdateField(vespalib::stringref, const search::AttributeVector *) override {}
+};
+
+}
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 7de2dd74400..78733b14aaa 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
@@ -13,23 +13,6 @@ using search::index::Schema;
namespace proton {
-FastAccessFeedView::UpdateScope
-FastAccessFeedView::getUpdateScope(const DocumentUpdate &upd)
-{
- UpdateScope updateScope;
- for (const auto &update : upd.getUpdates()) {
- const vespalib::string &fieldName = update.getField().getName();
- if (!fastPartialUpdateAttribute(fieldName)) {
- updateScope._nonAttributeFields = true;
- break;
- }
- }
- if (!upd.getFieldPathUpdates().empty()) {
- updateScope._nonAttributeFields = true;
- }
- return updateScope;
-}
-
/**
* NOTE: For both put, update and remove we only need to pass the 'onWriteDone'
* instance when we are going to commit as part of handling the operation.
@@ -47,9 +30,9 @@ FastAccessFeedView::putAttributes(SerialNum serialNum, search::DocumentIdT lid,
void
FastAccessFeedView::updateAttributes(SerialNum serialNum, search::DocumentIdT lid, const DocumentUpdate &upd,
- bool immediateCommit, OnOperationDoneType onWriteDone)
+ bool immediateCommit, OnOperationDoneType onWriteDone, IFieldUpdateCallback & onUpdate)
{
- _attributeWriter->update(serialNum, upd, lid, immediateCommit, onWriteDone);
+ _attributeWriter->update(serialNum, upd, lid, immediateCommit, onWriteDone, onUpdate);
}
void
@@ -116,19 +99,4 @@ FastAccessFeedView::sync()
_writeService.attributeFieldWriter().sync();
}
-bool
-FastAccessFeedView::fastPartialUpdateAttribute(const vespalib::string &fieldName) const {
- search::AttributeVector *attribute = _attributeWriter->getWritableAttribute(fieldName);
- if (attribute == nullptr) {
- // Partial update to non-attribute field must update document
- return false;
- }
- search::attribute::BasicType::Type attrType = attribute->getBasicType();
- // Partial update to tensor, predicate or reference attribute
- // must update document
- return ((attrType != search::attribute::BasicType::Type::PREDICATE) &&
- (attrType != search::attribute::BasicType::Type::TENSOR) &&
- (attrType != search::attribute::BasicType::Type::REFERENCE));
-}
-
} // namespace proton
diff --git a/searchcore/src/vespa/searchcore/proton/server/fast_access_feed_view.h b/searchcore/src/vespa/searchcore/proton/server/fast_access_feed_view.h
index 217fe5acf4a..3af97b4ecb9 100644
--- a/searchcore/src/vespa/searchcore/proton/server/fast_access_feed_view.h
+++ b/searchcore/src/vespa/searchcore/proton/server/fast_access_feed_view.h
@@ -39,13 +39,11 @@ private:
const IAttributeWriter::SP _attributeWriter;
DocIdLimit &_docIdLimit;
- UpdateScope getUpdateScope(const document::DocumentUpdate &upd) override;
-
void putAttributes(SerialNum serialNum, search::DocumentIdT lid, const document::Document &doc,
bool immediateCommit, OnPutDoneType onWriteDone) override;
void updateAttributes(SerialNum serialNum, search::DocumentIdT lid, const document::DocumentUpdate &upd,
- bool immediateCommit, OnOperationDoneType onWriteDone) override;
+ bool immediateCommit, OnOperationDoneType onWriteDone, IFieldUpdateCallback & onUpdate) override;
void updateAttributes(SerialNum serialNum, Lid lid, FutureDoc doc,
bool immediateCommit, OnOperationDoneType onWriteDone) override;
void removeAttributes(SerialNum serialNum, search::DocumentIdT lid,
@@ -74,8 +72,6 @@ public:
void handleCompactLidSpace(const CompactLidSpaceOperation &op) override;
void sync() override;
-
- bool fastPartialUpdateAttribute(const vespalib::string &fieldName) const;
};
} // namespace proton
diff --git a/searchcore/src/vespa/searchcore/proton/server/searchable_feed_view.cpp b/searchcore/src/vespa/searchcore/proton/server/searchable_feed_view.cpp
index 88ddd9730df..4cda07eee8b 100644
--- a/searchcore/src/vespa/searchcore/proton/server/searchable_feed_view.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/searchable_feed_view.cpp
@@ -118,29 +118,6 @@ SearchableFeedView::performIndexHeartBeat(SerialNum serialNum)
_indexWriter->heartBeat(serialNum);
}
-SearchableFeedView::UpdateScope
-SearchableFeedView::getUpdateScope(const DocumentUpdate &upd)
-{
- UpdateScope updateScope;
- const Schema &schema = *_schema;
- for(size_t i(0), m(upd.getUpdates().size());
- !(updateScope._indexedFields && updateScope._nonAttributeFields) &&
- (i < m); i++) {
- const document::FieldUpdate & fu(upd.getUpdates()[i]);
- const vespalib::string &name = fu.getField().getName();
- if (schema.isIndexField(name)) {
- updateScope._indexedFields = true;
- }
- if (!fastPartialUpdateAttribute(name)) {
- updateScope._nonAttributeFields = true;
- }
- }
- if (!upd.getFieldPathUpdates().empty()) {
- updateScope._nonAttributeFields = true;
- }
- return updateScope;
-}
-
void
SearchableFeedView::updateIndexedFields(SerialNum serialNum, search::DocumentIdT lid, FutureDoc futureDoc,
bool immediateCommit, OnOperationDoneType onWriteDone)
diff --git a/searchcore/src/vespa/searchcore/proton/server/searchable_feed_view.h b/searchcore/src/vespa/searchcore/proton/server/searchable_feed_view.h
index 81d81a6cc27..ed3ba6740b1 100644
--- a/searchcore/src/vespa/searchcore/proton/server/searchable_feed_view.h
+++ b/searchcore/src/vespa/searchcore/proton/server/searchable_feed_view.h
@@ -34,24 +34,19 @@ private:
bool hasIndexedFields() const { return _hasIndexedFields; }
- void
- performIndexPut(SerialNum serialNum, search::DocumentIdT lid, const document::Document &doc,
- bool immediateCommit, OnOperationDoneType onWriteDone);
+ void performIndexPut(SerialNum serialNum, search::DocumentIdT lid, const document::Document &doc,
+ bool immediateCommit, OnOperationDoneType onWriteDone);
- void
- performIndexPut(SerialNum serialNum, search::DocumentIdT lid, const document::Document::SP &doc,
- bool immediateCommit, OnOperationDoneType onWriteDone);
- void
- performIndexPut(SerialNum serialNum, search::DocumentIdT lid, FutureDoc doc,
- bool immediateCommit, OnOperationDoneType onWriteDone);
+ void performIndexPut(SerialNum serialNum, search::DocumentIdT lid, const document::Document::SP &doc,
+ bool immediateCommit, OnOperationDoneType onWriteDone);
+ void performIndexPut(SerialNum serialNum, search::DocumentIdT lid, FutureDoc doc,
+ bool immediateCommit, OnOperationDoneType onWriteDone);
- void
- performIndexRemove(SerialNum serialNum, search::DocumentIdT lid,
- bool immediateCommit, OnRemoveDoneType onWriteDone);
+ void performIndexRemove(SerialNum serialNum, search::DocumentIdT lid,
+ bool immediateCommit, OnRemoveDoneType onWriteDone);
- void
- performIndexRemove(SerialNum serialNum, const LidVector &lidsToRemove,
- bool immediateCommit, OnWriteDoneType onWriteDone);
+ void performIndexRemove(SerialNum serialNum, const LidVector &lidsToRemove,
+ bool immediateCommit, OnWriteDoneType onWriteDone);
void performIndexHeartBeat(SerialNum serialNum);
@@ -60,23 +55,17 @@ private:
void performSync();
void heartBeatIndexedFields(SerialNum serialNum) override;
- virtual void
- putIndexedFields(SerialNum serialNum, search::DocumentIdT lid, const document::Document::SP &newDoc,
- bool immediateCommit, OnOperationDoneType onWriteDone) override;
+ void putIndexedFields(SerialNum serialNum, search::DocumentIdT lid, const document::Document::SP &newDoc,
+ bool immediateCommit, OnOperationDoneType onWriteDone) override;
- UpdateScope getUpdateScope(const document::DocumentUpdate &upd) override;
+ void updateIndexedFields(SerialNum serialNum, search::DocumentIdT lid, FutureDoc newDoc,
+ bool immediateCommit, OnOperationDoneType onWriteDone) override;
- virtual void
- updateIndexedFields(SerialNum serialNum, search::DocumentIdT lid, FutureDoc newDoc,
- bool immediateCommit, OnOperationDoneType onWriteDone) override;
+ void removeIndexedFields(SerialNum serialNum, search::DocumentIdT lid,
+ bool immediateCommit, OnRemoveDoneType onWriteDone) override;
- virtual void
- removeIndexedFields(SerialNum serialNum, search::DocumentIdT lid,
- bool immediateCommit, OnRemoveDoneType onWriteDone) override;
-
- virtual void
- removeIndexedFields(SerialNum serialNum, const LidVector &lidsToRemove,
- bool immediateCommit, OnWriteDoneType onWriteDone) override;
+ void removeIndexedFields(SerialNum serialNum, const LidVector &lidsToRemove,
+ bool immediateCommit, OnWriteDoneType onWriteDone) override;
void performIndexForceCommit(SerialNum serialNum, OnForceCommitDoneType onCommitDone);
void forceCommit(SerialNum serialNum, OnForceCommitDoneType onCommitDone) override;
@@ -85,7 +74,7 @@ public:
SearchableFeedView(const StoreOnlyFeedView::Context &storeOnlyCtx, const PersistentParams &params,
const FastAccessFeedView::Context &fastUpdateCtx, Context ctx);
- virtual ~SearchableFeedView();
+ ~SearchableFeedView() override;
const IIndexWriter::SP &getIndexWriter() const { return _indexWriter; }
void sync() override;
};
diff --git a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp
index 34902e5c673..a0f6ee98b71 100644
--- a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp
@@ -17,6 +17,8 @@
#include <vespa/vespalib/util/exceptions.h>
#include <vespa/log/log.h>
+#include <vespa/searchcore/proton/attribute/ifieldupdatecallback.h>
+
LOG_SETUP(".proton.server.storeonlyfeedview");
using document::BucketId;
@@ -300,21 +302,15 @@ StoreOnlyFeedView::heartBeatIndexedFields(SerialNum ) {}
void
StoreOnlyFeedView::heartBeatAttributes(SerialNum ) {}
-
-StoreOnlyFeedView::UpdateScope
-StoreOnlyFeedView::getUpdateScope(const DocumentUpdate &upd)
+void
+StoreOnlyFeedView::updateAttributes(SerialNum, Lid, const DocumentUpdate & upd, bool,
+ OnOperationDoneType, IFieldUpdateCallback & onUpdate)
{
- UpdateScope updateScope;
- if (!upd.getUpdates().empty() || !upd.getFieldPathUpdates().empty()) {
- updateScope._nonAttributeFields = true;
+ for (const auto & fieldUpdate : upd.getUpdates()) {
+ onUpdate.onUpdateField(fieldUpdate.getField().getName(), nullptr);
}
- return updateScope;
}
-
-void
-StoreOnlyFeedView::updateAttributes(SerialNum, Lid, const DocumentUpdate &, bool, OnOperationDoneType) {}
-
void
StoreOnlyFeedView::updateAttributes(SerialNum, Lid, FutureDoc, bool, OnOperationDoneType)
{
@@ -390,6 +386,34 @@ void StoreOnlyFeedView::heartBeatSummary(SerialNum serialNum) {
}));
}
+StoreOnlyFeedView::UpdateScope::UpdateScope(const search::index::Schema & schema, const DocumentUpdate & upd)
+ : _schema(&schema),
+ _indexedFields(false),
+ _nonAttributeFields(!upd.getFieldPathUpdates().empty())
+{}
+
+namespace {
+
+bool isAttributeUpdateable(const search::AttributeVector *attribute) {
+ search::attribute::BasicType::Type attrType = attribute->getBasicType();
+ // Partial update to tensor, predicate or reference attribute
+ // must update document
+ return ((attrType != search::attribute::BasicType::Type::PREDICATE) &&
+ (attrType != search::attribute::BasicType::Type::TENSOR) &&
+ (attrType != search::attribute::BasicType::Type::REFERENCE));
+}
+}
+
+void
+StoreOnlyFeedView::UpdateScope::onUpdateField(vespalib::stringref fieldName, const search::AttributeVector * attr) {
+ if (!_nonAttributeFields && (attr == nullptr || !isAttributeUpdateable(attr))) {
+ _nonAttributeFields = true;
+ }
+ if (!_indexedFields && _schema->isIndexField(fieldName)) {
+ _indexedFields = true;
+ }
+}
+
void
StoreOnlyFeedView::internalUpdate(FeedToken token, const UpdateOperation &updOp) {
if ( ! updOp.getUpdate()) {
@@ -422,9 +446,9 @@ StoreOnlyFeedView::internalUpdate(FeedToken token, const UpdateOperation &updOp)
bool immediateCommit = _commitTimeTracker.needCommit();
auto onWriteDone = createUpdateDoneContext(std::move(token), updOp.getUpdate());
- updateAttributes(serialNum, lid, upd, immediateCommit, onWriteDone);
+ UpdateScope updateScope(*_schema, upd);
+ updateAttributes(serialNum, lid, upd, immediateCommit, onWriteDone, updateScope);
- UpdateScope updateScope(getUpdateScope(upd));
if (updateScope.hasIndexOrNonAttributeFields()) {
PromisedDoc promisedDoc;
FutureDoc futureDoc = promisedDoc.get_future().share();
diff --git a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h
index 1ccce8a4a09..a11512590f3 100644
--- a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h
+++ b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h
@@ -9,6 +9,7 @@
#include "searchcontext.h"
#include "pendinglidtracker.h"
#include <vespa/searchcore/proton/common/doctypename.h>
+#include <vespa/searchcore/proton/attribute/ifieldupdatecallback.h>
#include <vespa/searchcore/proton/common/feeddebugger.h>
#include <vespa/searchcore/proton/documentmetastore/documentmetastore.h>
#include <vespa/searchcore/proton/documentmetastore/documentmetastorecontext.h>
@@ -33,6 +34,7 @@ class PutDoneContext;
class RemoveDoneContext;
class CommitTimeTracker;
class IGidToLidChangeHandler;
+class IFieldUpdateCallback;
namespace documentmetastore { class ILidReuseDelayer; }
@@ -120,18 +122,19 @@ public:
};
protected:
- struct UpdateScope
+ class UpdateScope : public IFieldUpdateCallback
{
+ private:
+ const search::index::Schema *_schema;
+ public:
bool _indexedFields;
bool _nonAttributeFields;
- UpdateScope()
- : _indexedFields(false),
- _nonAttributeFields(false)
- {}
+ UpdateScope(const search::index::Schema & schema, const DocumentUpdate & upd);
bool hasIndexOrNonAttributeFields() const {
return _indexedFields || _nonAttributeFields;
}
+ void onUpdateField(vespalib::stringref fieldName, const search::AttributeVector * attr) override;
};
private:
@@ -200,10 +203,8 @@ private:
virtual void putIndexedFields(SerialNum serialNum, Lid lid, const DocumentSP &newDoc,
bool immediateCommit, OnOperationDoneType onWriteDone);
- virtual UpdateScope getUpdateScope(const DocumentUpdate &upd);
-
virtual void updateAttributes(SerialNum serialNum, Lid lid, const DocumentUpdate &upd,
- bool immediateCommit, OnOperationDoneType onWriteDone);
+ bool immediateCommit, OnOperationDoneType onWriteDone, IFieldUpdateCallback & onUpdate);
virtual void updateAttributes(SerialNum serialNum, Lid lid, FutureDoc doc,
bool immediateCommit, OnOperationDoneType onWriteDone);