diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2020-11-08 16:06:15 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2020-11-08 22:24:43 +0000 |
commit | bc0c19e3e45fa4941b98c46e869eca7d890ff6b3 (patch) | |
tree | 99d84a999ad597f3c44d8cb7686a7e8f98247953 /searchcore | |
parent | 434567d25d1ccecbabf193ce1692be718ca11ea0 (diff) |
Use a hash_set<int32_t> to quickly check if a field is an index field.
This avoid computing the hash of a string necessary when using a hash_map<string, ...>.
Diffstat (limited to 'searchcore')
6 files changed, 62 insertions, 55 deletions
diff --git a/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp b/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp index b875ab8e058..54fe88050b5 100644 --- a/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp +++ b/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp @@ -355,7 +355,7 @@ struct MyAttributeWriter : public IAttributeWriter _updateLid = lid; for (const auto & fieldUpdate : upd.getUpdates()) { search::AttributeVector * attr = getWritableAttribute(fieldUpdate.getField().getName()); - onUpdate.onUpdateField(fieldUpdate.getField().getName(), attr); + onUpdate.onUpdateField(fieldUpdate.getField(), attr); } } void update(SerialNum serialNum, const document::Document &doc, DocumentIdT lid, OnWriteDoneType) override { diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.cpp b/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.cpp index 42971fe3d4c..ee7f9d0c851 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.cpp +++ b/searchcore/src/vespa/searchcore/proton/attribute/attribute_writer.cpp @@ -680,7 +680,7 @@ AttributeWriter::update(SerialNum serialNum, const DocumentUpdate &upd, Document LOG(debug, "Retrieving guard for attribute vector '%s'.", fupd.getField().getName().data()); auto found = _attrMap.find(fupd.getField().getName()); AttributeVector * attrp = (found != _attrMap.end()) ? found->second.first : nullptr; - onUpdate.onUpdateField(fupd.getField().getName(), attrp); + onUpdate.onUpdateField(fupd.getField(), attrp); if (__builtin_expect(attrp == nullptr, false)) { LOG(spam, "Failed to find attribute vector %s", fupd.getField().getName().data()); continue; diff --git a/searchcore/src/vespa/searchcore/proton/attribute/ifieldupdatecallback.h b/searchcore/src/vespa/searchcore/proton/attribute/ifieldupdatecallback.h index ffb8555cd2c..c7453d618ff 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/ifieldupdatecallback.h +++ b/searchcore/src/vespa/searchcore/proton/attribute/ifieldupdatecallback.h @@ -5,16 +5,17 @@ #include <vespa/vespalib/stllike/string.h> namespace search { class AttributeVector; } +namespace document { class Field; } namespace proton { struct IFieldUpdateCallback { - virtual ~IFieldUpdateCallback() { } - virtual void onUpdateField(vespalib::stringref fieldName, const search::AttributeVector * attr) = 0; + virtual ~IFieldUpdateCallback() = default; + virtual void onUpdateField(const document::Field & field, const search::AttributeVector * attr) = 0; }; struct DummyFieldUpdateCallback : IFieldUpdateCallback { - void onUpdateField(vespalib::stringref, const search::AttributeVector *) override {} + void onUpdateField(const document::Field & , const search::AttributeVector *) override {} }; } 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 7cfad4f1ac1..fdacf59fa02 100644 --- a/searchcore/src/vespa/searchcore/proton/server/searchable_feed_view.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/searchable_feed_view.cpp @@ -34,7 +34,7 @@ SearchableFeedView::SearchableFeedView(StoreOnlyFeedView::Context storeOnlyCtx, const FastAccessFeedView::Context &fastUpdateCtx, Context ctx) : Parent(std::move(storeOnlyCtx), params, fastUpdateCtx), _indexWriter(ctx._indexWriter), - _hasIndexedFields(_schema->getNumIndexFields() > 0) + _hasIndexedFields(getSchema()->getNumIndexFields() > 0) { } SearchableFeedView::~SearchableFeedView() = default; diff --git a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp index bf357188766..89e765e2e2b 100644 --- a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp @@ -8,14 +8,14 @@ #include "remove_batch_done_context.h" #include "removedonecontext.h" #include "updatedonecontext.h" -#include <vespa/document/datatype/documenttype.h> -#include <vespa/document/fieldvalue/document.h> -#include <vespa/document/repo/documenttyperepo.h> #include <vespa/searchcore/proton/attribute/ifieldupdatecallback.h> #include <vespa/searchcore/proton/common/feedtoken.h> #include <vespa/searchcore/proton/feedoperation/operations.h> #include <vespa/searchcore/proton/reference/i_gid_to_lid_change_handler.h> #include <vespa/searchlib/common/gatecallback.h> +#include <vespa/document/datatype/documenttype.h> +#include <vespa/document/fieldvalue/document.h> +#include <vespa/document/repo/documenttyperepo.h> #include <vespa/vespalib/util/isequencedtaskexecutor.h> #include <vespa/vespalib/util/exceptions.h> @@ -148,8 +148,8 @@ SummaryPutDoneContext::SummaryPutDoneContext(FeedToken token, IPendingLidTracker SummaryPutDoneContext::~SummaryPutDoneContext() = default; -std::vector<document::GlobalId> getGidsToRemove(const IDocumentMetaStore &metaStore, - const LidVectorContext::LidVector &lidsToRemove) +std::vector<document::GlobalId> +getGidsToRemove(const IDocumentMetaStore &metaStore, const LidVectorContext::LidVector &lidsToRemove) { std::vector<document::GlobalId> gids; gids.reserve(lidsToRemove.size()); @@ -162,8 +162,9 @@ std::vector<document::GlobalId> getGidsToRemove(const IDocumentMetaStore &metaSt return gids; } -void putMetaData(documentmetastore::IStore &meta_store, const DocumentId & doc_id, - const DocumentOperation &op, bool is_removed_doc) +void +putMetaData(documentmetastore::IStore &meta_store, const DocumentId & doc_id, + const DocumentOperation &op, bool is_removed_doc) { documentmetastore::IStore::Result putRes( meta_store.put(doc_id.getGlobalId(), @@ -177,8 +178,9 @@ void putMetaData(documentmetastore::IStore &meta_store, const DocumentId & doc_i assert(op.getLid() == putRes._lid); } -void removeMetaData(documentmetastore::IStore &meta_store, const GlobalId & gid, const DocumentId &doc_id, - const DocumentOperation &op, bool is_removed_doc) +void +removeMetaData(documentmetastore::IStore &meta_store, const GlobalId & gid, const DocumentId &doc_id, + const DocumentOperation &op, bool is_removed_doc) { assert(meta_store.validLid(op.getPrevLid())); assert(is_removed_doc == op.getPrevMarkedAsRemoved()); @@ -207,6 +209,37 @@ moveMetaData(documentmetastore::IStore &meta_store, const DocumentId & doc_id, c meta_store.move(op.getPrevLid(), op.getLid(), op.get_prepare_serial_num()); } +class UpdateScope final : public IFieldUpdateCallback +{ +private: + const vespalib::hash_set<int32_t> & _indexedFields; + bool _nonAttributeFields; +public: + bool _hasIndexedFields; + + UpdateScope(const vespalib::hash_set<int32_t> & indexedFields, const DocumentUpdate & upd); + bool hasIndexOrNonAttributeFields() const { + return _hasIndexedFields || _nonAttributeFields; + } + void onUpdateField(const document::Field & field, const search::AttributeVector * attr) override; +}; + +UpdateScope::UpdateScope(const vespalib::hash_set<int32_t> & indexedFields, const DocumentUpdate & upd) + : _indexedFields(indexedFields), + _nonAttributeFields(!upd.getFieldPathUpdates().empty()), + _hasIndexedFields(false) +{} + +void +UpdateScope::onUpdateField(const document::Field & field, const search::AttributeVector * attr) { + if (!_nonAttributeFields && (attr == nullptr || !attr->isUpdateableInMemoryOnly())) { + _nonAttributeFields = true; + } + if (!_hasIndexedFields && (_indexedFields.find(field.getId()) != _indexedFields.end())) { + _hasIndexedFields = true; + } +} + } // namespace StoreOnlyFeedView::StoreOnlyFeedView(Context ctx, const PersistentParams ¶ms) @@ -220,12 +253,18 @@ StoreOnlyFeedView::StoreOnlyFeedView(Context ctx, const PersistentParams ¶ms _pendingLidsForDocStore(), _pendingLidsForCommit(std::move(ctx._pendingLidsForCommit)), _schema(std::move(ctx._schema)), + _indexedFields(), _writeService(ctx._writeService), _params(params), _metaStore(_documentMetaStoreContext->get()), _gidToLidChangeHandler(ctx._gidToLidChangeHandler) { _docType = _repo->getDocumentType(_params._docTypeName.getName()); + if (_schema && _docType) { + for (const auto &indexField : _schema->getIndexFields()) { + _indexedFields.insert(_docType->getField(indexField.getName()).getId()); + } + } } StoreOnlyFeedView::~StoreOnlyFeedView() = default; @@ -339,7 +378,7 @@ StoreOnlyFeedView::updateAttributes(SerialNum, Lid, const DocumentUpdate & upd, OnOperationDoneType, IFieldUpdateCallback & onUpdate) { for (const auto & fieldUpdate : upd.getUpdates()) { - onUpdate.onUpdateField(fieldUpdate.getField().getName(), nullptr); + onUpdate.onUpdateField(fieldUpdate.getField(), nullptr); } } @@ -408,22 +447,6 @@ void StoreOnlyFeedView::heartBeatSummary(SerialNum serialNum) { })); } -StoreOnlyFeedView::UpdateScope::UpdateScope(const search::index::Schema & schema, const DocumentUpdate & upd) - : _schema(&schema), - _indexedFields(false), - _nonAttributeFields(!upd.getFieldPathUpdates().empty()) -{} - -void -StoreOnlyFeedView::UpdateScope::onUpdateField(vespalib::stringref fieldName, const search::AttributeVector * attr) { - if (!_nonAttributeFields && (attr == nullptr || !attr->isUpdateableInMemoryOnly())) { - _nonAttributeFields = true; - } - if (!_indexedFields && _schema->isIndexField(fieldName)) { - _indexedFields = true; - } -} - void StoreOnlyFeedView::internalUpdate(FeedToken token, const UpdateOperation &updOp) { if ( ! updOp.getUpdate()) { @@ -455,7 +478,7 @@ StoreOnlyFeedView::internalUpdate(FeedToken token, const UpdateOperation &updOp) auto uncommitted = get_pending_lid_token(updOp); auto onWriteDone = createUpdateDoneContext(std::move(token), std::move(uncommitted), updOp.getUpdate()); - UpdateScope updateScope(*_schema, upd); + UpdateScope updateScope(_indexedFields, upd); updateAttributes(serialNum, lid, upd, onWriteDone, updateScope); if (updateScope.hasIndexOrNonAttributeFields()) { @@ -463,7 +486,7 @@ StoreOnlyFeedView::internalUpdate(FeedToken token, const UpdateOperation &updOp) FutureDoc futureDoc = promisedDoc.get_future().share(); onWriteDone->setDocument(futureDoc); _pendingLidsForDocStore.waitComplete(lid); - if (updateScope._indexedFields) { + if (updateScope._hasIndexedFields) { updateIndexedFields(serialNum, lid, futureDoc, onWriteDone); } PromisedStream promisedStream; diff --git a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h index da7d5e53a88..c033ae0c43f 100644 --- a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h +++ b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h @@ -9,7 +9,6 @@ #include "searchcontext.h" #include <vespa/searchcore/proton/common/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> @@ -19,9 +18,10 @@ #include <vespa/searchcore/proton/reference/pending_notify_remove_done.h> #include <vespa/searchcorespi/index/ithreadingservice.h> #include <vespa/searchlib/query/base.h> +#include <vespa/searchcore/proton/feedoperation/operations.h> #include <vespa/vespalib/util/threadstackexecutorbase.h> +#include <vespa/vespalib/stllike/hash_set.h> #include <future> -#include <vespa/searchcore/proton/feedoperation/operations.h> namespace search { class IDestructorCallback; } @@ -60,7 +60,6 @@ public: using OnOperationDoneType = const std::shared_ptr<OperationDoneContext> &; using OnPutDoneType = const std::shared_ptr<PutDoneContext> &; using OnRemoveDoneType = const std::shared_ptr<RemoveDoneContext> &; - using FeedTokenUP = std::unique_ptr<FeedToken>; using FutureDoc = std::shared_future<std::unique_ptr<const Document>>; using PromisedDoc = std::promise<std::unique_ptr<const Document>>; using FutureStream = std::future<vespalib::nbostream>; @@ -121,22 +120,6 @@ public: {} }; -protected: - class UpdateScope : public IFieldUpdateCallback - { - private: - const search::index::Schema *_schema; - public: - bool _indexedFields; - bool _nonAttributeFields; - - 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: const ISummaryAdapter::SP _summaryAdapter; const IDocumentMetaStoreContext::SP _documentMetaStoreContext; @@ -145,9 +128,9 @@ private: LidReuseDelayer _lidReuseDelayer; PendingLidTracker _pendingLidsForDocStore; std::shared_ptr<PendingLidTrackerBase> _pendingLidsForCommit; - + const search::index::Schema::SP _schema; + vespalib::hash_set<int32_t> _indexedFields; protected: - const search::index::Schema::SP _schema; searchcorespi::index::IThreadingService &_writeService; PersistentParams _params; IDocumentMetaStore &_metaStore; |