diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2019-01-11 22:48:53 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-11 22:48:53 +0100 |
commit | 9ba701cbecf1d7ac6e28fe102041c5b942b6acf8 (patch) | |
tree | ae9c5cc07b4ddf5b2b44cade707ad3de74cdbd01 | |
parent | 50d4755fedcec858bbc124f6a43db71685fea8c6 (diff) | |
parent | 77cd27d86c8a2ee2722fb79896ad2157e9120a4a (diff) |
Merge pull request #8121 from vespa-engine/balder/bool-for-summary-too
Balder/bool for summary too
31 files changed, 357 insertions, 1241 deletions
diff --git a/document/src/vespa/document/fieldvalue/boolfieldvalue.cpp b/document/src/vespa/document/fieldvalue/boolfieldvalue.cpp index 8ee2556d751..88ad1ddd11b 100644 --- a/document/src/vespa/document/fieldvalue/boolfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/boolfieldvalue.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright 2019 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "boolfieldvalue.h" #include <vespa/document/datatype/datatype.h> @@ -57,4 +57,29 @@ BoolFieldValue::clone() const { return new BoolFieldValue(*this); } +char +BoolFieldValue::getAsByte() const { + return _value ? 1 : 0; +} +int32_t +BoolFieldValue::getAsInt() const { + return _value ? 1 : 0; +} +int64_t +BoolFieldValue::getAsLong() const { + return _value ? 1 : 0; +} +float +BoolFieldValue::getAsFloat() const { + return _value ? 1 : 0; +} +double +BoolFieldValue::getAsDouble() const { + return _value ? 1 : 0; +} +vespalib::string +BoolFieldValue::getAsString() const { + return _value ? "true" : "false"; +} + } // namespace document diff --git a/document/src/vespa/document/fieldvalue/boolfieldvalue.h b/document/src/vespa/document/fieldvalue/boolfieldvalue.h index d81fa25848d..689bd3f4d53 100644 --- a/document/src/vespa/document/fieldvalue/boolfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/boolfieldvalue.h @@ -1,4 +1,4 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright 2019 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once @@ -6,6 +6,9 @@ namespace document { +/** + * Represent the value in a filed of type 'bool' which can be either true or false. + **/ class BoolFieldValue : public FieldValue { bool _value; bool _altered; @@ -31,6 +34,13 @@ public: FieldValue &assign(const FieldValue &rhs) override; + char getAsByte() const override; + int32_t getAsInt() const override; + int64_t getAsLong() const override; + float getAsFloat() const override; + double getAsDouble() const override; + vespalib::string getAsString() const override; + DECLARE_IDENTIFIABLE(BoolFieldValue); }; diff --git a/searchcore/src/tests/proton/docsummary/docsummary.cpp b/searchcore/src/tests/proton/docsummary/docsummary.cpp index db6116073e6..c0c706383f6 100644 --- a/searchcore/src/tests/proton/docsummary/docsummary.cpp +++ b/searchcore/src/tests/proton/docsummary/docsummary.cpp @@ -106,7 +106,7 @@ public: TuneFileSummary(), _fileHeaderContext, _noTlSyncer, - NULL), + nullptr), _serialNum(1) { } @@ -262,7 +262,7 @@ public: op.setPrevDbDocumentId(prevDbdId); _ddb->getFeedHandler().storeOperation(op, std::make_shared<search::IgnoreCallback>()); SearchView *sv(dynamic_cast<SearchView *>(_ddb->getReadySubDB()->getSearchView().get())); - if (sv != NULL) { + if (sv != nullptr) { // cf. FeedView::putAttributes() DocIdLimit &docIdLimit = sv->getDocIdLimit(); if (docIdLimit.get() <= lid) @@ -278,14 +278,11 @@ private: ResultConfig _resultCfg; std::set<vespalib::string> _markupFields; - const ResultConfig &getResultConfig() const - { + const ResultConfig &getResultConfig() const{ return _resultCfg; } - const std::set<vespalib::string> & - getMarkupFields() const - { + const std::set<vespalib::string> &getMarkupFields() const{ return _markupFields; } @@ -295,31 +292,12 @@ private: GeneralResultPtr getResult(const DocsumReply & reply, uint32_t id, uint32_t resultClassID); - bool - assertString(const std::string & exp, - const std::string & fieldName, - DocumentStoreAdapter &dsa, - uint32_t id); + bool assertString(const std::string & exp, const std::string & fieldName, DocumentStoreAdapter &dsa, uint32_t id); - bool - assertString(const std::string &exp, - const std::string &fieldName, - const DocsumReply &reply, - uint32_t id, - uint32_t resultClassID); + void assertTensor(const Tensor::UP &exp, const std::string &fieldName, const DocsumReply &reply, + uint32_t id, uint32_t resultClassID); - void - assertTensor(const Tensor::UP &exp, - const std::string &fieldName, - const DocsumReply &reply, - uint32_t id, - uint32_t resultClassID); - - bool - assertSlime(const std::string &exp, - const DocsumReply &reply, - uint32_t id, - bool relaxed = false); + bool assertSlime(const std::string &exp, const DocsumReply &reply, uint32_t id,bool relaxed = false); void requireThatAdapterHandlesAllFieldTypes(); void requireThatAdapterHandlesMultipleDocuments(); @@ -346,12 +324,10 @@ GeneralResultPtr Test::getResult(DocumentStoreAdapter & dsa, uint32_t docId) { DocsumStoreValue docsum = dsa.getMappedDocsum(docId); - ASSERT_TRUE(docsum.pt() != NULL); - GeneralResultPtr retval(new GeneralResult(dsa.getResultClass(), - 0, 0, 0)); + ASSERT_TRUE(docsum.pt() != nullptr); + auto retval = std::make_unique<GeneralResult>(dsa.getResultClass()); // skip the 4 byte class id - ASSERT_TRUE(retval->unpack(docsum.pt() + 4, - docsum.len() - 4) == 0); + ASSERT_TRUE(retval->unpack(docsum.pt() + 4, docsum.len() - 4)); return retval; } @@ -359,46 +335,26 @@ Test::getResult(DocumentStoreAdapter & dsa, uint32_t docId) GeneralResultPtr Test::getResult(const DocsumReply & reply, uint32_t id, uint32_t resultClassID) { - GeneralResultPtr retval(new GeneralResult(getResultConfig(). - LookupResultClass(resultClassID), - 0, 0, 0)); + auto retval = std::make_unique<GeneralResult>(getResultConfig().LookupResultClass(resultClassID)); const DocsumReply::Docsum & docsum = reply.docsums[id]; // skip the 4 byte class id - ASSERT_EQUAL(0, retval->unpack(docsum.data.c_str() + 4, docsum.data.size() - 4)); + ASSERT_TRUE(retval->unpack(docsum.data.c_str() + 4, docsum.data.size() - 4)); return retval; } bool Test::assertString(const std::string & exp, const std::string & fieldName, - DocumentStoreAdapter &dsa, - uint32_t id) + DocumentStoreAdapter &dsa, uint32_t id) { GeneralResultPtr res = getResult(dsa, id); - return EXPECT_EQUAL(exp, std::string(res->GetEntry(fieldName.c_str())-> - _stringval, - res->GetEntry(fieldName.c_str())-> - _stringlen)); + return EXPECT_EQUAL(exp, std::string(res->GetEntry(fieldName.c_str())->_stringval, + res->GetEntry(fieldName.c_str())->_stringlen)); } - -bool -Test::assertString(const std::string & exp, const std::string & fieldName, - const DocsumReply & reply, - uint32_t id, uint32_t resultClassID) -{ - GeneralResultPtr res = getResult(reply, id, resultClassID); - return EXPECT_EQUAL(exp, std::string(res->GetEntry(fieldName.c_str())-> - _stringval, - res->GetEntry(fieldName.c_str())-> - _stringlen)); -} - - void Test::assertTensor(const Tensor::UP & exp, const std::string & fieldName, - const DocsumReply & reply, - uint32_t id, uint32_t) + const DocsumReply & reply, uint32_t id, uint32_t) { const DocsumReply::Docsum & docsum = reply.docsums[id]; uint32_t classId; @@ -408,8 +364,7 @@ Test::assertTensor(const Tensor::UP & exp, const std::string & fieldName, vespalib::Slime slime; vespalib::Memory serialized(docsum.data.c_str() + sizeof(classId), docsum.data.size() - sizeof(classId)); - size_t decodeRes = BinaryFormat::decode(serialized, - slime); + size_t decodeRes = BinaryFormat::decode(serialized, slime); ASSERT_EQUAL(decodeRes, serialized.size); EXPECT_EQUAL(exp.get() != nullptr, slime.get()[fieldName].valid()); @@ -547,7 +502,7 @@ Test::requireThatAdapterHandlesMultipleDocuments() } { // doc 2 DocsumStoreValue docsum = dsa.getMappedDocsum(2); - EXPECT_TRUE(docsum.pt() == NULL); + EXPECT_TRUE(docsum.pt() == nullptr); } { // doc 0 (again) GeneralResultPtr res = getResult(dsa, 0); @@ -640,7 +595,7 @@ Test::requireThatDocsumRequestIsProcessed() EXPECT_TRUE(assertSlime("{a:40}", *rep, 1, false)); EXPECT_EQUAL(search::endDocId, rep->docsums[2].docid); EXPECT_EQUAL(gid9, rep->docsums[2].gid); - EXPECT_TRUE(rep->docsums[2].data.get() == NULL); + EXPECT_TRUE(rep->docsums[2].data.get() == nullptr); } @@ -874,11 +829,11 @@ Test::requireThatSummaryAdapterHandlesPutAndRemove() dc._sa->put(1, 1, *exp); IDocumentStore & store = dc._ddb->getReadySubDB()->getSummaryManager()->getBackingStore(); Document::UP act = store.read(1, *bc._repo); - EXPECT_TRUE(act.get() != NULL); + EXPECT_TRUE(act.get() != nullptr); EXPECT_EQUAL(exp->getType(), act->getType()); EXPECT_EQUAL("foo", act->getValue("f1")->toString()); dc._sa->remove(2, 1); - EXPECT_TRUE(store.read(1, *bc._repo).get() == NULL); + EXPECT_TRUE(store.read(1, *bc._repo).get() == nullptr); } @@ -928,7 +883,7 @@ Test::requireThatAnnotationsAreUsed() IDocumentStore & store = dc._ddb->getReadySubDB()->getSummaryManager()->getBackingStore(); Document::UP act = store.read(1, *bc._repo); - EXPECT_TRUE(act.get() != NULL); + EXPECT_TRUE(act.get() != nullptr); EXPECT_EQUAL(exp->getType(), act->getType()); EXPECT_EQUAL("foo bar", act->getValue("g")->getAsString()); EXPECT_EQUAL("foo bar", act->getValue("dynamicstring")->getAsString()); @@ -1082,7 +1037,7 @@ Test::requireThatUrisAreUsed() IDocumentStore & store = dc._ddb->getReadySubDB()->getSummaryManager()->getBackingStore(); Document::UP act = store.read(1, *bc._repo); - EXPECT_TRUE(act.get() != NULL); + EXPECT_TRUE(act.get() != nullptr); EXPECT_EQUAL(exp->getType(), act->getType()); DocumentStoreAdapter dsa(store, *bc._repo, getResultConfig(), "class0", @@ -1140,7 +1095,7 @@ Test::requireThatPositionsAreUsed() IDocumentStore & store = dc._ddb->getReadySubDB()->getSummaryManager()->getBackingStore(); Document::UP act = store.read(1, *bc._repo); - EXPECT_TRUE(act.get() != NULL); + EXPECT_TRUE(act.get() != nullptr); EXPECT_EQUAL(exp->getType(), act->getType()); DocsumRequest req; @@ -1219,7 +1174,7 @@ Test::requireThatRawFieldsWorks() IDocumentStore & store = dc._ddb->getReadySubDB()->getSummaryManager()->getBackingStore(); Document::UP act = store.read(1, *bc._repo); - EXPECT_TRUE(act.get() != NULL); + EXPECT_TRUE(act.get() != nullptr); EXPECT_EQUAL(exp->getType(), act->getType()); DocumentStoreAdapter dsa(store, *bc._repo, getResultConfig(), "class0", diff --git a/searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp b/searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp index ea6a16e1547..c65d18a590f 100644 --- a/searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp +++ b/searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp @@ -24,9 +24,7 @@ const vespalib::string DOCUMENT_ID_FIELD("documentid"); } bool -DocumentStoreAdapter::writeStringField(const char * buf, - uint32_t buflen, - ResType type) +DocumentStoreAdapter::writeStringField(const char * buf, uint32_t buflen, ResType type) { switch (type) { case RES_STRING: @@ -47,6 +45,8 @@ DocumentStoreAdapter::writeField(const FieldValue &value, ResType type) switch (type) { case RES_BYTE: return _resultPacker.AddByte(value.getAsInt()); + case RES_BOOL: + return _resultPacker.AddByte(value.getAsInt()); case RES_SHORT: return _resultPacker.AddShort(value.getAsInt()); case RES_INT: @@ -63,8 +63,7 @@ DocumentStoreAdapter::writeField(const FieldValue &value, ResType type) case RES_JSONSTRING: { if (value.getClass().inherits(LiteralFieldValueB::classId)) { - const LiteralFieldValueB & lfv = - static_cast<const LiteralFieldValueB &>(value); + auto & lfv = static_cast<const LiteralFieldValueB &>(value); vespalib::stringref s = lfv.getValueRef(); return writeStringField(s.data(), s.size(), type); } else { @@ -86,7 +85,7 @@ DocumentStoreAdapter::writeField(const FieldValue &value, ResType type) { vespalib::nbostream serialized; if (value.getClass().inherits(TensorFieldValue::classId)) { - const TensorFieldValue &tvalue = static_cast<const TensorFieldValue &>(value); + const auto &tvalue = static_cast<const TensorFieldValue &>(value); const std::unique_ptr<Tensor> &tensor = tvalue.getAsTensorPtr(); if (tensor) { vespalib::tensor::TypedBinaryFormat::serialize(serialized, *tensor); @@ -95,9 +94,7 @@ DocumentStoreAdapter::writeField(const FieldValue &value, ResType type) return _resultPacker.AddSerializedTensor(serialized.peek(), serialized.size()); } default: - LOG(warning, - "Unknown docsum field type: %s. Add empty field", - ResultConfig::GetResTypeName(type)); + LOG(warning, "Unknown docsum field type: %s. Add empty field",ResultConfig::GetResTypeName(type)); return _resultPacker.AddEmpty(); } return false; @@ -114,46 +111,32 @@ DocumentStoreAdapter::convertFromSearchDoc(Document &doc, uint32_t docId) if (fieldName == DOCUMENT_ID_FIELD) { StringFieldValue value(doc.getId().toString()); if (!writeField(value, entry->_type)) { - LOG(warning, "Error while writing field '%s' for docId %u", - fieldName.c_str(), docId); + LOG(warning, "Error while writing field '%s' for docId %u", fieldName.c_str(), docId); } continue; } const Field *field = _fieldCache->getField(i); if (!field) { - LOG(debug, - "Did not find field '%s' in the document " - "for docId %u. Adding empty field", + LOG(debug, "Did not find field '%s' in the document for docId %u. Adding empty field", fieldName.c_str(), docId); _resultPacker.AddEmpty(); continue; } FieldValue::UP fieldValue = doc.getValue(*field); - if (fieldValue.get() == NULL) { - LOG(spam, - "No field value for field '%s' in the document " - "for docId %u. Adding empty field", + if ( ! fieldValue) { + LOG(spam, "No field value for field '%s' in the document for docId %u. Adding empty field", fieldName.c_str(), docId); _resultPacker.AddEmpty(); continue; } - LOG(spam, - "writeField(%s): value(%s), type(%d)", - fieldName.c_str(), fieldValue->toString().c_str(), - entry->_type); - FieldValue::UP convertedFieldValue = - SummaryFieldConverter::convertSummaryField(markup, *fieldValue); - if (convertedFieldValue.get() != NULL) { + LOG(spam, "writeField(%s): value(%s), type(%d)", fieldName.c_str(), fieldValue->toString().c_str(), entry->_type); + FieldValue::UP convertedFieldValue = SummaryFieldConverter::convertSummaryField(markup, *fieldValue); + if (convertedFieldValue) { if (!writeField(*convertedFieldValue, entry->_type)) { - LOG(warning, - "Error while writing field '%s' for docId %u", - fieldName.c_str(), docId); + LOG(warning, "Error while writing field '%s' for docId %u", fieldName.c_str(), docId); } } else { - LOG(spam, - "No converted field value for field '%s' " - " in the document " - "for docId %u. Adding empty field", + LOG(spam, "No converted field value for field '%s' in the document for docId %u. Adding empty field", fieldName.c_str(), docId); _resultPacker.AddEmpty(); } @@ -171,46 +154,33 @@ DocumentStoreAdapter(const search::IDocumentStore & docStore, _repo(repo), _resultConfig(resultConfig), _resultClass(resultConfig. - LookupResultClass(resultConfig. - LookupResultClassId(resultClassName. - c_str()))), + LookupResultClass(resultConfig.LookupResultClassId(resultClassName.c_str()))), _resultPacker(&_resultConfig), _fieldCache(fieldCache), _markupFields(markupFields) { } -DocumentStoreAdapter::~DocumentStoreAdapter() {} +DocumentStoreAdapter::~DocumentStoreAdapter() = default; DocsumStoreValue DocumentStoreAdapter::getMappedDocsum(uint32_t docId) { if (!_resultPacker.Init(getSummaryClassId())) { - LOG(warning, - "Error during init of result class '%s' with class id %u", - _resultClass->GetClassName(), getSummaryClassId()); + LOG(warning, "Error during init of result class '%s' with class id %u", _resultClass->GetClassName(), getSummaryClassId()); return DocsumStoreValue(); } Document::UP document = _docStore.read(docId, _repo); - if (document.get() == NULL) { - LOG(debug, - "Did not find summary document for docId %u. " - "Returning empty docsum", - docId); + if ( ! document) { + LOG(debug, "Did not find summary document for docId %u. Returning empty docsum", docId); return DocsumStoreValue(); } - LOG(spam, - "getMappedDocSum(%u): document={\n%s\n}", - docId, - document->toString(true).c_str()); + LOG(spam, "getMappedDocSum(%u): document={\n%s\n}", docId, document->toString(true).c_str()); convertFromSearchDoc(*document, docId); const char * buf; uint32_t buflen; if (!_resultPacker.GetDocsumBlob(&buf, &buflen)) { - LOG(warning, - "Error while getting the docsum blob for docId %u. " - "Returning empty docsum", - docId); + LOG(warning, "Error while getting the docsum blob for docId %u. Returning empty docsum", docId); return DocsumStoreValue(); } return DocsumStoreValue(buf, buflen); diff --git a/searchcore/src/vespa/searchcore/proton/docsummary/summarymanager.cpp b/searchcore/src/vespa/searchcore/proton/docsummary/summarymanager.cpp index 54961d10fd3..1abe9540859 100644 --- a/searchcore/src/vespa/searchcore/proton/docsummary/summarymanager.cpp +++ b/searchcore/src/vespa/searchcore/proton/docsummary/summarymanager.cpp @@ -51,7 +51,7 @@ public: SerialNum flushedSerialNum, Time lastFlushTime, searchcorespi::index::IThreadService & summaryService, std::shared_ptr<ICompactableLidSpace> target); - ~ShrinkSummaryLidSpaceFlushTarget(); + ~ShrinkSummaryLidSpaceFlushTarget() override; Task::UP initFlush(SerialNum currentSerial) override; }; @@ -65,7 +65,7 @@ ShrinkSummaryLidSpaceFlushTarget(const vespalib::string &name, Type type, Compon { } -ShrinkSummaryLidSpaceFlushTarget::~ShrinkSummaryLidSpaceFlushTarget() {} +ShrinkSummaryLidSpaceFlushTarget::~ShrinkSummaryLidSpaceFlushTarget() = default; IFlushTarget::Task::UP ShrinkSummaryLidSpaceFlushTarget::initFlush(SerialNum currentSerial) @@ -93,7 +93,7 @@ SummarySetup(const vespalib::string & baseDir, const DocTypeName & docTypeName, _repo(repo), _markupFields() { - std::unique_ptr<ResultConfig> resultConfig(new ResultConfig()); + auto resultConfig = std::make_unique<ResultConfig>(); if (!resultConfig->ReadConfig(summaryCfg, make_string("SummaryManager(%s)", baseDir.c_str()).c_str())) { std::ostringstream oss; config::OstreamConfigWriter writer(oss); @@ -103,12 +103,11 @@ SummarySetup(const vespalib::string & baseDir, const DocTypeName & docTypeName, baseDir.c_str(), oss.str().c_str())); } - _juniperConfig.reset(new juniper::Juniper(&_juniperProps, &_wordFolder)); - _docsumWriter.reset(new DynamicDocsumWriter(resultConfig.release(), NULL)); + _juniperConfig = std::make_unique<juniper::Juniper>(&_juniperProps, &_wordFolder); + _docsumWriter = std::make_unique<DynamicDocsumWriter>(resultConfig.release(), nullptr); DynamicDocsumConfig dynCfg(this, _docsumWriter.get()); dynCfg.configure(summarymapCfg); - for (size_t i = 0; i < summarymapCfg.override.size(); ++i) { - const SummarymapConfig::Override & o = summarymapCfg.override[i]; + for (const auto & o : summarymapCfg.override) { if (o.command == "dynamicteaser" || o.command == "textextractor") { vespalib::string markupField = o.arguments; if (markupField.empty()) @@ -118,11 +117,11 @@ SummarySetup(const vespalib::string & baseDir, const DocTypeName & docTypeName, } } const DocumentType *docType = repo->getDocumentType(docTypeName.getName()); - if (docType != NULL) { - _fieldCacheRepo.reset(new FieldCacheRepo(getResultConfig(), *docType)); + if (docType != nullptr) { + _fieldCacheRepo = std::make_unique<FieldCacheRepo>(getResultConfig(), *docType); } else if (getResultConfig().GetNumResultClasses() == 0) { LOG(debug, "Create empty field cache repo for document type '%s'", docTypeName.toString().c_str()); - _fieldCacheRepo.reset(new FieldCacheRepo()); + _fieldCacheRepo = std::make_unique<FieldCacheRepo>(); } else { throw IllegalArgumentException(make_string("Did not find document type '%s' in current document type repo." " Cannot setup field cache repo for the summary setup", @@ -212,7 +211,7 @@ IFlushTarget::List SummaryManager::getFlushTargets(searchcorespi::index::IThread } void SummaryManager::reconfigure(const LogDocumentStore::Config & config) { - LogDocumentStore & docStore = dynamic_cast<LogDocumentStore &> (*_docStore); + auto & docStore = dynamic_cast<LogDocumentStore &> (*_docStore); docStore.reconfigure(config); } diff --git a/searchsummary/src/tests/docsumformat/docsum-pack.cpp b/searchsummary/src/tests/docsumformat/docsum-pack.cpp index 7a9834e3fd8..18b38db3fa1 100644 --- a/searchsummary/src/tests/docsumformat/docsum-pack.cpp +++ b/searchsummary/src/tests/docsumformat/docsum-pack.cpp @@ -10,7 +10,6 @@ LOG_SETUP("docsum-pack"); using namespace search::docsummary; - // needed to resolve external symbol from httpd.h on AIX void FastS_block_usr2() {} @@ -20,8 +19,8 @@ class MyApp : public FastOS_Application private: bool _rc; uint32_t _cnt; - search::docsummary::ResultConfig _config; - search::docsummary::ResultPacker _packer; + ResultConfig _config; + ResultPacker _packer; public: MyApp(); @@ -33,33 +32,18 @@ public: { ReportTestResult(line, rc); return rc; } // compare runtime info (,but ignore result class) - bool Equal(search::docsummary::ResEntry *a, search::docsummary::ResEntry *b); - bool Equal(search::docsummary::GeneralResult *a, search::docsummary::GeneralResult *b); - - void TestFieldIndex(uint32_t line, search::docsummary::GeneralResult *gres, - const char *field, int idx); - - void TestIntValue(uint32_t line, search::docsummary::GeneralResult *gres, - const char *field, uint32_t value); - - void TestDoubleValue(uint32_t line, search::docsummary::GeneralResult *gres, - const char *field, double value); + bool Equal(ResEntry *a, ResEntry *b); + bool Equal(GeneralResult *a, GeneralResult *b); - void TestInt64Value(uint32_t line, search::docsummary::GeneralResult *gres, - const char *field, uint64_t value); + void TestIntValue(uint32_t line, GeneralResult *gres, const char *field, uint32_t value); + void TestDoubleValue(uint32_t line, GeneralResult *gres, const char *field, double value); + void TestInt64Value(uint32_t line, GeneralResult *gres, const char *field, uint64_t value); + void TestStringValue(uint32_t line, GeneralResult *gres, const char *field, const char *value); + void TestDataValue(uint32_t line, GeneralResult *gres, const char *field, const char *value); - void TestStringValue(uint32_t line, search::docsummary::GeneralResult *gres, - const char *field, const char *value); - - void TestDataValue(uint32_t line, search::docsummary::GeneralResult *gres, - const char *field, const char *value); - - void TestBasic(); void TestFailLong(); void TestFailShort(); void TestFailOrder(); - void TestCompress(); - void TestCompat(); void TestBasicInplace(); void TestCompressInplace(); @@ -72,7 +56,8 @@ MyApp::MyApp() _config(), _packer(&_config) {} -MyApp::~MyApp() {} + +MyApp::~MyApp() = default; void MyApp::ReportTestResult(uint32_t line, bool rc) @@ -89,7 +74,7 @@ MyApp::ReportTestResult(uint32_t line, bool rc) bool -MyApp::Equal(search::docsummary::ResEntry *a, search::docsummary::ResEntry *b) +MyApp::Equal(ResEntry *a, ResEntry *b) { if (a->_type != b->_type) return false; @@ -106,7 +91,7 @@ MyApp::Equal(search::docsummary::ResEntry *a, search::docsummary::ResEntry *b) bool -MyApp::Equal(search::docsummary::GeneralResult *a, search::docsummary::GeneralResult *b) +MyApp::Equal(GeneralResult *a, GeneralResult *b) { uint32_t numEntries = a->GetClass()->GetNumEntries(); @@ -125,56 +110,36 @@ MyApp::Equal(search::docsummary::GeneralResult *a, search::docsummary::GeneralRe return true; } - -void -MyApp::TestFieldIndex(uint32_t line, search::docsummary::GeneralResult *gres, - const char *field, int idx) -{ - bool rc = (gres != NULL && - gres->GetClass()->GetIndexFromName(field) == idx); - - RTR(line, rc); -} - - void -MyApp::TestIntValue(uint32_t line, search::docsummary::GeneralResult *gres, - const char *field, uint32_t value) +MyApp::TestIntValue(uint32_t line, GeneralResult *gres, const char *field, uint32_t value) { - search::docsummary::ResEntry *entry - = (gres != NULL) ? gres->GetEntry(field) : NULL; + ResEntry *entry = (gres != nullptr) ? gres->GetEntry(field) : nullptr; - bool rc = (entry != NULL && + bool rc = (entry != nullptr && entry->_type == RES_INT && entry->_intval == value); RTR(line, rc); } - void -MyApp::TestDoubleValue(uint32_t line, search::docsummary::GeneralResult *gres, - const char *field, double value) +MyApp::TestDoubleValue(uint32_t line, GeneralResult *gres, const char *field, double value) { - search::docsummary::ResEntry *entry - = (gres != NULL) ? gres->GetEntry(field) : NULL; + ResEntry *entry = (gres != nullptr) ? gres->GetEntry(field) : nullptr; - bool rc = (entry != NULL && + bool rc = (entry != nullptr && entry->_type == RES_DOUBLE && entry->_doubleval == value); RTR(line, rc); } - void -MyApp::TestInt64Value(uint32_t line, search::docsummary::GeneralResult *gres, - const char *field, uint64_t value) +MyApp::TestInt64Value(uint32_t line, GeneralResult *gres, const char *field, uint64_t value) { - search::docsummary::ResEntry *entry - = (gres != NULL) ? gres->GetEntry(field) : NULL; + ResEntry *entry = (gres != nullptr) ? gres->GetEntry(field) : nullptr; - bool rc = (entry != NULL && + bool rc = (entry != nullptr && entry->_type == RES_INT64 && entry->_int64val == value); @@ -183,36 +148,29 @@ MyApp::TestInt64Value(uint32_t line, search::docsummary::GeneralResult *gres, void -MyApp::TestStringValue(uint32_t line, search::docsummary::GeneralResult *gres, - const char *field, const char *value) +MyApp::TestStringValue(uint32_t line, GeneralResult *gres, const char *field, const char *value) { - search::docsummary::ResEntry *entry - = (gres != NULL) ? gres->GetEntry(field) : NULL; + ResEntry *entry = (gres != nullptr) ? gres->GetEntry(field) : nullptr; - bool rc = (entry != NULL && + bool rc = (entry != nullptr && entry->_type == RES_STRING && entry->_stringlen == strlen(value) && strncmp(entry->_stringval, value, entry->_stringlen) == 0); - if (!rc && entry != NULL) { - LOG(warning, - "string value '%.*s' != '%s'", - (int) entry->_stringlen, - entry->_stringval, value); + if (!rc && entry != nullptr) { + LOG(warning,"string value '%.*s' != '%s'", + (int) entry->_stringlen, entry->_stringval, value); } RTR(line, rc); } - void -MyApp::TestDataValue(uint32_t line, search::docsummary::GeneralResult *gres, - const char *field, const char *value) +MyApp::TestDataValue(uint32_t line, GeneralResult *gres, const char *field, const char *value) { - search::docsummary::ResEntry *entry - = (gres != NULL) ? gres->GetEntry(field) : NULL; + ResEntry *entry = (gres != nullptr) ? gres->GetEntry(field) : nullptr; - bool rc = (entry != NULL && + bool rc = (entry != nullptr && entry->_type == RES_DATA && entry->_datalen == strlen(value) && strncmp(entry->_dataval, value, entry->_datalen) == 0); @@ -220,62 +178,6 @@ MyApp::TestDataValue(uint32_t line, search::docsummary::GeneralResult *gres, RTR(line, rc); } - -void -MyApp::TestBasic() -{ - const char *buf; - uint32_t buflen; - - search::docsummary::urlresult *res; - search::docsummary::GeneralResult *gres; - - uint32_t intval = 4; - uint16_t shortval = 2; - uint8_t byteval = 1; - float floatval = 4.5; - double doubleval = 8.75; - uint64_t int64val = 8; - const char *strval = "This is a string"; - const char *datval = "This is data"; - const char *lstrval = "This is a long string"; - const char *ldatval = "This is long data"; - - RTR(__LINE__, _packer.Init(0)); - RTR(__LINE__, _packer.AddInteger(intval)); - RTR(__LINE__, _packer.AddShort(shortval)); - RTR(__LINE__, _packer.AddByte(byteval)); - RTR(__LINE__, _packer.AddFloat(floatval)); - RTR(__LINE__, _packer.AddDouble(doubleval)); - RTR(__LINE__, _packer.AddInt64(int64val)); - RTR(__LINE__, _packer.AddString(strval, strlen(strval))); - RTR(__LINE__, _packer.AddData(datval, strlen(datval))); - RTR(__LINE__, _packer.AddLongString(lstrval, strlen(lstrval))); - RTR(__LINE__, _packer.AddLongData(ldatval, strlen(ldatval))); - RTR(__LINE__, _packer.GetDocsumBlob(&buf, &buflen)); - - res = _config.Unpack(0, 0, 0, buf, buflen); - gres = res->IsGeneral() ? (search::docsummary::GeneralResult *) res : NULL; - - RTR(__LINE__, gres != NULL); - TestIntValue (__LINE__, gres, "integer", 4); - TestIntValue (__LINE__, gres, "short", 2); - TestIntValue (__LINE__, gres, "byte", 1); - TestDoubleValue(__LINE__, gres, "float", floatval); - TestDoubleValue(__LINE__, gres, "double", doubleval); - TestInt64Value (__LINE__, gres, "int64", int64val); - TestStringValue(__LINE__, gres, "string", strval); - TestDataValue (__LINE__, gres, "data", datval); - TestStringValue(__LINE__, gres, "longstring", lstrval); - TestDataValue (__LINE__, gres, "longdata", ldatval); - RTR(__LINE__, (gres != NULL && - gres->GetClass()->GetNumEntries() == 10)); - RTR(__LINE__, (gres != NULL && - gres->GetClass()->GetClassID() == 0)); - delete res; -} - - void MyApp::TestFailLong() { @@ -308,7 +210,6 @@ MyApp::TestFailLong() RTR(__LINE__, !_packer.GetDocsumBlob(&buf, &buflen)); } - void MyApp::TestFailShort() { @@ -371,95 +272,6 @@ MyApp::TestFailOrder() } -void -MyApp::TestCompress() -{ - const char *buf; - uint32_t buflen; - - search::docsummary::urlresult *res; - search::docsummary::GeneralResult *gres; - - const char *lstrval = "string string string"; - const char *ldatval = "data data data"; - - RTR(__LINE__, _packer.Init(2)); - RTR(__LINE__, _packer.AddLongString(lstrval, strlen(lstrval))); - RTR(__LINE__, _packer.AddLongData(ldatval, strlen(ldatval))); - RTR(__LINE__, _packer.GetDocsumBlob(&buf, &buflen)); - - res = _config.Unpack(0, 0, 0, buf, buflen); - gres = res->IsGeneral() ? (search::docsummary::GeneralResult *) res : NULL; - - RTR(__LINE__, gres != NULL); - TestStringValue(__LINE__, gres, "text", lstrval); - TestDataValue (__LINE__, gres, "data", ldatval); - RTR(__LINE__, (gres != NULL && - gres->GetClass()->GetNumEntries() == 2)); - RTR(__LINE__, (gres != NULL && - gres->GetClass()->GetClassID() == 2)); - delete res; -} - - -void -MyApp::TestCompat() -{ - const char *buf; - uint32_t buflen; - - search::docsummary::urlresult *res1; - search::docsummary::GeneralResult *gres1; - - search::docsummary::urlresult *res2; - search::docsummary::GeneralResult *gres2; - - const char *strval = "string string string string"; - const char *datval = "data data data data"; - - RTR(__LINE__, _packer.Init(1)); - RTR(__LINE__, _packer.AddData(strval, strlen(strval))); - RTR(__LINE__, _packer.AddString(datval, strlen(datval))); - RTR(__LINE__, _packer.GetDocsumBlob(&buf, &buflen)); - res1 = _config.Unpack(0, 0, 0, buf, buflen); - gres1 = res1->IsGeneral() ? (search::docsummary::GeneralResult *) res1 : NULL; - - RTR(__LINE__, _packer.Init(2)); - RTR(__LINE__, _packer.AddLongData(strval, strlen(strval))); - RTR(__LINE__, _packer.AddLongString(datval, strlen(datval))); - RTR(__LINE__, _packer.GetDocsumBlob(&buf, &buflen)); - res2 = _config.Unpack(0, 0, 0, buf, buflen); - gres2 = res2->IsGeneral() ? (search::docsummary::GeneralResult *) res2 : NULL; - - RTR(__LINE__, gres1 != NULL); - RTR(__LINE__, gres2 != NULL); - - TestStringValue(__LINE__, gres1, "text", strval); - TestDataValue (__LINE__, gres1, "data", datval); - TestFieldIndex (__LINE__, gres1, "text", 0); - TestFieldIndex (__LINE__, gres1, "data", 1); - RTR(__LINE__, (gres1 != NULL && - gres1->GetClass()->GetNumEntries() == 2)); - - TestStringValue(__LINE__, gres2, "text", strval); - TestDataValue (__LINE__, gres2, "data", datval); - TestFieldIndex (__LINE__, gres2, "text", 0); - TestFieldIndex (__LINE__, gres2, "data", 1); - RTR(__LINE__, (gres2 != NULL && - gres2->GetClass()->GetNumEntries() == 2)); - - RTR(__LINE__, (gres1 != NULL && - gres1->GetClass()->GetClassID() == 1)); - RTR(__LINE__, (gres2 != NULL && - gres2->GetClass()->GetClassID() == 2)); - - RTR(__LINE__, (gres1 != NULL && gres2 != NULL && - Equal(gres1, gres2))); - - delete res1; - delete res2; -} - void MyApp::TestBasicInplace() @@ -467,8 +279,8 @@ MyApp::TestBasicInplace() const char *buf; uint32_t buflen; - const search::docsummary::ResultClass *resClass; - search::docsummary::GeneralResult *gres; + const ResultClass *resClass; + GeneralResult *gres; uint32_t intval = 4; uint16_t shortval = 2; @@ -495,18 +307,18 @@ MyApp::TestBasicInplace() RTR(__LINE__, _packer.GetDocsumBlob(&buf, &buflen)); resClass = _config.LookupResultClass(_config.GetClassID(buf, buflen)); - if (resClass == NULL) { - gres = NULL; + if (resClass == nullptr) { + gres = nullptr; } else { DocsumStoreValue value(buf, buflen); - gres = new search::docsummary::GeneralResult(resClass, 0, 0, 0); + gres = new GeneralResult(resClass); if (!gres->inplaceUnpack(value)) { delete gres; - gres = NULL; + gres = nullptr; } } - RTR(__LINE__, gres != NULL); + RTR(__LINE__, gres != nullptr); TestIntValue (__LINE__, gres, "integer", 4); TestIntValue (__LINE__, gres, "short", 2); TestIntValue (__LINE__, gres, "byte", 1); @@ -517,9 +329,9 @@ MyApp::TestBasicInplace() TestDataValue (__LINE__, gres, "data", datval); TestStringValue(__LINE__, gres, "longstring", lstrval); TestDataValue (__LINE__, gres, "longdata", ldatval); - RTR(__LINE__, (gres != NULL && + RTR(__LINE__, (gres != nullptr && gres->GetClass()->GetNumEntries() == 10)); - RTR(__LINE__, (gres != NULL && + RTR(__LINE__, (gres != nullptr && gres->GetClass()->GetClassID() == 0)); delete gres; } @@ -533,8 +345,8 @@ MyApp::TestCompressInplace() search::RawBuf field1(32768); search::RawBuf field2(32768); - const search::docsummary::ResultClass *resClass; - search::docsummary::GeneralResult *gres; + const ResultClass *resClass; + GeneralResult *gres; const char *lstrval = "string string string"; const char *ldatval = "data data data"; @@ -545,48 +357,46 @@ MyApp::TestCompressInplace() RTR(__LINE__, _packer.GetDocsumBlob(&buf, &buflen)); resClass = _config.LookupResultClass(_config.GetClassID(buf, buflen)); - if (resClass == NULL) { - gres = NULL; + if (resClass == nullptr) { + gres = nullptr; } else { DocsumStoreValue value(buf, buflen); - gres = new search::docsummary::GeneralResult(resClass, 0, 0, 0); + gres = new GeneralResult(resClass); if (!gres->inplaceUnpack(value)) { delete gres; - gres = NULL; + gres = nullptr; } } - search::docsummary::ResEntry *e1 = (gres == NULL) ? NULL : gres->GetEntry("text"); - search::docsummary::ResEntry *e2 = (gres == NULL) ? NULL : gres->GetEntry("data"); + ResEntry *e1 = (gres == nullptr) ? nullptr : gres->GetEntry("text"); + ResEntry *e2 = (gres == nullptr) ? nullptr : gres->GetEntry("data"); - if (e1 != NULL) + if (e1 != nullptr) e1->_extract_field(&field1); - if (e2 != NULL) + if (e2 != nullptr) e2->_extract_field(&field2); - RTR(__LINE__, gres != NULL); - RTR(__LINE__, e1 != NULL); - RTR(__LINE__, e2 != NULL); + RTR(__LINE__, gres != nullptr); + RTR(__LINE__, e1 != nullptr); + RTR(__LINE__, e2 != nullptr); RTR(__LINE__, strcmp(field1.GetDrainPos(), lstrval) == 0); RTR(__LINE__, strcmp(field2.GetDrainPos(), ldatval) == 0); RTR(__LINE__, strlen(lstrval) == field1.GetUsedLen()); RTR(__LINE__, strlen(ldatval) == field2.GetUsedLen()); - RTR(__LINE__, (gres != NULL && + RTR(__LINE__, (gres != nullptr && gres->GetClass()->GetNumEntries() == 2)); - RTR(__LINE__, (gres != NULL && + RTR(__LINE__, (gres != nullptr && gres->GetClass()->GetClassID() == 2)); delete gres; } - - int MyApp::Main() { _rc = true; _cnt = 0; - search::docsummary::ResultClass *resClass; + ResultClass *resClass; resClass = _config.AddResultClass("c0", 0); resClass->AddConfigEntry("integer", RES_INT); @@ -608,12 +418,9 @@ MyApp::Main() resClass->AddConfigEntry("text", RES_LONG_STRING); resClass->AddConfigEntry("data", RES_LONG_DATA); - TestBasic(); TestFailLong(); TestFailShort(); TestFailOrder(); - TestCompress(); - TestCompat(); TestBasicInplace(); TestCompressInplace(); @@ -621,7 +428,6 @@ MyApp::Main() return (_rc ? 0 : 1); } - int main(int argc, char **argv) { diff --git a/searchsummary/src/tests/docsummary/positionsdfw_test.cpp b/searchsummary/src/tests/docsummary/positionsdfw_test.cpp index 7497a66d138..764ff4723cb 100644 --- a/searchsummary/src/tests/docsummary/positionsdfw_test.cpp +++ b/searchsummary/src/tests/docsummary/positionsdfw_test.cpp @@ -24,8 +24,7 @@ using search::attribute::IAttributeFunctor; using vespalib::string; using std::vector; -namespace search { -namespace docsummary { +namespace search::docsummary { namespace { @@ -136,7 +135,7 @@ void checkWritePositionField(Test &test, AttrType &attr, vespalib::Slime target; vespalib::slime::SlimeInserter inserter(target); - writer->insertField(doc_id, nullptr, &state, res_type, inserter); + writer->insertField(doc_id, &state, res_type, inserter); vespalib::Memory got = target.get().asString(); test.EXPECT_EQUAL(expected.size(), got.size); @@ -154,7 +153,6 @@ void Test::requireThat2DPositionFieldIsWritten() { } } // namespace -} // namespace docsummary -} // namespace search +} TEST_APPHOOK(search::docsummary::Test); diff --git a/searchsummary/src/vespa/searchsummary/docsummary/attribute_combiner_dfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/attribute_combiner_dfw.cpp index 015eb70c74a..153bcea886f 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/attribute_combiner_dfw.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/attribute_combiner_dfw.cpp @@ -90,7 +90,7 @@ StructFields::~StructFields() = default; } AttributeCombinerDFW::AttributeCombinerDFW(const vespalib::string &fieldName) - : IDocsumFieldWriter(), + : IDocsumFW(), _stateIndex(0), _fieldName(fieldName) { @@ -124,11 +124,7 @@ AttributeCombinerDFW::create(const vespalib::string &fieldName, IAttributeManage } void -AttributeCombinerDFW::insertField(uint32_t docid, - GeneralResult *, - GetDocsumsState *state, - ResType, - vespalib::slime::Inserter &target) +AttributeCombinerDFW::insertField(uint32_t docid, GetDocsumsState *state, ResType, vespalib::slime::Inserter &target) { auto &fieldWriterState = state->_fieldWriterStates[_stateIndex]; if (!fieldWriterState) { diff --git a/searchsummary/src/vespa/searchsummary/docsummary/attribute_combiner_dfw.h b/searchsummary/src/vespa/searchsummary/docsummary/attribute_combiner_dfw.h index ef54522a923..e58b0f740bf 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/attribute_combiner_dfw.h +++ b/searchsummary/src/vespa/searchsummary/docsummary/attribute_combiner_dfw.h @@ -15,7 +15,7 @@ class DynamicDocsumWriter; * This class reads values from multiple struct field attributes and * inserts them as an array of struct or a map of struct. */ -class AttributeCombinerDFW : public IDocsumFieldWriter +class AttributeCombinerDFW : public IDocsumFW { protected: uint32_t _stateIndex; @@ -28,8 +28,7 @@ public: bool IsGenerated() const override; bool setFieldWriterStateIndex(uint32_t fieldWriterStateIndex) override; static std::unique_ptr<IDocsumFieldWriter> create(const vespalib::string &fieldName, IAttributeManager &attrMgr); - void insertField(uint32_t docid, GeneralResult *gres, GetDocsumsState *state, - ResType type, vespalib::slime::Inserter &target) override; + void insertField(uint32_t docid, GetDocsumsState *state, ResType type, vespalib::slime::Inserter &target) override; }; } diff --git a/searchsummary/src/vespa/searchsummary/docsummary/attributedfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/attributedfw.cpp index ee2e9d9fa92..19dd096c46c 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/attributedfw.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/attributedfw.cpp @@ -21,6 +21,7 @@ using namespace search; using search::attribute::IAttributeContext; using search::attribute::IAttributeVector; using search::attribute::BasicType; +using vespalib::slime::Inserter; namespace search::docsummary { @@ -42,12 +43,8 @@ public: SingleAttrDFW(const vespalib::string & attrName) : AttrDFW(attrName) { } - virtual void insertField(uint32_t docid, - GeneralResult *gres, - GetDocsumsState *state, - ResType type, - vespalib::slime::Inserter &target) override; - virtual bool isDefaultValue(uint32_t docid, const GetDocsumsState * state) const override; + void insertField(uint32_t docid, GetDocsumsState *state, ResType type, Inserter &target) override; + bool isDefaultValue(uint32_t docid, const GetDocsumsState * state) const override; }; bool SingleAttrDFW::isDefaultValue(uint32_t docid, const GetDocsumsState * state) const @@ -56,11 +53,7 @@ bool SingleAttrDFW::isDefaultValue(uint32_t docid, const GetDocsumsState * state } void -SingleAttrDFW::insertField(uint32_t docid, - GeneralResult *, - GetDocsumsState * state, - ResType type, - vespalib::slime::Inserter &target) +SingleAttrDFW::insertField(uint32_t docid, GetDocsumsState * state, ResType type, Inserter &target) { const char *s=""; const IAttributeVector & v = vec(*state); @@ -80,6 +73,11 @@ SingleAttrDFW::insertField(uint32_t docid, target.insertLong(val); break; } + case RES_BOOL: { + uint8_t val = v.getInt(docid); + target.insertBool(val != 0); + break; + } case RES_FLOAT: { float val = v.getFloat(docid); target.insertDouble(val); @@ -141,20 +139,12 @@ class MultiAttrDFW : public AttrDFW { public: MultiAttrDFW(const vespalib::string & attrName) : AttrDFW(attrName) {} - virtual void insertField(uint32_t docid, - GeneralResult *gres, - GetDocsumsState *state, - ResType type, - vespalib::slime::Inserter &target) override; + void insertField(uint32_t docid, GetDocsumsState *state, ResType type, Inserter &target) override; }; void -MultiAttrDFW::insertField(uint32_t docid, - GeneralResult *, - GetDocsumsState *state, - ResType, - vespalib::slime::Inserter &target) +MultiAttrDFW::insertField(uint32_t docid, GetDocsumsState *state, ResType, Inserter &target) { using vespalib::slime::Cursor; using vespalib::Memory; diff --git a/searchsummary/src/vespa/searchsummary/docsummary/attributedfw.h b/searchsummary/src/vespa/searchsummary/docsummary/attributedfw.h index 643170663b8..d8102734452 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/attributedfw.h +++ b/searchsummary/src/vespa/searchsummary/docsummary/attributedfw.h @@ -8,7 +8,7 @@ namespace search::attribute { class IAttributeVector; } namespace search::docsummary { -class AttrDFW : public IDocsumFieldWriter +class AttrDFW : public IDocsumFW { private: vespalib::string _attrName; diff --git a/searchsummary/src/vespa/searchsummary/docsummary/docsumfieldwriter.cpp b/searchsummary/src/vespa/searchsummary/docsummary/docsumfieldwriter.cpp index 18e7e471663..f24f5841bd2 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/docsumfieldwriter.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/docsumfieldwriter.cpp @@ -29,22 +29,16 @@ IDocsumFieldWriter::setFieldWriterStateIndex(uint32_t) //-------------------------------------------------------------------------- -EmptyDFW::EmptyDFW() { } +EmptyDFW::EmptyDFW() = default; - -EmptyDFW::~EmptyDFW() { } +EmptyDFW::~EmptyDFW() = default; void -EmptyDFW::insertField(uint32_t /*docid*/, - GeneralResult *, - GetDocsumsState *, - ResType, - vespalib::slime::Inserter &target) +EmptyDFW::insertField(uint32_t, GetDocsumsState *, ResType, vespalib::slime::Inserter &target) { // insert explicitly-empty field? // target.insertNix(); (void)target; - return; } //-------------------------------------------------------------------------- @@ -54,11 +48,7 @@ CopyDFW::CopyDFW() { } - -CopyDFW::~CopyDFW() -{ -} - +CopyDFW::~CopyDFW() = default; bool CopyDFW::Init(const ResultConfig & config, const char *inputField) @@ -69,11 +59,10 @@ CopyDFW::Init(const ResultConfig & config, const char *inputField) LOG(warning, "no docsum format contains field '%s'; copied fields will be empty", inputField); } - for (ResultConfig::const_iterator it(config.begin()), mt(config.end()); it != mt; it++) { - const ResConfigEntry *entry = - it->GetEntry(it->GetIndexFromEnumValue(_inputFieldEnumValue)); + for (const auto & field : config) { + const ResConfigEntry *entry = field.GetEntry(field.GetIndexFromEnumValue(_inputFieldEnumValue)); - if (entry != NULL && + if (entry != nullptr && !IsRuntimeCompatible(entry->_type, RES_INT) && !IsRuntimeCompatible(entry->_type, RES_DOUBLE) && !IsRuntimeCompatible(entry->_type, RES_INT64) && @@ -81,25 +70,21 @@ CopyDFW::Init(const ResultConfig & config, const char *inputField) !IsRuntimeCompatible(entry->_type, RES_DATA)) { LOG(warning, "cannot use docsum field '%s' as input to copy; type conflict with result class %d (%s)", - inputField, it->GetClassID(), it->GetClassName()); + inputField, field.GetClassID(), field.GetClassName()); return false; } } return true; } - void -CopyDFW::insertField(uint32_t /*docid*/, - GeneralResult *gres, - GetDocsumsState *state, - ResType type, - vespalib::slime::Inserter &target) +CopyDFW::insertField(uint32_t /*docid*/, GeneralResult *gres, GetDocsumsState *state, ResType type, + vespalib::slime::Inserter &target) { int idx = gres->GetClass()->GetIndexFromEnumValue(_inputFieldEnumValue); ResEntry *entry = gres->GetEntry(idx); - if (entry != NULL && + if (entry != nullptr && IsRuntimeCompatible(entry->_type, type)) { switch (type) { @@ -117,6 +102,9 @@ CopyDFW::insertField(uint32_t /*docid*/, uint8_t val8 = entry->_intval; target.insertLong(val8); break; } + case RES_BOOL: { + target.insertBool(entry->_intval != 0); + break; } case RES_FLOAT: { float valfloat = entry->_doubleval; diff --git a/searchsummary/src/vespa/searchsummary/docsummary/docsumfieldwriter.h b/searchsummary/src/vespa/searchsummary/docsummary/docsumfieldwriter.h index 51079f7736e..870e4fa8d83 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/docsumfieldwriter.h +++ b/searchsummary/src/vespa/searchsummary/docsummary/docsumfieldwriter.h @@ -16,7 +16,7 @@ class GetDocsumsState; class IDocsumFieldWriter { public: - typedef std::unique_ptr<IDocsumFieldWriter> UP; + using UP = std::unique_ptr<IDocsumFieldWriter>; IDocsumFieldWriter() : _index(0) { } virtual ~IDocsumFieldWriter() {} @@ -27,10 +27,7 @@ public: { return ResultConfig::IsRuntimeCompatible(a, b); } virtual bool IsGenerated() const = 0; - virtual void insertField(uint32_t docid, - GeneralResult *gres, - GetDocsumsState *state, - ResType type, + virtual void insertField(uint32_t docid, GeneralResult *gres, GetDocsumsState *state, ResType type, vespalib::slime::Inserter &target) = 0; virtual const vespalib::string & getAttributeName() const { return _empty; } virtual bool isDefaultValue(uint32_t docid, const GetDocsumsState * state) const { @@ -46,20 +43,27 @@ private: static const vespalib::string _empty; }; +class IDocsumFW : public IDocsumFieldWriter +{ +public: + virtual void insertField(uint32_t docid, GetDocsumsState *state, ResType type, vespalib::slime::Inserter &target) = 0; + void insertField(uint32_t docid, GeneralResult *, GetDocsumsState *state, ResType type, + vespalib::slime::Inserter &target) override + { + insertField(docid, state, type, target); + } +}; + //-------------------------------------------------------------------------- -class EmptyDFW : public IDocsumFieldWriter +class EmptyDFW : public IDocsumFW { public: EmptyDFW(); - virtual ~EmptyDFW(); - - virtual bool IsGenerated() const override { return true; } - virtual void insertField(uint32_t docid, - GeneralResult *gres, - GetDocsumsState *state, - ResType type, - vespalib::slime::Inserter &target) override; + ~EmptyDFW() override; + + bool IsGenerated() const override { return true; } + void insertField(uint32_t docid, GetDocsumsState *state, ResType type, vespalib::slime::Inserter &target) override; }; //-------------------------------------------------------------------------- @@ -71,16 +75,13 @@ private: public: CopyDFW(); - virtual ~CopyDFW(); + ~CopyDFW() override; bool Init(const ResultConfig & config, const char *inputField); - virtual bool IsGenerated() const override { return false; } - virtual void insertField(uint32_t docid, - GeneralResult *gres, - GetDocsumsState *state, - ResType type, - vespalib::slime::Inserter &target) override; + bool IsGenerated() const override { return false; } + void insertField(uint32_t docid, GeneralResult *gres, GetDocsumsState *state, ResType type, + vespalib::slime::Inserter &target) override; }; //-------------------------------------------------------------------------- diff --git a/searchsummary/src/vespa/searchsummary/docsummary/docsumwriter.cpp b/searchsummary/src/vespa/searchsummary/docsummary/docsumwriter.cpp index 722ea9d9000..a188ab6e60a 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/docsumwriter.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/docsumwriter.cpp @@ -78,23 +78,23 @@ DynamicDocsumWriter::resolveInputClass(ResolveClassInfo &rci, uint32_t id) const } } -static void convertEntry(GetDocsumsState *state, - const ResConfigEntry *resCfg, - const ResEntry *entry, - Inserter &inserter, - Slime &slime) +static void convertEntry(GetDocsumsState *state, const ResConfigEntry *resCfg, const ResEntry *entry, + Inserter &inserter, Slime &slime) { using vespalib::slime::BinaryFormat; const char *ptr; uint32_t len; - LOG_ASSERT(resCfg != 0 && entry != 0); + LOG_ASSERT(resCfg != nullptr && entry != nullptr); switch (resCfg->_type) { case RES_INT: case RES_SHORT: case RES_BYTE: inserter.insertLong(entry->_intval); break; + case RES_BOOL: + inserter.insertBool(entry->_intval != 0); + break; case RES_FLOAT: case RES_DOUBLE: inserter.insertDouble(entry->_doubleval); @@ -130,12 +130,8 @@ static void convertEntry(GetDocsumsState *state, void -DynamicDocsumWriter::insertDocsum(const ResolveClassInfo & rci, - uint32_t docid, - GetDocsumsState *state, - IDocsumStore *docinfos, - vespalib::Slime & slime, - vespalib::slime::Inserter & topInserter) +DynamicDocsumWriter::insertDocsum(const ResolveClassInfo & rci, uint32_t docid, GetDocsumsState *state, + IDocsumStore *docinfos, vespalib::Slime & slime, vespalib::slime::Inserter & topInserter) { if (rci.allGenerated) { // generate docsum entry on-the-fly @@ -144,8 +140,7 @@ DynamicDocsumWriter::insertDocsum(const ResolveClassInfo & rci, const ResConfigEntry *resCfg = rci.outputClass->GetEntry(i); IDocsumFieldWriter *writer = _overrideTable[resCfg->_enumValue]; if (! writer->isDefaultValue(docid, state)) { - const Memory field_name(resCfg->_bindname.data(), - resCfg->_bindname.size()); + const Memory field_name(resCfg->_bindname.data(), resCfg->_bindname.size()); ObjectInserter inserter(docsum, field_name); writer->insertField(docid, nullptr, state, resCfg->_type, inserter); } @@ -154,7 +149,7 @@ DynamicDocsumWriter::insertDocsum(const ResolveClassInfo & rci, // look up docsum entry DocsumStoreValue value = docinfos->getMappedDocsum(docid); // re-pack docsum blob - GeneralResult gres(rci.inputClass, 0, docid, 0); + GeneralResult gres(rci.inputClass); if (! gres.inplaceUnpack(value)) { LOG(debug, "Unpack failed: illegal docsum entry for document %d. This is expected during lidspace compaction.", docid); topInserter.insertNix(); @@ -272,10 +267,10 @@ DynamicDocsumWriter::Override(const char *fieldName, IDocsumFieldWriter *writer) ++_numFieldWriterStates; } - for (ResultConfig::iterator it(_resultConfig->begin()), mt(_resultConfig->end()); it != mt; it++) { + for (auto & entry : *_resultConfig) { - if (it->GetIndexFromEnumValue(fieldEnumValue) >= 0) { - ResultClass::DynamicInfo *info = it->getDynamicInfo(); + if (entry.GetIndexFromEnumValue(fieldEnumValue) >= 0) { + ResultClass::DynamicInfo *info = entry.getDynamicInfo(); info->_overrideCnt++; if (writer->IsGenerated()) info->_generateCnt++; @@ -306,15 +301,11 @@ DynamicDocsumWriter::InitState(IAttributeManager & attrMan, GetDocsumsState *sta uint32_t -DynamicDocsumWriter::WriteDocsum(uint32_t docid, - GetDocsumsState *state, - IDocsumStore *docinfos, - search::RawBuf *target) +DynamicDocsumWriter::WriteDocsum(uint32_t docid, GetDocsumsState *state, IDocsumStore *docinfos, search::RawBuf *target) { vespalib::Slime slime; vespalib::slime::SlimeInserter inserter(slime); - ResolveClassInfo rci = resolveClassInfo(state->_args.getResultClassName(), - docinfos->getSummaryClassId()); + ResolveClassInfo rci = resolveClassInfo(state->_args.getResultClassName(), docinfos->getSummaryClassId()); insertDocsum(rci, docid, state, docinfos, slime, inserter); return slime2RawBuf(slime, *target); } diff --git a/searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp index 4112afc1895..b9177ac8782 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp @@ -23,7 +23,7 @@ struct ExplicitItemData uint32_t _weight; ExplicitItemData() - : _index(NULL), _indexlen(0), _term(NULL), _termlen(0), _weight(0) + : _index(nullptr), _indexlen(0), _term(nullptr), _termlen(0), _weight(0) {} ExplicitItemData(const char *index, uint32_t indexlen, const char* term, @@ -43,19 +43,16 @@ struct QueryItem { search::SimpleQueryStackDumpIterator *_si; const ExplicitItemData *_data; - QueryItem() : _si(NULL), _data(NULL) {} - QueryItem(search::SimpleQueryStackDumpIterator *si) : _si(si), _data(NULL) {} - QueryItem(ExplicitItemData *data) : _si(NULL), _data(data) {} + QueryItem() : _si(nullptr), _data(nullptr) {} + QueryItem(search::SimpleQueryStackDumpIterator *si) : _si(si), _data(nullptr) {} + QueryItem(ExplicitItemData *data) : _si(nullptr), _data(data) {} private: QueryItem(const QueryItem&); QueryItem& operator= (const QueryItem&); }; -}; - -namespace search { -class Property; +} -namespace fef { +namespace search::fef { class TermVisitor : public IPropertiesVisitor { public: @@ -104,24 +101,22 @@ TermVisitor::visitProperty(const Property::Value &key, const Property &values) } -namespace docsummary { +namespace search::docsummary { class JuniperQueryAdapter : public juniper::IQuery { private: - JuniperQueryAdapter(const JuniperQueryAdapter&); - JuniperQueryAdapter operator= (const JuniperQueryAdapter&); - KeywordExtractor *_kwExtractor; const vespalib::stringref _buf; const search::fef::Properties *_highlightTerms; juniper::IQueryVisitor *_visitor; public: - JuniperQueryAdapter(KeywordExtractor *kwExtractor, - vespalib::stringref buf, - const search::fef::Properties *highlightTerms = NULL) - : _kwExtractor(kwExtractor), _buf(buf), _highlightTerms(highlightTerms), _visitor(NULL) {} + JuniperQueryAdapter(const JuniperQueryAdapter&) = delete; + JuniperQueryAdapter operator= (const JuniperQueryAdapter&) = delete; + JuniperQueryAdapter(KeywordExtractor *kwExtractor, vespalib::stringref buf, + const search::fef::Properties *highlightTerms = nullptr) + : _kwExtractor(kwExtractor), _buf(buf), _highlightTerms(highlightTerms), _visitor(nullptr) {} // TODO: put this functionality into the stack dump iterator bool SkipItem(search::SimpleQueryStackDumpIterator *iterator) const @@ -136,28 +131,28 @@ public: return true; } - virtual bool Traverse(juniper::IQueryVisitor *v) const override; + bool Traverse(juniper::IQueryVisitor *v) const override; - virtual int Weight(const juniper::QueryItem* item) const override + int Weight(const juniper::QueryItem* item) const override { - if (item->_si != NULL) { + if (item->_si != nullptr) { return item->_si->GetWeight().percent(); } else { return item->_data->_weight; } } - virtual juniper::ItemCreator Creator(const juniper::QueryItem* item) const override + juniper::ItemCreator Creator(const juniper::QueryItem* item) const override { // cast master: Knut Omang - if (item->_si != NULL) { + if (item->_si != nullptr) { return (juniper::ItemCreator) item->_si->getCreator(); } else { return juniper::CREA_ORIG; } } - virtual const char *Index(const juniper::QueryItem* item, size_t *len) const override + const char *Index(const juniper::QueryItem* item, size_t *len) const override { - if (item->_si != NULL) { + if (item->_si != nullptr) { *len = item->_si->getIndexName().size(); return item->_si->getIndexName().data(); } else { @@ -166,14 +161,14 @@ public: } } - virtual bool UsefulIndex(const juniper::QueryItem* item) const override + bool UsefulIndex(const juniper::QueryItem* item) const override { vespalib::stringref index; - if (_kwExtractor == NULL) + if (_kwExtractor == nullptr) return true; - if (item->_si != NULL) { + if (item->_si != nullptr) { index = item->_si->getIndexName(); } else { index = vespalib::stringref(item->_data->_index, item->_data->_indexlen); @@ -182,8 +177,6 @@ public: } }; - - bool JuniperQueryAdapter::Traverse(juniper::IQueryVisitor *v) const { @@ -308,7 +301,7 @@ JuniperDFW::JuniperDFW(juniper::Juniper * juniper) } -JuniperDFW::~JuniperDFW() { } +JuniperDFW::~JuniperDFW() = default; bool JuniperDFW::Init( @@ -319,10 +312,10 @@ JuniperDFW::Init( { bool rc = true; const util::StringEnum & enums(config.GetFieldNameEnum()); - if (langFieldName != NULL) + if (langFieldName != nullptr) _langFieldEnumValue = enums.Lookup(langFieldName); _juniperConfig = _juniper->CreateConfig(fieldName); - if (_juniperConfig.get() == NULL) { + if (_juniperConfig.get() == nullptr) { LOG(warning, "could not create juniper config for field '%s'", fieldName); rc = false; } @@ -350,7 +343,7 @@ JuniperTeaserDFW::Init( const ResConfigEntry *entry = it->GetEntry(it->GetIndexFromEnumValue(_inputFieldEnumValue)); - if (entry != NULL && + if (entry != nullptr && !IsRuntimeCompatible(entry->_type, RES_STRING) && !IsRuntimeCompatible(entry->_type, RES_DATA)) { @@ -363,15 +356,13 @@ JuniperTeaserDFW::Init( } vespalib::string -DynamicTeaserDFW::makeDynamicTeaser(uint32_t docid, - GeneralResult *gres, - GetDocsumsState *state) +DynamicTeaserDFW::makeDynamicTeaser(uint32_t docid, GeneralResult *gres, GetDocsumsState *state) { - if (state->_dynteaser._query == NULL) { + if (state->_dynteaser._query == nullptr) { JuniperQueryAdapter iq(state->_kwExtractor, state->_args.getStackDump(), &state->_args.highlightTerms()); - state->_dynteaser._query = _juniper->CreateQueryHandle(iq, NULL); + state->_dynteaser._query = _juniper->CreateQueryHandle(iq, nullptr); } if (docid != state->_dynteaser._docid || @@ -384,34 +375,31 @@ DynamicTeaserDFW::makeDynamicTeaser(uint32_t docid, _langFieldEnumValue, state->_dynteaser._lang, (juniper::AnalyseCompatible(_juniperConfig.get(), state->_dynteaser._config) ? "no" : "yes")); - if (state->_dynteaser._result != NULL) + if (state->_dynteaser._result != nullptr) juniper::ReleaseResult(state->_dynteaser._result); state->_dynteaser._docid = docid; state->_dynteaser._input = _inputFieldEnumValue; state->_dynteaser._lang = _langFieldEnumValue; state->_dynteaser._config = _juniperConfig.get(); - state->_dynteaser._result = NULL; + state->_dynteaser._result = nullptr; int idx = gres->GetClass()->GetIndexFromEnumValue(_inputFieldEnumValue); ResEntry *entry = gres->GetEntry(idx); - if (entry != NULL && - state->_dynteaser._query != NULL) { + if (entry != nullptr && state->_dynteaser._query != nullptr) { // obtain Juniper input const char *buf; uint32_t buflen; - entry->_resolve_field(&buf, &buflen, - &state->_docSumFieldSpace); + entry->_resolve_field(&buf, &buflen, &state->_docSumFieldSpace); if (LOG_WOULD_LOG(spam)) { std::ostringstream hexDump; hexDump << vespalib::HexDump(buf, buflen); LOG(spam, "makeDynamicTeaser: docid=%d, input='%s', hexdump:\n%s", - docid, std::string(buf, buflen).c_str(), - hexDump.str().c_str()); + docid, std::string(buf, buflen).c_str(), hexDump.str().c_str()); } uint32_t langid = static_cast<uint32_t>(-1); @@ -422,33 +410,29 @@ DynamicTeaserDFW::makeDynamicTeaser(uint32_t docid, } } - juniper::Summary *teaser = (state->_dynteaser._result != NULL) + juniper::Summary *teaser = (state->_dynteaser._result != nullptr) ? juniper::GetTeaser(state->_dynteaser._result, _juniperConfig.get()) - : NULL; + : nullptr; if (LOG_WOULD_LOG(debug)) { std::ostringstream hexDump; - if (teaser != NULL) { + if (teaser != nullptr) { hexDump << vespalib::HexDump(teaser->Text(), teaser->Length()); } LOG(debug, "makeDynamicTeaser: docid=%d, teaser='%s', hexdump:\n%s", - docid, (teaser != NULL ? std::string(teaser->Text(), teaser->Length()).c_str() : "NULL"), + docid, (teaser != nullptr ? std::string(teaser->Text(), teaser->Length()).c_str() : "nullptr"), hexDump.str().c_str()); } - if (teaser != NULL) { - return vespalib::string(teaser->Text(), - teaser->Length()); + if (teaser != nullptr) { + return vespalib::string(teaser->Text(), teaser->Length()); } else { return vespalib::string(); } } void -DynamicTeaserDFW::insertField(uint32_t docid, - GeneralResult *gres, - GetDocsumsState *state, - ResType, +DynamicTeaserDFW::insertField(uint32_t docid, GeneralResult *gres, GetDocsumsState *state, ResType, vespalib::slime::Inserter &target) { vespalib::string teaser = makeDynamicTeaser(docid, gres, state); @@ -456,6 +440,4 @@ DynamicTeaserDFW::insertField(uint32_t docid, target.insertString(value); } -} // namespace docsummary -} // namespace search - +} diff --git a/searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.cpp index bf010172fa9..ae3d6acde43 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.cpp @@ -40,8 +40,7 @@ void fmtZcurve(int64_t zval, vespalib::slime::Inserter &target) } void -GeoPositionDFW::insertField(uint32_t docid, GeneralResult *, GetDocsumsState * dsState, - ResType, vespalib::slime::Inserter &target) +GeoPositionDFW::insertField(uint32_t docid, GetDocsumsState * dsState, ResType, vespalib::slime::Inserter &target) { using vespalib::slime::Cursor; using vespalib::slime::ObjectSymbolInserter; diff --git a/searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.h b/searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.h index 8f630cde3af..9bd85abaf17 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.h +++ b/searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.h @@ -14,8 +14,7 @@ class GeoPositionDFW : public AttrDFW public: typedef std::unique_ptr<GeoPositionDFW> UP; GeoPositionDFW(const vespalib::string & attrName); - void insertField(uint32_t docid, GeneralResult *gres, GetDocsumsState *state, - ResType type, vespalib::slime::Inserter &target) override; + void insertField(uint32_t docid, GetDocsumsState *state, ResType type, vespalib::slime::Inserter &target) override; static UP create(const char *attribute_name, IAttributeManager *attribute_manager); }; diff --git a/searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.cpp index 48e79a5e34c..9c82c00c3ef 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.cpp @@ -66,8 +66,7 @@ AbsDistanceDFW::findMinDistance(uint32_t docid, GetDocsumsState *state) } void -AbsDistanceDFW::insertField(uint32_t docid, GeneralResult *, GetDocsumsState *state, - ResType type, vespalib::slime::Inserter &target) +AbsDistanceDFW::insertField(uint32_t docid, GetDocsumsState *state, ResType type, vespalib::slime::Inserter &target) { bool forceEmpty = true; @@ -166,8 +165,7 @@ formatField(const attribute::IAttributeVector &attribute, uint32_t docid, ResTyp } void -PositionsDFW::insertField(uint32_t docid, GeneralResult *, GetDocsumsState * dsState, - ResType type, vespalib::slime::Inserter &target) +PositionsDFW::insertField(uint32_t docid, GetDocsumsState * dsState, ResType type, vespalib::slime::Inserter &target) { vespalib::asciistream val(formatField(vec(*dsState), docid, type)); target.insertString(vespalib::Memory(val.c_str(), val.size())); @@ -175,8 +173,7 @@ PositionsDFW::insertField(uint32_t docid, GeneralResult *, GetDocsumsState * dsS //-------------------------------------------------------------------------- -PositionsDFW::UP createPositionsDFW(const char *attribute_name, - IAttributeManager *attribute_manager) +PositionsDFW::UP createPositionsDFW(const char *attribute_name, IAttributeManager *attribute_manager) { PositionsDFW::UP ret; if (attribute_manager != nullptr) { @@ -195,12 +192,10 @@ PositionsDFW::UP createPositionsDFW(const char *attribute_name, return ret; } } - ret.reset(new PositionsDFW(attribute_name)); - return ret; + return std::make_unique<PositionsDFW>(attribute_name); } -AbsDistanceDFW::UP createAbsDistanceDFW(const char *attribute_name, - IAttributeManager *attribute_manager) +AbsDistanceDFW::UP createAbsDistanceDFW(const char *attribute_name, IAttributeManager *attribute_manager) { AbsDistanceDFW::UP ret; if (attribute_manager != nullptr) { @@ -219,8 +214,7 @@ AbsDistanceDFW::UP createAbsDistanceDFW(const char *attribute_name, return ret; } } - ret.reset(new AbsDistanceDFW(attribute_name)); - return ret; + return std::make_unique<AbsDistanceDFW>(attribute_name); } } diff --git a/searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.h b/searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.h index 69a7ba3f58f..999da6f1860 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.h +++ b/searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.h @@ -14,7 +14,7 @@ public: AbsDistanceDFW(const vespalib::string & attrName); bool IsGenerated() const override { return true; } - void insertField(uint32_t docid, GeneralResult *gres, GetDocsumsState *state, + void insertField(uint32_t docid, GetDocsumsState *state, ResType type, vespalib::slime::Inserter &target) override; }; @@ -28,8 +28,7 @@ public: PositionsDFW(const vespalib::string & attrName); bool IsGenerated() const override { return true; } - void insertField(uint32_t docid, GeneralResult *gres, GetDocsumsState *state, - ResType type, vespalib::slime::Inserter &target) override ; + void insertField(uint32_t docid, GetDocsumsState *state, ResType type, vespalib::slime::Inserter &target) override; }; PositionsDFW::UP createPositionsDFW(const char *attribute_name, IAttributeManager *index_man); diff --git a/searchsummary/src/vespa/searchsummary/docsummary/rankfeaturesdfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/rankfeaturesdfw.cpp index 9748bdac3b3..a1c96bb3e5b 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/rankfeaturesdfw.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/rankfeaturesdfw.cpp @@ -20,7 +20,7 @@ RankFeaturesDFW::init(IDocsumEnvironment * env) } void -RankFeaturesDFW::insertField(uint32_t docid, GeneralResult *, GetDocsumsState *state, +RankFeaturesDFW::insertField(uint32_t docid, GetDocsumsState *state, ResType type, vespalib::slime::Inserter &target) { if (state->_rankFeatures.get() == nullptr) { diff --git a/searchsummary/src/vespa/searchsummary/docsummary/rankfeaturesdfw.h b/searchsummary/src/vespa/searchsummary/docsummary/rankfeaturesdfw.h index 04ee14c79ca..37790d2f9b8 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/rankfeaturesdfw.h +++ b/searchsummary/src/vespa/searchsummary/docsummary/rankfeaturesdfw.h @@ -19,8 +19,7 @@ public: ~RankFeaturesDFW(); void init(IDocsumEnvironment * env); bool IsGenerated() const override { return true; } - void insertField(uint32_t docid, GeneralResult *gres, GetDocsumsState *state, - ResType type, vespalib::slime::Inserter &target) override; + void insertField(uint32_t docid, GetDocsumsState *state, ResType type, vespalib::slime::Inserter &target) override; }; } diff --git a/searchsummary/src/vespa/searchsummary/docsummary/resultclass.h b/searchsummary/src/vespa/searchsummary/docsummary/resultclass.h index e7c7c799b5f..52e331cd365 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/resultclass.h +++ b/searchsummary/src/vespa/searchsummary/docsummary/resultclass.h @@ -18,6 +18,7 @@ namespace search::docsummary { enum ResType { RES_INT = 0, RES_SHORT, + RES_BOOL, RES_BYTE, RES_FLOAT, RES_DOUBLE, diff --git a/searchsummary/src/vespa/searchsummary/docsummary/resultconfig.cpp b/searchsummary/src/vespa/searchsummary/docsummary/resultconfig.cpp index 1c42709826f..f3834ef4a12 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/resultconfig.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/resultconfig.cpp @@ -45,6 +45,7 @@ ResultConfig::GetResTypeName(ResType type) case RES_INT: return "integer"; case RES_SHORT: return "short"; case RES_BYTE: return "byte"; + case RES_BOOL: return "bool"; case RES_FLOAT: return "float"; case RES_DOUBLE: return "double"; case RES_INT64: return "int64"; @@ -73,15 +74,14 @@ ResultConfig::Reset() ResultClass * ResultConfig::AddResultClass(const char *name, uint32_t id) { - ResultClass *ret = NULL; + ResultClass *ret = nullptr; if (id != NoClassID() && (_classLookup.find(id) == _classLookup.end())) { ResultClass::UP rc(new ResultClass(name, id, _fieldEnum)); ret = rc.get(); _classLookup[id] = std::move(rc); if (_nameLookup.find(name) != _nameLookup.end()) { - LOG(warning, "Duplicate result class name: %s " - "(now maps to class id %u)", name, id); + LOG(warning, "Duplicate result class name: %s (now maps to class id %u)", name, id); } _nameLookup[name] = id; } @@ -93,7 +93,7 @@ const ResultClass* ResultConfig::LookupResultClass(uint32_t id) const { IdMap::const_iterator it(_classLookup.find(id)); - return (it != _classLookup.end()) ? it->second.get() : NULL; + return (it != _classLookup.end()) ? it->second.get() : nullptr; } uint32_t @@ -113,8 +113,8 @@ ResultConfig::LookupResultClassId(const vespalib::string &name) const void ResultConfig::CreateEnumMaps() { - for (IdMap::iterator it(_classLookup.begin()), mt(_classLookup.end()); it != mt; it++) { - it ->second->CreateEnumMap(); + for (auto & entry : _classLookup) { + entry.second->CreateEnumMap(); } } @@ -137,14 +137,12 @@ ResultConfig::ReadConfig(const vespa::config::search::SummaryConfig &cfg, const break; } ResultClass *resClass = AddResultClass(cfg.classes[i].name.c_str(), classID); - if (resClass == NULL) { - LOG(error, - "%s: unable to add classes[%d] name %s", - configId, i, cfg.classes[i].name.c_str()); + if (resClass == nullptr) { + LOG(error,"%s: unable to add classes[%d] name %s", configId, i, cfg.classes[i].name.c_str()); rc = false; break; } - for (unsigned int j = 0; rc && j < cfg.classes[i].fields.size(); j++) { + for (unsigned int j = 0; rc && (j < cfg.classes[i].fields.size()); j++) { const char *fieldtype = cfg.classes[i].fields[j].type.c_str(); const char *fieldname = cfg.classes[i].fields[j].name.c_str(); LOG(debug, "Reconfiguring class '%s' field '%s' of type '%s'", cfg.classes[i].name.c_str(), fieldname, fieldtype); @@ -152,6 +150,8 @@ ResultConfig::ReadConfig(const vespa::config::search::SummaryConfig &cfg, const rc = resClass->AddConfigEntry(fieldname, RES_INT); } else if (strcmp(fieldtype, "short") == 0) { rc = resClass->AddConfigEntry(fieldname, RES_SHORT); + } else if (strcmp(fieldtype, "bool") == 0) { + rc = resClass->AddConfigEntry(fieldname, RES_BOOL); } else if (strcmp(fieldtype, "byte") == 0) { rc = resClass->AddConfigEntry(fieldname, RES_BYTE); } else if (strcmp(fieldtype, "float") == 0) { @@ -176,17 +176,13 @@ ResultConfig::ReadConfig(const vespa::config::search::SummaryConfig &cfg, const rc = resClass->AddConfigEntry(fieldname, RES_TENSOR); } else if (strcmp(fieldtype, "featuredata") == 0) { rc = resClass->AddConfigEntry(fieldname, RES_FEATUREDATA); - } else { // FAIL: unknown field type - LOG(error, - "%s %s.fields[%d]: unknown type '%s'", - configId, cfg.classes[i].name.c_str(), j, fieldtype); + } else { + LOG(error, "%s %s.fields[%d]: unknown type '%s'", configId, cfg.classes[i].name.c_str(), j, fieldtype); rc = false; break; } - if (!rc) { // FAIL: duplicate field name - LOG(error, - "%s %s.fields[%d]: duplicate name '%s'", - configId, cfg.classes[i].name.c_str(), j, fieldname); + if (!rc) { + LOG(error, "%s %s.fields[%d]: duplicate name '%s'", configId, cfg.classes[i].name.c_str(), j, fieldname); break; } } @@ -212,33 +208,5 @@ ResultConfig::GetClassID(const char *buf, uint32_t buflen) return ret; } -urlresult* -ResultConfig::Unpack(uint32_t partition, - uint32_t docid, - HitRank metric, - const char *buf, - uint32_t buflen) const -{ - urlresult *ret = NULL; - const ResultClass *resClass = NULL; - uint32_t tmp32; - - if (buflen >= sizeof(tmp32)) { - memcpy(&tmp32, buf, sizeof(tmp32)); - buf += sizeof(tmp32); - buflen -= sizeof(tmp32); - resClass = LookupResultClass(tmp32); - } - - if (resClass != NULL && (buflen > 0)) { - ret = new GeneralResult(resClass, partition, docid, metric); - if (ret->unpack(buf, buflen) != 0) { // FAIL: unpack - delete ret; - ret = NULL; - } - } - - return (ret != NULL) ? ret : new badurlresult(partition, docid, metric); -} } diff --git a/searchsummary/src/vespa/searchsummary/docsummary/resultconfig.h b/searchsummary/src/vespa/searchsummary/docsummary/resultconfig.h index eac6d4b113f..31218d94e93 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/resultconfig.h +++ b/searchsummary/src/vespa/searchsummary/docsummary/resultconfig.h @@ -115,6 +115,9 @@ public: return true; } switch (a) { + case RES_BYTE: + case RES_BOOL: + return (b == RES_BYTE || b == RES_BOOL); case RES_STRING: case RES_DATA: return (b == RES_STRING || b == RES_DATA); @@ -147,7 +150,8 @@ public: case RES_INT: case RES_SHORT: case RES_BYTE: - return (b == RES_INT || b == RES_SHORT || b == RES_BYTE); + case RES_BOOL: + return (b == RES_INT || b == RES_SHORT || b == RES_BYTE || b == RES_BOOL); case RES_FLOAT: case RES_DOUBLE: return (b == RES_FLOAT || b == RES_DOUBLE); @@ -269,29 +273,6 @@ public: * @param buflen length of docsum blob. **/ uint32_t GetClassID(const char *buf, uint32_t buflen); - - /** - * Unpack docsum blob. The first n (0/8/16/32) bits are read from - * the data given and used to look up the appropriate result - * class. A GeneralResult object is created based on that - * class and told to unpack the rest of the docsum blob. If this - * operation succeeds, the GeneralResult object is - * returned. It if fails, a badurlresult object is returned - * instead. - * - * @return object representing the unpacked result. - * @param partition partition path for current hit. - * @param docid docid for current hit. - * @param metric relevance estimate for current hit. - * @param buf docsum blob. - * @param buflen length of docsum blob. - **/ - urlresult * - Unpack(uint32_t partition, - uint32_t docid, - HitRank metric, - const char *buf, - uint32_t buflen) const; }; } diff --git a/searchsummary/src/vespa/searchsummary/docsummary/resultpacker.cpp b/searchsummary/src/vespa/searchsummary/docsummary/resultpacker.cpp index 178e1a90667..c9642b80e56 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/resultpacker.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/resultpacker.cpp @@ -23,7 +23,7 @@ bool ResultPacker::CheckEntry(ResType type) if (_error) return false; - bool rc = (_cfgEntry != NULL && + bool rc = (_cfgEntry != nullptr && IsBinaryCompatible(_cfgEntry->_type, type)); if (rc) { @@ -43,7 +43,7 @@ ResultPacker::SetFormatError(ResType type) { _error = true; - if (_cfgEntry != NULL) { + if (_cfgEntry != nullptr) { LOG(error, "ResultPacker: format error: got '%s', expected '%s'", GetResTypeName(type), @@ -60,17 +60,15 @@ ResultPacker::ResultPacker(const ResultConfig *resConfig) : _buf(32768), _cbuf(32768), _resConfig(resConfig), - _resClass(NULL), + _resClass(nullptr), _entryIdx(0), - _cfgEntry(NULL), + _cfgEntry(nullptr), _error(true) { } -ResultPacker::~ResultPacker() -{ -} +ResultPacker::~ResultPacker() = default; void ResultPacker::InitPlain() @@ -82,16 +80,16 @@ bool ResultPacker::Init(uint32_t classID) { _buf.reset(); - _resClass = (_resConfig != NULL) ? - _resConfig->LookupResultClass(classID) : NULL; + _resClass = (_resConfig != nullptr) ? + _resConfig->LookupResultClass(classID) : nullptr; _entryIdx = 0; - if (_resClass != NULL) { + if (_resClass != nullptr) { uint32_t id = _resClass->GetClassID(); _buf.append(&id, sizeof(id)); _cfgEntry = _resClass->GetEntry(_entryIdx); _error = false; } else { - _cfgEntry = NULL; + _cfgEntry = nullptr; _error = true; LOG(error, "ResultPacker: resultclass %d does not exist", classID); @@ -104,22 +102,23 @@ ResultPacker::Init(uint32_t classID) bool ResultPacker::AddEmpty() { - if (!_error && _cfgEntry != NULL) { + if (!_error && _cfgEntry != nullptr) { switch (_cfgEntry->_type) { case RES_INT: return AddInteger(search::attribute::getUndefined<int32_t>()); case RES_SHORT: return AddShort(search::attribute::getUndefined<int16_t>()); + case RES_BOOL: return AddByte(0); case RES_BYTE: return AddByte(search::attribute::getUndefined<int8_t>()); case RES_FLOAT: return AddFloat(search::attribute::getUndefined<float>()); case RES_DOUBLE: return AddDouble(search::attribute::getUndefined<double>()); case RES_INT64: return AddInt64(search::attribute::getUndefined<int64_t>()); - case RES_STRING: return AddString(NULL, 0); - case RES_DATA: return AddData(NULL, 0); + case RES_STRING: return AddString(nullptr, 0); + case RES_DATA: return AddData(nullptr, 0); case RES_XMLSTRING: case RES_JSONSTRING: case RES_FEATUREDATA: - case RES_LONG_STRING: return AddLongString(NULL, 0); - case RES_TENSOR: return AddSerializedTensor(NULL, 0); - case RES_LONG_DATA: return AddLongData(NULL, 0); + case RES_LONG_STRING: return AddLongString(nullptr, 0); + case RES_TENSOR: return AddSerializedTensor(nullptr, 0); + case RES_LONG_DATA: return AddLongData(nullptr, 0); } } return AddInteger(0); // to provoke error condition @@ -271,7 +270,7 @@ ResultPacker::GetDocsumBlob(const char **buf, uint32_t *buflen) _resClass->GetNumEntries() - _entryIdx); } if (_error) { - *buf = NULL; + *buf = nullptr; *buflen = 0; return false; } else { diff --git a/searchsummary/src/vespa/searchsummary/docsummary/summaryfeaturesdfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/summaryfeaturesdfw.cpp index 7cf1e65fbc0..9992d782d6e 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/summaryfeaturesdfw.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/summaryfeaturesdfw.cpp @@ -12,13 +12,11 @@ namespace search::docsummary { SummaryFeaturesDFW::SummaryFeaturesDFW() : - _env(NULL) + _env(nullptr) { } -SummaryFeaturesDFW::~SummaryFeaturesDFW() -{ -} +SummaryFeaturesDFW::~SummaryFeaturesDFW() = default; void SummaryFeaturesDFW::init(IDocsumEnvironment * env) @@ -30,8 +28,7 @@ static vespalib::string _G_cached("vespa.summaryFeatures.cached"); static vespalib::Memory _M_cached("vespa.summaryFeatures.cached"); void -SummaryFeaturesDFW::insertField(uint32_t docid, GeneralResult *, GetDocsumsState *state, - ResType type, vespalib::slime::Inserter &target) +SummaryFeaturesDFW::insertField(uint32_t docid, GetDocsumsState *state, ResType type, vespalib::slime::Inserter &target) { if ( ! state->_summaryFeatures) { state->_callback.FillSummaryFeatures(state, _env); @@ -41,7 +38,7 @@ SummaryFeaturesDFW::insertField(uint32_t docid, GeneralResult *, GetDocsumsState } const FeatureSet::StringVector &names = state->_summaryFeatures->getNames(); const feature_t *values = state->_summaryFeatures->getFeaturesByDocId(docid); - if (type == RES_FEATUREDATA && values != NULL) { + if (type == RES_FEATUREDATA && values != nullptr) { vespalib::slime::Cursor& obj = target.insertObject(); for (uint32_t i = 0; i < names.size(); ++i) { vespalib::Memory name(names[i].c_str(), names[i].size()); @@ -55,7 +52,7 @@ SummaryFeaturesDFW::insertField(uint32_t docid, GeneralResult *, GetDocsumsState return; } vespalib::JSONStringer & json(state->_jsonStringer); - if (values != NULL) { + if (values != nullptr) { json.clear(); json.beginObject(); for (uint32_t i = 0; i < names.size(); ++i) { diff --git a/searchsummary/src/vespa/searchsummary/docsummary/summaryfeaturesdfw.h b/searchsummary/src/vespa/searchsummary/docsummary/summaryfeaturesdfw.h index e417e89cf04..f1452d4c0a9 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/summaryfeaturesdfw.h +++ b/searchsummary/src/vespa/searchsummary/docsummary/summaryfeaturesdfw.h @@ -10,7 +10,7 @@ namespace search::docsummary { class IDocsumEnvironment; -class FeaturesDFW : public IDocsumFieldWriter +class FeaturesDFW : public IDocsumFW { protected: void featureDump(vespalib::JSONStringer & json, vespalib::stringref name, double feature); @@ -29,7 +29,7 @@ public: ~SummaryFeaturesDFW() override; void init(IDocsumEnvironment * env); bool IsGenerated() const override { return true; } - void insertField(uint32_t docid, GeneralResult *gres, GetDocsumsState *state, + void insertField(uint32_t docid, GetDocsumsState *state, ResType type, vespalib::slime::Inserter &target) override; }; diff --git a/searchsummary/src/vespa/searchsummary/docsummary/textextractordfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/textextractordfw.cpp index 121520c4d03..a0efda07f04 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/textextractordfw.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/textextractordfw.cpp @@ -27,16 +27,13 @@ TextExtractorDFW::init(const vespalib::string & fieldName, const vespalib::strin } void -TextExtractorDFW::insertField(uint32_t, - GeneralResult *gres, - GetDocsumsState *state, - ResType, +TextExtractorDFW::insertField(uint32_t, GeneralResult *gres, GetDocsumsState *state, ResType, vespalib::slime::Inserter &target) { vespalib::string extracted; ResEntry * entry = gres->GetEntryFromEnumValue(_inputFieldEnum); - if (entry != NULL) { - const char * buf = NULL; + if (entry != nullptr) { + const char * buf = nullptr; uint32_t buflen = 0; entry->_resolve_field(&buf, &buflen, &state->_docSumFieldSpace); // extract the text diff --git a/searchsummary/src/vespa/searchsummary/docsummary/urlresult.cpp b/searchsummary/src/vespa/searchsummary/docsummary/urlresult.cpp index 9cd5c58f971..074cc1cadf1 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/urlresult.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/urlresult.cpp @@ -10,45 +10,6 @@ LOG_SETUP(".searchlib.docsummary.urlresult"); namespace search::docsummary { -urlresult::urlresult(uint32_t partition, uint32_t docid, HitRank metric) - : _partition(partition), - _docid(docid), - _metric(metric) -{ } - - -urlresult::~urlresult() { } - - -/*===============================================================*/ - - -badurlresult::badurlresult() - : urlresult(0, 0, 0) -{ } - - -badurlresult::badurlresult(uint32_t partition, uint32_t docid, HitRank metric) - : urlresult(partition, docid, metric) -{ } - - -badurlresult::~badurlresult() { } - - -int -badurlresult::unpack(const char *buf, const size_t buflen) -{ - (void) buf; - (void) buflen; - LOG(warning, "badurlresult::unpack"); - return 0; -} - - -/*===============================================================*/ - - void GeneralResult::AllocEntries(uint32_t buflen, bool inplace) { @@ -60,10 +21,10 @@ GeneralResult::AllocEntries(uint32_t buflen, bool inplace) if (cnt > 0) { _entrycnt = cnt; _entries = (ResEntry *) malloc(needMem); - assert(_entries != NULL); + assert(_entries != nullptr); if (inplace) { - _buf = NULL; - _bufEnd = NULL; + _buf = nullptr; + _bufEnd = nullptr; } else { _buf = ((char *)_entries) + cnt * sizeof(ResEntry); _bufEnd = _buf + buflen + 1; @@ -71,20 +32,19 @@ GeneralResult::AllocEntries(uint32_t buflen, bool inplace) memset(_entries, 0, cnt * sizeof(ResEntry)); } else { _entrycnt = 0; - _entries = NULL; - _buf = NULL; - _bufEnd = NULL; + _entries = nullptr; + _buf = nullptr; + _bufEnd = nullptr; } } - void GeneralResult::FreeEntries() { uint32_t cnt = _entrycnt; - // (_buf == NULL) <=> (_inplace_unpack() || (cnt == 0)) - if (_buf != NULL) { + // (_buf == nullptr) <=> (_inplace_unpack() || (cnt == 0)) + if (_buf != nullptr) { for (uint32_t i = 0; i < cnt; i++) { if (ResultConfig::IsVariableSize(_entries[i]._type) && !InBuf(_entries[i]._stringval)) @@ -94,41 +54,32 @@ GeneralResult::FreeEntries() free(_entries); // free '_entries'/'_buf' chunk } - - -GeneralResult::GeneralResult(const ResultClass *resClass, - uint32_t partition, uint32_t docid, - HitRank metric) - : urlresult(partition, docid, metric), - _resClass(resClass), +GeneralResult::GeneralResult(const ResultClass *resClass) + : _resClass(resClass), _entrycnt(0), - _entries(NULL), - _buf(NULL), - _bufEnd(NULL) + _entries(nullptr), + _buf(nullptr), + _bufEnd(nullptr) { } - GeneralResult::~GeneralResult() { FreeEntries(); } - ResEntry * GeneralResult::GetEntry(uint32_t idx) { - return (idx < _entrycnt) ? &_entries[idx] : NULL; + return (idx < _entrycnt) ? &_entries[idx] : nullptr; } - ResEntry * GeneralResult::GetEntry(const char *name) { int idx = _resClass->GetIndexFromName(name); - return (idx >= 0 && (uint32_t)idx < _entrycnt) ? - &_entries[idx] : NULL; + return (idx >= 0 && (uint32_t)idx < _entrycnt) ? &_entries[idx] : nullptr; } @@ -136,398 +87,17 @@ ResEntry * GeneralResult::GetEntryFromEnumValue(uint32_t value) { int idx = _resClass->GetIndexFromEnumValue(value); - - return (idx >= 0 && (uint32_t)idx < _entrycnt) ? - &_entries[idx] : NULL; + return (idx >= 0 && (uint32_t)idx < _entrycnt) ? &_entries[idx] : nullptr; } - -int -GeneralResult::unpack(const char *buf, const size_t buflen) -{ - bool rc = true; - const char *ebuf = buf + buflen; // Ref to first after buffer - const char *p = buf; // current position in buffer - - if (_entries != NULL) - FreeEntries(); - - AllocEntries(buflen); - - for (uint32_t i = 0; rc && i < _entrycnt; i++) { - const ResConfigEntry *entry = _resClass->GetEntry(i); - - switch (entry->_type) { - - case RES_INT: { - - if (p + sizeof(_entries[i]._intval) <= ebuf) { - - memcpy(&_entries[i]._intval, p, sizeof(_entries[i]._intval)); - _entries[i]._type = RES_INT; - p += sizeof(_entries[i]._intval); - - } else { - - LOG(debug, "GeneralResult::unpack: p + sizeof(..._intval) > ebuf"); - LOG(error, "Document summary too short, couldn't unpack"); - rc = false; - } - break; - } - - case RES_SHORT: { - - uint16_t shortval; - if (p + sizeof(shortval) <= ebuf) { - - memcpy(&shortval, p, sizeof(shortval)); - _entries[i]._intval = (uint32_t)shortval; - _entries[i]._type = RES_INT; // type promotion - p += sizeof(shortval); - - } else { - - LOG(debug, "GeneralResult::unpack: p + sizeof(shortval) > ebuf"); - LOG(error, "Document summary too short, couldn't unpack"); - rc = false; - } - break; - } - - case RES_BYTE: { - - uint8_t byteval; - if (p + sizeof(byteval) <= ebuf) { - - memcpy(&byteval, p, sizeof(byteval)); - _entries[i]._intval = (uint32_t)byteval; - _entries[i]._type = RES_INT; // type promotion - p += sizeof(byteval); - - } else { - - LOG(debug, "GeneralResult::unpack: p + sizeof(byteval) > ebuf"); - LOG(error, "Document summary too short, couldn't unpack"); - rc = false; - } - break; - } - - case RES_FLOAT: { - - float floatval; - if (p + sizeof(floatval) <= ebuf) { - - memcpy(&floatval, p, sizeof(floatval)); - _entries[i]._doubleval = (double)floatval; - _entries[i]._type = RES_DOUBLE; // type promotion - p += sizeof(floatval); - - } else { - - LOG(debug, "GeneralResult::unpack: p + sizeof(floatval) > ebuf"); - LOG(error, "Document summary too short, couldn't unpack"); - rc = false; - } - break; - } - - case RES_DOUBLE: { - - if (p + sizeof(_entries[i]._doubleval) <= ebuf) { - - memcpy(&_entries[i]._doubleval, p, sizeof(_entries[i]._doubleval)); - _entries[i]._type = RES_DOUBLE; - p += sizeof(_entries[i]._doubleval); - - } else { - - LOG(debug, "GeneralResult::unpack: p + sizeof(..._doubleval) > ebuf"); - LOG(error, "Document summary too short, couldn't unpack"); - rc = false; - } - break; - } - - case RES_INT64: { - - if (p + sizeof(_entries[i]._int64val) <= ebuf) { - - memcpy(&_entries[i]._int64val, p, sizeof(_entries[i]._int64val)); - _entries[i]._type = RES_INT64; - p += sizeof(_entries[i]._int64val); - - } else { - - LOG(debug, "GeneralResult::unpack: p + sizeof(..._int64val) > ebuf"); - LOG(error, "Document summary too short, couldn't unpack"); - rc = false; - } - break; - } - - case RES_STRING: { - - uint16_t slen; - if (p + sizeof(slen) <= ebuf) { - - memcpy(&slen, p, sizeof(slen)); - p += sizeof(slen); - - if (p + slen <= ebuf) { - - _entries[i]._stringval = _buf + (p - buf); - memcpy(_entries[i]._stringval, p, slen); - _entries[i]._stringval[slen] = '\0'; - _entries[i]._stringlen = slen; - _entries[i]._type = RES_STRING; - p += slen; - - } else { - - LOG(debug, "GeneralResult::unpack: p + slen > ebuf"); - LOG(error, "Document summary too short, couldn't unpack"); - rc = false; - } - - } else { - - LOG(debug, "GeneralResult::unpack: p + sizeof(slen) > ebuf"); - LOG(error, "Document summary too short, couldn't unpack"); - rc = false; - } - break; - } - - case RES_DATA: { - - uint16_t dlen; - if (p + sizeof(dlen) <= ebuf) { - - memcpy(&dlen, p, sizeof(dlen)); - p += sizeof(dlen); - - if (p + dlen <= ebuf) { - - _entries[i]._dataval = _buf + (p - buf); - memcpy(_entries[i]._dataval, p, dlen); - _entries[i]._dataval[dlen] = '\0'; // just in case. - _entries[i]._datalen = dlen; - _entries[i]._type = RES_DATA; - p += dlen; - - } else { - - LOG(debug, "GeneralResult::unpack: p + dlen > ebuf"); - LOG(error, "Document summary too short, couldn't unpack"); - rc = false; - } - - } else { - - LOG(debug, "GeneralResult::unpack: p + sizeof(dlen) > ebuf"); - LOG(error, "Document summary too short, couldn't unpack"); - rc = false; - } - break; - } - - case RES_XMLSTRING: - case RES_JSONSTRING: - case RES_FEATUREDATA: - case RES_LONG_STRING: { - - uint32_t lslen; - bool compressed; - if (p + sizeof(lslen) <= ebuf) { - - memcpy(&lslen, p, sizeof(lslen)); - p += sizeof(lslen); - - compressed = ((lslen & 0x80000000) != 0); - lslen &= 0x7fffffff; - - if (p + lslen <= ebuf) { - - if (compressed) { // COMPRESSED - uint32_t realLen = 0; - if (lslen >= sizeof(realLen)) - memcpy(&realLen, p, sizeof(realLen)); - else - LOG(warning, "Cannot uncompress docsum field %s; docsum field meta-data incomplete", - entry->_bindname.c_str()); - if (realLen > 0) { - _entries[i]._stringval = new char[realLen + 1]; - } - if (_entries[i]._stringval != NULL) { - uLongf rlen = realLen; - if ((uncompress((Bytef *)_entries[i]._stringval, &rlen, - (const Bytef *)(p + sizeof(realLen)), - lslen - sizeof(realLen)) == Z_OK) && - rlen == realLen) { - assert(rlen == realLen); - - // COMPRESSED LONG STRING FIELD OK - _entries[i]._stringval[realLen] = '\0'; - _entries[i]._stringlen = realLen; - - } else { - LOG(warning, "Cannot uncompress docsum field %s; decompression error", - entry->_bindname.c_str()); - delete [] _entries[i]._stringval; - _entries[i]._stringval = NULL; - } - } - // insert empty field if decompress failed - if (_entries[i]._stringval == NULL) { - _entries[i]._stringval = _buf + (p - buf); - _entries[i]._stringval[0] = '\0'; - _entries[i]._stringlen = 0; - } - - } else { // UNCOMPRESSED - - _entries[i]._stringval = _buf + (p - buf); - memcpy(_entries[i]._stringval, p, lslen); - _entries[i]._stringval[lslen] = '\0'; - _entries[i]._stringlen = lslen; - - } - _entries[i]._type = RES_STRING; // type normalization - p += lslen; - - } else { - - LOG(debug, "GeneralResult::unpack: p + lslen > ebuf"); - LOG(error, "Document summary too short, couldn't unpack"); - rc = false; - } - - } else { - - LOG(debug, "GeneralResult::unpack: p + sizeof(lslen) > ebuf"); - LOG(error, "Document summary too short, couldn't unpack"); - rc = false; - } - break; - } - - case RES_TENSOR: - case RES_LONG_DATA: { - - uint32_t ldlen; - bool compressed; - if (p + sizeof(ldlen) <= ebuf) { - - memcpy(&ldlen, p, sizeof(ldlen)); - p += sizeof(ldlen); - - compressed = ((ldlen & 0x80000000) != 0); - ldlen &= 0x7fffffff; - - if (p + ldlen <= ebuf) { - - if (compressed) { // COMPRESSED - uint32_t realLen = 0; - if (ldlen >= sizeof(realLen)) - memcpy(&realLen, p, sizeof(realLen)); - else - LOG(warning, "Cannot uncompress docsum field %s; docsum field meta-data incomplete", - entry->_bindname.c_str()); - if (realLen > 0) { - _entries[i]._dataval = new char [realLen + 1]; - } - if (_entries[i]._dataval != NULL) { - uLongf rlen = realLen; - if ((uncompress((Bytef *)_entries[i]._dataval, &rlen, - (const Bytef *)(p + sizeof(realLen)), - ldlen - sizeof(realLen)) == Z_OK) && - rlen == realLen) { - assert(rlen == realLen); - - // COMPRESSED LONG DATA FIELD OK - _entries[i]._dataval[realLen] = '\0'; - _entries[i]._datalen = realLen; - - } else { - LOG(warning, "Cannot uncompress docsum field %s; decompression error", - entry->_bindname.c_str()); - delete [] _entries[i]._dataval; - _entries[i]._dataval = NULL; - } - } - - // insert empty field if decompress failed - if (_entries[i]._dataval == NULL) { - _entries[i]._dataval = _buf + (p - buf); - _entries[i]._dataval[0] = '\0'; - _entries[i]._datalen = 0; - } - - } else { // UNCOMPRESSED - - _entries[i]._dataval = _buf + (p - buf); - memcpy(_entries[i]._dataval, p, ldlen); - _entries[i]._dataval[ldlen] = '\0'; // just in case - _entries[i]._datalen = ldlen; - - } - _entries[i]._type = RES_DATA; // type normalization - p += ldlen; - - } else { - - LOG(debug, "GeneralResult::unpack: p + ldlen > ebuf"); - LOG(error, "Document summary too short, couldn't unpack"); - rc = false; - } - - } else { - - LOG(debug, "GeneralResult::unpack: p + sizeof(ldlen) > ebuf"); - LOG(error, "Document summary too short, couldn't unpack"); - rc = false; - } - break; - } - - default: - LOG(warning, "GeneralResult::unpack: no such type:%d", entry->_type); - LOG(error, "Incorrect type in document summary, couldn't unpack"); - rc = false; - break; - } // END -- switch (entry->_type) { - } // END -- for (uint32_t i = 0; rc && i < _entrycnt; i++) { - - if (rc && p != ebuf) { - LOG(debug, "GeneralResult::unpack: p:%p != ebuf:%p", p, ebuf); - LOG(error, "Document summary too long, couldn't unpack."); - rc = false; - } - - if (rc) - return 0; // SUCCESS - - // clean up on failure - FreeEntries(); - _entrycnt = 0; - _entries = NULL; - _buf = NULL; - _bufEnd = NULL; - - return -1; // FAIL -} - - bool -GeneralResult::_inplace_unpack(const char *buf, const size_t buflen) +GeneralResult::unpack(const char *buf, const size_t buflen) { bool rc = true; const char *ebuf = buf + buflen; // Ref to first after buffer const char *p = buf; // current position in buffer - if (_entries != NULL) + if (_entries != nullptr) FreeEntries(); AllocEntries(buflen, true); @@ -538,17 +108,12 @@ GeneralResult::_inplace_unpack(const char *buf, const size_t buflen) switch (entry->_type) { case RES_INT: { - if (p + sizeof(_entries[i]._intval) <= ebuf) { - memcpy(&_entries[i]._intval, p, sizeof(_entries[i]._intval)); _entries[i]._type = RES_INT; p += sizeof(_entries[i]._intval); - } else { - - LOG(debug, - "GeneralResult::_inplace_unpack: p + sizeof(..._intval) > ebuf"); + LOG(debug, "GeneralResult::_inplace_unpack: p + sizeof(..._intval) > ebuf"); LOG(error, "Document summary too short, couldn't unpack"); rc = false; } @@ -556,39 +121,29 @@ GeneralResult::_inplace_unpack(const char *buf, const size_t buflen) } case RES_SHORT: { - uint16_t shortval; if (p + sizeof(shortval) <= ebuf) { - memcpy(&shortval, p, sizeof(shortval)); _entries[i]._intval = (uint32_t)shortval; _entries[i]._type = RES_INT; // type promotion p += sizeof(shortval); - } else { - - LOG(debug, - "GeneralResult::_inplace_unpack: p + sizeof(shortval) > ebuf"); + LOG(debug, "GeneralResult::_inplace_unpack: p + sizeof(shortval) > ebuf"); LOG(error, "Document summary too short, couldn't unpack"); rc = false; } break; } - + case RES_BOOL: case RES_BYTE: { - uint8_t byteval; if (p + sizeof(byteval) <= ebuf) { - memcpy(&byteval, p, sizeof(byteval)); _entries[i]._intval = (uint32_t)byteval; _entries[i]._type = RES_INT; // type promotion p += sizeof(byteval); - } else { - - LOG(debug, - "GeneralResult::_inplace_unpack: p + sizeof(byteval) > ebuf"); + LOG(debug, "GeneralResult::_inplace_unpack: p + sizeof(byteval) > ebuf"); LOG(error, "Document summary too short, couldn't unpack"); rc = false; } @@ -596,17 +151,13 @@ GeneralResult::_inplace_unpack(const char *buf, const size_t buflen) } case RES_FLOAT: { - float floatval; if (p + sizeof(floatval) <= ebuf) { - memcpy(&floatval, p, sizeof(floatval)); _entries[i]._doubleval = (double)floatval; _entries[i]._type = RES_DOUBLE; // type promotion p += sizeof(floatval); - } else { - LOG(debug, "GeneralResult::unpack: p + sizeof(floatval) > ebuf"); LOG(error, "Document summary too short, couldn't unpack"); rc = false; @@ -615,15 +166,11 @@ GeneralResult::_inplace_unpack(const char *buf, const size_t buflen) } case RES_DOUBLE: { - if (p + sizeof(_entries[i]._doubleval) <= ebuf) { - memcpy(&_entries[i]._doubleval, p, sizeof(_entries[i]._doubleval)); _entries[i]._type = RES_DOUBLE; p += sizeof(_entries[i]._doubleval); - } else { - LOG(debug, "GeneralResult::unpack: p + sizeof(..._doubleval) > ebuf"); LOG(error, "Document summary too short, couldn't unpack"); rc = false; @@ -632,15 +179,11 @@ GeneralResult::_inplace_unpack(const char *buf, const size_t buflen) } case RES_INT64: { - if (p + sizeof(_entries[i]._int64val) <= ebuf) { - memcpy(&_entries[i]._int64val, p, sizeof(_entries[i]._int64val)); _entries[i]._type = RES_INT64; p += sizeof(_entries[i]._int64val); - } else { - LOG(debug, "GeneralResult::unpack: p + sizeof(..._int64val) > ebuf"); LOG(error, "Document summary too short, couldn't unpack"); rc = false; @@ -649,29 +192,21 @@ GeneralResult::_inplace_unpack(const char *buf, const size_t buflen) } case RES_STRING: { - uint16_t slen; if (p + sizeof(slen) <= ebuf) { - memcpy(&slen, p, sizeof(slen)); p += sizeof(slen); - if (p + slen <= ebuf) { - _entries[i]._stringval = const_cast<char *>(p); _entries[i]._stringlen = slen; _entries[i]._type = RES_STRING; p += slen; - } else { - LOG(debug, "GeneralResult::_inplace_unpack: p + slen > ebuf"); LOG(error, "Document summary too short, couldn't unpack"); rc = false; } - } else { - LOG(debug, "GeneralResult::_inplace_unpack: p + sizeof(slen) > ebuf"); LOG(error, "Document summary too short, couldn't unpack"); rc = false; @@ -680,29 +215,21 @@ GeneralResult::_inplace_unpack(const char *buf, const size_t buflen) } case RES_DATA: { - uint16_t dlen; if (p + sizeof(dlen) <= ebuf) { - memcpy(&dlen, p, sizeof(dlen)); p += sizeof(dlen); - if (p + dlen <= ebuf) { - _entries[i]._dataval = const_cast<char *>(p); _entries[i]._datalen = dlen; _entries[i]._type = RES_DATA; p += dlen; - } else { - LOG(debug, "GeneralResult::_inplace_unpack: p + dlen > ebuf"); LOG(error, "Document summary too short, couldn't unpack"); rc = false; } - } else { - LOG(debug, "GeneralResult::_inplace_unpack: p + sizeof(dlen) > ebuf"); LOG(error, "Document summary too short, couldn't unpack"); rc = false; @@ -714,32 +241,23 @@ GeneralResult::_inplace_unpack(const char *buf, const size_t buflen) case RES_JSONSTRING: case RES_FEATUREDATA: case RES_LONG_STRING: { - uint32_t flen; uint32_t lslen; if (p + sizeof(flen) <= ebuf) { - memcpy(&flen, p, sizeof(flen)); p += sizeof(flen); - lslen = flen & 0x7fffffff; - if (p + lslen <= ebuf) { - _entries[i]._stringval = const_cast<char *>(p); _entries[i]._stringlen = flen; // with compression flag _entries[i]._type = RES_STRING; // type normalization p += lslen; - } else { - LOG(debug, "GeneralResult::_inplace_unpack: p + lslen > ebuf"); LOG(error, "Document summary too short, couldn't unpack"); rc = false; } - } else { - LOG(debug, "GeneralResult::_inplace_unpack: p + sizeof(lslen) > ebuf"); LOG(error, "Document summary too short, couldn't unpack"); rc = false; @@ -748,32 +266,23 @@ GeneralResult::_inplace_unpack(const char *buf, const size_t buflen) } case RES_TENSOR : case RES_LONG_DATA: { - uint32_t flen; uint32_t ldlen; if (p + sizeof(flen) <= ebuf) { - memcpy(&flen, p, sizeof(flen)); p += sizeof(flen); - ldlen = flen & 0x7fffffff; - if (p + ldlen <= ebuf) { - _entries[i]._dataval = const_cast<char *>(p); _entries[i]._datalen = flen; // with compression flag _entries[i]._type = RES_DATA; // type normalization p += ldlen; - } else { - LOG(debug, "GeneralResult::_inplace_unpack: p + ldlen > ebuf"); LOG(error, "Document summary too short, couldn't unpack"); rc = false; } - } else { - LOG(debug, "GeneralResult::_inplace_unpack: p + sizeof(ldlen) > ebuf"); LOG(error, "Document summary too short, couldn't unpack"); rc = false; @@ -782,9 +291,7 @@ GeneralResult::_inplace_unpack(const char *buf, const size_t buflen) } default: - LOG(warning, - "GeneralResult::_inplace_unpack: no such type:%d", - entry->_type); + LOG(warning, "GeneralResult::_inplace_unpack: no such type:%d", entry->_type); LOG(error, "Incorrect type in document summary, couldn't unpack"); rc = false; break; @@ -803,9 +310,9 @@ GeneralResult::_inplace_unpack(const char *buf, const size_t buflen) // clean up on failure FreeEntries(); _entrycnt = 0; - _entries = NULL; - _buf = NULL; - _bufEnd = NULL; + _entries = nullptr; + _buf = nullptr; + _bufEnd = nullptr; return false; // FAIL } diff --git a/searchsummary/src/vespa/searchsummary/docsummary/urlresult.h b/searchsummary/src/vespa/searchsummary/docsummary/urlresult.h index 4d1fca0992d..a4cdd1b7f69 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/urlresult.h +++ b/searchsummary/src/vespa/searchsummary/docsummary/urlresult.h @@ -7,37 +7,7 @@ namespace search::docsummary { -class urlresult -{ -protected: - uint32_t _partition; - uint32_t _docid; - HitRank _metric; - -public: - urlresult(uint32_t partition, uint32_t docid, HitRank metric); - virtual ~urlresult(); - - virtual bool IsGeneral() const { return false; } - uint32_t GetPartition() const { return _partition; } - uint32_t GetDocID() const { return _docid; } - HitRank GetMetric() const { return _metric; } - virtual int unpack(const char *buf, const size_t buflen) = 0; -}; - - -class badurlresult : public urlresult -{ -public: - badurlresult(); - badurlresult(uint32_t partition, uint32_t docid, HitRank metric); - ~badurlresult() override; - - int unpack(const char *buf, const size_t buflen) override; -}; - - -class GeneralResult : public urlresult +class GeneralResult { private: GeneralResult(const GeneralResult &); @@ -49,31 +19,27 @@ private: char *_buf; // allocated in same chunk as _entries char *_bufEnd; // first byte after _buf - bool InBuf(void *pt) { - return ((char *)pt >= _buf && - (char *)pt < _bufEnd); + bool InBuf(const void *pt) const { + return ((const char *)pt >= _buf && + (const char *)pt < _bufEnd); } void AllocEntries(uint32_t buflen, bool inplace = false); void FreeEntries(); - bool _inplace_unpack(const char *buf, const size_t buflen); - public: - GeneralResult(const ResultClass *resClass, uint32_t partition, - uint32_t docid, HitRank metric); + GeneralResult(const ResultClass *resClass); ~GeneralResult(); const ResultClass *GetClass() const { return _resClass; } ResEntry *GetEntry(uint32_t idx); ResEntry *GetEntry(const char *name); ResEntry *GetEntryFromEnumValue(uint32_t val); - bool IsGeneral() const override { return true; } - int unpack(const char *buf, const size_t buflen) override; + bool unpack(const char *buf, const size_t buflen); bool inplaceUnpack(const DocsumStoreValue &value) { if (value.valid()) { - return _inplace_unpack(value.fieldsPt(), value.fieldsSz()); + return unpack(value.fieldsPt(), value.fieldsSz()); } else { return false; } diff --git a/vsm/src/vespa/vsm/vsm/docsumconfig.cpp b/vsm/src/vespa/vsm/vsm/docsumconfig.cpp index 25c13967c49..ab89f4d460f 100644 --- a/vsm/src/vespa/vsm/vsm/docsumconfig.cpp +++ b/vsm/src/vespa/vsm/vsm/docsumconfig.cpp @@ -20,7 +20,7 @@ DynamicDocsumConfig::createFieldWriter(const string & fieldName, const string & (overrideName == "absdist") || (overrideName == "subproject")) { - fieldWriter.reset(new EmptyDFW()); + fieldWriter = std::make_unique<EmptyDFW>(); rc = true; } else if ((overrideName == "attribute") || (overrideName == "attributecombiner") || |