diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2018-06-14 09:37:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-14 09:37:36 +0200 |
commit | 3302fb4a790925ad0437d2bd7b4747c4d02a971b (patch) | |
tree | b4299bc5f651565a86180d0389eef9df4bbdbbbc | |
parent | f562d35d3636cfbb6fd6d9caeb94d97dcdfc0f8e (diff) | |
parent | 747bda75a444c866d8e4752315e6949fd23194bd (diff) |
Merge pull request #6185 from vespa-engine/balder/balder/prepare-lazy-deserialize-rebased-2
Balder/balder/prepare lazy deserialize rebased 2
61 files changed, 587 insertions, 556 deletions
diff --git a/document/src/tests/documentselectparsertest.cpp b/document/src/tests/documentselectparsertest.cpp index 05ec2ce99d0..2433bfecdab 100644 --- a/document/src/tests/documentselectparsertest.cpp +++ b/document/src/tests/documentselectparsertest.cpp @@ -163,8 +163,7 @@ DocumentUpdate::SP DocumentSelectParserTest::createUpdate( const std::string& hstr) { const DocumentType* type = _repo->getDocumentType(doctype); - DocumentUpdate::SP doc( - new DocumentUpdate(*type, DocumentId(id))); + DocumentUpdate::SP doc(new DocumentUpdate(*_repo, *type, DocumentId(id))); doc->addUpdate(FieldUpdate(doc->getType().getField("headerval")) .addUpdate(AssignValueUpdate(IntFieldValue(hint)))); doc->addUpdate(FieldUpdate(doc->getType().getField("hstringval")) diff --git a/document/src/tests/documentupdatetestcase.cpp b/document/src/tests/documentupdatetestcase.cpp index 9ba17d95264..2a77d610420 100644 --- a/document/src/tests/documentupdatetestcase.cpp +++ b/document/src/tests/documentupdatetestcase.cpp @@ -191,16 +191,15 @@ DocumentUpdateTest::testSimpleUsage() { fieldUpdate.addUpdate(AssignValueUpdate(IntFieldValue(1))); ByteBuffer::UP fieldBuf = serialize(fieldUpdate); fieldBuf->flip(); - FieldUpdate fieldUpdateCopy(repo, *docType, *fieldBuf, - Document::getNewestSerializationVersion()); + FieldUpdate fieldUpdateCopy(repo, *docType, *fieldBuf, Document::getNewestSerializationVersion()); CPPUNIT_ASSERT_EQUAL(fieldUpdate, fieldUpdateCopy); // Test that a document update can be serialized - DocumentUpdate docUpdate(*docType, DocumentId("doc::testdoc")); + DocumentUpdate docUpdate(repo, *docType, DocumentId("doc::testdoc")); docUpdate.addUpdate(fieldUpdateCopy); - ByteBuffer::UP docBuf = serialize42(docUpdate); + ByteBuffer::UP docBuf = serializeHEAD(docUpdate); docBuf->flip(); - DocumentUpdate::UP docUpdateCopy(DocumentUpdate::create42(repo, *docBuf)); + auto docUpdateCopy(DocumentUpdate::createHEAD(repo, nbostream(docBuf->getBufferAtPos(), docBuf->getRemaining()))); // Create a test document Document doc(*docType, DocumentId("doc::testdoc")); @@ -214,62 +213,53 @@ DocumentUpdateTest::testSimpleUsage() { // Verify that we can apply simple updates to it { Document updated(doc); - DocumentUpdate upd(*docType, DocumentId("doc::testdoc")); - upd.addUpdate(FieldUpdate(docType->getField("intf")) - .addUpdate(ClearValueUpdate())); + DocumentUpdate upd(repo, *docType, DocumentId("doc::testdoc")); + upd.addUpdate(FieldUpdate(docType->getField("intf")).addUpdate(ClearValueUpdate())); upd.applyTo(updated); CPPUNIT_ASSERT(doc != updated); CPPUNIT_ASSERT(! updated.getValue("intf")); } { Document updated(doc); - DocumentUpdate upd(*docType, DocumentId("doc::testdoc")); - upd.addUpdate(FieldUpdate(docType->getField("intf")) - .addUpdate(AssignValueUpdate(IntFieldValue(15)))); + DocumentUpdate upd(repo, *docType, DocumentId("doc::testdoc")); + upd.addUpdate(FieldUpdate(docType->getField("intf")).addUpdate(AssignValueUpdate(IntFieldValue(15)))); upd.applyTo(updated); CPPUNIT_ASSERT(doc != updated); CPPUNIT_ASSERT_EQUAL(15, updated.getValue("intf")->getAsInt()); } { Document updated(doc); - DocumentUpdate upd(*docType, DocumentId("doc::testdoc")); - upd.addUpdate(FieldUpdate(docType->getField("intf")) - .addUpdate(ArithmeticValueUpdate( - ArithmeticValueUpdate::Add, 15))); + DocumentUpdate upd(repo, *docType, DocumentId("doc::testdoc")); + upd.addUpdate(FieldUpdate(docType->getField("intf")).addUpdate(ArithmeticValueUpdate(ArithmeticValueUpdate::Add, 15))); upd.applyTo(updated); CPPUNIT_ASSERT(doc != updated); CPPUNIT_ASSERT_EQUAL(20, updated.getValue("intf")->getAsInt()); } { Document updated(doc); - DocumentUpdate upd(*docType, DocumentId("doc::testdoc")); - upd.addUpdate(FieldUpdate(docType->getField("intarr")) - .addUpdate(AddValueUpdate(IntFieldValue(4)))); + DocumentUpdate upd(repo, *docType, DocumentId("doc::testdoc")); + upd.addUpdate(FieldUpdate(docType->getField("intarr")).addUpdate(AddValueUpdate(IntFieldValue(4)))); upd.applyTo(updated); CPPUNIT_ASSERT(doc != updated); - std::unique_ptr<ArrayFieldValue> val(dynamic_cast<ArrayFieldValue*>( - updated.getValue("intarr").release())); + std::unique_ptr<ArrayFieldValue> val(dynamic_cast<ArrayFieldValue*>(updated.getValue("intarr").release())); CPPUNIT_ASSERT_EQUAL(size_t(3), val->size()); CPPUNIT_ASSERT_EQUAL(4, (*val)[2].getAsInt()); } { Document updated(doc); - DocumentUpdate upd(*docType, DocumentId("doc::testdoc")); - upd.addUpdate(FieldUpdate(docType->getField("intarr")) - .addUpdate(RemoveValueUpdate(IntFieldValue(3)))); + DocumentUpdate upd(repo, *docType, DocumentId("doc::testdoc")); + upd.addUpdate(FieldUpdate(docType->getField("intarr")).addUpdate(RemoveValueUpdate(IntFieldValue(3)))); upd.applyTo(updated); CPPUNIT_ASSERT(doc != updated); - std::unique_ptr<ArrayFieldValue> val(dynamic_cast<ArrayFieldValue*>( - updated.getValue("intarr").release())); + std::unique_ptr<ArrayFieldValue> val(dynamic_cast<ArrayFieldValue*>(updated.getValue("intarr").release())); CPPUNIT_ASSERT_EQUAL(size_t(1), val->size()); CPPUNIT_ASSERT_EQUAL(7, (*val)[0].getAsInt()); } { Document updated(doc); - DocumentUpdate upd(*docType, DocumentId("doc::testdoc")); + DocumentUpdate upd(repo, *docType, DocumentId("doc::testdoc")); upd.addUpdate(FieldUpdate(docType->getField("bytef")) - .addUpdate(ArithmeticValueUpdate( - ArithmeticValueUpdate::Add, 15))); + .addUpdate(ArithmeticValueUpdate(ArithmeticValueUpdate::Add, 15))); upd.applyTo(updated); CPPUNIT_ASSERT(doc != updated); CPPUNIT_ASSERT_EQUAL(15, (int) updated.getValue("bytef")->getAsByte()); @@ -286,9 +276,8 @@ DocumentUpdateTest::testClearField() CPPUNIT_ASSERT_EQUAL(4, doc->getValue("headerval")->getAsInt()); // Apply an update. - DocumentUpdate(*doc->getDataType(), doc->getId()) - .addUpdate(FieldUpdate(doc->getField("headerval")) - .addUpdate(AssignValueUpdate())) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) + .addUpdate(FieldUpdate(doc->getField("headerval")).addUpdate(AssignValueUpdate())) .applyTo(*doc); CPPUNIT_ASSERT(!doc->getValue("headerval")); } @@ -303,9 +292,8 @@ DocumentUpdateTest::testUpdateApplySingleValue() CPPUNIT_ASSERT_EQUAL(4, doc->getValue("headerval")->getAsInt()); // Apply an update. - DocumentUpdate(*doc->getDataType(), doc->getId()) - .addUpdate(FieldUpdate(doc->getField("headerval")) - .addUpdate(AssignValueUpdate(IntFieldValue(9)))) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) + .addUpdate(FieldUpdate(doc->getField("headerval")).addUpdate(AssignValueUpdate(IntFieldValue(9)))) .applyTo(*doc); CPPUNIT_ASSERT_EQUAL(9, doc->getValue("headerval")->getAsInt()); } @@ -316,28 +304,23 @@ DocumentUpdateTest::testUpdateArray() // Create a document. TestDocMan docMan; Document::UP doc(docMan.createDocument()); - CPPUNIT_ASSERT_EQUAL((document::FieldValue*)NULL, - doc->getValue(doc->getField("tags")).get()); + CPPUNIT_ASSERT_EQUAL((document::FieldValue*)NULL, doc->getValue(doc->getField("tags")).get()); // Assign array field. ArrayFieldValue myarray(doc->getType().getField("tags").getDataType()); myarray.add(StringFieldValue("foo")); myarray.add(StringFieldValue("bar")); - DocumentUpdate(*doc->getDataType(), doc->getId()) - .addUpdate(FieldUpdate(doc->getField("tags")) - .addUpdate(AssignValueUpdate(myarray))) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) + .addUpdate(FieldUpdate(doc->getField("tags")).addUpdate(AssignValueUpdate(myarray))) .applyTo(*doc); - std::unique_ptr<ArrayFieldValue> - fval1(doc->getAs<ArrayFieldValue>(doc->getField("tags"))); + auto fval1(doc->getAs<ArrayFieldValue>(doc->getField("tags"))); CPPUNIT_ASSERT_EQUAL((size_t) 2, fval1->size()); - CPPUNIT_ASSERT_EQUAL(std::string("foo"), - std::string((*fval1)[0].getAsString())); - CPPUNIT_ASSERT_EQUAL(std::string("bar"), - std::string((*fval1)[1].getAsString())); + CPPUNIT_ASSERT_EQUAL(std::string("foo"), std::string((*fval1)[0].getAsString())); + CPPUNIT_ASSERT_EQUAL(std::string("bar"), std::string((*fval1)[1].getAsString())); // Append array field - DocumentUpdate(*doc->getDataType(), doc->getId()) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) .addUpdate(FieldUpdate(doc->getField("tags")) .addUpdate(AddValueUpdate(StringFieldValue("another"))) .addUpdate(AddValueUpdate(StringFieldValue("tag")))) @@ -345,21 +328,16 @@ DocumentUpdateTest::testUpdateArray() std::unique_ptr<ArrayFieldValue> fval2(doc->getAs<ArrayFieldValue>(doc->getField("tags"))); CPPUNIT_ASSERT_EQUAL((size_t) 4, fval2->size()); - CPPUNIT_ASSERT_EQUAL(std::string("foo"), - std::string((*fval2)[0].getAsString())); - CPPUNIT_ASSERT_EQUAL(std::string("bar"), - std::string((*fval2)[1].getAsString())); - CPPUNIT_ASSERT_EQUAL(std::string("another"), - std::string((*fval2)[2].getAsString())); - CPPUNIT_ASSERT_EQUAL(std::string("tag"), - std::string((*fval2)[3].getAsString())); + CPPUNIT_ASSERT_EQUAL(std::string("foo"), std::string((*fval2)[0].getAsString())); + CPPUNIT_ASSERT_EQUAL(std::string("bar"), std::string((*fval2)[1].getAsString())); + CPPUNIT_ASSERT_EQUAL(std::string("another"), std::string((*fval2)[2].getAsString())); + CPPUNIT_ASSERT_EQUAL(std::string("tag"), std::string((*fval2)[3].getAsString())); // Append single value. try { - DocumentUpdate(*doc->getDataType(), doc->getId()) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) .addUpdate(FieldUpdate(doc->getField("tags")) - .addUpdate(AssignValueUpdate( - StringFieldValue("THROW MEH!")))) + .addUpdate(AssignValueUpdate(StringFieldValue("THROW MEH!")))) .applyTo(*doc); CPPUNIT_FAIL("Expected exception when assinging a string value to an " "array field."); @@ -369,25 +347,22 @@ DocumentUpdateTest::testUpdateArray() } // Remove array field. - DocumentUpdate(*doc->getDataType(), doc->getId()) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) .addUpdate(FieldUpdate(doc->getField("tags")) .addUpdate(RemoveValueUpdate(StringFieldValue("foo"))) .addUpdate(RemoveValueUpdate(StringFieldValue("tag")))) .applyTo(*doc); - std::unique_ptr<ArrayFieldValue> - fval3(doc->getAs<ArrayFieldValue>(doc->getField("tags"))); + auto fval3(doc->getAs<ArrayFieldValue>(doc->getField("tags"))); CPPUNIT_ASSERT_EQUAL((size_t) 2, fval3->size()); - CPPUNIT_ASSERT_EQUAL(std::string("bar"), - std::string((*fval3)[0].getAsString())); - CPPUNIT_ASSERT_EQUAL(std::string("another"), - std::string((*fval3)[1].getAsString())); + CPPUNIT_ASSERT_EQUAL(std::string("bar"), std::string((*fval3)[0].getAsString())); + CPPUNIT_ASSERT_EQUAL(std::string("another"), std::string((*fval3)[1].getAsString())); // Remove array from array. ArrayFieldValue myarray2(doc->getType().getField("tags").getDataType()); myarray2.add(StringFieldValue("foo")); myarray2.add(StringFieldValue("bar")); try { - DocumentUpdate(*doc->getDataType(), doc->getId()) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) .addUpdate(FieldUpdate(doc->getField("tags")) .addUpdate(RemoveValueUpdate(myarray2))) .applyTo(*doc); @@ -412,12 +387,10 @@ DocumentUpdateTest::testUpdateWeightedSet() WeightedSetFieldValue wset(field.getDataType()); wset.add(StringFieldValue("foo"), 3); wset.add(StringFieldValue("bar"), 14); - DocumentUpdate(*doc->getDataType(), doc->getId()) - .addUpdate(FieldUpdate(field) - .addUpdate(AssignValueUpdate(wset))) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) + .addUpdate(FieldUpdate(field).addUpdate(AssignValueUpdate(wset))) .applyTo(*doc); - std::unique_ptr<WeightedSetFieldValue> - fval1(doc->getAs<WeightedSetFieldValue>(field)); + auto fval1(doc->getAs<WeightedSetFieldValue>(field)); CPPUNIT_ASSERT_EQUAL((size_t) 2, fval1->size()); CPPUNIT_ASSERT(fval1->contains(StringFieldValue("foo"))); CPPUNIT_ASSERT(fval1->find(StringFieldValue("foo")) != fval1->end()); @@ -430,12 +403,11 @@ DocumentUpdateTest::testUpdateWeightedSet() WeightedSetFieldValue wset2(field.getDataType()); wset2.add(StringFieldValue("foo"), 16); wset2.add(StringFieldValue("bar"), 24); - DocumentUpdate(*doc->getDataType(), doc->getId()) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) .addUpdate(FieldUpdate(field) .addUpdate(AssignValueUpdate(wset2))) .applyTo(*doc); - std::unique_ptr<WeightedSetFieldValue> - fval2(doc->getAs<WeightedSetFieldValue>(field)); + auto fval2(doc->getAs<WeightedSetFieldValue>(field)); CPPUNIT_ASSERT_EQUAL((size_t) 2, fval2->size()); CPPUNIT_ASSERT(fval2->contains(StringFieldValue("foo"))); CPPUNIT_ASSERT(fval2->find(StringFieldValue("foo")) != fval1->end()); @@ -445,12 +417,10 @@ DocumentUpdateTest::testUpdateWeightedSet() CPPUNIT_ASSERT_EQUAL(24, fval2->get(StringFieldValue("bar"), 0)); // Append weighted field - DocumentUpdate(*doc->getDataType(), doc->getId()) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) .addUpdate(FieldUpdate(field) - .addUpdate(AddValueUpdate(StringFieldValue("foo")) - .setWeight(3)) - .addUpdate(AddValueUpdate(StringFieldValue("too")) - .setWeight(14))) + .addUpdate(AddValueUpdate(StringFieldValue("foo")).setWeight(3)) + .addUpdate(AddValueUpdate(StringFieldValue("too")).setWeight(14))) .applyTo(*doc); std::unique_ptr<WeightedSetFieldValue> fval3(doc->getAs<WeightedSetFieldValue>(field)); @@ -463,13 +433,12 @@ DocumentUpdateTest::testUpdateWeightedSet() CPPUNIT_ASSERT_EQUAL(14, fval3->get(StringFieldValue("too"), 0)); // Remove weighted field - DocumentUpdate(*doc->getDataType(), doc->getId()) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) .addUpdate(FieldUpdate(field) .addUpdate(RemoveValueUpdate(StringFieldValue("foo"))) .addUpdate(RemoveValueUpdate(StringFieldValue("too")))) .applyTo(*doc); - std::unique_ptr<WeightedSetFieldValue> - fval4(doc->getAs<WeightedSetFieldValue>(field)); + auto fval4(doc->getAs<WeightedSetFieldValue>(field)); CPPUNIT_ASSERT_EQUAL((size_t) 1, fval4->size()); CPPUNIT_ASSERT(!fval4->contains(StringFieldValue("foo"))); CPPUNIT_ASSERT(fval4->contains(StringFieldValue("bar"))); @@ -500,21 +469,18 @@ struct WeightedSetAutoCreateFixture // and remove-if-zero attributes set. Attempting to explicitly create // a field matching those characteristics will in fact fail with a // redefinition error. - builder.document(42, "test", - Struct("test.header") - .addField("strwset", DataType::T_TAG), - Struct("test.body")); + builder.document(42, "test", Struct("test.header").addField("strwset", DataType::T_TAG), Struct("test.body")); return builder.config(); } }; -WeightedSetAutoCreateFixture::~WeightedSetAutoCreateFixture() {} +WeightedSetAutoCreateFixture::~WeightedSetAutoCreateFixture() = default; WeightedSetAutoCreateFixture::WeightedSetAutoCreateFixture() : repo(makeConfig()), docType(repo.getDocumentType("test")), doc(*docType, DocumentId("doc::testdoc")), field(docType->getField("strwset")), - update(*docType, DocumentId("doc::testdoc")) + update(repo, *docType, DocumentId("doc::testdoc")) { update.addUpdate(FieldUpdate(field) .addUpdate(MapValueUpdate(StringFieldValue("foo"), @@ -585,7 +551,8 @@ void DocumentUpdateTest::testReadSerializedFile() } close(fd); - DocumentUpdate::UP updp(DocumentUpdate::create42(repo, buf)); + nbostream is(buf.getBufferAtPos(), buf.getRemaining()); + DocumentUpdate::UP updp(DocumentUpdate::create42(repo, is)); DocumentUpdate& upd(*updp); const DocumentType *type = repo.getDocumentType("serializetest"); @@ -647,7 +614,7 @@ void DocumentUpdateTest::testGenerateSerializedFile() DocumentTypeRepo repo(readDocumenttypesConfig(file_name)); const DocumentType *type(repo.getDocumentType("serializetest")); - DocumentUpdate upd(*type, DocumentId(DocIdString("update", "test"))); + DocumentUpdate upd(repo, *type, DocumentId(DocIdString("update", "test"))); upd.addUpdate(FieldUpdate(type->getField("intfield")) .addUpdate(AssignValueUpdate(IntFieldValue(4)))); upd.addUpdate(FieldUpdate(type->getField("floatfield")) @@ -678,11 +645,10 @@ void DocumentUpdateTest::testSetBadFieldTypes() // Create a test document TestDocMan docMan; Document::UP doc(docMan.createDocument()); - CPPUNIT_ASSERT_EQUAL((document::FieldValue*)NULL, - doc->getValue(doc->getField("headerval")).get()); + CPPUNIT_ASSERT_EQUAL((document::FieldValue*)NULL, doc->getValue(doc->getField("headerval")).get()); // Assign a float value to an int field. - DocumentUpdate update(*doc->getDataType(), doc->getId()); + DocumentUpdate update(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()); try { update.addUpdate(FieldUpdate(doc->getField("headerval")) .addUpdate(AssignValueUpdate(FloatFieldValue(4.00f)))); @@ -701,23 +667,19 @@ void DocumentUpdateTest::testSetBadFieldTypes() void DocumentUpdateTest::testUpdateApplyNoParams() { - // Create a test document TestDocMan docMan; Document::UP doc(docMan.createDocument()); - CPPUNIT_ASSERT_EQUAL((document::FieldValue*)NULL, - doc->getValue(doc->getField("tags")).get()); + CPPUNIT_ASSERT_EQUAL((document::FieldValue*)NULL, doc->getValue(doc->getField("tags")).get()); // Assign array field with no parameters - illegal. - DocumentUpdate update(*doc->getDataType(), doc->getId()); + DocumentUpdate update(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()); try { - update.addUpdate(FieldUpdate(doc->getField("tags")) - .addUpdate(AssignValueUpdate())); + update.addUpdate(FieldUpdate(doc->getField("tags")).addUpdate(AssignValueUpdate())); CPPUNIT_FAIL("Expected exception when assign a NULL value."); } catch (std::exception& e) { ; // fprintf(stderr, "Got exception => OK: %s\n", e.what()); } - // Apply update update.applyTo(*doc); // Verify that the field was cleared in the document. @@ -727,20 +689,16 @@ DocumentUpdateTest::testUpdateApplyNoParams() void DocumentUpdateTest::testUpdateApplyNoArrayValues() { - // Create a test document TestDocMan docMan; Document::UP doc(docMan.createDocument()); const Field &field(doc->getType().getField("tags")); - CPPUNIT_ASSERT_EQUAL((document::FieldValue*) 0, - doc->getValue(field).get()); + CPPUNIT_ASSERT_EQUAL((document::FieldValue*) 0, doc->getValue(field).get()); // Assign array field with no array values = empty array - DocumentUpdate update(*doc->getDataType(), doc->getId()); + DocumentUpdate update(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()); update.addUpdate(FieldUpdate(field) - .addUpdate(AssignValueUpdate( - ArrayFieldValue(field.getDataType())))); + .addUpdate(AssignValueUpdate(ArrayFieldValue(field.getDataType())))); - // Apply update update.applyTo(*doc); // Verify that the field was set in the document @@ -759,7 +717,7 @@ DocumentUpdateTest::testUpdateArrayEmptyParamValue() CPPUNIT_ASSERT_EQUAL((document::FieldValue*) 0, doc->getValue(field).get()); // Assign array field with no array values = empty array. - DocumentUpdate update(*doc->getDataType(), doc->getId()); + DocumentUpdate update(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()); update.addUpdate(FieldUpdate(field).addUpdate(AssignValueUpdate(ArrayFieldValue(field.getDataType())))); update.applyTo(*doc); @@ -769,7 +727,7 @@ DocumentUpdateTest::testUpdateArrayEmptyParamValue() CPPUNIT_ASSERT_EQUAL((size_t) 0, fval1->size()); // Remove array field. - DocumentUpdate update2(*doc->getDataType(), doc->getId()); + DocumentUpdate update2(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()); update2.addUpdate(FieldUpdate(field).addUpdate(ClearValueUpdate())); update2.applyTo(*doc); @@ -788,7 +746,7 @@ DocumentUpdateTest::testUpdateWeightedSetEmptyParamValue() CPPUNIT_ASSERT_EQUAL((document::FieldValue*) 0, doc->getValue(field).get()); // Assign weighted set with no items = empty set. - DocumentUpdate update(*doc->getDataType(), doc->getId()); + DocumentUpdate update(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()); update.addUpdate(FieldUpdate(field).addUpdate(AssignValueUpdate(WeightedSetFieldValue(field.getDataType())))); update.applyTo(*doc); @@ -798,7 +756,7 @@ DocumentUpdateTest::testUpdateWeightedSetEmptyParamValue() CPPUNIT_ASSERT_EQUAL((size_t) 0, fval1->size()); // Remove weighted set field. - DocumentUpdate update2(*doc->getDataType(), doc->getId()); + DocumentUpdate update2(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()); update2.addUpdate(FieldUpdate(field).addUpdate(ClearValueUpdate())); update2.applyTo(*doc); @@ -817,7 +775,7 @@ DocumentUpdateTest::testUpdateArrayWrongSubtype() CPPUNIT_ASSERT_EQUAL((document::FieldValue*) 0, doc->getValue(field).get()); // Assign int values to string array. - DocumentUpdate update(*doc->getDataType(), doc->getId()); + DocumentUpdate update(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()); try { update.addUpdate(FieldUpdate(field) .addUpdate(AddValueUpdate(IntFieldValue(123))) @@ -842,17 +800,14 @@ DocumentUpdateTest::testUpdateWeightedSetWrongSubtype() TestDocMan docMan; Document::UP doc(docMan.createDocument()); const Field &field(doc->getType().getField("stringweightedset")); - CPPUNIT_ASSERT_EQUAL((document::FieldValue*) 0, - doc->getValue(field).get()); + CPPUNIT_ASSERT_EQUAL((document::FieldValue*) 0, doc->getValue(field).get()); // Assign int values to string array. - DocumentUpdate update(*doc->getDataType(), doc->getId()); + DocumentUpdate update(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()); try { update.addUpdate(FieldUpdate(field) - .addUpdate(AddValueUpdate(IntFieldValue(123)) - .setWeight(1000)) - .addUpdate(AddValueUpdate(IntFieldValue(456)) - .setWeight(2000))); + .addUpdate(AddValueUpdate(IntFieldValue(123)).setWeight(1000)) + .addUpdate(AddValueUpdate(IntFieldValue(456)).setWeight(2000))); CPPUNIT_FAIL("Expected exception when adding wrong type."); } catch (std::exception& e) { ; // fprintf(stderr, "Got exception => OK: %s\n", e.what()); @@ -879,79 +834,61 @@ DocumentUpdateTest::testMapValueUpdate() doc->setValue(field1, wsval1); doc->setValue(field2, wsval2); - DocumentUpdate(*doc->getDataType(), doc->getId()) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) .addUpdate(FieldUpdate(field1) - .addUpdate(MapValueUpdate( - StringFieldValue("banana"), - ArithmeticValueUpdate(ArithmeticValueUpdate::Add, 1.0) - ))) + .addUpdate(MapValueUpdate(StringFieldValue("banana"), + ArithmeticValueUpdate(ArithmeticValueUpdate::Add, 1.0)))) .applyTo(*doc); std::unique_ptr<WeightedSetFieldValue> fv1 = doc->getAs<WeightedSetFieldValue>(field1); CPPUNIT_ASSERT(fv1->size() == 0); - DocumentUpdate(*doc->getDataType(), doc->getId()) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) .addUpdate(FieldUpdate(field2) - .addUpdate(MapValueUpdate( - StringFieldValue("banana"), - ArithmeticValueUpdate(ArithmeticValueUpdate::Add, 1.0) - ))) + .addUpdate(MapValueUpdate(StringFieldValue("banana"), + ArithmeticValueUpdate(ArithmeticValueUpdate::Add, 1.0)))) .applyTo(*doc); - std::unique_ptr<WeightedSetFieldValue> fv2 = - doc->getAs<WeightedSetFieldValue>(field2); + auto fv2 = doc->getAs<WeightedSetFieldValue>(field2); CPPUNIT_ASSERT(fv2->size() == 1); CPPUNIT_ASSERT(fv1->find(StringFieldValue("apple")) == fv1->end()); - DocumentUpdate(*doc->getDataType(), doc->getId()) - .addUpdate(FieldUpdate(field1) - .addUpdate(ClearValueUpdate())) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) + .addUpdate(FieldUpdate(field1).addUpdate(ClearValueUpdate())) .applyTo(*doc); - DocumentUpdate(*doc->getDataType(), doc->getId()) - .addUpdate(FieldUpdate(field1) - .addUpdate(AddValueUpdate(StringFieldValue("apple")) - .setWeight(1))) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) + .addUpdate(FieldUpdate(field1).addUpdate(AddValueUpdate(StringFieldValue("apple")).setWeight(1))) .applyTo(*doc); - std::unique_ptr<WeightedSetFieldValue> - fval3(doc->getAs<WeightedSetFieldValue>(field1)); + auto fval3(doc->getAs<WeightedSetFieldValue>(field1)); CPPUNIT_ASSERT(fval3->find(StringFieldValue("apple")) != fval3->end()); CPPUNIT_ASSERT_EQUAL(1, fval3->get(StringFieldValue("apple"))); - DocumentUpdate(*doc->getDataType(), doc->getId()) - .addUpdate(FieldUpdate(field2) - .addUpdate(AddValueUpdate(StringFieldValue("apple")) - .setWeight(1))) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) + .addUpdate(FieldUpdate(field2).addUpdate(AddValueUpdate(StringFieldValue("apple")).setWeight(1))) .applyTo(*doc); - std::unique_ptr<WeightedSetFieldValue> - fval3b(doc->getAs<WeightedSetFieldValue>(field2)); + auto fval3b(doc->getAs<WeightedSetFieldValue>(field2)); CPPUNIT_ASSERT(fval3b->find(StringFieldValue("apple")) != fval3b->end()); CPPUNIT_ASSERT_EQUAL(1, fval3b->get(StringFieldValue("apple"))); - DocumentUpdate(*doc->getDataType(), doc->getId()) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) .addUpdate(FieldUpdate(field1) - .addUpdate(MapValueUpdate( - StringFieldValue("apple"), - ArithmeticValueUpdate(ArithmeticValueUpdate::Sub, 1.0) - ))) + .addUpdate(MapValueUpdate(StringFieldValue("apple"), + ArithmeticValueUpdate(ArithmeticValueUpdate::Sub, 1.0)))) .applyTo(*doc); - std::unique_ptr<WeightedSetFieldValue> fv3 = - doc->getAs<WeightedSetFieldValue>(field1); + auto fv3 = doc->getAs<WeightedSetFieldValue>(field1); CPPUNIT_ASSERT(fv3->find(StringFieldValue("apple")) != fv3->end()); CPPUNIT_ASSERT_EQUAL(0, fv3->get(StringFieldValue("apple"))); - DocumentUpdate(*doc->getDataType(), doc->getId()) + DocumentUpdate(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()) .addUpdate(FieldUpdate(field2) - .addUpdate(MapValueUpdate( - StringFieldValue("apple"), - ArithmeticValueUpdate(ArithmeticValueUpdate::Sub, 1.0) - ))) + .addUpdate(MapValueUpdate(StringFieldValue("apple"), + ArithmeticValueUpdate(ArithmeticValueUpdate::Sub, 1.0)))) .applyTo(*doc); - std::unique_ptr<WeightedSetFieldValue> fv4 = - doc->getAs<WeightedSetFieldValue>(field2); + auto fv4 = doc->getAs<WeightedSetFieldValue>(field2); CPPUNIT_ASSERT(fv4->find(StringFieldValue("apple")) == fv4->end()); } @@ -965,9 +902,8 @@ DocumentUpdateTest::testTensorAssignUpdate() Document updated(*doc); FieldValue::UP new_value(createTensorFieldValue()); testValueUpdate(AssignValueUpdate(*new_value), *DataType::TENSOR); - DocumentUpdate upd(*doc->getDataType(), doc->getId()); - upd.addUpdate(FieldUpdate(upd.getType().getField("tensor")). - addUpdate(AssignValueUpdate(*new_value))); + DocumentUpdate upd(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()); + upd.addUpdate(FieldUpdate(upd.getType().getField("tensor")).addUpdate(AssignValueUpdate(*new_value))); upd.applyTo(updated); FieldValue::UP fval(updated.getValue("tensor")); CPPUNIT_ASSERT(fval); @@ -983,9 +919,8 @@ DocumentUpdateTest::testTensorClearUpdate() Document updated(*doc); updated.setValue(updated.getField("tensor"), *createTensorFieldValue()); CPPUNIT_ASSERT(*doc != updated); - DocumentUpdate upd(*doc->getDataType(), doc->getId()); - upd.addUpdate(FieldUpdate(upd.getType().getField("tensor")). - addUpdate(ClearValueUpdate())); + DocumentUpdate upd(docMan.getTypeRepo(), *doc->getDataType(), doc->getId()); + upd.addUpdate(FieldUpdate(upd.getType().getField("tensor")).addUpdate(ClearValueUpdate())); upd.applyTo(updated); CPPUNIT_ASSERT(!updated.getValue("tensor")); CPPUNIT_ASSERT(*doc == updated); @@ -1036,12 +971,11 @@ struct CreateIfNonExistentFixture CreateIfNonExistentFixture(); }; -CreateIfNonExistentFixture::~CreateIfNonExistentFixture() {} +CreateIfNonExistentFixture::~CreateIfNonExistentFixture() = default; CreateIfNonExistentFixture::CreateIfNonExistentFixture() : docMan(), document(docMan.createDocument()), - update(new DocumentUpdate(*document->getDataType(), - document->getId())) + update(new DocumentUpdate(docMan.getTypeRepo(), *document->getDataType(), document->getId())) { update->addUpdate(FieldUpdate(document->getField("headerval")) .addUpdate(AssignValueUpdate(IntFieldValue(1)))); @@ -1069,7 +1003,8 @@ DocumentUpdateTest::testThatCreateIfNonExistentFlagIsSerializedAndDeserialized() ByteBuffer::UP buf(serialize42(*f.update)); buf->flip(); - DocumentUpdate::UP deserialized = DocumentUpdate::create42(f.docMan.getTypeRepo(), *buf); + nbostream is(buf->getBufferAtPos(), buf->getRemaining()); + auto deserialized = DocumentUpdate::create42(f.docMan.getTypeRepo(), is); CPPUNIT_ASSERT_EQUAL(*f.update, *deserialized); CPPUNIT_ASSERT(deserialized->getCreateIfNonExistent()); } @@ -1089,7 +1024,7 @@ ArrayUpdateFixture::ArrayUpdateFixture() doc(doc_man.createDocument()), array_field(doc->getType().getField("tags")) // of type array<string> { - update = std::make_unique<DocumentUpdate>(*doc->getDataType(), doc->getId()); + update = std::make_unique<DocumentUpdate>(doc_man.getTypeRepo(), *doc->getDataType(), doc->getId()); update->addUpdate(FieldUpdate(array_field) .addUpdate(MapValueUpdate(IntFieldValue(1), AssignValueUpdate(StringFieldValue("bar"))))); diff --git a/document/src/tests/fieldpathupdatetestcase.cpp b/document/src/tests/fieldpathupdatetestcase.cpp index b240f322e4b..80a63a86b92 100644 --- a/document/src/tests/fieldpathupdatetestcase.cpp +++ b/document/src/tests/fieldpathupdatetestcase.cpp @@ -371,7 +371,7 @@ FieldPathUpdateTestCase::testRemoveField() doc->setValue("strfoo", StringFieldValue("cocacola")); CPPUNIT_ASSERT_EQUAL(vespalib::string("cocacola"), doc->getValue("strfoo")->getAsString()); //doc->print(std::cerr, true, ""); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP(new RemoveFieldPathUpdate("strfoo"))); docUp.applyTo(*doc); CPPUNIT_ASSERT(doc->hasValue("strfoo") == false); @@ -392,7 +392,7 @@ FieldPathUpdateTestCase::testApplyRemoveMultiList() } CPPUNIT_ASSERT(doc->hasValue("strarray")); //doc->print(std::cerr, true, ""); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP( new RemoveFieldPathUpdate("strarray[$x]", "foobar.strarray[$x] == \"remove val 1\""))); docUp.applyTo(*doc); @@ -417,7 +417,7 @@ FieldPathUpdateTestCase::testApplyRemoveEntireListField() doc->setValue("strarray", strArray); } //doc->print(std::cerr, true, ""); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP(new RemoveFieldPathUpdate("strarray", ""))); docUp.applyTo(*doc); CPPUNIT_ASSERT(!doc->hasValue("strarray")); @@ -436,7 +436,7 @@ FieldPathUpdateTestCase::testApplyRemoveMultiWset() } CPPUNIT_ASSERT(doc->hasValue("strwset")); //doc->print(std::cerr, true, ""); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP(new RemoveFieldPathUpdate("strwset{remove val 1}"))); docUp.applyTo(*doc); { @@ -452,14 +452,14 @@ FieldPathUpdateTestCase::testApplyAssignSingle() Document::UP doc(new Document(_foobar_type, DocumentId("doc:drekka:karsk"))); CPPUNIT_ASSERT(doc->hasValue("strfoo") == false); // Test assignment of non-existing - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP( new AssignFieldPathUpdate(*doc->getDataType(), "strfoo", std::string(), StringFieldValue("himert")))); docUp.applyTo(*doc); CPPUNIT_ASSERT(doc->hasValue("strfoo")); CPPUNIT_ASSERT_EQUAL(vespalib::string("himert"), doc->getValue("strfoo")->getAsString()); // Test overwriting existing - DocumentUpdate docUp2(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp2(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp2.addFieldPathUpdate(FieldPathUpdate::CP( new AssignFieldPathUpdate(*doc->getDataType(), "strfoo", std::string(), StringFieldValue("wunderbaum")))); docUp2.applyTo(*doc); @@ -472,7 +472,7 @@ FieldPathUpdateTestCase::testApplyAssignMath() Document::UP doc(new Document(_foobar_type, DocumentId("doc:bat:man"))); doc->setValue("num", IntFieldValue(34)); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP(new AssignFieldPathUpdate("num", "", "($value * 2) / $value"))); docUp.applyTo(*doc); CPPUNIT_ASSERT_EQUAL(static_cast<const FieldValue&>(IntFieldValue(2)), *doc->getValue("num")); @@ -484,7 +484,7 @@ FieldPathUpdateTestCase::testApplyAssignMathByteToZero() Document::UP doc(new Document(_foobar_type, DocumentId("doc:bat:man"))); doc->setValue("byteval", ByteFieldValue(3)); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP(new AssignFieldPathUpdate("byteval", "", "$value - 3"))); docUp.applyTo(*doc); CPPUNIT_ASSERT_EQUAL(static_cast<const FieldValue&>(ByteFieldValue(0)), *doc->getValue("byteval")); @@ -497,7 +497,7 @@ FieldPathUpdateTestCase::testApplyAssignMathNotModifiedOnUnderflow() Document::UP doc(new Document(_foobar_type, DocumentId("doc:bat:man"))); doc->setValue("byteval", ByteFieldValue(low_value)); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP(new AssignFieldPathUpdate("byteval", "", "$value - 4"))); docUp.applyTo(*doc); // Over/underflow will happen. You must have control of your data types. @@ -510,7 +510,7 @@ FieldPathUpdateTestCase::testApplyAssignMathNotModifiedOnOverflow() Document::UP doc(new Document(_foobar_type, DocumentId("doc:bat:man"))); doc->setValue("byteval", ByteFieldValue(127)); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP(new AssignFieldPathUpdate("byteval", "", "$value + 200"))); docUp.applyTo(*doc); // Over/underflow will happen. You must have control of your data types. @@ -524,7 +524,7 @@ FieldPathUpdateTestCase::testApplyAssignMathDivZero() CPPUNIT_ASSERT(doc->hasValue("num") == false); doc->setValue("num", IntFieldValue(10)); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP(new AssignFieldPathUpdate("num", "", "$value / ($value - 10)"))); docUp.applyTo(*doc); CPPUNIT_ASSERT_EQUAL(static_cast<const FieldValue&>(IntFieldValue(10)), *doc->getValue("num")); @@ -538,7 +538,7 @@ FieldPathUpdateTestCase::testApplyAssignFieldNotExistingInExpression() CPPUNIT_ASSERT(doc->hasValue("num") == false); doc->setValue("num", IntFieldValue(10)); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP(new AssignFieldPathUpdate("num", "", "foobar.num2 + $value"))); docUp.applyTo(*doc); CPPUNIT_ASSERT_EQUAL(static_cast<const FieldValue&>(IntFieldValue(10)), *doc->getValue("num")); @@ -550,7 +550,7 @@ FieldPathUpdateTestCase::testApplyAssignFieldNotExistingInPath() Document::UP doc(new Document(_foobar_type, DocumentId("doc:bat:man"))); doc->setRepo(*_repo); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); try { docUp.addFieldPathUpdate(FieldPathUpdate::CP(new AssignFieldPathUpdate("nosuchnum", "", "foobar.num + $value"))); docUp.applyTo(*doc); @@ -565,7 +565,7 @@ FieldPathUpdateTestCase::testApplyAssignTargetNotExisting() Document::UP doc(new Document(_foobar_type, DocumentId("doc:bat:man"))); CPPUNIT_ASSERT(doc->hasValue("num") == false); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP(new AssignFieldPathUpdate("num", "", "$value + 5"))); docUp.applyTo(*doc); CPPUNIT_ASSERT_EQUAL(static_cast<const FieldValue&>(IntFieldValue(5)), *doc->getValue("num")); @@ -582,7 +582,7 @@ FieldPathUpdateTestCase::testAssignSimpleMapValueWithVariable() mfv.put(StringFieldValue("baz"), StringFieldValue("bananas")); doc->setValue("strmap", mfv); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); // Select on value, not key docUp.addFieldPathUpdate(FieldPathUpdate::CP( new AssignFieldPathUpdate(*doc->getDataType(), @@ -608,7 +608,7 @@ FieldPathUpdateTestCase::testApplyAssignMathRemoveIfZero() doc->setValue("num", IntFieldValue(34)); CPPUNIT_ASSERT(doc->hasValue("num") == true); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); FieldPathUpdate::CP up1(new AssignFieldPathUpdate("num", "", "($value * 2) / $value - 2")); static_cast<AssignFieldPathUpdate&>(*up1).setRemoveIfZero(true); docUp.addFieldPathUpdate(up1); @@ -635,7 +635,7 @@ FieldPathUpdateTestCase::testApplyAssignMultiList() updateArray.add(StringFieldValue("assigned val 0")); updateArray.add(StringFieldValue("assigned val 1")); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP( new AssignFieldPathUpdate(*doc->getDataType(), "strarray", std::string(), updateArray))); docUp.applyTo(*doc); @@ -667,7 +667,7 @@ FieldPathUpdateTestCase::testApplyAssignMultiWset() assignWset.add(StringFieldValue("assigned val 0"), 5); assignWset.add(StringFieldValue("assigned val 1"), 10); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP( new AssignFieldPathUpdate(*doc->getDataType(), "strwset", std::string(), assignWset))); //doc->print(std::cerr, true, ""); @@ -696,7 +696,7 @@ FieldPathUpdateTestCase::testAssignWsetRemoveIfZero() } { - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); IntFieldValue zeroWeight(0); FieldPathUpdate::CP assignUpdate( new AssignFieldPathUpdate(*doc->getDataType(), "strwset{you say goodbye}", std::string(), zeroWeight)); @@ -724,7 +724,7 @@ FieldPathUpdateTestCase::testApplyAddMultiList() adds.add(StringFieldValue("a festivus for the rest of us")); adds.add(StringFieldValue("george is getting upset!")); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP( new AddFieldPathUpdate(*doc->getDataType(), "strarray", std::string(), adds))); //doc->print(std::cerr, true, ""); @@ -747,7 +747,7 @@ FieldPathUpdateTestCase::testAddAndAssignList() CPPUNIT_ASSERT(doc->hasValue("strarray")); } - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP( new AssignFieldPathUpdate(*doc->getDataType(), "strarray[1]", std::string(), StringFieldValue("assigned val 1")))); @@ -829,7 +829,7 @@ FieldPathUpdateTestCase::testAssignMap() Keys k; Fixture f(_foobar_type, k); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP( new AssignFieldPathUpdate(*f.doc->getDataType(), "structmap{" + k.key2 + "}", std::string(), f.fv4))); docUp.applyTo(*f.doc); @@ -850,7 +850,7 @@ FieldPathUpdateTestCase::testAssignMapStruct() Keys k; Fixture f(_foobar_type, k); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP( new AssignFieldPathUpdate(*f.doc->getDataType(), "structmap{" + k.key2 + "}.rating", std::string(), IntFieldValue(48)))); @@ -872,7 +872,7 @@ FieldPathUpdateTestCase::testAssignMapStructVariable() Keys k; Fixture f(_foobar_type, k); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP( new AssignFieldPathUpdate(*f.doc->getDataType(), "structmap{$x}.rating", "foobar.structmap{$x}.title == \"farnsworth\"", IntFieldValue(48)))); @@ -899,7 +899,7 @@ FieldPathUpdateTestCase::testAssignMapNoExist() fv1.setValue("title", StringFieldValue("fry")); fv1.setValue("rating", IntFieldValue(30)); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP( new AssignFieldPathUpdate(*doc->getDataType(), "structmap{foo}", std::string(), fv1))); //doc->print(std::cerr, true, ""); @@ -922,7 +922,7 @@ FieldPathUpdateTestCase::testAssignMapNoExistNoCreate() fv1.setValue("title", StringFieldValue("fry")); fv1.setValue("rating", IntFieldValue(30)); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); FieldPathUpdate::CP assignUpdate( new AssignFieldPathUpdate(*doc->getDataType(), "structmap{foo}", std::string(), fv1)); static_cast<AssignFieldPathUpdate&>(*assignUpdate).setCreateMissingPath(false); @@ -944,7 +944,7 @@ FieldPathUpdateTestCase::testQuotedStringKey() const char field_path[] = "structmap{\"here is a \\\"fancy\\\" 'map' :-} key :-{\"}"; Fixture f(_foobar_type, k); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP( new AssignFieldPathUpdate(*f.doc->getDataType(), field_path, std::string(), f.fv4))); docUp.applyTo(*f.doc); @@ -970,8 +970,8 @@ FieldPathUpdateTestCase::testEqualityComparison() fv4.setValue("rating", IntFieldValue(95)); { - DocumentUpdate docUp1(_foobar_type, DocumentId("doc:barbar:foofoo")); - DocumentUpdate docUp2(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp1(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp2(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); CPPUNIT_ASSERT(docUp1 == docUp2); FieldPathUpdate::CP assignUp1(new AssignFieldPathUpdate(*doc->getDataType(), @@ -982,8 +982,8 @@ FieldPathUpdateTestCase::testEqualityComparison() CPPUNIT_ASSERT(docUp1 == docUp2); } { - DocumentUpdate docUp1(_foobar_type, DocumentId("doc:barbar:foofoo")); - DocumentUpdate docUp2(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp1(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp2(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); // where-clause diff FieldPathUpdate::CP assignUp1(new AssignFieldPathUpdate(*doc->getDataType(), "structmap{here be dragons}", std::string(), fv4)); @@ -994,8 +994,8 @@ FieldPathUpdateTestCase::testEqualityComparison() CPPUNIT_ASSERT(docUp1 != docUp2); } { - DocumentUpdate docUp1(_foobar_type, DocumentId("doc:barbar:foofoo")); - DocumentUpdate docUp2(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp1(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp2(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); // fieldpath diff FieldPathUpdate::CP assignUp1(new AssignFieldPathUpdate(*doc->getDataType(), "structmap{here be dragons}", std::string(), fv4)); @@ -1020,7 +1020,7 @@ FieldPathUpdateTestCase::testAffectsDocumentBody() // structmap is body field { - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); FieldPathUpdate::CP update1(new AssignFieldPathUpdate(*doc->getDataType(), "structmap{janitor}", std::string(), fv4)); @@ -1030,7 +1030,7 @@ FieldPathUpdateTestCase::testAffectsDocumentBody() // strfoo is header field { - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); FieldPathUpdate::CP update1(new AssignFieldPathUpdate(*doc->getDataType(), "strfoo", std::string(), StringFieldValue("helloworld"))); static_cast<AssignFieldPathUpdate&>(*update1).setCreateMissingPath(true); @@ -1045,7 +1045,7 @@ FieldPathUpdateTestCase::testIncompatibleDataTypeFails() Document::UP doc(new Document(_foobar_type, DocumentId("doc:things:stuff"))); MapFieldValue mfv(doc->getType().getField("structmap").getDataType()); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); try { FieldPathUpdate::CP update1(new AssignFieldPathUpdate(*doc->getDataType(), "structmap{foo}", @@ -1066,7 +1066,7 @@ FieldPathUpdateTestCase::testSerializeAssign() val.setValue("title", StringFieldValue("cool frog")); val.setValue("rating", IntFieldValue(100)); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); FieldPathUpdate::CP update1(new AssignFieldPathUpdate(*doc->getDataType(), "structmap{ribbit}", "true", val)); static_cast<AssignFieldPathUpdate&>(*update1).setCreateMissingPath(true); @@ -1086,7 +1086,7 @@ FieldPathUpdateTestCase::testSerializeAdd() adds.add(StringFieldValue("a festivus for the rest of us")); adds.add(StringFieldValue("george is getting upset!")); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); FieldPathUpdate::CP update1(new AddFieldPathUpdate(*doc->getDataType(), "strarray", std::string(), adds)); docUp.addFieldPathUpdate(update1); @@ -1100,7 +1100,7 @@ FieldPathUpdateTestCase::testSerializeRemove() Document::UP doc(new Document(_foobar_type, DocumentId("doc:weloveto:serializestuff"))); MapFieldValue mfv(doc->getType().getField("structmap").getDataType()); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); FieldPathUpdate::CP update1(new RemoveFieldPathUpdate("structmap{ribbit}", std::string())); docUp.addFieldPathUpdate(update1); @@ -1115,7 +1115,7 @@ FieldPathUpdateTestCase::testSerializeAssignMath() CPPUNIT_ASSERT(doc->hasValue("num") == false); doc->setValue("num", IntFieldValue(34)); - DocumentUpdate docUp(_foobar_type, DocumentId("doc:barbar:foofoo")); + DocumentUpdate docUp(*_repo, _foobar_type, DocumentId("doc:barbar:foofoo")); docUp.addFieldPathUpdate(FieldPathUpdate::CP(new AssignFieldPathUpdate("num", "", "($value * 2) / $value"))); testSerialize(*_repo, docUp); } @@ -1124,7 +1124,7 @@ DocumentUpdate::UP FieldPathUpdateTestCase::createDocumentUpdateForSerialization(const DocumentTypeRepo& repo) { const DocumentType *docType(repo.getDocumentType("serializetest")); - DocumentUpdate::UP docUp(new DocumentUpdate(*docType, DocumentId("doc:serialization:xlanguage"))); + DocumentUpdate::UP docUp(new DocumentUpdate(repo, *docType, DocumentId("doc:serialization:xlanguage"))); FieldPathUpdate::CP assign(new AssignFieldPathUpdate("intfield", "", "3")); static_cast<AssignFieldPathUpdate&>(*assign).setRemoveIfZero(true); diff --git a/document/src/tests/testxml.cpp b/document/src/tests/testxml.cpp index 4cc1306ff45..09c2ef86279 100644 --- a/document/src/tests/testxml.cpp +++ b/document/src/tests/testxml.cpp @@ -73,7 +73,7 @@ createTestDocumentUpdate(const DocumentTypeRepo& repo) const DocumentType* type(repo.getDocumentType("testdoc")); DocumentId id("doc:crawler/http://www.ntnu.no/"); - DocumentUpdate::UP up(new DocumentUpdate(*type, id)); + DocumentUpdate::UP up(new DocumentUpdate(repo, *type, id)); up->addUpdate(FieldUpdate(type->getField("intattr")) .addUpdate(AssignValueUpdate(IntFieldValue(7)))); up->addUpdate(FieldUpdate(type->getField("stringattr")) diff --git a/document/src/vespa/document/base/forcelink.cpp b/document/src/vespa/document/base/forcelink.cpp index 8f683e40059..bc0097b68f4 100644 --- a/document/src/vespa/document/base/forcelink.cpp +++ b/document/src/vespa/document/base/forcelink.cpp @@ -13,7 +13,7 @@ ForceLink::ForceLink(void) if (time(NULL) == 0) { DocumentType type("foo", 1); Document document(type, DocumentId("doc:ns:bar")); - DocumentUpdate documentUpdate(type, DocumentId("doc:ns:bar")); + DocumentUpdate documentUpdate; MapValueUpdate mapValueUpdate(IntFieldValue(3), ClearValueUpdate()); AddValueUpdate addValueUpdate(IntFieldValue(3)); RemoveValueUpdate removeValueUpdate(IntFieldValue(3)); diff --git a/document/src/vespa/document/serialization/vespadocumentserializer.cpp b/document/src/vespa/document/serialization/vespadocumentserializer.cpp index 1a628ea2618..dac5ca4458b 100644 --- a/document/src/vespa/document/serialization/vespadocumentserializer.cpp +++ b/document/src/vespa/document/serialization/vespadocumentserializer.cpp @@ -439,17 +439,19 @@ void VespaDocumentSerializer::write42(const DocumentUpdate &value) void VespaDocumentSerializer::writeHEAD(const DocumentUpdate &value) { + if (!value._needHardReserialize) { + _stream.write(value._backing.peek(), value._backing.size()); + return; + } write(value.getId()); _stream.write(value.getType().getName().c_str(), value.getType().getName().size() + 1); _stream << static_cast<uint16_t>(0); - const DocumentUpdate::FieldUpdateV & updates(value.getUpdates()); - _stream << static_cast<uint32_t>(updates.size()); - for (const auto & update : updates) { + _stream << static_cast<uint32_t>(value._updates.size()); + for (const auto & update : value._updates) { write(update); } - const DocumentUpdate::FieldPathUpdateV & fieldPathUpdates(value.getFieldPathUpdates()); - _stream << static_cast<uint32_t>(value.serializeFlags(fieldPathUpdates.size())); - for (const auto & update : fieldPathUpdates) { + _stream << static_cast<uint32_t>(value.serializeFlags(value._fieldPathUpdates.size())); + for (const auto & update : value._fieldPathUpdates) { _stream << update->getSerializedType(); write(*update); } diff --git a/document/src/vespa/document/update/documentupdate.cpp b/document/src/vespa/document/update/documentupdate.cpp index 30b760a6102..cb0beff6a15 100644 --- a/document/src/vespa/document/update/documentupdate.cpp +++ b/document/src/vespa/document/update/documentupdate.cpp @@ -25,59 +25,43 @@ namespace document { // Declare content bits. static const unsigned char CONTENT_HASTYPE = 0x01; -DocumentUpdate::DocumentUpdate(const DataType &type, const DocumentId& id) +DocumentUpdate::DocumentUpdate(const DocumentTypeRepo & repo, const DataType &type, const DocumentId& id) : _documentId(id), _type(&type), + _repo(&repo), + _backing(), _updates(), _fieldPathUpdates(), _version(Document::getNewestSerializationVersion()), - _createIfNonExistent(false) + _createIfNonExistent(false), + _needHardReserialize(false) { if (!type.getClass().inherits(DocumentType::classId)) { - throw IllegalArgumentException("Cannot generate a document with non-document type " + type.toString() + ".", - VESPA_STRLOC); + throw IllegalArgumentException("Cannot generate a document with non-document type " + type.toString() + ".", VESPA_STRLOC); } + serializeHeader(); } -DocumentUpdate::DocumentUpdate(const DocumentTypeRepo& repo, - ByteBuffer& buffer, - SerializeVersion serializeVersion) - : _documentId("doc::"), +DocumentUpdate::DocumentUpdate() + : _documentId(), _type(DataType::DOCUMENT), + _repo(nullptr), + _backing(), _updates(), + _fieldPathUpdates(), _version(Document::getNewestSerializationVersion()), - _createIfNonExistent(false) + _createIfNonExistent(false), + _needHardReserialize(false) { - switch (serializeVersion) { - case SerializeVersion::SERIALIZE_HEAD: - deserializeHEAD(repo, buffer); - break; - case SerializeVersion::SERIALIZE_42: - deserialize42(repo, buffer); - break; - default: - throw IllegalArgumentException("bad serializeVersion provided.", VESPA_STRLOC); - } } DocumentUpdate::~DocumentUpdate() = default; - bool DocumentUpdate::operator==(const DocumentUpdate& other) const { - if (_documentId != other._documentId) return false; - if (*_type != *other._type) return false; - if (_updates.size() != other._updates.size()) return false; - for (std::size_t i = 0, n = _updates.size(); i < n; ++i) { - if (_updates[i] != other._updates[i]) return false; - } - if (_fieldPathUpdates.size() != other._fieldPathUpdates.size()) return false; - for (std::size_t i = 0, n = _fieldPathUpdates.size(); i < n; ++i) { - if (*_fieldPathUpdates[i] != *other._fieldPathUpdates[i]) return false; - } - if (_createIfNonExistent != other._createIfNonExistent) return false; - return true; + return (_backing.size() == other._backing.size()) && + (memcmp(_backing.peek(), other._backing.peek(), _backing.size()) == 0); } const DocumentType& @@ -85,22 +69,67 @@ DocumentUpdate::getType() const { return static_cast<const DocumentType &> (*_type); } +const DocumentUpdate::FieldUpdateV & +DocumentUpdate::getUpdates() const { + ensureDeserialized(); + return _updates; +} + +const DocumentUpdate::FieldPathUpdateV & +DocumentUpdate::getFieldPathUpdates() const { + ensureDeserialized(); + return _fieldPathUpdates; +} + +void +DocumentUpdate::eagerDeserialize() const { + ensureDeserialized(); +} + +void DocumentUpdate::lazyDeserialize(const DocumentTypeRepo & repo, nbostream & stream) { + size_t start(stream.rp()); + deserializeHEAD(repo, stream); + stream.rp(start); +} +void DocumentUpdate::ensureDeserialized() const { + if (_updates.empty() && _fieldPathUpdates.empty()) { + const_cast<DocumentUpdate &>(*this).lazyDeserialize(*_repo, const_cast<nbostream &>(_backing)); + } +} + DocumentUpdate& DocumentUpdate::addUpdate(const FieldUpdate& update) { + ensureDeserialized(); _updates.push_back(update); + reserialize(); return *this; } DocumentUpdate& DocumentUpdate::addFieldPathUpdate(const FieldPathUpdate::CP& update) { + ensureDeserialized(); _fieldPathUpdates.push_back(update); + reserialize(); return *this; } void -DocumentUpdate::print(std::ostream& out, bool verbose, - const std::string& indent) const +DocumentUpdate::setCreateIfNonExistent(bool value) { + ensureDeserialized(); + _createIfNonExistent = value; + reserialize(); +} + +bool +DocumentUpdate::getCreateIfNonExistent() const { + ensureDeserialized(); + return _createIfNonExistent; +} + +void +DocumentUpdate::print(std::ostream& out, bool verbose, const std::string& indent) const { + ensureDeserialized(); out << "DocumentUpdate("; if (_type) { _type->print(out, verbose, indent + " "); @@ -131,6 +160,7 @@ DocumentUpdate::print(std::ostream& out, bool verbose, void DocumentUpdate::applyTo(Document& doc) const { + ensureDeserialized(); const DocumentType& type = doc.getType(); if (_type->getName() != type.getName()) { string err = make_string("Can not apply a \"%s\" document update to a \"%s\" document.", @@ -150,6 +180,17 @@ DocumentUpdate::applyTo(Document& doc) const } void +DocumentUpdate::serializeHeader() { + string id_string = _documentId.getScheme().toString(); + _backing.write(id_string.data(), id_string.size()); + _backing << static_cast<uint8_t>(0); + _backing.write(getType().getName().c_str(), getType().getName().size() + 1); + _backing << static_cast<uint16_t>(0); // version + _backing << static_cast<uint32_t>(0); // Number of updates + _backing << static_cast<uint32_t>(0); // Number of field path updates +} + +void DocumentUpdate::serializeHEAD(nbostream &stream) const { VespaDocumentSerializer serializer(stream); @@ -165,92 +206,157 @@ DocumentUpdate::serializeFlags(int size_) const } namespace { - std::pair<const DocumentType *, DocumentId> - deserializeTypeAndId(const DocumentTypeRepo& repo, ByteBuffer& buffer) { - nbostream stream(buffer.getBufferAtPos(), buffer.getRemaining()); - DocumentId docId(stream); - buffer.incPos(stream.rp()); - - // Read content bit vector. - unsigned char content = 0x00; - buffer.getByte(content); - - // Why on earth do we have this whether we have type part? - // We need type for object to work, so just throwing exception if it's - // not there. - if((content & CONTENT_HASTYPE) == 0) { - throw IllegalStateException("Missing document type", VESPA_STRLOC); - } - vespalib::stringref typestr = buffer.getBufferAtPos(); - buffer.incPos(typestr.length() + 1); +vespalib::stringref +readCStr(nbostream & stream) { + const char * s = stream.peek(); + size_t sz = strnlen(s, stream.size()); + stream.adjustReadPos(sz+1); + return vespalib::stringref(s, sz); +} - int16_t version = 0; - buffer.getShortNetwork(version); - const DocumentType *type = repo.getDocumentType(typestr); - if (!type) { - throw DocumentTypeNotFoundException(typestr, VESPA_STRLOC); - } - return std::make_pair(type, docId); +std::pair<const DocumentType *, DocumentId> +deserializeTypeAndId(const DocumentTypeRepo& repo, vespalib::nbostream & stream) { + DocumentId docId(stream); + + // Read content bit vector. + unsigned char content = 0x00; + stream >> content; + + // Why on earth do we have this whether we have type part? + // We need type for object to work, so just throwing exception if it's + // not there. + if((content & CONTENT_HASTYPE) == 0) { + throw IllegalStateException("Missing document type", VESPA_STRLOC); } + + vespalib::stringref typestr = readCStr(stream); + + int16_t version = 0; + stream >> version; + const DocumentType *type = repo.getDocumentType(typestr); + if (!type) { + throw DocumentTypeNotFoundException(typestr, VESPA_STRLOC); + } + return std::make_pair(type, docId); +} } // Deserialize the content of the given buffer into this document update. DocumentUpdate::UP -DocumentUpdate::create42(const DocumentTypeRepo& repo, ByteBuffer& buffer) +DocumentUpdate::create42(const DocumentTypeRepo& repo, vespalib::nbostream & stream) { - return std::make_unique<DocumentUpdate>(repo, buffer, SerializeVersion::SERIALIZE_42); + auto update = std::make_unique<DocumentUpdate>(); + update->init42(repo, stream); + return update; } DocumentUpdate::UP DocumentUpdate::createHEAD(const DocumentTypeRepo& repo, ByteBuffer& buffer) { - return std::make_unique<DocumentUpdate>(repo, buffer, SerializeVersion::SERIALIZE_HEAD); + vespalib::nbostream is(buffer.getBufferAtPos(), buffer.getRemaining()); + auto update = std::make_unique<DocumentUpdate>(); + update->initHEAD(repo, is); + buffer.setPos(buffer.getPos() + is.rp()); + return update; +} + +DocumentUpdate::UP +DocumentUpdate::createHEAD(const DocumentTypeRepo& repo, vespalib::nbostream stream) +{ + auto update = std::make_unique<DocumentUpdate>(); + update->initHEAD(repo, std::move(stream)); + return update; } void -DocumentUpdate::deserialize42(const DocumentTypeRepo& repo, ByteBuffer& buffer) +DocumentUpdate::init42(const DocumentTypeRepo & repo, vespalib::nbostream & stream) { - int pos = buffer.getPos(); - try{ - buffer.getShortNetwork(_version); + _repo = &repo; + deserialize42(repo, stream); + reserialize(); +} +void +DocumentUpdate::initHEAD(const DocumentTypeRepo & repo, vespalib::nbostream && stream) +{ + _repo = &repo; + _backing = std::move(stream); + size_t startPos = _backing.rp(); + deserializeHeader(repo, _backing); + _backing.rp(startPos); +} - std::pair<const DocumentType *, DocumentId> typeAndId(deserializeTypeAndId(repo, buffer)); +void +DocumentUpdate::initHEAD(const DocumentTypeRepo & repo, vespalib::nbostream & stream) +{ + size_t startPos = stream.rp(); + deserializeHEAD(repo, stream); + size_t sz = stream.rp() - startPos; + _backing = nbostream(stream.peek() - sz, sz); +} + +void +DocumentUpdate::deserialize42(const DocumentTypeRepo& repo, vespalib::nbostream & stream) +{ + size_t pos = stream.rp(); + try{ + int16_t version(0); + stream >> version; + std::pair<const DocumentType *, DocumentId> typeAndId(deserializeTypeAndId(repo, stream)); _type = typeAndId.first; _documentId = typeAndId.second; // Read field updates, if any. - if(buffer.getRemaining() > 0) { - int sizeAndFlags = 0; - buffer.getIntNetwork(sizeAndFlags); + if (! stream.empty()) { + int32_t sizeAndFlags = 0; + stream >> sizeAndFlags; int numUpdates = deserializeFlags(sizeAndFlags); _updates.reserve(numUpdates); + ByteBuffer buffer(stream.peek(), stream.size()); for (int i = 0; i < numUpdates; i++) { _updates.emplace_back(repo, *typeAndId.first, buffer, _version); } + stream.adjustReadPos(buffer.getPos()); } } catch (const DeserializeException &) { - buffer.setPos(pos); + stream.rp(pos); throw; } catch (const BufferOutOfBoundsException &) { - buffer.setPos(pos); + stream.rp(pos); throw; } } void -DocumentUpdate::deserializeHEAD(const DocumentTypeRepo &repo, ByteBuffer &buffer) +DocumentUpdate::deserializeHeader(const DocumentTypeRepo &repo, vespalib::nbostream & stream) { - int pos = buffer.getPos(); + assert(_updates.empty()); + assert(_fieldPathUpdates.empty()); + _documentId = DocumentId(stream); + + vespalib::stringref typestr = readCStr(stream); + int16_t version = 0; + stream >> version; + const DocumentType *docType = repo.getDocumentType(typestr); + if (!docType) { + throw DocumentTypeNotFoundException(typestr, VESPA_STRLOC); + } + _type = docType; + _type = docType; +} + +void +DocumentUpdate::deserializeHEAD(const DocumentTypeRepo &repo, vespalib::nbostream & stream) +{ + _updates.clear(); + _fieldPathUpdates.clear(); + size_t pos = stream.rp(); try { - nbostream stream(buffer.getBufferAtPos(), buffer.getRemaining()); _documentId = DocumentId(stream); - buffer.incPos(stream.rp()); - vespalib::stringref typestr = buffer.getBufferAtPos(); - buffer.incPos(typestr.length() + 1); + vespalib::stringref typestr = readCStr(stream); int16_t version = 0; - buffer.getShortNetwork(version); + stream >> version; const DocumentType *docType = repo.getDocumentType(typestr); if (!docType) { throw DocumentTypeNotFoundException(typestr, VESPA_STRLOC); @@ -258,27 +364,31 @@ DocumentUpdate::deserializeHEAD(const DocumentTypeRepo &repo, ByteBuffer &buffer _type = docType; // Read field updates, if any. - if (buffer.getRemaining() > 0) { - int numUpdates = 0; - buffer.getIntNetwork(numUpdates); + if ( ! stream.empty() ) { + int32_t numUpdates = 0; + stream >> numUpdates; _updates.reserve(numUpdates); + ByteBuffer buffer(stream.peek(), stream.size()); for (int i = 0; i < numUpdates; i++) { - _updates.emplace_back(repo, *docType, buffer, 8); + _updates.emplace_back(repo, *docType, buffer, _version); } + stream.adjustReadPos(buffer.getPos()); } // Read fieldpath updates, if any - int sizeAndFlags = 0; - buffer.getIntNetwork(sizeAndFlags); + int32_t sizeAndFlags = 0; + stream >> sizeAndFlags; int numUpdates = deserializeFlags(sizeAndFlags); _fieldPathUpdates.reserve(numUpdates); + ByteBuffer buffer(stream.peek(), stream.size()); for (int i = 0; i < numUpdates; ++i) { - _fieldPathUpdates.emplace_back(FieldPathUpdate::createInstance(repo, *_type, buffer, 8).release()); + _fieldPathUpdates.emplace_back(FieldPathUpdate::createInstance(repo, *_type, buffer, _version).release()); } + stream.adjustReadPos(buffer.getPos()); } catch (const DeserializeException &) { - buffer.setPos(pos); + stream.rp(pos); throw; } catch (const BufferOutOfBoundsException &) { - buffer.setPos(pos); + stream.rp(pos); throw; } } @@ -293,6 +403,7 @@ DocumentUpdate::deserializeFlags(int sizeAndFlags) void DocumentUpdate::printXml(XmlOutputStream& xos) const { + ensureDeserialized(); xos << XmlTag("document") << XmlAttribute("type", _type->getName()) << XmlAttribute("id", getId().toString()); @@ -304,4 +415,15 @@ DocumentUpdate::printXml(XmlOutputStream& xos) const xos << XmlEndTag(); } +void +DocumentUpdate::reserialize() +{ + nbostream stream; + VespaDocumentSerializer serializer(stream); + _needHardReserialize = true; + serializer.writeHEAD(*this); + _backing = std::move(stream); + _needHardReserialize = false; +} + } diff --git a/document/src/vespa/document/update/documentupdate.h b/document/src/vespa/document/update/documentupdate.h index c6250fb6b75..f791dceb496 100644 --- a/document/src/vespa/document/update/documentupdate.h +++ b/document/src/vespa/document/update/documentupdate.h @@ -41,16 +41,6 @@ class VespaDocumentSerializer; */ class DocumentUpdate final : public Printable, public XmlSerializable { -private: - /** - * Enum class containing the legal serialization version for - * document updates. This version is not encoded in the serialized - * document update. - */ - enum class SerializeVersion { - SERIALIZE_42, // old style format, before vespa 5.0 - SERIALIZE_HEAD // new style format, since vespa 5.0 - }; public: typedef std::unique_ptr<DocumentUpdate> UP; typedef std::shared_ptr<DocumentUpdate> SP; @@ -60,12 +50,13 @@ public: /** * Create old style document update, no support for field path updates. */ - static DocumentUpdate::UP create42(const DocumentTypeRepo&, ByteBuffer&); + static DocumentUpdate::UP create42(const DocumentTypeRepo & repo, vespalib::nbostream & stream); /** * Create new style document update, possibly with field path updates. */ - static DocumentUpdate::UP createHEAD(const DocumentTypeRepo&, ByteBuffer&); + static DocumentUpdate::UP createHEAD(const DocumentTypeRepo & repo, vespalib::nbostream stream); + static DocumentUpdate::UP createHEAD(const DocumentTypeRepo & repo, ByteBuffer & buffer); /** * Create a document update from a byte buffer containing a serialized @@ -75,7 +66,7 @@ public: * @param buffer The buffer containing the serialized document update * @param serializeVersion Selector between serialization formats. */ - DocumentUpdate(const DocumentTypeRepo &repo, ByteBuffer &buffer, SerializeVersion serializeVersion); + DocumentUpdate(); /** * The document type is not strictly needed, as we know this at applyTo() * time, but search does not use applyTo() code to do the update, and don't @@ -86,7 +77,7 @@ public: * @param type The document type that this update is applicable for. * @param id The identifier of the document that this update is created for. */ - DocumentUpdate(const DataType &type, const DocumentId& id); + DocumentUpdate(const DocumentTypeRepo & repo, const DataType &type, const DocumentId& id); DocumentUpdate(const DocumentUpdate &) = delete; DocumentUpdate & operator = (const DocumentUpdate &) = delete; @@ -104,63 +95,61 @@ public: * type as this. */ void applyTo(Document& doc) const; - - /** - * Add a field update to this document update. - * @return A reference to this. - */ - DocumentUpdate& addUpdate(const FieldUpdate& update); - /** - * Add a fieldpath update to this document update. - * @return A reference to this. - */ + DocumentUpdate& addUpdate(const FieldUpdate& update); DocumentUpdate& addFieldPathUpdate(const FieldPathUpdate::CP& update); /** @return The list of updates. */ - const FieldUpdateV & getUpdates() const { return _updates; } + const FieldUpdateV & getUpdates() const; /** @return The list of fieldpath updates. */ - const FieldPathUpdateV & getFieldPathUpdates() const { return _fieldPathUpdates; } + const FieldPathUpdateV & getFieldPathUpdates() const; + + void eagerDeserialize() const; /** @return The type of document this update is for. */ const DocumentType& getType() const; - void print(std::ostream& out, bool verbose, const std::string& indent) const override; - void serializeHEAD(vespalib::nbostream &stream) const; - void printXml(XmlOutputStream&) const override; /** * Sets whether this update should create the document it updates if that document does not exist. * In this case an empty document is created before the update is applied. */ - void setCreateIfNonExistent(bool value) { - _createIfNonExistent = value; - } + void setCreateIfNonExistent(bool value); /** * Gets whether this update should create the document it updates if that document does not exist. */ - bool getCreateIfNonExistent() const { - return _createIfNonExistent; - } + bool getCreateIfNonExistent() const; int serializeFlags(int size_) const; int16_t getVersion() const { return _version; } private: - DocumentId _documentId; // The ID of the document to update. - const DataType *_type; // The type of document this update is for. - FieldUpdateV _updates; // The list of field updates. - FieldPathUpdateV _fieldPathUpdates; - int16_t _version; // Serialization version - bool _createIfNonExistent; + DocumentId _documentId; // The ID of the document to update. + const DataType *_type; // The type of document this update is for. + const DocumentTypeRepo *_repo; + vespalib::nbostream _backing; + FieldUpdateV _updates; // The list of field updates. + FieldPathUpdateV _fieldPathUpdates; + const int16_t _version; // Serialization version + bool _createIfNonExistent; + bool _needHardReserialize; int deserializeFlags(int sizeAndFlags); - void deserialize42(const DocumentTypeRepo&, ByteBuffer&); - void deserializeHEAD(const DocumentTypeRepo&, ByteBuffer&); + void init42(const DocumentTypeRepo & repo, vespalib::nbostream & stream); + void initHEAD(const DocumentTypeRepo & repo, vespalib::nbostream && stream); + void initHEAD(const DocumentTypeRepo & repo, vespalib::nbostream & stream); + void deserialize42(const DocumentTypeRepo & repo, vespalib::nbostream & stream); + void deserializeHEAD(const DocumentTypeRepo & repo, vespalib::nbostream & stream); + void lazyDeserialize(const DocumentTypeRepo & repo, vespalib::nbostream & stream); + void ensureDeserialized() const; + void serializeHeader(); + void reserialize(); + void deserializeHeader(const DocumentTypeRepo & repo, vespalib::nbostream & stream); + friend VespaDocumentSerializer; }; } // document diff --git a/documentapi/src/tests/messagebus/messagebus_test.cpp b/documentapi/src/tests/messagebus/messagebus_test.cpp index cd2820d8c05..dff3f3f1bac 100644 --- a/documentapi/src/tests/messagebus/messagebus_test.cpp +++ b/documentapi/src/tests/messagebus/messagebus_test.cpp @@ -59,7 +59,7 @@ void Test::testMessage() { // Test one update. UpdateDocumentMessage upd1( document::DocumentUpdate::SP( - new document::DocumentUpdate(*testdoc_type, + new document::DocumentUpdate(*_repo, *testdoc_type, document::DocumentId(document::DocIdString( "testdoc", "testme1"))))); @@ -80,7 +80,7 @@ void Test::testMessage() { // Compare to another. UpdateDocumentMessage upd2( document::DocumentUpdate::SP( - new document::DocumentUpdate(*testdoc_type, + new document::DocumentUpdate(*_repo, *testdoc_type, document::DocumentId(document::DocIdString( "testdoc", "testme2"))))); EXPECT_TRUE(!(upd1.getDocumentUpdate().getId() == upd2.getDocumentUpdate().getId())); diff --git a/documentapi/src/tests/messages/messages50test.cpp b/documentapi/src/tests/messages/messages50test.cpp index 48728ff6057..6705277d5c3 100644 --- a/documentapi/src/tests/messages/messages50test.cpp +++ b/documentapi/src/tests/messages/messages50test.cpp @@ -672,8 +672,7 @@ Messages50Test::testUpdateDocumentMessage() { const DocumentTypeRepo &repo = getTypeRepo(); const document::DocumentType &docType = *repo.getDocumentType("testdoc"); - document::DocumentUpdate::SP - upd(new document::DocumentUpdate(docType, document::DocumentId("doc:scheme:"))); + auto upd(std::make_shared<document::DocumentUpdate>(repo, docType, document::DocumentId("doc:scheme:"))); upd->addFieldPathUpdate(document::FieldPathUpdate::CP( new document::RemoveFieldPathUpdate("intfield", "testdoc.intfield > 0"))); UpdateDocumentMessage msg(upd); @@ -682,7 +681,7 @@ Messages50Test::testUpdateDocumentMessage() EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 89u, serialize("UpdateDocumentMessage", msg)); for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { mbus::Routable::UP obj = deserialize("UpdateDocumentMessage", DocumentProtocol::MESSAGE_UPDATEDOCUMENT, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { + if (EXPECT_TRUE(obj.get() != nullptr)) { UpdateDocumentMessage &ref = static_cast<UpdateDocumentMessage&>(*obj); EXPECT_EQUAL(*upd, ref.getDocumentUpdate()); EXPECT_EQUAL(666u, ref.getOldTimestamp()); @@ -703,21 +702,21 @@ Messages50Test::testBatchDocumentUpdateMessage() { document::DocumentUpdate::SP upd; - upd.reset(new document::DocumentUpdate(docType, document::DocumentId("userdoc:footype:1234:foo"))); + upd.reset(new document::DocumentUpdate(repo, docType, document::DocumentId("userdoc:footype:1234:foo"))); upd->addFieldPathUpdate(document::FieldPathUpdate::CP( new document::RemoveFieldPathUpdate("intfield", "testdoc.intfield > 0"))); msg.addUpdate(upd); } { document::DocumentUpdate::SP upd; - upd.reset(new document::DocumentUpdate(docType, document::DocumentId("orderdoc(32,17):footype:1234:123456789:foo"))); + upd.reset(new document::DocumentUpdate(repo, docType, document::DocumentId("orderdoc(32,17):footype:1234:123456789:foo"))); upd->addFieldPathUpdate(document::FieldPathUpdate::CP( new document::RemoveFieldPathUpdate("intfield", "testdoc.intfield > 0"))); msg.addUpdate(upd); } try { document::DocumentUpdate::SP upd; - upd.reset(new document::DocumentUpdate(docType, document::DocumentId("userdoc:footype:5678:foo"))); + upd.reset(new document::DocumentUpdate(repo, docType, document::DocumentId("userdoc:footype:5678:foo"))); upd->addFieldPathUpdate(document::FieldPathUpdate::CP( new document::RemoveFieldPathUpdate("intfield", "testdoc.intfield > 0"))); msg.addUpdate(upd); @@ -726,7 +725,7 @@ Messages50Test::testBatchDocumentUpdateMessage() } try { document::DocumentUpdate::SP upd; - upd.reset(new document::DocumentUpdate(docType, document::DocumentId("groupdoc:footype:hable:foo"))); + upd.reset(new document::DocumentUpdate(repo, docType, document::DocumentId("groupdoc:footype:hable:foo"))); upd->addFieldPathUpdate(document::FieldPathUpdate::CP( new document::RemoveFieldPathUpdate("intfield", "testdoc.intfield > 0"))); msg.addUpdate(upd); diff --git a/documentapi/src/tests/messages/messages52test.cpp b/documentapi/src/tests/messages/messages52test.cpp index eaf8bbec8c4..8f5d7381500 100644 --- a/documentapi/src/tests/messages/messages52test.cpp +++ b/documentapi/src/tests/messages/messages52test.cpp @@ -91,7 +91,7 @@ Messages52Test::testUpdateDocumentMessage() const DocumentTypeRepo & repo = getTypeRepo(); const document::DocumentType & docType = *repo.getDocumentType("testdoc"); - auto docUpdate = std::make_shared<document::DocumentUpdate>(docType, document::DocumentId("doc:scheme:")); + auto docUpdate = std::make_shared<document::DocumentUpdate>(repo, docType, document::DocumentId("doc:scheme:")); docUpdate->addFieldPathUpdate(document::FieldPathUpdate::CP( new document::RemoveFieldPathUpdate("intfield", "testdoc.intfield > 0"))); diff --git a/documentapi/src/tests/policies/policies_test.cpp b/documentapi/src/tests/policies/policies_test.cpp index 7852136dfc7..3e804c30415 100644 --- a/documentapi/src/tests/policies/policies_test.cpp +++ b/documentapi/src/tests/policies/policies_test.cpp @@ -621,7 +621,7 @@ Test::testDocumentRouteSelector() EXPECT_TRUE(frame.testSelect(StringList().add("foo").add("bar"))); frame.setMessage(make_unique<UpdateDocumentMessage>( - make_shared<DocumentUpdate>(*_docType, DocumentId("doc:scheme:")))); + make_shared<DocumentUpdate>(*_repo, *_docType, DocumentId("doc:scheme:")))); EXPECT_TRUE(frame.testSelect(StringList().add("foo"))); put = make_unique<PutDocumentMessage>(make_shared<Document>(*_docType, DocumentId("doc:scheme:"))); @@ -650,7 +650,7 @@ Test::testDocumentRouteSelectorIgnore() EXPECT_EQUAL(0u, reply->getNumErrors()); frame.setMessage(make_unique<UpdateDocumentMessage>( - make_shared<DocumentUpdate>(*_docType, DocumentId("doc:scheme:")))); + make_shared<DocumentUpdate>(*_repo, *_docType, DocumentId("doc:scheme:")))); EXPECT_TRUE(frame.testSelect(StringList().add("docproc/cluster.foo"))); } diff --git a/persistence/src/vespa/persistence/conformancetest/conformancetest.cpp b/persistence/src/vespa/persistence/conformancetest/conformancetest.cpp index f9538a94c59..c1373a391f0 100644 --- a/persistence/src/vespa/persistence/conformancetest/conformancetest.cpp +++ b/persistence/src/vespa/persistence/conformancetest/conformancetest.cpp @@ -897,10 +897,8 @@ void ConformanceTest::testUpdate() { const document::DocumentType *docType( testDocMan.getTypeRepo().getDocumentType("testdoctype1")); - document::DocumentUpdate::SP - update(new DocumentUpdate(*docType, doc1->getId())); - std::shared_ptr<document::AssignValueUpdate> assignUpdate( - new document::AssignValueUpdate(document::IntFieldValue(42))); + document::DocumentUpdate::SP update(new DocumentUpdate(testDocMan.getTypeRepo(), *docType, doc1->getId())); + std::shared_ptr<document::AssignValueUpdate> assignUpdate(new document::AssignValueUpdate(document::IntFieldValue(42))); document::FieldUpdate fieldUpdate(docType->getField("headerval")); fieldUpdate.addUpdate(*assignUpdate); update->addUpdate(fieldUpdate); diff --git a/searchcore/src/apps/vespa-transactionlog-inspect/vespa-transactionlog-inspect.cpp b/searchcore/src/apps/vespa-transactionlog-inspect/vespa-transactionlog-inspect.cpp index 17f1faffbba..8ffe4807427 100644 --- a/searchcore/src/apps/vespa-transactionlog-inspect/vespa-transactionlog-inspect.cpp +++ b/searchcore/src/apps/vespa-transactionlog-inspect/vespa-transactionlog-inspect.cpp @@ -1,8 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/config/helper/configgetter.h> - #include <vespa/searchcore/proton/server/replaypacketdispatcher.h> +#include <vespa/searchcore/proton/feedoperation/operations.h> #include <vespa/searchlib/common/fileheadercontext.h> #include <vespa/searchlib/transactionlog/translogclient.h> #include <vespa/searchlib/transactionlog/translogserver.h> diff --git a/searchcore/src/tests/proton/attribute/attribute_test.cpp b/searchcore/src/tests/proton/attribute/attribute_test.cpp index c41b6bdcb97..0e6bd2c74fe 100644 --- a/searchcore/src/tests/proton/attribute/attribute_test.cpp +++ b/searchcore/src/tests/proton/attribute/attribute_test.cpp @@ -445,7 +445,7 @@ TEST_F("require that attribute writer handles update", Fixture) schema.addAttributeField(Schema::AttributeField("a2", schema::DataType::INT32, CollectionType::SINGLE)); DocBuilder idb(schema); const document::DocumentType &dt(idb.getDocumentType()); - DocumentUpdate upd(dt, DocumentId("doc::1")); + DocumentUpdate upd(*idb.getDocumentTypeRepo(), dt, DocumentId("doc::1")); upd.addUpdate(FieldUpdate(upd.getType().getField("a1")) .addUpdate(ArithmeticValueUpdate(ArithmeticValueUpdate::Add, 5))); upd.addUpdate(FieldUpdate(upd.getType().getField("a2")) @@ -489,7 +489,7 @@ TEST_F("require that attribute writer handles predicate update", Fixture) EXPECT_EQUAL(2u, a1->getNumDocs()); const document::DocumentType &dt(idb.getDocumentType()); - DocumentUpdate upd(dt, DocumentId("doc::1")); + DocumentUpdate upd(*idb.getDocumentTypeRepo(), dt, DocumentId("doc::1")); PredicateFieldValue new_value(builder.feature("foo").value("bar").build()); upd.addUpdate(FieldUpdate(upd.getType().getField("a1")) .addUpdate(AssignValueUpdate(new_value))); @@ -678,7 +678,7 @@ TEST_F("require that attribute writer handles tensor assign update", Fixture) EXPECT_TRUE(tensor->equals(*tensor2)); const document::DocumentType &dt(builder.getDocumentType()); - DocumentUpdate upd(dt, DocumentId("doc::1")); + DocumentUpdate upd(*builder.getDocumentTypeRepo(), dt, DocumentId("doc::1")); auto new_tensor = createTensor({ {{{"x", "8"}, {"y", "9"}}, 11} }, {"x", "y"}); TensorFieldValue new_value; diff --git a/searchcore/src/tests/proton/documentdb/combiningfeedview/combiningfeedview_test.cpp b/searchcore/src/tests/proton/documentdb/combiningfeedview/combiningfeedview_test.cpp index f06bb124eb8..958be6a4686 100644 --- a/searchcore/src/tests/proton/documentdb/combiningfeedview/combiningfeedview_test.cpp +++ b/searchcore/src/tests/proton/documentdb/combiningfeedview/combiningfeedview_test.cpp @@ -1,15 +1,16 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/log/log.h> -LOG_SETUP("combiningfeedview_test"); #include <vespa/document/test/make_bucket_space.h> -#include <vespa/searchcore/proton/feedoperation/moveoperation.h> +#include <vespa/searchcore/proton/feedoperation/operations.h> #include <vespa/searchcore/proton/server/combiningfeedview.h> #include <vespa/searchcore/proton/test/test.h> #include <vespa/searchlib/common/idestructorcallback.h> #include <vespa/document/update/documentupdate.h> #include <vespa/vespalib/testkit/testapp.h> +#include <vespa/log/log.h> +LOG_SETUP("combiningfeedview_test"); + using document::DocumentTypeRepo; using document::DocumentUpdate; using document::test::makeBucketSpace; @@ -22,8 +23,8 @@ typedef std::vector<IFeedView::SP> FeedViewVector; struct MyStreamHandler : public NewConfigOperation::IStreamHandler { - virtual void serializeConfig(SerialNum, vespalib::nbostream &) override {} - virtual void deserializeConfig(SerialNum, vespalib::nbostream &) override {} + void serializeConfig(SerialNum, vespalib::nbostream &) override {} + void deserializeConfig(SerialNum, vespalib::nbostream &) override {} }; diff --git a/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp b/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp index bab6aff821f..760f7457d33 100644 --- a/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp +++ b/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp @@ -14,6 +14,7 @@ #include <vespa/searchcore/proton/reference/i_document_db_reference_resolver.h> #include <vespa/searchcore/proton/reprocessing/i_reprocessing_task.h> #include <vespa/searchcore/proton/reprocessing/reprocessingrunner.h> +#include <vespa/searchcore/proton/feedoperation/operations.h> #include <vespa/searchcore/proton/server/bootstrapconfig.h> #include <vespa/searchcore/proton/server/document_subdb_explorer.h> #include <vespa/searchcore/proton/server/emptysearchview.h> diff --git a/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp b/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp index e774728b41e..a1bce7174bf 100644 --- a/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp +++ b/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp @@ -316,7 +316,7 @@ struct UpdateContext { DocumentUpdate::SP update; BucketId bucketId; UpdateContext(const vespalib::string &docId, DocBuilder &builder) : - update(new DocumentUpdate(builder.getDocumentType(), DocumentId(docId))), + update(new DocumentUpdate(*builder.getDocumentTypeRepo(), builder.getDocumentType(), DocumentId(docId))), bucketId(BucketFactory::getBucketId(update->getId())) { } diff --git a/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp b/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp index a9fa79f513c..d21e5abe30b 100644 --- a/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp +++ b/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp @@ -11,6 +11,7 @@ #include <vespa/searchcore/proton/server/isummaryadapter.h> #include <vespa/searchcore/proton/server/matchview.h> #include <vespa/searchcore/proton/server/searchable_feed_view.h> +#include <vespa/searchcore/proton/feedoperation/operations.h> #include <vespa/searchcore/proton/test/document_meta_store_context_observer.h> #include <vespa/searchcore/proton/test/dummy_document_store.h> #include <vespa/searchcore/proton/test/dummy_summary_manager.h> @@ -478,11 +479,11 @@ struct DocumentContext DocumentContext::DocumentContext(const vespalib::string &docId, uint64_t timestamp, DocBuilder &builder) : doc(builder.startDocument(docId).startSummaryField("s1").addStr(docId).endField().endDocument().release()), - upd(new DocumentUpdate(builder.getDocumentType(), doc->getId())), + upd(new DocumentUpdate(*builder.getDocumentTypeRepo(), builder.getDocumentType(), doc->getId())), bid(BucketFactory::getNumBucketBits(), doc->getId().getGlobalId().convertToBucketId().getRawId()), ts(timestamp) {} -DocumentContext::~DocumentContext() {} +DocumentContext::~DocumentContext() = default; struct FeedTokenContext { diff --git a/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp b/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp index e8247a52199..d07c29ead69 100644 --- a/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp +++ b/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp @@ -9,6 +9,8 @@ #include <vespa/searchcore/proton/server/putdonecontext.h> #include <vespa/searchcore/proton/server/removedonecontext.h> #include <vespa/searchcore/proton/server/storeonlyfeedview.h> +#include <vespa/searchcore/proton/feedoperation/moveoperation.h> +#include <vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.h> #include <vespa/searchcore/proton/reference/dummy_gid_to_lid_change_handler.h> #include <vespa/searchcore/proton/test/mock_summary_adapter.h> #include <vespa/searchcore/proton/test/thread_utils.h> diff --git a/searchcore/src/tests/proton/feedoperation/feedoperation_test.cpp b/searchcore/src/tests/proton/feedoperation/feedoperation_test.cpp index 9a9d896f2b9..e87e9209a17 100644 --- a/searchcore/src/tests/proton/feedoperation/feedoperation_test.cpp +++ b/searchcore/src/tests/proton/feedoperation/feedoperation_test.cpp @@ -122,7 +122,7 @@ public: } auto makeUpdate() { - auto upd(std::make_shared<DocumentUpdate>(_docType, docId)); + auto upd(std::make_shared<DocumentUpdate>(*_repo, _docType, docId)); upd->addUpdate(FieldUpdate(upd->getType().getField("string")). addUpdate(AssignValueUpdate(StringFieldValue("newval")))); return upd; @@ -136,6 +136,7 @@ public: TEST("require that toString() on derived classes are meaningful") { + DocumentTypeRepo repo; BucketId bucket_id1(42); BucketId bucket_id2(43); BucketId bucket_id3(44); @@ -146,7 +147,7 @@ TEST("require that toString() on derived classes are meaningful") MyStreamHandler stream_handler; DocumentIdT doc_id_limit = 15; DocumentId doc_id("doc:foo:bar"); - DocumentUpdate::SP update(new DocumentUpdate(*DataType::DOCUMENT, doc_id)); + DocumentUpdate::SP update(new DocumentUpdate(repo, *DataType::DOCUMENT, doc_id)); EXPECT_EQUAL("DeleteBucket(BucketId(0x0000000000000000), serialNum=0)", DeleteBucketOperation().toString()); diff --git a/searchcore/src/tests/proton/persistenceengine/persistenceengine_test.cpp b/searchcore/src/tests/proton/persistenceengine/persistenceengine_test.cpp index 73580416e65..7f065d0cc15 100644 --- a/searchcore/src/tests/proton/persistenceengine/persistenceengine_test.cpp +++ b/searchcore/src/tests/proton/persistenceengine/persistenceengine_test.cpp @@ -67,7 +67,9 @@ createDoc(const DocumentType &docType, const DocumentId &docId) document::DocumentUpdate::SP createUpd(const DocumentType& docType, const DocumentId &docId) { - return document::DocumentUpdate::SP(new document::DocumentUpdate(docType, docId)); + static std::vector<std::unique_ptr<document::DocumentTypeRepo>> repoList; + repoList.emplace_back(std::make_unique<document::DocumentTypeRepo>(docType)); + return std::make_shared<document::DocumentUpdate>(*repoList.back(), docType, docId); } storage::spi::ClusterState diff --git a/searchcore/src/tests/proton/server/feedstates_test.cpp b/searchcore/src/tests/proton/server/feedstates_test.cpp index dfa461e2b57..f206ffc9b17 100644 --- a/searchcore/src/tests/proton/server/feedstates_test.cpp +++ b/searchcore/src/tests/proton/server/feedstates_test.cpp @@ -1,8 +1,6 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. // Unit tests for feedstates. -#include <vespa/log/log.h> -LOG_SETUP("feedstates_test"); #include <vespa/document/base/documentid.h> #include <vespa/document/base/testdocrepo.h> @@ -11,6 +9,7 @@ LOG_SETUP("feedstates_test"); #include <vespa/searchcore/proton/server/feedstates.h> #include <vespa/searchcore/proton/server/ireplayconfig.h> #include <vespa/searchcore/proton/server/memoryconfigstore.h> +#include <vespa/searchcore/proton/feedoperation/removeoperation.h> #include <vespa/searchcore/proton/test/dummy_feed_view.h> #include <vespa/searchlib/common/serialnum.h> #include <vespa/vespalib/objects/nbostream.h> @@ -18,6 +17,9 @@ LOG_SETUP("feedstates_test"); #include <vespa/vespalib/util/buffer.h> #include <vespa/searchcore/proton/bucketdb/bucketdbhandler.h> +#include <vespa/log/log.h> +LOG_SETUP("feedstates_test"); + using document::BucketId; using document::DocumentId; using document::DocumentTypeRepo; @@ -83,7 +85,7 @@ Fixture::Fixture() state("doctypename", feed_view_ptr, _bucketDBHandler, replay_config, config_store) { } -Fixture::~Fixture() {} +Fixture::~Fixture() = default; struct RemoveOperationContext @@ -107,7 +109,7 @@ RemoveOperationContext::RemoveOperationContext(search::SerialNum serial) packet.reset(new Packet()); packet->add(Packet::Entry(serial, FeedOperation::REMOVE, buf)); } -RemoveOperationContext::~RemoveOperationContext() {} +RemoveOperationContext::~RemoveOperationContext() = default; TEST_F("require that active FeedView can change during replay", Fixture) { RemoveOperationContext opCtx(10); diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/compact_lid_space_operation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/compact_lid_space_operation.cpp index cd906891b92..c2a3439388a 100644 --- a/searchcore/src/vespa/searchcore/proton/feedoperation/compact_lid_space_operation.cpp +++ b/searchcore/src/vespa/searchcore/proton/feedoperation/compact_lid_space_operation.cpp @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "compact_lid_space_operation.h" +#include <vespa/vespalib/objects/nbostream.h> #include <vespa/vespalib/util/stringfmt.h> namespace proton { @@ -27,8 +28,7 @@ CompactLidSpaceOperation::serialize(vespalib::nbostream& os) const } void -CompactLidSpaceOperation::deserialize(vespalib::nbostream& is, - const document::DocumentTypeRepo&) +CompactLidSpaceOperation::deserialize(vespalib::nbostream& is, const document::DocumentTypeRepo&) { is >> _subDbId; is >> _lidLimit; diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/feedoperation.h b/searchcore/src/vespa/searchcore/proton/feedoperation/feedoperation.h index 8a00c739126..77b95547bd0 100644 --- a/searchcore/src/vespa/searchcore/proton/feedoperation/feedoperation.h +++ b/searchcore/src/vespa/searchcore/proton/feedoperation/feedoperation.h @@ -2,10 +2,10 @@ #pragma once #include <vespa/searchlib/common/serialnum.h> -#include <vespa/vespalib/objects/nbostream.h> +#include <vespa/vespalib/stllike/string.h> namespace document { class DocumentTypeRepo; } - +namespace vespalib { class nbostream; } namespace proton { class FeedOperation diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.cpp index 71a701bdb40..67e4d1b4287 100644 --- a/searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.cpp +++ b/searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.cpp @@ -2,6 +2,7 @@ #include "lidvectorcontext.h" #include <vespa/searchlib/common/bitvector.h> +#include <vespa/vespalib/objects/nbostream.h> #include <vespa/log/log.h> LOG_SETUP(".proton.feedoperation.lidvectorcontext"); diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.h b/searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.h index b432bbcf20a..b307e50da0a 100644 --- a/searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.h +++ b/searchcore/src/vespa/searchcore/proton/feedoperation/lidvectorcontext.h @@ -2,9 +2,10 @@ #pragma once #include <vespa/searchlib/query/base.h> -#include <vespa/vespalib/objects/nbostream.h> #include <vector> +namespace vespalib { class nbostream; } + namespace proton { class LidVectorContext @@ -29,5 +30,4 @@ public: size_t getNumLids() const { return _result.size(); } }; -} // namespace proton - +} diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/newconfigoperation.h b/searchcore/src/vespa/searchcore/proton/feedoperation/newconfigoperation.h index b7b041135d4..144aa534bf7 100644 --- a/searchcore/src/vespa/searchcore/proton/feedoperation/newconfigoperation.h +++ b/searchcore/src/vespa/searchcore/proton/feedoperation/newconfigoperation.h @@ -2,30 +2,29 @@ #pragma once #include "feedoperation.h" -#include <vespa/vespalib/objects/nbostream.h> namespace proton { + namespace feedoperation { + struct IStreamHandler { + virtual ~IStreamHandler() {} + virtual void serializeConfig(search::SerialNum serialNum, vespalib::nbostream &os) = 0; + virtual void deserializeConfig(search::SerialNum serialNum, vespalib::nbostream &is) = 0; + }; + } + class NewConfigOperation : public FeedOperation { public: - struct IStreamHandler { - virtual ~IStreamHandler() {} - virtual void serializeConfig(SerialNum serialNum, - vespalib::nbostream &os) = 0; - virtual void deserializeConfig(SerialNum serialNum, - vespalib::nbostream &is) = 0; - }; + using IStreamHandler = feedoperation::IStreamHandler; private: IStreamHandler &_streamHandler; public: - NewConfigOperation(SerialNum serialNum, - IStreamHandler &streamHandler); - virtual ~NewConfigOperation() {} - virtual void serialize(vespalib::nbostream &os) const override; - virtual void deserialize(vespalib::nbostream &is, - const document::DocumentTypeRepo &repo) override; - virtual vespalib::string toString() const override; + NewConfigOperation(SerialNum serialNum, IStreamHandler &streamHandler); + ~NewConfigOperation() override {} + void serialize(vespalib::nbostream &os) const override; + void deserialize(vespalib::nbostream &is, const document::DocumentTypeRepo &repo) override; + vespalib::string toString() const override; }; } // namespace proton diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.cpp index eea693e4680..69f754cd594 100644 --- a/searchcore/src/vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.cpp +++ b/searchcore/src/vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.cpp @@ -2,6 +2,7 @@ #include "pruneremoveddocumentsoperation.h" #include <vespa/vespalib/util/stringfmt.h> +#include <vespa/vespalib/objects/nbostream.h> #include <cassert> #include <vespa/log/log.h> @@ -22,8 +23,7 @@ PruneRemovedDocumentsOperation::PruneRemovedDocumentsOperation() PruneRemovedDocumentsOperation:: -PruneRemovedDocumentsOperation(DocumentIdT docIdLimit, - uint32_t subDbId) +PruneRemovedDocumentsOperation(DocumentIdT docIdLimit, uint32_t subDbId) : RemoveDocumentsOperation(FeedOperation::PRUNE_REMOVED_DOCUMENTS), _subDbId(subDbId) { @@ -44,8 +44,7 @@ PruneRemovedDocumentsOperation::serialize(vespalib::nbostream &os) const void -PruneRemovedDocumentsOperation::deserialize(vespalib::nbostream &is, - const DocumentTypeRepo &) +PruneRemovedDocumentsOperation::deserialize(vespalib::nbostream &is, const DocumentTypeRepo &) { is >> _subDbId; deserializeLidsToRemove(is); diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/removedocumentsoperation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/removedocumentsoperation.cpp index 6aa479611d1..ef482a19ca3 100644 --- a/searchcore/src/vespa/searchcore/proton/feedoperation/removedocumentsoperation.cpp +++ b/searchcore/src/vespa/searchcore/proton/feedoperation/removedocumentsoperation.cpp @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "removedocumentsoperation.h" +#include <vespa/vespalib/objects/nbostream.h> namespace proton { @@ -16,11 +17,9 @@ RemoveDocumentsOperation::serializeLidsToRemove(vespalib::nbostream &os) const { uint32_t mapSize = _lidsToRemoveMap.size(); os << mapSize; - for (LidsToRemoveMap::const_iterator - it = _lidsToRemoveMap.begin(), ite = _lidsToRemoveMap.end(); - it != ite; ++it) { - os << it->first; - it->second->serialize(os); + for (const auto & entry : _lidsToRemoveMap) { + os << entry.first; + entry.second->serialize(os); } } diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.cpp index f3ef73f4d90..16ddedc4745 100644 --- a/searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.cpp +++ b/searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.cpp @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "spoolerreplayoperation.h" +#include <vespa/vespalib/objects/nbostream.h> #include <vespa/vespalib/util/stringfmt.h> using vespalib::make_string; @@ -14,10 +15,7 @@ SpoolerReplayOperation::SpoolerReplayOperation(Type type) { } - -SpoolerReplayOperation::SpoolerReplayOperation(Type type, - SerialNum serialNum, - SerialNum spoolerSerialNum) +SpoolerReplayOperation::SpoolerReplayOperation(Type type, SerialNum serialNum, SerialNum spoolerSerialNum) : FeedOperation(type), _spoolerSerialNum(spoolerSerialNum) { @@ -39,11 +37,8 @@ SpoolerReplayOperation::deserialize(vespalib::nbostream &is) } vespalib::string SpoolerReplayOperation::toString() const { - return make_string( - "SpoolerReplay%s(spoolerSerialNum=%" PRIu64 - ", serialNum=%" PRIu64 ")", - getType() == SPOOLER_REPLAY_START ? "Start" : "Complete", - _spoolerSerialNum, getSerialNum()); + return make_string("SpoolerReplay%s(spoolerSerialNum=%" PRIu64", serialNum=%" PRIu64 ")", + getType() == SPOOLER_REPLAY_START ? "Start" : "Complete", _spoolerSerialNum, getSerialNum()); } @@ -53,8 +48,7 @@ SpoolerReplayStartOperation::SpoolerReplayStartOperation() } -SpoolerReplayStartOperation::SpoolerReplayStartOperation(SerialNum serialNum, - SerialNum spoolerSerialNum) +SpoolerReplayStartOperation::SpoolerReplayStartOperation(SerialNum serialNum, SerialNum spoolerSerialNum) : SpoolerReplayOperation(FeedOperation::SPOOLER_REPLAY_START, serialNum, spoolerSerialNum) @@ -70,12 +64,8 @@ SpoolerReplayCompleteOperation::SpoolerReplayCompleteOperation() SpoolerReplayCompleteOperation::SpoolerReplayCompleteOperation(SerialNum serialNum, SerialNum spoolerSerialNum) - : SpoolerReplayOperation(FeedOperation::SPOOLER_REPLAY_COMPLETE, - serialNum, - spoolerSerialNum) + : SpoolerReplayOperation(FeedOperation::SPOOLER_REPLAY_COMPLETE, serialNum, spoolerSerialNum) { } - - } // namespace proton diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.h b/searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.h index 028d01dec20..028ad1c6bfa 100644 --- a/searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.h +++ b/searchcore/src/vespa/searchcore/proton/feedoperation/spoolerreplayoperation.h @@ -11,15 +11,12 @@ private: SerialNum _spoolerSerialNum; protected: SpoolerReplayOperation(Type type); - SpoolerReplayOperation(Type type, - SerialNum serialNum, - SerialNum spoolerSerialNum); + SpoolerReplayOperation(Type type, SerialNum serialNum, SerialNum spoolerSerialNum); public: - virtual ~SpoolerReplayOperation() {} + ~SpoolerReplayOperation() override {} SerialNum getSpoolerSerialNum() const { return _spoolerSerialNum; } - virtual void serialize(vespalib::nbostream &os) const override; - virtual void deserialize(vespalib::nbostream &is, - const document::DocumentTypeRepo &) override { + void serialize(vespalib::nbostream &os) const override; + void deserialize(vespalib::nbostream &is, const document::DocumentTypeRepo &) override { deserialize(is); } void deserialize(vespalib::nbostream &is); @@ -38,8 +35,7 @@ public: * @param serialNum the current serial number of the transaction log. * @param spoolerSerialNum the serial number of the first entry of the spooler log replay. */ - SpoolerReplayStartOperation(SerialNum serialNum, - SerialNum spoolerSerialNum); + SpoolerReplayStartOperation(SerialNum serialNum, SerialNum spoolerSerialNum); }; @@ -54,8 +50,7 @@ public: * @param serialNum the current serial number of the transaction log. * @param spoolerSerialNum the serial number of the last entry of the spooler log replay. */ - SpoolerReplayCompleteOperation(SerialNum serialNum, - SerialNum spoolerSerialNum); + SpoolerReplayCompleteOperation(SerialNum serialNum, SerialNum spoolerSerialNum); }; } // namespace proton diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.cpp index d31f1faec77..dc83848152c 100644 --- a/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.cpp +++ b/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.cpp @@ -51,12 +51,11 @@ UpdateOperation::serializeUpdate(vespalib::nbostream &os) const } void -UpdateOperation::deserializeUpdate(vespalib::nbostream &is, const document::DocumentTypeRepo &repo) +UpdateOperation::deserializeUpdate(vespalib::nbostream && is, const document::DocumentTypeRepo &repo) { - document::ByteBuffer buf(is.peek(), is.size()); - DocumentUpdate::UP update = (getType() == UPDATE_42) ? DocumentUpdate::create42(repo, buf) : DocumentUpdate::createHEAD(repo, buf); - is.adjustReadPos(buf.getPos()); - _upd = std::move(update); + _upd = (getType() == UPDATE_42) + ? DocumentUpdate::create42(repo, is) + : DocumentUpdate::createHEAD(repo, std::move(is)); } void @@ -73,7 +72,7 @@ UpdateOperation::deserialize(vespalib::nbostream &is, const DocumentTypeRepo &re { DocumentOperation::deserialize(is, repo); try { - deserializeUpdate(is, repo); + deserializeUpdate(std::move(is), repo); } catch (document::DocumentTypeNotFoundException &e) { LOG(warning, "Failed deserialize update operation using unknown document type '%s'", e.getDocumentTypeName().c_str()); @@ -83,18 +82,19 @@ UpdateOperation::deserialize(vespalib::nbostream &is, const DocumentTypeRepo &re } void -UpdateOperation::deserializeUpdate(const DocumentTypeRepo &repo) +UpdateOperation::verifyUpdate(const DocumentTypeRepo &repo) { vespalib::nbostream stream; serializeUpdate(stream); - deserializeUpdate(stream, repo); + deserializeUpdate(std::move(stream), repo); + _upd->eagerDeserialize(); // Will trigger exceptions if incompatible } -vespalib::string UpdateOperation::toString() const { +vespalib::string +UpdateOperation::toString() const { return make_string("%s(%s, %s)", ((getType() == FeedOperation::UPDATE_42) ? "Update42" : "Update"), - _upd.get() ? - _upd->getId().getScheme().toString().c_str() : "NULL", + _upd.get() ? _upd->getId().getScheme().toString().c_str() : "NULL", docArgsToString().c_str()); } diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.h b/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.h index 99dcbfbce6c..83e87fea096 100644 --- a/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.h +++ b/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.h @@ -19,7 +19,7 @@ private: const storage::spi::Timestamp ×tamp, const DocumentUpdateSP &upd); void serializeUpdate(vespalib::nbostream &os) const; - void deserializeUpdate(vespalib::nbostream &is, const document::DocumentTypeRepo &repo); + void deserializeUpdate(vespalib::nbostream && is, const document::DocumentTypeRepo &repo); public: UpdateOperation(); UpdateOperation(Type type); @@ -30,7 +30,7 @@ public: const DocumentUpdateSP &getUpdate() const { return _upd; } void serialize(vespalib::nbostream &os) const override; void deserialize(vespalib::nbostream &is, const document::DocumentTypeRepo &repo) override; - void deserializeUpdate(const document::DocumentTypeRepo &repo); + void verifyUpdate(const document::DocumentTypeRepo &repo); vespalib::string toString() const override; }; diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.cpp index d7f38a0cc52..c5e6acd80ed 100644 --- a/searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.cpp +++ b/searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.cpp @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "wipehistoryoperation.h" +#include <vespa/vespalib/objects/nbostream.h> #include <vespa/vespalib/util/stringfmt.h> using vespalib::make_string; @@ -9,29 +10,29 @@ namespace proton { WipeHistoryOperation::WipeHistoryOperation() : FeedOperation(FeedOperation::WIPE_HISTORY), - _wipeTimeLimit(0) { + _wipeTimeLimit(0) +{ } WipeHistoryOperation::WipeHistoryOperation(SerialNum serialNum, fastos::TimeStamp wipeTimeLimit) : FeedOperation(FeedOperation::WIPE_HISTORY), - _wipeTimeLimit(wipeTimeLimit) { + _wipeTimeLimit(wipeTimeLimit) +{ setSerialNum(serialNum); } void WipeHistoryOperation::serialize(vespalib::nbostream &str) const { str << _wipeTimeLimit; } -void WipeHistoryOperation::deserialize(vespalib::nbostream &str, - const document::DocumentTypeRepo &) { +void WipeHistoryOperation::deserialize(vespalib::nbostream &str, const document::DocumentTypeRepo &) { fastos::TimeStamp::TimeT t; str >> t; _wipeTimeLimit = t; } vespalib::string WipeHistoryOperation::toString() const { - return make_string("WipeHistory(wipeTimeLimit=%" PRIu64 - ", serialNum=%" PRIu64 ")", + return make_string("WipeHistory(wipeTimeLimit=%" PRIu64 ", serialNum=%" PRIu64 ")", _wipeTimeLimit.ns(), getSerialNum()); } diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.h b/searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.h index 80b551dbd92..0cf7256bf27 100644 --- a/searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.h +++ b/searchcore/src/vespa/searchcore/proton/feedoperation/wipehistoryoperation.h @@ -12,14 +12,13 @@ class WipeHistoryOperation : public FeedOperation { public: WipeHistoryOperation(); WipeHistoryOperation(SerialNum serialNum, fastos::TimeStamp wipeTimeLimit); - virtual ~WipeHistoryOperation() {} + ~WipeHistoryOperation() override {} fastos::TimeStamp getWipeTimeLimit() const { return _wipeTimeLimit; } - virtual void serialize(vespalib::nbostream &str) const override; - virtual void deserialize(vespalib::nbostream &str, - const document::DocumentTypeRepo &) override; - virtual vespalib::string toString() const override; + void serialize(vespalib::nbostream &str) const override; + void deserialize(vespalib::nbostream &str, const document::DocumentTypeRepo &) override; + vespalib::string toString() const override; }; } // namespace proton diff --git a/searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.cpp b/searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.cpp index bab3494ca5c..f774c953af4 100644 --- a/searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.cpp +++ b/searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.cpp @@ -377,6 +377,7 @@ PersistenceEngine::update(const Bucket& b, Timestamp t, const DocumentUpdate::SP upd->getId().toString().c_str(), state.message().c_str())); } } + upd->eagerDeserialize(); std::shared_lock<std::shared_timed_mutex> rguard(_rwMutex); DocTypeName docType(upd->getType()); LOG(spam, "update(%s, %" PRIu64 ", (\"%s\", \"%s\"), createIfNonExistent='%s')", diff --git a/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.cpp b/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.cpp index 987218beefa..6ed801154d8 100644 --- a/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.cpp @@ -3,7 +3,7 @@ #include "combiningfeedview.h" #include <vespa/document/fieldvalue/document.h> #include <vespa/searchcore/proton/documentmetastore/i_document_meta_store.h> -#include <vespa/searchcore/proton/feedoperation/moveoperation.h> +#include <vespa/searchcore/proton/feedoperation/operations.h> #include <vespa/searchlib/common/idestructorcallback.h> #include <vespa/log/log.h> @@ -13,17 +13,15 @@ using document::DocumentTypeRepo; using document::DocumentId; using search::IDestructorCallback; -namespace proton -{ +namespace proton { -namespace -{ +namespace { std::shared_ptr<const DocumentTypeRepo> getRepo(const std::vector<IFeedView::SP> &views) { for (const auto &view : views) { - if (view.get() == NULL) + if (view.get() == nullptr) continue; return view->getDocumentTypeRepo(); } diff --git a/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.h b/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.h index 6644f21a3b7..3546fdbea71 100644 --- a/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.h +++ b/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.h @@ -3,21 +3,14 @@ #pragma once #include "ifeedview.h" -#include <vespa/searchcore/proton/common/feedtoken.h> -#include <vespa/searchcore/proton/feedoperation/deletebucketoperation.h> -#include <vespa/searchcore/proton/feedoperation/joinbucketsoperation.h> -#include <vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.h> -#include <vespa/searchcore/proton/feedoperation/putoperation.h> -#include <vespa/searchcore/proton/feedoperation/removeoperation.h> -#include <vespa/searchcore/proton/feedoperation/splitbucketoperation.h> -#include <vespa/searchcore/proton/feedoperation/updateoperation.h> -#include <vespa/searchcore/proton/feedoperation/createbucketoperation.h> -#include <vespa/searchlib/common/serialnum.h> #include "replaypacketdispatcher.h" #include "ibucketstatecalculator.h" +#include <vespa/searchcore/proton/common/feedtoken.h> +#include <vespa/searchlib/common/serialnum.h> namespace proton { +class DocumentOperation; class CombiningFeedView : public IFeedView { diff --git a/searchcore/src/vespa/searchcore/proton/server/documentdb.cpp b/searchcore/src/vespa/searchcore/proton/server/documentdb.cpp index 61ce0e6dc6f..ad7a2d57c89 100644 --- a/searchcore/src/vespa/searchcore/proton/server/documentdb.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/documentdb.cpp @@ -17,6 +17,7 @@ #include <vespa/searchcore/proton/attribute/imported_attributes_repo.h> #include <vespa/searchcore/proton/common/eventlogger.h> #include <vespa/searchcore/proton/common/statusreport.h> +#include <vespa/searchcore/proton/feedoperation/noopoperation.h> #include <vespa/searchcore/proton/index/index_writer.h> #include <vespa/searchcore/proton/initializer/task_runner.h> #include <vespa/searchcore/proton/metrics/attribute_metrics_collection.h> diff --git a/searchcore/src/vespa/searchcore/proton/server/fast_access_feed_view.cpp b/searchcore/src/vespa/searchcore/proton/server/fast_access_feed_view.cpp index 6364e772f94..1c2406b2acf 100644 --- a/searchcore/src/vespa/searchcore/proton/server/fast_access_feed_view.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/fast_access_feed_view.cpp @@ -5,6 +5,7 @@ #include "operationdonecontext.h" #include "removedonecontext.h" #include "putdonecontext.h" +#include <vespa/searchcore/proton/feedoperation/operations.h> #include <vespa/searchlib/common/isequencedtaskexecutor.h> using document::Document; @@ -71,7 +72,7 @@ FastAccessFeedView::FastAccessFeedView(const StoreOnlyFeedView::Context &storeOn _docIdLimit(ctx._docIdLimit) {} -FastAccessFeedView::~FastAccessFeedView() {} +FastAccessFeedView::~FastAccessFeedView() = default; void FastAccessFeedView::handleCompactLidSpace(const CompactLidSpaceOperation &op) diff --git a/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp b/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp index 66e721f9222..97cc25e635f 100644 --- a/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp @@ -14,6 +14,7 @@ #include <vespa/searchcore/proton/bucketdb/ibucketdbhandler.h> #include <vespa/searchcore/proton/persistenceengine/i_resource_write_filter.h> #include <vespa/searchcore/proton/persistenceengine/transport_latch.h> +#include <vespa/searchcore/proton/feedoperation/operations.h> #include <vespa/searchcore/proton/common/eventlogger.h> #include <vespa/searchcorespi/index/ithreadingservice.h> #include <vespa/searchlib/common/gatecallback.h> @@ -522,7 +523,7 @@ FeedHandler::considerUpdateOperationForRejection(FeedToken &token, UpdateOperati */ if (_documentType != &update.getType()) { try { - op.deserializeUpdate(*_repo); + op.verifyUpdate(*_repo); } catch (document::FieldNotFoundException &e) { if (token) { auto message = make_string("Update operation rejected for document '%s' of type '%s': 'Field not found'", diff --git a/searchcore/src/vespa/searchcore/proton/server/feedstate.h b/searchcore/src/vespa/searchcore/proton/server/feedstate.h index 472f5cb224f..fa0a1702499 100644 --- a/searchcore/src/vespa/searchcore/proton/server/feedstate.h +++ b/searchcore/src/vespa/searchcore/proton/server/feedstate.h @@ -25,6 +25,7 @@ private: Type _type; protected: + using FeedOperationUP = std::unique_ptr<FeedOperation>; void throwExceptionInReceive(const vespalib::string &docType, uint64_t serialRangeFrom, uint64_t serialRangeTo, size_t packetSize); void throwExceptionInHandleOperation(const vespalib::string &docType, const FeedOperation &op); @@ -38,7 +39,7 @@ public: Type getType() const { return _type; } vespalib::string getName() const; - virtual void handleOperation(FeedToken token, std::unique_ptr<FeedOperation> op) = 0; + virtual void handleOperation(FeedToken token, FeedOperationUP op) = 0; virtual void receive(const PacketWrapper::SP &wrap, vespalib::Executor &executor) = 0; }; diff --git a/searchcore/src/vespa/searchcore/proton/server/feedstates.cpp b/searchcore/src/vespa/searchcore/proton/server/feedstates.cpp index f0866347f59..ae323bc93df 100644 --- a/searchcore/src/vespa/searchcore/proton/server/feedstates.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/feedstates.cpp @@ -6,6 +6,7 @@ #include "ireplayconfig.h" #include "replaypacketdispatcher.h" #include <vespa/searchcore/proton/bucketdb/ibucketdbhandler.h> +#include <vespa/searchcore/proton/feedoperation/operations.h> #include <vespa/searchcore/proton/common/eventlogger.h> #include <vespa/searchlib/common/idestructorcallback.h> #include <vespa/vespalib/util/closuretask.h> diff --git a/searchcore/src/vespa/searchcore/proton/server/feedstates.h b/searchcore/src/vespa/searchcore/proton/server/feedstates.h index 963a78d0d6b..a9224669d87 100644 --- a/searchcore/src/vespa/searchcore/proton/server/feedstates.h +++ b/searchcore/src/vespa/searchcore/proton/server/feedstates.h @@ -28,16 +28,13 @@ public: { } - virtual void handleOperation(FeedToken, FeedOperation::UP op) override { + void handleOperation(FeedToken, FeedOperationUP op) override { throwExceptionInHandleOperation(_doc_type_name, *op); } - virtual void - receive(const PacketWrapper::SP &wrap, vespalib::Executor &) override { - throwExceptionInReceive(_doc_type_name.c_str(), - wrap->packet.range().from(), - wrap->packet.range().to(), - wrap->packet.size()); + void receive(const PacketWrapper::SP &wrap, vespalib::Executor &) override { + throwExceptionInReceive(_doc_type_name.c_str(), wrap->packet.range().from(), + wrap->packet.range().to(), wrap->packet.size()); } }; @@ -57,12 +54,11 @@ public: IReplayConfig &replay_config, FeedConfigStore &config_store); - virtual void handleOperation(FeedToken, FeedOperation::UP op) override { + void handleOperation(FeedToken, FeedOperationUP op) override { throwExceptionInHandleOperation(_doc_type_name, *op); } - virtual void receive(const PacketWrapper::SP &wrap, - vespalib::Executor &executor) override; + void receive(const PacketWrapper::SP &wrap, vespalib::Executor &executor) override; }; @@ -79,15 +75,13 @@ public: _handler(handler) { } - void handleOperation(FeedToken token, FeedOperation::UP op) override { + void handleOperation(FeedToken token, FeedOperationUP op) override { _handler.performOperation(std::move(token), std::move(op)); } void receive(const PacketWrapper::SP &wrap, vespalib::Executor &) override { - throwExceptionInReceive(_handler.getDocTypeName().c_str(), - wrap->packet.range().from(), - wrap->packet.range().to(), - wrap->packet.size()); + throwExceptionInReceive(_handler.getDocTypeName().c_str(), wrap->packet.range().from(), + wrap->packet.range().to(), wrap->packet.size()); } }; } // namespace proton diff --git a/searchcore/src/vespa/searchcore/proton/server/ireplaypackethandler.h b/searchcore/src/vespa/searchcore/proton/server/ireplaypackethandler.h index 210ece3a36a..e93821e2a36 100644 --- a/searchcore/src/vespa/searchcore/proton/server/ireplaypackethandler.h +++ b/searchcore/src/vespa/searchcore/proton/server/ireplaypackethandler.h @@ -2,10 +2,28 @@ #pragma once -#include <vespa/searchcore/proton/feedoperation/operations.h> +namespace document { class DocumentTypeRepo; } namespace proton { +class PutOperation; +class RemoveOperation; +class UpdateOperation; +class NoopOperation; +class NewConfigOperation; +class WipeHistoryOperation; +class DeleteBucketOperation; +class SplitBucketOperation; +class JoinBucketsOperation; +class PruneRemovedDocumentsOperation; +class SpoolerReplayStartOperation; +class SpoolerReplayCompleteOperation; +class MoveOperation; +class CreateBucketOperation; +class CompactLidSpaceOperation; + +namespace feedoperation { class IStreamHandler; } + /** * Interface used to handle the various feed operations during * replay of the transaction log. @@ -29,7 +47,7 @@ struct IReplayPacketHandler virtual void replay(const CreateBucketOperation &op) = 0; virtual void replay(const CompactLidSpaceOperation &op) = 0; - virtual NewConfigOperation::IStreamHandler &getNewConfigStreamHandler() = 0; + virtual feedoperation::IStreamHandler &getNewConfigStreamHandler() = 0; virtual const document::DocumentTypeRepo &getDeserializeRepo() = 0; }; diff --git a/searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.cpp b/searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.cpp index cdb42906fc2..42451f08315 100644 --- a/searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.cpp @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "replaypacketdispatcher.h" +#include <vespa/searchcore/proton/feedoperation/operations.h> #include <vespa/vespalib/util/exceptions.h> #include <vespa/document/util/serializableexceptions.h> diff --git a/searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.h b/searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.h index fc6f99471d8..771a79ddad9 100644 --- a/searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.h +++ b/searchcore/src/vespa/searchcore/proton/server/replaypacketdispatcher.h @@ -7,6 +7,7 @@ namespace proton { +class FeedOperation; /** * Utility class that deserializes packet entries into feed operations * during replay from the transaction log and dispatches the feed operations @@ -22,14 +23,11 @@ private: void replay(OperationType &op, vespalib::nbostream &is, const Packet::Entry &entry); protected: - virtual void - store(const FeedOperation &op); + virtual void store(const FeedOperation &op); public: ReplayPacketDispatcher(IReplayPacketHandler &handler); - - virtual - ~ReplayPacketDispatcher(); + virtual ~ReplayPacketDispatcher(); void replayEntry(const Packet::Entry &entry); }; diff --git a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp index 29615b0daf9..22ff1b90de4 100644 --- a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp @@ -13,6 +13,7 @@ #include <vespa/searchcore/proton/documentmetastore/ilidreusedelayer.h> #include <vespa/searchcore/proton/reference/i_gid_to_lid_change_handler.h> #include <vespa/searchcore/proton/attribute/ifieldupdatecallback.h> +#include <vespa/searchcore/proton/feedoperation/operations.h> #include <vespa/searchlib/common/isequencedtaskexecutor.h> #include <vespa/document/datatype/documenttype.h> diff --git a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h index 825e14b4368..37f67399f4d 100644 --- a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h +++ b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.h @@ -13,7 +13,7 @@ #include <vespa/searchcore/proton/common/feeddebugger.h> #include <vespa/searchcore/proton/documentmetastore/documentmetastore.h> #include <vespa/searchcore/proton/documentmetastore/documentmetastorecontext.h> -#include <vespa/searchcore/proton/feedoperation/feedoperation.h> +#include <vespa/searchcore/proton/feedoperation/lidvectorcontext.h> #include <vespa/searchcore/proton/persistenceengine/resulthandler.h> #include <vespa/searchcore/proton/reference/pending_notify_remove_done.h> #include <vespa/searchcorespi/index/ithreadingservice.h> @@ -23,7 +23,6 @@ namespace search { class IDestructorCallback; } -namespace document { class GLobalId; } namespace proton { @@ -35,6 +34,8 @@ class RemoveDoneContext; class CommitTimeTracker; class IGidToLidChangeHandler; class IFieldUpdateCallback; +class RemoveDocumentsOperation; +class DocumentOperation; namespace documentmetastore { class ILidReuseDelayer; } diff --git a/storage/src/tests/bucketdb/bucketmanagertest.cpp b/storage/src/tests/bucketdb/bucketmanagertest.cpp index d12e6b90b2a..829a080ad01 100644 --- a/storage/src/tests/bucketdb/bucketmanagertest.cpp +++ b/storage/src/tests/bucketdb/bucketmanagertest.cpp @@ -723,6 +723,7 @@ public: auto createUpdateCommand(const document::BucketId& bucket) const { auto update = std::make_shared<document::DocumentUpdate>( + _self._node->getTestDocMan().getTypeRepo(), *_self._node->getTestDocMan().getTypeRepo() .getDocumentType("testdoctype1"), document::DocumentId("id:foo:testdoctype1::bar2")); diff --git a/storage/src/tests/distributor/externaloperationhandlertest.cpp b/storage/src/tests/distributor/externaloperationhandlertest.cpp index 81b0293b0c0..54aca78d13d 100644 --- a/storage/src/tests/distributor/externaloperationhandlertest.cpp +++ b/storage/src/tests/distributor/externaloperationhandlertest.cpp @@ -200,6 +200,7 @@ std::shared_ptr<api::UpdateCommand> ExternalOperationHandlerTest::makeUpdateComm const vespalib::string& doc_type, const vespalib::string& id) const { auto update = std::make_shared<document::DocumentUpdate>( + _testDocMan.getTypeRepo(), *_testDocMan.getTypeRepo().getDocumentType(doc_type), document::DocumentId(id)); return std::make_shared<api::UpdateCommand>( diff --git a/storage/src/tests/distributor/twophaseupdateoperationtest.cpp b/storage/src/tests/distributor/twophaseupdateoperationtest.cpp index 28602124045..ea2cc00c642 100644 --- a/storage/src/tests/distributor/twophaseupdateoperationtest.cpp +++ b/storage/src/tests/distributor/twophaseupdateoperationtest.cpp @@ -294,7 +294,7 @@ TwoPhaseUpdateOperationTest::sendUpdate(const std::string& bucketState, document::DocumentUpdate::SP update; if (!options._withError) { update = std::make_shared<document::DocumentUpdate>( - *_doc_type, + *_repo, *_doc_type, document::DocumentId(document::DocIdString("test", "test"))); document::FieldUpdate fup(_doc_type->getField("headerval")); fup.addUpdate(ArithmeticValueUpdate(ArithmeticValueUpdate::Add, 10)); @@ -304,7 +304,7 @@ TwoPhaseUpdateOperationTest::sendUpdate(const std::string& bucketState, // part of the Get. Just a sneaky way to force an eval error. auto* badDocType = _repo->getDocumentType("testdoctype2"); update = std::make_shared<document::DocumentUpdate>( - *badDocType, + *_repo, *badDocType, document::DocumentId(document::DocIdString("test", "test"))); document::FieldUpdate fup(badDocType->getField("onlyinchild")); fup.addUpdate(ArithmeticValueUpdate(ArithmeticValueUpdate::Add, 10)); diff --git a/storage/src/tests/distributor/updateoperationtest.cpp b/storage/src/tests/distributor/updateoperationtest.cpp index 92474728957..9ce862f5db8 100644 --- a/storage/src/tests/distributor/updateoperationtest.cpp +++ b/storage/src/tests/distributor/updateoperationtest.cpp @@ -75,8 +75,7 @@ std::shared_ptr<UpdateOperation> UpdateOperation_Test::sendUpdate(const std::string& bucketState) { document::DocumentUpdate::SP update( - new document::DocumentUpdate( - *_html_type, + new document::DocumentUpdate(*_repo, *_html_type, document::DocumentId(document::DocIdString("test", "test")))); _bId = getExternalOperationHandler().getBucketId(update->getId()); diff --git a/storage/src/tests/persistence/filestorage/filestormanagertest.cpp b/storage/src/tests/persistence/filestorage/filestormanagertest.cpp index 838df87662f..369e820f987 100644 --- a/storage/src/tests/persistence/filestorage/filestormanagertest.cpp +++ b/storage/src/tests/persistence/filestorage/filestormanagertest.cpp @@ -2725,6 +2725,7 @@ void FileStorManagerTest::update_command_size_is_added_to_metric() { document::BucketId bucket(16, 4000); createBucket(bucket, 0); auto update = std::make_shared<document::DocumentUpdate>( + _node->getTestDocMan().getTypeRepo(), _node->getTestDocMan().createRandomDocument()->getType(), document::DocumentId("id:foo:testdoctype1::bar")); auto cmd = std::make_shared<api::UpdateCommand>( diff --git a/storage/src/tests/persistence/persistencetestutils.cpp b/storage/src/tests/persistence/persistencetestutils.cpp index f15921e447d..368eae104e8 100644 --- a/storage/src/tests/persistence/persistencetestutils.cpp +++ b/storage/src/tests/persistence/persistencetestutils.cpp @@ -223,16 +223,11 @@ PersistenceTestUtils::doGetOnDisk( } document::DocumentUpdate::SP -PersistenceTestUtils::createBodyUpdate( - const document::DocumentId& docId, - const document::FieldValue& updateValue) +PersistenceTestUtils::createBodyUpdate(const document::DocumentId& docId, const document::FieldValue& updateValue) { - const DocumentType* docType(_env->_component.getTypeRepo() - ->getDocumentType("testdoctype1")); - document::DocumentUpdate::SP update( - new document::DocumentUpdate(*docType, docId)); - std::shared_ptr<document::AssignValueUpdate> assignUpdate( - new document::AssignValueUpdate(updateValue)); + const DocumentType* docType(_env->_component.getTypeRepo()->getDocumentType("testdoctype1")); + document::DocumentUpdate::SP update(new document::DocumentUpdate(*_env->_component.getTypeRepo(), *docType, docId)); + std::shared_ptr<document::AssignValueUpdate> assignUpdate(new document::AssignValueUpdate(updateValue)); document::FieldUpdate fieldUpdate(docType->getField("content")); fieldUpdate.addUpdate(*assignUpdate); update->addUpdate(fieldUpdate); @@ -240,16 +235,11 @@ PersistenceTestUtils::createBodyUpdate( } document::DocumentUpdate::SP -PersistenceTestUtils::createHeaderUpdate( - const document::DocumentId& docId, - const document::FieldValue& updateValue) +PersistenceTestUtils::createHeaderUpdate(const document::DocumentId& docId, const document::FieldValue& updateValue) { - const DocumentType* docType(_env->_component.getTypeRepo() - ->getDocumentType("testdoctype1")); - document::DocumentUpdate::SP update( - new document::DocumentUpdate(*docType, docId)); - std::shared_ptr<document::AssignValueUpdate> assignUpdate( - new document::AssignValueUpdate(updateValue)); + const DocumentType* docType(_env->_component.getTypeRepo()->getDocumentType("testdoctype1")); + document::DocumentUpdate::SP update(new document::DocumentUpdate(*_env->_component.getTypeRepo(), *docType, docId)); + std::shared_ptr<document::AssignValueUpdate> assignUpdate(new document::AssignValueUpdate(updateValue)); document::FieldUpdate fieldUpdate(docType->getField("headerval")); fieldUpdate.addUpdate(*assignUpdate); update->addUpdate(fieldUpdate); diff --git a/storage/src/tests/persistence/testandsettest.cpp b/storage/src/tests/persistence/testandsettest.cpp index c729df1e7eb..686e10ba5ef 100644 --- a/storage/src/tests/persistence/testandsettest.cpp +++ b/storage/src/tests/persistence/testandsettest.cpp @@ -189,7 +189,7 @@ std::unique_ptr<api::UpdateCommand> TestAndSetTest::conditional_update_test( { putTestDocument(matchingHeader, timestampOne); - auto docUpdate = std::make_shared<document::DocumentUpdate>(testDoc->getType(), testDocId); + auto docUpdate = std::make_shared<document::DocumentUpdate>(_env->_testDocMan.getTypeRepo(), testDoc->getType(), testDocId); auto fieldUpdate = document::FieldUpdate(testDoc->getField("content")); fieldUpdate.addUpdate(document::AssignValueUpdate(NEW_CONTENT)); docUpdate->addUpdate(fieldUpdate); diff --git a/storage/src/tests/storageserver/changedbucketownershiphandlertest.cpp b/storage/src/tests/storageserver/changedbucketownershiphandlertest.cpp index 7df598bed97..98ad8761736 100644 --- a/storage/src/tests/storageserver/changedbucketownershiphandlertest.cpp +++ b/storage/src/tests/storageserver/changedbucketownershiphandlertest.cpp @@ -597,25 +597,19 @@ ChangedBucketOwnershipHandlerTest::testAbortOutdatedPutOperation() void ChangedBucketOwnershipHandlerTest::testAbortOutdatedUpdateCommand() { - const document::DocumentType* docType(_testDocRepo.getTypeRepo() - .getDocumentType("testdoctype1")); + const document::DocumentType* docType(_testDocRepo.getTypeRepo().getDocumentType("testdoctype1")); document::DocumentId docId("id:foo:testdoctype1::bar"); - document::DocumentUpdate::SP update( - std::make_shared<document::DocumentUpdate>(*docType, docId)); - CPPUNIT_ASSERT(changeAbortsMessage<api::UpdateCommand>( - getBucketToAbort(), update, api::Timestamp(1234))); - CPPUNIT_ASSERT(!changeAbortsMessage<api::UpdateCommand>( - getBucketToAllow(), update, api::Timestamp(1234))); + auto update(std::make_shared<document::DocumentUpdate>(_testDocRepo.getTypeRepo(), *docType, docId)); + CPPUNIT_ASSERT(changeAbortsMessage<api::UpdateCommand>(getBucketToAbort(), update, api::Timestamp(1234))); + CPPUNIT_ASSERT(!changeAbortsMessage<api::UpdateCommand>(getBucketToAllow(), update, api::Timestamp(1234))); } void ChangedBucketOwnershipHandlerTest::testAbortOutdatedRemoveCommand() { document::DocumentId docId("id:foo:testdoctype1::bar"); - CPPUNIT_ASSERT(changeAbortsMessage<api::RemoveCommand>( - getBucketToAbort(), docId, api::Timestamp(1234))); - CPPUNIT_ASSERT(!changeAbortsMessage<api::RemoveCommand>( - getBucketToAllow(), docId, api::Timestamp(1234))); + CPPUNIT_ASSERT(changeAbortsMessage<api::RemoveCommand>(getBucketToAbort(), docId, api::Timestamp(1234))); + CPPUNIT_ASSERT(!changeAbortsMessage<api::RemoveCommand>(getBucketToAllow(), docId, api::Timestamp(1234))); } void diff --git a/storage/src/tests/storageserver/documentapiconvertertest.cpp b/storage/src/tests/storageserver/documentapiconvertertest.cpp index 695ae17c5d4..40d561bd589 100644 --- a/storage/src/tests/storageserver/documentapiconvertertest.cpp +++ b/storage/src/tests/storageserver/documentapiconvertertest.cpp @@ -181,7 +181,7 @@ void DocumentApiConverterTest::testForwardedPut() void DocumentApiConverterTest::testUpdate() { - auto update = std::make_shared<document::DocumentUpdate>(_html_type, defaultDocId); + auto update = std::make_shared<document::DocumentUpdate>(*_repo, _html_type, defaultDocId); documentapi::UpdateDocumentMessage updateMsg(update); updateMsg.setOldTimestamp(1234); updateMsg.setNewTimestamp(5678); @@ -327,19 +327,19 @@ DocumentApiConverterTest::testBatchDocumentUpdate() { document::DocumentId docId(document::UserDocIdString("userdoc:test:1234:test1")); - auto update = std::make_shared<document::DocumentUpdate>(_html_type, docId); + auto update = std::make_shared<document::DocumentUpdate>(*_repo, _html_type, docId); updates.push_back(update); } { document::DocumentId docId(document::UserDocIdString("userdoc:test:1234:test2")); - auto update = std::make_shared<document::DocumentUpdate>(_html_type, docId); + auto update = std::make_shared<document::DocumentUpdate>(*_repo, _html_type, docId); updates.push_back(update); } { document::DocumentId docId(document::UserDocIdString("userdoc:test:1234:test3")); - auto update = std::make_shared<document::DocumentUpdate>(_html_type, docId); + auto update = std::make_shared<document::DocumentUpdate>(*_repo, _html_type, docId); updates.push_back(update); } diff --git a/storageapi/src/tests/mbusprot/storageprotocoltest.cpp b/storageapi/src/tests/mbusprot/storageprotocoltest.cpp index a809d80e0f5..cfc69bcde45 100644 --- a/storageapi/src/tests/mbusprot/storageprotocoltest.cpp +++ b/storageapi/src/tests/mbusprot/storageprotocoltest.cpp @@ -294,7 +294,7 @@ void StorageProtocolTest::testUpdate51() { ScopedName test("testUpdate51"); - document::DocumentUpdate::SP update(new document::DocumentUpdate(*_testDoc->getDataType(), _testDoc->getId())); + document::DocumentUpdate::SP update(new document::DocumentUpdate(_docMan.getTypeRepo(), *_testDoc->getDataType(), _testDoc->getId())); std::shared_ptr<document::AssignValueUpdate> assignUpdate(new document::AssignValueUpdate(document::IntFieldValue(17))); document::FieldUpdate fieldUpdate(_testDoc->getField("headerval")); fieldUpdate.addUpdate(*assignUpdate); @@ -912,7 +912,7 @@ StorageProtocolTest::testUpdateCommand52() { ScopedName test("testUpdateCommand52"); - document::DocumentUpdate::SP update(new document::DocumentUpdate(*_testDoc->getDataType(), _testDoc->getId())); + document::DocumentUpdate::SP update(new document::DocumentUpdate(_docMan.getTypeRepo(), *_testDoc->getDataType(), _testDoc->getId())); UpdateCommand::SP cmd(new UpdateCommand(_bucket, update, 14)); cmd->setCondition(TestAndSetCondition(CONDITION_STRING)); diff --git a/storageapi/src/vespa/storageapi/mbusprot/protocolserialization5_0.cpp b/storageapi/src/vespa/storageapi/mbusprot/protocolserialization5_0.cpp index 44050264484..47b77af74a5 100644 --- a/storageapi/src/vespa/storageapi/mbusprot/protocolserialization5_0.cpp +++ b/storageapi/src/vespa/storageapi/mbusprot/protocolserialization5_0.cpp @@ -228,9 +228,8 @@ ProtocolSerialization5_0::onDecodeUpdateCommand(BBuf& buf) const uint32_t size = SH::getInt(buf); if (size != 0) { - document::ByteBuffer bbuf(buf.getBufferAtPos(), size); + update = document::DocumentUpdate::createHEAD(getTypeRepo(), vespalib::nbostream(buf.getBufferAtPos(), size)); buf.incPos(size); - update = document::DocumentUpdate::createHEAD(getTypeRepo(), bbuf); } document::Bucket bucket = getBucket(buf); |