diff options
author | Tor Egge <Tor.Egge@online.no> | 2022-09-21 16:41:42 +0200 |
---|---|---|
committer | Tor Egge <Tor.Egge@online.no> | 2022-09-21 16:41:42 +0200 |
commit | c918094f4b3c7c02d6e8cea51b3c5d2650fecb2a (patch) | |
tree | b7b866395b96dec68e6ed4950ddaa0cc7b86d76a | |
parent | 5e08068fa0c7def183cf94b659e7d6fdb5ec1297 (diff) |
Stop using search::index::DocBuilder in searchcore attribute unit test.
5 files changed, 207 insertions, 167 deletions
diff --git a/searchcore/src/tests/proton/attribute/attribute_test.cpp b/searchcore/src/tests/proton/attribute/attribute_test.cpp index e5314d1bf5d..ea264c506a6 100644 --- a/searchcore/src/tests/proton/attribute/attribute_test.cpp +++ b/searchcore/src/tests/proton/attribute/attribute_test.cpp @@ -17,8 +17,8 @@ #include <vespa/searchlib/attribute/imported_attribute_vector_factory.h> #include <vespa/searchlib/attribute/interlock.h> #include <vespa/searchlib/attribute/predicate_attribute.h> -#include <vespa/searchlib/index/docbuilder.h> #include <vespa/searchlib/index/dummyfileheadercontext.h> +#include <vespa/searchlib/index/empty_doc_builder.h> #include <vespa/searchlib/predicate/predicate_hash.h> #include <vespa/searchlib/predicate/predicate_index.h> #include <vespa/searchlib/tensor/dense_tensor_attribute.h> @@ -32,7 +32,14 @@ #include <vespa/document/datatype/mapdatatype.h> #include <vespa/document/datatype/tensor_data_type.h> #include <vespa/document/fieldvalue/document.h> +#include <vespa/document/fieldvalue/arrayfieldvalue.h> +#include <vespa/document/fieldvalue/intfieldvalue.h> +#include <vespa/document/fieldvalue/mapfieldvalue.h> +#include <vespa/document/fieldvalue/predicatefieldvalue.h> +#include <vespa/document/fieldvalue/stringfieldvalue.h> +#include <vespa/document/fieldvalue/tensorfieldvalue.h> #include <vespa/document/predicate/predicate_slime_builder.h> +#include <vespa/document/repo/configbuilder.h> #include <vespa/document/update/arithmeticvalueupdate.h> #include <vespa/document/update/assignvalueupdate.h> #include <vespa/document/update/documentupdate.h> @@ -75,7 +82,7 @@ using search::attribute::ImportedAttributeVector; using search::attribute::ImportedAttributeVectorFactory; using search::attribute::ReferenceAttribute; using search::index::DummyFileHeaderContext; -using search::index::schema::CollectionType; +using search::index::EmptyDocBuilder; using search::predicate::PredicateHash; using search::predicate::PredicateIndex; using search::tensor::DenseTensorAttribute; @@ -214,14 +221,12 @@ AttributeWriterTest::~AttributeWriterTest() = default; TEST_F(AttributeWriterTest, handles_put) { - Schema s; - s.addAttributeField(Schema::AttributeField("a1", schema::DataType::INT32, CollectionType::SINGLE)); - s.addAttributeField(Schema::AttributeField("a2", schema::DataType::INT32, CollectionType::ARRAY)); - s.addAttributeField(Schema::AttributeField("a3", schema::DataType::FLOAT, CollectionType::SINGLE)); - s.addAttributeField(Schema::AttributeField("a4", schema::DataType::STRING, CollectionType::SINGLE)); - - DocBuilder idb(s); - + EmptyDocBuilder edb([](auto& header) + { using namespace document::config_builder; + header.addField("a1", DataType::T_INT) + .addField("a2", Array(DataType::T_INT)) + .addField("a3", DataType::T_FLOAT) + .addField("a4", DataType::T_STRING); }); auto a1 = addAttribute("a1"); auto a2 = addAttribute({"a2", AVConfig(AVBasicType::INT32, AVCollectionType::ARRAY)}); auto a3 = addAttribute({"a3", AVConfig(AVBasicType::FLOAT)}); @@ -233,7 +238,7 @@ TEST_F(AttributeWriterTest, handles_put) attribute::ConstCharContent sbuf; { // empty document should give default values EXPECT_EQ(1u, a1->getNumDocs()); - put(1, *idb.startDocument("id:ns:searchdocument::1").endDocument(), 1); + put(1, *edb.make_document("id:ns:searchdocument::1"), 1); EXPECT_EQ(2u, a1->getNumDocs()); EXPECT_EQ(2u, a2->getNumDocs()); EXPECT_EQ(2u, a3->getNumDocs()); @@ -255,10 +260,12 @@ TEST_F(AttributeWriterTest, handles_put) EXPECT_EQ(strcmp("", sbuf[0]), 0); } { // document with single value & multi value attribute - auto doc = idb.startDocument("id:ns:searchdocument::2"). - startAttributeField("a1").addInt(10).endField(). - startAttributeField("a2").startElement().addInt(20).endElement(). - startElement().addInt(30).endElement().endField().endDocument(); + auto doc = edb.make_document("id:ns:searchdocument::2"); + doc->setValue("a1", IntFieldValue(10)); + ArrayFieldValue int_array(edb.get_data_type("Array<Int>")); + int_array.add(IntFieldValue(20)); + int_array.add(IntFieldValue(30)); + doc->setValue("a2",int_array); put(2, *doc, 2); EXPECT_EQ(3u, a1->getNumDocs()); EXPECT_EQ(3u, a2->getNumDocs()); @@ -275,11 +282,13 @@ TEST_F(AttributeWriterTest, handles_put) EXPECT_EQ(30u, ibuf[1]); } { // replace existing document - auto doc = idb.startDocument("id:ns:searchdocument::2"). - startAttributeField("a1").addInt(100).endField(). - startAttributeField("a2").startElement().addInt(200).endElement(). - startElement().addInt(300).endElement(). - startElement().addInt(400).endElement().endField().endDocument(); + auto doc = edb.make_document("id:ns:searchdocument::2"); + doc->setValue("a1", IntFieldValue(100)); + ArrayFieldValue int_array(edb.get_data_type("Array<Int>")); + int_array.add(IntFieldValue(200)); + int_array.add(IntFieldValue(300)); + int_array.add(IntFieldValue(400)); + doc->setValue("a2",int_array); put(3, *doc, 2); EXPECT_EQ(3u, a1->getNumDocs()); EXPECT_EQ(3u, a2->getNumDocs()); @@ -300,10 +309,7 @@ TEST_F(AttributeWriterTest, handles_put) TEST_F(AttributeWriterTest, handles_predicate_put) { - Schema s; - s.addAttributeField(Schema::AttributeField("a1", schema::DataType::BOOLEANTREE, CollectionType::SINGLE)); - DocBuilder idb(s); - + EmptyDocBuilder edb([](auto& header) { header.addField("a1", DataType::T_PREDICATE); }); auto a1 = addAttribute({"a1", AVConfig(AVBasicType::PREDICATE)}); allocAttributeWriter(); @@ -311,17 +317,15 @@ TEST_F(AttributeWriterTest, handles_predicate_put) // empty document should give default values EXPECT_EQ(1u, a1->getNumDocs()); - put(1, *idb.startDocument("id:ns:searchdocument::1").endDocument(), 1); + put(1, *edb.make_document("id:ns:searchdocument::1"), 1); EXPECT_EQ(2u, a1->getNumDocs()); EXPECT_EQ(1u, a1->getStatus().getLastSyncToken()); EXPECT_EQ(0u, index.getZeroConstraintDocs().size()); // document with single value attribute PredicateSlimeBuilder builder; - auto doc = - idb.startDocument("id:ns:searchdocument::2").startAttributeField("a1") - .addPredicate(builder.true_predicate().build()) - .endField().endDocument(); + auto doc = edb.make_document("id:ns:searchdocument::2"); + doc->setValue("a1", PredicateFieldValue(builder.true_predicate().build())); put(2, *doc, 2); EXPECT_EQ(3u, a1->getNumDocs()); EXPECT_EQ(2u, a1->getStatus().getLastSyncToken()); @@ -331,9 +335,8 @@ TEST_F(AttributeWriterTest, handles_predicate_put) EXPECT_FALSE(it.valid()); // replace existing document - doc = idb.startDocument("id:ns:searchdocument::2").startAttributeField("a1") - .addPredicate(builder.feature("foo").value("bar").build()) - .endField().endDocument(); + doc = edb.make_document("id:ns:searchdocument::2"); + doc->setValue("a1", PredicateFieldValue(builder.feature("foo").value("bar").build())); put(3, *doc, 2); EXPECT_EQ(3u, a1->getNumDocs()); EXPECT_EQ(3u, a1->getStatus().getLastSyncToken()); @@ -403,14 +406,12 @@ TEST_F(AttributeWriterTest, visibility_delay_is_honoured) { auto a1 = addAttribute({"a1", AVConfig(AVBasicType::STRING)}); allocAttributeWriter(); - Schema s; - s.addAttributeField(Schema::AttributeField("a1", schema::DataType::STRING, CollectionType::SINGLE)); - DocBuilder idb(s); + + EmptyDocBuilder edb([](auto& header) { header.addField("a1", DataType::T_STRING); }); EXPECT_EQ(1u, a1->getNumDocs()); EXPECT_EQ(0u, a1->getStatus().getLastSyncToken()); - Document::UP doc = idb.startDocument("id:ns:searchdocument::1") - .startAttributeField("a1").addStr("10").endField() - .endDocument(); + auto doc = edb.make_document("id:ns:searchdocument::1"); + doc->setValue("a1", StringFieldValue("10")); put(3, *doc, 1); EXPECT_EQ(2u, a1->getNumDocs()); EXPECT_EQ(3u, a1->getStatus().getLastSyncToken()); @@ -432,12 +433,15 @@ TEST_F(AttributeWriterTest, visibility_delay_is_honoured) EXPECT_EQ(8u, a1->getStatus().getLastSyncToken()); verifyAttributeContent(*a1, 2, "10"); - awDelayed.put(9, *idb.startDocument("id:ns:searchdocument::1").startAttributeField("a1").addStr("11").endField().endDocument(), - 2, emptyCallback); - awDelayed.put(10, *idb.startDocument("id:ns:searchdocument::1").startAttributeField("a1").addStr("20").endField().endDocument(), - 2, emptyCallback); - awDelayed.put(11, *idb.startDocument("id:ns:searchdocument::1").startAttributeField("a1").addStr("30").endField().endDocument(), - 2, emptyCallback); + doc = edb.make_document("id:ns:searchdocument::1"); + doc->setValue("a1", StringFieldValue("11")); + awDelayed.put(9, *doc, 2, emptyCallback); + doc = edb.make_document("id:ns:searchdocument::1"); + doc->setValue("a1", StringFieldValue("20")); + awDelayed.put(10, *doc, 2, emptyCallback); + doc = edb.make_document("id:ns:searchdocument::1"); + doc->setValue("a1", StringFieldValue("30")); + awDelayed.put(11, *doc, 2, emptyCallback); EXPECT_EQ(8u, a1->getStatus().getLastSyncToken()); verifyAttributeContent(*a1, 2, "10"); awDelayed.forceCommit(12, emptyCallback); @@ -449,16 +453,12 @@ TEST_F(AttributeWriterTest, handles_predicate_remove) { auto a1 = addAttribute({"a1", AVConfig(AVBasicType::PREDICATE)}); allocAttributeWriter(); - Schema s; - s.addAttributeField( - Schema::AttributeField("a1", schema::DataType::BOOLEANTREE, CollectionType::SINGLE)); - DocBuilder idb(s); + EmptyDocBuilder edb([](auto& header) { header.addField("a1", DataType::T_PREDICATE); }); + PredicateSlimeBuilder builder; - auto doc = - idb.startDocument("id:ns:searchdocument::1").startAttributeField("a1") - .addPredicate(builder.true_predicate().build()) - .endField().endDocument(); + auto doc = edb.make_document("id:ns:searchdocument::1"); + doc->setValue("a1", PredicateFieldValue(builder.true_predicate().build())); put(1, *doc, 1); EXPECT_EQ(2u, a1->getNumDocs()); @@ -477,12 +477,10 @@ TEST_F(AttributeWriterTest, handles_update) fillAttribute(a1, 1, 10, 1); fillAttribute(a2, 1, 20, 1); - Schema schema; - schema.addAttributeField(Schema::AttributeField("a1", schema::DataType::INT32, CollectionType::SINGLE)); - schema.addAttributeField(Schema::AttributeField("a2", schema::DataType::INT32, CollectionType::SINGLE)); - DocBuilder idb(schema); - const document::DocumentType &dt(idb.getDocumentType()); - DocumentUpdate upd(*idb.getDocumentTypeRepo(), dt, DocumentId("id:ns:searchdocument::1")); + EmptyDocBuilder edb([](auto& header) + { header.addField("a1", DataType::T_INT) + .addField("a2", DataType::T_INT); }); + DocumentUpdate upd(edb.get_repo(), edb.get_document_type(), DocumentId("id:ns:searchdocument::1")); upd.addUpdate(FieldUpdate(upd.getType().getField("a1")) .addUpdate(std::make_unique<ArithmeticValueUpdate>(ArithmeticValueUpdate::Add, 5))); upd.addUpdate(FieldUpdate(upd.getType().getField("a2")) @@ -513,20 +511,14 @@ TEST_F(AttributeWriterTest, handles_predicate_update) { auto a1 = addAttribute({"a1", AVConfig(AVBasicType::PREDICATE)}); allocAttributeWriter(); - Schema schema; - schema.addAttributeField(Schema::AttributeField("a1", schema::DataType::BOOLEANTREE, CollectionType::SINGLE)); - - DocBuilder idb(schema); + EmptyDocBuilder edb([](auto& header) { header.addField("a1", DataType::T_PREDICATE); }); PredicateSlimeBuilder builder; - auto doc = - idb.startDocument("id:ns:searchdocument::1").startAttributeField("a1") - .addPredicate(builder.true_predicate().build()) - .endField().endDocument(); + auto doc = edb.make_document("id:ns:searchdocument::1"); + doc->setValue("a1", PredicateFieldValue(builder.true_predicate().build())); put(1, *doc, 1); EXPECT_EQ(2u, a1->getNumDocs()); - const document::DocumentType &dt(idb.getDocumentType()); - DocumentUpdate upd(*idb.getDocumentTypeRepo(), dt, DocumentId("id:ns:searchdocument::1")); + DocumentUpdate upd(edb.get_repo(), edb.get_document_type(), DocumentId("id:ns:searchdocument::1")); upd.addUpdate(FieldUpdate(upd.getType().getField("a1")) .addUpdate(std::make_unique<AssignValueUpdate>(std::make_unique<PredicateFieldValue>(builder.feature("foo").value("bar").build())))); @@ -669,18 +661,13 @@ createTensorAttribute(AttributeWriterTest &t) { return ret; } -Schema -createTensorSchema(const vespalib::string& tensor_spec = sparse_tensor) { - Schema schema; - schema.addAttributeField(Schema::AttributeField("a1", schema::DataType::TENSOR, CollectionType::SINGLE, tensor_spec)); - return schema; -} - Document::UP -createTensorPutDoc(DocBuilder &builder, const Value &tensor) { - return builder.startDocument("id:ns:searchdocument::1"). - startAttributeField("a1"). - addTensor(SimpleValue::from_value(tensor)).endField().endDocument(); +createTensorPutDoc(EmptyDocBuilder& builder, const Value &tensor) { + auto doc = builder.make_document("id:ns:searchdocument::1"); + TensorFieldValue fv(*doc->getField("a1").getDataType().cast_tensor()); + fv = SimpleValue::from_value(tensor); + doc->setValue("a1", fv); + return doc; } } @@ -689,8 +676,7 @@ TEST_F(AttributeWriterTest, can_write_to_tensor_attribute) { auto a1 = createTensorAttribute(*this); allocAttributeWriter(); - Schema s = createTensorSchema(); - DocBuilder builder(s); + EmptyDocBuilder builder([](auto& header) { header.addTensorField("a1", sparse_tensor); }); auto tensor = make_tensor(TensorSpec(sparse_tensor) .add({{"x", "4"}, {"y", "5"}}, 7)); Document::UP doc = createTensorPutDoc(builder, *tensor); @@ -707,8 +693,7 @@ TEST_F(AttributeWriterTest, handles_tensor_assign_update) { auto a1 = createTensorAttribute(*this); allocAttributeWriter(); - Schema s = createTensorSchema(); - DocBuilder builder(s); + EmptyDocBuilder builder([](auto& header) { header.addTensorField("a1", sparse_tensor); }); auto tensor = make_tensor(TensorSpec(sparse_tensor) .add({{"x", "6"}, {"y", "7"}}, 9)); auto doc = createTensorPutDoc(builder, *tensor); @@ -720,8 +705,7 @@ TEST_F(AttributeWriterTest, handles_tensor_assign_update) EXPECT_TRUE(static_cast<bool>(tensor2)); EXPECT_EQ(*tensor, *tensor2); - const document::DocumentType &dt(builder.getDocumentType()); - DocumentUpdate upd(*builder.getDocumentTypeRepo(), dt, DocumentId("id:ns:searchdocument::1")); + DocumentUpdate upd(builder.get_repo(), builder.get_document_type(), DocumentId("id:ns:searchdocument::1")); auto new_tensor = make_tensor(TensorSpec(sparse_tensor) .add({{"x", "8"}, {"y", "9"}}, 11)); TensorDataType xySparseTensorDataType(vespalib::eval::ValueType::from_spec(sparse_tensor)); @@ -762,12 +746,10 @@ putAttributes(AttributeWriterTest &t, std::vector<uint32_t> expExecuteHistory) vespalib::string a2_name = "a2x"; vespalib::string a3_name = "a3y"; - Schema s; - s.addAttributeField(Schema::AttributeField(a1_name, schema::DataType::INT32, CollectionType::SINGLE)); - s.addAttributeField(Schema::AttributeField(a2_name, schema::DataType::INT32, CollectionType::SINGLE)); - s.addAttributeField(Schema::AttributeField(a3_name, schema::DataType::INT32, CollectionType::SINGLE)); - - DocBuilder idb(s); + EmptyDocBuilder edb([&](auto& header) + { header.addField(a1_name, DataType::T_INT) + .addField(a2_name, DataType::T_INT) + .addField(a3_name, DataType::T_INT); }); auto a1 = t.addAttribute(a1_name); auto a2 = t.addAttribute(a2_name); @@ -777,11 +759,11 @@ putAttributes(AttributeWriterTest &t, std::vector<uint32_t> expExecuteHistory) EXPECT_EQ(1u, a1->getNumDocs()); EXPECT_EQ(1u, a2->getNumDocs()); EXPECT_EQ(1u, a3->getNumDocs()); - t.put(1, *idb.startDocument("id:ns:searchdocument::1"). - startAttributeField(a1_name).addInt(10).endField(). - startAttributeField(a2_name).addInt(15).endField(). - startAttributeField(a3_name).addInt(20).endField(). - endDocument(), 1); + auto doc = edb.make_document("id:ns:searchdocument::1"); + doc->setValue(a1_name, IntFieldValue(10)); + doc->setValue(a2_name, IntFieldValue(15)); + doc->setValue(a3_name, IntFieldValue(20)); + t.put(1, *doc, 1); assertPutDone(*a1, 10); assertPutDone(*a2, 15); assertPutDone(*a3, 20); @@ -889,16 +871,14 @@ TEST_F(AttributeWriterTest, tensor_attributes_using_two_phase_put_are_in_separat class TwoPhasePutTest : public AttributeWriterTest { public: - Schema schema; - DocBuilder builder; + EmptyDocBuilder builder; vespalib::string doc_id; std::shared_ptr<MockDenseTensorAttribute> attr; std::unique_ptr<Value> tensor; TwoPhasePutTest() : AttributeWriterTest(), - schema(createTensorSchema(dense_tensor)), - builder(schema), + builder([&](auto& header) { header.addTensorField("a1", dense_tensor); }), doc_id("id:ns:searchdocument::1"), attr() { @@ -923,16 +903,17 @@ public: return createTensorPutDoc(builder, *tensor); } Document::UP make_no_field_doc() { - return builder.startDocument(doc_id).endDocument(); + return builder.make_document(doc_id); } Document::UP make_no_tensor_doc() { - return builder.startDocument(doc_id). - startAttributeField("a1"). - addTensor(std::unique_ptr<vespalib::eval::Value>()).endField().endDocument(); + auto doc = builder.make_document(doc_id); + TensorFieldValue fv(*doc->getField("a1").getDataType().cast_tensor()); + doc->setValue("a1", fv); + return doc; } DocumentUpdate::UP make_assign_update() { - auto upd = std::make_unique<DocumentUpdate>(*builder.getDocumentTypeRepo(), - builder.getDocumentType(), + auto upd = std::make_unique<DocumentUpdate>(builder.get_repo(), + builder.get_document_type(), DocumentId(doc_id)); TensorDataType tensor_type(vespalib::eval::ValueType::from_spec(dense_tensor)); auto tensor_value = std::make_unique<TensorFieldValue>(tensor_type); diff --git a/searchcore/src/tests/proton/docsummary/docsummary.cpp b/searchcore/src/tests/proton/docsummary/docsummary.cpp index 55353217d17..e76a7f72cbb 100644 --- a/searchcore/src/tests/proton/docsummary/docsummary.cpp +++ b/searchcore/src/tests/proton/docsummary/docsummary.cpp @@ -51,6 +51,7 @@ #include <vespa/searchlib/attribute/interlock.h> #include <vespa/searchlib/engine/docsumapi.h> #include <vespa/searchlib/index/dummyfileheadercontext.h> +#include <vespa/searchlib/index/empty_doc_builder.h> #include <vespa/searchlib/tensor/tensor_attribute.h> #include <vespa/searchlib/transactionlog/nosyncproxy.h> #include <vespa/searchlib/transactionlog/translogserver.h> @@ -68,7 +69,6 @@ #include <vespa/vespalib/util/size_literals.h> #include <vespa/config-summary.h> #include <filesystem> -#include <functional> #include <regex> #include <vespa/log/log.h> @@ -104,21 +104,6 @@ using namespace vespalib::slime; namespace proton { -using AddFieldsType = std::function<void(document::config_builder::Struct&)>; - -DocumenttypesConfig -get_document_types_config(AddFieldsType add_fields) -{ - using namespace document::config_builder; - DocumenttypesConfigBuilderHelper builder; - Struct header("searchdocument.header"); - add_fields(header); - builder.document(42, "searchdocument", - header, - Struct("searchdocument.body")); - return builder.config(); -} - class MockDocsumFieldWriterFactory : public search::docsummary::IDocsumFieldWriterFactory { public: @@ -143,12 +128,10 @@ private: vespalib::string _dir; }; -class BuildContext +class BuildContext : public EmptyDocBuilder { public: DirMaker _dmk; - std::shared_ptr<const DocumentTypeRepo> _repo; - const DocumentType* _document_type; document::FixedTypeRepo _fixed_repo; DummyFileHeaderContext _fileHeaderContext; vespalib::ThreadStackExecutor _summaryExecutor; @@ -160,41 +143,21 @@ public: ~BuildContext(); - const DocumentTypeRepo& get_repo() { return *_repo; } - const DocumentType& get_document_type() { return* _document_type; } const document::FixedTypeRepo& get_fixed_repo() { return _fixed_repo; } - std::unique_ptr<Document> - make_document(vespalib::string document_id) - { - auto doc = std::make_unique<Document>(get_document_type(), - DocumentId(document_id)); - doc->setRepo(get_repo()); - return doc; - } - void put_document(uint32_t docId, std::unique_ptr<Document> doc) { _str.write(_serialNum++, docId, *doc); } - const DataType & - get_data_type(const vespalib::string &name) const - { - const DataType *type = _repo->getDataType(*_document_type, name); - ASSERT_TRUE(type); - return *type; - } - StringFieldValue make_annotated_string(); }; BuildContext::BuildContext(AddFieldsType add_fields) - : _dmk("summary"), - _repo(std::make_shared<const DocumentTypeRepo>(get_document_types_config(add_fields))), - _document_type(_repo->getDocumentType("searchdocument")), - _fixed_repo(*_repo, *_document_type), + : EmptyDocBuilder(add_fields), + _dmk("summary"), + _fixed_repo(get_repo(), get_document_type()), _summaryExecutor(4, 128_Ki), _noTlSyncer(), _str(_summaryExecutor, "summary", @@ -547,7 +510,7 @@ GlobalId gid9 = DocumentId("id:ns:searchdocument::9").getGlobalId(); // not exis TEST("requireThatDocsumRequestIsProcessed") { BuildContext bc([](auto& header) { header.addField("a", DataType::T_INT); }); - DBContext dc(bc._repo, getDocTypeName()); + DBContext dc(bc.get_repo_sp(), getDocTypeName()); auto doc = bc.make_document("id:ns:searchdocument::1"); doc->setValue("a", IntFieldValue(10)); dc.put(*doc, 1); @@ -578,7 +541,7 @@ TEST("requireThatRewritersAreUsed") BuildContext bc([](auto& header) { header.addField("aa", DataType::T_INT) .addField("ab", DataType::T_INT); }); - DBContext dc(bc._repo, getDocTypeName()); + DBContext dc(bc.get_repo_sp(), getDocTypeName()); auto doc = bc.make_document("id:ns:searchdocument::1"); doc->setValue("aa", IntFieldValue(10)); doc->setValue("ab", IntFieldValue(20)); @@ -596,7 +559,7 @@ TEST("requireThatSummariesTimeout") BuildContext bc([](auto& header) { header.addField("aa", DataType::T_INT) .addField("ab", DataType::T_INT); }); - DBContext dc(bc._repo, getDocTypeName()); + DBContext dc(bc.get_repo_sp(), getDocTypeName()); auto doc = bc.make_document("id:ns:searchdocument::1"); doc->setValue("aa", IntFieldValue(10)); doc->setValue("ab", IntFieldValue(20)); @@ -620,7 +583,7 @@ void verifyFieldListHonoured(DocsumRequest::FieldList fields, const std::string BuildContext bc([](auto& header) { header.addField("ba", DataType::T_INT) .addField("bb", DataType::T_FLOAT); }); - DBContext dc(bc._repo, getDocTypeName()); + DBContext dc(bc.get_repo_sp(), getDocTypeName()); auto doc = bc.make_document("id:ns:searchdocument::1"); doc->setValue("ba", IntFieldValue(10)); doc->setValue("bb", FloatFieldValue(10.1250)); @@ -657,7 +620,7 @@ TEST("requireThatAttributesAreUsed") .addField("bh", Wset(DataType::T_FLOAT)) .addField("bi", Wset(DataType::T_STRING)) .addTensorField("bj", "tensor(x{},y{})"); }); - DBContext dc(bc._repo, getDocTypeName()); + DBContext dc(bc.get_repo_sp(), getDocTypeName()); auto doc = bc.make_document("id:ns:searchdocument::1"); dc.put(*doc, 1); // empty doc doc = bc.make_document("id:ns:searchdocument::2"); @@ -752,17 +715,17 @@ TEST("requireThatAttributesAreUsed") TEST("requireThatSummaryAdapterHandlesPutAndRemove") { BuildContext bc([](auto& header) { header.addField("f1", DataType::T_STRING); }); - DBContext dc(bc._repo, getDocTypeName()); + DBContext dc(bc.get_repo_sp(), getDocTypeName()); auto exp = bc.make_document("id:ns:searchdocument::1"); exp->setValue("f1", StringFieldValue("foo")); dc._sa->put(1, 1, *exp); IDocumentStore & store = dc._ddb->getReadySubDB()->getSummaryManager()->getBackingStore(); - Document::UP act = store.read(1, *bc._repo); + Document::UP act = store.read(1, bc.get_repo()); 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() == nullptr); + EXPECT_TRUE(store.read(1, bc.get_repo()).get() == nullptr); } const std::string TERM_ORIG = "\357\277\271"; @@ -780,20 +743,20 @@ TEST_F("requireThatAnnotationsAreUsed", Fixture) BuildContext bc([](auto& header) { header.addField("g", DataType::T_STRING) .addField("dynamicstring", DataType::T_STRING); }); - DBContext dc(bc._repo, getDocTypeName()); + DBContext dc(bc.get_repo_sp(), getDocTypeName()); auto exp = bc.make_document("id:ns:searchdocument::0"); exp->setValue("g", bc.make_annotated_string()); exp->setValue("dynamicstring", bc.make_annotated_string()); dc._sa->put(1, 1, *exp); IDocumentStore & store = dc._ddb->getReadySubDB()->getSummaryManager()->getBackingStore(); - Document::UP act = store.read(1, *bc._repo); + Document::UP act = store.read(1, bc.get_repo()); 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()); - DocumentStoreAdapter dsa(store, *bc._repo); + DocumentStoreAdapter dsa(store, bc.get_repo()); EXPECT_TRUE(assertString("foo bar", "g", dsa, 1)); EXPECT_TRUE(assertAnnotatedString(TERM_EMPTY + "foo" + TERM_SEP + " " + TERM_SEP + @@ -809,7 +772,7 @@ TEST_F("requireThatUrisAreUsed", Fixture) header.addField("urisingle", UrlDataType::getInstance().getId()) .addField("uriarray", Array(UrlDataType::getInstance().getId())) .addField("uriwset", Wset(UrlDataType::getInstance().getId())); }); - DBContext dc(bc._repo, getDocTypeName()); + DBContext dc(bc.get_repo_sp(), getDocTypeName()); auto exp = bc.make_document("id:ns:searchdocument::0"); StructFieldValue uri(bc.get_data_type("url")); uri.setValue("all", StringFieldValue("http://www.example.com:81/fluke?ab=2#4")); @@ -860,11 +823,11 @@ TEST_F("requireThatUrisAreUsed", Fixture) IDocumentStore & store = dc._ddb->getReadySubDB()->getSummaryManager()->getBackingStore(); - Document::UP act = store.read(1, *bc._repo); + Document::UP act = store.read(1, bc.get_repo()); EXPECT_TRUE(act.get() != nullptr); EXPECT_EQUAL(exp->getType(), act->getType()); - DocumentStoreAdapter dsa(store, *bc._repo); + DocumentStoreAdapter dsa(store, bc.get_repo()); auto res = dsa.get_document(1); { vespalib::Slime slime; @@ -901,7 +864,7 @@ TEST("requireThatPositionsAreUsed") header.addField("sp2", DataType::T_LONG) .addField("ap2", Array(DataType::T_LONG)) .addField("wp2", Wset(DataType::T_LONG)); }); - DBContext dc(bc._repo, getDocTypeName()); + DBContext dc(bc.get_repo_sp(), getDocTypeName()); auto exp = bc.make_document("id:ns:searchdocument::1"); exp->setValue("sp2", LongFieldValue(ZCurve::encode(1002, 1003))); ArrayFieldValue pos_array(bc.get_data_type("Array<Long>")); @@ -915,7 +878,7 @@ TEST("requireThatPositionsAreUsed") dc.put(*exp, 1); IDocumentStore & store = dc._ddb->getReadySubDB()->getSummaryManager()->getBackingStore(); - Document::UP act = store.read(1, *bc._repo); + Document::UP act = store.read(1, bc.get_repo()); EXPECT_TRUE(act); EXPECT_EQUAL(exp->getType(), act->getType()); @@ -962,7 +925,7 @@ TEST_F("requireThatRawFieldsWorks", Fixture) raw1w1 += std::string(&binaryBlob[0], &binaryBlob[0] + binaryBlob.size()); - DBContext dc(bc._repo, getDocTypeName()); + DBContext dc(bc.get_repo_sp(), getDocTypeName()); auto exp = bc.make_document("id:ns:searchdocument::0"); exp->setValue("i", RawFieldValue(raw1s)); ArrayFieldValue raw_array(bc.get_data_type("Array<Raw>")); @@ -976,11 +939,11 @@ TEST_F("requireThatRawFieldsWorks", Fixture) dc._sa->put(1, 1, *exp); IDocumentStore & store = dc._ddb->getReadySubDB()->getSummaryManager()->getBackingStore(); - Document::UP act = store.read(1, *bc._repo); + Document::UP act = store.read(1, bc.get_repo()); EXPECT_TRUE(act.get() != nullptr); EXPECT_EQUAL(exp->getType(), act->getType()); - DocumentStoreAdapter dsa(store, *bc._repo); + DocumentStoreAdapter dsa(store, bc.get_repo()); ASSERT_TRUE(assertString(raw1s, "i", dsa, 1)); diff --git a/searchlib/src/vespa/searchlib/index/CMakeLists.txt b/searchlib/src/vespa/searchlib/index/CMakeLists.txt index 00a06363596..958614844d1 100644 --- a/searchlib/src/vespa/searchlib/index/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/index/CMakeLists.txt @@ -6,6 +6,7 @@ vespa_add_library(searchlib_searchlib_index OBJECT docidandfeatures.cpp doctypebuilder.cpp dummyfileheadercontext.cpp + empty_doc_builder.cpp indexbuilder.cpp postinglisthandle.cpp postinglistcounts.cpp diff --git a/searchlib/src/vespa/searchlib/index/empty_doc_builder.cpp b/searchlib/src/vespa/searchlib/index/empty_doc_builder.cpp new file mode 100644 index 00000000000..45588791926 --- /dev/null +++ b/searchlib/src/vespa/searchlib/index/empty_doc_builder.cpp @@ -0,0 +1,59 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "empty_doc_builder.h" +#include <vespa/document/datatype/documenttype.h> +#include <vespa/document/fieldvalue/document.h> +#include <vespa/document/repo/documenttyperepo.h> +#include <vespa/document/repo/configbuilder.h> +#include <cassert> + +using document::DataType; +using document::Document; +using document::DocumentId; +using document::DocumentTypeRepo; + +namespace search::index { + +namespace { + +DocumenttypesConfig +get_document_types_config(EmptyDocBuilder::AddFieldsType add_fields) +{ + using namespace document::config_builder; + DocumenttypesConfigBuilderHelper builder; + Struct header("searchdocument.header"); + add_fields(header); + builder.document(42, "searchdocument", + header, + Struct("searchdocument.body")); + return builder.config(); +} + +} + +EmptyDocBuilder::EmptyDocBuilder(AddFieldsType add_fields) + : _repo(std::make_shared<const DocumentTypeRepo>(get_document_types_config(add_fields))), + _document_type(_repo->getDocumentType("searchdocument")) +{ +} + +EmptyDocBuilder::~EmptyDocBuilder() = default; + + +std::unique_ptr<Document> +EmptyDocBuilder::make_document(vespalib::string document_id) +{ + auto doc = std::make_unique<Document>(get_document_type(), DocumentId(document_id)); + doc->setRepo(get_repo()); + return doc; +} + +const DataType& +EmptyDocBuilder::get_data_type(const vespalib::string &name) const +{ + const DataType *type = _repo->getDataType(*_document_type, name); + assert(type); + return *type; +} + +} diff --git a/searchlib/src/vespa/searchlib/index/empty_doc_builder.h b/searchlib/src/vespa/searchlib/index/empty_doc_builder.h new file mode 100644 index 00000000000..d4b54359f87 --- /dev/null +++ b/searchlib/src/vespa/searchlib/index/empty_doc_builder.h @@ -0,0 +1,36 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/vespalib/stllike/string.h> +#include <functional> +#include <memory> + +namespace document { +class DataType; +class Document; +class DocumentType; +class DocumentTypeRepo; +} +namespace document::config_builder { struct Struct; } + +namespace search::index { + +/* + * Class used to make empty search documents. + */ +class EmptyDocBuilder { + std::shared_ptr<const document::DocumentTypeRepo> _repo; + const document::DocumentType* _document_type; +public: + using AddFieldsType = std::function<void(document::config_builder::Struct&)>; + explicit EmptyDocBuilder(AddFieldsType add_fields); + ~EmptyDocBuilder(); + const document::DocumentTypeRepo& get_repo() const noexcept { return *_repo; } + std::shared_ptr<const document::DocumentTypeRepo> get_repo_sp() const noexcept { return _repo; } + const document::DocumentType& get_document_type() const noexcept { return *_document_type; } + std::unique_ptr<document::Document> make_document(vespalib::string document_id); + const document::DataType &get_data_type(const vespalib::string &name) const; +}; + +} |