summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/AutoscalingMetrics.java6
-rw-r--r--document/src/tests/documentcalculatortestcase.cpp20
-rw-r--r--document/src/tests/documentselectparsertest.cpp6
-rw-r--r--document/src/tests/documenttestcase.cpp32
-rw-r--r--document/src/tests/documenttypetestcase.cpp2
-rw-r--r--document/src/tests/documentupdatetestcase.cpp6
-rw-r--r--document/src/tests/fieldpathupdatetestcase.cpp101
-rw-r--r--document/src/tests/fieldsettest.cpp10
-rw-r--r--document/src/tests/fieldvalue/document_test.cpp4
-rw-r--r--document/src/tests/select/select_test.cpp4
-rw-r--r--document/src/tests/serialization/vespadocumentserializer_test.cpp21
-rw-r--r--document/src/tests/testxml.cpp5
-rw-r--r--document/src/vespa/document/base/forcelink.cpp8
-rw-r--r--document/src/vespa/document/base/testdocman.cpp2
-rw-r--r--document/src/vespa/document/datatype/documenttype.cpp2
-rw-r--r--document/src/vespa/document/fieldset/fieldset.h3
-rw-r--r--document/src/vespa/document/fieldset/fieldsets.cpp4
-rw-r--r--document/src/vespa/document/fieldvalue/document.cpp20
-rw-r--r--document/src/vespa/document/fieldvalue/document.h6
-rw-r--r--document/src/vespa/document/fieldvalue/structfieldvalue.cpp10
-rw-r--r--document/src/vespa/document/fieldvalue/structfieldvalue.h1
-rw-r--r--documentapi/src/tests/messages/messages60test.cpp4
-rw-r--r--documentapi/src/tests/policies/policies_test.cpp21
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/MetricsResponse.java20
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/MetricsV2MetricsFetcherTest.java49
-rw-r--r--persistence/src/vespa/persistence/dummyimpl/dummypersistence.cpp4
-rw-r--r--searchcore/src/tests/proton/attribute/attribute_populator/attribute_populator_test.cpp2
-rw-r--r--searchcore/src/tests/proton/attribute/attribute_test.cpp2
-rw-r--r--searchcore/src/tests/proton/attribute/document_field_extractor/document_field_extractor_test.cpp2
-rw-r--r--searchcore/src/tests/proton/common/cachedselect_test.cpp4
-rw-r--r--searchcore/src/tests/proton/common/selectpruner_test.cpp3
-rw-r--r--searchcore/src/tests/proton/document_iterator/document_iterator_test.cpp168
-rw-r--r--searchcore/src/tests/proton/documentdb/maintenancecontroller/maintenancecontroller_test.cpp3
-rw-r--r--searchcore/src/tests/proton/feedoperation/feedoperation_test.cpp2
-rw-r--r--searchcore/src/tests/proton/persistenceengine/persistenceengine_test.cpp2
-rw-r--r--searchcore/src/tests/proton/server/documentretriever_test.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/bmcluster/bm_feed.cpp3
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/documentretriever.cpp3
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/documentretrieverbase.cpp3
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp4
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp3
-rw-r--r--searchlib/src/apps/tests/memoryindexstress_test.cpp3
-rw-r--r--searchlib/src/tests/attribute/attribute_test.cpp40
-rw-r--r--searchlib/src/tests/attribute/postinglist/postinglist.cpp14
-rw-r--r--searchlib/src/tests/docstore/document_store_visitor/document_store_visitor_test.cpp2
-rw-r--r--searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp2
-rw-r--r--searchlib/src/tests/memoryindex/memory_index/memory_index_test.cpp4
-rw-r--r--searchlib/src/tests/predicate/document_features_store_test.cpp14
-rw-r--r--searchlib/src/vespa/searchlib/attribute/postingstore.cpp3
-rw-r--r--searchlib/src/vespa/searchlib/test/doc_builder.cpp3
-rw-r--r--searchsummary/src/tests/docsummary/document_id_dfw/document_id_dfw_test.cpp3
-rw-r--r--searchsummary/src/tests/docsummary/matched_elements_filter/matched_elements_filter_test.cpp2
-rw-r--r--searchsummary/src/tests/docsummary/slime_summary/slime_summary_test.cpp2
-rw-r--r--storage/src/tests/bucketdb/bucketmanagertest.cpp2
-rw-r--r--storage/src/tests/distributor/bucketdatabasetest.cpp85
-rw-r--r--storage/src/tests/distributor/getoperationtest.cpp2
-rw-r--r--storage/src/tests/distributor/putoperationtest.cpp10
-rw-r--r--storage/src/tests/distributor/top_level_bucket_db_updater_test.cpp4
-rw-r--r--storage/src/tests/distributor/twophaseupdateoperationtest.cpp2
-rw-r--r--storage/src/tests/persistence/filestorage/filestormanagertest.cpp12
-rw-r--r--storage/src/tests/storageserver/documentapiconvertertest.cpp4
-rw-r--r--storage/src/tests/storageserver/rpc/storage_api_rpc_service_test.cpp2
-rw-r--r--storage/src/vespa/storage/bucketdb/btree_bucket_database.cpp13
-rw-r--r--storage/src/vespa/storage/bucketdb/btree_bucket_database.h3
-rw-r--r--storage/src/vespa/storage/bucketdb/bucketdatabase.h12
-rw-r--r--storage/src/vespa/storage/distributor/idealstatemanager.cpp2
-rw-r--r--storage/src/vespa/storage/distributor/operations/external/twophaseupdateoperation.cpp3
-rw-r--r--storage/src/vespa/storage/distributor/operations/external/visitoroperation.cpp22
-rw-r--r--streamingvisitors/src/tests/document/document.cpp2
-rw-r--r--streamingvisitors/src/tests/hitcollector/hitcollector_test.cpp4
-rw-r--r--streamingvisitors/src/tests/matching_elements_filler/matching_elements_filler_test.cpp2
-rw-r--r--vespalib/src/tests/btree/btree_test.cpp11
-rw-r--r--vespalib/src/tests/datastore/array_store/array_store_test.cpp12
-rw-r--r--vespalib/src/tests/datastore/datastore/datastore_test.cpp24
-rw-r--r--vespalib/src/tests/datastore/unique_store/unique_store_test.cpp14
-rw-r--r--vespalib/src/vespa/vespalib/datastore/array_store.h7
-rw-r--r--vespalib/src/vespa/vespalib/datastore/buffer_free_list.cpp18
-rw-r--r--vespalib/src/vespa/vespalib/datastore/buffer_free_list.h17
-rw-r--r--vespalib/src/vespa/vespalib/datastore/bufferstate.cpp2
-rw-r--r--vespalib/src/vespa/vespalib/datastore/bufferstate.h25
-rw-r--r--vespalib/src/vespa/vespalib/datastore/datastorebase.cpp171
-rw-r--r--vespalib/src/vespa/vespalib/datastore/datastorebase.h41
-rw-r--r--vespalib/src/vespa/vespalib/datastore/unique_store.hpp2
-rw-r--r--vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp11
84 files changed, 679 insertions, 531 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/AutoscalingMetrics.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/AutoscalingMetrics.java
index 29a54548256..8bb6be16e4a 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/AutoscalingMetrics.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/AutoscalingMetrics.java
@@ -11,7 +11,8 @@ import java.util.Set;
import java.util.stream.Collectors;
/**
- * Metrics used for autoscaling
+ * Metrics used for autoscaling.
+ * See com.yahoo.vespa.hosted.provision.autoscale.MetricsResponse
*
* @author bratseth
*/
@@ -23,9 +24,12 @@ public class AutoscalingMetrics {
List<String> metrics = new ArrayList<>();
metrics.add(HostedNodeAdminMetrics.CPU_UTIL.baseName());
+ metrics.add(HostedNodeAdminMetrics.GPU_UTIL.baseName());
// Memory util
metrics.add(HostedNodeAdminMetrics.MEM_UTIL.baseName()); // node level - default
+ metrics.add(HostedNodeAdminMetrics.GPU_MEM_USED.baseName());
+ metrics.add(HostedNodeAdminMetrics.GPU_MEM_TOTAL.baseName());
metrics.add(SearchNodeMetrics.CONTENT_PROTON_RESOURCE_USAGE_MEMORY.average()); // the basis for blocking
// Disk util
diff --git a/document/src/tests/documentcalculatortestcase.cpp b/document/src/tests/documentcalculatortestcase.cpp
index 7e27dcf2d36..dafc87f4ccd 100644
--- a/document/src/tests/documentcalculatortestcase.cpp
+++ b/document/src/tests/documentcalculatortestcase.cpp
@@ -24,7 +24,7 @@ TEST_F(DocumentCalculatorTest, testConstant) {
auto variables = std::make_unique<select::VariableMap>();
DocumentCalculator calc(getRepo(), "4.0");
- Document doc(*_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
+ Document doc(_testRepo.getTypeRepo(), *_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
EXPECT_EQ(4.0, calc.evaluate(doc, std::move(variables)));
}
@@ -32,7 +32,7 @@ TEST_F(DocumentCalculatorTest, testSimple) {
auto variables = std::make_unique<select::VariableMap>();
DocumentCalculator calc(getRepo(), "(3 + 5) / 2");
- Document doc(*_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
+ Document doc(_testRepo.getTypeRepo(), *_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
EXPECT_EQ(4.0, calc.evaluate(doc, std::move(variables)));
}
@@ -42,7 +42,7 @@ TEST_F(DocumentCalculatorTest, testVariables) {
(*variables)["y"] = 5.0;
DocumentCalculator calc(getRepo(), "($x + $y) / 2");
- Document doc(*_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
+ Document doc(_testRepo.getTypeRepo(), *_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
EXPECT_EQ(4.0, calc.evaluate(doc, std::move(variables)));
}
@@ -53,7 +53,7 @@ TEST_F(DocumentCalculatorTest, testFields) {
DocumentCalculator calc(getRepo(), "(testdoctype1.headerval + testdoctype1"
".hfloatval) / testdoctype1.headerlongval");
- Document doc(*_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
+ Document doc(_testRepo.getTypeRepo(), *_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
doc.setValue(doc.getField("headerval"), IntFieldValue(5));
doc.setValue(doc.getField("hfloatval"), FloatFieldValue(3.0));
doc.setValue(doc.getField("headerlongval"), LongFieldValue(2));
@@ -67,7 +67,7 @@ TEST_F(DocumentCalculatorTest, testFieldsDivZero) {
DocumentCalculator calc(getRepo(), "(testdoctype1.headerval + testdoctype1"
".hfloatval) / testdoctype1.headerlongval");
- Document doc(*_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
+ Document doc(_testRepo.getTypeRepo(), *_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
doc.setValue(doc.getField("headerval"), IntFieldValue(5));
doc.setValue(doc.getField("hfloatval"), FloatFieldValue(3.0));
doc.setValue(doc.getField("headerlongval"), LongFieldValue(0));
@@ -79,7 +79,7 @@ TEST_F(DocumentCalculatorTest, testDivideByZero) {
auto variables = std::make_unique<select::VariableMap>();
DocumentCalculator calc(getRepo(), "(3 + 5) / 0");
- Document doc(*_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
+ Document doc(_testRepo.getTypeRepo(), *_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
EXPECT_THROW(calc.evaluate(doc, std::move(variables)),
vespalib::IllegalArgumentException);
}
@@ -88,7 +88,7 @@ TEST_F(DocumentCalculatorTest, testModByZero) {
auto variables = std::make_unique<select::VariableMap>();
DocumentCalculator calc(getRepo(), "(3 + 5) % 0");
- Document doc(*_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
+ Document doc(_testRepo.getTypeRepo(), *_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
EXPECT_THROW(calc.evaluate(doc, std::move(variables)),
vespalib::IllegalArgumentException);
}
@@ -98,7 +98,7 @@ TEST_F(DocumentCalculatorTest, testFieldNotSet) {
DocumentCalculator calc(getRepo(), "(testdoctype1.headerval + testdoctype1"
".hfloatval) / testdoctype1.headerlongval");
- Document doc(*_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
+ Document doc(_testRepo.getTypeRepo(), *_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
doc.setValue(doc.getField("hfloatval"), FloatFieldValue(3.0));
doc.setValue(doc.getField("headerlongval"), LongFieldValue(2));
EXPECT_THROW(calc.evaluate(doc, std::move(variables)),
@@ -111,7 +111,7 @@ TEST_F(DocumentCalculatorTest, testFieldNotFound) {
"(testdoctype1.mynotfoundfield + testdoctype1"
".hfloatval) / testdoctype1.headerlongval");
- Document doc(*_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
+ Document doc(_testRepo.getTypeRepo(), *_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
doc.setValue(doc.getField("hfloatval"), FloatFieldValue(3.0));
doc.setValue(doc.getField("headerlongval"), LongFieldValue(2));
EXPECT_THROW(calc.evaluate(doc, std::move(variables)),
@@ -122,7 +122,7 @@ TEST_F(DocumentCalculatorTest, testByteSubtractionZeroResult) {
auto variables = std::make_unique<select::VariableMap>();
DocumentCalculator calc(getRepo(), "testdoctype1.byteval - 3");
- Document doc(*_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
+ Document doc(_testRepo.getTypeRepo(), *_testRepo.getDocumentType("testdoctype1"), DocumentId("id:ns:testdoctype1::foo"));
doc.setValue(doc.getField("byteval"), ByteFieldValue(3));
EXPECT_EQ(0.0, calc.evaluate(doc, std::move(variables)));
}
diff --git a/document/src/tests/documentselectparsertest.cpp b/document/src/tests/documentselectparsertest.cpp
index 5e14a080f27..13ad2873bfa 100644
--- a/document/src/tests/documentselectparsertest.cpp
+++ b/document/src/tests/documentselectparsertest.cpp
@@ -120,7 +120,7 @@ Document::SP DocumentSelectParserTest::createDoc(
uint64_t hlong)
{
const DocumentType* type = _repo->getDocumentType(doctype);
- auto doc = std::make_shared<Document>(*type, DocumentId(id));
+ auto doc = std::make_shared<Document>(*_repo, *type, DocumentId(id));
doc->setValue(doc->getField("headerval"), IntFieldValue(hint));
if (hlong != 0) {
@@ -1662,7 +1662,7 @@ TEST_F(DocumentSelectParserTest, test_parse_utilities_handle_malformed_input)
TEST_F(DocumentSelectParserTest, imported_field_references_are_treated_as_valid_field_with_missing_value) {
const DocumentType* type = _repo->getDocumentType("with_imported");
ASSERT_TRUE(type != nullptr);
- Document doc(*type, DocumentId("id::with_imported::foo"));
+ Document doc(*_repo, *type, DocumentId("id::with_imported::foo"));
PARSE("with_imported.my_imported_field == null", doc, True);
PARSE("with_imported.my_imported_field != null", doc, False);
@@ -1674,7 +1674,7 @@ TEST_F(DocumentSelectParserTest, imported_field_references_are_treated_as_valid_
TEST_F(DocumentSelectParserTest, imported_field_references_only_support_for_simple_expressions) {
const DocumentType* type = _repo->getDocumentType("with_imported");
ASSERT_TRUE(type != nullptr);
- Document doc(*type, DocumentId("id::with_imported::foo"));
+ Document doc(*_repo, *type, DocumentId("id::with_imported::foo"));
PARSE("with_imported.my_imported_field.foo", doc, Invalid);
PARSE("with_imported.my_imported_field[0]", doc, Invalid);
diff --git a/document/src/tests/documenttestcase.cpp b/document/src/tests/documenttestcase.cpp
index bc4065438e6..2e9e783470c 100644
--- a/document/src/tests/documenttestcase.cpp
+++ b/document/src/tests/documenttestcase.cpp
@@ -136,8 +136,8 @@ TEST(DocumentTest, testTraversing)
type.addField(primitive1);
type.addField(structl1s1);
- Document doc(type, DocumentId("id:ns:test::1"));
- doc.setValue(primitive1, IntFieldValue(1));
+ auto doc = Document::make_without_repo(type, DocumentId("id:ns:test::1"));
+ doc->setValue(primitive1, IntFieldValue(1));
StructFieldValue l1s1(struct3);
l1s1.setValue(primitive1, IntFieldValue(2));
@@ -159,11 +159,11 @@ TEST(DocumentTest, testTraversing)
l2s1.setValue(sarrF, sarr1);
l1s1.setValue(s2, l2s1);
- doc.setValue(structl1s1, l1s1);
+ doc->setValue(structl1s1, l1s1);
Handler fullTraverser;
FieldPath empty;
- doc.iterateNested(empty.getFullRange(), fullTraverser);
+ doc->iterateNested(empty.getFullRange(), fullTraverser);
EXPECT_EQ(fullTraverser.getResult(),
std::string("<0:P-0<0:P-0<0:P-0P-0[P-0P-1P-2][<0:P-0P-0><1:P-1P-1>]>>>"));
}
@@ -208,14 +208,14 @@ TEST(DocumentTest, testVariables)
iiiaV.add(iiaV);
}
- Document doc(type, DocumentId("id:ns:test::1"));
- doc.setValue(iiiarrF, iiiaV);
+ auto doc = Document::make_without_repo(type, DocumentId("id:ns:test::1"));
+ doc->setValue(iiiarrF, iiiaV);
{
VariableIteratorHandler handler;
FieldPath path;
type.buildFieldPath(path, "iiiarray[$x][$y][$z]");
- doc.iterateNested(path.getFullRange(), handler);
+ doc->iterateNested(path.getFullRange(), handler);
std::string fasit =
"x: 0,y: 0,z: 0, - 1\n"
@@ -315,7 +315,7 @@ TEST(DocumentTest, testModifyDocument)
type.addField(primitive1);
type.addField(structl1s1);
- Document::UP doc(new Document(type, DocumentId("id:ns:test::1")));
+ auto doc = Document::make_without_repo(type, DocumentId("id:ns:test::1"));
doc->setValue(primitive1, IntFieldValue(1));
StructFieldValue l1s1(struct3);
@@ -389,7 +389,7 @@ TEST(DocumentTest, testSimpleUsage)
type->addField(strF);
DocumentTypeRepo repo(*type);
- Document value(*repo.getDocumentType("test"), DocumentId("id:ns:test::1"));
+ Document value(repo, *repo.getDocumentType("test"), DocumentId("id:ns:test::1"));
// Initially empty
EXPECT_EQ(size_t(0), value.getSetFieldCount());
@@ -412,7 +412,7 @@ TEST(DocumentTest, testSimpleUsage)
// Serialize & equality
nbostream buffer;
value.serialize(buffer);
- Document value2(*repo.getDocumentType("test"),
+ Document value2(repo, *repo.getDocumentType("test"),
DocumentId("id::test:n=3:foo"));
EXPECT_TRUE(value != value2);
value2.deserialize(repo, buffer);
@@ -508,7 +508,7 @@ TEST(DocumentTest, testSimpleUsage)
// Refuse to accept non-document types
try{
StructDataType otherType("foo", 4);
- Document value6(otherType, DocumentId("id:ns:foo::1"));
+ auto doc = Document::make_without_repo(otherType, DocumentId("id:ns:foo::1"));
FAIL() << "Didn't complain about non-document type";
} catch (std::exception& e) {
EXPECT_THAT(e.what(), HasSubstr("Cannot generate a document with non-document type"));
@@ -706,7 +706,7 @@ TEST(DocumentTest,testReadSerializedAllVersions)
// Create a memory instance of document
{
- Document doc(*docType, DocumentId("id:ns:serializetest::http://test.doc.id/"));
+ Document doc(repo, *docType, DocumentId("id:ns:serializetest::http://test.doc.id/"));
doc.setValue("intfield", IntFieldValue::make(5));
doc.setValue("floatfield", FloatFieldValue::make(-9.23));
doc.setValue("stringfield", StringFieldValue::make("This is a string."));
@@ -714,7 +714,7 @@ TEST(DocumentTest,testReadSerializedAllVersions)
doc.setValue("doublefield", DoubleFieldValue::make(98374532.398820));
doc.setValue("bytefield", ByteFieldValue::make(-2));
doc.setValue("rawfield", std::make_unique<RawFieldValue>("RAW DATA", 8));
- Document docInDoc(*docInDocType, DocumentId("id:ns:docindoc::http://doc.in.doc/"));
+ Document docInDoc(repo, *docInDocType, DocumentId("id:ns:docindoc::http://doc.in.doc/"));
docInDoc.setValue("stringindocfield", StringFieldValue::make("Elvis is dead"));
doc.setValue("docfield", docInDoc);
ArrayFieldValue floatArray(*arrayOfFloatDataType);
@@ -828,7 +828,7 @@ TEST(DocumentTest, testGenerateSerializedFile)
{
const std::string file_name = TEST_PATH("data/crossplatform-java-cpp-doctypes.cfg");
DocumentTypeRepo repo(readDocumenttypesConfig(file_name));
- Document doc(*repo.getDocumentType("serializetest"), DocumentId("id:ns:serializetest::http://test.doc.id/"));
+ Document doc(repo, *repo.getDocumentType("serializetest"), DocumentId("id:ns:serializetest::http://test.doc.id/"));
doc.setValue("intfield", IntFieldValue::make(5));
doc.setValue("floatfield", FloatFieldValue::make(-9.23));
@@ -841,7 +841,7 @@ TEST(DocumentTest, testGenerateSerializedFile)
const DocumentType *docindoc_type = repo.getDocumentType("docindoc");
EXPECT_TRUE(docindoc_type);
- Document embedDoc(*docindoc_type, DocumentId("id:ns:docindoc::http://embedded"));
+ Document embedDoc(repo, *docindoc_type, DocumentId("id:ns:docindoc::http://embedded"));
doc.setValue("docfield", embedDoc);
@@ -949,7 +949,7 @@ TEST(DocumentTest, testUnknownEntries)
DocumentTypeRepo repo(type2);
- Document doc1(type1, DocumentId("id:ns:test::1"));
+ Document doc1(repo, type1, DocumentId("id:ns:test::1"));
doc1.setValue(field1, IntFieldValue(1));
doc1.setValue(field2, IntFieldValue(2));
doc1.setValue(field3, IntFieldValue(3));
diff --git a/document/src/tests/documenttypetestcase.cpp b/document/src/tests/documenttypetestcase.cpp
index 95ee3f4deed..df6d8aa900f 100644
--- a/document/src/tests/documenttypetestcase.cpp
+++ b/document/src/tests/documenttypetestcase.cpp
@@ -108,7 +108,7 @@ TEST(DocumentTypeTest, testMultipleInheritance)
EXPECT_TRUE(docType3->hasField("tmp"));
EXPECT_TRUE(docType3->hasField("tall"));
- Document doc(*docType3, DocumentId("id:ns:test3::1"));
+ Document doc(repo, *docType3, DocumentId("id:ns:test3::1"));
IntFieldValue intVal(3);
doc.setValue(doc.getField("nalle"), intVal);
diff --git a/document/src/tests/documentupdatetestcase.cpp b/document/src/tests/documentupdatetestcase.cpp
index 7a5d88d1013..3fbccaa155f 100644
--- a/document/src/tests/documentupdatetestcase.cpp
+++ b/document/src/tests/documentupdatetestcase.cpp
@@ -141,7 +141,7 @@ TEST(DocumentUpdateTest, testSimpleUsage)
auto docUpdateCopy(DocumentUpdate::createHEAD(repo, docBuf));
// Create a test document
- Document doc(*docType, DocumentId("id:ns:test::1"));
+ Document doc(repo, *docType, DocumentId("id:ns:test::1"));
doc.setValue("bytef", ByteFieldValue::make(0));
doc.setValue("intf", IntFieldValue::make(5));
ArrayFieldValue array(*arrayType);
@@ -417,7 +417,7 @@ WeightedSetAutoCreateFixture::~WeightedSetAutoCreateFixture() = default;
WeightedSetAutoCreateFixture::WeightedSetAutoCreateFixture()
: repo(makeConfig()),
docType(repo.getDocumentType("test")),
- doc(*docType, DocumentId("id:ns:test::1")),
+ doc(repo, *docType, DocumentId("id:ns:test::1")),
field(docType->getField("strwset")),
update(repo, *docType, DocumentId("id:ns:test::1"))
{
@@ -1355,7 +1355,7 @@ struct UpdateToEmptyDocumentFixture {
Document::UP make_empty_doc() {
vespalib::nbostream stream;
{
- Document doc(doc_type, DocumentId("id:test:test::0"));
+ Document doc(*repo, doc_type, DocumentId("id:test:test::0"));
VespaDocumentSerializer serializer(stream);
serializer.write(doc);
}
diff --git a/document/src/tests/fieldpathupdatetestcase.cpp b/document/src/tests/fieldpathupdatetestcase.cpp
index a32face5e55..e9f984c9586 100644
--- a/document/src/tests/fieldpathupdatetestcase.cpp
+++ b/document/src/tests/fieldpathupdatetestcase.cpp
@@ -133,8 +133,7 @@ FieldPathUpdateTestCase::TearDown()
TEST_F(FieldPathUpdateTestCase, testRemoveField)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::things:thangs"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::things:thangs"));
EXPECT_TRUE(doc->hasValue("strfoo") == false);
doc->setValue("strfoo", StringFieldValue("cocacola"));
EXPECT_EQ(vespalib::string("cocacola"), doc->getValue("strfoo")->getAsString());
@@ -146,8 +145,7 @@ TEST_F(FieldPathUpdateTestCase, testRemoveField)
TEST_F(FieldPathUpdateTestCase, testApplyRemoveMultiList)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::things:thangs"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::things:thangs"));
EXPECT_TRUE(doc->hasValue("strarray") == false);
{
ArrayFieldValue strArray(doc->getType().getField("strarray").getDataType());
@@ -171,8 +169,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyRemoveMultiList)
TEST_F(FieldPathUpdateTestCase, testApplyRemoveMultiList2)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::things:thangs"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::things:thangs"));
EXPECT_TRUE(doc->hasValue("strarray") == false);
{
ArrayFieldValue strArray(doc->getType().getField("strarray").getDataType());
@@ -195,8 +192,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyRemoveMultiList2)
TEST_F(FieldPathUpdateTestCase, testApplyRemoveEntireListField)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::things:thangs"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::things:thangs"));
EXPECT_TRUE(doc->hasValue("strarray") == false);
{
ArrayFieldValue strArray(doc->getType().getField("strarray").getDataType());
@@ -214,8 +210,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyRemoveEntireListField)
TEST_F(FieldPathUpdateTestCase, testApplyRemoveMultiWset)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::helan:halvan"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::helan:halvan"));
EXPECT_TRUE(doc->hasValue("strwset") == false);
{
WeightedSetFieldValue strWset(doc->getType().getField("strwset").getDataType());
@@ -237,8 +232,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyRemoveMultiWset)
TEST_F(FieldPathUpdateTestCase, testApplyAssignSingle)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::drekka:karsk"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::drekka:karsk"));
EXPECT_TRUE(doc->hasValue("strfoo") == false);
// Test assignment of non-existing
DocumentUpdate docUp(*_repo, *_foobar_type, DocumentId("id:ns:foobar::barbar:foofoo"));
@@ -255,8 +249,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyAssignSingle)
TEST_F(FieldPathUpdateTestCase, testApplyAssignMath)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::bat:man"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::bat:man"));
doc->setValue("num", IntFieldValue(34));
DocumentUpdate docUp(*_repo, *_foobar_type, DocumentId("id:ns:foobar::barbar:foofoo"));
@@ -267,8 +260,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyAssignMath)
TEST_F(FieldPathUpdateTestCase, testApplyAssignMathByteToZero)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::bat:man"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::bat:man"));
doc->setValue("byteval", ByteFieldValue(3));
DocumentUpdate docUp(*_repo, *_foobar_type, DocumentId("id:ns:foobar::barbar:foofoo"));
@@ -280,8 +272,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyAssignMathByteToZero)
TEST_F(FieldPathUpdateTestCase, testApplyAssignMathNotModifiedOnUnderflow)
{
int low_value = -126;
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::bat:man"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::bat:man"));
doc->setValue("byteval", ByteFieldValue(low_value));
DocumentUpdate docUp(*_repo, *_foobar_type, DocumentId("id:ns:foobar::barbar:foofoo"));
@@ -293,8 +284,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyAssignMathNotModifiedOnUnderflow)
TEST_F(FieldPathUpdateTestCase, testApplyAssignMathNotModifiedOnOverflow)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::bat:man"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::bat:man"));
doc->setValue("byteval", ByteFieldValue(127));
DocumentUpdate docUp(*_repo, *_foobar_type, DocumentId("id:ns:foobar::barbar:foofoo"));
@@ -306,8 +296,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyAssignMathNotModifiedOnOverflow)
TEST_F(FieldPathUpdateTestCase, testApplyAssignMathDivZero)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::bat:man"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::bat:man"));
EXPECT_TRUE(doc->hasValue("num") == false);
doc->setValue("num", IntFieldValue(10));
@@ -319,8 +308,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyAssignMathDivZero)
TEST_F(FieldPathUpdateTestCase, testApplyAssignFieldNotExistingInExpression)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::bat:man"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::bat:man"));
EXPECT_TRUE(doc->hasValue("num") == false);
doc->setValue("num", IntFieldValue(10));
@@ -332,8 +320,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyAssignFieldNotExistingInExpression)
TEST_F(FieldPathUpdateTestCase, testApplyAssignFieldNotExistingInPath)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::bat:man"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::bat:man"));
DocumentUpdate docUp(*_repo, *_foobar_type, DocumentId("id:ns:foobar::barbar:foofoo"));
try {
@@ -346,8 +333,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyAssignFieldNotExistingInPath)
TEST_F(FieldPathUpdateTestCase, testApplyAssignTargetNotExisting)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::bat:man"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::bat:man"));
EXPECT_TRUE(doc->hasValue("num") == false);
DocumentUpdate docUp(*_repo, *_foobar_type, DocumentId("id:ns:foobar::barbar:foofoo"));
@@ -358,8 +344,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyAssignTargetNotExisting)
TEST_F(FieldPathUpdateTestCase, testAssignSimpleMapValueWithVariable)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::bug:hunter"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::bug:hunter"));
MapFieldValue mfv(doc->getType().getField("strmap").getDataType());
mfv.put(StringFieldValue("foo"), StringFieldValue("bar"));
@@ -385,8 +370,7 @@ TEST_F(FieldPathUpdateTestCase, testAssignSimpleMapValueWithVariable)
TEST_F(FieldPathUpdateTestCase, testApplyAssignMathRemoveIfZero)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::bat:man"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::bat:man"));
EXPECT_TRUE(doc->hasValue("num") == false);
doc->setValue("num", IntFieldValue(34));
EXPECT_TRUE(doc->hasValue("num") == true);
@@ -402,8 +386,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyAssignMathRemoveIfZero)
TEST_F(FieldPathUpdateTestCase, testApplyAssignMultiList)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::fest:skinnvest"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::fest:skinnvest"));
EXPECT_TRUE(doc->hasValue("strarray") == false);
{
@@ -432,8 +415,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyAssignMultiList)
TEST_F(FieldPathUpdateTestCase, testApplyAssignMultiWset)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::fest:skinnvest"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::fest:skinnvest"));
EXPECT_TRUE(doc->hasValue("strarray") == false);
{
@@ -463,8 +445,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyAssignMultiWset)
TEST_F(FieldPathUpdateTestCase, testAssignWsetRemoveIfZero)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::tronder:bataljon"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::tronder:bataljon"));
EXPECT_TRUE(doc->hasValue("strarray") == false);
{
@@ -493,8 +474,7 @@ TEST_F(FieldPathUpdateTestCase, testAssignWsetRemoveIfZero)
TEST_F(FieldPathUpdateTestCase, testApplyAddMultiList)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::george:costanza"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::george:costanza"));
EXPECT_TRUE(doc->hasValue("strarray") == false);
auto adds = std::make_unique<ArrayFieldValue>(doc->getType().getField("strarray").getDataType());
@@ -512,8 +492,7 @@ TEST_F(FieldPathUpdateTestCase, testApplyAddMultiList)
TEST_F(FieldPathUpdateTestCase, testAddAndAssignList)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::fancy:pants"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::fancy:pants"));
EXPECT_TRUE(doc->hasValue("strarray") == false);
{
@@ -580,14 +559,12 @@ struct Fixture {
Fixture::~Fixture() = default;
Fixture::Fixture(const DocumentTypeRepo &repo, const DocumentType &doc_type, const Keys &k)
: _doc_type(&doc_type),
- doc(new Document(doc_type, DocumentId("id:ns:" + doc_type.getName() + "::planet:express"))),
+ doc(new Document(repo, doc_type, DocumentId("id:ns:" + doc_type.getName() + "::planet:express"))),
mfv(getMapType(doc_type)),
fv1(getMapType(doc_type).getValueType()),
fv2(getMapType(doc_type).getValueType()),
fv3(getMapType(doc_type).getValueType())
{
- doc->setRepo(repo);
-
fv1.setValue("title", StringFieldValue("fry"));
fv1.setValue("rating", IntFieldValue(30));
mfv.put(StringFieldValue(k.key1), fv1);
@@ -646,7 +623,6 @@ TEST_F(FieldPathUpdateTestCase, testAssignMapStructVariable)
DocumentUpdate docUp(*_repo, *_foobar_type, DocumentId("id:ns:foobar::barbar:foofoo"));
docUp.addFieldPathUpdate(std::make_unique<AssignFieldPathUpdate>(*f.doc->getDataType(), "structmap{$x}.rating",
"foobar.structmap{$x}.title == \"farnsworth\"", IntFieldValue::make(48)));
- f.doc->setRepo(*_repo);
docUp.applyTo(*f.doc);
std::unique_ptr<MapFieldValue> valueNow = f.doc->getAs<MapFieldValue>(f.doc->getField("structmap"));
@@ -665,8 +641,7 @@ createFry(const DataType & type) {
}
TEST_F(FieldPathUpdateTestCase, testAssignMapNoExist)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::planet:express"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::planet:express"));
MapFieldValue mfv(doc->getType().getField("structmap").getDataType());
DocumentUpdate docUp(*_repo, *_foobar_type, DocumentId("id:ns:foobar::barbar:foofoo"));
@@ -683,8 +658,7 @@ TEST_F(FieldPathUpdateTestCase, testAssignMapNoExist)
TEST_F(FieldPathUpdateTestCase, testAssignMapNoExistNoCreate)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::planet:express"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::planet:express"));
MapFieldValue mfv(doc->getType().getField("structmap").getDataType());
DocumentUpdate docUp(*_repo, *_foobar_type, DocumentId("id:ns:foobar::barbar:foofoo"));
@@ -730,8 +704,7 @@ createTastyCake(const DataType &type) {
}
TEST_F(FieldPathUpdateTestCase, testEqualityComparison)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::foo:zoo"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::foo:zoo"));
MapFieldValue mfv(doc->getType().getField("structmap").getDataType());
{
@@ -772,8 +745,7 @@ TEST_F(FieldPathUpdateTestCase, testEqualityComparison)
TEST_F(FieldPathUpdateTestCase, testAffectsDocumentBody)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::things:stuff"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::things:stuff"));
MapFieldValue mfv(doc->getType().getField("structmap").getDataType());
auto fv4 = std::make_unique<StructFieldValue>(dynamic_cast<const MapDataType&>(*mfv.getDataType()).getValueType());
@@ -801,8 +773,7 @@ TEST_F(FieldPathUpdateTestCase, testAffectsDocumentBody)
TEST_F(FieldPathUpdateTestCase, testIncompatibleDataTypeFails)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::things:stuff"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::things:stuff"));
MapFieldValue mfv(doc->getType().getField("structmap").getDataType());
DocumentUpdate docUp(*_repo, *_foobar_type, DocumentId("id:ns:foobar::barbar:foofoo"));
@@ -817,8 +788,7 @@ TEST_F(FieldPathUpdateTestCase, testIncompatibleDataTypeFails)
TEST_F(FieldPathUpdateTestCase, testSerializeAssign)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::weloveto:serializestuff"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::weloveto:serializestuff"));
MapFieldValue mfv(doc->getType().getField("structmap").getDataType());
auto val = std::make_unique<StructFieldValue>(dynamic_cast<const MapDataType&>(*mfv.getDataType()).getValueType());
@@ -836,8 +806,7 @@ TEST_F(FieldPathUpdateTestCase, testSerializeAssign)
TEST_F(FieldPathUpdateTestCase, testSerializeAdd)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::george:costanza"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::george:costanza"));
EXPECT_TRUE(doc->hasValue("strarray") == false);
auto adds = std::make_unique<ArrayFieldValue>(doc->getType().getField("strarray").getDataType());
@@ -854,8 +823,7 @@ TEST_F(FieldPathUpdateTestCase, testSerializeAdd)
TEST_F(FieldPathUpdateTestCase, testSerializeRemove)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::weloveto:serializestuff"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::weloveto:serializestuff"));
MapFieldValue mfv(doc->getType().getField("structmap").getDataType());
DocumentUpdate docUp(*_repo, *_foobar_type, DocumentId("id:ns:foobar::barbar:foofoo"));
@@ -867,8 +835,7 @@ TEST_F(FieldPathUpdateTestCase, testSerializeRemove)
TEST_F(FieldPathUpdateTestCase, testSerializeAssignMath)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id:ns:foobar::bat:man"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id:ns:foobar::bat:man"));
EXPECT_TRUE(doc->hasValue("num") == false);
doc->setValue("num", IntFieldValue(34));
@@ -940,8 +907,7 @@ TEST_F(FieldPathUpdateTestCase, testGenerateSerializedFile)
TEST_F(FieldPathUpdateTestCase, array_element_update_for_invalid_index_is_ignored)
{
- auto doc = std::make_unique<Document>(*_foobar_type, DocumentId("id::foobar::1"));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, DocumentId("id::foobar::1"));
auto& field = doc->getType().getField("strarray");
ArrayFieldValue str_array(field.getDataType());
@@ -959,8 +925,7 @@ TEST_F(FieldPathUpdateTestCase, array_element_update_for_invalid_index_is_ignore
TEST_F(FieldPathUpdateTestCase, update_can_have_removes_for_both_existent_and_nonexistent_keys) {
DocumentId doc_id("id:ns:foobar::george:costanza");
- auto doc = std::make_unique<Document>(*_foobar_type, doc_id);
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_foobar_type, doc_id);
auto& map_type = dynamic_cast<const MapDataType&>(doc->getType().getField("structmap").getDataType());
auto& struct_type = map_type.getValueType();
MapFieldValue mfv(map_type);
diff --git a/document/src/tests/fieldsettest.cpp b/document/src/tests/fieldsettest.cpp
index 4ce8e53ae3c..1664ad8e0ff 100644
--- a/document/src/tests/fieldsettest.cpp
+++ b/document/src/tests/fieldsettest.cpp
@@ -144,7 +144,7 @@ FieldSetTest::doCopyFields(const Document& src,
const std::string& fieldSetStr,
Document* dest)
{
- Document destDoc(src.getType(), DocumentId("id:ns:" + src.getType().getName() + "::fieldset"));
+ Document destDoc(docRepo, src.getType(), DocumentId("id:ns:" + src.getType().getName() + "::fieldset"));
if (!dest) {
dest = &destDoc;
}
@@ -196,7 +196,7 @@ TEST_F(FieldSetTest, testCopyDocumentFields)
doCopyFields(*src, repo, "testdoctype1:hstringval,content"));
// Test that we overwrite already set fields in destination document
{
- Document dest(src->getType(), DocumentId("id:ns:" + src->getType().getName() + "::bar"));
+ Document dest(repo, src->getType(), DocumentId("id:ns:" + src->getType().getName() + "::bar"));
dest.setValue(dest.getField("content"), StringFieldValue("overwriteme"));
EXPECT_EQ(std::string("content: megafoo megabar\n"),
doCopyFields(*src, repo, src->getType().getName() + ":content", &dest));
@@ -209,7 +209,7 @@ FieldSetTest::doCopyDocument(const Document& src,
const std::string& fieldSetStr)
{
auto fset = FieldSetRepo::parse(docRepo, fieldSetStr);
- Document::UP doc(FieldSet::createDocumentSubsetCopy(src, *fset));
+ Document::UP doc(FieldSet::createDocumentSubsetCopy(docRepo, src, *fset));
return stringifyFields(*doc);
}
@@ -221,7 +221,7 @@ TEST_F(FieldSetTest, testDocumentSubsetCopy)
Document::UP src(createTestDocument(testDocMan));
{
- Document::UP doc(FieldSet::createDocumentSubsetCopy(*src, AllFields()));
+ Document::UP doc(FieldSet::createDocumentSubsetCopy(repo, *src, AllFields()));
// Test that document id and type are copied correctly.
EXPECT_TRUE(doc.get());
EXPECT_EQ(src->getId(), doc->getId());
@@ -230,7 +230,7 @@ TEST_F(FieldSetTest, testDocumentSubsetCopy)
stringifyFields(*doc));
}
{
- Document::UP doc(FieldSet::createDocumentSubsetCopy(*src, DocumentOnly()));
+ Document::UP doc(FieldSet::createDocumentSubsetCopy(repo, *src, DocumentOnly()));
// Test that document id and type are copied correctly.
EXPECT_TRUE(doc.get());
EXPECT_EQ(src->getId(), doc->getId());
diff --git a/document/src/tests/fieldvalue/document_test.cpp b/document/src/tests/fieldvalue/document_test.cpp
index fd277bc2eb4..3efaabb1c2e 100644
--- a/document/src/tests/fieldvalue/document_test.cpp
+++ b/document/src/tests/fieldvalue/document_test.cpp
@@ -16,9 +16,9 @@ TEST("require that document with id schema 'id' checks type") {
const DataType *type = repo.getDocumentType("testdoctype1");
ASSERT_TRUE(type);
- Document(*type, DocumentId("id:ns:testdoctype1::")); // Should not throw
+ Document(repo.getTypeRepo(), *type, DocumentId("id:ns:testdoctype1::")); // Should not throw
- EXPECT_EXCEPTION(Document(*type, DocumentId("id:ns:type::")),
+ EXPECT_EXCEPTION(Document(repo.getTypeRepo(), *type, DocumentId("id:ns:type::")),
vespalib::IllegalArgumentException,
"testdoctype1 that don't match the id (type type)");
}
diff --git a/document/src/tests/select/select_test.cpp b/document/src/tests/select/select_test.cpp
index 03bd17d47b5..30128fbea0a 100644
--- a/document/src/tests/select/select_test.cpp
+++ b/document/src/tests/select/select_test.cpp
@@ -85,7 +85,7 @@ DocumentSelectTest::check_select(const Document& doc, const vespalib::string& ex
TEST_F(DocumentSelectTest, check_existing_reference_field)
{
- auto document = std::make_unique<Document>(*_child_document_type, DocumentId("id::child::0"));
+ auto document = std::make_unique<Document>(*_repo, *_child_document_type, DocumentId("id::child::0"));
document->setFieldValue(_child_ref_field, std::make_unique<ReferenceFieldValue>(_child_ref_field_type, DocumentId("id::parent::1")));
EXPECT_TRUE(document->hasValue(_child_ref_field));
check_select(*document, "child.ref == null", Result::False);
@@ -102,7 +102,7 @@ TEST_F(DocumentSelectTest, check_existing_reference_field)
TEST_F(DocumentSelectTest, check_missing_reference_field)
{
- auto document = std::make_unique<Document>(*_child_document_type, DocumentId("id::child::0"));
+ auto document = std::make_unique<Document>(*_repo, *_child_document_type, DocumentId("id::child::0"));
EXPECT_FALSE(document->hasValue(_child_ref_field));
check_select(*document, "child.ref == null", Result::True);
check_select(*document, "child.ref != null", Result::False);
diff --git a/document/src/tests/serialization/vespadocumentserializer_test.cpp b/document/src/tests/serialization/vespadocumentserializer_test.cpp
index 7528878bfb5..e91e38e0fe4 100644
--- a/document/src/tests/serialization/vespadocumentserializer_test.cpp
+++ b/document/src/tests/serialization/vespadocumentserializer_test.cpp
@@ -515,7 +515,7 @@ TEST("requireThatDocumentCanBeSerialized") {
const DocumentType &type = repo.getDocumentType();
DocumentId doc_id("id:ns:" + type.getName() + "::");
- Document value(type, doc_id);
+ Document value(repo.getDocumentTypeRepo(), type, doc_id);
value.setValue(type.getField("header field"), IntFieldValue(42));
value.setValue(type.getField("body field"), StringFieldValue("foobar"));
@@ -580,7 +580,7 @@ TEST("requireThatUnmodifiedDocumentRetainsUnknownFieldOnSerialization") {
DocumentTypeRepo repo2Fields(builder2.config());
DocumentId doc_id("id:ns:my_doctype::");
- Document value(*repo2Fields.getDocumentType(doc_type_id), doc_id);
+ Document value(repo2Fields, *repo2Fields.getDocumentType(doc_type_id), doc_id);
value.setValue("field1", IntFieldValue(42));
value.setValue("field2", StringFieldValue("megafoo"));
@@ -632,12 +632,12 @@ TEST("requireThatDocumentWithDocumentCanBeSerialized") {
setSpanTree(str, *tree);
const Field str_field("str", *DataType::STRING);
- Document inner(*inner_type, DocumentId("id:ns:" + inner_type->getName() + "::"));
+ Document inner(my_repo, *inner_type, DocumentId("id:ns:" + inner_type->getName() + "::"));
inner.setValue(str_field, str);
const DocumentType *type = my_repo.getDocumentType(outer_type_id);
ASSERT_TRUE(type);
DocumentId doc_id("id:ns:" + type->getName() + "::");
- Document value(*type, doc_id);
+ Document value(my_repo, *type, doc_id);
const Field doc_field(inner_name, *inner_type);
value.setValue(doc_field, inner);
@@ -659,9 +659,10 @@ TEST("requireThatReadDocumentTypeThrowsIfUnknownType") {
template <typename FieldValueT>
void serializeToFile(FieldValueT &value, const string &file_name,
+ const DocumentTypeRepo& my_repo,
const DocumentType *type, const string &field_name) {
DocumentId doc_id("id:test:" + type->getName() + "::foo");
- Document doc(*type, doc_id);
+ Document doc(my_repo, *type, doc_id);
doc.setValue(type->getField(field_name), value);
nbostream stream;
@@ -675,7 +676,7 @@ void serializeToFile(FieldValueT &value, const string &file_name,
void serializeToFile(PredicateFieldValue &value, const string &file_name) {
const DocumentType *type = doc_repo.getDocumentType(predicate_doc_type_id);
- serializeToFile(value, file_name, type, predicate_field_name);
+ serializeToFile(value, file_name, doc_repo, type, predicate_field_name);
}
template <typename FieldValueT>
@@ -819,7 +820,7 @@ const DocumentTypeRepo tensor_doc_repo1(getTensorDocTypesConfig("tensor(dimX{})"
void serializeToFile(TensorFieldValue &value, const string &file_name) {
const DocumentType *type =
tensor_doc_repo.getDocumentType(tensor_doc_type_id);
- serializeToFile(value, file_name, type, tensor_field_name);
+ serializeToFile(value, file_name, tensor_doc_repo, type, tensor_field_name);
}
void deserializeAndCheck(const string &file_name, TensorFieldValue &value) {
@@ -870,7 +871,7 @@ TensorDocFixture::TensorDocFixture(const DocumentTypeRepo &docTypeRepo,
: _docTypeRepo(docTypeRepo),
_docType(_docTypeRepo.getDocumentType(tensor_doc_type_id)),
_tensor(std::move(tensor)),
- _doc(*_docType, DocumentId("id:test:my_type::foo")),
+ _doc(_docTypeRepo, *_docType, DocumentId("id:test:my_type::foo")),
_blob()
{
auto fv = _doc.getField(tensor_field_name).createValue();
@@ -963,7 +964,7 @@ struct RefFixture {
const string data_dir = TEST_PATH("../../test/resources/reference/");
const string field_name = "ref_field";
serializeToFile(value, data_dir + file_base_name + "__cpp.new",
- ref_doc_type, field_name);
+ fixed_repo.getDocumentTypeRepo(), ref_doc_type, field_name);
vespalib::rename(data_dir + file_base_name + "__cpp.new",
data_dir + file_base_name + "__cpp");
@@ -999,7 +1000,7 @@ TEST_F("ReferenceFieldValue with ID serialization matches Java", RefFixture) {
struct AssociatedDocumentRepoFixture {
const DocumentType& doc_type{repo.getDocumentType()};
DocumentId doc_id{"id:ns:" + doc_type.getName() + "::"};
- Document source_doc{doc_type, doc_id};
+ Document source_doc{doc_repo, doc_type, doc_id};
std::unique_ptr<Document> roundtrip_serialize_source_document() {
nbostream stream;
diff --git a/document/src/tests/testxml.cpp b/document/src/tests/testxml.cpp
index 5f194661fe5..13024ddb005 100644
--- a/document/src/tests/testxml.cpp
+++ b/document/src/tests/testxml.cpp
@@ -22,8 +22,7 @@ namespace {
Document::UP createTestDocument(const DocumentTypeRepo& repo)
{
const DocumentType* type(repo.getDocumentType("testdoc"));
- auto doc = std::make_unique<Document>(*type,DocumentId("id:ns:testdoc::crawler/http://www.ntnu.no/"));
- doc->setRepo(repo);
+ auto doc = std::make_unique<Document>(repo, *type, DocumentId("id:ns:testdoc::crawler/http://www.ntnu.no/"));
std::string s("humlepungens buffer");
ByteBuffer bb(s.c_str(), s.size());
@@ -45,7 +44,7 @@ Document::UP createTestDocument(const DocumentTypeRepo& repo)
val.add(rawVal3);
doc->setValue(doc->getField("rawarrayattr"), val);
- auto doc2 = std::make_unique<Document>(*type, DocumentId("id:ns:testdoc::crawler/http://www.ntnu.no/2"));
+ auto doc2 = std::make_unique<Document>(repo, *type, DocumentId("id:ns:testdoc::crawler/http://www.ntnu.no/2"));
doc2->setValue(doc2->getField("stringattr"), StringFieldValue("tjo hei paa du"));
doc->setValue(doc->getField("docfield"), *doc2);
diff --git a/document/src/vespa/document/base/forcelink.cpp b/document/src/vespa/document/base/forcelink.cpp
index cfa3354f5f2..975fca5aa2c 100644
--- a/document/src/vespa/document/base/forcelink.cpp
+++ b/document/src/vespa/document/base/forcelink.cpp
@@ -1,9 +1,10 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "forcelink.h"
-#include <vespa/document/update/updates.h>
-#include <vespa/document/fieldvalue/fieldvalues.h>
#include <vespa/document/datatype/documenttype.h>
+#include <vespa/document/fieldvalue/fieldvalues.h>
+#include <vespa/document/repo/documenttyperepo.h>
+#include <vespa/document/update/updates.h>
namespace document {
@@ -12,7 +13,8 @@ ForceLink::ForceLink(void)
{
if (time(NULL) == 0) {
DocumentType type("foo", 1);
- Document document(type, DocumentId("doc:ns:bar"));
+ DocumentTypeRepo repo(type);
+ Document document(repo, *repo.getDocumentType("foo"), DocumentId("doc:ns:bar"));
DocumentUpdate documentUpdate;
MapValueUpdate mapValueUpdate(std::make_unique<IntFieldValue>(3), std::make_unique<ClearValueUpdate>());
AddValueUpdate addValueUpdate(std::make_unique<IntFieldValue>(3));
diff --git a/document/src/vespa/document/base/testdocman.cpp b/document/src/vespa/document/base/testdocman.cpp
index 59e4d4d8386..471a2f8c196 100644
--- a/document/src/vespa/document/base/testdocman.cpp
+++ b/document/src/vespa/document/base/testdocman.cpp
@@ -79,7 +79,7 @@ TestDocMan::createDocument(
{
const DocumentType *type_ptr = _repo->getDocumentType(type);
assert(type_ptr);
- Document::UP doc(new Document(*type_ptr, DocumentId(id)));
+ Document::UP doc(new Document(*_repo, *type_ptr, DocumentId(id)));
doc->setValue(doc->getField("content"), StringFieldValue(content.c_str()));
return doc;
}
diff --git a/document/src/vespa/document/datatype/documenttype.cpp b/document/src/vespa/document/datatype/documenttype.cpp
index 0d38ce1f623..80181a7ad35 100644
--- a/document/src/vespa/document/datatype/documenttype.cpp
+++ b/document/src/vespa/document/datatype/documenttype.cpp
@@ -175,7 +175,7 @@ DocumentType::isA(const DataType& other) const
FieldValue::UP
DocumentType::createFieldValue() const
{
- return std::make_unique<Document>(*this, DocumentId("id::" + getName() + "::"));
+ return Document::make_without_repo(*this, DocumentId("id::" + getName() + "::"));
}
void
diff --git a/document/src/vespa/document/fieldset/fieldset.h b/document/src/vespa/document/fieldset/fieldset.h
index 1f53f7a3456..5b67701e395 100644
--- a/document/src/vespa/document/fieldset/fieldset.h
+++ b/document/src/vespa/document/fieldset/fieldset.h
@@ -6,6 +6,7 @@
namespace document {
class Document;
+class DocumentTypeRepo;
/**
* FieldSet class. Represents a subset of fields in a document type.
@@ -57,7 +58,7 @@ public:
* See comment for copyFields() for performance notes.
* @return The new, (partially) copied document instance.
*/
- static std::unique_ptr<Document> createDocumentSubsetCopy(const Document& src, const FieldSet& fields);
+ static std::unique_ptr<Document> createDocumentSubsetCopy(const DocumentTypeRepo& type_repo, const Document& src, const FieldSet& fields);
/**
* Strip all fields _except_ the ones that are contained within the
diff --git a/document/src/vespa/document/fieldset/fieldsets.cpp b/document/src/vespa/document/fieldset/fieldsets.cpp
index 0ed9ace7467..0ab959d6815 100644
--- a/document/src/vespa/document/fieldset/fieldsets.cpp
+++ b/document/src/vespa/document/fieldset/fieldsets.cpp
@@ -80,9 +80,9 @@ FieldSet::copyFields(Document& dest, const Document& src, const FieldSet& fields
}
Document::UP
-FieldSet::createDocumentSubsetCopy(const Document& src, const FieldSet& fields)
+FieldSet::createDocumentSubsetCopy(const DocumentTypeRepo& type_repo, const Document& src, const FieldSet& fields)
{
- auto ret = std::make_unique<Document>(src.getType(), src.getId());
+ auto ret = std::make_unique<Document>(type_repo, src.getType(), src.getId());
copyFields(*ret, src, fields);
return ret;
}
diff --git a/document/src/vespa/document/fieldvalue/document.cpp b/document/src/vespa/document/fieldvalue/document.cpp
index 33b1bbe8d2c..2fb1611f6ff 100644
--- a/document/src/vespa/document/fieldvalue/document.cpp
+++ b/document/src/vespa/document/fieldvalue/document.cpp
@@ -95,6 +95,26 @@ Document::Document(const DataType &type, DocumentId documentId)
}
}
+Document::UP
+Document::make_without_repo(const DataType& type, DocumentId id)
+{
+ // Must use new as the constructor is private.
+ return Document::UP(new Document(type, id));
+}
+
+Document::Document(const DocumentTypeRepo& repo, const DataType &type, DocumentId documentId)
+ : StructuredFieldValue(Type::DOCUMENT, verifyDocumentType(&type)),
+ _id(std::move(documentId)),
+ _fields(repo, getType().getFieldsType()),
+ _backingBuffer(),
+ _lastModified(0)
+{
+ _fields.setDocumentType(getType());
+ if (_id.hasDocType() && (_id.getDocType() != type.getName())) {
+ throwTypeMismatch(type.getName(), _id.getDocType());
+ }
+}
+
void Document::setRepo(const DocumentTypeRepo& repo)
{
_fields.setRepo(repo);
diff --git a/document/src/vespa/document/fieldvalue/document.h b/document/src/vespa/document/fieldvalue/document.h
index c871e324f05..ac3963a4cc0 100644
--- a/document/src/vespa/document/fieldvalue/document.h
+++ b/document/src/vespa/document/fieldvalue/document.h
@@ -50,7 +50,13 @@ public:
Document(Document &&) noexcept;
Document & operator =(const Document &);
Document & operator =(Document &&) noexcept;
+private:
Document(const DataType &, DocumentId id);
+public:
+ // Should preferably only be used by unit tests.
+ // TODO: Remove all usage of this outside of unit tests.
+ static Document::UP make_without_repo(const DataType& type, DocumentId id);
+ Document(const DocumentTypeRepo& repo, const DataType&, DocumentId id);
Document(const DocumentTypeRepo& repo, vespalib::nbostream& stream);
Document(const DocumentTypeRepo& repo, vespalib::DataBuffer && buffer);
~Document() noexcept override;
diff --git a/document/src/vespa/document/fieldvalue/structfieldvalue.cpp b/document/src/vespa/document/fieldvalue/structfieldvalue.cpp
index 444e763c52b..083012a213c 100644
--- a/document/src/vespa/document/fieldvalue/structfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/structfieldvalue.cpp
@@ -36,6 +36,16 @@ StructFieldValue::StructFieldValue(const DataType &type)
{
}
+StructFieldValue::StructFieldValue(const DocumentTypeRepo& repo, const DataType& type)
+ : StructuredFieldValue(Type::STRUCT, type),
+ _fields(),
+ _repo(&repo),
+ _doc_type(nullptr),
+ _version(Document::getNewestSerializationVersion()),
+ _hasChanged(true)
+{
+}
+
StructFieldValue::StructFieldValue(const StructFieldValue & rhs) = default;
StructFieldValue & StructFieldValue::operator = (const StructFieldValue & rhs) = default;
diff --git a/document/src/vespa/document/fieldvalue/structfieldvalue.h b/document/src/vespa/document/fieldvalue/structfieldvalue.h
index 360aa6dca63..e888847fdfe 100644
--- a/document/src/vespa/document/fieldvalue/structfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/structfieldvalue.h
@@ -36,6 +36,7 @@ public:
using UP = std::unique_ptr<StructFieldValue>;
explicit StructFieldValue(const DataType &type);
+ explicit StructFieldValue(const DocumentTypeRepo& repo, const DataType& type);
StructFieldValue(const StructFieldValue & rhs);
StructFieldValue & operator = (const StructFieldValue & rhs);
StructFieldValue(StructFieldValue && rhs) noexcept = default;
diff --git a/documentapi/src/tests/messages/messages60test.cpp b/documentapi/src/tests/messages/messages60test.cpp
index ab300794307..258e8821e0c 100644
--- a/documentapi/src/tests/messages/messages60test.cpp
+++ b/documentapi/src/tests/messages/messages60test.cpp
@@ -79,9 +79,9 @@ namespace {
document::Document::SP
createDoc(const DocumentTypeRepo &repo, const string &type_name, const string &id)
{
- return document::Document::SP(new document::Document(
+ return std::make_shared<document::Document>(repo,
*repo.getDocumentType(type_name),
- document::DocumentId(id)));
+ document::DocumentId(id));
}
} // namespace
diff --git a/documentapi/src/tests/policies/policies_test.cpp b/documentapi/src/tests/policies/policies_test.cpp
index 33823681765..ada3e9154f2 100644
--- a/documentapi/src/tests/policies/policies_test.cpp
+++ b/documentapi/src/tests/policies/policies_test.cpp
@@ -58,6 +58,9 @@ private:
static void assertMirrorReady(const IMirrorAPI &mirror);
static void assertMirrorContains(const IMirrorAPI &mirror, const string &pattern, uint32_t numEntries);
mbus::Message::UP newPutDocumentMessage(const string &documentId);
+ std::shared_ptr<Document> make_doc(DocumentId docid) {
+ return std::make_shared<Document>(*_repo, *_docType, docid);
+ }
public:
Test();
@@ -169,7 +172,7 @@ void
Test::testAND()
{
TestFrame frame(_repo);
- frame.setMessage(make_unique<PutDocumentMessage>(make_shared<Document>(*_docType, DocumentId("id:ns:testdoc::"))));
+ frame.setMessage(make_unique<PutDocumentMessage>(make_doc(DocumentId("id:ns:testdoc::"))));
frame.setHop(mbus::HopSpec("test", "[AND]")
.addRecipient("foo")
.addRecipient("bar"));
@@ -255,7 +258,7 @@ Test::requireThatExternPolicyMergesOneReplyAsProtocol()
mbus::Message::UP
Test::newPutDocumentMessage(const string &documentId)
{
- return make_unique<PutDocumentMessage>(std::make_shared<Document>(*_docType, DocumentId(documentId)));
+ return make_unique<PutDocumentMessage>(make_doc(DocumentId(documentId)));
}
void
@@ -389,7 +392,7 @@ Test::testLocalService()
{
// Prepare message.
TestFrame frame(_repo, "docproc/cluster.default");
- frame.setMessage(make_unique<PutDocumentMessage>(make_shared<Document>(*_docType, DocumentId("id:ns:testdoc::"))));
+ frame.setMessage(make_unique<PutDocumentMessage>(make_doc(DocumentId("id:ns:testdoc::"))));
// Test select with proper address.
for (uint32_t i = 0; i < 10; ++i) {
@@ -470,7 +473,7 @@ Test::testRoundRobin()
{
// Prepare message.
TestFrame frame(_repo, "docproc/cluster.default");
- frame.setMessage(make_unique<PutDocumentMessage>(make_shared<Document>(*_docType, DocumentId("id:ns:testdoc::"))));
+ frame.setMessage(make_unique<PutDocumentMessage>(make_doc(DocumentId("id:ns:testdoc::"))));
// Test select with proper address.
for (uint32_t i = 0; i < 10; ++i) {
@@ -562,7 +565,7 @@ Test::multipleGetRepliesAreMergedToFoundDocument()
for (uint32_t i = 0, len = selected.size(); i < len; ++i) {
Document::SP doc;
if (i == 0) {
- doc = std::make_shared<Document>(*_docType, DocumentId("id:ns:testdoc::yarn"));
+ doc = make_doc(DocumentId("id:ns:testdoc::yarn"));
doc->setLastModified(123456ULL);
}
auto reply = std::make_unique<GetDocumentReply>(std::move(doc));
@@ -611,7 +614,7 @@ Test::testDocumentRouteSelector()
frame.setMessage(make_unique<GetDocumentMessage>(DocumentId("id:ns:testdoc::")));
EXPECT_TRUE(frame.testSelect(StringList().add("foo")));
- mbus::Message::UP put = make_unique<PutDocumentMessage>(make_shared<Document>(*_docType, DocumentId("id:ns:testdoc::")));
+ mbus::Message::UP put = make_unique<PutDocumentMessage>(make_doc(DocumentId("id:ns:testdoc::")));
frame.setMessage(std::move(put));
EXPECT_TRUE(frame.testSelect( StringList().add("foo")));
@@ -622,7 +625,7 @@ Test::testDocumentRouteSelector()
make_shared<DocumentUpdate>(*_repo, *_docType, DocumentId("id:ns:testdoc::"))));
EXPECT_TRUE(frame.testSelect(StringList().add("foo")));
- put = make_unique<PutDocumentMessage>(make_shared<Document>(*_docType, DocumentId("id:ns:testdoc::")));
+ put = make_unique<PutDocumentMessage>(make_doc(DocumentId("id:ns:testdoc::")));
frame.setMessage(std::move(put));
EXPECT_TRUE(frame.testMergeOneReply("foo"));
}
@@ -639,7 +642,7 @@ Test::testDocumentRouteSelectorIgnore()
.addRecipient("docproc/cluster.foo"));
frame.setMessage(make_unique<PutDocumentMessage>(
- make_shared<Document>(*_docType, DocumentId("id:yarn:testdoc:n=1234:fluff"))));
+ make_doc(DocumentId("id:yarn:testdoc:n=1234:fluff"))));
std::vector<mbus::RoutingNode*> leaf;
ASSERT_TRUE(frame.select(leaf, 0));
mbus::Reply::UP reply = frame.getReceptor().getReply(TIMEOUT);
@@ -912,7 +915,7 @@ Test::testSubsetService()
{
// Prepare message.
TestFrame frame(_repo, "docproc/cluster.default");
- frame.setMessage(make_unique<PutDocumentMessage>(make_shared<Document>(*_docType, DocumentId("id:ns:testdoc::"))));
+ frame.setMessage(make_unique<PutDocumentMessage>(make_doc(DocumentId("id:ns:testdoc::"))));
// Test requerying for adding nodes.
frame.setHop(mbus::HopSpec("test", "docproc/cluster.default/[SubsetService:2]/chain.default"));
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/MetricsResponse.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/MetricsResponse.java
index 8b7a2bafc40..fa9cfff0d68 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/MetricsResponse.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/MetricsResponse.java
@@ -120,11 +120,13 @@ public class MetricsResponse {
cpu { // a node resource
@Override
- public List<String> metricResponseNames() { return List.of(HostedNodeAdminMetrics.CPU_UTIL.baseName()); }
+ public List<String> metricResponseNames() {
+ return List.of(HostedNodeAdminMetrics.CPU_UTIL.baseName(), HostedNodeAdminMetrics.GPU_UTIL.baseName());
+ }
@Override
double computeFinal(ListMap<String, Double> values) {
- return values.values().stream().flatMap(List::stream).mapToDouble(v -> v).average().orElse(0) / 100; // % to ratio
+ return values.values().stream().flatMap(List::stream).mapToDouble(v -> v).max().orElse(0) / 100; // % to ratio
}
},
@@ -133,11 +135,17 @@ public class MetricsResponse {
@Override
public List<String> metricResponseNames() {
return List.of(HostedNodeAdminMetrics.MEM_UTIL.baseName(),
- SearchNodeMetrics.CONTENT_PROTON_RESOURCE_USAGE_MEMORY.average());
+ SearchNodeMetrics.CONTENT_PROTON_RESOURCE_USAGE_MEMORY.average(),
+ HostedNodeAdminMetrics.GPU_MEM_USED.baseName(),
+ HostedNodeAdminMetrics.GPU_MEM_TOTAL.baseName());
}
@Override
double computeFinal(ListMap<String, Double> values) {
+ return Math.max(gpuMemUtil(values), cpuMemUtil(values));
+ }
+
+ private double cpuMemUtil(ListMap<String, Double> values) {
var valueList = values.get(SearchNodeMetrics.CONTENT_PROTON_RESOURCE_USAGE_MEMORY.average()); // prefer over mem.util
if ( ! valueList.isEmpty()) return valueList.get(0);
@@ -147,6 +155,12 @@ public class MetricsResponse {
return 0;
}
+ private double gpuMemUtil(ListMap<String, Double> values) {
+ var usedGpuMemory = values.get(HostedNodeAdminMetrics.GPU_MEM_USED.baseName()).stream().mapToDouble(v -> v).sum();
+ var totalGpuMemory = values.get(HostedNodeAdminMetrics.GPU_MEM_TOTAL.baseName()).stream().mapToDouble(v -> v).sum();
+ return totalGpuMemory > 0 ? usedGpuMemory / totalGpuMemory : 0;
+ }
+
},
disk { // a node resource
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/MetricsV2MetricsFetcherTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/MetricsV2MetricsFetcherTest.java
index 24697d02681..01a4e96a195 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/MetricsV2MetricsFetcherTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/MetricsV2MetricsFetcherTest.java
@@ -80,7 +80,7 @@ public class MetricsV2MetricsFetcherTest {
assertTrue(values.get(0).getSecond().stable());
}
- {
+ { // read response 2 when unstable
httpClient.cannedResponse = cannedResponseForApplication2;
try (Mutex lock = tester.nodeRepository().applications().lock(application1)) {
tester.nodeRepository().nodes().write(tester.nodeRepository().nodes().list(Node.State.active).owner(application2)
@@ -89,6 +89,18 @@ public class MetricsV2MetricsFetcherTest {
List<Pair<String, NodeMetricSnapshot>> values = new ArrayList<>(fetcher.fetchMetrics(application2).get().nodeMetrics());
assertFalse(values.get(0).getSecond().stable());
}
+
+ {
+ httpClient.cannedResponse = cannedResponseForApplication3;
+ List<Pair<String, NodeMetricSnapshot>> values = new ArrayList<>(fetcher.fetchMetrics(application2).get().nodeMetrics());
+ assertEquals("http://host-3.yahoo.com:4080/metrics/v2/values?consumer=autoscaling",
+ httpClient.requestsReceived.get(1));
+ assertEquals(1, values.size());
+ assertEquals("host-3.yahoo.com", values.get(0).getFirst());
+ assertEquals(0.13, values.get(0).getSecond().load().cpu(), delta);
+ assertEquals(0.9375, values.get(0).getSecond().load().memory(), delta);
+ }
+
}
private static class MockHttpClient implements MetricsV2MetricsFetcher.AsyncHttpClient {
@@ -208,7 +220,42 @@ public class MetricsV2MetricsFetcherTest {
{
"values": {
"cpu.util": 10,
+ "gpu.util": 8,
+ "mem.util": 15,
+ "gpu.memory.used": 0,
+ "gpu.memory.total": 8,
+ "disk.util": 20,
+ "application_generation.last": 3,
+ "in_service.last": 0
+ },
+ "dimensions": {
+ "state": "active"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ """;
+
+ final String cannedResponseForApplication3 =
+ """
+ {
+ "nodes": [
+ {
+ "hostname": "host-3.yahoo.com",
+ "role": "role0",
+ "node": {
+ "timestamp": 1300,
+ "metrics": [
+ {
+ "values": {
+ "cpu.util": 10,
+ "gpu.util": 13,
"mem.util": 15,
+ "gpu.memory.used": 7.5,
+ "gpu.memory.total": 8,
"disk.util": 20,
"application_generation.last": 3,
"in_service.last": 0
diff --git a/persistence/src/vespa/persistence/dummyimpl/dummypersistence.cpp b/persistence/src/vespa/persistence/dummyimpl/dummypersistence.cpp
index 0c0086861b2..993a8baec09 100644
--- a/persistence/src/vespa/persistence/dummyimpl/dummypersistence.cpp
+++ b/persistence/src/vespa/persistence/dummyimpl/dummypersistence.cpp
@@ -477,7 +477,7 @@ DummyPersistence::updateAsync(const Bucket& bucket, Timestamp ts, DocumentUpdate
onComplete->onComplete(std::make_unique<UpdateResult>());
return;
} else {
- docToUpdate = std::make_shared<document::Document>(upd->getType(), upd->getId());
+ docToUpdate = std::make_shared<document::Document>(*upd->getRepoPtr(), upd->getType(), upd->getId());
updatedTs = ts;
}
}
@@ -680,7 +680,7 @@ DummyPersistence::iterate(IteratorId id, uint64_t maxByteSize) const
{
assert(entry->getDocument());
// Create new document with only wanted fields.
- Document::UP filtered(FieldSet::createDocumentSubsetCopy(*entry->getDocument(), *it->_fieldSet));
+ auto filtered = FieldSet::createDocumentSubsetCopy(*_repo, *entry->getDocument(), *it->_fieldSet);
auto ret = DocEntry::create(entry->getTimestamp(), std::move(filtered), entry->getSize());
entries.push_back(std::move(ret));
} else {
diff --git a/searchcore/src/tests/proton/attribute/attribute_populator/attribute_populator_test.cpp b/searchcore/src/tests/proton/attribute/attribute_populator/attribute_populator_test.cpp
index 19b8348fb7a..b4d3eb13ac7 100644
--- a/searchcore/src/tests/proton/attribute/attribute_populator/attribute_populator_test.cpp
+++ b/searchcore/src/tests/proton/attribute/attribute_populator/attribute_populator_test.cpp
@@ -60,7 +60,7 @@ struct DocContext
std::shared_ptr<Document> create(uint32_t id, int64_t fieldValue) {
vespalib::string docId =
vespalib::make_string("id:searchdocument:searchdocument::%u", id);
- auto doc = std::make_shared<Document>(*_repo->getDocumentType("searchdocument"), DocumentId(docId));
+ auto doc = std::make_shared<Document>(*_repo, *_repo->getDocumentType("searchdocument"), DocumentId(docId));
doc->setValue("a1", IntFieldValue(fieldValue));
return doc;
}
diff --git a/searchcore/src/tests/proton/attribute/attribute_test.cpp b/searchcore/src/tests/proton/attribute/attribute_test.cpp
index 75d9c78d07e..4458cd66ad6 100644
--- a/searchcore/src/tests/proton/attribute/attribute_test.cpp
+++ b/searchcore/src/tests/proton/attribute/attribute_test.cpp
@@ -1050,7 +1050,7 @@ public:
}
std::unique_ptr<Document> makeDoc() {
- return std::make_unique<Document>(_type, DocumentId("id::test::1"));
+ return Document::make_without_repo(_type, DocumentId("id::test::1"));
}
};
diff --git a/searchcore/src/tests/proton/attribute/document_field_extractor/document_field_extractor_test.cpp b/searchcore/src/tests/proton/attribute/document_field_extractor/document_field_extractor_test.cpp
index 903b4d89696..42dad54394f 100644
--- a/searchcore/src/tests/proton/attribute/document_field_extractor/document_field_extractor_test.cpp
+++ b/searchcore/src/tests/proton/attribute/document_field_extractor/document_field_extractor_test.cpp
@@ -109,7 +109,7 @@ struct FixtureBase
Document *
makeDoc()
{
- doc = std::make_unique<Document>(type, DocumentId("id::test::1"));
+ doc = Document::make_without_repo(type, DocumentId("id::test::1"));
extractor = std::make_unique<DocumentFieldExtractor>(*doc);
return doc.get();
}
diff --git a/searchcore/src/tests/proton/common/cachedselect_test.cpp b/searchcore/src/tests/proton/common/cachedselect_test.cpp
index 6565ec601e6..93a7e46285e 100644
--- a/searchcore/src/tests/proton/common/cachedselect_test.cpp
+++ b/searchcore/src/tests/proton/common/cachedselect_test.cpp
@@ -123,7 +123,7 @@ makeDoc(const DocumentTypeRepo &repo,
int32_t ab)
{
const DocumentType *docType = repo.getDocumentType("test");
- Document::UP doc(new Document(*docType, DocumentId(docId)));
+ auto doc = std::make_unique<Document>(repo, *docType, DocumentId(docId));
if (ia != "null")
doc->setValue("ia", StringFieldValue(ia));
if (ib != "null")
@@ -348,7 +348,7 @@ TestFixture::testParse(const string &selection,
const DocumentType *docType = repo.getDocumentType(docTypeName);
ASSERT_TRUE(docType != nullptr);
- Document::UP emptyDoc(new Document(*docType, DocumentId()));
+ auto emptyDoc = std::make_unique<Document>(repo, *docType, DocumentId());
res->set(selection,
docTypeName,
diff --git a/searchcore/src/tests/proton/common/selectpruner_test.cpp b/searchcore/src/tests/proton/common/selectpruner_test.cpp
index 4bc7ef53d94..80d6314c392 100644
--- a/searchcore/src/tests/proton/common/selectpruner_test.cpp
+++ b/searchcore/src/tests/proton/common/selectpruner_test.cpp
@@ -222,8 +222,7 @@ TestFixture::testPrune(const string &selection, const string &exp, const string
LOG(info, "ParseTree: '%s'", os.str().c_str());
const DocumentType *docType = repo.getDocumentType(docTypeName);
ASSERT_TRUE(docType != nullptr);
- auto emptyDoc = std::make_unique<Document>(*docType, document::DocumentId("id:ns:" + docTypeName + "::1"));
- emptyDoc->setRepo(repo);
+ auto emptyDoc = std::make_unique<Document>(repo, *docType, document::DocumentId("id:ns:" + docTypeName + "::1"));
SelectPruner pruner(docTypeName, &_amgr, *emptyDoc, repo, _hasFields, _hasDocuments);
pruner.process(*select);
std::ostringstream pos;
diff --git a/searchcore/src/tests/proton/document_iterator/document_iterator_test.cpp b/searchcore/src/tests/proton/document_iterator/document_iterator_test.cpp
index f89af9a11a6..ff55d3cca7c 100644
--- a/searchcore/src/tests/proton/document_iterator/document_iterator_test.cpp
+++ b/searchcore/src/tests/proton/document_iterator/document_iterator_test.cpp
@@ -156,8 +156,12 @@ struct UnitDR : DocumentRetrieverBaseForTest {
static void reset() { _docidCnt = 2; }
};
+Document::UP make_doc(DocumentId docid) {
+ return Document::make_without_repo(*DataType::DOCUMENT, docid);
+}
+
UnitDR::UnitDR()
- : repo(), document(std::make_unique<Document>(*DataType::DOCUMENT, DocumentId())), timestamp(0),
+ : repo(), document(make_doc(DocumentId())), timestamp(0),
bucket(), removed(false), docid(0), docIdLimit(std::numeric_limits<uint32_t>::max())
{}
UnitDR::UnitDR(document::Document::UP d, Timestamp t, Bucket b, bool r)
@@ -242,7 +246,7 @@ struct AttrUnitDR : public UnitDR
CachedSelect::SP parseSelect(const vespalib::string &selection) const override {
auto res = std::make_shared<CachedSelect>();
- res->set(selection, "foo", Document(document->getType(), DocumentId()), repo, &_amgr, true);
+ res->set(selection, "foo", Document(repo, document->getType(), DocumentId()), repo, &_amgr, true);
return res;
}
};
@@ -291,7 +295,7 @@ IDocumentRetriever::SP nil() { return std::make_unique<UnitDR>(); }
IDocumentRetriever::SP
doc(const DocumentId &id, Timestamp t, Bucket b) {
- return std::make_shared<UnitDR>(std::make_unique<Document>(*DataType::DOCUMENT, id), t, b, false);
+ return std::make_shared<UnitDR>(make_doc(id), t, b, false);
}
IDocumentRetriever::SP
@@ -301,7 +305,7 @@ doc(const std::string &id, Timestamp t, Bucket b) {
IDocumentRetriever::SP
rem(const DocumentId &id, Timestamp t, Bucket b) {
- return std::make_shared<UnitDR>(std::make_unique<Document>(*DataType::DOCUMENT, id), t, b, true);
+ return std::make_shared<UnitDR>(make_doc(id), t, b, true);
}
IDocumentRetriever::SP
@@ -338,14 +342,14 @@ const DocumentType &getAttrDocType() {
}
IDocumentRetriever::SP doc_with_fields(const std::string &id, Timestamp t, Bucket b) {
- auto d = std::make_unique<Document>(getDocType(), DocumentId(id));
+ auto d = Document::make_without_repo(getDocType(), DocumentId(id));
d->setValue("header", StringFieldValue::make("foo"));
d->setValue("body", StringFieldValue::make("bar"));
return std::make_shared<UnitDR>(getDocType(), std::move(d), t, b, false);
}
IDocumentRetriever::SP doc_with_null_fields(const std::string &id, Timestamp t, Bucket b) {
- return std::make_unique<AttrUnitDR>(std::make_unique<Document>(getAttrDocType(), DocumentId(id)), t, b, false);
+ return std::make_unique<AttrUnitDR>(Document::make_without_repo(getAttrDocType(), DocumentId(id)), t, b, false);
}
IDocumentRetriever::SP doc_with_attr_fields(const vespalib::string &id,
@@ -355,7 +359,7 @@ IDocumentRetriever::SP doc_with_attr_fields(const vespalib::string &id,
const vespalib::string &ss,
const vespalib::string &attr_ss)
{
- auto d = std::make_unique<Document>(getAttrDocType(), DocumentId(id));
+ auto d = Document::make_without_repo(getAttrDocType(), DocumentId(id));
d->setValue("header", StringFieldValue::make("foo"));
d->setValue("body", StringFieldValue::make("bar"));
d->setValue("aa", IntFieldValue::make(aa));
@@ -367,7 +371,7 @@ IDocumentRetriever::SP doc_with_attr_fields(const vespalib::string &id,
auto doc_rec(VisitRecordingUnitDR::VisitedLIDs& visited_lids, const std::string &id, Timestamp t, Bucket b)
{
- return std::make_shared<VisitRecordingUnitDR>(visited_lids, std::make_unique<Document>(getAttrDocType(), DocumentId(id)), t, b, false);
+ return std::make_shared<VisitRecordingUnitDR>(visited_lids, Document::make_without_repo(getAttrDocType(), DocumentId(id)), t, b, false);
}
void checkDoc(const IDocumentRetriever &dr, const std::string &id,
@@ -462,9 +466,9 @@ TEST("require that normal documents can be iterated") {
IterateResult res = itr.iterate(largeNum);
EXPECT_TRUE(res.isCompleted());
EXPECT_EQUAL(3u, res.getEntries().size());
- TEST_DO(checkEntry(res, 0, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::1")), Timestamp(2)));
- TEST_DO(checkEntry(res, 1, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::2")), Timestamp(3)));
- TEST_DO(checkEntry(res, 2, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::3")), Timestamp(4)));
+ TEST_DO(checkEntry(res, 0, *make_doc(DocumentId("id:ns:document::1")), Timestamp(2)));
+ TEST_DO(checkEntry(res, 1, *make_doc(DocumentId("id:ns:document::2")), Timestamp(3)));
+ TEST_DO(checkEntry(res, 2, *make_doc(DocumentId("id:ns:document::3")), Timestamp(4)));
}
void verifyIterateIgnoringStopSignal(DocumentIterator & itr) {
@@ -495,7 +499,7 @@ void verifyReadConsistency(DocumentIterator & itr, ILidCommitState & lidCommitSt
IterateResult res = itr.iterate(largeNum);
EXPECT_TRUE(res.isCompleted());
EXPECT_EQUAL(1u, res.getEntries().size());
- TEST_DO(checkEntry(res, 0, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::1")), Timestamp(2)));
+ TEST_DO(checkEntry(res, 0, *make_doc(DocumentId("id:ns:document::1")), Timestamp(2)));
}
class ILidCommitStateProxy : public ILidCommitState {
@@ -552,7 +556,7 @@ TEST("require that docid limit is honoured") {
IterateResult res = itr.iterate(largeNum);
EXPECT_TRUE(res.isCompleted());
EXPECT_EQUAL(1u, res.getEntries().size());
- TEST_DO(checkEntry(res, 0, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::1")), Timestamp(2)));
+ TEST_DO(checkEntry(res, 0, *make_doc(DocumentId("id:ns:document::1")), Timestamp(2)));
udr.setDocIdLimit(7);
DocumentIterator limited(bucket(5), std::make_shared<document::AllFields>(), selectAll(), newestV(), -1, false);
@@ -583,7 +587,7 @@ TEST("require that remove entries can be ignored") {
IterateResult res = itr.iterate(largeNum);
EXPECT_TRUE(res.isCompleted());
EXPECT_EQUAL(1u, res.getEntries().size());
- TEST_DO(checkEntry(res, 0, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::2")), Timestamp(3)));
+ TEST_DO(checkEntry(res, 0, *make_doc(DocumentId("id:ns:document::2")), Timestamp(3)));
}
TEST("require that iterating all versions returns both documents and removes") {
@@ -595,7 +599,7 @@ TEST("require that iterating all versions returns both documents and removes") {
EXPECT_TRUE(res.isCompleted());
EXPECT_EQUAL(3u, res.getEntries().size());
TEST_DO(checkEntry(res, 0, DocumentId("id:ns:document::1"), Timestamp(2)));
- TEST_DO(checkEntry(res, 1, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::2")), Timestamp(3)));
+ TEST_DO(checkEntry(res, 1, *make_doc(DocumentId("id:ns:document::2")), Timestamp(3)));
TEST_DO(checkEntry(res, 2, DocumentId("id:ns:document::3"), Timestamp(4)));
}
@@ -620,7 +624,7 @@ TEST("require that entries in other buckets are skipped") {
IterateResult res = itr.iterate(largeNum);
EXPECT_TRUE(res.isCompleted());
EXPECT_EQUAL(1u, res.getEntries().size());
- TEST_DO(checkEntry(res, 0, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::2")), Timestamp(3)));
+ TEST_DO(checkEntry(res, 0, *make_doc(DocumentId("id:ns:document::2")), Timestamp(3)));
}
TEST("require that maxBytes splits iteration results") {
@@ -628,16 +632,16 @@ TEST("require that maxBytes splits iteration results") {
itr.add(doc("id:ns:document::1", Timestamp(2), bucket(5)));
itr.add(cat(rem("id:ns:document::2", Timestamp(3), bucket(5)),
doc("id:ns:document::3", Timestamp(4), bucket(5))));
- IterateResult res1 = itr.iterate(getSize(Document(*DataType::DOCUMENT, DocumentId("id:ns:document::1"))) +
+ IterateResult res1 = itr.iterate(getSize(*make_doc(DocumentId("id:ns:document::1"))) +
getSize(DocumentId("id:ns:document::2")));
EXPECT_TRUE(!res1.isCompleted());
EXPECT_EQUAL(2u, res1.getEntries().size());
- TEST_DO(checkEntry(res1, 0, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::1")), Timestamp(2)));
+ TEST_DO(checkEntry(res1, 0, *make_doc(DocumentId("id:ns:document::1")), Timestamp(2)));
TEST_DO(checkEntry(res1, 1, DocumentId("id:ns:document::2"), Timestamp(3)));
IterateResult res2 = itr.iterate(largeNum);
EXPECT_TRUE(res2.isCompleted());
- TEST_DO(checkEntry(res2, 0, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::3")), Timestamp(4)));
+ TEST_DO(checkEntry(res2, 0, *make_doc(DocumentId("id:ns:document::3")), Timestamp(4)));
IterateResult res3 = itr.iterate(largeNum);
EXPECT_TRUE(res3.isCompleted());
@@ -671,7 +675,7 @@ TEST("require that at least one document is returned by visit") {
doc("id:ns:document::3", Timestamp(4), bucket(5))));
IterateResult res1 = itr.iterate(0);
EXPECT_TRUE( ! res1.getEntries().empty());
- TEST_DO(checkEntry(res1, 0, Document(*DataType::DOCUMENT,DocumentId("id:ns:document::1")), Timestamp(2)));
+ TEST_DO(checkEntry(res1, 0, *make_doc(DocumentId("id:ns:document::1")), Timestamp(2)));
}
TEST("require that documents outside the timestamp limits are ignored") {
@@ -687,8 +691,8 @@ TEST("require that documents outside the timestamp limits are ignored") {
IterateResult res = itr.iterate(largeNum);
EXPECT_TRUE(res.isCompleted());
EXPECT_EQUAL(4u, res.getEntries().size());
- TEST_DO(checkEntry(res, 0, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::2")), Timestamp(100)));
- TEST_DO(checkEntry(res, 1, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::3")), Timestamp(200)));
+ TEST_DO(checkEntry(res, 0, *make_doc(DocumentId("id:ns:document::2")), Timestamp(100)));
+ TEST_DO(checkEntry(res, 1, *make_doc(DocumentId("id:ns:document::3")), Timestamp(200)));
TEST_DO(checkEntry(res, 2, DocumentId("id:ns:document::6"), Timestamp(100)));
TEST_DO(checkEntry(res, 3, DocumentId("id:ns:document::7"), Timestamp(200)));
}
@@ -706,8 +710,8 @@ TEST("require that timestamp subset returns the appropriate documents") {
IterateResult res = itr.iterate(largeNum);
EXPECT_TRUE(res.isCompleted());
EXPECT_EQUAL(3u, res.getEntries().size());
- TEST_DO(checkEntry(res, 0, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::2")), Timestamp(400)));
- TEST_DO(checkEntry(res, 1, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::4")), Timestamp(200)));
+ TEST_DO(checkEntry(res, 0, *make_doc(DocumentId("id:ns:document::2")), Timestamp(400)));
+ TEST_DO(checkEntry(res, 1, *make_doc(DocumentId("id:ns:document::4")), Timestamp(200)));
TEST_DO(checkEntry(res, 2, DocumentId("id:ns:document::6"), Timestamp(350)));
}
@@ -724,8 +728,8 @@ TEST("require that document selection will filter results") {
IterateResult res = itr.iterate(largeNum);
EXPECT_TRUE(res.isCompleted());
EXPECT_EQUAL(4u, res.getEntries().size());
- TEST_DO(checkEntry(res, 0, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::xxx1")), Timestamp(99)));
- TEST_DO(checkEntry(res, 1, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::xxx2")), Timestamp(200)));
+ TEST_DO(checkEntry(res, 0, *make_doc(DocumentId("id:ns:document::xxx1")), Timestamp(99)));
+ TEST_DO(checkEntry(res, 1, *make_doc(DocumentId("id:ns:document::xxx2")), Timestamp(200)));
TEST_DO(checkEntry(res, 2, DocumentId("id:ns:document::xxx3"), Timestamp(99)));
TEST_DO(checkEntry(res, 3, DocumentId("id:ns:document::xxx4"), Timestamp(200)));
}
@@ -737,10 +741,10 @@ TEST("require that document selection handles 'field == null'") {
IterateResult res = itr.iterate(largeNum);
EXPECT_TRUE(res.isCompleted());
ASSERT_EQUAL(2u, res.getEntries().size());
- Document expected1(getAttrDocType(), DocumentId("id:ns:foo::xxx1"));
- TEST_DO(checkEntry(res, 0, expected1, Timestamp(99)));
- Document expected2(getAttrDocType(), DocumentId("id:ns:foo::xxx2"));
- TEST_DO(checkEntry(res, 1, expected2, Timestamp(100)));
+ auto expected1 = Document::make_without_repo(getAttrDocType(), DocumentId("id:ns:foo::xxx1"));
+ TEST_DO(checkEntry(res, 0, *expected1, Timestamp(99)));
+ auto expected2 = Document::make_without_repo(getAttrDocType(), DocumentId("id:ns:foo::xxx2"));
+ TEST_DO(checkEntry(res, 1, *expected2, Timestamp(100)));
}
TEST("require that invalid document selection returns no documents") {
@@ -771,7 +775,7 @@ TEST("require that document selection and timestamp range works together") {
IterateResult res = itr.iterate(largeNum);
EXPECT_TRUE(res.isCompleted());
EXPECT_EQUAL(2u, res.getEntries().size());
- TEST_DO(checkEntry(res, 0, Document(*DataType::DOCUMENT, DocumentId("id:ns:document::xxx2")), Timestamp(200)));
+ TEST_DO(checkEntry(res, 0, *make_doc(DocumentId("id:ns:document::xxx2")), Timestamp(200)));
TEST_DO(checkEntry(res, 1, DocumentId("id:ns:document::xxx4"), Timestamp(200)));
}
@@ -782,9 +786,9 @@ TEST("require that fieldset limits fields returned") {
IterateResult res = itr.iterate(largeNum);
EXPECT_TRUE(res.isCompleted());
EXPECT_EQUAL(1u, res.getEntries().size());
- Document expected(getDocType(), DocumentId("id:ns:foo::xxx1"));
- expected.setValue("header", StringFieldValue::make("foo"));
- TEST_DO(checkEntry(res, 0, expected, Timestamp(1)));
+ auto expected = Document::make_without_repo(getDocType(), DocumentId("id:ns:foo::xxx1"));
+ expected->setValue("header", StringFieldValue::make("foo"));
+ TEST_DO(checkEntry(res, 0, *expected, Timestamp(1)));
}
namespace {
@@ -838,22 +842,22 @@ TEST("require that attributes are used")
IterateResult res = itr.iterate(largeNum);
EXPECT_TRUE(res.isCompleted());
EXPECT_EQUAL(2u, res.getEntries().size());
- Document expected1(getAttrDocType(), DocumentId("id:ns:foo::xx2"));
- expected1.setValue("header", StringFieldValue::make("foo"));
- expected1.setValue("body", StringFieldValue::make("bar"));
- expected1.setValue("aa", IntFieldValue::make(27));
- expected1.setValue("ab", IntFieldValue::make(28));
- expected1.setValue("dd", DoubleFieldValue::make(2.7));
- expected1.setValue("ss", StringFieldValue::make("x27"));
- Document expected2(getAttrDocType(), DocumentId("id:ns:foo::xx4"));
- expected2.setValue("header", StringFieldValue::make("foo"));
- expected2.setValue("body", StringFieldValue::make("bar"));
- expected2.setValue("aa", IntFieldValue::make(45));
- expected2.setValue("ab", IntFieldValue::make(46));
- expected2.setValue("dd", DoubleFieldValue::make(4.5));
- expected2.setValue("ss", StringFieldValue::make("x45"));
- TEST_DO(checkEntry(res, 0, expected1, Timestamp(2)));
- TEST_DO(checkEntry(res, 1, expected2, Timestamp(4)));
+ auto expected1 = Document::make_without_repo(getAttrDocType(), DocumentId("id:ns:foo::xx2"));
+ expected1->setValue("header", StringFieldValue::make("foo"));
+ expected1->setValue("body", StringFieldValue::make("bar"));
+ expected1->setValue("aa", IntFieldValue::make(27));
+ expected1->setValue("ab", IntFieldValue::make(28));
+ expected1->setValue("dd", DoubleFieldValue::make(2.7));
+ expected1->setValue("ss", StringFieldValue::make("x27"));
+ auto expected2 = Document::make_without_repo(getAttrDocType(), DocumentId("id:ns:foo::xx4"));
+ expected2->setValue("header", StringFieldValue::make("foo"));
+ expected2->setValue("body", StringFieldValue::make("bar"));
+ expected2->setValue("aa", IntFieldValue::make(45));
+ expected2->setValue("ab", IntFieldValue::make(46));
+ expected2->setValue("dd", DoubleFieldValue::make(4.5));
+ expected2->setValue("ss", StringFieldValue::make("x45"));
+ TEST_DO(checkEntry(res, 0, *expected1, Timestamp(2)));
+ TEST_DO(checkEntry(res, 1, *expected2, Timestamp(4)));
DocumentIterator itr2(bucket(5), std::make_shared<document::AllFields>(), selectDocs("foo.dd == 4.5"), docV(), -1, false);
itr2.add(doc_with_attr_fields("id:ns:foo::xx5", Timestamp(5), bucket(5),
@@ -868,22 +872,22 @@ TEST("require that attributes are used")
IterateResult res2 = itr2.iterate(largeNum);
EXPECT_TRUE(res2.isCompleted());
EXPECT_EQUAL(2u, res2.getEntries().size());
- Document expected3(getAttrDocType(), DocumentId("id:ns:foo::xx6"));
- expected3.setValue("header", StringFieldValue::make("foo"));
- expected3.setValue("body", StringFieldValue::make("bar"));
- expected3.setValue("aa", IntFieldValue::make(27));
- expected3.setValue("ab", IntFieldValue::make(28));
- expected3.setValue("dd", DoubleFieldValue::make(2.7));
- expected3.setValue("ss", StringFieldValue::make("x27"));
- Document expected4(getAttrDocType(), DocumentId("id:ns:foo::xx8"));
- expected4.setValue("header", StringFieldValue::make("foo"));
- expected4.setValue("body", StringFieldValue::make("bar"));
- expected4.setValue("aa", IntFieldValue::make(45));
- expected4.setValue("ab", IntFieldValue::make(46));
- expected4.setValue("dd", DoubleFieldValue::make(4.5));
- expected4.setValue("ss", StringFieldValue::make("x45"));
- TEST_DO(checkEntry(res2, 0, expected3, Timestamp(6)));
- TEST_DO(checkEntry(res2, 1, expected4, Timestamp(8)));
+ auto expected3 = Document::make_without_repo(getAttrDocType(), DocumentId("id:ns:foo::xx6"));
+ expected3->setValue("header", StringFieldValue::make("foo"));
+ expected3->setValue("body", StringFieldValue::make("bar"));
+ expected3->setValue("aa", IntFieldValue::make(27));
+ expected3->setValue("ab", IntFieldValue::make(28));
+ expected3->setValue("dd", DoubleFieldValue::make(2.7));
+ expected3->setValue("ss", StringFieldValue::make("x27"));
+ auto expected4 = Document::make_without_repo(getAttrDocType(), DocumentId("id:ns:foo::xx8"));
+ expected4->setValue("header", StringFieldValue::make("foo"));
+ expected4->setValue("body", StringFieldValue::make("bar"));
+ expected4->setValue("aa", IntFieldValue::make(45));
+ expected4->setValue("ab", IntFieldValue::make(46));
+ expected4->setValue("dd", DoubleFieldValue::make(4.5));
+ expected4->setValue("ss", StringFieldValue::make("x45"));
+ TEST_DO(checkEntry(res2, 0, *expected3, Timestamp(6)));
+ TEST_DO(checkEntry(res2, 1, *expected4, Timestamp(8)));
DocumentIterator itr3(bucket(5), std::make_shared<document::AllFields>(), selectDocs("foo.ss == \"x45\""), docV(), -1, false);
itr3.add(doc_with_attr_fields("id:ns:foo::xx9", Timestamp(9), bucket(5),
@@ -898,22 +902,22 @@ TEST("require that attributes are used")
IterateResult res3 = itr3.iterate(largeNum);
EXPECT_TRUE(res3.isCompleted());
EXPECT_EQUAL(2u, res3.getEntries().size());
- Document expected5(getAttrDocType(), DocumentId("id:ns:foo::xx10"));
- expected5.setValue("header", StringFieldValue::make("foo"));
- expected5.setValue("body", StringFieldValue::make("bar"));
- expected5.setValue("aa", IntFieldValue::make(27));
- expected5.setValue("ab", IntFieldValue::make(28));
- expected5.setValue("dd", DoubleFieldValue::make(2.7));
- expected5.setValue("ss", StringFieldValue::make("x27"));
- Document expected6(getAttrDocType(), DocumentId("id:ns:foo::xx12"));
- expected6.setValue("header", StringFieldValue::make("foo"));
- expected6.setValue("body", StringFieldValue::make("bar"));
- expected6.setValue("aa", IntFieldValue::make(45));
- expected6.setValue("ab", IntFieldValue::make(46));
- expected6.setValue("dd", DoubleFieldValue::make(4.5));
- expected6.setValue("ss", StringFieldValue::make("x45"));
- TEST_DO(checkEntry(res3, 0, expected5, Timestamp(10)));
- TEST_DO(checkEntry(res3, 1, expected6, Timestamp(12)));
+ auto expected5 = Document::make_without_repo(getAttrDocType(), DocumentId("id:ns:foo::xx10"));
+ expected5->setValue("header", StringFieldValue::make("foo"));
+ expected5->setValue("body", StringFieldValue::make("bar"));
+ expected5->setValue("aa", IntFieldValue::make(27));
+ expected5->setValue("ab", IntFieldValue::make(28));
+ expected5->setValue("dd", DoubleFieldValue::make(2.7));
+ expected5->setValue("ss", StringFieldValue::make("x27"));
+ auto expected6 = Document::make_without_repo(getAttrDocType(), DocumentId("id:ns:foo::xx12"));
+ expected6->setValue("header", StringFieldValue::make("foo"));
+ expected6->setValue("body", StringFieldValue::make("bar"));
+ expected6->setValue("aa", IntFieldValue::make(45));
+ expected6->setValue("ab", IntFieldValue::make(46));
+ expected6->setValue("dd", DoubleFieldValue::make(4.5));
+ expected6->setValue("ss", StringFieldValue::make("x45"));
+ TEST_DO(checkEntry(res3, 0, *expected5, Timestamp(10)));
+ TEST_DO(checkEntry(res3, 1, *expected6, Timestamp(12)));
}
TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/searchcore/src/tests/proton/documentdb/maintenancecontroller/maintenancecontroller_test.cpp b/searchcore/src/tests/proton/documentdb/maintenancecontroller/maintenancecontroller_test.cpp
index 5afe0a0c5a2..bf960768c89 100644
--- a/searchcore/src/tests/proton/documentdb/maintenancecontroller/maintenancecontroller_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/maintenancecontroller/maintenancecontroller_test.cpp
@@ -516,8 +516,7 @@ MyDocumentSubDB::handleRemove(RemoveOperationWithDocId &op)
assert(op.getLid() == putRes._lid);
const document::DocumentType *docType =
_repo->getDocumentType(_docTypeName.getName());
- auto doc = std::make_unique<Document>(*docType, docId);
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *docType, docId);
_docs[op.getLid()] = std::move(doc);
needCommit = true;
}
diff --git a/searchcore/src/tests/proton/feedoperation/feedoperation_test.cpp b/searchcore/src/tests/proton/feedoperation/feedoperation_test.cpp
index 87947788bdf..0479fa61e2b 100644
--- a/searchcore/src/tests/proton/feedoperation/feedoperation_test.cpp
+++ b/searchcore/src/tests/proton/feedoperation/feedoperation_test.cpp
@@ -126,7 +126,7 @@ public:
return upd;
}
auto makeDoc() {
- auto doc(std::make_shared<Document>(_docType, docId));
+ auto doc(std::make_shared<Document>(*_repo, _docType, docId));
doc->setValue("string", StringFieldValue("stringval"));
return doc;
}
diff --git a/searchcore/src/tests/proton/persistenceengine/persistenceengine_test.cpp b/searchcore/src/tests/proton/persistenceengine/persistenceengine_test.cpp
index e9fd4fa9d37..996d9846934 100644
--- a/searchcore/src/tests/proton/persistenceengine/persistenceengine_test.cpp
+++ b/searchcore/src/tests/proton/persistenceengine/persistenceengine_test.cpp
@@ -61,7 +61,7 @@ createDocType(const vespalib::string &name, int32_t id)
Document::SP
createDoc(const DocumentType &docType, const DocumentId &docId)
{
- return std::make_shared<Document>(docType, docId);
+ return Document::SP(Document::make_without_repo(docType, docId).release());
}
diff --git a/searchcore/src/tests/proton/server/documentretriever_test.cpp b/searchcore/src/tests/proton/server/documentretriever_test.cpp
index 6cc2ca22531..f99c3ab0f67 100644
--- a/searchcore/src/tests/proton/server/documentretriever_test.cpp
+++ b/searchcore/src/tests/proton/server/documentretriever_test.cpp
@@ -161,7 +161,7 @@ struct MyDocumentStore : proton::test::DummyDocumentStore {
return std::move(_testDoc);
}
const DocumentType *doc_type = r.getDocumentType(doc_type_name);
- auto doc = std::make_unique<Document>(*doc_type, doc_id);
+ auto doc = std::make_unique<Document>(r, *doc_type, doc_id);
ASSERT_TRUE(doc);
doc->setValue(static_field, IntFieldValue::make(static_value));
doc->setValue(dyn_field_i, IntFieldValue::make(static_value));
diff --git a/searchcore/src/vespa/searchcore/bmcluster/bm_feed.cpp b/searchcore/src/vespa/searchcore/bmcluster/bm_feed.cpp
index 0856bad0035..b257f85acdc 100644
--- a/searchcore/src/vespa/searchcore/bmcluster/bm_feed.cpp
+++ b/searchcore/src/vespa/searchcore/bmcluster/bm_feed.cpp
@@ -60,8 +60,7 @@ std::unique_ptr<Document>
BmFeed::make_document(uint32_t n, uint32_t i) const
{
auto id = make_document_id(n, i);
- auto document = std::make_unique<Document>(*_document_type, id);
- document->setRepo(*_repo);
+ auto document = std::make_unique<Document>(*_repo, *_document_type, id);
document->setFieldValue(_field, IntFieldValue::make(i));
return document;
}
diff --git a/searchcore/src/vespa/searchcore/proton/server/documentretriever.cpp b/searchcore/src/vespa/searchcore/proton/server/documentretriever.cpp
index ee2af5b606c..b8240b33b6c 100644
--- a/searchcore/src/vespa/searchcore/proton/server/documentretriever.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/documentretriever.cpp
@@ -244,7 +244,7 @@ DocumentRetriever::getPartialDocument(search::DocumentIdT lid, const document::D
FieldSet::stripFields(*doc, fieldSet);
}
} else {
- doc = std::make_unique<Document>(getDocumentType(), docId);
+ doc = std::make_unique<Document>(getDocumentTypeRepo(), getDocumentType(), docId);
switch (fieldSet.getType()) {
case FieldSet::Type::ALL:
populate(lid, *doc);
@@ -271,7 +271,6 @@ DocumentRetriever::getPartialDocument(search::DocumentIdT lid, const document::D
case FieldSet::Type::DOCID:
break;
}
- doc->setRepo(getDocumentTypeRepo());
}
return doc;
}
diff --git a/searchcore/src/vespa/searchcore/proton/server/documentretrieverbase.cpp b/searchcore/src/vespa/searchcore/proton/server/documentretrieverbase.cpp
index 914f3d8bcfd..bb7d80c5ebc 100644
--- a/searchcore/src/vespa/searchcore/proton/server/documentretrieverbase.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/documentretrieverbase.cpp
@@ -26,8 +26,7 @@ DocumentRetrieverBase::DocumentRetrieverBase(
_hasFields(hasFields)
{
const document::DocumentType * docType(_repo.getDocumentType(_docTypeName.getName()));
- _emptyDoc = std::make_unique<document::Document>(*docType, DocumentId("id:empty:" + _docTypeName.getName() + "::empty"));
- _emptyDoc->setRepo(_repo);
+ _emptyDoc = std::make_unique<document::Document>(_repo, *docType, DocumentId("id:empty:" + _docTypeName.getName() + "::empty"));
}
DocumentRetrieverBase::~DocumentRetrieverBase() = default;
diff --git a/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp b/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp
index 6bbedcdb18e..e9a14385c6a 100644
--- a/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp
@@ -217,8 +217,8 @@ FeedHandler::performInternalUpdate(FeedToken token, UpdateOperation &op)
void
FeedHandler::createNonExistingDocument(FeedToken token, const UpdateOperation &op)
{
- auto doc = make_shared<Document>(op.getUpdate()->getType(), op.getUpdate()->getId());
- doc->setRepo(*_activeFeedView->getDocumentTypeRepo());
+ auto doc = make_shared<Document>(*_activeFeedView->getDocumentTypeRepo(),
+ op.getUpdate()->getType(), op.getUpdate()->getId());
op.getUpdate()->applyTo(*doc);
PutOperation putOp(op.getBucketId(), op.getTimestamp(), std::move(doc));
putOp.set_prepare_serial_num(op.get_prepare_serial_num());
diff --git a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp
index 533b270c20a..c2b4c0507db 100644
--- a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp
@@ -586,8 +586,7 @@ StoreOnlyFeedView::internalRemove(FeedToken token, const RemoveOperationWithDocI
adjustMetaStore(rmOp, docId.getGlobalId(), docId);
if (rmOp.getValidDbdId(_params._subDbId)) {
- auto clearDoc = std::make_unique<Document>(*_docType, docId);
- clearDoc->setRepo(*_repo);
+ auto clearDoc = std::make_unique<Document>(*_repo, *_docType, docId);
putSummary(serialNum, rmOp.getLid(), std::move(clearDoc), std::make_shared<SummaryPutDoneContext>(std::move(token), get_pending_lid_token(rmOp)));
}
diff --git a/searchlib/src/apps/tests/memoryindexstress_test.cpp b/searchlib/src/apps/tests/memoryindexstress_test.cpp
index fb743ad93ac..fdb132d9a36 100644
--- a/searchlib/src/apps/tests/memoryindexstress_test.cpp
+++ b/searchlib/src/apps/tests/memoryindexstress_test.cpp
@@ -153,8 +153,7 @@ makeDoc(const DocumentTypeRepo &repo, uint32_t i,
idstr << "id:test:test:: " << i;
DocumentId id(idstr.str());
const DocumentType *docType = repo.getDocumentType(doc_type_name);
- auto doc(std::make_unique<Document>(*docType, id));
- doc->setRepo(repo);
+ auto doc(std::make_unique<Document>(repo, *docType, id));
if (!titleString.empty()) {
setFieldValue(*doc, title, titleString);
}
diff --git a/searchlib/src/tests/attribute/attribute_test.cpp b/searchlib/src/tests/attribute/attribute_test.cpp
index 16b5ef78951..f336742ca4b 100644
--- a/searchlib/src/tests/attribute/attribute_test.cpp
+++ b/searchlib/src/tests/attribute/attribute_test.cpp
@@ -912,8 +912,8 @@ AttributeTest::testSingle()
cfg.setFastSearch(true);
AttributePtr ptr = createAttribute("sv-post-int32", cfg);
ptr->updateStat(true);
- EXPECT_EQ(887756u, ptr->getStatus().getAllocated());
- EXPECT_EQ(656444u, ptr->getStatus().getUsed());
+ EXPECT_EQ(347084u, ptr->getStatus().getAllocated());
+ EXPECT_EQ(101852u, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testSingle<IntegerAttribute, AttributeVector::largeint_t, int32_t>(ptr, values);
}
@@ -934,8 +934,8 @@ AttributeTest::testSingle()
cfg.setFastSearch(true);
AttributePtr ptr = createAttribute("sv-post-float", cfg);
ptr->updateStat(true);
- EXPECT_EQ(887756u, ptr->getStatus().getAllocated());
- EXPECT_EQ(656444u, ptr->getStatus().getUsed());
+ EXPECT_EQ(347084u, ptr->getStatus().getAllocated());
+ EXPECT_EQ(101852u, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testSingle<FloatingPointAttribute, double, float>(ptr, values);
}
@@ -947,8 +947,8 @@ AttributeTest::testSingle()
{
AttributePtr ptr = createAttribute("sv-string", Config(BasicType::STRING, CollectionType::SINGLE));
ptr->updateStat(true);
- EXPECT_EQ(403552u, ptr->getStatus().getAllocated());
- EXPECT_EQ(328576u, ptr->getStatus().getUsed());
+ EXPECT_EQ(133216u, ptr->getStatus().getAllocated());
+ EXPECT_EQ(53280u, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testSingle<StringAttribute, string, string>(ptr, values);
}
@@ -957,8 +957,8 @@ AttributeTest::testSingle()
cfg.setFastSearch(true);
AttributePtr ptr = createAttribute("sv-fs-string", cfg);
ptr->updateStat(true);
- EXPECT_EQ(902256u, ptr->getStatus().getAllocated());
- EXPECT_EQ(657088u, ptr->getStatus().getUsed());
+ EXPECT_EQ(361584u, ptr->getStatus().getAllocated());
+ EXPECT_EQ(105216u, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testSingle<StringAttribute, string, string>(ptr, values);
}
@@ -1089,8 +1089,8 @@ AttributeTest::testArray()
{
AttributePtr ptr = createAttribute("a-int32", Config(BasicType::INT32, CollectionType::ARRAY));
ptr->updateStat(true);
- EXPECT_EQ(1474480u, ptr->getStatus().getAllocated());
- EXPECT_EQ(1462192u, ptr->getStatus().getUsed());
+ EXPECT_EQ(528304u, ptr->getStatus().getAllocated());
+ EXPECT_EQ(512576u, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testArray<IntegerAttribute, AttributeVector::largeint_t>(ptr, values);
}
@@ -1099,8 +1099,8 @@ AttributeTest::testArray()
cfg.setFastSearch(true);
AttributePtr ptr = createAttribute("flags", cfg);
ptr->updateStat(true);
- EXPECT_EQ(1474480u, ptr->getStatus().getAllocated());
- EXPECT_EQ(1462192u, ptr->getStatus().getUsed());
+ EXPECT_EQ(528304u, ptr->getStatus().getAllocated());
+ EXPECT_EQ(512576u, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testArray<IntegerAttribute, AttributeVector::largeint_t>(ptr, values);
}
@@ -1109,8 +1109,8 @@ AttributeTest::testArray()
cfg.setFastSearch(true);
AttributePtr ptr = createAttribute("a-fs-int32", cfg);
ptr->updateStat(true);
- EXPECT_EQ(2371884u, ptr->getStatus().getAllocated());
- EXPECT_EQ(2118656u, ptr->getStatus().getUsed());
+ EXPECT_EQ(885036u, ptr->getStatus().getAllocated());
+ EXPECT_EQ(614448u, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testArray<IntegerAttribute, AttributeVector::largeint_t>(ptr, values);
}
@@ -1128,8 +1128,8 @@ AttributeTest::testArray()
cfg.setFastSearch(true);
AttributePtr ptr = createAttribute("a-fs-float", cfg);
ptr->updateStat(true);
- EXPECT_EQ(2371884u, ptr->getStatus().getAllocated());
- EXPECT_EQ(2118656u, ptr->getStatus().getUsed());
+ EXPECT_EQ(885036u, ptr->getStatus().getAllocated());
+ EXPECT_EQ(614448u, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testArray<FloatingPointAttribute, double>(ptr, values);
}
@@ -1140,8 +1140,8 @@ AttributeTest::testArray()
{
AttributePtr ptr = createAttribute("a-string", Config(BasicType::STRING, CollectionType::ARRAY));
ptr->updateStat(true);
- EXPECT_EQ(1865744u, ptr->getStatus().getAllocated());
- EXPECT_EQ(1790768u, ptr->getStatus().getUsed());
+ EXPECT_EQ(649232u, ptr->getStatus().getAllocated());
+ EXPECT_EQ(565856u, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testArray<StringAttribute, string>(ptr, values);
}
@@ -1150,8 +1150,8 @@ AttributeTest::testArray()
cfg.setFastSearch(true);
AttributePtr ptr = createAttribute("afs-string", cfg);
ptr->updateStat(true);
- EXPECT_EQ(2386384u, ptr->getStatus().getAllocated());
- EXPECT_EQ(2119300u, ptr->getStatus().getUsed());
+ EXPECT_EQ(899536u, ptr->getStatus().getAllocated());
+ EXPECT_EQ(617812u, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testArray<StringAttribute, string>(ptr, values);
}
diff --git a/searchlib/src/tests/attribute/postinglist/postinglist.cpp b/searchlib/src/tests/attribute/postinglist/postinglist.cpp
index 7d2a89b6e5b..39e31b23498 100644
--- a/searchlib/src/tests/attribute/postinglist/postinglist.cpp
+++ b/searchlib/src/tests/attribute/postinglist/postinglist.cpp
@@ -581,21 +581,15 @@ AttributePostingListTest::doCompactEnumStore(Tree &tree,
TreeManager &treeMgr,
ValueHandle &valueHandle)
{
- LOG(info,
- "doCompactEnumStore start");
+ LOG(info,"doCompactEnumStore start");
Tree::Iterator i = tree.begin(treeMgr);
- uint32_t numBuffers = valueHandle.getNumBuffers();
std::vector<uint32_t> toHold;
+ valueHandle.for_each_active_buffer([&toHold](uint32_t buffer_id, const vespalib::datastore::BufferState &) {
+ toHold.push_back(buffer_id);
+ });
- for (uint32_t bufferId = 0; bufferId < numBuffers; ++bufferId) {
- vespalib::datastore::BufferState &state = valueHandle.getBufferState(bufferId);
- if (state.isActive()) {
- toHold.push_back(bufferId);
- // Freelists already disabled due to variable sized data
- }
- }
valueHandle.switch_primary_buffer(0, 0u);
for (; i.valid(); ++i)
diff --git a/searchlib/src/tests/docstore/document_store_visitor/document_store_visitor_test.cpp b/searchlib/src/tests/docstore/document_store_visitor/document_store_visitor_test.cpp
index efe858c016a..e841e334215 100644
--- a/searchlib/src/tests/docstore/document_store_visitor/document_store_visitor_test.cpp
+++ b/searchlib/src/tests/docstore/document_store_visitor/document_store_visitor_test.cpp
@@ -60,7 +60,7 @@ makeDoc(const DocumentTypeRepo &repo, uint32_t i, bool before)
idstr << "id:test:test:: " << i;
DocumentId id(idstr.str());
const DocumentType *docType = repo.getDocumentType(doc_type_name);
- Document::UP doc(new Document(*docType, id));
+ Document::UP doc(new Document(repo, *docType, id));
ASSERT_TRUE(doc.get());
asciistream mainstr;
mainstr << "static text" << i << " body something";
diff --git a/searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp b/searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp
index 414e06bd464..580fd199806 100644
--- a/searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp
+++ b/searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp
@@ -426,7 +426,7 @@ makeDoc(const DocumentTypeRepo &repo, uint32_t i, bool extra_field, size_t numRe
idstr << "id:test:test:: " << i;
DocumentId id(idstr.str());
const DocumentType *docType = repo.getDocumentType(doc_type_name);
- Document::UP doc(new Document(*docType, id));
+ Document::UP doc(new Document(repo, *docType, id));
ASSERT_TRUE(doc.get());
asciistream mainstr;
mainstr << "static text" << i << " body something";
diff --git a/searchlib/src/tests/memoryindex/memory_index/memory_index_test.cpp b/searchlib/src/tests/memoryindex/memory_index/memory_index_test.cpp
index 1b1c1181666..8073fb8d232 100644
--- a/searchlib/src/tests/memoryindex/memory_index/memory_index_test.cpp
+++ b/searchlib/src/tests/memoryindex/memory_index/memory_index_test.cpp
@@ -462,8 +462,8 @@ TEST(MemoryIndexTest, require_that_num_docs_and_doc_id_limit_is_returned)
TEST(MemoryIndexTest, require_that_we_understand_the_memory_footprint)
{
- constexpr size_t BASE_ALLOCATED = 1172040u;
- constexpr size_t BASE_USED = 984116u;
+ constexpr size_t BASE_ALLOCATED = 361032u;
+ constexpr size_t BASE_USED = 151188u;
{
MySetup setup;
Index index(setup);
diff --git a/searchlib/src/tests/predicate/document_features_store_test.cpp b/searchlib/src/tests/predicate/document_features_store_test.cpp
index c37fe2739ca..4ac4bdc32f0 100644
--- a/searchlib/src/tests/predicate/document_features_store_test.cpp
+++ b/searchlib/src/tests/predicate/document_features_store_test.cpp
@@ -165,17 +165,17 @@ TEST("require that both features and ranges are removed by 'remove'") {
TEST("require that both features and ranges counts towards memory usage") {
DocumentFeaturesStore features_store(10);
- EXPECT_EQUAL(328152u, features_store.getMemoryUsage().usedBytes());
+ EXPECT_EQUAL(50136u, features_store.getMemoryUsage().usedBytes());
PredicateTreeAnnotations annotations;
annotations.features.push_back(PredicateHash::hash64("foo=100-199"));
features_store.insert(annotations, doc_id);
- EXPECT_EQUAL(328160u, features_store.getMemoryUsage().usedBytes());
+ EXPECT_EQUAL(50144u, features_store.getMemoryUsage().usedBytes());
annotations.features.clear();
annotations.range_features.push_back({"foo", 100, 199});
features_store.insert(annotations, doc_id + 1);
- EXPECT_EQUAL(328256u, features_store.getMemoryUsage().usedBytes());
+ EXPECT_EQUAL(50240u, features_store.getMemoryUsage().usedBytes());
}
TEST("require that DocumentFeaturesStore can be serialized") {
@@ -205,17 +205,17 @@ TEST("require that serialization cleans up wordstore") {
PredicateTreeAnnotations annotations;
annotations.range_features.push_back({"foo", 100, 199});
features_store.insert(annotations, doc_id);
- EXPECT_EQUAL(328248u, features_store.getMemoryUsage().usedBytes());
+ EXPECT_EQUAL(50232u, features_store.getMemoryUsage().usedBytes());
annotations.range_features.push_back({"bar", 100, 199});
features_store.insert(annotations, doc_id + 1);
- EXPECT_EQUAL(328636u, features_store.getMemoryUsage().usedBytes());
+ EXPECT_EQUAL(50620u, features_store.getMemoryUsage().usedBytes());
features_store.remove(doc_id + 1);
- EXPECT_EQUAL(328588u, features_store.getMemoryUsage().usedBytes());
+ EXPECT_EQUAL(50572u, features_store.getMemoryUsage().usedBytes());
vespalib::DataBuffer buffer;
features_store.serialize(buffer);
DocumentFeaturesStore features_store2(buffer);
- EXPECT_EQUAL(328248u, features_store2.getMemoryUsage().usedBytes());
+ EXPECT_EQUAL(50232u, features_store2.getMemoryUsage().usedBytes());
}
diff --git a/searchlib/src/vespa/searchlib/attribute/postingstore.cpp b/searchlib/src/vespa/searchlib/attribute/postingstore.cpp
index 2aa05e7fa9f..94720212faf 100644
--- a/searchlib/src/vespa/searchlib/attribute/postingstore.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/postingstore.cpp
@@ -727,13 +727,12 @@ template <typename DataT>
void
PostingStore<DataT>::compact_worst_buffers(CompactionSpec compaction_spec, const CompactionStrategy& compaction_strategy)
{
-
auto compacting_buffers = this->start_compact_worst_buffers(compaction_spec, compaction_strategy);
bool compact_btree_roots = false;
auto filter = compacting_buffers->make_entry_ref_filter();
// Start with looking at buffers being compacted
for (uint32_t buffer_id : compacting_buffers->get_buffer_ids()) {
- if (isBTree(_store.getBufferState(buffer_id).getTypeId())) {
+ if (isBTree(_store.getBufferMeta(buffer_id).getTypeId())) {
compact_btree_roots = true;
}
}
diff --git a/searchlib/src/vespa/searchlib/test/doc_builder.cpp b/searchlib/src/vespa/searchlib/test/doc_builder.cpp
index 2097cd53b2c..3950a28bea7 100644
--- a/searchlib/src/vespa/searchlib/test/doc_builder.cpp
+++ b/searchlib/src/vespa/searchlib/test/doc_builder.cpp
@@ -59,8 +59,7 @@ DocBuilder::~DocBuilder() = default;
std::unique_ptr<Document>
DocBuilder::make_document(vespalib::string document_id)
{
- auto doc = std::make_unique<Document>(get_document_type(), DocumentId(document_id));
- doc->setRepo(get_repo());
+ auto doc = std::make_unique<Document>(get_repo(), get_document_type(), DocumentId(document_id));
return doc;
}
diff --git a/searchsummary/src/tests/docsummary/document_id_dfw/document_id_dfw_test.cpp b/searchsummary/src/tests/docsummary/document_id_dfw/document_id_dfw_test.cpp
index 7e54f35ff38..8dfdd1877f1 100644
--- a/searchsummary/src/tests/docsummary/document_id_dfw/document_id_dfw_test.cpp
+++ b/searchsummary/src/tests/docsummary/document_id_dfw/document_id_dfw_test.cpp
@@ -95,8 +95,7 @@ DocumentIdDFWTest::~DocumentIdDFWTest() = default;
std::unique_ptr<IDocsumStoreDocument>
DocumentIdDFWTest::make_docsum_store_document(const vespalib::string& id)
{
- auto doc = std::make_unique<Document>(*_document_type, DocumentId(id));
- doc->setRepo(*_repo);
+ auto doc = std::make_unique<Document>(*_repo, *_document_type, DocumentId(id));
return std::make_unique<DocsumStoreDocument>(std::move(doc));
}
diff --git a/searchsummary/src/tests/docsummary/matched_elements_filter/matched_elements_filter_test.cpp b/searchsummary/src/tests/docsummary/matched_elements_filter/matched_elements_filter_test.cpp
index 7eb634f5609..7b83dbe2c4e 100644
--- a/searchsummary/src/tests/docsummary/matched_elements_filter/matched_elements_filter_test.cpp
+++ b/searchsummary/src/tests/docsummary/matched_elements_filter/matched_elements_filter_test.cpp
@@ -102,7 +102,7 @@ public:
}
~DocsumStore();
std::unique_ptr<IDocsumStoreDocument> getMappedDocsum() {
- auto doc = std::make_unique<Document>(_doc_type, DocumentId("id:test:test::0"));
+ auto doc = Document::make_without_repo(_doc_type, DocumentId("id:test:test::0"));
{
ArrayFieldValue array_value(_array_type);
if (!_empty_values) {
diff --git a/searchsummary/src/tests/docsummary/slime_summary/slime_summary_test.cpp b/searchsummary/src/tests/docsummary/slime_summary/slime_summary_test.cpp
index 93f87d9c5be..7077f707247 100644
--- a/searchsummary/src/tests/docsummary/slime_summary/slime_summary_test.cpp
+++ b/searchsummary/src/tests/docsummary/slime_summary/slime_summary_test.cpp
@@ -68,7 +68,7 @@ struct SlimeSummaryTest : testing::Test, IDocsumStore, GetDocsumsStateCallback {
if (empty_get_mapped_docsum) {
return std::make_unique<DocsumStoreDocument>(std::unique_ptr<Document>());
}
- auto doc = std::make_unique<Document>(doc_type, DocumentId("id:test:test::0"));
+ auto doc = Document::make_without_repo(doc_type, DocumentId("id:test:test::0"));
doc->setValue("int_field", IntFieldValue(4));
doc->setValue("short_field", ShortFieldValue(2));
doc->setValue("byte_field", ByteFieldValue(1));
diff --git a/storage/src/tests/bucketdb/bucketmanagertest.cpp b/storage/src/tests/bucketdb/bucketmanagertest.cpp
index dc33bfd04e2..ea3a782d432 100644
--- a/storage/src/tests/bucketdb/bucketmanagertest.cpp
+++ b/storage/src/tests/bucketdb/bucketmanagertest.cpp
@@ -171,7 +171,7 @@ void BucketManagerTest::setupTestEnvironment(bool fakePersistenceLayer,
}
// Generate a doc to use for testing..
const DocumentType &type(*_node->getTypeRepo()->getDocumentType("text/html"));
- _document = std::make_shared<document::Document>(type, document::DocumentId("id:ns:text/html::ntnu"));
+ _document = std::make_shared<document::Document>(*_node->getTypeRepo(), type, document::DocumentId("id:ns:text/html::ntnu"));
}
void BucketManagerTest::addBucketsToDB(uint32_t count)
diff --git a/storage/src/tests/distributor/bucketdatabasetest.cpp b/storage/src/tests/distributor/bucketdatabasetest.cpp
index 661fd7fee72..fcc64e0cccf 100644
--- a/storage/src/tests/distributor/bucketdatabasetest.cpp
+++ b/storage/src/tests/distributor/bucketdatabasetest.cpp
@@ -87,7 +87,7 @@ struct ListAllProcessor : public BucketDatabase::EntryProcessor {
std::string dump_db(const BucketDatabase& db) {
ListAllProcessor proc;
- db.forEach(proc, document::BucketId());
+ db.for_each_upper_bound(proc, document::BucketId());
return proc.ost.str();
}
@@ -122,41 +122,70 @@ TEST_P(BucketDatabaseTest, iterating) {
{
ListAllProcessor proc;
- db().forEach(proc, document::BucketId());
-
- EXPECT_EQ(
- std::string(
- "BucketId(0x4000000000000010) : "
- "node(idx=1,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n"
- "BucketId(0x400000000000002a) : "
- "node(idx=3,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n"
- "BucketId(0x400000000000000b) : "
- "node(idx=2,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n"),
- proc.ost.str());
+ db().for_each_upper_bound(proc, document::BucketId());
+
+ EXPECT_EQ("BucketId(0x4000000000000010) : "
+ "node(idx=1,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n"
+ "BucketId(0x400000000000002a) : "
+ "node(idx=3,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n"
+ "BucketId(0x400000000000000b) : "
+ "node(idx=2,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n",
+ proc.ost.str());
}
{
ListAllProcessor proc;
- db().forEach(proc, document::BucketId(16, 0x2a));
+ db().for_each_lower_bound(proc, document::BucketId()); // lbound (in practice) equal to ubound when starting at zero
+
+ EXPECT_EQ("BucketId(0x4000000000000010) : "
+ "node(idx=1,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n"
+ "BucketId(0x400000000000002a) : "
+ "node(idx=3,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n"
+ "BucketId(0x400000000000000b) : "
+ "node(idx=2,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n",
+ proc.ost.str());
+ }
+
+ {
+ ListAllProcessor proc;
+ db().for_each_upper_bound(proc, document::BucketId(16, 0x2a));
+
+ EXPECT_EQ("BucketId(0x400000000000000b) : "
+ "node(idx=2,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n",
+ proc.ost.str());
+ }
+
+ {
+ ListAllProcessor proc;
+ db().for_each_lower_bound(proc, document::BucketId(16, 0x2a));
+ // Includes 0x2a
+ EXPECT_EQ("BucketId(0x400000000000002a) : "
+ "node(idx=3,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n"
+ "BucketId(0x400000000000000b) : "
+ "node(idx=2,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n",
+ proc.ost.str());
+ }
- EXPECT_EQ(
- std::string(
- "BucketId(0x400000000000000b) : "
- "node(idx=2,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n"),
- proc.ost.str());
+ {
+ StoppingProcessor proc;
+ db().for_each_upper_bound(proc, document::BucketId());
+
+ EXPECT_EQ("BucketId(0x4000000000000010) : "
+ "node(idx=1,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n"
+ "BucketId(0x400000000000002a) : "
+ "node(idx=3,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n",
+ proc.ost.str());
}
{
StoppingProcessor proc;
- db().forEach(proc, document::BucketId());
-
- EXPECT_EQ(
- std::string(
- "BucketId(0x4000000000000010) : "
- "node(idx=1,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n"
- "BucketId(0x400000000000002a) : "
- "node(idx=3,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n"),
- proc.ost.str());
+ db().for_each_lower_bound(proc, document::BucketId());
+
+ EXPECT_EQ("BucketId(0x4000000000000010) : "
+ "node(idx=1,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n"
+ "BucketId(0x400000000000002a) : "
+ "node(idx=3,crc=0x0,docs=0/0,bytes=1/1,trusted=false,active=false,ready=false)\n",
+ proc.ost.str());
}
}
@@ -761,7 +790,7 @@ TEST_P(BucketDatabaseTest, DISABLED_benchmark_const_iteration) {
auto elapsed = vespalib::BenchmarkTimer::benchmark([&] {
DummyProcessor proc;
- db().forEach(proc, document::BucketId());
+ db().for_each_upper_bound(proc, document::BucketId());
}, 5);
fprintf(stderr, "Full DB iteration of %s takes %g seconds\n",
db().toString(false).c_str(), elapsed);
diff --git a/storage/src/tests/distributor/getoperationtest.cpp b/storage/src/tests/distributor/getoperationtest.cpp
index 8d188f6c005..36a1495579f 100644
--- a/storage/src/tests/distributor/getoperationtest.cpp
+++ b/storage/src/tests/distributor/getoperationtest.cpp
@@ -85,7 +85,7 @@ struct GetOperationTest : Test, DistributorStripeTestUtil {
if (!authorVal.empty()) {
const document::DocumentType* type(_repo->getDocumentType("text/html"));
- doc = std::make_unique<document::Document>(*type, docId);
+ doc = std::make_unique<document::Document>(*_repo, *type, docId);
doc->setValue(doc->getField("author"),
document::StringFieldValue(authorVal));
diff --git a/storage/src/tests/distributor/putoperationtest.cpp b/storage/src/tests/distributor/putoperationtest.cpp
index 735666e5c89..2a3f06b1e8c 100644
--- a/storage/src/tests/distributor/putoperationtest.cpp
+++ b/storage/src/tests/distributor/putoperationtest.cpp
@@ -83,8 +83,12 @@ public:
return *_testDocMan.getTypeRepo().getDocumentType("testdoctype1");
}
+ const document::DocumentTypeRepo& type_repo() const {
+ return _testDocMan.getTypeRepo();
+ }
+
Document::SP createDummyDocument(const char* ns, const char* id) const {
- return std::make_shared<Document>(doc_type(), DocumentId(vespalib::make_string("id:%s:testdoctype1::%s", ns, id)));
+ return std::make_shared<Document>(type_repo(), doc_type(), DocumentId(vespalib::make_string("id:%s:testdoctype1::%s", ns, id)));
}
static std::shared_ptr<api::PutCommand> createPut(Document::SP doc) {
@@ -98,7 +102,7 @@ PutOperationTest::~PutOperationTest() = default;
document::BucketId
PutOperationTest::createAndSendSampleDocument(vespalib::duration timeout) {
- auto doc = std::make_shared<Document>(doc_type(), DocumentId("id:test:testdoctype1::"));
+ auto doc = std::make_shared<Document>(type_repo(), doc_type(), DocumentId("id:test:testdoctype1::"));
document::BucketId id = operation_context().make_split_bit_constrained_bucket_id(doc->getId());
addIdealNodes(id);
@@ -453,7 +457,7 @@ TEST_F(PutOperationTest, no_storage_nodes) {
TEST_F(PutOperationTest, update_correct_bucket_on_remapped_put) {
setup_stripe(2, 2, "storage:2 distributor:1");
- auto doc = std::make_shared<Document>(doc_type(), DocumentId("id:test:testdoctype1:n=13:uri"));
+ auto doc = std::make_shared<Document>(type_repo(), doc_type(), DocumentId("id:test:testdoctype1:n=13:uri"));
addNodesToBucketDB(document::BucketId(16,13), "0=0,1=0");
sendPut(createPut(doc));
diff --git a/storage/src/tests/distributor/top_level_bucket_db_updater_test.cpp b/storage/src/tests/distributor/top_level_bucket_db_updater_test.cpp
index 7b4f688b253..d5d33a178fe 100644
--- a/storage/src/tests/distributor/top_level_bucket_db_updater_test.cpp
+++ b/storage/src/tests/distributor/top_level_bucket_db_updater_test.cpp
@@ -1697,7 +1697,7 @@ TopLevelBucketDBUpdaterTest::merge_bucket_lists(
BucketDumper dumper_tmp(true);
for (auto* s : distributor_stripes()) {
auto& db = s->getBucketSpaceRepo().get(document::FixedBucketSpaces::default_space()).getBucketDatabase();
- db.forEach(dumper_tmp);
+ db.for_each_upper_bound(dumper_tmp);
}
{
@@ -1717,7 +1717,7 @@ TopLevelBucketDBUpdaterTest::merge_bucket_lists(
BucketDumper dumper(include_bucket_info);
for (auto* s : distributor_stripes()) {
auto& db = s->getBucketSpaceRepo().get(document::FixedBucketSpaces::default_space()).getBucketDatabase();
- db.forEach(dumper);
+ db.for_each_upper_bound(dumper);
db.clear();
}
return dumper.ost.str();
diff --git a/storage/src/tests/distributor/twophaseupdateoperationtest.cpp b/storage/src/tests/distributor/twophaseupdateoperationtest.cpp
index 579fd156962..da32225cde3 100644
--- a/storage/src/tests/distributor/twophaseupdateoperationtest.cpp
+++ b/storage/src/tests/distributor/twophaseupdateoperationtest.cpp
@@ -237,7 +237,7 @@ TwoPhaseUpdateOperationTest::replyToGet(
std::shared_ptr<api::StorageReply> reply;
if (haveDocument) {
- auto doc(std::make_shared<Document>(*_doc_type, DocumentId("id:ns:" + _doc_type->getName() + "::1")));
+ auto doc(std::make_shared<Document>(*_repo, *_doc_type, DocumentId("id:ns:" + _doc_type->getName() + "::1")));
doc->setValue("headerval", IntFieldValue(oldTimestamp));
reply = std::make_shared<api::GetReply>(get, doc, oldTimestamp);
diff --git a/storage/src/tests/persistence/filestorage/filestormanagertest.cpp b/storage/src/tests/persistence/filestorage/filestormanagertest.cpp
index 7f3fe06fc29..4227f3dbe13 100644
--- a/storage/src/tests/persistence/filestorage/filestormanagertest.cpp
+++ b/storage/src/tests/persistence/filestorage/filestormanagertest.cpp
@@ -485,7 +485,7 @@ TEST_F(FileStorManagerTest, flush) {
// Creating a document to test with
document::DocumentId docId("id:ns:testdoctype1::crawler:http://www.ntnu.no/");
- auto doc = std::make_shared<Document>(*_testdoctype1, docId);
+ auto doc = std::make_shared<Document>(*_node->getTypeRepo(), *_testdoctype1, docId);
document::BucketId bid(4000);
static const uint32_t msgCount = 10;
@@ -1032,7 +1032,7 @@ FileStorTestBase::putDoc(DummyStorageLink& top,
document::BucketId bucket(16, factory.getBucketId(docId).getRawId());
//std::cerr << "doc bucket is " << bucket << " vs source " << source << "\n";
_node->getPersistenceProvider().createBucket(makeSpiBucket(target));
- Document::SP doc(new Document(*_testdoctype1, docId));
+ auto doc = std::make_shared<Document>(*_node->getTypeRepo(), *_testdoctype1, docId);
auto cmd = std::make_shared<api::PutCommand>(makeDocumentBucket(target), doc, docNum+1);
cmd->setAddress(_Storage3);
cmd->setPriority(120);
@@ -1073,7 +1073,7 @@ TEST_F(FileStorManagerTest, split_empty_target_with_remapped_ops) {
document::DocumentId docId(
vespalib::make_string("id:ns:testdoctype1:n=%d:1234", 0x100001));
- auto doc = std::make_shared<Document>(*_testdoctype1, docId);
+ auto doc = std::make_shared<Document>(*_node->getTypeRepo(), *_testdoctype1, docId);
auto putCmd = std::make_shared<api::PutCommand>(makeDocumentBucket(source), doc, 1001);
putCmd->setAddress(_Storage3);
putCmd->setPriority(120);
@@ -1399,7 +1399,7 @@ TEST_F(FileStorManagerTest, delete_bucket) {
auto& top = c.top;
// Creating a document to test with
document::DocumentId docId("id:crawler:testdoctype1:n=4000:http://www.ntnu.no/");
- auto doc = std::make_shared<Document>(*_testdoctype1, docId);
+ auto doc = std::make_shared<Document>(*_node->getTypeRepo(), *_testdoctype1, docId);
document::BucketId bid(16, 4000);
createBucket(bid);
@@ -1440,7 +1440,7 @@ TEST_F(FileStorManagerTest, delete_bucket_rejects_outdated_bucket_info) {
auto& top = c.top;
// Creating a document to test with
document::DocumentId docId("id:crawler:testdoctype1:n=4000:http://www.ntnu.no/");
- Document::SP doc(new Document(*_testdoctype1, docId));
+ auto doc = std::make_shared<Document>(*_node->getTypeRepo(), *_testdoctype1, docId);
document::BucketId bid(16, 4000);
createBucket(bid);
@@ -1487,7 +1487,7 @@ TEST_F(FileStorManagerTest, delete_bucket_with_invalid_bucket_info){
auto& top = c.top;
// Creating a document to test with
document::DocumentId docId("id:crawler:testdoctype1:n=4000:http://www.ntnu.no/");
- auto doc = std::make_shared<Document>(*_testdoctype1, docId);
+ auto doc = std::make_shared<Document>(*_node->getTypeRepo(), *_testdoctype1, docId);
document::BucketId bid(16, 4000);
createBucket(bid);
diff --git a/storage/src/tests/storageserver/documentapiconvertertest.cpp b/storage/src/tests/storageserver/documentapiconvertertest.cpp
index c375443b265..42944c81f13 100644
--- a/storage/src/tests/storageserver/documentapiconvertertest.cpp
+++ b/storage/src/tests/storageserver/documentapiconvertertest.cpp
@@ -106,7 +106,7 @@ struct DocumentApiConverterTest : Test {
};
TEST_F(DocumentApiConverterTest, put) {
- auto doc = std::make_shared<Document>(_html_type, defaultDocId);
+ auto doc = std::make_shared<Document>(*_repo, _html_type, defaultDocId);
documentapi::PutDocumentMessage putmsg(doc);
putmsg.setTimestamp(1234);
@@ -126,7 +126,7 @@ TEST_F(DocumentApiConverterTest, put) {
}
TEST_F(DocumentApiConverterTest, forwarded_put) {
- auto doc = std::make_shared<Document>(_html_type, DocumentId("id:ns:" + _html_type.getName() + "::test"));
+ auto doc = std::make_shared<Document>(*_repo, _html_type, DocumentId("id:ns:" + _html_type.getName() + "::test"));
auto putmsg = std::make_unique<documentapi::PutDocumentMessage>(doc);
auto* putmsg_raw = putmsg.get();
diff --git a/storage/src/tests/storageserver/rpc/storage_api_rpc_service_test.cpp b/storage/src/tests/storageserver/rpc/storage_api_rpc_service_test.cpp
index bfc22b9f1ea..26c5b8df5a5 100644
--- a/storage/src/tests/storageserver/rpc/storage_api_rpc_service_test.cpp
+++ b/storage/src/tests/storageserver/rpc/storage_api_rpc_service_test.cpp
@@ -161,7 +161,7 @@ public:
std::shared_ptr<api::PutCommand> create_dummy_put_command() const {
auto doc_type = _doc_type_repo->getDocumentType("testdoctype1");
- auto doc = std::make_shared<document::Document>(*doc_type, document::DocumentId("id:foo:testdoctype1::bar"));
+ auto doc = std::make_shared<document::Document>(*_doc_type_repo, *doc_type, document::DocumentId("id:foo:testdoctype1::bar"));
doc->setFieldValue(doc->getField("hstringval"), std::make_unique<document::StringFieldValue>("hello world"));
return std::make_shared<api::PutCommand>(makeDocumentBucket(document::BucketId(0)), std::move(doc), 100);
}
diff --git a/storage/src/vespa/storage/bucketdb/btree_bucket_database.cpp b/storage/src/vespa/storage/bucketdb/btree_bucket_database.cpp
index 23421e724a2..baec5494b36 100644
--- a/storage/src/vespa/storage/bucketdb/btree_bucket_database.cpp
+++ b/storage/src/vespa/storage/bucketdb/btree_bucket_database.cpp
@@ -151,9 +151,16 @@ BTreeBucketDatabase::process_update(const document::BucketId& bucket, EntryUpdat
}
// TODO need snapshot read with guarding
-// FIXME semantics of for-each in judy and bit tree DBs differ, former expects lbound, latter ubound..!
-// FIXME but bit-tree code says "lowerBound" in impl and "after" in declaration???
-void BTreeBucketDatabase::forEach(EntryProcessor& proc, const BucketId& after) const {
+void BTreeBucketDatabase::for_each_lower_bound(EntryProcessor& proc, const BucketId& at_or_after) const {
+ for (auto iter = _impl->lower_bound(at_or_after.toKey()); iter.valid(); ++iter) {
+ if (!proc.process(_impl->const_value_ref_from_valid_iterator(iter))) {
+ break;
+ }
+ }
+}
+
+// TODO need snapshot read with guarding
+void BTreeBucketDatabase::for_each_upper_bound(EntryProcessor& proc, const BucketId& after) const {
for (auto iter = _impl->upper_bound(after.toKey()); iter.valid(); ++iter) {
if (!proc.process(_impl->const_value_ref_from_valid_iterator(iter))) {
break;
diff --git a/storage/src/vespa/storage/bucketdb/btree_bucket_database.h b/storage/src/vespa/storage/bucketdb/btree_bucket_database.h
index c20dad13618..3cf77b5444b 100644
--- a/storage/src/vespa/storage/bucketdb/btree_bucket_database.h
+++ b/storage/src/vespa/storage/bucketdb/btree_bucket_database.h
@@ -44,7 +44,8 @@ public:
std::vector<Entry>& entries) const override;
void update(const Entry& newEntry) override;
void process_update(const document::BucketId& bucket, EntryUpdateProcessor &processor, bool create_if_nonexisting) override;
- void forEach(EntryProcessor&, const document::BucketId& after) const override;
+ void for_each_lower_bound(EntryProcessor&, const document::BucketId& at_or_after) const override;
+ void for_each_upper_bound(EntryProcessor&, const document::BucketId& after) const override;
Entry upperBound(const document::BucketId& value) const override;
uint64_t size() const override;
void clear() override;
diff --git a/storage/src/vespa/storage/bucketdb/bucketdatabase.h b/storage/src/vespa/storage/bucketdb/bucketdatabase.h
index d3d9c34c7fc..4e0b727036a 100644
--- a/storage/src/vespa/storage/bucketdb/bucketdatabase.h
+++ b/storage/src/vespa/storage/bucketdb/bucketdatabase.h
@@ -99,9 +99,15 @@ public:
virtual void process_update(const document::BucketId& bucket, EntryUpdateProcessor &processor, bool create_if_nonexisting) = 0;
- virtual void forEach(
- EntryProcessor&,
- const document::BucketId& after = document::BucketId()) const = 0;
+ virtual void for_each_lower_bound(EntryProcessor&, const document::BucketId& at_or_after) const = 0;
+ void for_each_lower_bound(EntryProcessor& proc) const {
+ for_each_lower_bound(proc, document::BucketId());
+ }
+
+ virtual void for_each_upper_bound(EntryProcessor&, const document::BucketId& after) const = 0;
+ void for_each_upper_bound(EntryProcessor& proc) const {
+ for_each_upper_bound(proc, document::BucketId());
+ }
using TrailingInserter = bucketdb::TrailingInserter<Entry>;
using Merger = bucketdb::Merger<Entry>;
diff --git a/storage/src/vespa/storage/distributor/idealstatemanager.cpp b/storage/src/vespa/storage/distributor/idealstatemanager.cpp
index cf255b5ec18..2c33bc490fe 100644
--- a/storage/src/vespa/storage/distributor/idealstatemanager.cpp
+++ b/storage/src/vespa/storage/distributor/idealstatemanager.cpp
@@ -265,7 +265,7 @@ IdealStateManager::getBucketStatus(
void IdealStateManager::dump_bucket_space_db_status(document::BucketSpace bucket_space, std::ostream& out) const {
StatusBucketVisitor proc(*this, bucket_space, out);
auto& distributorBucketSpace = _op_ctx.bucket_space_repo().get(bucket_space);
- distributorBucketSpace.getBucketDatabase().forEach(proc);
+ distributorBucketSpace.getBucketDatabase().for_each_upper_bound(proc);
}
void IdealStateManager::getBucketStatus(std::ostream& out) const {
diff --git a/storage/src/vespa/storage/distributor/operations/external/twophaseupdateoperation.cpp b/storage/src/vespa/storage/distributor/operations/external/twophaseupdateoperation.cpp
index bdf4fa2ba72..515b72520ec 100644
--- a/storage/src/vespa/storage/distributor/operations/external/twophaseupdateoperation.cpp
+++ b/storage/src/vespa/storage/distributor/operations/external/twophaseupdateoperation.cpp
@@ -672,8 +672,7 @@ std::shared_ptr<document::Document>
TwoPhaseUpdateOperation::createBlankDocument() const
{
const document::DocumentUpdate& up(*_updateCmd->getUpdate());
- auto doc = std::make_shared<document::Document>(up.getType(), up.getId());
- doc->setRepo(*up.getRepoPtr());
+ auto doc = std::make_shared<document::Document>(*up.getRepoPtr(), up.getType(), up.getId());
return doc;
}
diff --git a/storage/src/vespa/storage/distributor/operations/external/visitoroperation.cpp b/storage/src/vespa/storage/distributor/operations/external/visitoroperation.cpp
index 9e9196dbee7..ca47ab7478c 100644
--- a/storage/src/vespa/storage/distributor/operations/external/visitoroperation.cpp
+++ b/storage/src/vespa/storage/distributor/operations/external/visitoroperation.cpp
@@ -388,23 +388,19 @@ VisitorOperation::pickBucketsToVisit(const std::vector<BucketDatabase::Entry>& b
std::vector<document::BucketId> bucketVisitOrder;
- for (uint32_t i = 0; i < buckets.size(); ++i) {
- bucketVisitOrder.push_back(buckets[i].getBucketId());
+ for (const auto& bucket : buckets) {
+ bucketVisitOrder.push_back(bucket.getBucketId());
}
VisitorOrder bucketLessThan;
std::sort(bucketVisitOrder.begin(), bucketVisitOrder.end(), bucketLessThan);
- std::vector<document::BucketId>::const_iterator iter(bucketVisitOrder.begin());
- std::vector<document::BucketId>::const_iterator end(bucketVisitOrder.end());
+ auto iter = bucketVisitOrder.begin();
+ auto end = bucketVisitOrder.end();
for (; iter != end; ++iter) {
- if (bucketLessThan(*iter, _lastBucket) ||
- *iter == _lastBucket)
- {
- LOG(spam,
- "Skipping bucket %s because it is lower than or equal to progress bucket %s",
- iter->toString().c_str(),
- _lastBucket.toString().c_str());
+ if (bucketLessThan(*iter, _lastBucket) || *iter == _lastBucket) {
+ LOG(spam, "Skipping bucket %s because it is lower than or equal to progress bucket %s",
+ iter->toString().c_str(), _lastBucket.toString().c_str());
continue;
}
LOG(spam, "Iterating: Found in db: %s", iter->toString().c_str());
@@ -460,11 +456,11 @@ getBucketIdAndLast(BucketDatabase& database,
{
if (!super.contains(last)) {
NextEntryFinder proc(super);
- database.forEach(proc, super);
+ database.for_each_upper_bound(proc, super);
return proc._next;
} else {
NextEntryFinder proc(last);
- database.forEach(proc, last);
+ database.for_each_upper_bound(proc, last);
return proc._next;
}
}
diff --git a/streamingvisitors/src/tests/document/document.cpp b/streamingvisitors/src/tests/document/document.cpp
index 1e97d232a64..acebd9ed4a4 100644
--- a/streamingvisitors/src/tests/document/document.cpp
+++ b/streamingvisitors/src/tests/document/document.cpp
@@ -29,7 +29,7 @@ DocumentTest::testStorageDocument()
dt.addField(fa);
dt.addField(fb);
- document::Document::UP doc(new document::Document(dt, DocumentId()));
+ auto doc = document::Document::make_without_repo(dt, DocumentId());
doc->setValue(fa, StringFieldValue("foo"));
doc->setValue(fb, StringFieldValue("bar"));
diff --git a/streamingvisitors/src/tests/hitcollector/hitcollector_test.cpp b/streamingvisitors/src/tests/hitcollector/hitcollector_test.cpp
index 9715b44b27b..6950c90f097 100644
--- a/streamingvisitors/src/tests/hitcollector/hitcollector_test.cpp
+++ b/streamingvisitors/src/tests/hitcollector/hitcollector_test.cpp
@@ -77,8 +77,8 @@ HitCollectorTest::assertHit(SearchResult::RankType expRank, uint32_t expDocId, u
void
HitCollectorTest::addHit(HitCollector &hc, uint32_t docId, double score, const char *sortData, size_t sortDataSize)
{
- document::Document::UP doc(new document::Document(_docType, DocumentId("id:ns:testdoc::")));
- StorageDocument::UP sdoc(new StorageDocument(std::move(doc), SharedFieldPathMap(), 0));
+ auto doc = document::Document::make_without_repo(_docType, DocumentId("id:ns:testdoc::"));
+ auto sdoc = std::make_unique<StorageDocument>(std::move(doc), SharedFieldPathMap(), 0);
ASSERT_TRUE(sdoc->valid());
MatchData md(MatchData::params());
hc.addHit(sdoc.get(), docId, md, score, sortData, sortDataSize);
diff --git a/streamingvisitors/src/tests/matching_elements_filler/matching_elements_filler_test.cpp b/streamingvisitors/src/tests/matching_elements_filler/matching_elements_filler_test.cpp
index 59e84b7d08c..458031b5f01 100644
--- a/streamingvisitors/src/tests/matching_elements_filler/matching_elements_filler_test.cpp
+++ b/streamingvisitors/src/tests/matching_elements_filler/matching_elements_filler_test.cpp
@@ -211,7 +211,7 @@ MyDocType::make_field_path(vespalib::string path) const
std::unique_ptr<document::Document>
MyDocType::make_test_doc() const
{
- auto doc = std::make_unique<document::Document>(_document_type, DocumentId("id::test::1"));
+ auto doc = document::Document::make_without_repo(_document_type, DocumentId("id::test::1"));
doc->setValue("elem_array", *make_elem_array({{"foo", 10},{"bar", 20},{"baz", 30},{"foo", 40}, {"zap", 20}, {"zap", 20}}));
// the elements in maps are ordered on the key
doc->setValue("elem_map", *make_elem_map({{"@foo", {"foo", 10}}, {"@bar", {"bar", 20}},{"@baz", {"baz", 30}},{"@foo@", {"foo", 40}},{"@zap", {"zap", 20}}, {"@zap@", {"zap", 20}}}));
diff --git a/vespalib/src/tests/btree/btree_test.cpp b/vespalib/src/tests/btree/btree_test.cpp
index ef64549e16a..b8da9ea6042 100644
--- a/vespalib/src/tests/btree/btree_test.cpp
+++ b/vespalib/src/tests/btree/btree_test.cpp
@@ -1064,7 +1064,8 @@ adjustAllocatedBytes(size_t nodeCount, size_t nodeSize)
TEST_F(BTreeTest, require_that_memory_usage_is_calculated)
{
- constexpr size_t BASE = 163912;
+ constexpr size_t BASE_ALLOCATED = 28744u;
+ constexpr size_t BASE_USED = 24984;
typedef BTreeNodeAllocator<int32_t, int8_t,
btree::NoAggregated,
MyTraits::INTERNAL_SLOTS, MyTraits::LEAF_SLOTS> NodeAllocator;
@@ -1083,8 +1084,8 @@ TEST_F(BTreeTest, require_that_memory_usage_is_calculated)
const uint32_t initialLeafNodes = 128u;
mu.incAllocatedBytes(adjustAllocatedBytes(initialInternalNodes, sizeof(INode)));
mu.incAllocatedBytes(adjustAllocatedBytes(initialLeafNodes, sizeof(LNode)));
- mu.incAllocatedBytes(BASE);
- mu.incUsedBytes(BASE);
+ mu.incAllocatedBytes(BASE_ALLOCATED);
+ mu.incUsedBytes(BASE_USED);
mu.incUsedBytes(sizeof(INode));
mu.incDeadBytes(sizeof(INode));
EXPECT_TRUE(assertMemoryUsage(mu, tm.getMemoryUsage()));
@@ -1115,8 +1116,8 @@ TEST_F(BTreeTest, require_that_memory_usage_is_calculated)
mu = vespalib::MemoryUsage();
mu.incAllocatedBytes(adjustAllocatedBytes(initialInternalNodes, sizeof(INode)));
mu.incAllocatedBytes(adjustAllocatedBytes(initialLeafNodes, sizeof(LNode)));
- mu.incAllocatedBytes(BASE);
- mu.incUsedBytes(BASE);
+ mu.incAllocatedBytes(BASE_ALLOCATED);
+ mu.incUsedBytes(BASE_USED);
mu.incUsedBytes(sizeof(INode) * 2);
mu.incDeadBytes(sizeof(INode) * 2);
mu.incUsedBytes(sizeof(LNode));
diff --git a/vespalib/src/tests/datastore/array_store/array_store_test.cpp b/vespalib/src/tests/datastore/array_store/array_store_test.cpp
index 97e1ddb985d..c32554232ef 100644
--- a/vespalib/src/tests/datastore/array_store/array_store_test.cpp
+++ b/vespalib/src/tests/datastore/array_store/array_store_test.cpp
@@ -210,16 +210,16 @@ INSTANTIATE_TEST_SUITE_P(NumberStoreFreeListsDisabledMultiTest,
TEST_P(NumberStoreTest, control_static_sizes) {
#ifdef _LIBCPP_VERSION
- EXPECT_EQ(472u, sizeof(store));
- EXPECT_EQ(296u, sizeof(NumberStoreTest::ArrayStoreType::DataStoreType));
+ EXPECT_EQ(464u, sizeof(store));
+ EXPECT_EQ(280u, sizeof(NumberStoreTest::ArrayStoreType::DataStoreType));
#else
- EXPECT_EQ(504u, sizeof(store));
- EXPECT_EQ(328u, sizeof(NumberStoreTest::ArrayStoreType::DataStoreType));
+ EXPECT_EQ(496u, sizeof(store));
+ EXPECT_EQ(320u, sizeof(NumberStoreTest::ArrayStoreType::DataStoreType));
#endif
EXPECT_EQ(112u, sizeof(NumberStoreTest::ArrayStoreType::SmallBufferType));
MemoryUsage usage = store.getMemoryUsage();
- EXPECT_EQ(1312160u, usage.allocatedBytes());
- EXPECT_EQ(1311232u, usage.usedBytes());
+ EXPECT_EQ(202144u, usage.allocatedBytes());
+ EXPECT_EQ(197776u, usage.usedBytes());
}
TEST_P(NumberStoreTest, add_and_get_small_arrays_of_trivial_type)
diff --git a/vespalib/src/tests/datastore/datastore/datastore_test.cpp b/vespalib/src/tests/datastore/datastore/datastore_test.cpp
index 794be39ae9b..7121bf5ce11 100644
--- a/vespalib/src/tests/datastore/datastore/datastore_test.cpp
+++ b/vespalib/src/tests/datastore/datastore/datastore_test.cpp
@@ -474,7 +474,8 @@ TEST(DataStoreTest, require_that_memory_stats_are_calculated)
TEST(DataStoreTest, require_that_memory_usage_is_calculated)
{
- constexpr size_t BASE = 676;
+ constexpr size_t BASE_ALLOCATED = 4228;
+ constexpr size_t BASE_USED = 308;
MyStore s;
MyRef r = s.addEntry(10);
s.addEntry(20);
@@ -483,8 +484,8 @@ TEST(DataStoreTest, require_that_memory_usage_is_calculated)
s.holdBuffer(r.bufferId());
s.assign_generation(100);
vespalib::MemoryUsage m = s.getMemoryUsage();
- EXPECT_EQ(MyRef::offsetSize() * sizeof(int) + BASE, m.allocatedBytes());
- EXPECT_EQ(5 * sizeof(int) + BASE, m.usedBytes());
+ EXPECT_EQ(MyRef::offsetSize() * sizeof(int) + BASE_ALLOCATED, m.allocatedBytes());
+ EXPECT_EQ(5 * sizeof(int) + BASE_USED, m.usedBytes());
EXPECT_EQ(0 * sizeof(int), m.deadBytes());
EXPECT_EQ(5 * sizeof(int), m.allocatedBytesOnHold());
s.reclaim_memory(101);
@@ -492,28 +493,29 @@ TEST(DataStoreTest, require_that_memory_usage_is_calculated)
TEST(DataStoreTest, require_that_we_can_disable_elemement_hold_list)
{
- constexpr size_t BASE = 676;
+ constexpr size_t BASE_ALLOCATED = 4228;
+ constexpr size_t BASE_USED = 308;
MyStore s;
MyRef r1 = s.addEntry(10);
MyRef r2 = s.addEntry(20);
MyRef r3 = s.addEntry(30);
(void) r3;
vespalib::MemoryUsage m = s.getMemoryUsage();
- EXPECT_EQ(MyRef::offsetSize() * sizeof(int) + BASE, m.allocatedBytes());
- EXPECT_EQ(4 * sizeof(int) + BASE, m.usedBytes());
+ EXPECT_EQ(MyRef::offsetSize() * sizeof(int) + BASE_ALLOCATED, m.allocatedBytes());
+ EXPECT_EQ(4 * sizeof(int) + BASE_USED, m.usedBytes());
EXPECT_EQ(1 * sizeof(int), m.deadBytes());
EXPECT_EQ(0 * sizeof(int), m.allocatedBytesOnHold());
s.holdElem(r1, 1);
m = s.getMemoryUsage();
- EXPECT_EQ(MyRef::offsetSize() * sizeof(int) + BASE, m.allocatedBytes());
- EXPECT_EQ(4 * sizeof(int) + BASE, m.usedBytes());
+ EXPECT_EQ(MyRef::offsetSize() * sizeof(int) + BASE_ALLOCATED, m.allocatedBytes());
+ EXPECT_EQ(4 * sizeof(int) + BASE_USED, m.usedBytes());
EXPECT_EQ(1 * sizeof(int), m.deadBytes());
EXPECT_EQ(1 * sizeof(int), m.allocatedBytesOnHold());
s.disableElemHoldList();
s.holdElem(r2, 1);
m = s.getMemoryUsage();
- EXPECT_EQ(MyRef::offsetSize() * sizeof(int) + BASE, m.allocatedBytes());
- EXPECT_EQ(4 * sizeof(int) + BASE, m.usedBytes());
+ EXPECT_EQ(MyRef::offsetSize() * sizeof(int) + BASE_ALLOCATED, m.allocatedBytes());
+ EXPECT_EQ(4 * sizeof(int) + BASE_USED, m.usedBytes());
EXPECT_EQ(2 * sizeof(int), m.deadBytes());
EXPECT_EQ(1 * sizeof(int), m.allocatedBytesOnHold());
s.assign_generation(100);
@@ -538,7 +540,7 @@ void assertGrowStats(GrowthStats expSizes,
TEST(DataStoreTest, require_that_buffer_growth_works)
{
- constexpr size_t BASE = 41032u;
+ constexpr size_t BASE = 10312;
// Always switch to new buffer, min size 4
assertGrowStats({ 4, 4, 4, 4, 8, 16, 16, 32, 64, 64 },
{ 4 }, 20 + BASE, 4, 0);
diff --git a/vespalib/src/tests/datastore/unique_store/unique_store_test.cpp b/vespalib/src/tests/datastore/unique_store/unique_store_test.cpp
index cf62d238d53..1781a680bac 100644
--- a/vespalib/src/tests/datastore/unique_store/unique_store_test.cpp
+++ b/vespalib/src/tests/datastore/unique_store/unique_store_test.cpp
@@ -470,14 +470,14 @@ TEST_F(DoubleTest, nan_is_handled)
}
TEST_F(DoubleTest, control_memory_usage) {
- EXPECT_EQ(464, sizeof(store));
+ EXPECT_EQ(456u, sizeof(store));
EXPECT_EQ(144u, sizeof(BufferState));
- EXPECT_EQ(163908u, store.get_values_memory_usage().allocatedBytes());
- EXPECT_EQ(163892u, store.get_values_memory_usage().usedBytes());
- EXPECT_EQ(262120u, store.get_dictionary_memory_usage().allocatedBytes());
- EXPECT_EQ(164176u, store.get_dictionary_memory_usage().usedBytes());
- EXPECT_EQ(426028u, store.getMemoryUsage().allocatedBytes());
- EXPECT_EQ(328068u, store.getMemoryUsage().usedBytes());
+ EXPECT_EQ(28740u, store.get_values_memory_usage().allocatedBytes());
+ EXPECT_EQ(24804u, store.get_values_memory_usage().usedBytes());
+ EXPECT_EQ(126952u, store.get_dictionary_memory_usage().allocatedBytes());
+ EXPECT_EQ(25248u, store.get_dictionary_memory_usage().usedBytes());
+ EXPECT_EQ(155692u, store.getMemoryUsage().allocatedBytes());
+ EXPECT_EQ(50052, store.getMemoryUsage().usedBytes());
}
GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/vespalib/src/vespa/vespalib/datastore/array_store.h b/vespalib/src/vespa/vespalib/datastore/array_store.h
index dd786e5f2e2..c2b65d72f03 100644
--- a/vespalib/src/vespa/vespalib/datastore/array_store.h
+++ b/vespalib/src/vespa/vespalib/datastore/array_store.h
@@ -76,10 +76,9 @@ public:
return ConstArrayRef();
}
RefT internalRef(ref);
- uint32_t typeId = _store.getTypeId(internalRef.bufferId());
- if (typeId != _largeArrayTypeId) [[likely]] {
- size_t arraySize = _mapper.get_array_size(typeId);
- return getSmallArray(internalRef, arraySize);
+ const BufferAndMeta & bufferAndMeta = _store.getBufferMeta(internalRef.bufferId());
+ if (bufferAndMeta.getTypeId() != _largeArrayTypeId) [[likely]] {
+ return getSmallArray(internalRef, bufferAndMeta.getArraySize());
} else {
return getLargeArray(internalRef);
}
diff --git a/vespalib/src/vespa/vespalib/datastore/buffer_free_list.cpp b/vespalib/src/vespa/vespalib/datastore/buffer_free_list.cpp
index 0a440e3e867..224ed4b0c8f 100644
--- a/vespalib/src/vespa/vespalib/datastore/buffer_free_list.cpp
+++ b/vespalib/src/vespa/vespalib/datastore/buffer_free_list.cpp
@@ -52,5 +52,23 @@ BufferFreeList::disable()
_free_list = nullptr;
}
+void
+BufferFreeList::push_entry(EntryRef ref) {
+ if (empty()) {
+ attach();
+ }
+ _free_refs.push_back(ref);
+}
+EntryRef
+BufferFreeList::pop_entry() {
+ EntryRef ret = _free_refs.back();
+ _free_refs.pop_back();
+ if (empty()) {
+ detach();
+ }
+ _dead_elems.store(_dead_elems.load(std::memory_order_relaxed) - _array_size, std::memory_order_relaxed);
+ return ret;
+}
+
}
diff --git a/vespalib/src/vespa/vespalib/datastore/buffer_free_list.h b/vespalib/src/vespa/vespalib/datastore/buffer_free_list.h
index 74fd47056de..148ddd8db88 100644
--- a/vespalib/src/vespa/vespalib/datastore/buffer_free_list.h
+++ b/vespalib/src/vespa/vespalib/datastore/buffer_free_list.h
@@ -41,21 +41,8 @@ public:
bool enabled() const { return _free_list != nullptr; }
bool empty() const { return _free_refs.empty(); }
uint32_t array_size() const { return _array_size; }
- void push_entry(EntryRef ref) {
- if (empty()) {
- attach();
- }
- _free_refs.push_back(ref);
- }
- EntryRef pop_entry() {
- EntryRef ret = _free_refs.back();
- _free_refs.pop_back();
- if (empty()) {
- detach();
- }
- _dead_elems.store(_dead_elems.load(std::memory_order_relaxed) - _array_size, std::memory_order_relaxed);
- return ret;
- }
+ void push_entry(EntryRef ref);
+ EntryRef pop_entry();
};
}
diff --git a/vespalib/src/vespa/vespalib/datastore/bufferstate.cpp b/vespalib/src/vespa/vespalib/datastore/bufferstate.cpp
index 45a94693eeb..47fba1ef697 100644
--- a/vespalib/src/vespa/vespalib/datastore/bufferstate.cpp
+++ b/vespalib/src/vespa/vespalib/datastore/bufferstate.cpp
@@ -171,7 +171,7 @@ BufferState::dropBuffer(uint32_t buffer_id, std::atomic<void*>& buffer)
}
void
-BufferState::disableElemHoldList()
+BufferState::disable_elem_hold_list()
{
_disableElemHoldList = true;
}
diff --git a/vespalib/src/vespa/vespalib/datastore/bufferstate.h b/vespalib/src/vespa/vespalib/datastore/bufferstate.h
index aa7f6dfdfa4..c3e6110cc52 100644
--- a/vespalib/src/vespa/vespalib/datastore/bufferstate.h
+++ b/vespalib/src/vespa/vespalib/datastore/bufferstate.h
@@ -86,7 +86,7 @@ public:
* Disable hold of elements, just mark elements as dead without cleanup.
* Typically used when tearing down data structure in a controlled manner.
*/
- void disableElemHoldList();
+ void disable_elem_hold_list();
/**
* Update stats to reflect that the given elements are put on hold.
@@ -134,23 +134,28 @@ public:
class BufferAndMeta {
public:
- BufferAndMeta() : BufferAndMeta(nullptr, 0, 0) { }
- BufferAndMeta(void* buffer, uint32_t typeId, uint32_t arraySize)
- : _buffer(buffer),
- _typeId(typeId),
- _arraySize(arraySize)
- { }
+ BufferAndMeta() : BufferAndMeta(nullptr, nullptr, 0, 0) { }
std::atomic<void*>& get_atomic_buffer() noexcept { return _buffer; }
void* get_buffer_relaxed() noexcept { return _buffer.load(std::memory_order_relaxed); }
const void* get_buffer_acquire() const noexcept { return _buffer.load(std::memory_order_acquire); }
uint32_t getTypeId() const { return _typeId; }
uint32_t getArraySize() const { return _arraySize; }
+ BufferState * get_state_relaxed() { return _state.load(std::memory_order_relaxed); }
+ const BufferState * get_state_acquire() const { return _state.load(std::memory_order_acquire); }
void setTypeId(uint32_t typeId) { _typeId = typeId; }
void setArraySize(uint32_t arraySize) { _arraySize = arraySize; }
+ void set_state(BufferState * state) { _state.store(state, std::memory_order_release); }
private:
- std::atomic<void*> _buffer;
- uint32_t _typeId;
- uint32_t _arraySize;
+ BufferAndMeta(void* buffer, BufferState * state, uint32_t typeId, uint32_t arraySize)
+ : _buffer(buffer),
+ _state(state),
+ _typeId(typeId),
+ _arraySize(arraySize)
+ { }
+ std::atomic<void*> _buffer;
+ std::atomic<BufferState*> _state;
+ uint32_t _typeId;
+ uint32_t _arraySize;
};
}
diff --git a/vespalib/src/vespa/vespalib/datastore/datastorebase.cpp b/vespalib/src/vespa/vespalib/datastore/datastorebase.cpp
index 99bdb19576f..a40aa713bca 100644
--- a/vespalib/src/vespa/vespalib/datastore/datastorebase.cpp
+++ b/vespalib/src/vespa/vespalib/datastore/datastorebase.cpp
@@ -84,16 +84,17 @@ DataStoreBase::DataStoreBase(uint32_t numBuffers, uint32_t offset_bits, size_t m
: _entry_ref_hold_list(),
_buffers(numBuffers),
_primary_buffer_ids(),
- _states(numBuffers),
+ _stash(),
_typeHandlers(),
_free_lists(),
_compaction_count(0u),
_genHolder(),
_maxArrays(maxArrays),
- _numBuffers(numBuffers),
- _offset_bits(offset_bits),
+ _bufferIdLimit(0u),
_hold_buffer_count(0u),
+ _offset_bits(offset_bits),
_freeListsEnabled(false),
+ _disableElemHoldList(false),
_initializing(false)
{
}
@@ -107,7 +108,7 @@ void
DataStoreBase::switch_primary_buffer(uint32_t typeId, size_t elemsNeeded)
{
size_t buffer_id = getFirstFreeBufferId();
- if ((buffer_id < _states.size()) && !getBufferState(buffer_id).isFree()) {
+ if (buffer_id >= getMaxNumBuffers()) {
LOG_ABORT(vespalib::make_string("switch_primary_buffer(%u, %zu): did not find a free buffer",
typeId, elemsNeeded).c_str());
}
@@ -159,19 +160,24 @@ DataStoreBase::consider_grow_active_buffer(uint32_t type_id, size_t elems_needed
uint32_t
DataStoreBase::getFirstFreeBufferId() {
- for (uint32_t buffer_id = 0; buffer_id < _states.size(); buffer_id++) {
- if (getBufferState(buffer_id).isFree()) {
+ uint32_t buffer_id = 0;
+ for (auto & buffer : _buffers) {
+ BufferState * state = buffer.get_state_relaxed();
+ if (state == nullptr || state->isFree()) {
return buffer_id;
}
+ buffer_id++;
}
- // Need next(new) buffer
- return _states.size();
+ // No free buffer, return out of bounds
+ return buffer_id;
}
BufferState &
DataStoreBase::getBufferState(uint32_t buffer_id) noexcept {
- assert(buffer_id < _states.size());
- return _states[buffer_id];
+ assert(buffer_id < get_bufferid_limit_relaxed());
+ BufferState * state = _buffers[buffer_id].get_state_relaxed();
+ assert(state != nullptr);
+ return *state;
}
void
@@ -202,7 +208,7 @@ DataStoreBase::init_primary_buffers()
uint32_t numTypes = _primary_buffer_ids.size();
for (uint32_t typeId = 0; typeId < numTypes; ++typeId) {
size_t buffer_id = getFirstFreeBufferId();
- assert((buffer_id == _states.size()) || getBufferState(buffer_id).isFree());
+ assert(buffer_id <= get_bufferid_limit_relaxed());
onActive(buffer_id, typeId, 0u);
_primary_buffer_ids[typeId] = buffer_id;
}
@@ -253,9 +259,12 @@ DataStoreBase::reclaim_all_memory()
void
DataStoreBase::dropBuffers()
{
- uint32_t numBuffers = _buffers.size();
- for (uint32_t bufferId = 0; bufferId < numBuffers; ++bufferId) {
- getBufferState(bufferId).dropBuffer(bufferId, _buffers[bufferId].get_atomic_buffer());
+ uint32_t buffer_id_limit = get_bufferid_limit_relaxed();
+ for (uint32_t bufferId = 0; bufferId < buffer_id_limit; ++bufferId) {
+ BufferAndMeta & buffer = _buffers[bufferId];
+ BufferState * state = buffer.get_state_relaxed();
+ assert(state != nullptr);
+ state->dropBuffer(bufferId, buffer.get_atomic_buffer());
}
_genHolder.reclaim_all();
}
@@ -278,18 +287,17 @@ DataStoreBase::getMemoryUsage() const {
size_t extra_allocated = 0;
extra_allocated += _buffers.capacity() * sizeof(BufferAndMeta);
extra_allocated += _primary_buffer_ids.capacity() * sizeof(uint32_t);
- extra_allocated += _states.capacity() * sizeof(BufferState);
extra_allocated += _typeHandlers.capacity() * sizeof(BufferTypeBase *);
extra_allocated += _free_lists.capacity() * sizeof(FreeList);
size_t extra_used = 0;
extra_used += _buffers.size() * sizeof(BufferAndMeta);
extra_used += _primary_buffer_ids.size() * sizeof(uint32_t);
- extra_used += _states.size() * sizeof(BufferState);
extra_used += _typeHandlers.size() * sizeof(BufferTypeBase *);
extra_used += _free_lists.size() * sizeof(FreeList);
usage.incAllocatedBytes(extra_allocated);
usage.incUsedBytes(extra_used);
+ usage.merge(_stash.get_memory_usage());
return usage;
}
@@ -305,41 +313,27 @@ DataStoreBase::holdBuffer(uint32_t bufferId)
void
DataStoreBase::enableFreeLists()
{
- for (auto& bState : _states) {
- if (!bState.isActive() || bState.getCompacting()) {
- continue;
- }
- bState.enable_free_list(_free_lists[bState.getTypeId()]);
- }
+ for_each_buffer([this](BufferState & state) {
+ if (!state.isActive() || state.getCompacting()) return;
+ state.enable_free_list(_free_lists[state.getTypeId()]);
+ });
_freeListsEnabled = true;
}
void
DataStoreBase::disableFreeLists()
{
- for (auto& bState : _states) {
- bState.disable_free_list();
- }
+ for_each_buffer([](BufferState & state) { state.disable_free_list(); });
_freeListsEnabled = false;
}
void
-DataStoreBase::enableFreeList(uint32_t bufferId)
-{
- BufferState &state = getBufferState(bufferId);
- if (_freeListsEnabled && state.isActive() && !state.getCompacting()) {
- state.enable_free_list(_free_lists[state.getTypeId()]);
- }
-}
-
-void
DataStoreBase::disableElemHoldList()
{
- for (auto &state : _states) {
- if (!state.isFree()) {
- state.disableElemHoldList();
- }
- }
+ for_each_buffer([](BufferState & state) {
+ if (!state.isFree()) state.disable_elem_hold_list();
+ });
+ _disableElemHoldList = true;
}
MemoryStats
@@ -347,19 +341,23 @@ DataStoreBase::getMemStats() const
{
MemoryStats stats;
- for (const auto& bState: _states) {
- auto typeHandler = bState.getTypeHandler();
- auto state = bState.getState();
+ uint32_t buffer_id_limit = get_bufferid_limit_acquire();
+ stats._freeBuffers = (getMaxNumBuffers() - buffer_id_limit);
+ for (uint32_t bufferId = 0; bufferId < buffer_id_limit; ++bufferId) {
+ const BufferState * bState = _buffers[bufferId].get_state_acquire();
+ assert(bState != nullptr);
+ auto typeHandler = bState->getTypeHandler();
+ auto state = bState->getState();
if ((state == BufferState::State::FREE) || (typeHandler == nullptr)) {
++stats._freeBuffers;
} else if (state == BufferState::State::ACTIVE) {
size_t elementSize = typeHandler->elementSize();
++stats._activeBuffers;
- bState.stats().add_to_mem_stats(elementSize, stats);
+ bState->stats().add_to_mem_stats(elementSize, stats);
} else if (state == BufferState::State::HOLD) {
size_t elementSize = typeHandler->elementSize();
++stats._holdBuffers;
- bState.stats().add_to_mem_stats(elementSize, stats);
+ bState->stats().add_to_mem_stats(elementSize, stats);
} else {
LOG_ABORT("should not be reached");
}
@@ -374,21 +372,24 @@ DataStoreBase::getMemStats() const
vespalib::AddressSpace
DataStoreBase::getAddressSpaceUsage() const
{
+ uint32_t buffer_id_limit = get_bufferid_limit_acquire();
size_t usedArrays = 0;
size_t deadArrays = 0;
- size_t limitArrays = 0;
- for (const auto& bState: _states) {
- if (bState.isActive()) {
- uint32_t arraySize = bState.getArraySize();
- usedArrays += bState.size() / arraySize;
- deadArrays += bState.stats().dead_elems() / arraySize;
- limitArrays += bState.capacity() / arraySize;
- } else if (bState.isOnHold()) {
- uint32_t arraySize = bState.getArraySize();
- usedArrays += bState.size() / arraySize;
- limitArrays += bState.capacity() / arraySize;
- } else if (bState.isFree()) {
+ size_t limitArrays = size_t(_maxArrays) * (getMaxNumBuffers() - buffer_id_limit);
+ for (uint32_t bufferId = 0; bufferId < buffer_id_limit; ++bufferId) {
+ const BufferState * bState = _buffers[bufferId].get_state_acquire();
+ assert(bState != nullptr);
+ if (bState->isFree()) {
limitArrays += _maxArrays;
+ } else if (bState->isActive()) {
+ uint32_t arraySize = bState->getArraySize();
+ usedArrays += bState->size() / arraySize;
+ deadArrays += bState->stats().dead_elems() / arraySize;
+ limitArrays += bState->capacity() / arraySize;
+ } else if (bState->isOnHold()) {
+ uint32_t arraySize = bState->getArraySize();
+ usedArrays += bState->size() / arraySize;
+ limitArrays += bState->capacity() / arraySize;
} else {
LOG_ABORT("should not be reached");
}
@@ -400,13 +401,29 @@ void
DataStoreBase::onActive(uint32_t bufferId, uint32_t typeId, size_t elemsNeeded)
{
assert(typeId < _typeHandlers.size());
- assert(bufferId < _numBuffers);
- BufferState &state = getBufferState(bufferId);
+ assert(bufferId <= _bufferIdLimit);
+
BufferAndMeta & bufferMeta = _buffers[bufferId];
- state.onActive(bufferId, typeId, _typeHandlers[typeId], elemsNeeded, bufferMeta.get_atomic_buffer());
+ BufferState *state = bufferMeta.get_state_relaxed();
+ if (state == nullptr) {
+ BufferState & newState = _stash.create<BufferState>();
+ if (_disableElemHoldList) {
+ newState.disable_elem_hold_list();
+ }
+ if ( ! _freeListsEnabled) {
+ newState.disable_free_list();
+ }
+ state = & newState;
+ bufferMeta.set_state(state);
+ _bufferIdLimit.store(bufferId + 1, std::memory_order_release);
+ }
+ assert(state->isFree());
+ state->onActive(bufferId, typeId, _typeHandlers[typeId], elemsNeeded, bufferMeta.get_atomic_buffer());
bufferMeta.setTypeId(typeId);
- bufferMeta.setArraySize(state.getArraySize());
- enableFreeList(bufferId);
+ bufferMeta.setArraySize(state->getArraySize());
+ if (_freeListsEnabled && state->isActive() && !state->getCompacting()) {
+ state->enable_free_list(_free_lists[state->getTypeId()]);
+ }
}
void
@@ -448,7 +465,7 @@ DataStoreBase::markCompacting(uint32_t bufferId)
}
assert(!state.getCompacting());
state.setCompacting();
- state.disableElemHoldList();
+ state.disable_elem_hold_list();
state.disable_free_list();
inc_compaction_count();
}
@@ -456,39 +473,41 @@ DataStoreBase::markCompacting(uint32_t bufferId)
std::unique_ptr<CompactingBuffers>
DataStoreBase::start_compact_worst_buffers(CompactionSpec compaction_spec, const CompactionStrategy& compaction_strategy)
{
+ uint32_t buffer_id_limit = get_bufferid_limit_relaxed();
// compact memory usage
- CompactBufferCandidates elem_buffers(_numBuffers, compaction_strategy.get_max_buffers(),
+ CompactBufferCandidates elem_buffers(buffer_id_limit, compaction_strategy.get_max_buffers(),
compaction_strategy.get_active_buffers_ratio(),
compaction_strategy.getMaxDeadBytesRatio() / 2,
CompactionStrategy::DEAD_BYTES_SLACK);
// compact address space
- CompactBufferCandidates array_buffers(_numBuffers, compaction_strategy.get_max_buffers(),
+ CompactBufferCandidates array_buffers(buffer_id_limit, compaction_strategy.get_max_buffers(),
compaction_strategy.get_active_buffers_ratio(),
compaction_strategy.getMaxDeadAddressSpaceRatio() / 2,
CompactionStrategy::DEAD_ADDRESS_SPACE_SLACK);
- uint32_t free_buffers = _buffers.size() - _states.size();
- for (uint32_t bufferId = 0; bufferId < _numBuffers; ++bufferId) {
- const auto &state = getBufferState(bufferId);
- if (state.isActive()) {
- auto typeHandler = state.getTypeHandler();
+ uint32_t free_buffers = getMaxNumBuffers() - buffer_id_limit;
+ for (uint32_t bufferId = 0; bufferId < buffer_id_limit; ++bufferId) {
+ BufferState * state = _buffers[bufferId].get_state_relaxed();
+ assert(state != nullptr);
+ if (state->isFree()) {
+ free_buffers++;
+ } else if (state->isActive()) {
+ auto typeHandler = state->getTypeHandler();
uint32_t arraySize = typeHandler->getArraySize();
uint32_t reservedElements = typeHandler->getReservedElements(bufferId);
- size_t used_elems = state.size();
- size_t deadElems = state.stats().dead_elems() - reservedElements;
+ size_t used_elems = state->size();
+ size_t deadElems = state->stats().dead_elems() - reservedElements;
if (compaction_spec.compact_memory()) {
elem_buffers.add(bufferId, used_elems, deadElems);
}
if (compaction_spec.compact_address_space()) {
- array_buffers.add(bufferId, used_elems / arraySize, deadElems / arraySize);
+ array_buffers.add(bufferId, used_elems / arraySize, deadElems / arraySize);
}
- } else if (state.isFree()) {
- ++free_buffers;
}
}
elem_buffers.set_free_buffers(free_buffers);
array_buffers.set_free_buffers(free_buffers);
std::vector<uint32_t> result;
- result.reserve(std::min(_numBuffers, 2 * compaction_strategy.get_max_buffers()));
+ result.reserve(std::min(buffer_id_limit, 2 * compaction_strategy.get_max_buffers()));
elem_buffers.select(result);
array_buffers.select(result);
std::sort(result.begin(), result.end());
@@ -497,7 +516,7 @@ DataStoreBase::start_compact_worst_buffers(CompactionSpec compaction_spec, const
for (auto buffer_id : result) {
markCompacting(buffer_id);
}
- return std::make_unique<CompactingBuffers>(*this, _numBuffers, _offset_bits, std::move(result));
+ return std::make_unique<CompactingBuffers>(*this, buffer_id_limit, _offset_bits, std::move(result));
}
void
diff --git a/vespalib/src/vespa/vespalib/datastore/datastorebase.h b/vespalib/src/vespa/vespalib/datastore/datastorebase.h
index 8749f2a27e6..ecbac451c5a 100644
--- a/vespalib/src/vespa/vespalib/datastore/datastorebase.h
+++ b/vespalib/src/vespa/vespalib/datastore/datastorebase.h
@@ -8,9 +8,8 @@
#include <vespa/vespalib/util/address_space.h>
#include <vespa/vespalib/util/generationholder.h>
#include <vespa/vespalib/util/generation_hold_list.h>
-#include <vespa/vespalib/util/memoryusage.h>
+#include <vespa/vespalib/util/stash.h>
#include <atomic>
-#include <deque>
#include <vector>
namespace vespalib::datastore {
@@ -75,7 +74,20 @@ public:
uint32_t primary_buffer_id(uint32_t typeId) const { return _primary_buffer_ids[typeId]; }
BufferState &getBufferState(uint32_t buffer_id) noexcept;
const BufferAndMeta & getBufferMeta(uint32_t buffer_id) const { return _buffers[buffer_id]; }
- uint32_t getNumBuffers() const { return _numBuffers; }
+ uint32_t getMaxNumBuffers() const noexcept { return _buffers.size(); }
+ uint32_t get_bufferid_limit_acquire() const noexcept { return _bufferIdLimit.load(std::memory_order_acquire); }
+ uint32_t get_bufferid_limit_relaxed() noexcept { return _bufferIdLimit.load(std::memory_order_relaxed); }
+
+ template<typename FuncType>
+ void for_each_active_buffer(FuncType func) {
+ uint32_t buffer_id_limit = get_bufferid_limit_relaxed();
+ for (uint32_t i = 0; i < buffer_id_limit; i++) {
+ const BufferState * state = _buffers[i].get_state_relaxed();
+ if (state && state->isActive()) {
+ func(i, *state);
+ }
+ }
+ }
/**
* Assign generation on data elements on hold lists added since the last time this function was called.
@@ -218,11 +230,7 @@ private:
* Hold of buffer has ended.
*/
void doneHoldBuffer(uint32_t bufferId);
- /**
- * Enable free list management.
- * This only works for fixed size elements.
- */
- void enableFreeList(uint32_t bufferId);
+
/**
* Switch buffer state to active for the given buffer.
*
@@ -236,24 +244,33 @@ private:
void fallbackResize(uint32_t bufferId, size_t elementsNeeded);
uint32_t getFirstFreeBufferId();
+ template<typename FuncType>
+ void for_each_buffer(FuncType func) {
+ uint32_t buffer_id_limit = get_bufferid_limit_relaxed();
+ for (uint32_t i = 0; i < buffer_id_limit; i++) {
+ func(*(_buffers[i].get_state_relaxed()));
+ }
+ }
+
virtual void reclaim_all_entry_refs() = 0;
- std::vector<BufferAndMeta> _buffers; // For fast mapping with known types
+ std::vector<BufferAndMeta> _buffers; // For fast mapping with known types
// Provides a mapping from typeId -> primary buffer for that type.
// The primary buffer is used for allocations of new element(s) if no available slots are found in free lists.
std::vector<uint32_t> _primary_buffer_ids;
- std::vector<BufferState> _states;
+ Stash _stash;
std::vector<BufferTypeBase *> _typeHandlers; // TypeId -> handler
std::vector<FreeList> _free_lists;
mutable std::atomic<uint64_t> _compaction_count;
vespalib::GenerationHolder _genHolder;
const uint32_t _maxArrays;
- const uint32_t _numBuffers;
- const uint32_t _offset_bits;
+ std::atomic<uint32_t> _bufferIdLimit;
uint32_t _hold_buffer_count;
+ const uint8_t _offset_bits;
bool _freeListsEnabled;
+ bool _disableElemHoldList;
bool _initializing;
};
diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store.hpp b/vespalib/src/vespa/vespalib/datastore/unique_store.hpp
index aef6ea07290..52b0798543f 100644
--- a/vespalib/src/vespa/vespalib/datastore/unique_store.hpp
+++ b/vespalib/src/vespa/vespalib/datastore/unique_store.hpp
@@ -102,8 +102,8 @@ private:
std::unique_ptr<CompactingBuffers> _compacting_buffers;
void allocMapping() {
- _mapping.resize(RefT::numBuffers());
auto& data_store = _compacting_buffers->get_store();
+ _mapping.resize(data_store.get_bufferid_limit_relaxed());
for (const auto bufferId : _compacting_buffers->get_buffer_ids()) {
BufferState &state = data_store.getBufferState(bufferId);
_mapping[bufferId].resize(state.get_used_arrays());
diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp b/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp
index 6d08a027bf1..32513d09c72 100644
--- a/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp
+++ b/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp
@@ -42,13 +42,10 @@ template <typename RefT>
void
UniqueStoreEnumerator<RefT>::allocate_enum_values(DataStoreBase & store)
{
- _enumValues.resize(RefType::numBuffers());
- for (uint32_t bufferId = 0; bufferId < RefType::numBuffers(); ++bufferId) {
- const BufferState &state = store.getBufferState(bufferId);
- if (state.isActive()) {
- _enumValues[bufferId].resize(state.get_used_arrays());
- }
- }
+ _enumValues.resize(store.get_bufferid_limit_relaxed());
+ store.for_each_active_buffer([this](uint32_t buffer_id, const BufferState & state) {
+ _enumValues[buffer_id].resize(state.get_used_arrays());
+ });
}
template <typename RefT>