aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@online.no>2022-09-21 16:41:42 +0200
committerTor Egge <Tor.Egge@online.no>2022-09-21 16:41:42 +0200
commitc918094f4b3c7c02d6e8cea51b3c5d2650fecb2a (patch)
treeb7b866395b96dec68e6ed4950ddaa0cc7b86d76a
parent5e08068fa0c7def183cf94b659e7d6fdb5ec1297 (diff)
Stop using search::index::DocBuilder in searchcore attribute unit test.
-rw-r--r--searchcore/src/tests/proton/attribute/attribute_test.cpp193
-rw-r--r--searchcore/src/tests/proton/docsummary/docsummary.cpp85
-rw-r--r--searchlib/src/vespa/searchlib/index/CMakeLists.txt1
-rw-r--r--searchlib/src/vespa/searchlib/index/empty_doc_builder.cpp59
-rw-r--r--searchlib/src/vespa/searchlib/index/empty_doc_builder.h36
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;
+};
+
+}