summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java5
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java10
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java4
-rw-r--r--config-model/src/main/java/com/yahoo/documentmodel/NewDocumentReferenceDataType.java1
-rw-r--r--config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java1
-rw-r--r--config-model/src/main/java/com/yahoo/documentmodel/OwnedStructDataType.java56
-rw-r--r--config-model/src/main/java/com/yahoo/documentmodel/OwnedTemporaryType.java41
-rw-r--r--config-model/src/main/java/com/yahoo/documentmodel/OwnedType.java15
-rw-r--r--config-model/src/main/java/com/yahoo/documentmodel/TemporaryUnknownType.java21
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/DocumentModelBuilder.java47
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/document/Attribute.java1
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/document/SDField.java9
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/parser/ConvertParsedTypes.java9
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedBlock.java4
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedDocument.java7
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedType.java55
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/configmodel/producers/DocumentManager.java16
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/configmodel/producers/DocumentTypes.java8
-rw-r--r--config-model/src/main/javacc/SDParser.jj12
-rw-r--r--config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java124
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/DocumentGraphValidatorTest.java1
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/DocumentReferenceResolverTest.java1
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/derived/SchemaOrdererTestCase.java1
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/derived/VsmFieldsTestCase.java1
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/parser/IntermediateParserTestCase.java2
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/parser/ParsedDocumentTestCase.java5
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/processing/ParentChildSearchModel.java1
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerClusterTest.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerTest.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java7
-rw-r--r--config/src/vespa/config/frt/frtconnectionpool.cpp12
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java8
-rw-r--r--configutil/src/apps/configstatus/main.cpp2
-rw-r--r--configutil/src/lib/configstatus.cpp2
-rw-r--r--configutil/src/lib/configstatus.h2
-rw-r--r--configutil/src/lib/modelinspect.cpp2
-rw-r--r--configutil/src/lib/modelinspect.h2
-rw-r--r--container-core/src/main/java/com/yahoo/processing/request/CompoundName.java2
-rw-r--r--container-search/abi-spec.json2
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/Item.java21
-rw-r--r--container-search/src/main/java/com/yahoo/search/grouping/request/DocIdNsSpecificValue.java4
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/QueryTree.java10
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueHandler.java8
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockIssueHandler.java10
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/ProjectInfo.java31
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java7
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java3
-rw-r--r--document/src/tests/arrayfieldvaluetest.cpp2
-rw-r--r--document/src/tests/documenttestcase.cpp48
-rw-r--r--document/src/tests/documentupdatetestcase.cpp6
-rw-r--r--document/src/tests/fieldvalue/fieldvalue_test.cpp2
-rw-r--r--document/src/tests/fieldvalue/referencefieldvalue_test.cpp30
-rw-r--r--document/src/tests/serialization/vespadocumentserializer_test.cpp16
-rw-r--r--document/src/tests/weightedsetfieldvaluetest.cpp3
-rw-r--r--document/src/vespa/document/base/fieldpath.cpp24
-rw-r--r--document/src/vespa/document/base/fieldpath.h12
-rw-r--r--document/src/vespa/document/datatype/datatype.cpp37
-rw-r--r--document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.cpp10
-rw-r--r--document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.h11
-rw-r--r--document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp13
-rw-r--r--document/src/vespa/document/fieldvalue/arrayfieldvalue.h4
-rw-r--r--document/src/vespa/document/fieldvalue/boolfieldvalue.cpp24
-rw-r--r--document/src/vespa/document/fieldvalue/boolfieldvalue.h5
-rw-r--r--document/src/vespa/document/fieldvalue/bytefieldvalue.cpp2
-rw-r--r--document/src/vespa/document/fieldvalue/bytefieldvalue.h5
-rw-r--r--document/src/vespa/document/fieldvalue/collectionfieldvalue.cpp1
-rw-r--r--document/src/vespa/document/fieldvalue/collectionfieldvalue.h8
-rw-r--r--document/src/vespa/document/fieldvalue/document.cpp16
-rw-r--r--document/src/vespa/document/fieldvalue/document.h7
-rw-r--r--document/src/vespa/document/fieldvalue/doublefieldvalue.cpp1
-rw-r--r--document/src/vespa/document/fieldvalue/doublefieldvalue.h5
-rw-r--r--document/src/vespa/document/fieldvalue/fieldvalue.cpp46
-rw-r--r--document/src/vespa/document/fieldvalue/fieldvalue.h59
-rw-r--r--document/src/vespa/document/fieldvalue/floatfieldvalue.cpp2
-rw-r--r--document/src/vespa/document/fieldvalue/floatfieldvalue.h5
-rw-r--r--document/src/vespa/document/fieldvalue/intfieldvalue.cpp1
-rw-r--r--document/src/vespa/document/fieldvalue/intfieldvalue.h5
-rw-r--r--document/src/vespa/document/fieldvalue/literalfieldvalue.cpp24
-rw-r--r--document/src/vespa/document/fieldvalue/literalfieldvalue.h25
-rw-r--r--document/src/vespa/document/fieldvalue/literalfieldvalue.hpp8
-rw-r--r--document/src/vespa/document/fieldvalue/longfieldvalue.cpp2
-rw-r--r--document/src/vespa/document/fieldvalue/longfieldvalue.h5
-rw-r--r--document/src/vespa/document/fieldvalue/mapfieldvalue.cpp31
-rw-r--r--document/src/vespa/document/fieldvalue/mapfieldvalue.h5
-rw-r--r--document/src/vespa/document/fieldvalue/numericfieldvalue.cpp2
-rw-r--r--document/src/vespa/document/fieldvalue/numericfieldvalue.h9
-rw-r--r--document/src/vespa/document/fieldvalue/numericfieldvalue.hpp15
-rw-r--r--document/src/vespa/document/fieldvalue/predicatefieldvalue.cpp24
-rw-r--r--document/src/vespa/document/fieldvalue/predicatefieldvalue.h6
-rw-r--r--document/src/vespa/document/fieldvalue/rawfieldvalue.cpp2
-rw-r--r--document/src/vespa/document/fieldvalue/rawfieldvalue.h13
-rw-r--r--document/src/vespa/document/fieldvalue/referencefieldvalue.cpp30
-rw-r--r--document/src/vespa/document/fieldvalue/referencefieldvalue.h12
-rw-r--r--document/src/vespa/document/fieldvalue/shortfieldvalue.cpp2
-rw-r--r--document/src/vespa/document/fieldvalue/shortfieldvalue.h5
-rw-r--r--document/src/vespa/document/fieldvalue/stringfieldvalue.cpp32
-rw-r--r--document/src/vespa/document/fieldvalue/stringfieldvalue.h9
-rw-r--r--document/src/vespa/document/fieldvalue/structfieldvalue.cpp4
-rw-r--r--document/src/vespa/document/fieldvalue/structfieldvalue.h12
-rw-r--r--document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp2
-rw-r--r--document/src/vespa/document/fieldvalue/structuredfieldvalue.h4
-rw-r--r--document/src/vespa/document/fieldvalue/structuredfieldvalue.hpp2
-rw-r--r--document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp33
-rw-r--r--document/src/vespa/document/fieldvalue/tensorfieldvalue.h25
-rw-r--r--document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp20
-rw-r--r--document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h8
-rw-r--r--document/src/vespa/document/select/valuenodes.cpp27
-rw-r--r--document/src/vespa/document/serialization/annotationdeserializer.cpp5
-rw-r--r--document/src/vespa/document/serialization/vespadocumentdeserializer.cpp2
-rw-r--r--document/src/vespa/document/update/addfieldpathupdate.cpp6
-rw-r--r--document/src/vespa/document/update/addvalueupdate.cpp6
-rw-r--r--document/src/vespa/document/update/arithmeticvalueupdate.cpp15
-rw-r--r--document/src/vespa/document/update/assignfieldpathupdate.cpp10
-rw-r--r--document/src/vespa/document/update/assignvalueupdate.cpp2
-rw-r--r--document/src/vespa/document/update/documentupdate.h11
-rw-r--r--document/src/vespa/document/update/fieldpathupdate.h1
-rw-r--r--document/src/vespa/document/update/fieldupdate.h3
-rw-r--r--document/src/vespa/document/update/mapvalueupdate.cpp4
-rw-r--r--document/src/vespa/document/update/removevalueupdate.cpp6
-rw-r--r--document/src/vespa/document/update/tensor_add_update.cpp10
-rw-r--r--document/src/vespa/document/update/tensor_modify_update.cpp14
-rw-r--r--document/src/vespa/document/update/tensor_remove_update.cpp8
-rw-r--r--document/src/vespa/document/update/valueupdate.h5
-rw-r--r--document/src/vespa/document/util/feed_reject_helper.cpp4
-rw-r--r--document/src/vespa/document/util/xmlserializable.h10
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/Flags.java2
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Limits.java5
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/PassthroughLoadBalancerService.java44
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerService.java29
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java18
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/EmptyProvisionServiceProvider.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java20
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisionServiceProvider.java3
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockProvisionServiceProvider.java3
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java3
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/PassthroughLoadBalancerServiceTest.java30
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerServiceTest.java15
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/document_field_extractor.cpp17
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/document_field_retriever.cpp4
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp33
-rw-r--r--searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp4
-rw-r--r--searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/DoubleValue.java6
-rw-r--r--searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TruthOperator.java2
-rw-r--r--searchlib/src/tests/tensor/hnsw_saver/hnsw_save_load_test.cpp10
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attributevector.hpp19
-rw-r--r--searchlib/src/vespa/searchlib/expression/documentfieldnode.cpp52
-rw-r--r--searchlib/src/vespa/searchlib/memoryindex/field_inverter.cpp22
-rw-r--r--searchlib/src/vespa/searchlib/memoryindex/url_field_inverter.cpp47
-rw-r--r--searchlib/src/vespa/searchlib/parsequery/parse.h4
-rw-r--r--searchlib/src/vespa/searchlib/tensor/hnsw_graph.cpp16
-rw-r--r--searchlib/src/vespa/searchlib/tensor/hnsw_graph.h22
-rw-r--r--searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp37
-rw-r--r--searchlib/src/vespa/searchlib/tensor/hnsw_index_saver.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/transactionlog/domain.cpp4
-rw-r--r--searchsummary/src/tests/extractkeywords/simplequerystackitem.cpp3
-rw-r--r--searchsummary/src/vespa/searchsummary/docsummary/matched_elements_filter_dfw.cpp2
-rw-r--r--searchsummary/src/vespa/searchsummary/docsummary/summaryfieldconverter.cpp11
-rw-r--r--staging_vespalib/src/vespa/vespalib/objects/objectvisitor.h1
-rw-r--r--staging_vespalib/src/vespa/vespalib/util/xmlserializable.h2
-rw-r--r--streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp20
-rw-r--r--tsan-suppressions.txt2
-rw-r--r--vdslib/src/vespa/vdslib/container/parameters.cpp3
-rw-r--r--vdslib/src/vespa/vdslib/container/parameters.h6
-rw-r--r--vespamalloc/src/tests/test1/testatomic.cpp26
-rw-r--r--vsm/src/vespa/vsm/searcher/fieldsearcher.cpp11
-rw-r--r--vsm/src/vespa/vsm/vsm/docsumfilter.cpp2
-rw-r--r--vsm/src/vespa/vsm/vsm/flattendocsumwriter.cpp7
-rw-r--r--vsm/src/vespa/vsm/vsm/slimefieldwriter.cpp22
171 files changed, 1037 insertions, 1093 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
index e3446002888..91514b89b3e 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
@@ -24,6 +24,8 @@ import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutorService;
+import static com.yahoo.config.provision.NodeResources.Architecture;
+
/**
* Model context containing state provided to model factories.
*
@@ -118,7 +120,8 @@ public interface ModelContext {
@ModelFeatureFlag(owners = {"arnej"}) default boolean avoidRenamingSummaryFeatures() { return false; }
@ModelFeatureFlag(owners = {"bjorncs", "baldersheim"}) default boolean mergeGroupingResultInSearchInvoker() { return false; }
@ModelFeatureFlag(owners = {"arnej"}) default boolean experimentalSdParsing() { return false; }
- @ModelFeatureFlag(owners = {"hmusum"}) default String adminClusterNodeArchitecture() { return "x86_64"; } // TODO: Cluster controllers only for now
+ @ModelFeatureFlag(owners = {"hmusum"}) default String adminClusterNodeArchitecture() { return adminClusterArchitecture().name(); } // TODO: Remove when 7.564 is oldest version in use
+ @ModelFeatureFlag(owners = {"hmusum"}) default Architecture adminClusterArchitecture() { return Architecture.getDefault(); }
}
/** Warning: As elsewhere in this package, do not make backwards incompatible changes that will break old config models! */
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
index 575080d3025..3e251a621ab 100644
--- a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
+++ b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
@@ -20,6 +20,8 @@ import java.util.List;
import java.util.Optional;
import java.util.Set;
+import static com.yahoo.config.provision.NodeResources.Architecture;
+
/**
* A test-only Properties class
*
@@ -81,7 +83,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
private List<String> environmentVariables = List.of();
private boolean avoidRenamingSummaryFeatures = false;
private boolean experimentalSdParsing = false;
- private String adminClusterNodeResourcesArchitecture = "x86_64";
+ private Architecture adminClusterNodeResourcesArchitecture = Architecture.getDefault();
@Override public ModelContext.FeatureFlags featureFlags() { return this; }
@Override public boolean multitenant() { return multitenant; }
@@ -143,7 +145,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
@Override public List<String> environmentVariables() { return environmentVariables; }
@Override public boolean avoidRenamingSummaryFeatures() { return this.avoidRenamingSummaryFeatures; }
@Override public boolean experimentalSdParsing() { return this.experimentalSdParsing; }
- @Override public String adminClusterNodeArchitecture() { return adminClusterNodeResourcesArchitecture; }
+ @Override public Architecture adminClusterArchitecture() { return adminClusterNodeResourcesArchitecture; }
public TestProperties maxUnCommittedMemory(int maxUnCommittedMemory) {
this.maxUnCommittedMemory = maxUnCommittedMemory;
@@ -391,8 +393,8 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
return this;
}
- public TestProperties setAdminClusterNodeResourcesArchitecture(String architectureFunction) {
- this.adminClusterNodeResourcesArchitecture = architectureFunction;
+ public TestProperties setAdminClusterNodeResourcesArchitecture(Architecture architecture) {
+ this.adminClusterNodeResourcesArchitecture = architecture;
return this;
}
diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java b/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java
index 8bf6dc7f1d9..a6bcf6b0fd2 100644
--- a/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java
+++ b/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java
@@ -36,7 +36,7 @@ import java.util.stream.IntStream;
*/
public class InMemoryProvisioner implements HostProvisioner {
- public static final NodeResources defaultResources = new NodeResources(1, 3, 10, 1);
+ public static final NodeResources defaultResources = new NodeResources(1, 3, 50, 1);
/**
* If this is true an exception is thrown when all nodes are used.
@@ -153,7 +153,7 @@ public class InMemoryProvisioner implements HostProvisioner {
if (alwaysReturnOneNode)
nodes = 1;
- int groups = requested.groups() > nodes ? nodes : requested.groups();
+ int groups = Math.min(requested.groups(), nodes);
List<HostSpec> allocation = new ArrayList<>();
if (groups == 1) {
diff --git a/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentReferenceDataType.java b/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentReferenceDataType.java
index 65c282e01e2..702ab835dd4 100644
--- a/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentReferenceDataType.java
+++ b/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentReferenceDataType.java
@@ -5,7 +5,6 @@ import com.yahoo.document.DataType;
import com.yahoo.document.DocumentType;
import com.yahoo.document.ReferenceDataType;
import com.yahoo.document.StructuredDataType;
-import com.yahoo.document.TemporaryStructuredDataType;
import com.yahoo.document.datatypes.FieldValue;
import com.yahoo.document.datatypes.ReferenceFieldValue;
diff --git a/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java b/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java
index dd8edbdde6c..ff5930f8f6a 100644
--- a/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java
+++ b/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java
@@ -7,7 +7,6 @@ import com.yahoo.document.Field;
import com.yahoo.documentmodel.NewDocumentReferenceDataType;
import com.yahoo.document.StructDataType;
import com.yahoo.document.StructuredDataType;
-import com.yahoo.document.TemporaryStructuredDataType;
import com.yahoo.document.annotation.AnnotationType;
import com.yahoo.document.annotation.AnnotationTypeRegistry;
import com.yahoo.document.datatypes.FieldValue;
diff --git a/config-model/src/main/java/com/yahoo/documentmodel/OwnedStructDataType.java b/config-model/src/main/java/com/yahoo/documentmodel/OwnedStructDataType.java
new file mode 100644
index 00000000000..761a1f0963c
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/documentmodel/OwnedStructDataType.java
@@ -0,0 +1,56 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.documentmodel;
+
+import com.yahoo.document.DocumentType;
+import com.yahoo.document.StructDataType;
+
+/**
+ * Model for StructDataType declared in a specific document
+ *
+ * @author arnej
+ **/
+public final class OwnedStructDataType extends StructDataType implements OwnedType {
+
+ private final String ownerName;
+ private final String uniqueName;
+ private boolean overrideId = false;
+
+ public OwnedStructDataType(String name, DocumentType document) {
+ this(name, document.getName());
+ }
+
+ public OwnedStructDataType(String name, String owner) {
+ super(name);
+ this.ownerName = owner;
+ this.uniqueName = name + "@" + owner;
+ }
+
+ public void enableOverride() {
+ this.overrideId = true;
+ }
+
+ @Override
+ public String getOwnerName() {
+ return ownerName;
+ }
+
+ @Override
+ public String getUniqueName() {
+ return uniqueName;
+ }
+
+ @Override
+ public String getName() {
+ return overrideId ? uniqueName : super.getName();
+ }
+
+ @Override
+ public int getId() {
+ return overrideId ? getUniqueId() : super.getId();
+ }
+
+ @Override
+ public String toString() {
+ return "{OwnedStructDataType "+uniqueName+" id="+getId()+" uid="+getUniqueId()+" enable override="+overrideId+"}";
+ }
+}
diff --git a/config-model/src/main/java/com/yahoo/documentmodel/OwnedTemporaryType.java b/config-model/src/main/java/com/yahoo/documentmodel/OwnedTemporaryType.java
new file mode 100644
index 00000000000..536c10ee242
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/documentmodel/OwnedTemporaryType.java
@@ -0,0 +1,41 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.documentmodel;
+
+import com.yahoo.document.DocumentType;
+import com.yahoo.document.StructDataType;
+
+/**
+ * Proxy for a struct type declared in a specific document
+ *
+ * @author arnej
+ **/
+public final class OwnedTemporaryType extends StructDataType implements OwnedType {
+
+ private final String ownerName;
+ private final String uniqueName;
+
+ public OwnedTemporaryType(String name, DocumentType document) {
+ this(name, document.getName());
+ }
+
+ public OwnedTemporaryType(String name, String owner) {
+ super(name);
+ this.ownerName = owner;
+ this.uniqueName = name + "@" + owner;
+ }
+
+ @Override
+ public String getOwnerName() {
+ return ownerName;
+ }
+
+ @Override
+ public String getUniqueName() {
+ return uniqueName;
+ }
+
+ @Override
+ public String toString() {
+ return "{OwnedTemporaryType "+uniqueName+" id="+getId()+" uid="+getUniqueId()+"}";
+ }
+}
diff --git a/config-model/src/main/java/com/yahoo/documentmodel/OwnedType.java b/config-model/src/main/java/com/yahoo/documentmodel/OwnedType.java
new file mode 100644
index 00000000000..e3a91692ca8
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/documentmodel/OwnedType.java
@@ -0,0 +1,15 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.documentmodel;
+
+/**
+ * API for a type declared in a specific document
+ *
+ * @author arnej
+ **/
+public interface OwnedType {
+ String getOwnerName();
+ String getUniqueName();
+ default int getUniqueId() {
+ return getUniqueName().hashCode();
+ }
+}
diff --git a/config-model/src/main/java/com/yahoo/documentmodel/TemporaryUnknownType.java b/config-model/src/main/java/com/yahoo/documentmodel/TemporaryUnknownType.java
new file mode 100644
index 00000000000..66f6354b3f5
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/documentmodel/TemporaryUnknownType.java
@@ -0,0 +1,21 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.documentmodel;
+
+import com.yahoo.document.StructDataType;
+
+/**
+ * Proxy for an unknown type (must resolve to struct or document)
+ *
+ * @author arnej
+ **/
+public final class TemporaryUnknownType extends StructDataType {
+
+ public TemporaryUnknownType(String name) {
+ super(name);
+ }
+
+ @Override
+ public String toString() {
+ return "{TemporaryUnknownType "+getName()+" id="+getId()+"}";
+ }
+}
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/DocumentModelBuilder.java b/config-model/src/main/java/com/yahoo/searchdefinition/DocumentModelBuilder.java
index 4660b81ff72..5b7b23d69d4 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/DocumentModelBuilder.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/DocumentModelBuilder.java
@@ -7,7 +7,6 @@ import com.yahoo.document.DataType;
import com.yahoo.document.DocumentType;
import com.yahoo.document.Field;
import com.yahoo.document.MapDataType;
-import com.yahoo.documentmodel.NewDocumentReferenceDataType;
import com.yahoo.document.StructDataType;
import com.yahoo.document.StructuredDataType;
import com.yahoo.document.TemporaryStructuredDataType;
@@ -15,7 +14,11 @@ import com.yahoo.document.WeightedSetDataType;
import com.yahoo.document.annotation.AnnotationReferenceDataType;
import com.yahoo.document.annotation.AnnotationType;
import com.yahoo.documentmodel.DataTypeCollection;
+import com.yahoo.documentmodel.NewDocumentReferenceDataType;
import com.yahoo.documentmodel.NewDocumentType;
+import com.yahoo.documentmodel.OwnedStructDataType;
+import com.yahoo.documentmodel.OwnedTemporaryType;
+import com.yahoo.documentmodel.TemporaryUnknownType;
import com.yahoo.documentmodel.VespaDocumentType;
import com.yahoo.searchdefinition.document.Attribute;
import com.yahoo.searchdefinition.document.SDDocumentType;
@@ -232,13 +235,37 @@ public class DocumentModelBuilder {
}
DataType original = type;
if (type instanceof TemporaryStructuredDataType) {
+ throw new IllegalArgumentException("Cannot handle temporary: " + type);
+ }
+ if (type instanceof TemporaryUnknownType) {
+ // must be a known struct or document type
DataType other = repo.getDataType(type.getId());
if (other == null || other == type) {
+ // maybe it is the name of a document type:
other = getDocumentType(docs, type.getName());
}
- if (other != null) {
- type = other;
+ if (other == null) {
+ throw new IllegalArgumentException("No replacement found for temporary type: " + type);
+ }
+ type = other;
+ } else if (type instanceof OwnedTemporaryType) {
+ // must be replaced with the real struct type
+ DataType other = repo.getDataType(type.getId());
+ if (other == null || other == type) {
+ throw new IllegalArgumentException("No replacement found for temporary type: " + type);
+ }
+ if (other instanceof OwnedStructDataType) {
+ var owned = (OwnedTemporaryType) type;
+ String ownedBy = owned.getOwnerName();
+ var otherOwned = (OwnedStructDataType) other;
+ String otherOwnedBy = otherOwned.getOwnerName();
+ if (! ownedBy.equals(otherOwnedBy)) {
+ throw new IllegalArgumentException("Wrong document for type: " + otherOwnedBy + " but expected " + ownedBy);
+ }
+ } else {
+ throw new IllegalArgumentException("Found wrong sort of type: " + other + " [" + other.getClass() + "]");
}
+ type = other;
} else if (type instanceof DocumentType) {
DataType other = getDocumentType(docs, type.getName());
if (other != null) {
@@ -364,6 +391,8 @@ public class DocumentModelBuilder {
for (SDDocumentType proxy : type.getInheritedTypes()) {
var inherited = (StructDataType) targetDt.getDataTypeRecursive(proxy.getName());
var converted = (StructDataType) targetDt.getDataType(type.getName());
+ assert(converted instanceof OwnedStructDataType);
+ assert(inherited instanceof OwnedStructDataType);
if (! converted.inherits(inherited)) {
converted.inherit(inherited);
}
@@ -382,15 +411,15 @@ public class DocumentModelBuilder {
StructDataType s = handleStruct(sa.getSdDocType());
annotation.setDataType(s);
if ((sa.getInherits() != null)) {
- structInheritance.put(s, "annotation."+sa.getInherits());
+ structInheritance.put(s, "annotation." + sa.getInherits());
}
} else if (sa.getInherits() != null) {
- StructDataType s = new StructDataType("annotation."+annotation.getName());
+ StructDataType s = new OwnedStructDataType("annotation." + annotation.getName(), sdoc.getName());
if (anyParentsHavePayLoad(sa, sdoc)) {
annotation.setDataType(s);
addType(s);
}
- structInheritance.put(s, "annotation."+sa.getInherits());
+ structInheritance.put(s, "annotation." + sa.getInherits());
}
} else {
var dt = annotation.getDataType();
@@ -532,16 +561,18 @@ public class DocumentModelBuilder {
@SuppressWarnings("deprecation")
private StructDataType handleStruct(SDDocumentType type) {
+ // System.err.println("handle struct " + type + " for doc " + targetDt.getName());
if (type.isStruct()) {
var st = type.getStruct();
if (st.getName().equals(type.getName()) &&
(st instanceof StructDataType) &&
- ! (st instanceof TemporaryStructuredDataType))
+ (! (st instanceof TemporaryUnknownType)) &&
+ (! (st instanceof OwnedTemporaryType)))
{
return handleStruct((StructDataType) st);
}
}
- StructDataType s = new StructDataType(type.getName());
+ StructDataType s = new OwnedStructDataType(type.getName(), targetDt.getName());
for (Field f : type.getDocumentType().contentStruct().getFieldsThisTypeOnly()) {
specialHandleAnnotationReference(f);
s.addField(f);
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/document/Attribute.java b/config-model/src/main/java/com/yahoo/searchdefinition/document/Attribute.java
index c592e4842a9..b466a78c69b 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/document/Attribute.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/document/Attribute.java
@@ -8,7 +8,6 @@ import com.yahoo.document.DocumentType;
import com.yahoo.document.PrimitiveDataType;
import com.yahoo.documentmodel.NewDocumentReferenceDataType;
import com.yahoo.document.StructuredDataType;
-import com.yahoo.document.TemporaryStructuredDataType;
import com.yahoo.document.TensorDataType;
import com.yahoo.document.WeightedSetDataType;
import com.yahoo.document.datatypes.BoolFieldValue;
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/document/SDField.java b/config-model/src/main/java/com/yahoo/searchdefinition/document/SDField.java
index 621e7ce8571..49ae00d0663 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/document/SDField.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/document/SDField.java
@@ -7,9 +7,10 @@ import com.yahoo.document.DocumentType;
import com.yahoo.document.Field;
import com.yahoo.document.MapDataType;
import com.yahoo.document.StructDataType;
-import com.yahoo.document.TemporaryStructuredDataType;
import com.yahoo.document.TensorDataType;
import com.yahoo.document.WeightedSetDataType;
+import com.yahoo.documentmodel.OwnedTemporaryType;
+import com.yahoo.documentmodel.TemporaryUnknownType;
import com.yahoo.language.Linguistics;
import com.yahoo.language.process.Embedder;
import com.yahoo.language.simple.SimpleLinguistics;
@@ -307,7 +308,11 @@ public class SDField extends Field implements TypedKey, FieldOperationContainer,
return;
}
SDDocumentType subType = sdoc != null ? sdoc.getType(dataType.getName()) : null;
- if (dataType instanceof TemporaryStructuredDataType && subType != null) {
+ if (dataType instanceof TemporaryUnknownType && subType != null) {
+ for (Field field : subType.fieldSet()) {
+ supplyStructField.accept(field.getName(), field.getDataType());
+ }
+ } else if (dataType instanceof OwnedTemporaryType && subType != null) {
for (Field field : subType.fieldSet()) {
supplyStructField.accept(field.getName(), field.getDataType());
}
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ConvertParsedTypes.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ConvertParsedTypes.java
index f628db85429..8e27b581769 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ConvertParsedTypes.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ConvertParsedTypes.java
@@ -4,11 +4,12 @@ package com.yahoo.searchdefinition.parser;
import com.yahoo.document.DataType;
import com.yahoo.document.DocumentType;
import com.yahoo.document.DocumentTypeManager;
-import com.yahoo.documentmodel.NewDocumentReferenceDataType;
-import com.yahoo.document.StructDataType;
import com.yahoo.document.PositionDataType;
+import com.yahoo.document.StructDataType;
import com.yahoo.document.WeightedSetDataType;
import com.yahoo.document.annotation.AnnotationReferenceDataType;
+import com.yahoo.documentmodel.NewDocumentReferenceDataType;
+import com.yahoo.documentmodel.OwnedStructDataType;
import com.yahoo.searchdefinition.document.annotation.SDAnnotationType;
import java.util.ArrayList;
@@ -58,7 +59,7 @@ public class ConvertParsedTypes {
var doc = schema.getDocument();
for (var struct : doc.getStructs()) {
String structId = doc.name() + "->" + struct.name();
- var dt = new StructDataType(struct.name());
+ var dt = new OwnedStructDataType(struct.name(), doc.name());
structsFromSchemas.put(structId, dt);
}
for (var annotation : doc.getAnnotations()) {
@@ -72,7 +73,7 @@ public class ConvertParsedTypes {
if (withStruct.isPresent()) {
ParsedStruct struct = withStruct.get();
String structId = doc.name() + "->" + struct.name();
- var old = structsFromSchemas.put(structId, new StructDataType(struct.name()));
+ var old = structsFromSchemas.put(structId, new OwnedStructDataType(struct.name(), doc.name()));
assert(old == null);
}
}
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedBlock.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedBlock.java
index 213733f7722..151da352f2f 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedBlock.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedBlock.java
@@ -15,6 +15,7 @@ public class ParsedBlock {
}
public final String name() { return name; }
+ public final String blockType() { return blockType; }
protected void verifyThat(boolean check, String msg, Object ... msgDetails) {
if (check) return;
@@ -28,5 +29,8 @@ public class ParsedBlock {
throw new IllegalArgumentException(buf.toString());
}
+ public String toString() {
+ return blockType + " '" + name + "'";
+ }
}
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedDocument.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedDocument.java
index ca128a93590..ea138808289 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedDocument.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedDocument.java
@@ -62,8 +62,9 @@ public class ParsedDocument extends ParsedBlock {
void inherit(String other) { inherited.add(other); }
void addField(ParsedField field) {
- String fieldName = field.name();
- verifyThat(! docFields.containsKey(fieldName), "already has field", fieldName);
+ String fieldName = field.name().toLowerCase();
+ verifyThat(! docFields.containsKey(fieldName),
+ "Duplicate (case insensitively) " + field + " in document type '" + this.name() + "'");
docFields.put(fieldName, field);
}
@@ -81,8 +82,6 @@ public class ParsedDocument extends ParsedBlock {
annotation.tagOwner(this);
}
- public String toString() { return "document " + name(); }
-
void resolveInherit(String name, ParsedDocument parsed) {
verifyThat(inherited.contains(name), "resolveInherit for non-inherited name", name);
verifyThat(name.equals(parsed.name()), "resolveInherit name mismatch for", name);
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedType.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedType.java
index d04277706a1..a5f00b1ce45 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedType.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedType.java
@@ -32,6 +32,61 @@ class ParsedType {
private boolean createIfNonExistent = false;
private boolean removeIfZero = false;
+ public String toString() {
+ var buf = new StringBuilder();
+ buf.append("[type ").append(variant).append("] {");
+ switch (variant) {
+ case NONE:
+ break;
+ case BUILTIN:
+ buf.append(name);
+ break;
+ case POSITION:
+ buf.append(name);
+ break;
+ case TENSOR:
+ buf.append(tensorType.toString());
+ break;
+ case ARRAY: buf
+ .append(" array<")
+ .append(valType.toString())
+ .append("> ");
+ break;
+ case WSET: buf
+ .append(" weightedset<")
+ .append(valType.toString())
+ .append(">");
+ if (createIfNonExistent) buf.append(",createIfNonExistent");
+ if (removeIfZero) buf.append(",removeIfZero");
+ buf.append(" ");
+ break;
+ case MAP: buf
+ .append(" map<")
+ .append(keyType.toString())
+ .append(",")
+ .append(valType.toString())
+ .append("> ");
+ break;
+ case DOC_REFERENCE: buf
+ .append(" reference<")
+ .append(valType.toString())
+ .append("> ");
+ break;
+ case ANN_REFERENCE: buf
+ .append(" ")
+ .append(toString())
+ .append(" ");
+ break;
+ case STRUCT:
+ case DOCUMENT:
+ case UNKNOWN:
+ buf.append(" ").append(name).append(" ");
+ break;
+ }
+ buf.append("}");
+ return buf.toString();
+ }
+
private static Variant guessVariant(String name) {
switch (name) {
case "bool": return Variant.BUILTIN;
diff --git a/config-model/src/main/java/com/yahoo/vespa/configmodel/producers/DocumentManager.java b/config-model/src/main/java/com/yahoo/vespa/configmodel/producers/DocumentManager.java
index ff311795089..8867ab63e2b 100644
--- a/config-model/src/main/java/com/yahoo/vespa/configmodel/producers/DocumentManager.java
+++ b/config-model/src/main/java/com/yahoo/vespa/configmodel/producers/DocumentManager.java
@@ -9,6 +9,8 @@ import com.yahoo.document.annotation.AnnotationType;
import com.yahoo.documentmodel.DataTypeCollection;
import com.yahoo.documentmodel.NewDocumentReferenceDataType;
import com.yahoo.documentmodel.NewDocumentType;
+import com.yahoo.documentmodel.OwnedTemporaryType;
+import com.yahoo.documentmodel.TemporaryUnknownType;
import com.yahoo.documentmodel.VespaDocumentType;
import com.yahoo.searchdefinition.document.FieldSet;
import com.yahoo.vespa.documentmodel.DocumentModel;
@@ -83,6 +85,12 @@ public class DocumentManager {
if (dataType instanceof TemporaryStructuredDataType) {
throw new IllegalArgumentException("Can not create config for temporary data type: " + dataType.getName());
}
+ if (dataType instanceof TemporaryUnknownType) {
+ throw new IllegalArgumentException("Can not create config for temporary data type: " + dataType.getName());
+ }
+ if (dataType instanceof OwnedTemporaryType) {
+ throw new IllegalArgumentException("Can not create config for temporary data type: " + dataType.getName());
+ }
if ((dataType.getId() < 0) || (dataType.getId()> DataType.lastPredefinedDataTypeId())) {
Datatype.Builder dataTypeBuilder = new Datatype.Builder();
documentConfigBuilder.datatype(dataTypeBuilder);
@@ -144,8 +152,6 @@ public class DocumentManager {
}
buildConfig(dt.getFieldSets(), doc);
buildImportedFieldsConfig(dt.getImportedFieldNames(), doc);
- } else if (type instanceof TemporaryStructuredDataType) {
- throw new IllegalArgumentException("Can not create config for temporary data type: " + type.getName());
} else if (type instanceof StructDataType) {
StructDataType structType = (StructDataType) type;
Datatype.Structtype.Builder structBuilder = new Datatype.Structtype.Builder();
@@ -348,7 +354,11 @@ public class DocumentManager {
indexMap.setDone(type);
if (type instanceof TemporaryStructuredDataType) {
throw new IllegalArgumentException("Can not create config for temporary data type: " + type.getName());
- } if (type instanceof StructDataType) {
+ } else if (type instanceof TemporaryUnknownType) {
+ throw new IllegalArgumentException("Can not create config for temporary data type: " + type.getName());
+ } else if (type instanceof OwnedTemporaryType) {
+ throw new IllegalArgumentException("Can not create config for temporary data type: " + type.getName());
+ } else if (type instanceof StructDataType) {
docTypeBuildOneType((StructDataType) type, documentBuilder, indexMap);
} else if (type instanceof ArrayDataType) {
docTypeBuildOneType((ArrayDataType) type, documentBuilder, indexMap);
diff --git a/config-model/src/main/java/com/yahoo/vespa/configmodel/producers/DocumentTypes.java b/config-model/src/main/java/com/yahoo/vespa/configmodel/producers/DocumentTypes.java
index 1240dac8bf1..e1a28c8114f 100644
--- a/config-model/src/main/java/com/yahoo/vespa/configmodel/producers/DocumentTypes.java
+++ b/config-model/src/main/java/com/yahoo/vespa/configmodel/producers/DocumentTypes.java
@@ -8,6 +8,8 @@ import com.yahoo.document.annotation.AnnotationType;
import com.yahoo.documentmodel.DataTypeCollection;
import com.yahoo.documentmodel.NewDocumentReferenceDataType;
import com.yahoo.documentmodel.NewDocumentType;
+import com.yahoo.documentmodel.OwnedTemporaryType;
+import com.yahoo.documentmodel.TemporaryUnknownType;
import com.yahoo.documentmodel.VespaDocumentType;
import com.yahoo.searchdefinition.document.FieldSet;
import com.yahoo.vespa.documentmodel.DocumentModel;
@@ -111,6 +113,12 @@ public class DocumentTypes {
built.add(type.getId());
DocumenttypesConfig.Documenttype.Datatype.Builder dataTypeBuilder = new DocumenttypesConfig.Documenttype.Datatype.Builder();
dataTypeBuilder.id(type.getId());
+ if (type instanceof TemporaryUnknownType) {
+ throw new IllegalArgumentException("Can not create config for temporary data type: " + type.getName());
+ }
+ if (type instanceof OwnedTemporaryType) {
+ throw new IllegalArgumentException("Can not create config for temporary data type: " + type.getName());
+ }
if (type instanceof StructDataType) {
buildConfig((StructDataType) type, dataTypeBuilder, documentBuilder, built);
} else if (type instanceof ArrayDataType) {
diff --git a/config-model/src/main/javacc/SDParser.jj b/config-model/src/main/javacc/SDParser.jj
index 018531616fb..ab0cdefc355 100644
--- a/config-model/src/main/javacc/SDParser.jj
+++ b/config-model/src/main/javacc/SDParser.jj
@@ -826,9 +826,10 @@ SDDocumentType structDefinition(Schema schema, SDDocumentType repo) :
// empty
}
SDDocumentType sdtype = repo.getOwnedType(struct.getDocumentName());
- DataType stype = sdtype != null
- ? sdtype.getStruct()
- : TemporaryStructuredDataType.create(struct.getName());
+ if (sdtype != null) {
+ throw new ParseException("Struct '" + name + "' is already defined.");
+ }
+ DataType stype = new OwnedTemporaryType(name, repo.getName());
struct.setStruct(stype);
return struct;
}
@@ -847,7 +848,6 @@ DataType dataType() :
DataType arrayType = null;
DataType wsetType = null;
TensorType tensorType;
- TemporaryStructuredDataType referenceType;
String referencedDoc;
}
{
@@ -863,9 +863,9 @@ DataType dataType() :
DataType type = VespaDocumentType.INSTANCE.getDataType(typeName);
if (type == null) {
- // we are basically creating TemporaryStructDataType instances for ANYTHING here!!
+ // we are basically creating TemporaryUnknownType instances for ANYTHING here!!
// we must do this and clean them up later.
- type = TemporaryStructuredDataType.create(typeName);
+ type = new TemporaryUnknownType(typeName);
}
if (isArrayOldStyle) {
diff --git a/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java b/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java
index 91aff3935ab..183ab56d45f 100644
--- a/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java
+++ b/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java
@@ -48,6 +48,9 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import static com.yahoo.config.model.test.TestUtil.joinLines;
+import static com.yahoo.config.provision.NodeResources.Architecture;
+import static com.yahoo.config.provision.NodeResources.DiskSpeed;
+import static com.yahoo.config.provision.NodeResources.StorageType;
import static com.yahoo.vespa.defaults.Defaults.getDefaults;
import static com.yahoo.vespa.model.search.NodeResourcesTuning.GB;
import static com.yahoo.vespa.model.search.NodeResourcesTuning.reservedMemoryGb;
@@ -550,7 +553,7 @@ public class ModelProvisioningTest {
assertEquals(3, subGroups.get(0).getNodes().size());
assertEquals(0, subGroups.get(0).getNodes().get(0).getDistributionKey());
assertEquals("bar/storage/0", subGroups.get(0).getNodes().get(0).getConfigId());
- assertEquals("node-1-3-10-57", subGroups.get(0).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-50-57", subGroups.get(0).getNodes().get(0).getHostName());
assertEquals(1, subGroups.get(0).getNodes().get(1).getDistributionKey());
assertEquals("bar/storage/1", subGroups.get(0).getNodes().get(1).getConfigId());
assertEquals(2, subGroups.get(0).getNodes().get(2).getDistributionKey());
@@ -559,13 +562,13 @@ public class ModelProvisioningTest {
assertEquals(3, subGroups.get(1).getNodes().size());
assertEquals(3, subGroups.get(1).getNodes().get(0).getDistributionKey());
assertEquals("bar/storage/3", subGroups.get(1).getNodes().get(0).getConfigId());
- assertEquals("node-1-3-10-54", subGroups.get(1).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-50-54", subGroups.get(1).getNodes().get(0).getHostName());
assertEquals(4, subGroups.get(1).getNodes().get(1).getDistributionKey());
assertEquals("bar/storage/4", subGroups.get(1).getNodes().get(1).getConfigId());
assertEquals(5, subGroups.get(1).getNodes().get(2).getDistributionKey());
assertEquals("bar/storage/5", subGroups.get(1).getNodes().get(2).getConfigId());
// ...
- assertEquals("node-1-3-10-51", subGroups.get(2).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-50-51", subGroups.get(2).getNodes().get(0).getHostName());
// ...
assertEquals("8", subGroups.get(8).getIndex());
assertEquals(3, subGroups.get(8).getNodes().size());
@@ -584,14 +587,14 @@ public class ModelProvisioningTest {
assertEquals(1, subGroups.get(0).getNodes().size());
assertEquals(0, subGroups.get(0).getNodes().get(0).getDistributionKey());
assertEquals("baz/storage/0", subGroups.get(0).getNodes().get(0).getConfigId());
- assertEquals("node-1-3-10-27", subGroups.get(0).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-50-27", subGroups.get(0).getNodes().get(0).getHostName());
assertEquals("1", subGroups.get(1).getIndex());
assertEquals(1, subGroups.get(1).getNodes().size());
assertEquals(1, subGroups.get(1).getNodes().get(0).getDistributionKey());
assertEquals("baz/storage/1", subGroups.get(1).getNodes().get(0).getConfigId());
- assertEquals("node-1-3-10-26", subGroups.get(1).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-50-26", subGroups.get(1).getNodes().get(0).getHostName());
// ...
- assertEquals("node-1-3-10-25", subGroups.get(2).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-50-25", subGroups.get(2).getNodes().get(0).getHostName());
// ...
assertEquals("26", subGroups.get(26).getIndex());
assertEquals(1, subGroups.get(26).getNodes().size());
@@ -691,7 +694,7 @@ public class ModelProvisioningTest {
assertEquals(3, subGroups.get(0).getNodes().size());
assertEquals(0, subGroups.get(0).getNodes().get(0).getDistributionKey());
assertEquals("bar/storage/0", subGroups.get(0).getNodes().get(0).getConfigId());
- assertEquals("node-1-3-10-57", subGroups.get(0).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-50-57", subGroups.get(0).getNodes().get(0).getHostName());
assertEquals(1, subGroups.get(0).getNodes().get(1).getDistributionKey());
assertEquals("bar/storage/1", subGroups.get(0).getNodes().get(1).getConfigId());
assertEquals(2, subGroups.get(0).getNodes().get(2).getDistributionKey());
@@ -700,13 +703,13 @@ public class ModelProvisioningTest {
assertEquals(3, subGroups.get(1).getNodes().size());
assertEquals(3, subGroups.get(1).getNodes().get(0).getDistributionKey());
assertEquals("bar/storage/3", subGroups.get(1).getNodes().get(0).getConfigId());
- assertEquals("node-1-3-10-54", subGroups.get(1).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-50-54", subGroups.get(1).getNodes().get(0).getHostName());
assertEquals(4, subGroups.get(1).getNodes().get(1).getDistributionKey());
assertEquals("bar/storage/4", subGroups.get(1).getNodes().get(1).getConfigId());
assertEquals(5, subGroups.get(1).getNodes().get(2).getDistributionKey());
assertEquals("bar/storage/5", subGroups.get(1).getNodes().get(2).getConfigId());
// ...
- assertEquals("node-1-3-10-51", subGroups.get(2).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-50-51", subGroups.get(2).getNodes().get(0).getHostName());
// ...
assertEquals("8", subGroups.get(8).getIndex());
assertEquals(3, subGroups.get(8).getNodes().size());
@@ -725,14 +728,14 @@ public class ModelProvisioningTest {
assertEquals(1, subGroups.get(0).getNodes().size());
assertEquals(0, subGroups.get(0).getNodes().get(0).getDistributionKey());
assertEquals("baz/storage/0", subGroups.get(0).getNodes().get(0).getConfigId());
- assertEquals("node-1-3-10-27", subGroups.get(0).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-50-27", subGroups.get(0).getNodes().get(0).getHostName());
assertEquals("1", subGroups.get(1).getIndex());
assertEquals(1, subGroups.get(1).getNodes().size());
assertEquals(1, subGroups.get(1).getNodes().get(0).getDistributionKey());
assertEquals("baz/storage/1", subGroups.get(1).getNodes().get(0).getConfigId());
- assertEquals("node-1-3-10-26", subGroups.get(1).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-50-26", subGroups.get(1).getNodes().get(0).getHostName());
// ...
- assertEquals("node-1-3-10-25", subGroups.get(2).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-50-25", subGroups.get(2).getNodes().get(0).getHostName());
// ...
assertEquals("26", subGroups.get(26).getIndex());
assertEquals(1, subGroups.get(26).getNodes().size());
@@ -767,9 +770,9 @@ public class ModelProvisioningTest {
ClusterControllerContainerCluster clusterControllers = model.getAdmin().getClusterControllers();
assertEquals(3, clusterControllers.getContainers().size());
assertEquals("cluster-controllers", clusterControllers.getName());
- assertEquals("node-1-3-10-03", clusterControllers.getContainers().get(0).getHostName());
- assertEquals("node-1-3-10-02", clusterControllers.getContainers().get(1).getHostName());
- assertEquals("node-1-3-10-01", clusterControllers.getContainers().get(2).getHostName());
+ assertEquals("node-1-3-50-03", clusterControllers.getContainers().get(0).getHostName());
+ assertEquals("node-1-3-50-02", clusterControllers.getContainers().get(1).getHostName());
+ assertEquals("node-1-3-50-01", clusterControllers.getContainers().get(2).getHostName());
// Check content cluster
ContentCluster cluster = model.getContentClusters().get("bar");
@@ -782,19 +785,19 @@ public class ModelProvisioningTest {
assertEquals(1, subGroups.get(0).getNodes().size());
assertEquals(0, subGroups.get(0).getNodes().get(0).getDistributionKey());
assertEquals("bar/storage/0", subGroups.get(0).getNodes().get(0).getConfigId());
- assertEquals("node-1-3-10-11", subGroups.get(0).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-50-11", subGroups.get(0).getNodes().get(0).getHostName());
// second group
assertEquals("1", subGroups.get(1).getIndex());
assertEquals(1, subGroups.get(1).getNodes().size());
assertEquals(1, subGroups.get(1).getNodes().get(0).getDistributionKey());
assertEquals("bar/storage/1", subGroups.get(1).getNodes().get(0).getConfigId());
- assertEquals("node-1-3-10-10", subGroups.get(1).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-50-10", subGroups.get(1).getNodes().get(0).getHostName());
// ... last group
assertEquals("7", subGroups.get(7).getIndex());
assertEquals(1, subGroups.get(7).getNodes().size());
assertEquals(7, subGroups.get(7).getNodes().get(0).getDistributionKey());
assertEquals("bar/storage/7", subGroups.get(7).getNodes().get(0).getConfigId());
- assertEquals("node-1-3-10-04", subGroups.get(7).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-50-04", subGroups.get(7).getNodes().get(0).getHostName());
}
@Test
@@ -811,15 +814,15 @@ public class ModelProvisioningTest {
int numberOfHosts = 11;
VespaModelTester tester = new VespaModelTester();
tester.addHosts(numberOfHosts);
- VespaModel model = tester.createModel(services, true, "node-1-3-10-09");
+ VespaModel model = tester.createModel(services, true, "node-1-3-50-09");
assertEquals(numberOfHosts, model.getRoot().hostSystem().getHosts().size());
// Check slobroks clusters
assertEquals("Includes retired node", 1+3, model.getAdmin().getSlobroks().size());
- assertEquals("node-1-3-10-11", model.getAdmin().getSlobroks().get(0).getHostName());
- assertEquals("node-1-3-10-10", model.getAdmin().getSlobroks().get(1).getHostName());
- assertEquals("node-1-3-10-08", model.getAdmin().getSlobroks().get(2).getHostName());
- assertEquals("Included in addition because it is retired", "node-1-3-10-09", model.getAdmin().getSlobroks().get(3).getHostName());
+ assertEquals("node-1-3-50-11", model.getAdmin().getSlobroks().get(0).getHostName());
+ assertEquals("node-1-3-50-10", model.getAdmin().getSlobroks().get(1).getHostName());
+ assertEquals("node-1-3-50-08", model.getAdmin().getSlobroks().get(2).getHostName());
+ assertEquals("Included in addition because it is retired", "node-1-3-50-09", model.getAdmin().getSlobroks().get(3).getHostName());
}
@Test
@@ -836,16 +839,16 @@ public class ModelProvisioningTest {
int numberOfHosts = 12;
VespaModelTester tester = new VespaModelTester();
tester.addHosts(numberOfHosts);
- VespaModel model = tester.createModel(services, true, "node-1-3-10-03", "node-1-3-10-04");
+ VespaModel model = tester.createModel(services, true, "node-1-3-50-03", "node-1-3-50-04");
assertEquals(10+2, model.getRoot().hostSystem().getHosts().size());
// Check slobroks clusters
assertEquals("Includes retired node", 3+2, model.getAdmin().getSlobroks().size());
- assertEquals("node-1-3-10-12", model.getAdmin().getSlobroks().get(0).getHostName());
- assertEquals("node-1-3-10-11", model.getAdmin().getSlobroks().get(1).getHostName());
- assertEquals("node-1-3-10-10", model.getAdmin().getSlobroks().get(2).getHostName());
- assertEquals("Included in addition because it is retired", "node-1-3-10-04", model.getAdmin().getSlobroks().get(3).getHostName());
- assertEquals("Included in addition because it is retired", "node-1-3-10-03", model.getAdmin().getSlobroks().get(4).getHostName());
+ assertEquals("node-1-3-50-12", model.getAdmin().getSlobroks().get(0).getHostName());
+ assertEquals("node-1-3-50-11", model.getAdmin().getSlobroks().get(1).getHostName());
+ assertEquals("node-1-3-50-10", model.getAdmin().getSlobroks().get(2).getHostName());
+ assertEquals("Included in addition because it is retired", "node-1-3-50-04", model.getAdmin().getSlobroks().get(3).getHostName());
+ assertEquals("Included in addition because it is retired", "node-1-3-50-03", model.getAdmin().getSlobroks().get(4).getHostName());
}
@Test
@@ -865,19 +868,19 @@ public class ModelProvisioningTest {
int numberOfHosts = 16;
VespaModelTester tester = new VespaModelTester();
tester.addHosts(numberOfHosts);
- VespaModel model = tester.createModel(services, true, "node-1-3-10-15", "node-1-3-10-05", "node-1-3-10-04");
+ VespaModel model = tester.createModel(services, true, "node-1-3-50-15", "node-1-3-50-05", "node-1-3-50-04");
assertEquals(numberOfHosts, model.getRoot().hostSystem().getHosts().size());
// Check slobroks clusters
// ... from cluster default
assertEquals("Includes retired node", 7, model.getAdmin().getSlobroks().size());
- assertEquals("node-1-3-10-16", model.getAdmin().getSlobroks().get(0).getHostName());
- assertEquals("node-1-3-10-14", model.getAdmin().getSlobroks().get(1).getHostName());
- assertEquals("Included in addition because it is retired", "node-1-3-10-15", model.getAdmin().getSlobroks().get(2).getHostName());
+ assertEquals("node-1-3-50-16", model.getAdmin().getSlobroks().get(0).getHostName());
+ assertEquals("node-1-3-50-14", model.getAdmin().getSlobroks().get(1).getHostName());
+ assertEquals("Included in addition because it is retired", "node-1-3-50-15", model.getAdmin().getSlobroks().get(2).getHostName());
// ... from cluster bar
- assertEquals("node-1-3-10-03", model.getAdmin().getSlobroks().get(3).getHostName());
- assertEquals("Included in addition because it is retired", "node-1-3-10-05", model.getAdmin().getSlobroks().get(5).getHostName());
- assertEquals("Included in addition because it is retired", "node-1-3-10-04", model.getAdmin().getSlobroks().get(6).getHostName());
+ assertEquals("node-1-3-50-03", model.getAdmin().getSlobroks().get(3).getHostName());
+ assertEquals("Included in addition because it is retired", "node-1-3-50-05", model.getAdmin().getSlobroks().get(5).getHostName());
+ assertEquals("Included in addition because it is retired", "node-1-3-50-04", model.getAdmin().getSlobroks().get(6).getHostName());
}
@Test
@@ -1104,7 +1107,7 @@ public class ModelProvisioningTest {
int numberOfHosts = 3;
VespaModelTester tester = new VespaModelTester();
tester.addHosts(numberOfHosts);
- VespaModel model = tester.createModel(services, false, "node-1-3-10-03");
+ VespaModel model = tester.createModel(services, false, "node-1-3-50-03");
assertEquals(numberOfHosts, model.getRoot().hostSystem().getHosts().size());
ContentCluster cluster = model.getContentClusters().get("bar");
@@ -1133,7 +1136,7 @@ public class ModelProvisioningTest {
int numberOfHosts = 5;
VespaModelTester tester = new VespaModelTester();
tester.addHosts(numberOfHosts);
- VespaModel model = tester.createModel(services, false, "node-1-3-10-05", "node-1-3-10-04", "node-1-3-10-03");
+ VespaModel model = tester.createModel(services, false, "node-1-3-50-05", "node-1-3-50-04", "node-1-3-50-03");
assertEquals(numberOfHosts, model.getRoot().hostSystem().getHosts().size());
ContentCluster cluster = model.getContentClusters().get("bar");
@@ -1162,7 +1165,7 @@ public class ModelProvisioningTest {
int numberOfHosts = 3;
VespaModelTester tester = new VespaModelTester();
tester.addHosts(numberOfHosts);
- VespaModel model = tester.createModel(services, false, false, true, "node-1-3-10-03");
+ VespaModel model = tester.createModel(services, false, false, true, "node-1-3-50-03");
assertEquals(numberOfHosts, model.getRoot().hostSystem().getHosts().size());
ContentCluster cluster = model.getContentClusters().get("bar");
@@ -1474,10 +1477,12 @@ public class ModelProvisioningTest {
}
@Test
- public void testUseArm64NodesForClusterControllers() {
+ public void testUseArm64NodesForAdminCluster() {
String services =
"<?xml version='1.0' encoding='utf-8' ?>" +
"<services>" +
+ " <admin version='4.0'>" +
+ " </admin>" +
" <container version='1.0' id='container'>" +
" <nodes count='2'>" +
" <resources vcpu='2' memory='8Gb' disk='30Gb'/>" +
@@ -1495,25 +1500,34 @@ public class ModelProvisioningTest {
VespaModelTester tester = new VespaModelTester();
tester.setHosted(true);
- tester.setAdminClusterArchitecture("arm64");
- tester.addHosts(new NodeResources(13.5, 100, 1000, 0.3), 6);
- tester.addHosts(new NodeResources(85, 200, 1000_000_000, 0.3), 20);
- tester.addHosts(new NodeResources(0.5, 2, 10, 0.3, NodeResources.DiskSpeed.any, NodeResources.StorageType.any, NodeResources.Architecture.arm64), 3);
+ tester.setAdminClusterArchitecture(Architecture.arm64);
+ tester.useDedicatedNodeForLogserver(true);
+ tester.addHosts(new NodeResources(13.5, 100, 1000, 0.3), 4);
+ tester.addHosts(new NodeResources(0.5, 2, 50, 0.3, DiskSpeed.fast, StorageType.any, Architecture.arm64), 4); // 3 ccs, 1 logserver
VespaModel model = tester.createModel(services, true, true);
List<HostResource> hosts = model.getRoot().hostSystem().getHosts();
- assertEquals(7, hosts.size());
- Set<HostResource> clusterControllerResources =
- hosts.stream()
- .filter(host -> host.getHostInfo().getServices().stream()
- .anyMatch(service -> service.getServiceType().equals("container-clustercontroller")))
- .collect(Collectors.toSet());
+ assertEquals(8, hosts.size());
+
+ Set<HostResource> clusterControllerResources = getHostResourcesForService(hosts, "container-clustercontroller");
assertEquals(3, clusterControllerResources.size());
- assertTrue(clusterControllerResources.stream().allMatch(host -> host.realResources().architecture().name().equals("arm64")));
+ assertTrue(clusterControllerResources.stream().allMatch(host -> host.realResources().architecture() == Architecture.arm64));
- // Other hosts should be x86_64
+ Set<HostResource> logserverResources = getHostResourcesForService(hosts, "logserver-container");
+ assertEquals(1, logserverResources.size());
+ assertTrue(logserverResources.stream().allMatch(host -> host.realResources().architecture() == Architecture.arm64));
+
+ // Other hosts should be default
assertTrue(hosts.stream()
.filter(host -> !clusterControllerResources.contains(host))
- .allMatch(host -> host.realResources().architecture().name().equals("x86_64")));
+ .filter(host -> !logserverResources.contains(host))
+ .allMatch(host -> host.realResources().architecture() == Architecture.getDefault()));
+ }
+
+ private Set<HostResource> getHostResourcesForService(List<HostResource> hosts, String service) {
+ return hosts.stream()
+ .filter(host -> host.getHostInfo().getServices().stream()
+ .anyMatch(s -> s.getServiceType().equals(service)))
+ .collect(Collectors.toSet());
}
@Test
@@ -2132,7 +2146,7 @@ public class ModelProvisioningTest {
"</services>";
VespaModelTester tester = new VespaModelTester();
tester.addHosts(4);
- VespaModel model = tester.createModel(servicesXml, true, "node-1-3-10-04");
+ VespaModel model = tester.createModel(servicesXml, true, "node-1-3-50-04");
ApplicationContainerCluster cluster = model.getContainerClusters().get("zk");
assertEquals(1, cluster.getContainers().stream().filter(Container::isRetired).count());
assertEquals(3, cluster.getContainers().stream().filter(c -> !c.isRetired()).count());
@@ -2161,7 +2175,7 @@ public class ModelProvisioningTest {
assertTrue("Initial servers are not joining", config.build().server().stream().noneMatch(ZookeeperServerConfig.Server::joining));
}
{
- VespaModel nextModel = tester.createModel(Zone.defaultZone(), servicesXml.apply(3), true, false, false, 0, Optional.of(model), new DeployState.Builder(), "node-1-3-10-04", "node-1-3-10-03");
+ VespaModel nextModel = tester.createModel(Zone.defaultZone(), servicesXml.apply(3), true, false, false, 0, Optional.of(model), new DeployState.Builder(), "node-1-3-50-04", "node-1-3-50-03");
ApplicationContainerCluster cluster = nextModel.getContainerClusters().get("zk");
ZookeeperServerConfig.Builder config = new ZookeeperServerConfig.Builder();
cluster.getContainers().forEach(c -> c.getConfig(config));
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/DocumentGraphValidatorTest.java b/config-model/src/test/java/com/yahoo/searchdefinition/DocumentGraphValidatorTest.java
index 8c8cb59e9d9..5bbb751585b 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/DocumentGraphValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/DocumentGraphValidatorTest.java
@@ -3,7 +3,6 @@ package com.yahoo.searchdefinition;
import com.yahoo.config.model.test.MockApplicationPackage;
import com.yahoo.documentmodel.NewDocumentReferenceDataType;
-import com.yahoo.document.TemporaryStructuredDataType;
import com.yahoo.searchdefinition.document.SDDocumentType;
import com.yahoo.searchdefinition.document.SDField;
import com.yahoo.searchdefinition.document.TemporarySDField;
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/DocumentReferenceResolverTest.java b/config-model/src/test/java/com/yahoo/searchdefinition/DocumentReferenceResolverTest.java
index b23ad4eb5b6..fe1b19be64b 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/DocumentReferenceResolverTest.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/DocumentReferenceResolverTest.java
@@ -4,7 +4,6 @@ package com.yahoo.searchdefinition;
import com.yahoo.config.model.test.MockApplicationPackage;
import com.yahoo.document.DataType;
import com.yahoo.documentmodel.NewDocumentReferenceDataType;
-import com.yahoo.document.TemporaryStructuredDataType;
import com.yahoo.searchdefinition.document.SDDocumentType;
import com.yahoo.searchdefinition.document.SDField;
import org.junit.Rule;
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/derived/SchemaOrdererTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/derived/SchemaOrdererTestCase.java
index ed3f5cb0ba6..11e21c7915d 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/derived/SchemaOrdererTestCase.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/derived/SchemaOrdererTestCase.java
@@ -3,7 +3,6 @@ package com.yahoo.searchdefinition.derived;
import com.yahoo.config.model.test.MockApplicationPackage;
import com.yahoo.documentmodel.NewDocumentReferenceDataType;
-import com.yahoo.document.TemporaryStructuredDataType;
import com.yahoo.searchdefinition.DocumentReference;
import com.yahoo.searchdefinition.DocumentReferences;
import com.yahoo.searchdefinition.Schema;
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/derived/VsmFieldsTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/derived/VsmFieldsTestCase.java
index 2d6b3acc4dd..9855ca30ebc 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/derived/VsmFieldsTestCase.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/derived/VsmFieldsTestCase.java
@@ -5,7 +5,6 @@ import com.yahoo.config.model.application.provider.MockFileRegistry;
import com.yahoo.config.model.deploy.TestProperties;
import com.yahoo.config.model.test.MockApplicationPackage;
import com.yahoo.documentmodel.NewDocumentReferenceDataType;
-import com.yahoo.document.TemporaryStructuredDataType;
import com.yahoo.searchdefinition.Application;
import com.yahoo.searchdefinition.Schema;
import com.yahoo.searchdefinition.document.SDDocumentType;
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/parser/IntermediateParserTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/parser/IntermediateParserTestCase.java
index 8bd04af8c54..36a72381156 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/parser/IntermediateParserTestCase.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/parser/IntermediateParserTestCase.java
@@ -69,7 +69,7 @@ public class IntermediateParserTestCase {
" }",
"}");
var e = assertThrows(IllegalArgumentException.class, () -> parseString(input));
- assertEquals("schema 'foo' error: already has document foo so cannot add document foo2", e.getMessage());
+ assertEquals("schema 'foo' error: already has document 'foo' so cannot add document 'foo2'", e.getMessage());
}
void checkFileParses(String fileName) throws Exception {
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/parser/ParsedDocumentTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/parser/ParsedDocumentTestCase.java
index 79d26fab404..9ae7b3aa4b8 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/parser/ParsedDocumentTestCase.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/parser/ParsedDocumentTestCase.java
@@ -21,7 +21,10 @@ public class ParsedDocumentTestCase {
var e = assertThrows(IllegalArgumentException.class, () ->
doc.addField(new ParsedField("zap", stringType)));
System.err.println("As expected: "+e);
- assertEquals("document 'foo' error: already has field zap", e.getMessage());
+ assertEquals("document 'foo' error: Duplicate (case insensitively) field 'zap' in document type 'foo'", e.getMessage());
+ e = assertThrows(IllegalArgumentException.class, () ->
+ doc.addField(new ParsedField("ZAP", stringType)));
+ assertEquals("document 'foo' error: Duplicate (case insensitively) field 'ZAP' in document type 'foo'", e.getMessage());
}
}
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/ParentChildSearchModel.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/ParentChildSearchModel.java
index 0b615595794..6ddacd066b1 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/processing/ParentChildSearchModel.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/ParentChildSearchModel.java
@@ -7,7 +7,6 @@ import com.yahoo.config.model.deploy.TestProperties;
import com.yahoo.config.model.test.MockApplicationPackage;
import com.yahoo.document.DataType;
import com.yahoo.documentmodel.NewDocumentReferenceDataType;
-import com.yahoo.document.TemporaryStructuredDataType;
import com.yahoo.searchdefinition.Application;
import com.yahoo.searchdefinition.DocumentReference;
import com.yahoo.searchdefinition.DocumentReferences;
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerClusterTest.java
index c00a5f65d08..7bf08461df7 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerClusterTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerClusterTest.java
@@ -104,7 +104,7 @@ public class MetricsProxyContainerClusterTest {
private void assertNodeConfig(MetricsNodesConfig.Node node) {
assertTrue(node.role().startsWith("container/foo/0/"));
- assertTrue(node.hostname().startsWith("node-1-3-10-"));
+ assertTrue(node.hostname().startsWith("node-1-3-50-"));
assertEquals(MetricsProxyContainer.BASEPORT, node.metricsPort());
assertEquals(MetricsV1Handler.VALUES_PATH, node.metricsPath());
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerTest.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerTest.java
index ad3a163f052..9b1ff54482b 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerTest.java
@@ -136,7 +136,7 @@ public class MetricsProxyContainerTest {
NodeInfoConfig config = hostedModel.getConfig(NodeInfoConfig.class, metricsV2Handler.getConfigId());
assertTrue(config.role().startsWith("content/my-content/0/"));
- assertTrue(config.hostname().startsWith("node-1-3-10-"));
+ assertTrue(config.hostname().startsWith("node-1-3-50-"));
}
@Test
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java b/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java
index b9a5fde9301..41f9b4c7b55 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java
@@ -30,6 +30,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
+import static com.yahoo.config.provision.NodeResources.Architecture;
import static com.yahoo.vespa.model.test.utils.ApplicationPackageUtils.generateSchemas;
/**
@@ -53,7 +54,7 @@ public class VespaModelTester {
private final Map<NodeResources, Collection<Host>> hostsByResources = new HashMap<>();
private ApplicationId applicationId = ApplicationId.defaultId();
private boolean useDedicatedNodeForLogserver = false;
- private String adminClusterArchitecture = "x86_64";
+ private Architecture adminClusterArchitecture = Architecture.getDefault();;
private HostProvisioner provisioner;
public VespaModelTester() {
@@ -102,7 +103,9 @@ public class VespaModelTester {
public void setHosted(boolean hosted) { this.hosted = hosted; }
/** Sets architecture to use for admin clusters. Default: x86_64 */
- public void setAdminClusterArchitecture(String architecture) { this.adminClusterArchitecture = architecture; }
+ public void setAdminClusterArchitecture(Architecture architecture) {
+ this.adminClusterArchitecture = architecture;
+ }
/** Sets the tenant, application name, and instance name of the model being built. */
public void setApplicationId(String tenant, String applicationName, String instanceName) {
diff --git a/config/src/vespa/config/frt/frtconnectionpool.cpp b/config/src/vespa/config/frt/frtconnectionpool.cpp
index 2ae812cd76e..0c11401e052 100644
--- a/config/src/vespa/config/frt/frtconnectionpool.cpp
+++ b/config/src/vespa/config/frt/frtconnectionpool.cpp
@@ -73,11 +73,13 @@ FRTConnectionPool::getNextRoundRobin()
FRTConnection* nextFRTConnection = nullptr;
if ( ! ready.empty()) {
- int sel = _selectIdx % (int)ready.size();
+ unsigned int sel = _selectIdx % (int)ready.size();
+ LOG_ASSERT(sel < ready.size());
_selectIdx = sel + 1;
nextFRTConnection = ready[sel];
} else if ( ! suspended.empty()) {
- int sel = _selectIdx % (int)suspended.size();
+ unsigned int sel = _selectIdx % (int)suspended.size();
+ LOG_ASSERT(sel < suspended.size());
_selectIdx = sel + 1;
nextFRTConnection = suspended[sel];
}
@@ -113,10 +115,12 @@ FRTConnectionPool::getNextHashBased()
FRTConnection* nextFRTConnection = nullptr;
if ( ! ready.empty()) {
- int sel = std::abs(hashCode(_hostname) % (int)ready.size());
+ unsigned int sel = std::abs(hashCode(_hostname) % (int)ready.size());
+ LOG_ASSERT(sel < ready.size());
nextFRTConnection = ready[sel];
} else if ( ! suspended.empty() ){
- int sel = std::abs(hashCode(_hostname) % (int)suspended.size());
+ unsigned int sel = std::abs(hashCode(_hostname) % (int)suspended.size());
+ LOG_ASSERT(sel < suspended.size());
nextFRTConnection = suspended[sel];
}
return nextFRTConnection;
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
index 1cfc7758def..718a25cc225 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
@@ -42,6 +42,7 @@ import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.function.ToIntFunction;
+import static com.yahoo.config.provision.NodeResources.Architecture;
import static com.yahoo.vespa.config.server.ConfigServerSpec.fromConfig;
import static com.yahoo.vespa.flags.FetchVector.Dimension.CLUSTER_TYPE;
@@ -211,7 +212,7 @@ public class ModelContextImpl implements ModelContext {
private final boolean avoidRenamingSummaryFeatures;
private final boolean mergeGroupingResultInSearchInvoker;
private final boolean experimentalSdParsing;
- private final String adminClusterNodeResourcesArchitecture;
+ private final Architecture adminClusterNodeResourcesArchitecture;
public FeatureFlags(FlagSource source, ApplicationId appId, Version version) {
this.defaultTermwiseLimit = flagValue(source, appId, version, Flags.DEFAULT_TERM_WISE_LIMIT);
@@ -261,7 +262,7 @@ public class ModelContextImpl implements ModelContext {
this.avoidRenamingSummaryFeatures = flagValue(source, appId, version, Flags.AVOID_RENAMING_SUMMARY_FEATURES);
this.mergeGroupingResultInSearchInvoker = flagValue(source, appId, version, Flags.MERGE_GROUPING_RESULT_IN_SEARCH_INVOKER);
this.experimentalSdParsing = flagValue(source, appId, version, Flags.EXPERIMENTAL_SD_PARSING);
- this.adminClusterNodeResourcesArchitecture = flagValue(source, appId, version, PermanentFlags.ADMIN_CLUSTER_NODE_ARCHITECTURE);
+ this.adminClusterNodeResourcesArchitecture = Architecture.valueOf(flagValue(source, appId, version, PermanentFlags.ADMIN_CLUSTER_NODE_ARCHITECTURE));
}
@Override public double defaultTermwiseLimit() { return defaultTermwiseLimit; }
@@ -313,7 +314,8 @@ public class ModelContextImpl implements ModelContext {
@Override public boolean avoidRenamingSummaryFeatures() { return avoidRenamingSummaryFeatures; }
@Override public boolean mergeGroupingResultInSearchInvoker() { return mergeGroupingResultInSearchInvoker; }
@Override public boolean experimentalSdParsing() { return experimentalSdParsing; }
- @Override public String adminClusterNodeArchitecture() { return adminClusterNodeResourcesArchitecture; }
+ @Override public String adminClusterNodeArchitecture() { return adminClusterArchitecture().name(); } // TODO: Remove when 7.564 is oldest version in use
+ @Override public Architecture adminClusterArchitecture() { return adminClusterNodeResourcesArchitecture; }
private static <V> V flagValue(FlagSource source, ApplicationId appId, Version vespaVersion, UnboundFlag<? extends V, ?, ?> flag) {
return flag.bindTo(source)
diff --git a/configutil/src/apps/configstatus/main.cpp b/configutil/src/apps/configstatus/main.cpp
index cd0424633d9..3656013cf2e 100644
--- a/configutil/src/apps/configstatus/main.cpp
+++ b/configutil/src/apps/configstatus/main.cpp
@@ -87,7 +87,7 @@ void Application::usage() {
int Application::Main() {
parseOpts();
-
+ fprintf(stderr, "Getting config from: %s\n", _specString.c_str());
config::ServerSpec spec(_specString);
config::ConfigUri uri = config::ConfigUri::createFromSpec(_cfgId, spec);
ConfigStatus status(_flags, uri);
diff --git a/configutil/src/lib/configstatus.cpp b/configutil/src/lib/configstatus.cpp
index 841d1604866..98a6bca7ba3 100644
--- a/configutil/src/lib/configstatus.cpp
+++ b/configutil/src/lib/configstatus.cpp
@@ -109,7 +109,7 @@ public:
MyHttpHandler::~MyHttpHandler() = default;
-ConfigStatus::ConfigStatus(Flags flags, const config::ConfigUri uri)
+ConfigStatus::ConfigStatus(Flags flags, const config::ConfigUri &uri)
: _cfg(), _flags(flags), _generation(0)
{
if (_flags.verbose) {
diff --git a/configutil/src/lib/configstatus.h b/configutil/src/lib/configstatus.h
index 4d792748419..7d658c9f2c2 100644
--- a/configutil/src/lib/configstatus.h
+++ b/configutil/src/lib/configstatus.h
@@ -22,7 +22,7 @@ public:
{}
};
- ConfigStatus(Flags flags, const config::ConfigUri uri);
+ ConfigStatus(Flags flags, const config::ConfigUri &uri);
~ConfigStatus();
int action();
diff --git a/configutil/src/lib/modelinspect.cpp b/configutil/src/lib/modelinspect.cpp
index d840a7d45ca..68544a55df4 100644
--- a/configutil/src/lib/modelinspect.cpp
+++ b/configutil/src/lib/modelinspect.cpp
@@ -21,7 +21,7 @@ ModelInspect::Flags::Flags(const Flags &) = default;
ModelInspect::Flags & ModelInspect::Flags::operator = (const Flags &) = default;
ModelInspect::Flags::~Flags() { }
-ModelInspect::ModelInspect(Flags flags, const config::ConfigUri uri, std::ostream &out)
+ModelInspect::ModelInspect(Flags flags, const config::ConfigUri &uri, std::ostream &out)
: _cfg(), _flags(flags), _out(out)
{
if (_flags.verbose) {
diff --git a/configutil/src/lib/modelinspect.h b/configutil/src/lib/modelinspect.h
index 33ef94b259b..0c677b9d174 100644
--- a/configutil/src/lib/modelinspect.h
+++ b/configutil/src/lib/modelinspect.h
@@ -20,7 +20,7 @@ public:
~Flags();
};
- ModelInspect(Flags flags, const config::ConfigUri uri, std::ostream &out);
+ ModelInspect(Flags flags, const config::ConfigUri &uri, std::ostream &out);
virtual ~ModelInspect();
int action(int cnt, char *argv[]);
diff --git a/container-core/src/main/java/com/yahoo/processing/request/CompoundName.java b/container-core/src/main/java/com/yahoo/processing/request/CompoundName.java
index f0a11626236..d571bf583d6 100644
--- a/container-core/src/main/java/com/yahoo/processing/request/CompoundName.java
+++ b/container-core/src/main/java/com/yahoo/processing/request/CompoundName.java
@@ -67,7 +67,7 @@ public final class CompoundName {
this.name = name;
this.lowerCasedName = toLowerCase(name);
- if (compounds.size()==1 && compounds.get(0).isEmpty())
+ if (compounds.size() == 1 && compounds.get(0).isEmpty())
this.compounds = ImmutableList.of();
else
this.compounds = ImmutableList.copyOf(compounds);
diff --git a/container-search/abi-spec.json b/container-search/abi-spec.json
index 4d559fcb985..5b990ca8758 100644
--- a/container-search/abi-spec.json
+++ b/container-search/abi-spec.json
@@ -720,6 +720,7 @@
"public static final enum com.yahoo.prelude.query.Item$ItemType WORD",
"public static final enum com.yahoo.prelude.query.Item$ItemType INT",
"public static final enum com.yahoo.prelude.query.Item$ItemType PHRASE",
+ "public static final enum com.yahoo.prelude.query.Item$ItemType MULTI_TERM",
"public static final enum com.yahoo.prelude.query.Item$ItemType PREFIX",
"public static final enum com.yahoo.prelude.query.Item$ItemType SUBSTRING",
"public static final enum com.yahoo.prelude.query.Item$ItemType NEAR",
@@ -741,7 +742,6 @@
"public static final enum com.yahoo.prelude.query.Item$ItemType GEO_LOCATION_TERM",
"public static final enum com.yahoo.prelude.query.Item$ItemType TRUE",
"public static final enum com.yahoo.prelude.query.Item$ItemType FALSE",
- "public static final enum com.yahoo.prelude.query.Item$ItemType MULTI_TERM",
"public final int code"
]
},
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/Item.java b/container-search/src/main/java/com/yahoo/prelude/query/Item.java
index 06fe07d3895..2e0c3cf8593 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/Item.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/Item.java
@@ -26,10 +26,7 @@ import java.util.Objects;
*/
public abstract class Item implements Cloneable {
- /**
- * The definitions in Item.ItemType must match the ones in
- * searchlib/src/vespa/searchlib/parsequery/parse.h
- */
+ // These must match the types in searchlib/src/vespa/searchlib/parsequery/parse.h
public enum ItemType {
OR(0),
AND(1),
@@ -38,7 +35,7 @@ public abstract class Item implements Cloneable {
WORD(4),
INT(5),
PHRASE(6),
- // 7 was PAREN, unused in Vespa 7
+ MULTI_TERM(7),
PREFIX(8),
SUBSTRING(9),
NEAR(11),
@@ -59,8 +56,7 @@ public abstract class Item implements Cloneable {
NEAREST_NEIGHBOR(26),
GEO_LOCATION_TERM(27),
TRUE(28),
- FALSE(29),
- MULTI_TERM(30);
+ FALSE(29);
public final int code;
@@ -70,10 +66,7 @@ public abstract class Item implements Cloneable {
}
- /**
- * The definitions in Item.ItemCreator must match the ones in
- * searchlib/src/searchlib/parsequery/parse.h
- */
+ // These must match the definitions in searchlib/src/searchlib/parsequery/parse.h
public enum ItemCreator {
ORIG(0),
@@ -266,11 +259,11 @@ public abstract class Item implements Cloneable {
}
/**
- * Returns an integer that contains all feature flags for this item. This must be kept in sync with the flags
- * defined in searchlib/parsequery/parse.h.
+ * Returns an integer that contains all feature flags for this item.
*
* @return the feature flags
*/
+ // This must be kept in sync with the flags in searchlib/parsequery/parse.h.
private byte getFlagsFeature() {
byte FLAGS_NORANK = 0x01;
byte FLAGS_SPECIALTOKEN = 0x02;
@@ -419,7 +412,7 @@ public abstract class Item implements Cloneable {
* the back-end to identify specific items for ranking purposes.
*
* @param label label for this item
- **/
+ */
public void setLabel(String label) {
setHasUniqueID(true);
this.label = label;
diff --git a/container-search/src/main/java/com/yahoo/search/grouping/request/DocIdNsSpecificValue.java b/container-search/src/main/java/com/yahoo/search/grouping/request/DocIdNsSpecificValue.java
index 353e92c723f..b7d8ce9fc77 100644
--- a/container-search/src/main/java/com/yahoo/search/grouping/request/DocIdNsSpecificValue.java
+++ b/container-search/src/main/java/com/yahoo/search/grouping/request/DocIdNsSpecificValue.java
@@ -10,9 +10,7 @@ package com.yahoo.search.grouping.request;
*/
public class DocIdNsSpecificValue extends DocumentValue {
- /**
- * Constructs a new instance of this class.
- */
+ /** Constructs a new instance of this class. */
public DocIdNsSpecificValue() {
this(null, null);
}
diff --git a/container-search/src/main/java/com/yahoo/search/query/QueryTree.java b/container-search/src/main/java/com/yahoo/search/query/QueryTree.java
index 115a2f6dbdc..3dac5648660 100644
--- a/container-search/src/main/java/com/yahoo/search/query/QueryTree.java
+++ b/container-search/src/main/java/com/yahoo/search/query/QueryTree.java
@@ -48,7 +48,7 @@ public class QueryTree extends CompositeItem {
return getRoot().encode(buffer);
}
- //Lets not pollute toString() by adding "ROOT"
+ // Let's not pollute toString() by adding "ROOT"
protected void appendHeadingString(StringBuilder sb) {
}
@@ -65,7 +65,7 @@ public class QueryTree extends CompositeItem {
if (this.getItemCount() == 0) // initializing
super.addItem(root);
else
- setItem(0,root); // replacing
+ setItem(0, root); // replacing
}
@Override
@@ -88,7 +88,7 @@ public class QueryTree extends CompositeItem {
@Override
public void addItem(Item item) {
- if (getItemCount()==0)
+ if (getItemCount() == 0)
super.addItem(item);
else
throw new RuntimeException("Programming error: Cannot add multiple roots");
@@ -96,8 +96,8 @@ public class QueryTree extends CompositeItem {
@Override
public void addItem(int index, Item item) {
- if (getItemCount()==0 && index==0)
- super.addItem(index,item);
+ if (getItemCount() == 0 && index == 0)
+ super.addItem(index, item);
else
throw new RuntimeException("Programming error: Cannot add multiple roots, have '" + getRoot() + "'");
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueHandler.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueHandler.java
index 6ee5b5a314f..dc8b22ac32d 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueHandler.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueHandler.java
@@ -100,4 +100,12 @@ public interface IssueHandler {
*/
boolean issueExists(Issue issue);
+ /**
+ * Returns information about project identified by the project key
+ *
+ * @param projectKey The project key to find information for
+ * @return Project info for project
+ * @throws RuntimeException exception if project not found
+ */
+ ProjectInfo projectInfo(String projectKey);
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockIssueHandler.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockIssueHandler.java
index 021f05f4d1f..257d2ff5e67 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockIssueHandler.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockIssueHandler.java
@@ -24,6 +24,7 @@ public class MockIssueHandler implements IssueHandler {
private final Clock clock;
private final AtomicLong counter = new AtomicLong();
private final Map<IssueId, MockIssue> issues = new HashMap<>();
+ private final Map<String, ProjectInfo> projects = new HashMap<>();
@Inject
@SuppressWarnings("unused")
@@ -112,6 +113,11 @@ public class MockIssueHandler implements IssueHandler {
return issues.values().stream().anyMatch(i -> i.issue.summary().equals(issue.summary()));
}
+ @Override
+ public ProjectInfo projectInfo(String projectKey) {
+ return projects.get(projectKey);
+ }
+
public MockIssueHandler close(IssueId issueId) {
issues.get(issueId).open = false;
touch(issueId);
@@ -137,6 +143,10 @@ public class MockIssueHandler implements IssueHandler {
issues.get(issueId).updated = clock.instant();
}
+ public void addProject(String projectKey, ProjectInfo projectInfo) {
+ projects.put(projectKey, projectInfo);
+ }
+
private static class PropertyInfo {
private List<List<User>> contacts = Collections.emptyList();
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/ProjectInfo.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/ProjectInfo.java
new file mode 100644
index 00000000000..8bf2ebfd092
--- /dev/null
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/ProjectInfo.java
@@ -0,0 +1,31 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.api.integration.organization;
+
+import java.util.Map;
+
+/**
+ * @author jvenstad
+ * @author mortent
+ */
+public class ProjectInfo {
+
+ private final String id;
+ private final Map<String, String> componentIds;
+
+ public ProjectInfo(String id, Map<String, String> componentIds) {
+ this.id = id;
+ this.componentIds = componentIds;
+ }
+
+ public boolean hasComponent(String component) {
+ return componentIds.containsKey(component);
+ }
+
+ public String id() {
+ return id;
+ }
+
+ public Map<String, String> componentIds() {
+ return componentIds;
+ }
+} \ No newline at end of file
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
index 246f3fff17e..d9a38a5b578 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
@@ -1883,6 +1883,13 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler {
private HttpResponse content(String tenantName, String applicationName, String instanceName, String environment, String region, String restPath, HttpRequest request) {
DeploymentId deploymentId = new DeploymentId(ApplicationId.from(tenantName, applicationName, instanceName), requireZone(environment, region));
+
+ String normalizedRestPath = URI.create("content/" + restPath).normalize().toString();
+ // Only content/ is allowed
+ if ( ! normalizedRestPath.startsWith("content/")) {
+ return ErrorResponse.forbidden("Access denied");
+ }
+
return controller.serviceRegistry().configServer().getApplicationPackageContent(deploymentId, "/" + restPath, request.getUri());
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
index 8ab43f15c89..f94f87b0f46 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
@@ -500,6 +500,9 @@ public class ApplicationApiTest extends ControllerContainerTest {
.userIdentity(USER_ID),
"INFO - All good");
+ // Get content/../foo
+ tester.assertResponse(request("/application/v4/tenant/tenant2/application/application1/instance/default/environment/dev/region/us-east-1/content/%2E%2E%2Ffoo", GET).userIdentity(USER_ID),
+ "{\"error-code\":\"FORBIDDEN\",\"message\":\"Access denied\"}", 403);
// Get content - root
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application1/instance/default/environment/dev/region/us-east-1/content/", GET).userIdentity(USER_ID),
"{\"path\":\"/\"}");
diff --git a/document/src/tests/arrayfieldvaluetest.cpp b/document/src/tests/arrayfieldvaluetest.cpp
index 375ce05a4e6..86cd50cf965 100644
--- a/document/src/tests/arrayfieldvaluetest.cpp
+++ b/document/src/tests/arrayfieldvaluetest.cpp
@@ -105,7 +105,7 @@ TEST(ArrayFieldValueTest, testArray)
// Iterating
const ArrayFieldValue& constVal(value);
for(const FieldValue & fval1 : constVal) {
- EXPECT_EQ((uint32_t) IntFieldValue::classId, fval1.getClass().id());
+ EXPECT_EQ(FieldValue::Type::INT, fval1.type());
}
value2 = value;
for(size_t i(0); i < value2.size(); i++) {
diff --git a/document/src/tests/documenttestcase.cpp b/document/src/tests/documenttestcase.cpp
index c852e219faa..4c97e99459e 100644
--- a/document/src/tests/documenttestcase.cpp
+++ b/document/src/tests/documenttestcase.cpp
@@ -50,11 +50,11 @@ TEST(DocumentTest, testSizeOf)
EXPECT_EQ(32u, sizeof(vespalib::GrowableByteBuffer));
EXPECT_EQ(88ul, sizeof(IdString));
EXPECT_EQ(104ul, sizeof(DocumentId));
- EXPECT_EQ(240ul, sizeof(Document));
+ EXPECT_EQ(256ul, sizeof(Document));
EXPECT_EQ(80ul, sizeof(NumericDataType));
EXPECT_EQ(24ul, sizeof(LongFieldValue));
- EXPECT_EQ(96ul, sizeof(StructFieldValue));
- EXPECT_EQ(16ul, sizeof(StructuredFieldValue));
+ EXPECT_EQ(104ul, sizeof(StructFieldValue));
+ EXPECT_EQ(24ul, sizeof(StructuredFieldValue));
EXPECT_EQ(56ul, sizeof(SerializableArray));
}
@@ -931,48 +931,6 @@ TEST(DocumentTest, testCRC32)
/// \todo TODO (was warning): Cannot test for in memory representation altered, as there is no syntax for getting internal refs to data from document. Add test when this is added.
}
-TEST(DocumentTest, testHasChanged)
-{
- TestDocRepo test_repo;
- Document doc(*test_repo.getDocumentType("testdoctype1"),
- DocumentId("id:ns:testdoctype1::crawler:http://www.ntnu.no/"));
- // Before deserialization we are changed.
- EXPECT_TRUE(doc.hasChanged());
-
- doc.setValue(doc.getField("hstringval"), StringFieldValue("bla bla bla bla bla"));
- // Still changed after setting a value of course.
- EXPECT_TRUE(doc.hasChanged());
-
- nbostream buf;
- doc.serialize(buf);
- // Setting a value in doc tags us changed.
- {
- buf.rp(0);
- Document doc2(test_repo.getTypeRepo(), buf);
- EXPECT_TRUE(!doc2.hasChanged());
-
- doc2.setValue("headerval", IntFieldValue::make(13));
- EXPECT_TRUE(doc2.hasChanged());
- }
- // Overwriting a value in doc tags us changed.
- {
- buf.rp(0);
- Document doc2(test_repo.getTypeRepo(), buf);
-
- doc2.setValue("hstringval", StringFieldValue::make("bla bla bla bla bla"));
- EXPECT_TRUE(doc2.hasChanged());
- }
- // Clearing value tags us changed.
- {
- buf.rp(0);
- Document doc2(test_repo.getTypeRepo(), buf);
-
- doc2.clear();
- EXPECT_TRUE(doc2.hasChanged());
- }
- // Add more tests here when we allow non-const refs to internals
-}
-
TEST(DocumentTest, testSliceSerialize)
{
// Test that document doesn't need its own bytebuffer, such that we
diff --git a/document/src/tests/documentupdatetestcase.cpp b/document/src/tests/documentupdatetestcase.cpp
index 26819699db4..e1e86bca671 100644
--- a/document/src/tests/documentupdatetestcase.cpp
+++ b/document/src/tests/documentupdatetestcase.cpp
@@ -495,7 +495,7 @@ TEST(DocumentUpdateTest, testReadSerializedFile)
const AddValueUpdate* add = static_cast<const AddValueUpdate*>(serValue);
const FieldValue* value = &add->getValue();
- EXPECT_TRUE(value->inherits(FloatFieldValue::classId));
+ EXPECT_TRUE(value->isA(FieldValue::Type::FLOAT));
EXPECT_FLOAT_EQ(value->getAsFloat(), 5.00f);
serValue = &serField3[1];
@@ -503,7 +503,7 @@ TEST(DocumentUpdateTest, testReadSerializedFile)
add = static_cast<const AddValueUpdate*>(serValue);
value = &add->getValue();
- EXPECT_TRUE(value->inherits(FloatFieldValue::classId));
+ EXPECT_TRUE(value->isA(FieldValue::Type::FLOAT));
EXPECT_FLOAT_EQ(value->getAsFloat(), 4.23f);
serValue = &serField3[2];
@@ -511,7 +511,7 @@ TEST(DocumentUpdateTest, testReadSerializedFile)
add = static_cast<const AddValueUpdate*>(serValue);
value = &add->getValue();
- EXPECT_TRUE(value->inherits(FloatFieldValue::classId));
+ EXPECT_TRUE(value->isA(FieldValue::Type::FLOAT));
EXPECT_FLOAT_EQ(value->getAsFloat(), -1.00f);
}
diff --git a/document/src/tests/fieldvalue/fieldvalue_test.cpp b/document/src/tests/fieldvalue/fieldvalue_test.cpp
index d8712768000..d27877f68c3 100644
--- a/document/src/tests/fieldvalue/fieldvalue_test.cpp
+++ b/document/src/tests/fieldvalue/fieldvalue_test.cpp
@@ -21,7 +21,7 @@ TEST("require that StringFieldValue can be assigned primitives") {
}
TEST("require that FieldValues does not change their storage size.") {
- EXPECT_EQUAL(8u, sizeof(FieldValue));
+ EXPECT_EQUAL(16u, sizeof(FieldValue));
EXPECT_EQUAL(16u, sizeof(IntFieldValue));
EXPECT_EQUAL(24u, sizeof(LongFieldValue));
EXPECT_EQUAL(104u, sizeof(StringFieldValue));
diff --git a/document/src/tests/fieldvalue/referencefieldvalue_test.cpp b/document/src/tests/fieldvalue/referencefieldvalue_test.cpp
index db380353a55..fccce30aaf8 100644
--- a/document/src/tests/fieldvalue/referencefieldvalue_test.cpp
+++ b/document/src/tests/fieldvalue/referencefieldvalue_test.cpp
@@ -7,7 +7,6 @@
#include <vespa/vespalib/testkit/testapp.h>
#include <vespa/vespalib/util/exceptions.h>
#include <ostream>
-#include <sstream>
using namespace document;
@@ -44,14 +43,6 @@ TEST_F("Reference can be constructed with document ID", Fixture) {
EXPECT_EQUAL(DocumentId("id:ns:foo::itsa-me"), fv.getDocumentId());
}
-TEST_F("Newly constructed reference is marked as changed", Fixture) {
- ReferenceFieldValue fv(f.refType);
- EXPECT_TRUE(fv.hasChanged());
-
- ReferenceFieldValue fv2(f.refType, DocumentId("id:ns:foo::itsa-me"));
- EXPECT_TRUE(fv2.hasChanged());
-}
-
TEST_F("Exception is thrown if constructor doc ID type does not match referenced document type", Fixture) {
EXPECT_EXCEPTION(
ReferenceFieldValue(f.refType, DocumentId("id:ns:bar::wario-time")),
@@ -78,12 +69,6 @@ TEST_F("Can explicitly assign new document ID to reference", Fixture) {
EXPECT_EQUAL(f.refType, *fv.getDataType());
}
-TEST_F("Assigning explicit document ID clears changed-flag", Fixture) {
- ReferenceFieldValue fv(f.refType);
- fv.setDeserializedDocumentId(DocumentId("id:ns:foo::yoshi-eggs"));
- EXPECT_FALSE(fv.hasChanged());
-}
-
TEST_F("Exception is thrown if explicitly assigned doc ID does not have same type as reference target type", Fixture) {
ReferenceFieldValue fv(f.refType);
@@ -104,19 +89,6 @@ TEST_F("assign()ing another reference field value assigns doc ID and type", Fixt
EXPECT_EQUAL(src.getDataType(), dest.getDataType());
}
-// Different FieldValue subclasses actually disagree on whether this should be
-// the case, e.g. LiteralFieldValue and TensorFieldValue. We go with the
-// latter's approach, as that should be the most conservative one.
-TEST_F("assign() marks assignee as changed", Fixture) {
- ReferenceFieldValue src(f.refType, DocumentId("id:ns:foo::yoshi"));
- ReferenceFieldValue dest(f.refType);
-
- dest.setDeserializedDocumentId(DocumentId("id:ns:foo::yoshi-eggs"));
- EXPECT_FALSE(dest.hasChanged());
-
- dest.assign(src);
- EXPECT_TRUE(dest.hasChanged());
-}
TEST_F("clone()ing creates new instance with same ID and type", Fixture) {
ReferenceFieldValue src(f.refType, DocumentId("id:ns:foo::yoshi"));
@@ -126,7 +98,6 @@ TEST_F("clone()ing creates new instance with same ID and type", Fixture) {
ASSERT_TRUE(cloned->hasValidDocumentId());
EXPECT_EQUAL(src.getDocumentId(), cloned->getDocumentId());
EXPECT_EQUAL(src.getDataType(), cloned->getDataType());
- EXPECT_TRUE(cloned->hasChanged());
}
TEST_F("Can clone() value without document ID", Fixture) {
@@ -136,7 +107,6 @@ TEST_F("Can clone() value without document ID", Fixture) {
ASSERT_TRUE(cloned);
EXPECT_FALSE(cloned->hasValidDocumentId());
EXPECT_EQUAL(src.getDataType(), cloned->getDataType());
- EXPECT_TRUE(cloned->hasChanged());
}
TEST_F("compare() orders first on type ID, then on document ID", Fixture) {
diff --git a/document/src/tests/serialization/vespadocumentserializer_test.cpp b/document/src/tests/serialization/vespadocumentserializer_test.cpp
index 33e8c521e09..3db001e1732 100644
--- a/document/src/tests/serialization/vespadocumentserializer_test.cpp
+++ b/document/src/tests/serialization/vespadocumentserializer_test.cpp
@@ -986,22 +986,6 @@ TEST_F("ReferenceFieldValue with ID can be roundtrip serialized", RefFixture) {
serializeAndDeserialize(ref_with_id, stream, f.fixed_repo);
}
-TEST_F("Empty ReferenceFieldValue has changed-flag cleared after deserialization", RefFixture) {
- ReferenceFieldValue src(f.ref_type());
- ReferenceFieldValue dest(f.ref_type());
- f.roundtrip_serialize(src, dest);
-
- EXPECT_FALSE(dest.hasChanged());
-}
-
-TEST_F("ReferenceFieldValue with ID has changed-flag cleared after deserialization", RefFixture) {
- ReferenceFieldValue src(f.ref_type(), DocumentId("id:ns:" + doc_name + "::foo"));
- ReferenceFieldValue dest(f.ref_type());
- f.roundtrip_serialize(src, dest);
-
- EXPECT_FALSE(dest.hasChanged());
-}
-
TEST_F("Empty ReferenceFieldValue serialization matches Java", RefFixture) {
ReferenceFieldValue value(f.ref_type());
f.verify_cross_language_serialization("empty_reference", value);
diff --git a/document/src/tests/weightedsetfieldvaluetest.cpp b/document/src/tests/weightedsetfieldvaluetest.cpp
index 61f727120d1..4cc897f22d7 100644
--- a/document/src/tests/weightedsetfieldvaluetest.cpp
+++ b/document/src/tests/weightedsetfieldvaluetest.cpp
@@ -141,8 +141,7 @@ TEST(WeightedSetFieldValueTest, testWeightedSet)
{
const FieldValue& fval1(*it->first);
(void) fval1;
- EXPECT_EQ((uint32_t) IntFieldValue::classId,
- it->first->getClass().id());
+ EXPECT_TRUE(it->first->isA(FieldValue::Type::INT));
const IntFieldValue& val = dynamic_cast<const IntFieldValue&>(*it->second);
(void) val;
}
diff --git a/document/src/vespa/document/base/fieldpath.cpp b/document/src/vespa/document/base/fieldpath.cpp
index 5da64272364..fcac59847cb 100644
--- a/document/src/vespa/document/base/fieldpath.cpp
+++ b/document/src/vespa/document/base/fieldpath.cpp
@@ -5,7 +5,6 @@
#include <vespa/document/datatype/mapdatatype.h>
#include <vespa/vespalib/util/exceptions.h>
#include <vespa/document/fieldvalue/fieldvalue.h>
-#include <vespa/vespalib/objects/visit.hpp>
using vespalib::IllegalArgumentException;
using vespalib::make_string;
@@ -127,17 +126,6 @@ FieldPathEntry::stealFieldValueToSet() const
return FieldValue::UP(_fillInVal.release());
}
-void
-FieldPathEntry::visitMembers(vespalib::ObjectVisitor &visitor) const
-{
- visit(visitor, "type", _type);
- visit(visitor, "name", _name);
- visit(visitor, "lookupIndex", _lookupIndex);
- visit(visitor, "lookupKey", _lookupKey);
- visit(visitor, "variableName", _variableName);
- visit(visitor, "fillInVal", _fillInVal);
-}
-
vespalib::string
FieldPathEntry::parseKey(vespalib::stringref & key)
{
@@ -191,7 +179,8 @@ FieldPath::FieldPath(const FieldPath &) = default;
FieldPath & FieldPath::operator=(const FieldPath &) = default;
FieldPath::~FieldPath() = default;
-FieldPath::iterator FieldPath::insert(iterator pos, std::unique_ptr<FieldPathEntry> entry) {
+FieldPath::iterator
+FieldPath::insert(iterator pos, std::unique_ptr<FieldPathEntry> entry) {
return _path.insert(pos, vespalib::CloneablePtr<FieldPathEntry>(entry.release()));
}
void FieldPath::push_back(std::unique_ptr<FieldPathEntry> entry) { _path.emplace_back(entry.release()); }
@@ -199,13 +188,4 @@ void FieldPath::pop_back() { _path.pop_back(); }
void FieldPath::clear() { _path.clear(); }
void FieldPath::reserve(size_t sz) { _path.reserve(sz); }
-void
-FieldPath::visitMembers(vespalib::ObjectVisitor& visitor) const
-{
- (void) visitor;
- for (uint32_t i = 0; i < _path.size(); ++i) {
-// visit(visitor, vespalib::make_string("[%u]", i), _path[i]);
- }
-}
-
}
diff --git a/document/src/vespa/document/base/fieldpath.h b/document/src/vespa/document/base/fieldpath.h
index 679fd0885dd..a79e4595a61 100644
--- a/document/src/vespa/document/base/fieldpath.h
+++ b/document/src/vespa/document/base/fieldpath.h
@@ -2,10 +2,7 @@
#pragma once
#include "field.h"
-#include <vespa/document/util/identifiableid.h>
-#include <vector>
-
-namespace vespalib { class ObjectVisitor; }
+#include <vespa/vespalib/util/memory.h>
namespace document {
@@ -80,7 +77,6 @@ public:
FieldValue * getFieldValueToSetPtr() const { return _fillInVal.get(); }
FieldValue & getFieldValueToSet() const { return *_fillInVal; }
std::unique_ptr<FieldValue> stealFieldValueToSet() const;
- void visitMembers(vespalib::ObjectVisitor &visitor) const;
/**
* Parses a string of the format {["]escaped string["]} to its unescaped value.
* @param key is the incoming value, and contains what is left when done.
@@ -115,8 +111,8 @@ public:
FieldPath();
FieldPath(const FieldPath &);
FieldPath & operator=(const FieldPath &);
- FieldPath(FieldPath &&) = default;
- FieldPath & operator=(FieldPath &&) = default;
+ FieldPath(FieldPath &&) noexcept = default;
+ FieldPath & operator=(FieldPath &&) noexcept = default;
~FieldPath();
template <typename InputIterator>
@@ -151,8 +147,6 @@ public:
const FieldPathEntry & operator[](Container::size_type i) const { return *_path[i]; }
- void visitMembers(vespalib::ObjectVisitor &visitor) const;
-
template <typename IT>
class Range {
public:
diff --git a/document/src/vespa/document/datatype/datatype.cpp b/document/src/vespa/document/datatype/datatype.cpp
index 87464a197ee..3cc7034e336 100644
--- a/document/src/vespa/document/datatype/datatype.cpp
+++ b/document/src/vespa/document/datatype/datatype.cpp
@@ -51,32 +51,32 @@ class DataType2FieldValueId
{
public:
DataType2FieldValueId();
- unsigned int getFieldValueId(unsigned int id) const {
+ FieldValue::Type getFieldValueId(unsigned int id) const {
return id < sizeof(_type2FieldValueId)/sizeof(_type2FieldValueId[0])
? _type2FieldValueId[id]
- : 0;
+ : FieldValue::Type::NONE;
}
private:
- unsigned int _type2FieldValueId[DataType::MAX];
+ FieldValue::Type _type2FieldValueId[DataType::MAX];
};
DataType2FieldValueId::DataType2FieldValueId()
{
for (size_t i(0); i < sizeof(_type2FieldValueId)/sizeof(_type2FieldValueId[0]); i++) {
- _type2FieldValueId[i] = 0;
+ _type2FieldValueId[i] = FieldValue::Type::NONE;
}
- _type2FieldValueId[DataType::T_BYTE] = ByteFieldValue::classId;
- _type2FieldValueId[DataType::T_SHORT] = ShortFieldValue::classId;
- _type2FieldValueId[DataType::T_INT] = IntFieldValue::classId;
- _type2FieldValueId[DataType::T_LONG] = LongFieldValue::classId;
- _type2FieldValueId[DataType::T_FLOAT] = FloatFieldValue::classId;
- _type2FieldValueId[DataType::T_DOUBLE] = DoubleFieldValue::classId;
- _type2FieldValueId[DataType::T_BOOL] = BoolFieldValue::classId;
- _type2FieldValueId[DataType::T_STRING] = StringFieldValue::classId;
- _type2FieldValueId[DataType::T_RAW] = RawFieldValue::classId;
- _type2FieldValueId[DataType::T_URI] = StringFieldValue::classId;
- _type2FieldValueId[DataType::T_PREDICATE] = PredicateFieldValue::classId;
- _type2FieldValueId[DataType::T_TENSOR] = TensorFieldValue::classId;
+ _type2FieldValueId[DataType::T_BYTE] = FieldValue::Type::BYTE;
+ _type2FieldValueId[DataType::T_SHORT] = FieldValue::Type::SHORT;
+ _type2FieldValueId[DataType::T_INT] = FieldValue::Type::INT;
+ _type2FieldValueId[DataType::T_LONG] = FieldValue::Type::LONG;
+ _type2FieldValueId[DataType::T_FLOAT] = FieldValue::Type::FLOAT;
+ _type2FieldValueId[DataType::T_DOUBLE] = FieldValue::Type::DOUBLE;
+ _type2FieldValueId[DataType::T_BOOL] = FieldValue::Type::BOOL;
+ _type2FieldValueId[DataType::T_STRING] = FieldValue::Type::STRING;
+ _type2FieldValueId[DataType::T_RAW] = FieldValue::Type::RAW;
+ _type2FieldValueId[DataType::T_URI] = FieldValue::Type::STRING;
+ _type2FieldValueId[DataType::T_PREDICATE] = FieldValue::Type::PREDICATE;
+ _type2FieldValueId[DataType::T_TENSOR] = FieldValue::Type::TENSOR;
}
DataType2FieldValueId _G_type2FieldValueId;
@@ -86,9 +86,8 @@ DataType2FieldValueId _G_type2FieldValueId;
bool DataType::isValueType(const FieldValue & fv) const
{
if ((_dataTypeId >= 0) && _dataTypeId < MAX) {
- const uint32_t cid(_G_type2FieldValueId.getFieldValueId(_dataTypeId));
- if (cid != 0) {
- return cid == fv.getClass().id();
+ if (fv.isA(_G_type2FieldValueId.getFieldValueId(_dataTypeId))) {
+ return true;
}
}
return _dataTypeId == fv.getDataType()->getId();
diff --git a/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.cpp b/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.cpp
index e26f0f15759..130e68a9f54 100644
--- a/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.cpp
@@ -9,12 +9,6 @@ using std::string;
namespace document {
-AnnotationReferenceFieldValue::AnnotationReferenceFieldValue(
- const DataType &type, int32_t annotation_index)
- : _type(&type),
- _annotation_index(annotation_index) {
-}
-
int AnnotationReferenceFieldValue::compare(const FieldValue &other) const {
if (getDataType()->equals(*other.getDataType())) {
const AnnotationReferenceFieldValue &val(static_cast<const AnnotationReferenceFieldValue &>(other));
@@ -35,8 +29,4 @@ void AnnotationReferenceFieldValue::printXml(XmlOutputStream &out) const {
out << _annotation_index;
}
-bool AnnotationReferenceFieldValue::hasChanged() const {
- return false;
-}
-
} // namespace document
diff --git a/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.h b/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.h
index 6fc85bf384f..732be94c5c8 100644
--- a/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/annotationreferencefieldvalue.h
@@ -9,15 +9,17 @@ namespace document {
class Annotation;
class AnnotationReferenceDataType;
-class AnnotationReferenceFieldValue : public FieldValue {
+class AnnotationReferenceFieldValue final : public FieldValue {
const DataType *_type;
int32_t _annotation_index;
public:
AnnotationReferenceFieldValue(const DataType &type)
- : _type(&type), _annotation_index(0) {}
- AnnotationReferenceFieldValue(const DataType &type,
- int32_t annotation_index);
+ : AnnotationReferenceFieldValue(type, 0) {}
+ AnnotationReferenceFieldValue(const DataType &type, int32_t annotation_index)
+ : FieldValue(Type::ANNOTATION_REFERENCE), _type(&type), _annotation_index(annotation_index)
+ {}
+
void setAnnotationIndex(int32_t index) { _annotation_index = index; }
void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); }
@@ -30,7 +32,6 @@ public:
AnnotationReferenceFieldValue *clone() const override;
const DataType *getDataType() const override { return _type; }
void printXml(XmlOutputStream &out) const override;
- bool hasChanged() const override;
};
} // namespace document
diff --git a/document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp b/document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp
index 07f731a9ea7..51bc42d2cee 100644
--- a/document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/arrayfieldvalue.cpp
@@ -23,10 +23,8 @@ using fieldvalue::ModificationStatus;
using fieldvalue::IteratorHandler;
using fieldvalue::VariableMap;
-IMPLEMENT_IDENTIFIABLE_ABSTRACT(ArrayFieldValue, CollectionFieldValue);
-
ArrayFieldValue::ArrayFieldValue(const DataType &type)
- : CollectionFieldValue(type),
+ : CollectionFieldValue(Type::ARRAY, type),
_array()
{
_array.reset(static_cast<IArray *>(createArray(getNestedType()).release()));
@@ -170,15 +168,6 @@ ArrayFieldValue::print(std::ostream& out, bool verbose,
out << "\n" << indent << ")";
}
-bool
-ArrayFieldValue::hasChanged() const
-{
- for (uint32_t i=0, n=_array->size(); i<n; ++i) {
- if (array()[i].hasChanged()) return true;
- }
- return false;
-}
-
fieldvalue::ModificationStatus
ArrayFieldValue::iterateSubset(int startPos, int endPos,
vespalib::stringref variable,
diff --git a/document/src/vespa/document/fieldvalue/arrayfieldvalue.h b/document/src/vespa/document/fieldvalue/arrayfieldvalue.h
index c4f879f7348..ae6aea47c2c 100644
--- a/document/src/vespa/document/fieldvalue/arrayfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/arrayfieldvalue.h
@@ -18,7 +18,7 @@
namespace document {
-class ArrayFieldValue : public CollectionFieldValue {
+class ArrayFieldValue final : public CollectionFieldValue {
private:
using IArray = vespalib::IArrayT<FieldValue>;
std::unique_ptr<IArray> _array;
@@ -68,14 +68,12 @@ public:
int compare(const FieldValue&) const override;
void printXml(XmlOutputStream& out) const override;
void print(std::ostream& out, bool verbose, const std::string& indent) const override;
- bool hasChanged() const override;
void swap(ArrayFieldValue & other) { _array.swap(other._array); }
// Iterator functionality
const_iterator begin() const { return array().begin(); }
const_iterator end() const { return array().end(); }
- DECLARE_IDENTIFIABLE_ABSTRACT(ArrayFieldValue);
private:
iterator begin() { return array().begin(); }
iterator end() { return array().end(); }
diff --git a/document/src/vespa/document/fieldvalue/boolfieldvalue.cpp b/document/src/vespa/document/fieldvalue/boolfieldvalue.cpp
index 1c5261877fd..bbd40623267 100644
--- a/document/src/vespa/document/fieldvalue/boolfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/boolfieldvalue.cpp
@@ -9,36 +9,37 @@ using namespace vespalib::xml;
namespace document {
-IMPLEMENT_IDENTIFIABLE(BoolFieldValue, FieldValue);
-
BoolFieldValue::BoolFieldValue(bool value)
- : _value(value), _altered(false) {
+ : FieldValue(Type::BOOL), _value(value) {
}
BoolFieldValue::~BoolFieldValue() = default;
-FieldValue &BoolFieldValue::assign(const FieldValue &rhs) {
- if (rhs.inherits(BoolFieldValue::classId)) {
+FieldValue &
+BoolFieldValue::assign(const FieldValue &rhs) {
+ if (rhs.isA(Type::BOOL)) {
operator=(static_cast<const BoolFieldValue &>(rhs));
return *this;
} else {
- _altered = true;
return FieldValue::assign(rhs);
}
}
-int BoolFieldValue::compare(const FieldValue&rhs) const {
+int
+BoolFieldValue::compare(const FieldValue&rhs) const {
int diff = FieldValue::compare(rhs);
if (diff != 0) return diff;
const BoolFieldValue &o = static_cast<const BoolFieldValue &>(rhs);
return (_value == o._value) ? 0 : _value ? 1 : -1;
}
-void BoolFieldValue::printXml(XmlOutputStream& out) const {
+void
+BoolFieldValue::printXml(XmlOutputStream& out) const {
out << XmlContent(getAsString());
}
-void BoolFieldValue::print(std::ostream& out, bool, const std::string&) const {
+void
+BoolFieldValue::print(std::ostream& out, bool, const std::string&) const {
out << (_value ? "true" : "false") << "\n";
}
@@ -47,11 +48,6 @@ BoolFieldValue::getDataType() const {
return DataType::BOOL;
}
-bool
-BoolFieldValue::hasChanged() const {
- return _altered;
-}
-
FieldValue *
BoolFieldValue::clone() const {
return new BoolFieldValue(*this);
diff --git a/document/src/vespa/document/fieldvalue/boolfieldvalue.h b/document/src/vespa/document/fieldvalue/boolfieldvalue.h
index 01cfcf2cd48..0265205665d 100644
--- a/document/src/vespa/document/fieldvalue/boolfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/boolfieldvalue.h
@@ -9,9 +9,8 @@ namespace document {
/**
* Represent the value in a field of type 'bool' which can be either true or false.
**/
-class BoolFieldValue : public FieldValue {
+class BoolFieldValue final : public FieldValue {
bool _value;
- bool _altered;
public:
BoolFieldValue(bool value=false);
@@ -27,7 +26,6 @@ public:
void print(std::ostream &out, bool verbose, const std::string &indent) const override;
const DataType *getDataType() const override;
- bool hasChanged() const override;
bool getValue() const { return _value; }
void setValue(bool v) { _value = v; }
@@ -42,7 +40,6 @@ public:
vespalib::string getAsString() const override;
BoolFieldValue& operator=(vespalib::stringref) override;
- DECLARE_IDENTIFIABLE(BoolFieldValue);
static std::unique_ptr<BoolFieldValue> make(bool value=false) { return std::make_unique<BoolFieldValue>(value); }
};
diff --git a/document/src/vespa/document/fieldvalue/bytefieldvalue.cpp b/document/src/vespa/document/fieldvalue/bytefieldvalue.cpp
index 5d514352302..fff07d9de4e 100644
--- a/document/src/vespa/document/fieldvalue/bytefieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/bytefieldvalue.cpp
@@ -5,6 +5,4 @@
namespace document {
-IMPLEMENT_IDENTIFIABLE(ByteFieldValue, NumericFieldValueBase);
-
} // document
diff --git a/document/src/vespa/document/fieldvalue/bytefieldvalue.h b/document/src/vespa/document/fieldvalue/bytefieldvalue.h
index 2cccf483c84..1b810828c53 100644
--- a/document/src/vespa/document/fieldvalue/bytefieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/bytefieldvalue.h
@@ -12,12 +12,12 @@
namespace document {
-class ByteFieldValue : public NumericFieldValue<int8_t> {
+class ByteFieldValue final : public NumericFieldValue<int8_t> {
public:
typedef int8_t Number;
ByteFieldValue(Number value = 0)
- : NumericFieldValue<Number>(value) {}
+ : NumericFieldValue<Number>(Type::BYTE, value) {}
void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); }
void accept(ConstFieldValueVisitor &visitor) const override { visitor.visit(*this); }
@@ -25,7 +25,6 @@ public:
ByteFieldValue* clone() const override { return new ByteFieldValue(*this); }
using NumericFieldValue<Number>::operator=;
- DECLARE_IDENTIFIABLE(ByteFieldValue);
static std::unique_ptr<ByteFieldValue> make(Number value=0) { return std::make_unique<ByteFieldValue>(value); }
};
diff --git a/document/src/vespa/document/fieldvalue/collectionfieldvalue.cpp b/document/src/vespa/document/fieldvalue/collectionfieldvalue.cpp
index 4c960502b71..b9400a1e663 100644
--- a/document/src/vespa/document/fieldvalue/collectionfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/collectionfieldvalue.cpp
@@ -5,7 +5,6 @@
namespace document {
-IMPLEMENT_IDENTIFIABLE_ABSTRACT(CollectionFieldValue, FieldValue);
CollectionFieldValue::CollectionFieldValue(const CollectionFieldValue& other)
: FieldValue(other),
diff --git a/document/src/vespa/document/fieldvalue/collectionfieldvalue.h b/document/src/vespa/document/fieldvalue/collectionfieldvalue.h
index 9efd3b91bc6..d4a1367bee2 100644
--- a/document/src/vespa/document/fieldvalue/collectionfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/collectionfieldvalue.h
@@ -27,9 +27,9 @@ protected:
void verifyType(const CollectionFieldValue& other) const;
public:
- CollectionFieldValue(const DataType &type)
- : FieldValue(),
- _type(&type)
+ CollectionFieldValue(Type type, const DataType &dataType)
+ : FieldValue(type),
+ _type(&dataType)
{}
CollectionFieldValue(const CollectionFieldValue& other);
@@ -61,8 +61,6 @@ public:
virtual bool isEmpty() const = 0;
virtual size_t size() const = 0;
virtual void clear() = 0;
-
- DECLARE_IDENTIFIABLE_ABSTRACT(CollectionFieldValue);
};
}
diff --git a/document/src/vespa/document/fieldvalue/document.cpp b/document/src/vespa/document/fieldvalue/document.cpp
index 57787738502..0cd1faa5d62 100644
--- a/document/src/vespa/document/fieldvalue/document.cpp
+++ b/document/src/vespa/document/fieldvalue/document.cpp
@@ -65,10 +65,8 @@ Document::setType(const DataType & type) {
_fields.setType(getType().getFieldsType());
}
-IMPLEMENT_IDENTIFIABLE_ABSTRACT(Document, StructuredFieldValue);
-
Document::Document()
- : StructuredFieldValue(*DataType::DOCUMENT),
+ : StructuredFieldValue(Type::DOCUMENT, *DataType::DOCUMENT),
_id(),
_fields(getType().getFieldsType()),
_backingBuffer(),
@@ -86,7 +84,7 @@ Document::Document(const Document& rhs)
{}
Document::Document(const DataType &type, DocumentId documentId)
- : StructuredFieldValue(verifyDocumentType(&type)),
+ : StructuredFieldValue(Type::DOCUMENT, verifyDocumentType(&type)),
_id(std::move(documentId)),
_fields(getType().getFieldsType()),
_backingBuffer(),
@@ -104,7 +102,7 @@ void Document::setRepo(const DocumentTypeRepo& repo)
}
Document::Document(const DocumentTypeRepo& repo, vespalib::nbostream & is)
- : StructuredFieldValue(*DataType::DOCUMENT),
+ : StructuredFieldValue(Type::DOCUMENT, *DataType::DOCUMENT),
_id(),
_fields(static_cast<const DocumentType &>(getType()).getFieldsType()),
_backingBuffer(),
@@ -114,7 +112,7 @@ Document::Document(const DocumentTypeRepo& repo, vespalib::nbostream & is)
}
Document::Document(const DocumentTypeRepo& repo, vespalib::DataBuffer && backingBuffer)
- : StructuredFieldValue(*DataType::DOCUMENT),
+ : StructuredFieldValue(Type::DOCUMENT, *DataType::DOCUMENT),
_id(),
_fields(static_cast<const DocumentType &>(getType()).getFieldsType()),
_backingBuffer(),
@@ -173,12 +171,6 @@ Document::setFieldValue(const Field& field, FieldValue::UP data)
_fields.setFieldValue(field, std::move(data));
}
-bool
-Document::hasChanged() const
-{
- return _fields.hasChanged();
-}
-
FieldValue&
Document::assign(const FieldValue& value)
{
diff --git a/document/src/vespa/document/fieldvalue/document.h b/document/src/vespa/document/fieldvalue/document.h
index da6bcca777c..610b2fcbd1b 100644
--- a/document/src/vespa/document/fieldvalue/document.h
+++ b/document/src/vespa/document/fieldvalue/document.h
@@ -24,7 +24,7 @@ namespace document {
class TransactionGuard;
-class Document : public StructuredFieldValue
+class Document final : public StructuredFieldValue
{
private:
DocumentId _id;
@@ -86,8 +86,6 @@ public:
void clear() override;
- bool hasChanged() const override;
-
// FieldValue implementation.
FieldValue& assign(const FieldValue&) override;
int compare(const FieldValue& other) const override;
@@ -109,9 +107,6 @@ public:
bool empty() const override { return _fields.empty(); }
uint32_t calculateChecksum() const;
-
- DECLARE_IDENTIFIABLE_ABSTRACT(Document);
-
void setFieldValue(const Field& field, FieldValue::UP data) override;
private:
friend TransactionGuard;
diff --git a/document/src/vespa/document/fieldvalue/doublefieldvalue.cpp b/document/src/vespa/document/fieldvalue/doublefieldvalue.cpp
index 943255e5ffc..3ab255be8db 100644
--- a/document/src/vespa/document/fieldvalue/doublefieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/doublefieldvalue.cpp
@@ -5,6 +5,5 @@
namespace document {
-IMPLEMENT_IDENTIFIABLE(DoubleFieldValue, NumericFieldValueBase);
} // document
diff --git a/document/src/vespa/document/fieldvalue/doublefieldvalue.h b/document/src/vespa/document/fieldvalue/doublefieldvalue.h
index b9b20bbd24a..56ba6e334e9 100644
--- a/document/src/vespa/document/fieldvalue/doublefieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/doublefieldvalue.h
@@ -12,11 +12,11 @@
namespace document {
-class DoubleFieldValue : public NumericFieldValue<double> {
+class DoubleFieldValue final : public NumericFieldValue<double> {
public:
typedef double Number;
- DoubleFieldValue(Number value = 0) : NumericFieldValue<Number>(value) {}
+ DoubleFieldValue(Number value = 0) : NumericFieldValue<Number>(Type::DOUBLE, value) {}
void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); }
void accept(ConstFieldValueVisitor &visitor) const override { visitor.visit(*this); }
@@ -25,7 +25,6 @@ public:
DoubleFieldValue* clone() const override { return new DoubleFieldValue(*this); }
using NumericFieldValue<Number>::operator=;
- DECLARE_IDENTIFIABLE(DoubleFieldValue);
static std::unique_ptr<DoubleFieldValue> make(Number value=0) { return std::make_unique<DoubleFieldValue>(value); }
};
diff --git a/document/src/vespa/document/fieldvalue/fieldvalue.cpp b/document/src/vespa/document/fieldvalue/fieldvalue.cpp
index cc55775d54c..79cc2daafce 100644
--- a/document/src/vespa/document/fieldvalue/fieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/fieldvalue.cpp
@@ -26,8 +26,50 @@ namespace document {
using namespace fieldvalue;
-IMPLEMENT_IDENTIFIABLE_ABSTRACT(FieldValue, vespalib::Identifiable);
-
+const char *
+FieldValue::className() const noexcept {
+ switch (type()) {
+ case Type::BOOL:
+ return "BoolFieldValue";
+ case Type::BYTE:
+ return "ByteFieldValue";
+ case Type::SHORT:
+ return "ShortFieldValue";
+ case Type::INT:
+ return "IntFieldValue";
+ case Type::LONG:
+ return "LongFieldValue";
+ case Type::FLOAT:
+ return "FloatFieldValue";
+ case Type::DOUBLE:
+ return "DoubleFieldValue";
+ case Type::STRING:
+ return "StringFieldValue";
+ case Type::RAW:
+ return "RawFieldValue";
+ case Type::PREDICATE:
+ return "PredicateFieldValue";
+ case Type::TENSOR:
+ return "TensorFieldValue";
+ case Type::ANNOTATION_REFERENCE:
+ return "AnnotationReferenceFieldValue";
+ case Type::REFERENCE:
+ return "ReferenceFieldValue";
+ case Type::ARRAY:
+ return "ArrayFieldValue";
+ case Type::WSET:
+ return "WSetFieldValue";
+ case Type::MAP:
+ return "MapFieldValue";
+ case Type::STRUCT:
+ return "StructFieldValue";
+ case Type::DOCUMENT:
+ return "DocumentFieldValue";
+ case Type::NONE:
+ default:
+ abort();
+ }
+}
void FieldValue::serialize(nbostream &stream) const {
VespaDocumentSerializer serializer(stream);
serializer.write(*this);
diff --git a/document/src/vespa/document/fieldvalue/fieldvalue.h b/document/src/vespa/document/fieldvalue/fieldvalue.h
index 5eadb3307b5..a45e42539ee 100644
--- a/document/src/vespa/document/fieldvalue/fieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/fieldvalue.h
@@ -13,38 +13,35 @@
#include "fieldvaluevisitor.h"
#include "modificationstatus.h"
-#include <vespa/document/util/xmlserializable.h>
+#include <vespa/document/util/identifiableid.h>
#include <vespa/document/base/fieldpath.h>
#include <vespa/vespalib/objects/identifiable.h>
#include <vespa/vespalib/util/polymorphicarraybase.h>
namespace vespalib { class nbostream; }
+namespace vespalib::xml { class XmlOutputStream; }
-namespace document {
+namespace document::fieldvalue { class IteratorHandler; }
-namespace fieldvalue { class IteratorHandler; }
+namespace document {
class DataType;
-class FieldValue : public vespalib::Identifiable
+class FieldValue
{
-protected:
- FieldValue(const FieldValue&) = default;
- FieldValue& operator=(const FieldValue&) = default;
- FieldValue(FieldValue &&) = default;
- FieldValue& operator=(FieldValue &&) = default;
- static std::unique_ptr<vespalib::IArrayBase> createArray(const DataType & baseType);
-
public:
+ enum class Type : uint8_t {
+ NONE, BOOL, BYTE, SHORT, INT, LONG, FLOAT, DOUBLE,
+ STRING, RAW, PREDICATE, TENSOR, ANNOTATION_REFERENCE,
+ REFERENCE, ARRAY, WSET, MAP, STRUCT, DOCUMENT
+ };
using PathRange = FieldPath::Range<FieldPath::const_iterator>;
using UP = std::unique_ptr<FieldValue>;
using SP = std::shared_ptr<FieldValue>;
using CP = vespalib::CloneablePtr<FieldValue>;
+ using XmlOutputStream = vespalib::xml::XmlOutputStream;
- DECLARE_IDENTIFIABLE_ABSTRACT(FieldValue);
-
- FieldValue() = default;
-
+ virtual ~FieldValue() = default;
/**
* Visit this fieldvalue for double dispatch.
*/
@@ -82,13 +79,6 @@ public:
*/
virtual int fastCompare(const FieldValue& other) const;
- /**
- * Returns true if this object have been altered since last
- * serialization/deserialization. If hasChanged() is false, then cached
- * information from last serialization effort is still valid.
- */
- virtual bool hasChanged() const = 0;
-
/** Cloneable implementation */
virtual FieldValue* clone() const = 0;
@@ -174,6 +164,27 @@ public:
// Utility functions to set commonly used value types.
virtual FieldValue& operator=(vespalib::stringref);
+
+ Type type() const noexcept { return _type; }
+ bool isA(Type type) const noexcept { return type == _type; }
+ bool isCollection() const noexcept { return (_type == Type::WSET) || (_type == Type::ARRAY); }
+ bool isStructured() const noexcept { return (_type == Type::DOCUMENT) || (_type == Type::STRUCT); }
+ bool isLiteral() const noexcept { return (_type == Type::STRING) || (_type == Type::RAW); }
+ bool isNumeric() const noexcept {
+ return (_type == Type::BYTE) || (_type == Type::SHORT) ||
+ (_type == Type::INT) || (_type == Type::LONG) || (_type == Type::FLOAT) || (_type == Type::DOUBLE);
+ }
+ bool isFixedSizeSingleValue() const noexcept {
+ return (_type == Type::BOOL) || isNumeric();
+ }
+ const char * className() const noexcept;
+protected:
+ FieldValue(Type type) noexcept : _type(type) { }
+ FieldValue(const FieldValue&) = default;
+ FieldValue& operator=(const FieldValue&) = default;
+ FieldValue(FieldValue &&) noexcept = default;
+ FieldValue& operator=(FieldValue &&) noexcept = default;
+ static std::unique_ptr<vespalib::IArrayBase> createArray(const DataType & baseType);
private:
fieldvalue::ModificationStatus
iterateNested(FieldPath::const_iterator start, FieldPath::const_iterator end, fieldvalue::IteratorHandler & handler) const {
@@ -181,10 +192,12 @@ private:
}
virtual FieldValue::UP onGetNestedFieldValue(PathRange nested) const;
virtual fieldvalue::ModificationStatus onIterateNested(PathRange nested, fieldvalue::IteratorHandler & handler) const;
+
+ Type _type;
};
std::ostream& operator<<(std::ostream& out, const FieldValue & p);
-XmlOutputStream & operator<<(XmlOutputStream & out, const FieldValue & p);
+vespalib::xml::XmlOutputStream & operator<<(vespalib::xml::XmlOutputStream & out, const FieldValue & p);
} // document
diff --git a/document/src/vespa/document/fieldvalue/floatfieldvalue.cpp b/document/src/vespa/document/fieldvalue/floatfieldvalue.cpp
index e44f36295c4..b3698841667 100644
--- a/document/src/vespa/document/fieldvalue/floatfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/floatfieldvalue.cpp
@@ -5,6 +5,4 @@
namespace document {
-IMPLEMENT_IDENTIFIABLE(FloatFieldValue, NumericFieldValueBase);
-
} // document
diff --git a/document/src/vespa/document/fieldvalue/floatfieldvalue.h b/document/src/vespa/document/fieldvalue/floatfieldvalue.h
index f662c400633..783459dec64 100644
--- a/document/src/vespa/document/fieldvalue/floatfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/floatfieldvalue.h
@@ -12,11 +12,11 @@
namespace document {
-class FloatFieldValue : public NumericFieldValue<float> {
+class FloatFieldValue final : public NumericFieldValue<float> {
public:
typedef float Number;
- FloatFieldValue(Number value = 0) : NumericFieldValue<Number>(value) {}
+ FloatFieldValue(Number value = 0) : NumericFieldValue<Number>(Type::FLOAT, value) {}
void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); }
void accept(ConstFieldValueVisitor &visitor) const override { visitor.visit(*this); }
@@ -25,7 +25,6 @@ public:
FloatFieldValue* clone() const override { return new FloatFieldValue(*this); }
using NumericFieldValue<Number>::operator=;
- DECLARE_IDENTIFIABLE(FloatFieldValue);
static std::unique_ptr<FloatFieldValue> make(Number value = 0) { return std::make_unique<FloatFieldValue>(value); }
};
diff --git a/document/src/vespa/document/fieldvalue/intfieldvalue.cpp b/document/src/vespa/document/fieldvalue/intfieldvalue.cpp
index 06edafcf374..42884c9fc8b 100644
--- a/document/src/vespa/document/fieldvalue/intfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/intfieldvalue.cpp
@@ -5,6 +5,5 @@
namespace document {
-IMPLEMENT_IDENTIFIABLE(IntFieldValue, NumericFieldValueBase);
} // document
diff --git a/document/src/vespa/document/fieldvalue/intfieldvalue.h b/document/src/vespa/document/fieldvalue/intfieldvalue.h
index d365e34779e..521aced292c 100644
--- a/document/src/vespa/document/fieldvalue/intfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/intfieldvalue.h
@@ -12,11 +12,11 @@
namespace document {
-class IntFieldValue : public NumericFieldValue<int32_t> {
+class IntFieldValue final : public NumericFieldValue<int32_t> {
public:
typedef int32_t Number;
- IntFieldValue(Number value = 0) : NumericFieldValue<Number>(value) {}
+ IntFieldValue(Number value = 0) : NumericFieldValue<Number>(Type::INT, value) {}
void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); }
void accept(ConstFieldValueVisitor &visitor) const override { visitor.visit(*this); }
@@ -25,7 +25,6 @@ public:
IntFieldValue* clone() const override { return new IntFieldValue(*this); }
using NumericFieldValue<Number>::operator=;
- DECLARE_IDENTIFIABLE(IntFieldValue);
static std::unique_ptr<IntFieldValue> make(Number value=0) { return std::make_unique<IntFieldValue>(value); }
};
diff --git a/document/src/vespa/document/fieldvalue/literalfieldvalue.cpp b/document/src/vespa/document/fieldvalue/literalfieldvalue.cpp
index 7ba537d9cc2..02ad759fb8c 100644
--- a/document/src/vespa/document/fieldvalue/literalfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/literalfieldvalue.cpp
@@ -8,13 +8,10 @@ using namespace vespalib::xml;
namespace document {
-IMPLEMENT_IDENTIFIABLE_ABSTRACT(LiteralFieldValueB, FieldValue);
-
-LiteralFieldValueB::LiteralFieldValueB() :
- FieldValue(),
+LiteralFieldValueB::LiteralFieldValueB(Type type) :
+ FieldValue(type),
_value(),
- _backing(),
- _altered(true)
+ _backing()
{
_value = _backing;
}
@@ -24,17 +21,15 @@ LiteralFieldValueB::~LiteralFieldValueB() = default;
LiteralFieldValueB::LiteralFieldValueB(const LiteralFieldValueB& other)
: FieldValue(other),
_value(),
- _backing(other.getValueRef()),
- _altered(other._altered)
+ _backing(other.getValueRef())
{
_value = _backing;
}
-LiteralFieldValueB::LiteralFieldValueB(const stringref & value)
- : FieldValue(),
+LiteralFieldValueB::LiteralFieldValueB(Type type, const stringref & value)
+ : FieldValue(type),
_value(),
- _backing(value),
- _altered(true)
+ _backing(value)
{
_value = _backing;
}
@@ -45,7 +40,6 @@ LiteralFieldValueB::operator=(const LiteralFieldValueB& other)
FieldValue::operator=(other);
_backing = other.getValueRef();
_value = _backing;
- _altered = other._altered;
return *this;
}
@@ -115,7 +109,7 @@ LiteralFieldValueB::syncBacking() const
_value = _backing;
}
-template class LiteralFieldValue<RawFieldValue, DataType::T_RAW, false>;
-template class LiteralFieldValue<StringFieldValue, DataType::T_STRING, true>;
+template class LiteralFieldValue<RawFieldValue, DataType::T_RAW>;
+template class LiteralFieldValue<StringFieldValue, DataType::T_STRING>;
} // namespace document
diff --git a/document/src/vespa/document/fieldvalue/literalfieldvalue.h b/document/src/vespa/document/fieldvalue/literalfieldvalue.h
index 6e3f0223b20..89f2f6afd74 100644
--- a/document/src/vespa/document/fieldvalue/literalfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/literalfieldvalue.h
@@ -24,15 +24,14 @@ class LiteralFieldValueB : public FieldValue {
public:
typedef vespalib::string string;
typedef vespalib::stringref stringref;
- DECLARE_IDENTIFIABLE_ABSTRACT(LiteralFieldValueB);
typedef std::unique_ptr<LiteralFieldValueB> UP;
typedef string value_type;
- LiteralFieldValueB();
+ explicit LiteralFieldValueB(Type type);
~LiteralFieldValueB();
LiteralFieldValueB(const LiteralFieldValueB &);
- LiteralFieldValueB(const stringref & value);
+ LiteralFieldValueB(Type type, const stringref & value);
const value_type & getValue() const { sync(); return _backing; }
/**
@@ -46,13 +45,11 @@ public:
void setValueRef(stringref value) {
_value = value;
- _altered = true;
}
void setValue(stringref value) {
_backing = value;
_value = _backing;
- _altered = true;
}
size_t hash() const override final { return vespalib::hashValue(_value.data(), _value.size()); }
void setValue(const char* val, size_t size) { setValue(stringref(val, size)); }
@@ -66,7 +63,6 @@ public:
void printXml(XmlOutputStream& out) const override;
void print(std::ostream& out, bool verbose, const std::string& indent) const override;
FieldValue& assign(const FieldValue&) override;
- bool hasChanged() const override{ return _altered; }
FieldValue& operator=(vespalib::stringref) override;
protected:
@@ -78,25 +74,18 @@ protected:
}
mutable stringref _value;
mutable string _backing; // Lazily set when needed
- mutable bool _altered; // Set if altered after deserialization
-private:
- virtual bool getAddZeroTerm() const = 0;
};
-template<typename SubClass, int type, bool addZeroTerm>
+template<typename SubClass, int dataType>
class LiteralFieldValue : public LiteralFieldValueB {
-private:
- bool getAddZeroTerm() const override{ return addZeroTerm; }
public:
- typedef std::unique_ptr<SubClass> UP;
-
- LiteralFieldValue() : LiteralFieldValueB() { }
- LiteralFieldValue(const stringref& value) : LiteralFieldValueB(value) { }
+ explicit LiteralFieldValue(Type type) : LiteralFieldValueB(type) { }
+ LiteralFieldValue(Type type, const stringref& value) : LiteralFieldValueB(type, value) { }
const DataType *getDataType() const override;
};
-extern template class LiteralFieldValue<RawFieldValue, DataType::T_RAW, false>;
-extern template class LiteralFieldValue<StringFieldValue, DataType::T_STRING, true>;
+extern template class LiteralFieldValue<RawFieldValue, DataType::T_RAW>;
+extern template class LiteralFieldValue<StringFieldValue, DataType::T_STRING>;
} // document
diff --git a/document/src/vespa/document/fieldvalue/literalfieldvalue.hpp b/document/src/vespa/document/fieldvalue/literalfieldvalue.hpp
index c5b30bc5ff1..91364de29fa 100644
--- a/document/src/vespa/document/fieldvalue/literalfieldvalue.hpp
+++ b/document/src/vespa/document/fieldvalue/literalfieldvalue.hpp
@@ -6,17 +6,17 @@
namespace document {
-template<typename SubClass, int type, bool addZeroTerm>
+template<typename SubClass, int dataType>
const DataType *
-LiteralFieldValue<SubClass, type, addZeroTerm>::getDataType() const
+LiteralFieldValue<SubClass, dataType>::getDataType() const
{
- switch (type) {
+ switch (dataType) {
case DataType::T_URI: return DataType::URI;
case DataType::T_STRING: return DataType::STRING;
case DataType::T_RAW: return DataType::RAW;
default:
throw vespalib::IllegalStateException(vespalib::make_string(
- "Illegal literal type id %i", type), VESPA_STRLOC);
+ "Illegal literal type id %i", dataType), VESPA_STRLOC);
}
}
diff --git a/document/src/vespa/document/fieldvalue/longfieldvalue.cpp b/document/src/vespa/document/fieldvalue/longfieldvalue.cpp
index f2f6cdb52b5..04f39f64beb 100644
--- a/document/src/vespa/document/fieldvalue/longfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/longfieldvalue.cpp
@@ -4,6 +4,4 @@
namespace document {
-IMPLEMENT_IDENTIFIABLE(LongFieldValue, NumericFieldValueBase);
-
} // document
diff --git a/document/src/vespa/document/fieldvalue/longfieldvalue.h b/document/src/vespa/document/fieldvalue/longfieldvalue.h
index 64ab4332cef..4b73ef0c2ea 100644
--- a/document/src/vespa/document/fieldvalue/longfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/longfieldvalue.h
@@ -12,11 +12,11 @@
namespace document {
-class LongFieldValue : public NumericFieldValue<int64_t> {
+class LongFieldValue final : public NumericFieldValue<int64_t> {
public:
typedef int64_t Number;
- LongFieldValue(Number value = 0) : NumericFieldValue<Number>(value) {}
+ LongFieldValue(Number value = 0) : NumericFieldValue<Number>(Type::LONG, value) {}
void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); }
void accept(ConstFieldValueVisitor &visitor) const override { visitor.visit(*this); }
@@ -25,7 +25,6 @@ public:
LongFieldValue* clone() const override { return new LongFieldValue(*this); }
using NumericFieldValue<Number>::operator=;
- DECLARE_IDENTIFIABLE(LongFieldValue);
static std::unique_ptr<LongFieldValue> make(Number value=0) { return std::make_unique<LongFieldValue>(value); }
};
diff --git a/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp b/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp
index 872185e7523..33ce4357f03 100644
--- a/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/mapfieldvalue.cpp
@@ -25,8 +25,6 @@ namespace document {
using namespace fieldvalue;
-IMPLEMENT_IDENTIFIABLE_ABSTRACT(MapFieldValue, FieldValue);
-
namespace {
const MapDataType *verifyMapType(const DataType& type) {
const MapDataType *ptr(dynamic_cast<const MapDataType *>(&type));
@@ -75,14 +73,13 @@ public:
}
MapFieldValue::MapFieldValue(const DataType &mapType)
- : FieldValue(),
+ : FieldValue(Type::MAP),
_type(verifyMapType(mapType)),
_count(0),
_keys(static_cast<IArray *>(createArray(getMapType().getKeyType()).release())),
_values(static_cast<IArray *>(createArray(getMapType().getValueType()).release())),
_present(),
- _lookupMap(),
- _altered(true)
+ _lookupMap()
{
}
@@ -95,8 +92,7 @@ MapFieldValue::MapFieldValue(const MapFieldValue & rhs) :
_keys(rhs._keys ? rhs._keys->clone() : nullptr),
_values(rhs._values ? rhs._values->clone() : nullptr),
_present(rhs._present),
- _lookupMap(),
- _altered(rhs._altered)
+ _lookupMap()
{
}
@@ -118,7 +114,6 @@ MapFieldValue::swap(MapFieldValue & rhs) {
std::swap(_values, rhs._values);
std::swap(_present, rhs._present);
std::swap(_lookupMap, rhs._lookupMap);
- std::swap(_altered, rhs._altered);
}
void MapFieldValue::verifyKey(const FieldValue & fv) const
@@ -146,7 +141,6 @@ MapFieldValue::insertVerify(const FieldValue& key, const FieldValue& value)
bool result(false);
if (found != end()) {
if (!(value == *found->second)) {
- _altered = true;
found->second->assign(value);
}
} else {
@@ -166,8 +160,6 @@ MapFieldValue::push_back(const FieldValue& key, const FieldValue& value)
if (_lookupMap) {
_lookupMap->insert(_present.size() - 1);
}
-
- _altered = true;
}
@@ -181,7 +173,6 @@ MapFieldValue::push_back(FieldValue::UP key, FieldValue::UP value)
if (_lookupMap) {
_lookupMap->insert(_present.size() - 1);
}
- _altered = true;
}
bool
@@ -255,7 +246,6 @@ MapFieldValue::erase(const FieldValue& key)
_count--;
_present[found.offset()] = false;
_lookupMap->erase(found.offset());
- _altered = true;
}
return result;
}
@@ -331,13 +321,6 @@ MapFieldValue::printXml(XmlOutputStream& xos) const
}
}
-bool
-MapFieldValue::hasChanged() const
-{
- // Keys are not allowed to change in a map, so the keys should not be
- // referred to externally, and should thus not need to be checked.
- return _altered;
-}
const DataType *
MapFieldValue::getDataType() const {
return _type;
@@ -369,7 +352,7 @@ MapFieldValue::buildLookupMap() const {
MapFieldValue::const_iterator
MapFieldValue::find(const FieldValue& key) const
{
- if ((size() > 0) && (key.getClass().id() == (*_keys)[0].getClass().id())) {
+ if ((size() > 0) && (key.type() == (*_keys)[0].type())) {
ssize_t index = findIndex(key);
if (index >= 0) {
return const_iterator(*this, index);
@@ -381,7 +364,7 @@ MapFieldValue::find(const FieldValue& key) const
MapFieldValue::iterator
MapFieldValue::find(const FieldValue& key)
{
- if ((size() > 0) && (key.getClass().id() == (*_keys)[0].getClass().id())) {
+ if ((size() > 0) && (key.type() == (*_keys)[0].type())) {
ssize_t index = findIndex(key);
if (index >= 0) {
return iterator(*this, index);
@@ -393,7 +376,7 @@ MapFieldValue::find(const FieldValue& key)
ssize_t
MapFieldValue::findIndex(const FieldValue& key) const
{
- if ((size() > 0) && (key.getClass().id() == (*_keys)[0].getClass().id())) {
+ if ((size() > 0) && (key.type() == (*_keys)[0].type())) {
ensureLookupMap();
auto found = _lookupMap->find(key);
if (found != _lookupMap->end()) {
@@ -428,7 +411,7 @@ MapFieldValue::iterateNestedImpl(PathRange nested,
IteratorHandler::CollectionScope autoScope(handler, complexFieldValue);
std::vector<const FieldValue*> keysToRemove;
bool wasModified = false;
- const bool isWSet(complexFieldValue.inherits(WeightedSetFieldValue::classId));
+ const bool isWSet(complexFieldValue.isA(FieldValue::Type::WSET));
uint32_t index(0);
if ( ! nested.atEnd() ) {
diff --git a/document/src/vespa/document/fieldvalue/mapfieldvalue.h b/document/src/vespa/document/fieldvalue/mapfieldvalue.h
index 5e8de6f3ed8..551543684f0 100644
--- a/document/src/vespa/document/fieldvalue/mapfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/mapfieldvalue.h
@@ -18,7 +18,7 @@ namespace document {
namespace mapfieldvalue {
class HashMap;
}
-class MapFieldValue : public FieldValue
+class MapFieldValue final : public FieldValue
{
public:
using IArray=vespalib::IArrayT<FieldValue>;
@@ -134,7 +134,6 @@ public:
MapFieldValue* clone() const override { return new MapFieldValue(*this); }
int compare(const FieldValue&) const override;
void print(std::ostream& out, bool verbose, const std::string& indent) const override;
- bool hasChanged() const override;
const DataType *getDataType() const override;
void printXml(XmlOutputStream& out) const override;
@@ -162,8 +161,6 @@ public:
}
FieldValue::UP createValue() const;
-
- DECLARE_IDENTIFIABLE_ABSTRACT(MapFieldValue);
};
} // namespace document
diff --git a/document/src/vespa/document/fieldvalue/numericfieldvalue.cpp b/document/src/vespa/document/fieldvalue/numericfieldvalue.cpp
index 7d02054f668..6247e815d73 100644
--- a/document/src/vespa/document/fieldvalue/numericfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/numericfieldvalue.cpp
@@ -6,8 +6,6 @@
namespace document {
-IMPLEMENT_IDENTIFIABLE_ABSTRACT(NumericFieldValueBase, FieldValue);
-
void
NumericFieldValueBase::printXml(XmlOutputStream& out) const
{
diff --git a/document/src/vespa/document/fieldvalue/numericfieldvalue.h b/document/src/vespa/document/fieldvalue/numericfieldvalue.h
index 28981fc5286..a19456f0e4a 100644
--- a/document/src/vespa/document/fieldvalue/numericfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/numericfieldvalue.h
@@ -18,21 +18,19 @@ namespace document {
class NumericFieldValueBase : public FieldValue
{
public:
- DECLARE_IDENTIFIABLE_ABSTRACT(NumericFieldValueBase);
void printXml(XmlOutputStream& out) const override;
+protected:
+ NumericFieldValueBase(Type type) : FieldValue(type) {}
};
template<typename Number>
class NumericFieldValue : public NumericFieldValueBase {
protected:
+ explicit NumericFieldValue(Type type, Number value=0) : NumericFieldValueBase(type), _value(value) { }
Number _value;
- bool _altered;
-
public:
typedef Number value_type;
- explicit NumericFieldValue(Number value=0) : NumericFieldValueBase(), _value(value), _altered(false) { }
-
value_type getValue() const { return _value; }
void setValue(Number newValue) { _value = newValue; }
@@ -51,7 +49,6 @@ public:
vespalib::string getAsString() const override;
void print(std::ostream& out, bool verbose, const std::string& indent) const override;
- bool hasChanged() const override final { return _altered; }
};
extern template class NumericFieldValue<float>;
diff --git a/document/src/vespa/document/fieldvalue/numericfieldvalue.hpp b/document/src/vespa/document/fieldvalue/numericfieldvalue.hpp
index f1bbce5450d..0c214a97aec 100644
--- a/document/src/vespa/document/fieldvalue/numericfieldvalue.hpp
+++ b/document/src/vespa/document/fieldvalue/numericfieldvalue.hpp
@@ -17,22 +17,21 @@ template<typename Number>
FieldValue&
NumericFieldValue<Number>::assign(const FieldValue& value)
{
- if (value.getClass().id() == IDENTIFIABLE_CLASSID(ByteFieldValue)) {
+ if (value.isA(FieldValue::Type::BYTE)) {
_value = static_cast<Number>(value.getAsByte());
- } else if (value.getClass().id() == IDENTIFIABLE_CLASSID(ShortFieldValue)) {
+ } else if (value.isA(FieldValue::Type::SHORT)) {
_value = static_cast<Number>(value.getAsInt());
- } else if (value.getClass().id() == IDENTIFIABLE_CLASSID(IntFieldValue)) {
+ } else if (value.isA(FieldValue::Type::INT)) {
_value = static_cast<Number>(value.getAsInt());
- } else if (value.getClass().id() == IDENTIFIABLE_CLASSID(LongFieldValue)) {
+ } else if (value.isA(FieldValue::Type::LONG)) {
_value = static_cast<Number>(value.getAsLong());
- } else if (value.getClass().id() == IDENTIFIABLE_CLASSID(FloatFieldValue)) {
+ } else if (value.isA(FieldValue::Type::FLOAT)) {
_value = static_cast<Number>(value.getAsFloat());
- } else if (value.getClass().id() == IDENTIFIABLE_CLASSID(DoubleFieldValue)) {
+ } else if (value.isA(FieldValue::Type::DOUBLE)) {
_value = static_cast<Number>(value.getAsDouble());
} else {
return FieldValue::assign(value);
}
- _altered = true;
return *this;
}
@@ -91,7 +90,6 @@ NumericFieldValue<Number>::operator=(vespalib::stringref value)
// Allow numbers to be specified in range max signed to max
// unsigned. These become negative numbers.
_value = static_cast<Number>(val);
- _altered = true;
return *this;
}
}
@@ -118,7 +116,6 @@ NumericFieldValue<Number>::operator=(vespalib::stringref value)
}
}
}
- _altered = true;
return *this;
}
diff --git a/document/src/vespa/document/fieldvalue/predicatefieldvalue.cpp b/document/src/vespa/document/fieldvalue/predicatefieldvalue.cpp
index 3a62eb5060c..b474db2ab6e 100644
--- a/document/src/vespa/document/fieldvalue/predicatefieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/predicatefieldvalue.cpp
@@ -14,22 +14,19 @@ using namespace vespalib::xml;
namespace document {
-IMPLEMENT_IDENTIFIABLE(PredicateFieldValue, FieldValue);
-
PredicateFieldValue::PredicateFieldValue()
- : _slime(std::make_unique<Slime>()), _altered(false) {
-}
+ : FieldValue(Type::PREDICATE),
+ _slime(std::make_unique<Slime>())
+{ }
PredicateFieldValue::PredicateFieldValue(vespalib::Slime::UP s)
- : FieldValue(),
- _slime(std::move(s)),
- _altered(false)
+ : FieldValue(Type::PREDICATE),
+ _slime(std::move(s))
{ }
PredicateFieldValue::PredicateFieldValue(const PredicateFieldValue &rhs)
: FieldValue(rhs),
- _slime(new Slime),
- _altered(rhs._altered)
+ _slime(new Slime)
{
inject(rhs._slime->get(), SlimeInserter(*_slime));
}
@@ -38,11 +35,10 @@ PredicateFieldValue::~PredicateFieldValue() = default;
FieldValue &
PredicateFieldValue::assign(const FieldValue &rhs) {
- if (rhs.inherits(PredicateFieldValue::classId)) {
+ if (rhs.isA(Type::PREDICATE)) {
operator=(static_cast<const PredicateFieldValue &>(rhs));
} else {
_slime.reset();
- _altered = true;
}
return *this;
}
@@ -52,7 +48,6 @@ PredicateFieldValue::operator=(const PredicateFieldValue &rhs)
{
_slime = std::make_unique<Slime>();
inject(rhs._slime->get(), SlimeInserter(*_slime));
- _altered = true;
return *this;
}
@@ -79,11 +74,6 @@ PredicateFieldValue::getDataType() const {
return DataType::PREDICATE;
}
-bool
-PredicateFieldValue::hasChanged() const {
- return _altered;
-}
-
FieldValue *
PredicateFieldValue::clone() const {
return new PredicateFieldValue(*this);
diff --git a/document/src/vespa/document/fieldvalue/predicatefieldvalue.h b/document/src/vespa/document/fieldvalue/predicatefieldvalue.h
index 5f7db35f953..c99a82a59e2 100644
--- a/document/src/vespa/document/fieldvalue/predicatefieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/predicatefieldvalue.h
@@ -9,9 +9,8 @@ namespace vespalib {
}
namespace document {
-class PredicateFieldValue : public FieldValue {
+class PredicateFieldValue final : public FieldValue {
std::unique_ptr<vespalib::Slime> _slime;
- bool _altered;
PredicateFieldValue & operator=(const PredicateFieldValue &rhs);
public:
@@ -33,13 +32,10 @@ public:
void print(std::ostream &out, bool verbose, const std::string &indent) const override;
const DataType *getDataType() const override;
- bool hasChanged() const override;
const vespalib::Slime &getSlime() const { return *_slime; }
FieldValue &assign(const FieldValue &rhs) override;
-
- DECLARE_IDENTIFIABLE(PredicateFieldValue);
};
}
diff --git a/document/src/vespa/document/fieldvalue/rawfieldvalue.cpp b/document/src/vespa/document/fieldvalue/rawfieldvalue.cpp
index 95f066b86ed..ab17a879dfa 100644
--- a/document/src/vespa/document/fieldvalue/rawfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/rawfieldvalue.cpp
@@ -9,8 +9,6 @@ using namespace vespalib::xml;
namespace document {
-IMPLEMENT_IDENTIFIABLE(RawFieldValue, LiteralFieldValueB);
-
void
RawFieldValue::printXml(XmlOutputStream& out) const
{
diff --git a/document/src/vespa/document/fieldvalue/rawfieldvalue.h b/document/src/vespa/document/fieldvalue/rawfieldvalue.h
index 98110816a9d..b946ecd0038 100644
--- a/document/src/vespa/document/fieldvalue/rawfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/rawfieldvalue.h
@@ -12,20 +12,19 @@
namespace document {
-class RawFieldValue
- : public LiteralFieldValue<RawFieldValue, DataType::T_RAW, false>
+class RawFieldValue final : public LiteralFieldValue<RawFieldValue, DataType::T_RAW>
{
public:
- typedef LiteralFieldValue<RawFieldValue, DataType::T_RAW, false> Parent;
+ typedef LiteralFieldValue<RawFieldValue, DataType::T_RAW> Parent;
RawFieldValue()
- : Parent() { }
+ : Parent(Type::RAW) { }
RawFieldValue(const string& value)
- : Parent(value) {}
+ : Parent(Type::RAW, value) {}
RawFieldValue(const char* rawVal, int len)
- : Parent(string(rawVal, len))
+ : Parent(Type::RAW, string(rawVal, len))
{
}
@@ -37,8 +36,6 @@ public:
void print(std::ostream& out, bool verbose, const std::string& indent) const override;
RawFieldValue& operator=(const string& value) { setValue(value); return *this; }
-
- DECLARE_IDENTIFIABLE(RawFieldValue);
};
} // document
diff --git a/document/src/vespa/document/fieldvalue/referencefieldvalue.cpp b/document/src/vespa/document/fieldvalue/referencefieldvalue.cpp
index 328e5b67151..cade633fb00 100644
--- a/document/src/vespa/document/fieldvalue/referencefieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/referencefieldvalue.cpp
@@ -11,28 +11,24 @@ using vespalib::make_string;
namespace document {
-IMPLEMENT_IDENTIFIABLE(ReferenceFieldValue, FieldValue);
-
ReferenceFieldValue::ReferenceFieldValue()
- : _dataType(nullptr),
- _documentId(),
- _altered(true)
+ : FieldValue(Type::REFERENCE),
+ _dataType(nullptr),
+ _documentId()
{
}
ReferenceFieldValue::ReferenceFieldValue(const ReferenceDataType& dataType)
- : _dataType(&dataType),
- _documentId(),
- _altered(true)
+ : FieldValue(Type::REFERENCE),
+ _dataType(&dataType),
+ _documentId()
{
}
-ReferenceFieldValue::ReferenceFieldValue(
- const ReferenceDataType& dataType,
- const DocumentId& documentId)
- : _dataType(&dataType),
- _documentId(documentId),
- _altered(true)
+ReferenceFieldValue::ReferenceFieldValue(const ReferenceDataType& dataType, const DocumentId& documentId)
+ : FieldValue(Type::REFERENCE),
+ _dataType(&dataType),
+ _documentId(documentId)
{
requireIdOfMatchingType(_documentId, _dataType->getTargetType());
}
@@ -67,7 +63,6 @@ FieldValue& ReferenceFieldValue::assign(const FieldValue& rhs) {
}
_documentId = refValueRhs->_documentId;
_dataType = refValueRhs->_dataType;
- _altered = true;
return *this;
}
@@ -77,7 +72,6 @@ void ReferenceFieldValue::setDeserializedDocumentId(const DocumentId& id) {
_documentId = id;
// Pre-cache GID to ensure it's not attempted lazily initialized later in a racing manner.
(void) _documentId.getGlobalId();
- _altered = false;
}
ReferenceFieldValue* ReferenceFieldValue::clone() const {
@@ -109,10 +103,6 @@ void ReferenceFieldValue::print(std::ostream& os, bool verbose, const std::strin
os << indent << "ReferenceFieldValue(" << *_dataType << ", DocumentId(" << _documentId << "))";
}
-bool ReferenceFieldValue::hasChanged() const {
- return _altered;
-}
-
void ReferenceFieldValue::accept(FieldValueVisitor& visitor) {
visitor.visit(*this);
}
diff --git a/document/src/vespa/document/fieldvalue/referencefieldvalue.h b/document/src/vespa/document/fieldvalue/referencefieldvalue.h
index d8160353b5f..c8adb49102a 100644
--- a/document/src/vespa/document/fieldvalue/referencefieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/referencefieldvalue.h
@@ -22,11 +22,10 @@ namespace document {
* document type "foo" inheriting "bar", you cannot have a reference<bar> field
* containing a document ID for a "foo" document.
*/
-class ReferenceFieldValue : public FieldValue {
+class ReferenceFieldValue final : public FieldValue {
const ReferenceDataType* _dataType;
// TODO wrap in std::optional once available.
DocumentId _documentId;
- bool _altered;
public:
// Empty constructor required for Identifiable.
ReferenceFieldValue();
@@ -53,9 +52,6 @@ public:
// Should only be called by deserializer code, as it will clear hasChanged.
// `id` must be a valid document ID and cannot be empty.
void setDeserializedDocumentId(const DocumentId& id);
- void clearChanged() {
- _altered = false;
- }
const DataType* getDataType() const override { return _dataType; }
FieldValue& assign(const FieldValue&) override;
@@ -63,16 +59,12 @@ public:
int compare(const FieldValue&) const override;
void printXml(XmlOutputStream&) const override { /* Not implemented */ }
void print(std::ostream&, bool, const std::string&) const override;
- bool hasChanged() const override;
void accept(FieldValueVisitor&) override;
void accept(ConstFieldValueVisitor&) const override;
-
- DECLARE_IDENTIFIABLE(ReferenceFieldValue);
private:
// Throws vespalib::IllegalArgumentException if doc type of `id` does not
// match the name of `type`.
- static void requireIdOfMatchingType(
- const DocumentId& id, const DocumentType& type);
+ static void requireIdOfMatchingType(const DocumentId& id, const DocumentType& type);
};
} // document
diff --git a/document/src/vespa/document/fieldvalue/shortfieldvalue.cpp b/document/src/vespa/document/fieldvalue/shortfieldvalue.cpp
index 9f0334a12ae..02fa8fb30a2 100644
--- a/document/src/vespa/document/fieldvalue/shortfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/shortfieldvalue.cpp
@@ -5,6 +5,4 @@
namespace document {
-IMPLEMENT_IDENTIFIABLE(ShortFieldValue, NumericFieldValueBase);
-
} // document
diff --git a/document/src/vespa/document/fieldvalue/shortfieldvalue.h b/document/src/vespa/document/fieldvalue/shortfieldvalue.h
index fa61c37c4eb..e135f2a4f54 100644
--- a/document/src/vespa/document/fieldvalue/shortfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/shortfieldvalue.h
@@ -12,13 +12,13 @@
namespace document {
-class ShortFieldValue : public NumericFieldValue<int16_t> {
+class ShortFieldValue final : public NumericFieldValue<int16_t> {
public:
typedef std::unique_ptr<ShortFieldValue> UP;
typedef int16_t Number;
ShortFieldValue(Number value = 0)
- : NumericFieldValue<Number>(value) {}
+ : NumericFieldValue<Number>(Type::SHORT, value) {}
void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); }
void accept(ConstFieldValueVisitor &visitor) const override { visitor.visit(*this); }
@@ -27,7 +27,6 @@ public:
ShortFieldValue* clone() const override { return new ShortFieldValue(*this); }
using NumericFieldValue<Number>::operator=;
- DECLARE_IDENTIFIABLE(ShortFieldValue);
static std::unique_ptr<ShortFieldValue> make(int16_t value = 0) { return std::make_unique<ShortFieldValue>(value); }
};
diff --git a/document/src/vespa/document/fieldvalue/stringfieldvalue.cpp b/document/src/vespa/document/fieldvalue/stringfieldvalue.cpp
index 0a46a11bddf..47e96b4f4e4 100644
--- a/document/src/vespa/document/fieldvalue/stringfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/stringfieldvalue.cpp
@@ -19,17 +19,16 @@ using vespalib::stringref;
namespace document {
-IMPLEMENT_IDENTIFIABLE(StringFieldValue, LiteralFieldValueB);
-
-StringFieldValue::StringFieldValue(const StringFieldValue & rhs) :
- Parent(rhs),
- _annotationData(rhs.copyAnnotationData())
+StringFieldValue::StringFieldValue(const StringFieldValue & rhs)
+ : Parent(rhs),
+ _annotationData(rhs.copyAnnotationData())
{
}
-StringFieldValue::~StringFieldValue() {}
+StringFieldValue::~StringFieldValue() = default;
-StringFieldValue & StringFieldValue::operator=(const StringFieldValue & rhs)
+StringFieldValue &
+StringFieldValue::operator=(const StringFieldValue & rhs)
{
if (&rhs != this) {
Parent::operator=(rhs);
@@ -38,8 +37,9 @@ StringFieldValue & StringFieldValue::operator=(const StringFieldValue & rhs)
return *this;
}
-int StringFieldValue::compare(const FieldValue& other) const {
- if (other.inherits(StringFieldValue::classId)) {
+int
+StringFieldValue::compare(const FieldValue& other) const {
+ if (other.isA(Type::STRING)) {
const StringFieldValue &other_s(static_cast<const StringFieldValue &>(other));
return _value.compare(other_s._value);
} else {
@@ -47,7 +47,8 @@ int StringFieldValue::compare(const FieldValue& other) const {
}
}
-void StringFieldValue::print(std::ostream& out, bool verbose, const std::string& indent) const {
+void
+StringFieldValue::print(std::ostream& out, bool verbose, const std::string& indent) const {
if ( ! hasSpanTrees()) {
Parent::print(out, verbose, indent);
} else {
@@ -88,7 +89,8 @@ StringFieldValue::doClearSpanTrees() {
_annotationData.reset();
}
-const SpanTree * StringFieldValue::findTree(const SpanTrees & trees, stringref name)
+const SpanTree *
+StringFieldValue::findTree(const SpanTrees & trees, stringref name)
{
for(const auto & tree : trees) {
if (tree->getName() == name) {
@@ -98,16 +100,18 @@ const SpanTree * StringFieldValue::findTree(const SpanTrees & trees, stringref n
return nullptr;
}
-StringFieldValue &StringFieldValue::operator=(stringref value)
+StringFieldValue &
+StringFieldValue::operator=(stringref value)
{
setValue(value);
_annotationData.reset();
return *this;
}
-FieldValue & StringFieldValue::assign(const FieldValue & rhs)
+FieldValue &
+StringFieldValue::assign(const FieldValue & rhs)
{
- if (rhs.inherits(StringFieldValue::classId)) {
+ if (rhs.isA(Type::STRING)) {
*this = static_cast<const StringFieldValue &>(rhs);
} else {
*this = rhs.getAsString().operator stringref();
diff --git a/document/src/vespa/document/fieldvalue/stringfieldvalue.h b/document/src/vespa/document/fieldvalue/stringfieldvalue.h
index 07e9e578692..95cd9c6190c 100644
--- a/document/src/vespa/document/fieldvalue/stringfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/stringfieldvalue.h
@@ -17,14 +17,14 @@ namespace document {
class FixedTypeRepo;
class DocumentTypeRepo;
-class StringFieldValue : public LiteralFieldValue<StringFieldValue, DataType::T_STRING, true> {
+class StringFieldValue final : public LiteralFieldValue<StringFieldValue, DataType::T_STRING> {
public:
- typedef LiteralFieldValue<StringFieldValue, DataType::T_STRING, true> Parent;
+ typedef LiteralFieldValue<StringFieldValue, DataType::T_STRING> Parent;
typedef std::vector<SpanTree::UP> SpanTrees;
- StringFieldValue() : Parent(), _annotationData() { }
+ StringFieldValue() : Parent(Type::STRING), _annotationData() { }
StringFieldValue(const vespalib::stringref &value)
- : Parent(value), _annotationData() { }
+ : Parent(Type::STRING, value), _annotationData() { }
StringFieldValue(const StringFieldValue &rhs);
@@ -55,7 +55,6 @@ public:
}
using LiteralFieldValueB::operator=;
- DECLARE_IDENTIFIABLE(StringFieldValue);
static std::unique_ptr<StringFieldValue> make(vespalib::stringref value) { return std::make_unique<StringFieldValue>(value); }
static std::unique_ptr<StringFieldValue> make() { return StringFieldValue::make(""); }
private:
diff --git a/document/src/vespa/document/fieldvalue/structfieldvalue.cpp b/document/src/vespa/document/fieldvalue/structfieldvalue.cpp
index fbe6dadb320..529e608533e 100644
--- a/document/src/vespa/document/fieldvalue/structfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/structfieldvalue.cpp
@@ -27,10 +27,8 @@ using namespace vespalib::xml;
namespace document {
-IMPLEMENT_IDENTIFIABLE_ABSTRACT(StructFieldValue, StructuredFieldValue);
-
StructFieldValue::StructFieldValue(const DataType &type)
- : StructuredFieldValue(type),
+ : StructuredFieldValue(Type::STRUCT, type),
_fields(),
_repo(nullptr),
_doc_type(nullptr),
diff --git a/document/src/vespa/document/fieldvalue/structfieldvalue.h b/document/src/vespa/document/fieldvalue/structfieldvalue.h
index 24e143ddc27..564c48273e6 100644
--- a/document/src/vespa/document/fieldvalue/structfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/structfieldvalue.h
@@ -22,7 +22,7 @@ class FixedTypeRepo;
class FieldSet;
class StructDataType;
-class StructFieldValue : public StructuredFieldValue
+class StructFieldValue final : public StructuredFieldValue
{
private:
SerializableArray _fields;
@@ -76,7 +76,12 @@ public:
bool empty() const override;
- bool hasChanged() const override { return _hasChanged; }
+ /**
+ * Returns true if this object have been altered since last
+ * serialization/deserialization. If hasChanged() is false, then cached
+ * information from last serialization effort is still valid.
+ */
+ bool hasChanged() const { return _hasChanged; }
uint32_t calculateChecksum() const;
@@ -85,9 +90,6 @@ public:
* has no content. This clears content and sets changed to false.
*/
void reset();
-
- DECLARE_IDENTIFIABLE_ABSTRACT(StructFieldValue);
-
private:
void setFieldValue(const Field&, FieldValue::UP value) override;
FieldValue::UP getFieldValue(const Field&) const override;
diff --git a/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp b/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp
index 53f75cb2e73..53a5fa14fee 100644
--- a/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/structuredfieldvalue.cpp
@@ -16,8 +16,6 @@ namespace document {
using namespace fieldvalue;
-IMPLEMENT_IDENTIFIABLE_ABSTRACT(StructuredFieldValue, FieldValue);
-
StructuredFieldValue::Iterator::Iterator()
: _iterator(),
_field(nullptr)
diff --git a/document/src/vespa/document/fieldvalue/structuredfieldvalue.h b/document/src/vespa/document/fieldvalue/structuredfieldvalue.h
index 9d79b6279a4..fdc4ecf7765 100644
--- a/document/src/vespa/document/fieldvalue/structuredfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/structuredfieldvalue.h
@@ -44,7 +44,7 @@ class StructuredFieldValue : public FieldValue
virtual StructuredCache * getCache() const { return nullptr; }
protected:
- StructuredFieldValue(const DataType &type) : FieldValue(), _type(&type) {}
+ StructuredFieldValue(Type type, const DataType &dataType) : FieldValue(type), _type(&dataType) {}
/** Called from Document when deserializing alters type. */
virtual void setType(const DataType& type) { _type = &type; }
@@ -106,8 +106,6 @@ protected:
fieldvalue::ModificationStatus
onIterateNested(PathRange nested, fieldvalue::IteratorHandler & handler) const override;
public:
- DECLARE_IDENTIFIABLE_ABSTRACT(StructuredFieldValue);
-
StructuredFieldValue* clone() const override = 0;
const DataType *getDataType() const override { return _type; }
diff --git a/document/src/vespa/document/fieldvalue/structuredfieldvalue.hpp b/document/src/vespa/document/fieldvalue/structuredfieldvalue.hpp
index 4b347d7cc07..c142fd9b6eb 100644
--- a/document/src/vespa/document/fieldvalue/structuredfieldvalue.hpp
+++ b/document/src/vespa/document/fieldvalue/structuredfieldvalue.hpp
@@ -12,7 +12,7 @@ template <typename T>
std::unique_ptr<T>
StructuredFieldValue::getAs(const Field &field) const {
FieldValue::UP val = getValue(field);
- T *t = Identifiable::cast<T *>(val.get());
+ T *t = dynamic_cast<T *>(val.get());
if (val.get() && !t) {
throw vespalib::IllegalStateException("Field " + field.toString() + " has unexpected type.", VESPA_STRLOC);
}
diff --git a/document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp b/document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp
index 42f4080d6b6..d9a56f9fa56 100644
--- a/document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/tensorfieldvalue.cpp
@@ -36,18 +36,16 @@ TensorFieldValue::TensorFieldValue()
}
TensorFieldValue::TensorFieldValue(const TensorDataType &dataType)
- : FieldValue(),
+ : FieldValue(Type::TENSOR),
_dataType(dataType),
- _tensor(),
- _altered(true)
+ _tensor()
{
}
TensorFieldValue::TensorFieldValue(const TensorFieldValue &rhs)
- : FieldValue(),
+ : FieldValue(Type::TENSOR),
_dataType(rhs._dataType),
- _tensor(),
- _altered(true)
+ _tensor()
{
if (rhs._tensor) {
_tensor = FastValueBuilderFactory::get().copy(*rhs._tensor);
@@ -56,10 +54,9 @@ TensorFieldValue::TensorFieldValue(const TensorFieldValue &rhs)
TensorFieldValue::TensorFieldValue(TensorFieldValue &&rhs)
- : FieldValue(),
+ : FieldValue(Type::TENSOR),
_dataType(rhs._dataType),
- _tensor(),
- _altered(true)
+ _tensor()
{
_tensor = std::move(rhs._tensor);
}
@@ -81,7 +78,6 @@ TensorFieldValue::operator=(const TensorFieldValue &rhs)
} else {
_tensor.reset();
}
- _altered = true;
} else {
throw WrongTensorTypeException(makeWrongTensorTypeMsg(_dataType.getTensorType(), rhs._tensor->type()), VESPA_STRLOC);
}
@@ -95,7 +91,6 @@ TensorFieldValue::operator=(std::unique_ptr<vespalib::eval::Value> rhs)
{
if (!rhs || _dataType.isAssignableType(rhs->type())) {
_tensor = std::move(rhs);
- _altered = true;
} else {
throw WrongTensorTypeException(makeWrongTensorTypeMsg(_dataType.getTensorType(), rhs->type()), VESPA_STRLOC);
}
@@ -133,14 +128,6 @@ TensorFieldValue::getDataType() const
return &_dataType;
}
-
-bool
-TensorFieldValue::hasChanged() const
-{
- return _altered;
-}
-
-
TensorFieldValue*
TensorFieldValue::clone() const
{
@@ -173,9 +160,8 @@ TensorFieldValue::printXml(XmlOutputStream& out) const
FieldValue &
TensorFieldValue::assign(const FieldValue &value)
{
- const TensorFieldValue *rhs =
- Identifiable::cast<const TensorFieldValue *>(&value);
- if (rhs != nullptr) {
+ if (value.isA(Type::TENSOR)) {
+ const auto * rhs = static_cast<const TensorFieldValue *>(&value);
*this = *rhs;
} else {
return FieldValue::assign(value);
@@ -189,7 +175,6 @@ TensorFieldValue::assignDeserialized(std::unique_ptr<vespalib::eval::Value> rhs)
{
if (!rhs || _dataType.isAssignableType(rhs->type())) {
_tensor = std::move(rhs);
- _altered = false; // Serialized form already exists
} else {
throw WrongTensorTypeException(makeWrongTensorTypeMsg(_dataType.getTensorType(), rhs->type()), VESPA_STRLOC);
}
@@ -232,6 +217,4 @@ TensorFieldValue::compare(const FieldValue &other) const
return lhs_spec.compare(rhs_spec);
}
-IMPLEMENT_IDENTIFIABLE(TensorFieldValue, FieldValue);
-
} // document
diff --git a/document/src/vespa/document/fieldvalue/tensorfieldvalue.h b/document/src/vespa/document/fieldvalue/tensorfieldvalue.h
index 6cb2ff08c2e..52b27346ff8 100644
--- a/document/src/vespa/document/fieldvalue/tensorfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/tensorfieldvalue.h
@@ -13,39 +13,34 @@ class TensorDataType;
/**
* Field value representing a tensor.
*/
-class TensorFieldValue : public FieldValue {
+class TensorFieldValue final : public FieldValue {
private:
const TensorDataType &_dataType;
std::unique_ptr<vespalib::eval::Value> _tensor;
- bool _altered;
public:
TensorFieldValue();
explicit TensorFieldValue(const TensorDataType &dataType);
TensorFieldValue(const TensorFieldValue &rhs);
TensorFieldValue(TensorFieldValue &&rhs);
- ~TensorFieldValue();
+ ~TensorFieldValue() override;
TensorFieldValue &operator=(const TensorFieldValue &rhs);
TensorFieldValue &operator=(std::unique_ptr<vespalib::eval::Value> rhs);
void make_empty_if_not_existing();
- virtual void accept(FieldValueVisitor &visitor) override;
- virtual void accept(ConstFieldValueVisitor &visitor) const override;
- virtual const DataType *getDataType() const override;
- virtual bool hasChanged() const override;
- virtual TensorFieldValue* clone() const override;
- virtual void print(std::ostream& out, bool verbose,
- const std::string& indent) const override;
- virtual void printXml(XmlOutputStream& out) const override;
- virtual FieldValue &assign(const FieldValue &value) override;
+ void accept(FieldValueVisitor &visitor) override;
+ void accept(ConstFieldValueVisitor &visitor) const override;
+ const DataType *getDataType() const override;
+ TensorFieldValue* clone() const override;
+ void print(std::ostream& out, bool verbose, const std::string& indent) const override;
+ void printXml(XmlOutputStream& out) const override;
+ FieldValue &assign(const FieldValue &value) override;
const vespalib::eval::Value *getAsTensorPtr() const {
return _tensor.get();
}
void assignDeserialized(std::unique_ptr<vespalib::eval::Value> rhs);
- virtual int compare(const FieldValue& other) const override;
-
- DECLARE_IDENTIFIABLE(TensorFieldValue);
+ int compare(const FieldValue& other) const override;
};
} // document
diff --git a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp
index 2a3726095df..fd26deab15a 100644
--- a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp
+++ b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.cpp
@@ -18,8 +18,6 @@ namespace document {
using namespace fieldvalue;
-IMPLEMENT_IDENTIFIABLE_ABSTRACT(WeightedSetFieldValue, CollectionFieldValue);
-
namespace {
const DataType &getKeyType(const DataType &type) {
const WeightedSetDataType *wtype = dynamic_cast<const WeightedSetDataType *>(&type);
@@ -32,10 +30,9 @@ const DataType &getKeyType(const DataType &type) {
} // namespace
WeightedSetFieldValue::WeightedSetFieldValue(const DataType &type)
- : CollectionFieldValue(type),
+ : CollectionFieldValue(Type::WSET, type),
_map_type(std::make_shared<MapDataType>(getKeyType(type), *DataType::INT)),
- _map(*_map_type),
- _altered(true)
+ _map(*_map_type)
{ }
WeightedSetFieldValue::WeightedSetFieldValue(const WeightedSetFieldValue &) = default;
@@ -54,7 +51,6 @@ WeightedSetFieldValue::add(const FieldValue& key, int weight)
{
verifyKey(key);
const WeightedSetDataType & wdt(static_cast<const WeightedSetDataType&>(*_type));
- _altered = true;
if (wdt.removeIfZero() && (weight == 0)) {
_map.erase(key);
return false;
@@ -66,14 +62,12 @@ bool
WeightedSetFieldValue::addIgnoreZeroWeight(const FieldValue& key, int32_t weight)
{
verifyKey(key);
- _altered = true;
return _map.insert(FieldValue::UP(key.clone()), IntFieldValue::make(weight));
}
void
WeightedSetFieldValue::push_back(FieldValue::UP key, int weight)
{
- _altered = true;
_map.push_back(std::move(key), IntFieldValue::make(weight));
}
@@ -103,7 +97,6 @@ WeightedSetFieldValue::increment(const FieldValue& key, int val)
_map.erase(key);
}
}
- _altered = true;
}
int32_t
@@ -125,7 +118,6 @@ bool
WeightedSetFieldValue::removeValue(const FieldValue& key)
{
bool result = _map.erase(key);
- _altered |= result;
return result;
}
@@ -179,14 +171,6 @@ WeightedSetFieldValue::print(std::ostream& out, bool verbose, const std::string&
out << ")";
}
-bool
-WeightedSetFieldValue::hasChanged() const
-{
- // Keys are not allowed to change in a map, so the keys should not be
- // referred to externally, and should thus not need to be checked.
- return _altered;
-}
-
WeightedSetFieldValue::const_iterator
WeightedSetFieldValue::find(const FieldValue& key) const
{
diff --git a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h
index d58819607b4..b2183efef42 100644
--- a/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h
+++ b/document/src/vespa/document/fieldvalue/weightedsetfieldvalue.h
@@ -14,7 +14,7 @@
namespace document {
-class WeightedSetFieldValue : public CollectionFieldValue
+class WeightedSetFieldValue final : public CollectionFieldValue
{
public:
struct FieldValuePtrOrder {
@@ -26,7 +26,6 @@ public:
private:
std::shared_ptr<const MapDataType> _map_type;
WeightedFieldValueMap _map;
- bool _altered;
void verifyKey(const FieldValue & key);
bool addValue(const FieldValue& fval) override { return add(fval, 1); }
@@ -46,7 +45,7 @@ public:
WeightedSetFieldValue & operator = (const WeightedSetFieldValue &);
WeightedSetFieldValue(WeightedSetFieldValue &&) = default;
WeightedSetFieldValue & operator = (WeightedSetFieldValue &&) = default;
- ~WeightedSetFieldValue();
+ ~WeightedSetFieldValue() override;
void accept(FieldValueVisitor &visitor) override { visitor.visit(*this); }
void accept(ConstFieldValueVisitor &visitor) const override { visitor.visit(*this); }
@@ -78,7 +77,6 @@ public:
int compare(const FieldValue&) const override;
void printXml(XmlOutputStream& out) const override;
void print(std::ostream& out, bool verbose, const std::string& indent) const override;
- bool hasChanged() const override;
// Implements iterating through internal content.
typedef WeightedFieldValueMap::const_iterator const_iterator;
@@ -92,8 +90,6 @@ public:
const_iterator find(const FieldValue& fv) const;
iterator find(const FieldValue& fv);
-
- DECLARE_IDENTIFIABLE_ABSTRACT(WeightedSetFieldValue);
};
} // document
diff --git a/document/src/vespa/document/select/valuenodes.cpp b/document/src/vespa/document/select/valuenodes.cpp
index 52e6b2e4223..f34b2e83b08 100644
--- a/document/src/vespa/document/select/valuenodes.cpp
+++ b/document/src/vespa/document/select/valuenodes.cpp
@@ -11,7 +11,6 @@
#include <vespa/vespalib/util/md5.h>
#include <vespa/document/util/stringutil.h>
#include <vespa/vespalib/text/lowercase.h>
-#include <regex>
#include <iomanip>
#include <sys/time.h>
@@ -272,43 +271,43 @@ IteratorHandler::onPrimitive(uint32_t fid, const Content& fv) {
std::unique_ptr<Value>
IteratorHandler::getInternalValue(const FieldValue& fval) const
{
- switch(fval.getClass().id()) {
- case document::BoolFieldValue::classId:
+ switch(fval.type()) {
+ case FieldValue::Type::BOOL:
{
const auto& val(dynamic_cast<const BoolFieldValue&>(fval));
return std::make_unique<IntegerValue>(val.getAsInt(), false);
}
- case document::IntFieldValue::classId:
+ case FieldValue::Type::INT:
{
const auto& val(dynamic_cast<const IntFieldValue&>(fval));
return std::make_unique<IntegerValue>(val.getAsInt(), false);
}
- case document::ByteFieldValue::classId:
+ case FieldValue::Type::BYTE:
{
const auto& val(dynamic_cast<const ByteFieldValue&>(fval));
return std::make_unique<IntegerValue>(val.getAsByte(), false);
}
- case LongFieldValue::classId:
+ case FieldValue::Type::LONG:
{
const auto& val(dynamic_cast<const LongFieldValue&>(fval));
return std::make_unique<IntegerValue>(val.getAsLong(), false);
}
- case FloatFieldValue::classId:
+ case FieldValue::Type::FLOAT:
{
const auto& val(dynamic_cast<const FloatFieldValue&>(fval));
return std::make_unique<FloatValue>(val.getAsFloat());
}
- case DoubleFieldValue::classId:
+ case FieldValue::Type::DOUBLE:
{
const auto& val(dynamic_cast<const DoubleFieldValue&>(fval));
return std::make_unique<FloatValue>(val.getAsDouble());
}
- case StringFieldValue::classId:
+ case FieldValue::Type::STRING:
{
const auto& val(dynamic_cast<const StringFieldValue&>(fval));
return std::make_unique<StringValue>(val.getAsString());
}
- case ReferenceFieldValue::classId:
+ case FieldValue::Type::REFERENCE:
{
const auto& val(dynamic_cast<const ReferenceFieldValue&>(fval));
if (val.hasValidDocumentId()) {
@@ -317,7 +316,7 @@ IteratorHandler::getInternalValue(const FieldValue& fval) const
return std::make_unique<InvalidValue>();
}
}
- case ArrayFieldValue::classId:
+ case FieldValue::Type::ARRAY:
{
const auto& val(dynamic_cast<const ArrayFieldValue&>(fval));
if (val.size() == 0) {
@@ -328,7 +327,7 @@ IteratorHandler::getInternalValue(const FieldValue& fval) const
return std::make_unique<ArrayValue>(values);
}
}
- case StructFieldValue::classId:
+ case FieldValue::Type::STRUCT:
{
const auto& val(dynamic_cast<const StructFieldValue&>(fval));
if (val.empty()) {
@@ -342,7 +341,7 @@ IteratorHandler::getInternalValue(const FieldValue& fval) const
return std::make_unique<StructValue>(values);
}
}
- case MapFieldValue::classId:
+ case FieldValue::Type::MAP:
{
const auto& val(static_cast<const MapFieldValue&>(fval));
if (val.isEmpty()) {
@@ -353,6 +352,8 @@ IteratorHandler::getInternalValue(const FieldValue& fval) const
return std::make_unique<ArrayValue>(values);
}
}
+ default:
+ break;
}
LOG(warning, "Tried to use unsupported datatype %s in field comparison",
fval.getDataType()->toString().c_str());
diff --git a/document/src/vespa/document/serialization/annotationdeserializer.cpp b/document/src/vespa/document/serialization/annotationdeserializer.cpp
index e3192459574..9e7a35cfdcb 100644
--- a/document/src/vespa/document/serialization/annotationdeserializer.cpp
+++ b/document/src/vespa/document/serialization/annotationdeserializer.cpp
@@ -119,9 +119,10 @@ void AnnotationDeserializer::readAnnotation(Annotation & annotation) {
if (features & 2) { // has value
uint32_t data_type_id = readValue<uint32_t>(_stream);
- const DataType *data_type = _repo.getDataType(data_type_id);
+ const DataType *data_type = type->getDataType();
if (!data_type) {
- LOG(warning, "Unknown data type %d", data_type_id);
+ LOG(warning, "Skipping payload (data type %d) for annotation type %s",
+ data_type_id, type->getName().c_str());
_stream.adjustReadPos(size - sizeof(uint32_t));
} else {
FieldValue::UP value(data_type->createFieldValue());
diff --git a/document/src/vespa/document/serialization/vespadocumentdeserializer.cpp b/document/src/vespa/document/serialization/vespadocumentdeserializer.cpp
index 747dfbbcee6..55ea4988fc4 100644
--- a/document/src/vespa/document/serialization/vespadocumentdeserializer.cpp
+++ b/document/src/vespa/document/serialization/vespadocumentdeserializer.cpp
@@ -447,8 +447,6 @@ VespaDocumentDeserializer::read(ReferenceFieldValue& value) {
DocumentId id;
read(id);
value.setDeserializedDocumentId(id);
- } else {
- value.clearChanged();
}
}
diff --git a/document/src/vespa/document/update/addfieldpathupdate.cpp b/document/src/vespa/document/update/addfieldpathupdate.cpp
index 227ac34d78b..bd06451759e 100644
--- a/document/src/vespa/document/update/addfieldpathupdate.cpp
+++ b/document/src/vespa/document/update/addfieldpathupdate.cpp
@@ -31,7 +31,7 @@ AddFieldPathUpdate::AddFieldPathUpdate()
: FieldPathUpdate(), _values()
{ }
-AddFieldPathUpdate::~AddFieldPathUpdate() { }
+AddFieldPathUpdate::~AddFieldPathUpdate() = default;
FieldPathUpdate*
AddFieldPathUpdate::clone() const {
@@ -53,13 +53,13 @@ private:
ModificationStatus
AddIteratorHandler::doModify(FieldValue &fv) {
- if (fv.inherits(CollectionFieldValue::classId)) {
+ if (fv.isCollection()) {
CollectionFieldValue &cf = static_cast<CollectionFieldValue &>(fv);
for (std::size_t i = 0; i < _values.size(); ++i) {
cf.add(_values[i]);
}
} else {
- vespalib::string err = make_string("Unable to add a value to a \"%s\" field value.", fv.getClass().name());
+ vespalib::string err = make_string("Unable to add a value to a \"%s\" field value.", fv.className());
throw vespalib::IllegalArgumentException(err, VESPA_STRLOC);
}
return ModificationStatus::MODIFIED;
diff --git a/document/src/vespa/document/update/addvalueupdate.cpp b/document/src/vespa/document/update/addvalueupdate.cpp
index e12afd8fa63..6f6c9a93738 100644
--- a/document/src/vespa/document/update/addvalueupdate.cpp
+++ b/document/src/vespa/document/update/addvalueupdate.cpp
@@ -63,14 +63,14 @@ AddValueUpdate::print(std::ostream& out, bool, const std::string& indent) const
bool
AddValueUpdate::applyTo(FieldValue& value) const
{
- if (value.inherits(ArrayFieldValue::classId)) {
+ if (value.isA(FieldValue::Type::ARRAY)) {
ArrayFieldValue& doc(static_cast<ArrayFieldValue&>(value));
doc.add(*_value);
- } else if (value.inherits(WeightedSetFieldValue::classId)) {
+ } else if (value.isA(FieldValue::Type::WSET)) {
WeightedSetFieldValue& doc(static_cast<WeightedSetFieldValue&>(value));
doc.add(*_value, _weight);
} else {
- std::string err = make_string("Unable to add a value to a \"%s\" field value.", value.getClass().name());
+ vespalib::string err = make_string("Unable to add a value to a \"%s\" field value.", value.className());
throw IllegalStateException(err, VESPA_STRLOC);
}
return true;
diff --git a/document/src/vespa/document/update/arithmeticvalueupdate.cpp b/document/src/vespa/document/update/arithmeticvalueupdate.cpp
index b33312d8e65..e5fb5aee8af 100644
--- a/document/src/vespa/document/update/arithmeticvalueupdate.cpp
+++ b/document/src/vespa/document/update/arithmeticvalueupdate.cpp
@@ -2,7 +2,6 @@
#include "arithmeticvalueupdate.h"
#include <vespa/document/base/field.h>
#include <vespa/document/fieldvalue/fieldvalues.h>
-#include <vespa/vespalib/objects/nbostream.h>
#include <vespa/vespalib/util/exceptions.h>
#include <vespa/vespalib/util/xmlstream.h>
#include <ostream>
@@ -44,25 +43,25 @@ ArithmeticValueUpdate::checkCompatibility(const Field& field) const
bool
ArithmeticValueUpdate::applyTo(FieldValue& value) const
{
- if (value.inherits(ByteFieldValue::classId)) {
+ if (value.isA(FieldValue::Type::BYTE)) {
ByteFieldValue& bValue = static_cast<ByteFieldValue&>(value);
bValue.setValue((int)applyTo(static_cast<int64_t>(bValue.getAsInt())));
- } else if (value.inherits(DoubleFieldValue::classId)) {
+ } else if (value.isA(FieldValue::Type::DOUBLE)) {
DoubleFieldValue& dValue = static_cast<DoubleFieldValue&>(value);
dValue.setValue(applyTo(dValue.getAsDouble()));
- } else if (value.inherits(FloatFieldValue::classId)) {
+ } else if (value.isA(FieldValue::Type::FLOAT)) {
FloatFieldValue& fValue = static_cast<FloatFieldValue&>(value);
fValue.setValue((float)applyTo(fValue.getAsFloat()));
- } else if (value.inherits(IntFieldValue::classId)) {
+ } else if (value.isA(FieldValue::Type::INT)) {
IntFieldValue& iValue = static_cast<IntFieldValue&>(value);
iValue.setValue((int)applyTo(static_cast<int64_t>(iValue.getAsInt())));
- } else if (value.inherits(LongFieldValue::classId)) {
+ } else if (value.isA(FieldValue::Type::LONG)) {
LongFieldValue& lValue = static_cast<LongFieldValue&>(value);
lValue.setValue(applyTo(lValue.getAsLong()));
} else {
- std::string err = vespalib::make_string(
+ vespalib::string err = vespalib::make_string(
"Unable to perform an arithmetic update on a \"%s\" field "
- "value.", value.getClass().name());
+ "value.", value.className());
throw IllegalStateException(err, VESPA_STRLOC);
}
return true;
diff --git a/document/src/vespa/document/update/assignfieldpathupdate.cpp b/document/src/vespa/document/update/assignfieldpathupdate.cpp
index 9fa5f4fa441..d4cbff2aae9 100644
--- a/document/src/vespa/document/update/assignfieldpathupdate.cpp
+++ b/document/src/vespa/document/update/assignfieldpathupdate.cpp
@@ -3,7 +3,6 @@
#include "assignfieldpathupdate.h"
#include <vespa/document/fieldvalue/fieldvalues.h>
#include <vespa/document/fieldvalue/iteratorhandler.h>
-#include <vespa/document/select/parser.h>
#include <vespa/document/select/variablemap.h>
#include <vespa/document/serialization/vespadocumentdeserializer.h>
#include <vespa/vespalib/objects/nbostream.h>
@@ -118,12 +117,11 @@ AssignValueIteratorHandler::doModify(FieldValue& fv) {
if (!(*fv.getDataType() == *_newValue.getDataType())) {
vespalib::string err = vespalib::make_string(
"Trying to assign \"%s\" of type %s to an instance of type %s",
- _newValue.toString().c_str(), _newValue.getClass().name(),
- fv.getClass().name());
+ _newValue.toString().c_str(), _newValue.className(), fv.className());
throw vespalib::IllegalArgumentException(err, VESPA_STRLOC);
}
if (_removeIfZero
- && _newValue.inherits(NumericFieldValueBase::classId)
+ && _newValue.isNumeric()
&& static_cast<const NumericFieldValueBase&>(_newValue).getAsLong() == 0)
{
return ModificationStatus::REMOVED;
@@ -135,13 +133,13 @@ AssignValueIteratorHandler::doModify(FieldValue& fv) {
ModificationStatus
AssignExpressionIteratorHandler::doModify(FieldValue& fv) {
LOG(spam, "fv = %s", fv.toString().c_str());
- if (fv.inherits(NumericFieldValueBase::classId)) {
+ if (fv.isNumeric()) {
std::unique_ptr<select::VariableMap> varHolder = std::make_unique<select::VariableMap>();
select::VariableMap & vars = *varHolder;
for (VariableMap::const_iterator i(getVariables().begin()),
e(getVariables().end()); i != e; ++i)
{
- if (i->second.key.get() && i->second.key->inherits(NumericFieldValueBase::classId)) {
+ if (i->second.key.get() && i->second.key->isNumeric()) {
vars[i->first] = i->second.key->getAsDouble();
} else {
vars[i->first] = i->second.index;
diff --git a/document/src/vespa/document/update/assignvalueupdate.cpp b/document/src/vespa/document/update/assignvalueupdate.cpp
index d6eb0b501d3..cf2321dbf56 100644
--- a/document/src/vespa/document/update/assignvalueupdate.cpp
+++ b/document/src/vespa/document/update/assignvalueupdate.cpp
@@ -71,7 +71,7 @@ AssignValueUpdate::applyTo(FieldValue& value) const
!value.getDataType()->isValueType(*_value))) {
vespalib::string err = vespalib::make_string(
"Unable to assign a \"%s\" value to a \"%s\" field value.",
- _value->getClass().name(), value.getClass().name());
+ _value->className(), value.className());
throw IllegalStateException(err, VESPA_STRLOC);
}
if (_value) {
diff --git a/document/src/vespa/document/update/documentupdate.h b/document/src/vespa/document/update/documentupdate.h
index 69f22237c8f..c7ebe913d79 100644
--- a/document/src/vespa/document/update/documentupdate.h
+++ b/document/src/vespa/document/update/documentupdate.h
@@ -40,13 +40,14 @@ class VespaDocumentSerializer;
* path updates was added, and a new serialization format was
* introduced while keeping the old one.
*/
-class DocumentUpdate final : public Printable, public XmlSerializable
+class DocumentUpdate final : public Printable, public vespalib::xml::XmlSerializable
{
public:
- typedef std::unique_ptr<DocumentUpdate> UP;
- typedef std::shared_ptr<DocumentUpdate> SP;
- typedef std::vector<FieldUpdate> FieldUpdateV;
- typedef std::vector<FieldPathUpdate::CP> FieldPathUpdateV;
+ using UP = std::unique_ptr<DocumentUpdate>;
+ using SP = std::shared_ptr<DocumentUpdate>;
+ using FieldUpdateV = std::vector<FieldUpdate>;
+ using FieldPathUpdateV = std::vector<FieldPathUpdate::CP>;
+ using XmlOutputStream = vespalib::xml::XmlOutputStream;
/**
* Create new style document update, possibly with field path updates.
diff --git a/document/src/vespa/document/update/fieldpathupdate.h b/document/src/vespa/document/update/fieldpathupdate.h
index 5283f0da455..28faad722d4 100644
--- a/document/src/vespa/document/update/fieldpathupdate.h
+++ b/document/src/vespa/document/update/fieldpathupdate.h
@@ -4,6 +4,7 @@
#include "updatevisitor.h"
#include <vespa/document/base/fieldpath.h>
#include <vespa/document/util/printable.h>
+#include <vespa/document/util/identifiableid.h>
namespace document {
diff --git a/document/src/vespa/document/update/fieldupdate.h b/document/src/vespa/document/update/fieldupdate.h
index 1e4137b9531..e364e5db5fd 100644
--- a/document/src/vespa/document/update/fieldupdate.h
+++ b/document/src/vespa/document/update/fieldupdate.h
@@ -23,7 +23,7 @@ class DocumentType;
class FieldUpdate : public vespalib::Identifiable,
public Printable,
- public XmlSerializable
+ public vespalib::xml::XmlSerializable
{
Field _field;
std::vector<ValueUpdate::CP> _updates;
@@ -31,6 +31,7 @@ class FieldUpdate : public vespalib::Identifiable,
public:
typedef vespalib::CloneablePtr<FieldUpdate> CP;
+ using XmlOutputStream = vespalib::xml::XmlOutputStream;
FieldUpdate(const Field& field);
FieldUpdate(const FieldUpdate &);
diff --git a/document/src/vespa/document/update/mapvalueupdate.cpp b/document/src/vespa/document/update/mapvalueupdate.cpp
index 18f2c013b7f..48e52a9d2cc 100644
--- a/document/src/vespa/document/update/mapvalueupdate.cpp
+++ b/document/src/vespa/document/update/mapvalueupdate.cpp
@@ -44,7 +44,7 @@ MapValueUpdate::checkCompatibility(const Field& field) const
{
// Check compatibility of nested types.
if (field.getDataType().isArray()) {
- if (_key->getClass().id() != IntFieldValue::classId) {
+ if ( !_key->isA(FieldValue::Type::INT)) {
throw IllegalArgumentException(vespalib::make_string(
"Key for field '%s' is of wrong type (expected '%s', was '%s').",
field.getName().data(), DataType::INT->toString().c_str(),
@@ -60,7 +60,7 @@ MapValueUpdate::checkCompatibility(const Field& field) const
}
} else {
throw IllegalArgumentException("MapValueUpdate does not support "
- "datatype " + field.getDataType().toString() + ".", VESPA_STRLOC);
+ "datatype " + field.getDataType().toString() + ".", VESPA_STRLOC);
}
}
diff --git a/document/src/vespa/document/update/removevalueupdate.cpp b/document/src/vespa/document/update/removevalueupdate.cpp
index d35d8db84a2..a61553da4d1 100644
--- a/document/src/vespa/document/update/removevalueupdate.cpp
+++ b/document/src/vespa/document/update/removevalueupdate.cpp
@@ -56,14 +56,14 @@ RemoveValueUpdate::checkCompatibility(const Field& field) const
bool
RemoveValueUpdate::applyTo(FieldValue& value) const
{
- if (value.inherits(ArrayFieldValue::classId)) {
+ if (value.isA(FieldValue::Type::ARRAY)) {
ArrayFieldValue& doc(static_cast<ArrayFieldValue&>(value));
doc.remove(*_key);
- } else if (value.inherits(WeightedSetFieldValue::classId)) {
+ } else if (value.isA(FieldValue::Type::WSET)) {
WeightedSetFieldValue& doc(static_cast<WeightedSetFieldValue&>(value));
doc.remove(*_key);
} else {
- std::string err = vespalib::make_string("Unable to remove a value from a \"%s\" field value.", value.getClass().name());
+ std::string err = vespalib::make_string("Unable to remove a value from a \"%s\" field value.", value.className());
throw IllegalStateException(err, VESPA_STRLOC);
}
return true;
diff --git a/document/src/vespa/document/update/tensor_add_update.cpp b/document/src/vespa/document/update/tensor_add_update.cpp
index 3b442b7b1d5..1f8aed2d8b4 100644
--- a/document/src/vespa/document/update/tensor_add_update.cpp
+++ b/document/src/vespa/document/update/tensor_add_update.cpp
@@ -8,10 +8,8 @@
#include <vespa/document/fieldvalue/document.h>
#include <vespa/document/fieldvalue/tensorfieldvalue.h>
#include <vespa/document/serialization/vespadocumentdeserializer.h>
-#include <vespa/document/util/serializableexceptions.h>
#include <vespa/eval/eval/value.h>
#include <vespa/eval/eval/fast_value.h>
-#include <vespa/vespalib/objects/nbostream.h>
#include <vespa/vespalib/stllike/asciistream.h>
#include <vespa/vespalib/util/stringfmt.h>
#include <vespa/vespalib/util/xmlstream.h>
@@ -99,7 +97,7 @@ TensorAddUpdate::apply_to(const Value &old_tensor,
bool
TensorAddUpdate::applyTo(FieldValue& value) const
{
- if (value.inherits(TensorFieldValue::classId)) {
+ if (value.isA(FieldValue::Type::TENSOR)) {
TensorFieldValue &tensorFieldValue = static_cast<TensorFieldValue &>(value);
tensorFieldValue.make_empty_if_not_existing();
auto oldTensor = tensorFieldValue.getAsTensorPtr();
@@ -110,7 +108,7 @@ TensorAddUpdate::applyTo(FieldValue& value) const
}
} else {
vespalib::string err = make_string("Unable to perform a tensor add update on a '%s' field value",
- value.getClass().name());
+ value.className());
throw IllegalStateException(err, VESPA_STRLOC);
}
return true;
@@ -136,11 +134,11 @@ void
TensorAddUpdate::deserialize(const DocumentTypeRepo &repo, const DataType &type, nbostream & stream)
{
auto tensor = type.createFieldValue();
- if (tensor->inherits(TensorFieldValue::classId)) {
+ if (tensor->isA(FieldValue::Type::TENSOR)) {
_tensor.reset(static_cast<TensorFieldValue *>(tensor.release()));
} else {
vespalib::string err = make_string("Expected tensor field value, got a '%s' field value",
- tensor->getClass().name());
+ tensor->className());
throw IllegalStateException(err, VESPA_STRLOC);
}
VespaDocumentDeserializer deserializer(repo, stream, Document::getNewestSerializationVersion());
diff --git a/document/src/vespa/document/update/tensor_modify_update.cpp b/document/src/vespa/document/update/tensor_modify_update.cpp
index 91ac6f4c754..49ea57f28c1 100644
--- a/document/src/vespa/document/update/tensor_modify_update.cpp
+++ b/document/src/vespa/document/update/tensor_modify_update.cpp
@@ -94,7 +94,7 @@ TensorModifyUpdate::TensorModifyUpdate()
TensorModifyUpdate::TensorModifyUpdate(const TensorModifyUpdate &rhs)
: _operation(rhs._operation),
_tensorType(std::make_unique<TensorDataType>(*rhs._tensorType)),
- _tensor(Identifiable::cast<TensorFieldValue *>(_tensorType->createFieldValue().release()))
+ _tensor(static_cast<TensorFieldValue *>(_tensorType->createFieldValue().release()))
{
*_tensor = *rhs._tensor;
}
@@ -102,7 +102,7 @@ TensorModifyUpdate::TensorModifyUpdate(const TensorModifyUpdate &rhs)
TensorModifyUpdate::TensorModifyUpdate(Operation operation, std::unique_ptr<TensorFieldValue> tensor)
: _operation(operation),
_tensorType(std::make_unique<TensorDataType>(dynamic_cast<const TensorDataType &>(*tensor->getDataType()))),
- _tensor(Identifiable::cast<TensorFieldValue *>(_tensorType->createFieldValue().release()))
+ _tensor(static_cast<TensorFieldValue *>(_tensorType->createFieldValue().release()))
{
*_tensor = *tensor;
}
@@ -116,7 +116,7 @@ TensorModifyUpdate::operator=(const TensorModifyUpdate &rhs)
_operation = rhs._operation;
_tensor.reset();
_tensorType = std::make_unique<TensorDataType>(*rhs._tensorType);
- _tensor.reset(Identifiable::cast<TensorFieldValue *>(_tensorType->createFieldValue().release()));
+ _tensor.reset(dynamic_cast<TensorFieldValue *>(_tensorType->createFieldValue().release()));
*_tensor = *rhs._tensor;
}
return *this;
@@ -177,7 +177,7 @@ TensorModifyUpdate::apply_to(const Value &old_tensor,
bool
TensorModifyUpdate::applyTo(FieldValue& value) const
{
- if (value.inherits(TensorFieldValue::classId)) {
+ if (value.isA(FieldValue::Type::TENSOR)) {
TensorFieldValue &tensorFieldValue = static_cast<TensorFieldValue &>(value);
auto oldTensor = tensorFieldValue.getAsTensorPtr();
if (oldTensor) {
@@ -188,7 +188,7 @@ TensorModifyUpdate::applyTo(FieldValue& value) const
}
} else {
vespalib::string err = make_string("Unable to perform a tensor modify update on a '%s' field value",
- value.getClass().name());
+ value.className());
throw IllegalStateException(err, VESPA_STRLOC);
}
return true;
@@ -241,11 +241,11 @@ TensorModifyUpdate::deserialize(const DocumentTypeRepo &repo, const DataType &ty
_operation = static_cast<Operation>(op);
_tensorType = convertToCompatibleType(dynamic_cast<const TensorDataType &>(type));
auto tensor = _tensorType->createFieldValue();
- if (tensor->inherits(TensorFieldValue::classId)) {
+ if (tensor->isA(FieldValue::Type::TENSOR)) {
_tensor.reset(static_cast<TensorFieldValue *>(tensor.release()));
} else {
vespalib::string err = make_string("Expected tensor field value, got a '%s' field value",
- tensor->getClass().name());
+ tensor->className());
throw IllegalStateException(err, VESPA_STRLOC);
}
VespaDocumentDeserializer deserializer(repo, stream, Document::getNewestSerializationVersion());
diff --git a/document/src/vespa/document/update/tensor_remove_update.cpp b/document/src/vespa/document/update/tensor_remove_update.cpp
index f4dc9490b62..f2d11ef8234 100644
--- a/document/src/vespa/document/update/tensor_remove_update.cpp
+++ b/document/src/vespa/document/update/tensor_remove_update.cpp
@@ -54,7 +54,7 @@ TensorRemoveUpdate::TensorRemoveUpdate(const TensorRemoveUpdate &rhs)
TensorRemoveUpdate::TensorRemoveUpdate(std::unique_ptr<TensorFieldValue> tensor)
: _tensorType(std::make_unique<TensorDataType>(dynamic_cast<const TensorDataType &>(*tensor->getDataType()))),
- _tensor(Identifiable::cast<TensorFieldValue *>(_tensorType->createFieldValue().release()))
+ _tensor(static_cast<TensorFieldValue *>(_tensorType->createFieldValue().release()))
{
*_tensor = *tensor;
}
@@ -67,7 +67,7 @@ TensorRemoveUpdate::operator=(const TensorRemoveUpdate &rhs)
if (&rhs != this) {
_tensor.reset();
_tensorType = std::make_unique<TensorDataType>(*rhs._tensorType);
- _tensor.reset(Identifiable::cast<TensorFieldValue *>(_tensorType->createFieldValue().release()));
+ _tensor.reset(static_cast<TensorFieldValue *>(_tensorType->createFieldValue().release()));
*_tensor = *rhs._tensor;
}
return *this;
@@ -122,7 +122,7 @@ TensorRemoveUpdate::apply_to(const Value &old_tensor,
bool
TensorRemoveUpdate::applyTo(FieldValue &value) const
{
- if (value.inherits(TensorFieldValue::classId)) {
+ if (value.isA(FieldValue::Type::TENSOR)) {
TensorFieldValue &tensorFieldValue = static_cast<TensorFieldValue &>(value);
auto oldTensor = tensorFieldValue.getAsTensorPtr();
if (oldTensor) {
@@ -133,7 +133,7 @@ TensorRemoveUpdate::applyTo(FieldValue &value) const
}
} else {
vespalib::string err = make_string("Unable to perform a tensor remove update on a '%s' field value",
- value.getClass().name());
+ value.className());
throw IllegalStateException(err, VESPA_STRLOC);
}
return true;
diff --git a/document/src/vespa/document/update/valueupdate.h b/document/src/vespa/document/update/valueupdate.h
index 9a8ed4e9537..ec903c1adc1 100644
--- a/document/src/vespa/document/update/valueupdate.h
+++ b/document/src/vespa/document/update/valueupdate.h
@@ -20,9 +20,9 @@
#include "updatevisitor.h"
#include <vespa/document/util/printable.h>
-#include <vespa/document/util/xmlserializable.h>
#include <vespa/document/util/identifiableid.h>
#include <vespa/vespalib/objects/nbostream.h>
+#include <vespa/vespalib/util/xmlserializable.h>
namespace document {
@@ -33,12 +33,13 @@ class DataType;
class ValueUpdate : public vespalib::Identifiable,
public Printable,
- public XmlSerializable
+ public vespalib::xml::XmlSerializable
{
protected:
using nbostream = vespalib::nbostream;
public:
using CP = vespalib::CloneablePtr<ValueUpdate>;
+ using XmlOutputStream = vespalib::xml::XmlOutputStream;
/**
* Create a value update object from the given stream.
diff --git a/document/src/vespa/document/util/feed_reject_helper.cpp b/document/src/vespa/document/util/feed_reject_helper.cpp
index f23524eddfb..a6829ec0c60 100644
--- a/document/src/vespa/document/util/feed_reject_helper.cpp
+++ b/document/src/vespa/document/util/feed_reject_helper.cpp
@@ -4,14 +4,12 @@
#include <vespa/document/update/documentupdate.h>
#include <vespa/document/update/assignvalueupdate.h>
#include <vespa/document/fieldvalue/boolfieldvalue.h>
-#include <vespa/document/fieldvalue/numericfieldvalue.h>
-
namespace document {
bool
FeedRejectHelper::isFixedSizeSingleValue(const document::FieldValue & fv) {
- return fv.inherits(BoolFieldValue::classId) || fv.inherits(NumericFieldValueBase::classId);
+ return fv.isFixedSizeSingleValue();
}
bool
diff --git a/document/src/vespa/document/util/xmlserializable.h b/document/src/vespa/document/util/xmlserializable.h
deleted file mode 100644
index f4a5db0de58..00000000000
--- a/document/src/vespa/document/util/xmlserializable.h
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#pragma once
-
-#include <vespa/vespalib/util/xmlserializable.h>
-
-namespace document {
- using XmlSerializable = vespalib::xml::XmlSerializable;
- using XmlOutputStream = vespalib::xml::XmlOutputStream;
-}
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
index fb75fcd8c81..88d21f69f7a 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
@@ -370,7 +370,7 @@ public class Flags {
ZONE_ID, APPLICATION_ID);
public static final UnboundBooleanFlag REUSE_NODE_INDEXES = defineFeatureFlag(
- "reuse-node-indexes", false,
+ "reuse-node-indexes", true,
List.of("bratseth"), "2022-02-25", "2022-04-25",
"Whether we should reuse earlier indexes when allocating new nodes",
"Takes effect immediately",
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java b/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java
index e3960d995e9..bc199f7160e 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java
@@ -260,7 +260,7 @@ public class PermanentFlags {
"Architecture to use for node resources. Used when implicitly creating admin clusters " +
"(logserver, clustercontroller). Valid values: x86_64, arm64",
"Takes effect on next redeployment",
- ZONE_ID, APPLICATION_ID, CLUSTER_ID, CLUSTER_TYPE);
+ ZONE_ID, APPLICATION_ID);
private PermanentFlags() {}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java
index 30432c1c078..43a78e3a315 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocationOptimizer.java
@@ -47,7 +47,7 @@ public class AllocationOptimizer {
limits = Limits.of(new ClusterResources(minimumNodes, 1, NodeResources.unspecified()),
new ClusterResources(maximumNodes, maximumNodes, NodeResources.unspecified()));
else
- limits = atLeast(minimumNodes, limits).fullySpecified(current.clusterSpec().type(), nodeRepository);
+ limits = atLeast(minimumNodes, limits).fullySpecified(current.clusterSpec().type(), nodeRepository, clusterModel.application().id());
Optional<AllocatableClusterResources> bestAllocation = Optional.empty();
NodeList hosts = nodeRepository.nodes().list().hosts();
for (int groups = limits.min().groups(); groups <= limits.max().groups(); groups++) {
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Limits.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Limits.java
index 3c9cbfe2620..ef45592ad18 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Limits.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Limits.java
@@ -1,6 +1,7 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.provision.autoscale;
+import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterResources;
import com.yahoo.config.provision.ClusterSpec;
@@ -59,10 +60,10 @@ public class Limits {
return resources;
}
- public Limits fullySpecified(ClusterSpec.Type type, NodeRepository nodeRepository) {
+ public Limits fullySpecified(ClusterSpec.Type type, NodeRepository nodeRepository, ApplicationId applicationId) {
if (this.isEmpty()) throw new IllegalStateException("Unspecified limits can not be made fully specified");
- var defaultResources = new CapacityPolicies(nodeRepository).defaultNodeResources(type);
+ var defaultResources = new CapacityPolicies(nodeRepository).defaultNodeResources(type, applicationId);
var specifiedMin = min.nodeResources().isUnspecified() ? min.with(defaultResources) : min;
var specifiedMax = max.nodeResources().isUnspecified() ? max.with(defaultResources) : max;
return new Limits(specifiedMin, specifiedMax);
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/PassthroughLoadBalancerService.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/PassthroughLoadBalancerService.java
deleted file mode 100644
index 23ddce3ba9e..00000000000
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/PassthroughLoadBalancerService.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.provision.lb;
-
-import com.yahoo.config.provision.ApplicationId;
-import com.yahoo.config.provision.ClusterSpec;
-import com.yahoo.config.provision.NodeType;
-
-import java.util.Comparator;
-import java.util.Optional;
-import java.util.Set;
-
-/**
- * Implementation of a load balancer service that returns a real as the load balancer instance. This is intended for
- * development purposes.
- *
- * @author mpolden
- */
-public class PassthroughLoadBalancerService implements LoadBalancerService {
-
- @Override
- public LoadBalancerInstance create(LoadBalancerSpec spec, boolean force) {
- var real = spec.reals().stream()
- .min(Comparator.naturalOrder())
- .orElseThrow(() -> new IllegalArgumentException("No reals given"));
- return new LoadBalancerInstance(real.hostname(), Optional.empty(), Set.of(real.port()),
- Set.of(real.ipAddress() + "/32"), Set.of());
- }
-
- @Override
- public void remove(ApplicationId application, ClusterSpec.Id cluster) {
- // Nothing to remove
- }
-
- @Override
- public Protocol protocol() {
- return Protocol.ipv4;
- }
-
- @Override
- public boolean supports(NodeType nodeType, ClusterSpec.Type clusterType) {
- return true;
- }
-
-}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerService.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerService.java
index 7dbebd1fc47..1345dfb8e65 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerService.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerService.java
@@ -5,16 +5,10 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.NodeType;
-import com.yahoo.vespa.hosted.provision.Node;
-import com.yahoo.vespa.hosted.provision.NodeList;
-import com.yahoo.vespa.hosted.provision.NodeRepository;
-import com.yahoo.vespa.hosted.provision.node.IP;
-import java.util.Comparator;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
-import java.util.stream.Collectors;
/**
* This implementation of {@link LoadBalancerService} returns the load balancer(s) that exists by default in the shared
@@ -27,28 +21,18 @@ import java.util.stream.Collectors;
*/
public class SharedLoadBalancerService implements LoadBalancerService {
- private static final Comparator<Node> hostnameComparator = Comparator.comparing(Node::hostname);
-
- private final NodeRepository nodeRepository;
private final String vipHostname;
- public SharedLoadBalancerService(NodeRepository nodeRepository, String vipHostname) {
- this.nodeRepository = Objects.requireNonNull(nodeRepository);
+ public SharedLoadBalancerService(String vipHostname) {
this.vipHostname = Objects.requireNonNull(vipHostname);
}
@Override
public LoadBalancerInstance create(LoadBalancerSpec spec, boolean force) {
- NodeList proxyNodes = nodeRepository.nodes().list().nodeType(NodeType.proxy).sortedBy(hostnameComparator);
- if (proxyNodes.isEmpty()) throw new IllegalStateException("No proxy nodes found in node-repository");
- Set<String> networks = proxyNodes.stream()
- .flatMap(node -> node.ipConfig().primary().stream())
- .map(SharedLoadBalancerService::withPrefixLength)
- .collect(Collectors.toSet());
return new LoadBalancerInstance(HostName.from(vipHostname),
Optional.empty(),
- Set.of(4080, 4443),
- networks,
+ Set.of(4443),
+ Set.of(),
spec.reals());
}
@@ -68,11 +52,4 @@ public class SharedLoadBalancerService implements LoadBalancerService {
return nodeType == NodeType.tenant && clusterType.isContainer();
}
- private static String withPrefixLength(String address) {
- if (IP.isV6(address)) {
- return address + "/128";
- }
- return address + "/32";
- }
-
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java
index 15decde0d7c..2d36108a1a6 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java
@@ -66,7 +66,7 @@ public class NodeRepositoryMaintenance extends AbstractComponent {
maintainers.add(new ScalingSuggestionsMaintainer(nodeRepository, defaults.scalingSuggestionsInterval, metric));
maintainers.add(new SwitchRebalancer(nodeRepository, defaults.switchRebalancerInterval, metric, deployer));
- provisionServiceProvider.getLoadBalancerService(nodeRepository)
+ provisionServiceProvider.getLoadBalancerService()
.map(lbService -> new LoadBalancerExpirer(nodeRepository, defaults.loadBalancerExpirerInterval, lbService, metric))
.ifPresent(maintainers::add);
provisionServiceProvider.getHostProvisioner()
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java
index 45e9efc1a1d..f7d5b966c12 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java
@@ -8,12 +8,15 @@ import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.Zone;
+import com.yahoo.vespa.flags.FlagSource;
import com.yahoo.vespa.flags.PermanentFlags;
import com.yahoo.vespa.hosted.provision.NodeRepository;
import java.util.function.Function;
import static com.yahoo.config.provision.NodeResources.Architecture;
+import static com.yahoo.vespa.flags.FetchVector.Dimension.APPLICATION_ID;
+import static com.yahoo.vespa.flags.PermanentFlags.ADMIN_CLUSTER_NODE_ARCHITECTURE;
/**
* Defines the policies for assigning cluster capacity in various environments
@@ -25,12 +28,12 @@ public class CapacityPolicies {
private final Zone zone;
private final Function<ClusterSpec.Type, Boolean> sharedHosts;
- private final Architecture architectureForAdminCluster;
+ private final FlagSource flagSource;
public CapacityPolicies(NodeRepository nodeRepository) {
this.zone = nodeRepository.zone();
this.sharedHosts = type -> PermanentFlags.SHARED_HOST.bindTo(nodeRepository.flagSource()).value().isEnabled(type.name());
- this.architectureForAdminCluster = Architecture.valueOf(PermanentFlags.ADMIN_CLUSTER_NODE_ARCHITECTURE.bindTo(nodeRepository.flagSource()).value());
+ this.flagSource = nodeRepository.flagSource();
}
public Capacity applyOn(Capacity capacity, ApplicationId application) {
@@ -73,11 +76,16 @@ public class CapacityPolicies {
return target;
}
- public NodeResources defaultNodeResources(ClusterSpec.Type clusterType) {
+ public NodeResources defaultNodeResources(ClusterSpec.Type clusterType, ApplicationId applicationId) {
if (clusterType == ClusterSpec.Type.admin) {
+ Architecture architecture = Architecture.valueOf(
+ ADMIN_CLUSTER_NODE_ARCHITECTURE.bindTo(flagSource)
+ .with(APPLICATION_ID, applicationId.serializedForm())
+ .value());
+
return zone.getCloud().dynamicProvisioning() && ! sharedHosts.apply(clusterType) ?
- new NodeResources(0.5, 4, 50, 0.3).with(architectureForAdminCluster) :
- new NodeResources(0.5, 2, 50, 0.3).with(architectureForAdminCluster);
+ new NodeResources(0.5, 4, 50, 0.3).with(architecture) :
+ new NodeResources(0.5, 2, 50, 0.3).with(architecture);
}
return zone.getCloud().dynamicProvisioning() ?
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/EmptyProvisionServiceProvider.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/EmptyProvisionServiceProvider.java
index 9a7fa672cfc..e7332f6474d 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/EmptyProvisionServiceProvider.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/EmptyProvisionServiceProvider.java
@@ -18,7 +18,7 @@ public class EmptyProvisionServiceProvider implements ProvisionServiceProvider {
private final HostResourcesCalculator hostResourcesCalculator = new IdentityHostResourcesCalculator();
@Override
- public Optional<LoadBalancerService> getLoadBalancerService(NodeRepository nodeRepository) {
+ public Optional<LoadBalancerService> getLoadBalancerService() {
return Optional.empty();
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java
index 97fe14caef6..e24d71f22f2 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java
@@ -70,7 +70,7 @@ public class NodeRepositoryProvisioner implements Provisioner {
this.allocationOptimizer = new AllocationOptimizer(nodeRepository);
this.capacityPolicies = new CapacityPolicies(nodeRepository);
this.zone = zone;
- this.loadBalancerProvisioner = provisionServiceProvider.getLoadBalancerService(nodeRepository)
+ this.loadBalancerProvisioner = provisionServiceProvider.getLoadBalancerService()
.map(lbService -> new LoadBalancerProvisioner(nodeRepository, lbService));
this.nodeResourceLimits = new NodeResourceLimits(nodeRepository);
this.preparer = new Preparer(nodeRepository,
@@ -106,14 +106,12 @@ public class NodeRepositoryProvisioner implements Provisioner {
logIfDownscaled(requested.minResources().nodes(), actual.minResources().nodes(), cluster, logger);
groups = target.groups();
- resources = target.nodeResources().isUnspecified() ? capacityPolicies.defaultNodeResources(cluster.type())
- : target.nodeResources();
+ resources = getNodeResources(cluster, target.nodeResources(), application);
nodeSpec = NodeSpec.from(target.nodes(), resources, exclusive, actual.canFail());
}
else {
groups = 1; // type request with multiple groups is not supported
- resources = requested.minResources().nodeResources().isUnspecified() ? capacityPolicies.defaultNodeResources(cluster.type())
- : requested.minResources().nodeResources();
+ resources = getNodeResources(cluster, requested.minResources().nodeResources(), application);
nodeSpec = NodeSpec.from(requested.type());
}
var reuseIndexes = Flags.REUSE_NODE_INDEXES.bindTo(nodeRepository.flagSource())
@@ -122,6 +120,12 @@ public class NodeRepositoryProvisioner implements Provisioner {
return asSortedHosts(preparer.prepare(application, cluster, nodeSpec, groups, reuseIndexes), resources);
}
+ private NodeResources getNodeResources(ClusterSpec cluster, NodeResources nodeResources, ApplicationId applicationId) {
+ return nodeResources.isUnspecified()
+ ? capacityPolicies.defaultNodeResources(cluster.type(), applicationId)
+ : nodeResources;
+ }
+
@Override
public void activate(Collection<HostSpec> hosts, ActivationContext context, ApplicationTransaction transaction) {
validate(hosts);
@@ -170,16 +174,16 @@ public class NodeRepositoryProvisioner implements Provisioner {
boolean firstDeployment = nodes.isEmpty();
AllocatableClusterResources currentResources =
firstDeployment // start at min, preserve current resources otherwise
- ? new AllocatableClusterResources(initialResourcesFrom(requested, clusterSpec), clusterSpec, nodeRepository)
+ ? new AllocatableClusterResources(initialResourcesFrom(requested, clusterSpec, application.id()), clusterSpec, nodeRepository)
: new AllocatableClusterResources(nodes.asList(), nodeRepository);
var clusterModel = new ClusterModel(application, cluster, clusterSpec, nodes, nodeRepository.metricsDb(), nodeRepository.clock());
return within(Limits.of(requested), currentResources, firstDeployment, clusterModel);
}
- private ClusterResources initialResourcesFrom(Capacity requested, ClusterSpec clusterSpec) {
+ private ClusterResources initialResourcesFrom(Capacity requested, ClusterSpec clusterSpec, ApplicationId applicationId) {
var initial = requested.minResources();
if (initial.nodeResources().isUnspecified())
- initial = initial.with(capacityPolicies.defaultNodeResources(clusterSpec.type()));
+ initial = initial.with(capacityPolicies.defaultNodeResources(clusterSpec.type(), applicationId));
return initial;
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisionServiceProvider.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisionServiceProvider.java
index c5835ec525a..6e301b7724c 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisionServiceProvider.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisionServiceProvider.java
@@ -1,7 +1,6 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.provision.provisioning;
-import com.yahoo.vespa.hosted.provision.NodeRepository;
import com.yahoo.vespa.hosted.provision.lb.LoadBalancerService;
import java.util.Optional;
@@ -13,7 +12,7 @@ import java.util.Optional;
*/
public interface ProvisionServiceProvider {
- Optional<LoadBalancerService> getLoadBalancerService(NodeRepository nodeRepository);
+ Optional<LoadBalancerService> getLoadBalancerService();
Optional<HostProvisioner> getHostProvisioner();
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockProvisionServiceProvider.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockProvisionServiceProvider.java
index 9f6143e5daa..d72c5959082 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockProvisionServiceProvider.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockProvisionServiceProvider.java
@@ -2,7 +2,6 @@
package com.yahoo.vespa.hosted.provision.testutils;
import com.google.inject.Inject;
-import com.yahoo.vespa.hosted.provision.NodeRepository;
import com.yahoo.vespa.hosted.provision.lb.LoadBalancerService;
import com.yahoo.vespa.hosted.provision.lb.LoadBalancerServiceMock;
import com.yahoo.vespa.hosted.provision.provisioning.EmptyProvisionServiceProvider;
@@ -38,7 +37,7 @@ public class MockProvisionServiceProvider implements ProvisionServiceProvider {
}
@Override
- public Optional<LoadBalancerService> getLoadBalancerService(NodeRepository nodeRepository) {
+ public Optional<LoadBalancerService> getLoadBalancerService() {
return loadBalancerService;
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java
index a04a3828f13..40e38d752ff 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java
@@ -15,7 +15,6 @@ import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.Zone;
-import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeRepository;
import com.yahoo.vespa.hosted.provision.Nodelike;
import com.yahoo.vespa.hosted.provision.provisioning.CapacityPolicies;
@@ -240,7 +239,7 @@ public class AutoscalingTest {
ClusterSpec cluster1 = tester.clusterSpec(ClusterSpec.Type.container, "cluster1");
NodeResources defaultResources =
- new CapacityPolicies(tester.nodeRepository()).defaultNodeResources(cluster1.type());
+ new CapacityPolicies(tester.nodeRepository()).defaultNodeResources(cluster1.type(), application1);
// deploy
tester.deploy(application1, cluster1, Capacity.from(min, max));
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/PassthroughLoadBalancerServiceTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/PassthroughLoadBalancerServiceTest.java
deleted file mode 100644
index 5fcc2afb85d..00000000000
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/PassthroughLoadBalancerServiceTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.provision.lb;
-
-import com.yahoo.config.provision.ApplicationId;
-import com.yahoo.config.provision.ClusterSpec;
-import com.yahoo.config.provision.HostName;
-import org.junit.Test;
-
-import java.util.Set;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * @author mpolden
- */
-public class PassthroughLoadBalancerServiceTest {
-
- @Test
- public void create() {
- var lbService = new PassthroughLoadBalancerService();
- var real = new Real(HostName.from("host1.example.com"), "192.0.2.10");
- var reals = Set.of(real, new Real(HostName.from("host2.example.com"), "192.0.2.11"));
- var instance = lbService.create(new LoadBalancerSpec(ApplicationId.from("tenant1", "app1", "default"),
- ClusterSpec.Id.from("c1"), reals), false);
- assertEquals(real.hostname(), instance.hostname());
- assertEquals(Set.of(real.port()), instance.ports());
- assertEquals(Set.of(real.ipAddress() + "/32"), instance.networks());
- }
-
-}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerServiceTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerServiceTest.java
index 28b40bb7642..4975e670e86 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerServiceTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/lb/SharedLoadBalancerServiceTest.java
@@ -4,8 +4,6 @@ package com.yahoo.vespa.hosted.provision.lb;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.HostName;
-import com.yahoo.config.provision.NodeType;
-import com.yahoo.vespa.hosted.provision.provisioning.ProvisioningTester;
import org.junit.Test;
import java.util.Optional;
@@ -18,8 +16,7 @@ import static org.junit.Assert.assertEquals;
*/
public class SharedLoadBalancerServiceTest {
- private final ProvisioningTester tester = new ProvisioningTester.Builder().build();
- private final SharedLoadBalancerService loadBalancerService = new SharedLoadBalancerService(tester.nodeRepository(), "vip.example.com");
+ private final SharedLoadBalancerService loadBalancerService = new SharedLoadBalancerService("vip.example.com");
private final ApplicationId applicationId = ApplicationId.from("tenant1", "application1", "default");
private final ClusterSpec.Id clusterId = ClusterSpec.Id.from("qrs1");
private final Set<Real> reals = Set.of(
@@ -29,18 +26,12 @@ public class SharedLoadBalancerServiceTest {
@Test
public void test_create_lb() {
- tester.makeReadyNodes(2, "default", NodeType.proxy);
var lb = loadBalancerService.create(new LoadBalancerSpec(applicationId, clusterId, reals), false);
assertEquals(HostName.from("vip.example.com"), lb.hostname());
assertEquals(Optional.empty(), lb.dnsZone());
- assertEquals(Set.of("127.0.0.1/32", "127.0.0.2/32", "::1/128", "::2/128"), lb.networks());
- assertEquals(Set.of(4080, 4443), lb.ports());
- }
-
- @Test(expected = IllegalStateException.class)
- public void test_exception_on_missing_proxies() {
- loadBalancerService.create(new LoadBalancerSpec(applicationId, clusterId, reals), false);
+ assertEquals(Set.of(), lb.networks());
+ assertEquals(Set.of(4443), lb.ports());
}
@Test
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/document_field_extractor.cpp b/searchcore/src/vespa/searchcore/proton/attribute/document_field_extractor.cpp
index 1c779be18be..c0c6f729509 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/document_field_extractor.cpp
+++ b/searchcore/src/vespa/searchcore/proton/attribute/document_field_extractor.cpp
@@ -110,13 +110,6 @@ makeArray(const FieldPathEntry &fieldPathEntry, size_t size)
return array;
}
-bool
-checkInherits(const FieldValue &fieldValue, unsigned id)
-{
- const vespalib::Identifiable::RuntimeClass &rc = fieldValue.getClass();
- return rc.inherits(id);
-}
-
}
DocumentFieldExtractor::DocumentFieldExtractor(const Document &doc)
@@ -176,7 +169,7 @@ template <typename ExtractorFunc>
std::unique_ptr<FieldValue>
extractFieldFromMap(const FieldValue *outerFieldValue, const FieldPathEntry &innerEntry, ExtractorFunc &&extractor)
{
- if (outerFieldValue != nullptr && checkInherits(*outerFieldValue, MapFieldValue::classId)) {
+ if (outerFieldValue && outerFieldValue->isA(FieldValue::Type::MAP)) {
const auto outerMap = static_cast<const MapFieldValue *>(outerFieldValue);
auto array = makeArray(innerEntry, outerMap->size());
uint32_t arrayIndex = 0;
@@ -190,9 +183,9 @@ extractFieldFromMap(const FieldValue *outerFieldValue, const FieldPathEntry &inn
template <typename CollectionFieldValueT, typename ExtractorFunc>
std::unique_ptr<FieldValue>
-extractFieldFromStructCollection(const FieldValue *outerFieldValue, const FieldPathEntry &innerEntry, ExtractorFunc &&extractor)
+extractFieldFromStructCollection(const FieldValue *outerFieldValue, FieldValue::Type expectedType, const FieldPathEntry &innerEntry, ExtractorFunc &&extractor)
{
- if (outerFieldValue != nullptr && checkInherits(*outerFieldValue, CollectionFieldValueT::classId)) {
+ if (outerFieldValue && outerFieldValue->isA(expectedType)) {
const auto *outerCollection = static_cast<const CollectionFieldValueT *>(outerFieldValue);
auto array = makeArray(innerEntry, outerCollection->size());
uint32_t arrayIndex = 0;
@@ -213,7 +206,7 @@ extractFieldFromStructCollection(const FieldValue *outerFieldValue, const FieldP
std::unique_ptr<FieldValue>
DocumentFieldExtractor::extractFieldFromStructArray(const FieldPath &fieldPath)
{
- return extractFieldFromStructCollection<ArrayFieldValue>(getCachedFieldValue(fieldPath[0]), fieldPath[1],
+ return extractFieldFromStructCollection<ArrayFieldValue>(getCachedFieldValue(fieldPath[0]), FieldValue::Type::ARRAY, fieldPath[1],
[](const auto *elem){ return elem; });
}
@@ -234,7 +227,7 @@ DocumentFieldExtractor::extractValueFieldFromPrimitiveMap(const FieldPath &field
std::unique_ptr<document::FieldValue>
DocumentFieldExtractor::extractValueFieldFromStructMap(const FieldPath &fieldPath)
{
- return extractFieldFromStructCollection<MapFieldValue>(getCachedFieldValue(fieldPath[0]), fieldPath[2],
+ return extractFieldFromStructCollection<MapFieldValue>(getCachedFieldValue(fieldPath[0]), FieldValue::Type::MAP, fieldPath[2],
[](const auto *elem){ return elem->second; });
}
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/document_field_retriever.cpp b/searchcore/src/vespa/searchcore/proton/attribute/document_field_retriever.cpp
index 00d84e795c7..cf543f1ba17 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/document_field_retriever.cpp
+++ b/searchcore/src/vespa/searchcore/proton/attribute/document_field_retriever.cpp
@@ -58,7 +58,7 @@ setValue(DocumentIdT lid, Document &doc, const document::Field & field, const IA
break;
}
FieldValue::UP fv = field.getDataType().createFieldValue();
- if (fv.get() && fv->getClass().id() != ArrayFieldValue::classId) {
+ if (fv && ! fv->isA(FieldValue::Type::ARRAY)) {
throw IllegalStateException("Field " + field.getName() + " does not contain an array.", VESPA_STRLOC);
}
ArrayFieldValue &array = static_cast<ArrayFieldValue &>(*fv.get());
@@ -78,7 +78,7 @@ setValue(DocumentIdT lid, Document &doc, const document::Field & field, const IA
break;
}
FieldValue::UP fv = field.getDataType().createFieldValue();
- if (fv.get() && fv->getClass().id() != WeightedSetFieldValue::classId) {
+ if (fv && ! fv->isA(FieldValue::Type::WSET)) {
throw IllegalStateException("Field " + field.getName() + " does not contain a wset.", VESPA_STRLOC);
}
WeightedSetFieldValue & wset(static_cast<WeightedSetFieldValue &>(*fv.get()));
diff --git a/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp b/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp
index 9c7b4bbb4b7..5b134c65e84 100644
--- a/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp
+++ b/searchcore/src/vespa/searchcore/proton/common/attribute_updater.cpp
@@ -136,16 +136,15 @@ AttributeUpdater::handleUpdateT(V & vec, Accessor, uint32_t lid, const ValueUpda
const AssignValueUpdate & assign(static_cast<const AssignValueUpdate &>(upd));
if (assign.hasValue()) {
const FieldValue & fv(assign.getValue());
- const vespalib::Identifiable::RuntimeClass & rc(fv.getClass());
- if (rc.inherits(ArrayFieldValue::classId)) {
+ if (fv.isA(FieldValue::Type::ARRAY)) {
ArrayAccessor<Accessor> ac(static_cast<const ArrayFieldValue & >(fv));
appendValue(vec, lid, ac);
- } else if (rc.inherits(WeightedSetFieldValue::classId)) {
+ } else if (fv.isA(FieldValue::Type::WSET)) {
WeightedSetAccessor<Accessor> ac(static_cast<const WeightedSetFieldValue & >(fv));
appendValue(vec, lid, ac);
} else {
LOG(warning, "Unsupported value %s in assign operation on multivalue vector %s",
- rc.name(), vec.getName().c_str());
+ fv.className(), vec.getName().c_str());
}
}
} else if (op == ValueUpdate::Add) {
@@ -158,7 +157,7 @@ AttributeUpdater::handleUpdateT(V & vec, Accessor, uint32_t lid, const ValueUpda
const MapValueUpdate & map(static_cast<const MapValueUpdate &>(upd));
if (!vec.AttributeVector::apply(lid, map)) {
throw UpdateException(make_string("attribute map(%s, %s) failed: %s[%u]",
- map.getKey().getClass().name(), map.getUpdate().getClass().name(),
+ map.getKey().className(), map.getUpdate().getClass().name(),
vec.getName().c_str(), lid));
}
} else {
@@ -323,15 +322,14 @@ AttributeUpdater::handleValueT(V & vec, Accessor, uint32_t lid, const FieldValue
{
if (vec.hasMultiValue()) {
vec.clearDoc(lid);
- const vespalib::Identifiable::RuntimeClass & rc = val.getClass();
- if (rc.inherits(ArrayFieldValue::classId)) {
+ if (val.isA(FieldValue::Type::ARRAY)) {
ArrayAccessor<Accessor> ac(static_cast<const ArrayFieldValue & >(val));
appendValue(vec, lid, ac);
- } else if (rc.inherits(WeightedSetFieldValue::classId)) {
+ } else if (val.isA(FieldValue::Type::WSET)) {
WeightedSetAccessor<Accessor> ac(static_cast<const WeightedSetFieldValue & >(val));
appendValue(vec, lid, ac);
} else {
- LOG(warning, "Unsupported value '%s' to assign on multivalue vector '%s'", rc.name(), vec.getName().c_str());
+ LOG(warning, "Unsupported value '%s' to assign on multivalue vector '%s'", val.className(), vec.getName().c_str());
}
} else {
updateValue(vec, lid, val);
@@ -412,7 +410,7 @@ namespace {
const vespalib::string &
getString(const search::StringAttribute & attr, uint32_t lid, const FieldValue & val) {
- if ( ! val.inherits(LiteralFieldValueB::classId) ) {
+ if ( ! val.isLiteral() ) {
throw UpdateException(make_string("Can not update a string attribute '%s' for lid=%d from a non-literal fieldvalue: %s",
attr.getName().c_str(), lid, val.toString().c_str()));
}
@@ -453,11 +451,10 @@ AttributeUpdater::updateValue(StringAttribute & vec, uint32_t lid, const FieldVa
namespace {
-template <typename ExpFieldValueType>
void
-validate_field_value_type(const FieldValue& val, const vespalib::string& attr_type, const vespalib::string& value_type)
+validate_field_value_type(FieldValue::Type expectedType, const FieldValue& val, const vespalib::string& attr_type, const vespalib::string& value_type)
{
- if (!val.inherits(ExpFieldValueType::classId)) {
+ if (!val.isA(expectedType)) {
throw UpdateException(
make_string("%s must be updated with %s, but was '%s'",
attr_type.c_str(), value_type.c_str(), val.toString(false).c_str()));
@@ -469,14 +466,14 @@ validate_field_value_type(const FieldValue& val, const vespalib::string& attr_ty
void
AttributeUpdater::updateValue(PredicateAttribute &vec, uint32_t lid, const FieldValue &val)
{
- validate_field_value_type<PredicateFieldValue>(val, "PredicateAttribute", "PredicateFieldValue");
+ validate_field_value_type(FieldValue::Type::PREDICATE, val, "PredicateAttribute", "PredicateFieldValue");
vec.updateValue(lid, static_cast<const PredicateFieldValue &>(val));
}
void
AttributeUpdater::updateValue(TensorAttribute &vec, uint32_t lid, const FieldValue &val)
{
- validate_field_value_type<TensorFieldValue>(val, "TensorAttribute", "TensorFieldValue");
+ validate_field_value_type(FieldValue::Type::TENSOR, val, "TensorAttribute", "TensorFieldValue");
const auto &tensor = static_cast<const TensorFieldValue &>(val).getAsTensorPtr();
if (tensor) {
vec.setTensor(lid, *tensor);
@@ -488,7 +485,7 @@ AttributeUpdater::updateValue(TensorAttribute &vec, uint32_t lid, const FieldVal
void
AttributeUpdater::updateValue(ReferenceAttribute &vec, uint32_t lid, const FieldValue &val)
{
- if (!val.inherits(ReferenceFieldValue::classId)) {
+ if (!val.isA(FieldValue::Type::REFERENCE)) {
vec.clearDoc(lid);
throw UpdateException(
make_string("ReferenceAttribute must be updated with "
@@ -518,7 +515,7 @@ validate_tensor_attribute_type(AttributeVector& attr)
std::unique_ptr<PrepareResult>
prepare_set_tensor(TensorAttribute& attr, uint32_t docid, const FieldValue& val)
{
- validate_field_value_type<TensorFieldValue>(val, "TensorAttribute", "TensorFieldValue");
+ validate_field_value_type(FieldValue::Type::TENSOR, val, "TensorAttribute", "TensorFieldValue");
const auto& tensor = static_cast<const TensorFieldValue&>(val).getAsTensorPtr();
if (tensor) {
return attr.prepare_set_tensor(docid, *tensor);
@@ -529,7 +526,7 @@ prepare_set_tensor(TensorAttribute& attr, uint32_t docid, const FieldValue& val)
void
complete_set_tensor(TensorAttribute& attr, uint32_t docid, const FieldValue& val, std::unique_ptr<PrepareResult> prepare_result)
{
- validate_field_value_type<TensorFieldValue>(val, "TensorAttribute", "TensorFieldValue");
+ validate_field_value_type(FieldValue::Type::TENSOR, val, "TensorAttribute", "TensorFieldValue");
const auto& tensor = static_cast<const TensorFieldValue&>(val).getAsTensorPtr();
if (tensor) {
attr.complete_set_tensor(docid, *tensor, std::move(prepare_result));
diff --git a/searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp b/searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp
index 1342324b727..3550b38383a 100644
--- a/searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp
+++ b/searchcore/src/vespa/searchcore/proton/docsummary/documentstoreadapter.cpp
@@ -58,7 +58,7 @@ DocumentStoreAdapter::writeField(const FieldValue &value, ResType type)
case RES_LONG_STRING:
case RES_JSONSTRING:
{
- if (value.getClass().inherits(LiteralFieldValueB::classId)) {
+ if (value.isLiteral()) {
auto & lfv = static_cast<const LiteralFieldValueB &>(value);
vespalib::stringref s = lfv.getValueRef();
return writeStringField(s.data(), s.size(), type);
@@ -80,7 +80,7 @@ DocumentStoreAdapter::writeField(const FieldValue &value, ResType type)
case RES_TENSOR:
{
vespalib::nbostream serialized;
- if (value.getClass().inherits(TensorFieldValue::classId)) {
+ if (value.isA(FieldValue::Type::TENSOR)) {
const auto &tvalue = static_cast<const TensorFieldValue &>(value);
auto tensor = tvalue.getAsTensorPtr();
if (tensor) {
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/DoubleValue.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/DoubleValue.java
index 6154b5ea76c..d8443cfd1ef 100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/DoubleValue.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/DoubleValue.java
@@ -129,8 +129,8 @@ public final class DoubleValue extends DoubleCompatibleValue {
/** Returns this or a mutable copy assigned the given value */
private DoubleValue mutable(double value) {
- DoubleValue mutable=this.asMutable();
- mutable.value=value;
+ DoubleValue mutable = this.asMutable();
+ mutable.value = value;
return mutable;
}
@@ -147,7 +147,7 @@ public final class DoubleValue extends DoubleCompatibleValue {
@Override
public boolean equals(Object other) {
- if (this==other) return true;
+ if (this == other) return true;
if ( ! (other instanceof Value)) return false;
if ( ! ((Value) other).hasDouble()) return false;
return this.asDouble() == ((Value) other).asDouble();
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TruthOperator.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TruthOperator.java
index 6f264903122..fc259867923 100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TruthOperator.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TruthOperator.java
@@ -21,7 +21,7 @@ public enum TruthOperator implements Serializable {
private final String operatorString;
TruthOperator(String operatorString) {
- this.operatorString=operatorString;
+ this.operatorString = operatorString;
}
/** Perform the truth operation on the input */
diff --git a/searchlib/src/tests/tensor/hnsw_saver/hnsw_save_load_test.cpp b/searchlib/src/tests/tensor/hnsw_saver/hnsw_save_load_test.cpp
index 43ff6f5b83b..add7801e03a 100644
--- a/searchlib/src/tests/tensor/hnsw_saver/hnsw_save_load_test.cpp
+++ b/searchlib/src/tests/tensor/hnsw_saver/hnsw_save_load_test.cpp
@@ -89,13 +89,13 @@ public:
HnswGraph copy;
void expect_empty_d(uint32_t docid) const {
- EXPECT_FALSE(copy.node_refs[docid].load_acquire().valid());
+ EXPECT_FALSE(copy.acquire_node_ref(docid).valid());
}
void expect_level_0(uint32_t docid, const V& exp_links) const {
- auto levels = copy.get_level_array(docid);
+ auto levels = copy.acquire_level_array(docid);
EXPECT_GE(levels.size(), 1);
- auto links = copy.get_link_array(docid, 0);
+ auto links = copy.acquire_link_array(docid, 0);
EXPECT_EQ(exp_links.size(), links.size());
for (size_t i = 0; i < exp_links.size() && i < links.size(); ++i) {
EXPECT_EQ(exp_links[i], links[i]);
@@ -103,9 +103,9 @@ public:
}
void expect_level_1(uint32_t docid, const V& exp_links) const {
- auto levels = copy.get_level_array(docid);
+ auto levels = copy.acquire_level_array(docid);
EXPECT_EQ(2, levels.size());
- auto links = copy.get_link_array(docid, 1);
+ auto links = copy.acquire_link_array(docid, 1);
EXPECT_EQ(exp_links.size(), links.size());
for (size_t i = 0; i < exp_links.size() && i < links.size(); ++i) {
EXPECT_EQ(exp_links[i], links[i]);
diff --git a/searchlib/src/vespa/searchlib/attribute/attributevector.hpp b/searchlib/src/vespa/searchlib/attribute/attributevector.hpp
index 623e10ef052..c75f7788467 100644
--- a/searchlib/src/vespa/searchlib/attribute/attributevector.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/attributevector.hpp
@@ -10,23 +10,6 @@
namespace search {
-template <typename T>
-inline bool myIsNan(T v) { (void)v; return false; }
-
-template <>
-inline bool
-myIsNan<float>(float v)
-{
- return std::isnan(v);
-}
-
-template <>
-inline bool
-myIsNan<double>(double v)
-{
- return std::isnan(v);
-}
-
template<typename T>
bool
AttributeVector::adjustWeight(ChangeVectorT< ChangeTemplate<T> > & changes, DocId doc, const T & v,
@@ -70,7 +53,7 @@ AttributeVector::adjustWeight(ChangeVectorT< ChangeTemplate<T> >& changes, DocId
size_t oldSz(changes.size());
if (wu.hasValue()) {
const FieldValue &wv = wu.getValue();
- if (wv.inherits(document::IntFieldValue::classId)) {
+ if (wv.isA(FieldValue::Type::INT)) {
changes.push_back(ChangeTemplate<T>(ChangeBase::SETWEIGHT, doc, v, wv.getAsInt()));
} else {
retval = false;
diff --git a/searchlib/src/vespa/searchlib/expression/documentfieldnode.cpp b/searchlib/src/vespa/searchlib/expression/documentfieldnode.cpp
index df3d2e5b19b..91e5a36a7cf 100644
--- a/searchlib/src/vespa/searchlib/expression/documentfieldnode.cpp
+++ b/searchlib/src/vespa/searchlib/expression/documentfieldnode.cpp
@@ -29,11 +29,12 @@ DocumentFieldNode::DocumentFieldNode(const DocumentFieldNode & rhs) :
_fieldPath(rhs._fieldPath),
_value(rhs._value),
_fieldName(rhs._fieldName),
- _doc(NULL)
+ _doc(nullptr)
{
}
-DocumentFieldNode & DocumentFieldNode::operator = (const DocumentFieldNode & rhs)
+DocumentFieldNode &
+DocumentFieldNode::operator = (const DocumentFieldNode & rhs)
{
if (this != &rhs) {
DocumentAccessorNode::operator=(rhs);
@@ -49,12 +50,11 @@ std::unique_ptr<ResultNode>
deduceResultNode(vespalib::stringref fieldName, const FieldValue & fv, bool preserveAccurateTypes, bool nestedMultiValue)
{
std::unique_ptr<ResultNode> value;
- const Identifiable::RuntimeClass & cInfo = fv.getClass();
- if (cInfo.inherits(ByteFieldValue::classId) || cInfo.inherits(IntFieldValue::classId) || cInfo.inherits(LongFieldValue::classId)) {
+ if (fv.isA(FieldValue::Type::BYTE) || fv.isA(FieldValue::Type::INT) || fv.isA(FieldValue::Type::LONG)) {
if (preserveAccurateTypes) {
- if (cInfo.inherits(ByteFieldValue::classId)) {
+ if (fv.isA(FieldValue::Type::BYTE)) {
value.reset(nestedMultiValue ? static_cast<ResultNode *>(new Int8ResultNodeVector()) : static_cast<ResultNode *>(new Int8ResultNode()));
- } else if (cInfo.inherits(IntFieldValue::classId)) {
+ } else if (fv.isA(FieldValue::Type::INT)) {
value.reset(nestedMultiValue ? static_cast<ResultNode *>(new Int32ResultNodeVector()) : static_cast<ResultNode *>(new Int32ResultNode()));
} else {
value.reset(nestedMultiValue ? static_cast<ResultNode *>(new Int64ResultNodeVector()) : static_cast<ResultNode *>(new Int64ResultNode()));
@@ -62,22 +62,20 @@ deduceResultNode(vespalib::stringref fieldName, const FieldValue & fv, bool pres
} else {
value.reset(nestedMultiValue ? static_cast<ResultNode *>(new Int64ResultNodeVector()) : static_cast<ResultNode *>(new Int64ResultNode()));
}
- } else if (cInfo.inherits(FloatFieldValue::classId) || cInfo.inherits(DoubleFieldValue::classId)) {
+ } else if (fv.isA(FieldValue::Type::FLOAT) || fv.isA(FieldValue::Type::DOUBLE)) {
value.reset(nestedMultiValue ? static_cast<ResultNode *>(new FloatResultNodeVector()) : static_cast<ResultNode *>(new FloatResultNode()));
- } else if (cInfo.inherits(BoolFieldValue::classId)) {
+ } else if (fv.isA(FieldValue::Type::BOOL)) {
value.reset(nestedMultiValue ? static_cast<ResultNode *>(new BoolResultNodeVector()) : static_cast<ResultNode *>(new BoolResultNode()));
- } else if (cInfo.inherits(StringFieldValue::classId)) {
+ } else if (fv.isA(FieldValue::Type::STRING)) {
value.reset(nestedMultiValue ? static_cast<ResultNode *>(new StringResultNodeVector()) : static_cast<ResultNode *>(new StringResultNode()));
- } else if (cInfo.inherits(RawFieldValue::classId)) {
+ } else if (fv.isA(FieldValue::Type::RAW)) {
value.reset(nestedMultiValue ? static_cast<ResultNode *>(new RawResultNodeVector()) : static_cast<ResultNode *>(new RawResultNode()));
- } else if (cInfo.inherits(CollectionFieldValue::classId) || cInfo.inherits(MapFieldValue::classId)) {
- if (cInfo.inherits(CollectionFieldValue::classId)) {
+ } else if (fv.isCollection() || fv.isA(FieldValue::Type::MAP)) {
+ if (fv.isCollection()) {
value = deduceResultNode(fieldName, *static_cast<const CollectionFieldValue &>(fv).createNested(), preserveAccurateTypes, nestedMultiValue);
- } else if (cInfo.inherits(MapFieldValue::classId)) {
- value = deduceResultNode(fieldName, *static_cast<const MapFieldValue &>(fv).createValue(), preserveAccurateTypes, nestedMultiValue);
} else {
- throw std::runtime_error(make_string("Can not deduce correct resultclass for documentfield '%s' in based on class '%s'",
- vespalib::string(fieldName).c_str(), cInfo.name()));
+ assert(fv.isA(FieldValue::Type::MAP));
+ value = deduceResultNode(fieldName, *static_cast<const MapFieldValue &>(fv).createValue(), preserveAccurateTypes, nestedMultiValue);
}
const Identifiable::RuntimeClass & rInfo = value->getClass();
if (rInfo.inherits(ResultNodeVector::classId)) {
@@ -100,16 +98,17 @@ deduceResultNode(vespalib::stringref fieldName, const FieldValue & fv, bool pres
value.reset(new RawResultNodeVector());
} else {
throw std::runtime_error(make_string("Can not deduce correct resultclass for documentfield '%s' in based on class '%s'. It nests down to %s which is not expected",
- vespalib::string(fieldName).c_str(), cInfo.name(), rInfo.name()));
+ vespalib::string(fieldName).c_str(), fv.className(), rInfo.name()));
}
} else {
throw std::runtime_error(make_string("Can not deduce correct resultclass for documentfield '%s' in based on class '%s'",
- vespalib::string(fieldName).c_str(), cInfo.name()));
+ vespalib::string(fieldName).c_str(), fv.className()));
}
return value;
}
-void DocumentFieldNode::onPrepare(bool preserveAccurateTypes)
+void
+DocumentFieldNode::onPrepare(bool preserveAccurateTypes)
{
LOG(debug, "DocumentFieldNode::onPrepare(this=%p)", this);
@@ -118,8 +117,8 @@ void DocumentFieldNode::onPrepare(bool preserveAccurateTypes)
for(document::FieldPath::const_iterator it(_fieldPath.begin()), mt(_fieldPath.end()); !nestedMultiValue && (it != mt); it++) {
const FieldPathEntry & fpe = **it;
if (fpe.getType() == document::FieldPathEntry::STRUCT_FIELD) {
- const vespalib::Identifiable::RuntimeClass & cInfo(fpe.getFieldValueToSet().getClass());
- nestedMultiValue = cInfo.inherits(CollectionFieldValue::classId) || cInfo.inherits(MapFieldValue::classId);
+ const FieldValue & fv = fpe.getFieldValueToSet();
+ nestedMultiValue = fv.isCollection() || fv.isA(FieldValue::Type::MAP);
}
}
const document::FieldPathEntry & endOfPath(_fieldPath.back());
@@ -127,9 +126,9 @@ void DocumentFieldNode::onPrepare(bool preserveAccurateTypes)
const FieldValue& fv = endOfPath.getFieldValueToSet();
_value.reset(deduceResultNode(_fieldName, fv, preserveAccurateTypes, nestedMultiValue).release());
if (_value->inherits(ResultNodeVector::classId)) {
- _handler.reset(new MultiHandler(static_cast<ResultNodeVector &>(*_value)));
+ _handler = std::make_unique<MultiHandler>(static_cast<ResultNodeVector &>(*_value));
} else {
- _handler.reset(new SingleHandler(*_value));
+ _handler = std::make_unique<SingleHandler>(*_value);
}
} else {
if (endOfPath.getDataType().isStructured()) {
@@ -222,10 +221,10 @@ DocumentFieldNode::Handler::onCollectionStart(const Content & c)
{
const document::FieldValue & fv = c.getValue();
LOG(spam, "onCollectionStart: field value '%s'", fv.toString().c_str());
- if (fv.inherits(document::ArrayFieldValue::classId)) {
+ if (fv.isA(FieldValue::Type::ARRAY)) {
const document::ArrayFieldValue & afv = static_cast<const document::ArrayFieldValue &>(fv);
LOG(spam, "onCollectionStart: Array size = '%zu'", afv.size());
- } else if (fv.inherits(document::WeightedSetFieldValue::classId)) {
+ } else if (fv.isA(FieldValue::Type::WSET)) {
const document::WeightedSetFieldValue & wsfv = static_cast<const document::WeightedSetFieldValue &>(fv);
LOG(spam, "onCollectionStart: WeightedSet size = '%zu'", wsfv.size());
}
@@ -253,9 +252,6 @@ DocumentFieldNode::visitMembers(vespalib::ObjectVisitor &visitor) const
{
visit(visitor, "fieldName", _fieldName);
visit(visitor, "value", _value);
- visitor.openStruct("fieldPath", "FieldPath");
- _fieldPath.visitMembers(visitor);
- visitor.closeStruct();
}
class String2ResultNode : public ResultNode
diff --git a/searchlib/src/vespa/searchlib/memoryindex/field_inverter.cpp b/searchlib/src/vespa/searchlib/memoryindex/field_inverter.cpp
index a443e994559..5a7d0e60153 100644
--- a/searchlib/src/vespa/searchlib/memoryindex/field_inverter.cpp
+++ b/searchlib/src/vespa/searchlib/memoryindex/field_inverter.cpp
@@ -271,7 +271,7 @@ FieldInverter::saveWord(const vespalib::stringref word)
uint32_t
FieldInverter::saveWord(const document::FieldValue &fv)
{
- assert(fv.getClass().id() == StringFieldValue::classId);
+ assert(fv.isA(FieldValue::Type::STRING));
using RawRef = std::pair<const char*, size_t>;
RawRef sRef = fv.getAsRaw();
return saveWord(vespalib::stringref(sRef.first, sRef.second));
@@ -303,8 +303,7 @@ FieldInverter::endDoc()
}
_calculator.add_field_length(field_length);
uint32_t newPosSize = static_cast<uint32_t>(_positions.size());
- _pendingDocs.insert({ _docId,
- { _oldPosSize, newPosSize - _oldPosSize } });
+ _pendingDocs.insert({ _docId, { _oldPosSize, newPosSize - _oldPosSize } });
_docId = 0;
_oldPosSize = newPosSize;
}
@@ -324,7 +323,7 @@ FieldInverter::processNormalDocArrayTextField(const ArrayFieldValue &field)
uint32_t ele = field.size();
for (;el < ele; ++el) {
const FieldValue &elfv = field[el];
- assert(elfv.getClass().id() == StringFieldValue::classId);
+ assert(elfv.isA(FieldValue::Type::STRING));
const auto &element = static_cast<const StringFieldValue &>(elfv);
startElement(1);
processAnnotations(element);
@@ -338,8 +337,8 @@ FieldInverter::processNormalDocWeightedSetTextField(const WeightedSetFieldValue
for (const auto & el : field) {
const FieldValue &key = *el.first;
const FieldValue &xweight = *el.second;
- assert(key.getClass().id() == StringFieldValue::classId);
- assert(xweight.getClass().id() == IntFieldValue::classId);
+ assert(key.isA(FieldValue::Type::STRING));
+ assert(xweight.isA(FieldValue::Type::INT));
const auto &element = static_cast<const StringFieldValue &>(key);
int32_t weight = xweight.getAsInt();
startElement(weight);
@@ -457,18 +456,17 @@ FieldInverter::startDoc(uint32_t docId) {
void
FieldInverter::invertNormalDocTextField(const FieldValue &val)
{
- const vespalib::Identifiable::RuntimeClass & cInfo(val.getClass());
const Schema::IndexField &field = _schema.getIndexField(_fieldId);
switch (field.getCollectionType()) {
case CollectionType::SINGLE:
- if (cInfo.id() == StringFieldValue::classId) {
+ if (val.isA(FieldValue::Type::STRING)) {
processNormalDocTextField(static_cast<const StringFieldValue &>(val));
} else {
throw std::runtime_error(make_string("Expected DataType::STRING, got '%s'", val.getDataType()->getName().c_str()));
}
break;
case CollectionType::WEIGHTEDSET:
- if (cInfo.id() == WeightedSetFieldValue::classId) {
+ if (val.isA(FieldValue::Type::WSET)) {
const auto &wset = static_cast<const WeightedSetFieldValue &>(val);
if (wset.getNestedType() == *DataType::STRING) {
processNormalDocWeightedSetTextField(wset);
@@ -476,11 +474,11 @@ FieldInverter::invertNormalDocTextField(const FieldValue &val)
throw std::runtime_error(make_string("Expected DataType::STRING, got '%s'", wset.getNestedType().getName().c_str()));
}
} else {
- throw std::runtime_error(make_string("Expected weighted set, got '%s'", cInfo.name()));
+ throw std::runtime_error(make_string("Expected weighted set, got '%s'", val.className()));
}
break;
case CollectionType::ARRAY:
- if (cInfo.id() == ArrayFieldValue::classId) {
+ if (val.isA(FieldValue::Type::ARRAY)) {
const auto &arr = static_cast<const ArrayFieldValue&>(val);
if (arr.getNestedType() == *DataType::STRING) {
processNormalDocArrayTextField(arr);
@@ -488,7 +486,7 @@ FieldInverter::invertNormalDocTextField(const FieldValue &val)
throw std::runtime_error(make_string("Expected DataType::STRING, got '%s'", arr.getNestedType().getName().c_str()));
}
} else {
- throw std::runtime_error(make_string("Expected Array, got '%s'", cInfo.name()));
+ throw std::runtime_error(make_string("Expected Array, got '%s'", val.className()));
}
break;
default:
diff --git a/searchlib/src/vespa/searchlib/memoryindex/url_field_inverter.cpp b/searchlib/src/vespa/searchlib/memoryindex/url_field_inverter.cpp
index 326b7b0967a..87bcdd31933 100644
--- a/searchlib/src/vespa/searchlib/memoryindex/url_field_inverter.cpp
+++ b/searchlib/src/vespa/searchlib/memoryindex/url_field_inverter.cpp
@@ -6,7 +6,6 @@
#include <vespa/document/fieldvalue/arrayfieldvalue.h>
#include <vespa/document/fieldvalue/stringfieldvalue.h>
#include <vespa/document/fieldvalue/weightedsetfieldvalue.h>
-#include <vespa/searchlib/common/sort.h>
#include <vespa/searchlib/util/url.h>
#include <vespa/vespalib/text/lowercase.h>
#include <vespa/vespalib/text/utf8.h>
@@ -122,7 +121,7 @@ UrlFieldInverter::processUrlSubField(FieldInverter *inverter,
if (!sfv) {
return;
}
- if (!sfv->inherits(IDENTIFIABLE_CLASSID(StringFieldValue))) {
+ if (!sfv->isA(FieldValue::Type::STRING)) {
LOG(error,
"Illegal field type %s for URL subfield %s, expected string",
sfv->getDataType()->getName().c_str(),
@@ -155,13 +154,13 @@ UrlFieldInverter::processAnnotatedUrlField(const StructFieldValue & field)
void
UrlFieldInverter::processUrlField(const FieldValue &url_field)
{
- if (url_field.inherits(IDENTIFIABLE_CLASSID(StringFieldValue))) {
+ if (url_field.isA(FieldValue::Type::STRING)) {
const vespalib::string &url_str =
static_cast<const StringFieldValue &>(url_field).getValue();
processUrlOldStyle(url_str);
return;
}
- assert(url_field.getClass().id() == StructFieldValue::classId);
+ assert(url_field.isA(FieldValue::Type::STRUCT));
const auto &field = static_cast<const StructFieldValue &>(url_field);
const FieldValue::UP all_val = field.getValue("all");
@@ -173,7 +172,7 @@ UrlFieldInverter::processUrlField(const FieldValue &url_field)
return;
}
- if (!all_val->inherits(IDENTIFIABLE_CLASSID(StringFieldValue))) {
+ if (!all_val->isA(FieldValue::Type::STRING)) {
LOG(error,
"Illegal field type %s for URL subfield all, expected string",
all_val->getDataType()->getName().c_str());
@@ -275,7 +274,7 @@ UrlFieldInverter::processWeightedSetUrlField(const WeightedSetFieldValue &field)
for (const auto & el : field) {
const FieldValue &key = *el.first;
const FieldValue &xweight = *el.second;
- assert(xweight.getClass().id() == IntFieldValue::classId);
+ assert(xweight.isA(FieldValue::Type::INT));
int32_t weight = xweight.getAsInt();
startElement(weight);
processUrlField(key);
@@ -298,7 +297,6 @@ isUriType(const DataType &type)
void
UrlFieldInverter::invertUrlField(const FieldValue &val)
{
- const vespalib::Identifiable::RuntimeClass & cInfo(val.getClass());
switch (_collectionType) {
case CollectionType::SINGLE:
if (isUriType(*val.getDataType())) {
@@ -309,30 +307,29 @@ UrlFieldInverter::invertUrlField(const FieldValue &val)
throw std::runtime_error(make_string("Expected URI struct, got '%s'", val.getDataType()->getName().c_str()));
}
break;
- case CollectionType::WEIGHTEDSET:
- if (cInfo.id() == WeightedSetFieldValue::classId) {
- const auto &wset = static_cast<const WeightedSetFieldValue &>(val);
- if (isUriType(wset.getNestedType())) {
- processWeightedSetUrlField(wset);
- } else {
- throw std::runtime_error(make_string("Expected wset of URI struct, got '%s'", wset.getNestedType().getName().c_str()));
- }
+ case CollectionType::WEIGHTEDSET: {
+ assert(val.isA(FieldValue::Type::WSET));
+ const auto &wset = static_cast<const WeightedSetFieldValue &>(val);
+ if (isUriType(wset.getNestedType())) {
+ processWeightedSetUrlField(wset);
} else {
- throw std::runtime_error(make_string("Expected weighted set, got '%s'", cInfo.name()));
+ throw std::runtime_error(
+ make_string("Expected wset of URI struct, got '%s'", wset.getNestedType().getName().c_str()));
}
break;
- case CollectionType::ARRAY:
- if (cInfo.id() == ArrayFieldValue::classId) {
- const auto &arr = static_cast<const ArrayFieldValue&>(val);
- if (isUriType(arr.getNestedType())) {
- processArrayUrlField(arr);
- } else {
- throw std::runtime_error(make_string("Expected array of URI struct, got '%s' (%s)", arr.getNestedType().getName().c_str(), arr.getNestedType().toString(true).c_str()));
- }
+ }
+ case CollectionType::ARRAY: {
+ assert(val.isA(FieldValue::Type::ARRAY));
+ const auto &arr = static_cast<const ArrayFieldValue &>(val);
+ if (isUriType(arr.getNestedType())) {
+ processArrayUrlField(arr);
} else {
- throw std::runtime_error(make_string("Expected Array, got '%s'", cInfo.name()));
+ throw std::runtime_error(
+ make_string("Expected array of URI struct, got '%s' (%s)", arr.getNestedType().getName().c_str(),
+ arr.getNestedType().toString(true).c_str()));
}
break;
+ }
default:
break;
}
diff --git a/searchlib/src/vespa/searchlib/parsequery/parse.h b/searchlib/src/vespa/searchlib/parsequery/parse.h
index c9b7940b887..34ea692c370 100644
--- a/searchlib/src/vespa/searchlib/parsequery/parse.h
+++ b/searchlib/src/vespa/searchlib/parsequery/parse.h
@@ -33,7 +33,7 @@ public:
ITEM_TERM = 4,
ITEM_NUMTERM = 5,
ITEM_PHRASE = 6,
- /* removed: ITEM_PAREN = 7, */
+ ITEM_MULTI_TERM = 7,
ITEM_PREFIXTERM = 8,
ITEM_SUBSTRINGTERM = 9,
ITEM_ANY = 10,
@@ -56,7 +56,7 @@ public:
ITEM_GEO_LOCATION_TERM = 27,
ITEM_TRUE = 28,
ITEM_FALSE = 29,
- ITEM_MULTI_TERM = 30,
+ ITEM_MAX = 30, // Indicates how long tables must be.
ITEM_UNDEF = 31,
};
diff --git a/searchlib/src/vespa/searchlib/tensor/hnsw_graph.cpp b/searchlib/src/vespa/searchlib/tensor/hnsw_graph.cpp
index 8beb111ca59..3049b643709 100644
--- a/searchlib/src/vespa/searchlib/tensor/hnsw_graph.cpp
+++ b/searchlib/src/vespa/searchlib/tensor/hnsw_graph.cpp
@@ -26,7 +26,7 @@ HnswGraph::make_node_for_document(uint32_t docid, uint32_t num_levels)
{
node_refs.ensure_size(docid + 1, AtomicEntryRef());
// A document cannot be added twice.
- assert(!node_refs[docid].load_acquire().valid());
+ assert(!get_node_ref(docid).valid());
// Note: The level array instance lives as long as the document is present in the index.
vespalib::Array<AtomicEntryRef> levels(num_levels, AtomicEntryRef());
auto node_ref = nodes.add(levels);
@@ -40,7 +40,7 @@ HnswGraph::make_node_for_document(uint32_t docid, uint32_t num_levels)
void
HnswGraph::remove_node_for_document(uint32_t docid)
{
- auto node_ref = node_refs[docid].load_acquire();
+ auto node_ref = get_node_ref(docid);
assert(node_ref.valid());
auto levels = nodes.get(node_ref);
vespalib::datastore::EntryRef invalid;
@@ -48,7 +48,7 @@ HnswGraph::remove_node_for_document(uint32_t docid)
// Ensure data referenced through the old ref can be recycled:
nodes.remove(node_ref);
for (size_t i = 0; i < levels.size(); ++i) {
- auto old_links_ref = levels[i].load_acquire();
+ auto old_links_ref = levels[i].load_relaxed();
links.remove(old_links_ref);
}
if (docid + 1 == node_refs_size.load(std::memory_order_relaxed)) {
@@ -60,7 +60,7 @@ void
HnswGraph::trim_node_refs_size()
{
uint32_t check_doc_id = node_refs_size.load(std::memory_order_relaxed) - 1;
- while (check_doc_id > 0u && !node_refs[check_doc_id].load_relaxed().valid()) {
+ while (check_doc_id > 0u && !get_node_ref(check_doc_id).valid()) {
--check_doc_id;
}
node_refs_size.store(check_doc_id + 1, std::memory_order_release);
@@ -70,11 +70,11 @@ void
HnswGraph::set_link_array(uint32_t docid, uint32_t level, const LinkArrayRef& new_links)
{
auto new_links_ref = links.add(new_links);
- auto node_ref = node_refs[docid].load_acquire();
+ auto node_ref = get_node_ref(docid);
assert(node_ref.valid());
auto levels = nodes.get_writable(node_ref);
assert(level < levels.size());
- auto old_links_ref = levels[level].load_acquire();
+ auto old_links_ref = levels[level].load_relaxed();
levels[level].store_release(new_links_ref);
links.remove(old_links_ref);
}
@@ -83,9 +83,9 @@ HnswGraph::Histograms
HnswGraph::histograms() const
{
Histograms result;
- size_t num_nodes = node_refs.size();
+ size_t num_nodes = node_refs_size.load(std::memory_order_acquire);
for (size_t i = 0; i < num_nodes; ++i) {
- auto node_ref = node_refs[i].load_acquire();
+ auto node_ref = acquire_node_ref(i);
if (node_ref.valid()) {
uint32_t levels = 0;
uint32_t l0links = 0;
diff --git a/searchlib/src/vespa/searchlib/tensor/hnsw_graph.h b/searchlib/src/vespa/searchlib/tensor/hnsw_graph.h
index 5d6cff73102..726abb8141d 100644
--- a/searchlib/src/vespa/searchlib/tensor/hnsw_graph.h
+++ b/searchlib/src/vespa/searchlib/tensor/hnsw_graph.h
@@ -56,11 +56,15 @@ struct HnswGraph {
void trim_node_refs_size();
NodeRef get_node_ref(uint32_t docid) const {
- return node_refs[docid].load_acquire();
+ return node_refs[docid].load_relaxed();
+ }
+
+ NodeRef acquire_node_ref(uint32_t docid) const {
+ return node_refs.acquire_elem_ref(docid).load_acquire();
}
bool still_valid(uint32_t docid, NodeRef node_ref) const {
- return node_ref.valid() && (get_node_ref(docid) == node_ref);
+ return node_ref.valid() && (acquire_node_ref(docid) == node_ref);
}
LevelArrayRef get_level_array(NodeRef node_ref) const {
@@ -75,6 +79,11 @@ struct HnswGraph {
return get_level_array(node_ref);
}
+ LevelArrayRef acquire_level_array(uint32_t docid) const {
+ auto node_ref = acquire_node_ref(docid);
+ return get_level_array(node_ref);
+ }
+
LinkArrayRef get_link_array(LevelArrayRef levels, uint32_t level) const {
if (level < levels.size()) {
auto links_ref = levels[level].load_acquire();
@@ -90,6 +99,11 @@ struct HnswGraph {
return get_link_array(levels, level);
}
+ LinkArrayRef acquire_link_array(uint32_t docid, uint32_t level) const {
+ auto levels = acquire_level_array(docid);
+ return get_link_array(levels, level);
+ }
+
LinkArrayRef get_link_array(NodeRef node_ref, uint32_t level) const {
auto levels = get_level_array(node_ref);
return get_link_array(levels, level);
@@ -124,7 +138,7 @@ struct HnswGraph {
while (true) {
uint64_t value = get_entry_atomic();
entry.docid = (uint32_t)value;
- entry.node_ref = get_node_ref(entry.docid);
+ entry.node_ref = acquire_node_ref(entry.docid);
entry.level = (int32_t)(value >> 32);
if ((entry.docid == 0)
&& (entry.level == -1)
@@ -144,7 +158,7 @@ struct HnswGraph {
}
}
- size_t size() const { return node_refs.size(); }
+ size_t size() const { return node_refs_size.load(std::memory_order_acquire); }
struct Histograms {
std::vector<uint32_t> level_histogram;
diff --git a/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp b/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp
index c99e059815b..5ae26757b0d 100644
--- a/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp
+++ b/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp
@@ -245,7 +245,7 @@ HnswIndex::find_nearest_in_layer(const TypedCells& input, const HnswCandidate& e
while (keep_searching) {
keep_searching = false;
for (uint32_t neighbor_docid : _graph.get_link_array(nearest.node_ref, level)) {
- auto neighbor_ref = _graph.get_node_ref(neighbor_docid);
+ auto neighbor_ref = _graph.acquire_node_ref(neighbor_docid);
double dist = calc_distance(input, neighbor_docid);
if (_graph.still_valid(neighbor_docid, neighbor_ref)
&& dist < nearest.distance)
@@ -289,7 +289,7 @@ HnswIndex::search_layer_helper(const TypedCells& input, uint32_t neighbors_to_fi
if (neighbor_docid >= doc_id_limit) {
continue;
}
- auto neighbor_ref = _graph.get_node_ref(neighbor_docid);
+ auto neighbor_ref = _graph.acquire_node_ref(neighbor_docid);
if ((! neighbor_ref.valid())
|| ! visited.try_mark(neighbor_docid))
{
@@ -433,7 +433,7 @@ HnswIndex::prepare_add_document(uint32_t docid,
TypedCells vector,
vespalib::GenerationHandler::Guard read_guard) const
{
- uint32_t max_nodes = _graph.node_refs.size();
+ uint32_t max_nodes = _graph.node_refs_size.load(std::memory_order_acquire);
if (max_nodes < _cfg.min_size_before_two_phase()) {
// the first documents added will do all work in write thread
// to ensure they are linked together:
@@ -543,7 +543,7 @@ HnswIndex::compact_link_arrays(CompactionSpec compaction_spec, const CompactionS
auto context = _graph.links.compactWorst(compaction_spec, compaction_strategy);
uint32_t doc_id_limit = _graph.node_refs.size();
for (uint32_t doc_id = 1; doc_id < doc_id_limit; ++doc_id) {
- EntryRef level_ref = _graph.node_refs[doc_id].load_relaxed();
+ EntryRef level_ref = _graph.get_node_ref(doc_id);
if (level_ref.valid()) {
vespalib::ArrayRef<AtomicEntryRef> refs(_graph.nodes.get_writable(level_ref));
context->compact(refs);
@@ -756,7 +756,7 @@ HnswIndex::top_k_candidates(const TypedCells &vector, uint32_t k, const BitVecto
HnswNode
HnswIndex::get_node(uint32_t docid) const
{
- auto node_ref = _graph.node_refs[docid].load_acquire();
+ auto node_ref = _graph.acquire_node_ref(docid);
if (!node_ref.valid()) {
return HnswNode();
}
@@ -790,15 +790,16 @@ bool
HnswIndex::check_link_symmetry() const
{
bool all_sym = true;
- for (size_t docid = 0; docid < _graph.node_refs.size(); ++docid) {
- auto node_ref = _graph.node_refs[docid].load_acquire();
+ size_t doc_id_limit = _graph.size();
+ for (size_t docid = 0; docid < doc_id_limit; ++docid) {
+ auto node_ref = _graph.acquire_node_ref(docid);
if (node_ref.valid()) {
auto levels = _graph.nodes.get(node_ref);
uint32_t level = 0;
for (const auto& links_ref : levels) {
auto links = _graph.links.get(links_ref.load_acquire());
for (auto neighbor_docid : links) {
- auto neighbor_links = _graph.get_link_array(neighbor_docid, level);
+ auto neighbor_links = _graph.acquire_link_array(neighbor_docid, level);
if (! has_link_to(neighbor_links, docid)) {
all_sym = false;
LOG(warning, "check_link_symmetry: docid %zu links to %u on level %u, but no backlink",
@@ -822,8 +823,10 @@ HnswIndex::count_reachable_nodes() const
}
std::vector<bool> visited(_graph.size());
LinkArray found_links;
- found_links.push_back(entry.docid);
- visited[entry.docid] = true;
+ if (entry.docid < visited.size()) {
+ found_links.push_back(entry.docid);
+ visited[entry.docid] = true;
+ }
vespalib::steady_time doom = vespalib::steady_clock::now() + MAX_COUNT_DURATION;
while (search_level >= 0) {
for (uint32_t idx = 0; idx < found_links.size(); ++idx) {
@@ -831,11 +834,15 @@ HnswIndex::count_reachable_nodes() const
return {found_links.size(), false};
}
uint32_t docid = found_links[idx];
- auto neighbors = _graph.get_link_array(docid, search_level);
- for (uint32_t neighbor : neighbors) {
- if (visited[neighbor]) continue;
- visited[neighbor] = true;
- found_links.push_back(neighbor);
+ if (docid < visited.size()) {
+ auto neighbors = _graph.acquire_link_array(docid, search_level);
+ for (uint32_t neighbor : neighbors) {
+ if (neighbor >= visited.size() || visited[neighbor]) {
+ continue;
+ }
+ visited[neighbor] = true;
+ found_links.push_back(neighbor);
+ }
}
}
--search_level;
diff --git a/searchlib/src/vespa/searchlib/tensor/hnsw_index_saver.cpp b/searchlib/src/vespa/searchlib/tensor/hnsw_index_saver.cpp
index 2eb9f7d4acd..cc2ecd584e1 100644
--- a/searchlib/src/vespa/searchlib/tensor/hnsw_index_saver.cpp
+++ b/searchlib/src/vespa/searchlib/tensor/hnsw_index_saver.cpp
@@ -14,7 +14,7 @@ count_valid_link_arrays(const HnswGraph & graph) {
size_t count(0);
size_t num_nodes = graph.node_refs.size();
for (size_t i = 0; i < num_nodes; ++i) {
- auto node_ref = graph.node_refs[i].load_acquire();
+ auto node_ref = graph.get_node_ref(i);
if (node_ref.valid()) {
count += graph.nodes.get(node_ref).size();
}
@@ -47,11 +47,11 @@ HnswIndexSaver::HnswIndexSaver(const HnswGraph &graph)
_meta_data.nodes.reserve(num_nodes+1);
for (size_t i = 0; i < num_nodes; ++i) {
_meta_data.nodes.push_back(_meta_data.refs.size());
- auto node_ref = graph.node_refs[i].load_acquire();
+ auto node_ref = graph.get_node_ref(i);
if (node_ref.valid()) {
auto levels = graph.nodes.get(node_ref);
for (const auto& links_ref : levels) {
- _meta_data.refs.push_back(links_ref.load_acquire());
+ _meta_data.refs.push_back(links_ref.load_relaxed());
}
}
}
diff --git a/searchlib/src/vespa/searchlib/transactionlog/domain.cpp b/searchlib/src/vespa/searchlib/transactionlog/domain.cpp
index 928497bf09d..0af1ffa7b33 100644
--- a/searchlib/src/vespa/searchlib/transactionlog/domain.cpp
+++ b/searchlib/src/vespa/searchlib/transactionlog/domain.cpp
@@ -214,9 +214,9 @@ Domain::triggerSyncNow(std::unique_ptr<vespalib::IDestructorCallback> after_sync
std::unique_lock guard(_currentChunkMutex);
commitAndTransferResponses(guard);
}
- _singleCommitter->execute(makeLambdaTask([after_sync=std::move(after_sync), domainPart=getActivePart()]() {
+ _singleCommitter->execute(makeLambdaTask([this, after_sync=std::move(after_sync)]() {
(void) after_sync;
- domainPart->sync();
+ getActivePart()->sync();
}));
}
diff --git a/searchsummary/src/tests/extractkeywords/simplequerystackitem.cpp b/searchsummary/src/tests/extractkeywords/simplequerystackitem.cpp
index b31173c74c2..f3706bfc7c1 100644
--- a/searchsummary/src/tests/extractkeywords/simplequerystackitem.cpp
+++ b/searchsummary/src/tests/extractkeywords/simplequerystackitem.cpp
@@ -186,8 +186,9 @@ SimpleQueryStackItem::AppendBuffer(RawBuf *buf) const
buf->appendCompressedPositiveNumber(_arg2); // allow_approximate
buf->appendCompressedPositiveNumber(_arg3); // explore_additional_hits
break;
- case ITEM_PREDICATE_QUERY: // not handled at all here
case ITEM_MULTI_TERM: // TODO: handle
+ case ITEM_PREDICATE_QUERY: // not handled at all here
+ case ITEM_MAX:
case ITEM_UNDEF:
abort();
break;
diff --git a/searchsummary/src/vespa/searchsummary/docsummary/matched_elements_filter_dfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/matched_elements_filter_dfw.cpp
index 2c2ce860e39..fb53ddcc470 100644
--- a/searchsummary/src/vespa/searchsummary/docsummary/matched_elements_filter_dfw.cpp
+++ b/searchsummary/src/vespa/searchsummary/docsummary/matched_elements_filter_dfw.cpp
@@ -82,7 +82,7 @@ filter_matching_elements_in_input_field_while_converting_to_slime(const FieldVal
// Only difference is that we filter matched elements on the fly.
auto converted = SummaryFieldConverter::convert_field_with_filter(false, input_field_value, matching_elems);
// This should hold as we also have asserted that (type == ResType::RES_JSONSTRING);
- assert(converted->getClass().inherits(LiteralFieldValueB::classId));
+ assert(converted->isLiteral());
auto& literal = static_cast<const LiteralFieldValueB&>(*converted);
vespalib::stringref buf = literal.getValueRef();
Slime input_field_as_slime;
diff --git a/searchsummary/src/vespa/searchsummary/docsummary/summaryfieldconverter.cpp b/searchsummary/src/vespa/searchsummary/docsummary/summaryfieldconverter.cpp
index 487fb9e329f..c107e5c8739 100644
--- a/searchsummary/src/vespa/searchsummary/docsummary/summaryfieldconverter.cpp
+++ b/searchsummary/src/vespa/searchsummary/docsummary/summaryfieldconverter.cpp
@@ -29,7 +29,6 @@
#include <vespa/eval/eval/value_codec.h>
#include <vespa/searchcommon/common/schema.h>
#include <vespa/searchlib/util/url.h>
-#include <vespa/vespalib/encoding/base64.h>
#include <vespa/vespalib/geo/zcurve.h>
#include <vespa/vespalib/stllike/asciistream.h>
#include <vespa/vespalib/util/size_literals.h>
@@ -176,7 +175,7 @@ void handleIndexingTerms(Handler &handler, const StringFieldValue &value) {
const StringFieldValue &ensureStringFieldValue(const FieldValue &value) __attribute__((noinline));
const StringFieldValue &ensureStringFieldValue(const FieldValue &value) {
- if (!value.inherits(IDENTIFIABLE_CLASSID(StringFieldValue))) {
+ if (!value.isA(FieldValue::Type::STRING)) {
throw vespalib::IllegalArgumentException("Illegal field type. " + value.toString(), VESPA_STRLOC);
}
return static_cast<const StringFieldValue &>(value);
@@ -287,9 +286,7 @@ class SummaryFieldValueConverter : protected ConstFieldValueVisitor
void visit(const StructFieldValue &value) override {
if (*value.getDataType() == *SearchDataType::URI) {
FieldValue::UP uriAllValue = value.getValue("all");
- if (uriAllValue &&
- uriAllValue->inherits(IDENTIFIABLE_CLASSID(StringFieldValue)))
- {
+ if (uriAllValue && uriAllValue->isA(FieldValue::Type::STRING)) {
uriAllValue->accept(*this);
return;
}
@@ -488,9 +485,7 @@ private:
}
if (*value.getDataType() == *SearchDataType::URI) {
FieldValue::UP uriAllValue = value.getValue("all");
- if (uriAllValue &&
- uriAllValue->inherits(IDENTIFIABLE_CLASSID(StringFieldValue)))
- {
+ if (uriAllValue && uriAllValue->isA(FieldValue::Type::STRING)) {
uriAllValue->accept(*this);
return;
}
diff --git a/staging_vespalib/src/vespa/vespalib/objects/objectvisitor.h b/staging_vespalib/src/vespa/vespalib/objects/objectvisitor.h
index 7e48e9f5b4b..dba731a8940 100644
--- a/staging_vespalib/src/vespa/vespalib/objects/objectvisitor.h
+++ b/staging_vespalib/src/vespa/vespalib/objects/objectvisitor.h
@@ -2,7 +2,6 @@
#pragma once
#include <vespa/vespalib/stllike/string.h>
-#include <stdint.h>
namespace vespalib {
diff --git a/staging_vespalib/src/vespa/vespalib/util/xmlserializable.h b/staging_vespalib/src/vespa/vespalib/util/xmlserializable.h
index 1ceee6dd7b2..76f0ad1fa3a 100644
--- a/staging_vespalib/src/vespa/vespalib/util/xmlserializable.h
+++ b/staging_vespalib/src/vespa/vespalib/util/xmlserializable.h
@@ -17,7 +17,7 @@ class XmlSerializable
{
public:
XmlSerializable() {}
- virtual ~XmlSerializable() {}
+ virtual ~XmlSerializable() = default;
virtual void printXml(XmlOutputStream& out) const = 0;
diff --git a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp
index cbf58b5313d..1e091d9a6d8 100644
--- a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp
+++ b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp
@@ -72,7 +72,7 @@ createMultiValueAttribute(const vespalib::string & name, const document::FieldVa
ndt = &cdt->getNestedType();
}
LOG(debug, "Create %s attribute '%s' with data type '%s' (%s)",
- arrayType ? "array" : "weighted set", name.c_str(), ndt->getName().c_str(), fv.getClass().name());
+ arrayType ? "array" : "weighted set", name.c_str(), ndt->getName().c_str(), fv.className());
if (ndt->getId() == DataType::T_BYTE ||
ndt->getId() == DataType::T_INT ||
ndt->getId() == DataType::T_LONG)
@@ -89,7 +89,7 @@ createMultiValueAttribute(const vespalib::string & name, const document::FieldVa
: std::make_shared<search::WeightedSetStringExtAttribute>(name);
} else {
LOG(debug, "Can not make an multivalue attribute out of %s with data type '%s' (%s)",
- name.c_str(), ndt->getName().c_str(), fv.getClass().name());
+ name.c_str(), ndt->getName().c_str(), fv.className());
}
return AttributeVector::SP();
}
@@ -97,15 +97,15 @@ createMultiValueAttribute(const vespalib::string & name, const document::FieldVa
AttributeVector::SP
createAttribute(const vespalib::string & name, const document::FieldValue & fv)
{
- LOG(debug, "Create single value attribute '%s' with value type '%s'", name.c_str(), fv.getClass().name());
- if (fv.inherits(document::ByteFieldValue::classId) || fv.inherits(document::IntFieldValue::classId) || fv.inherits(document::LongFieldValue::classId)) {
+ LOG(debug, "Create single value attribute '%s' with value type '%s'", name.c_str(), fv.className());
+ if (fv.isA(document::FieldValue::Type::BYTE) || fv.isA(document::FieldValue::Type::INT) || fv.isA(document::FieldValue::Type::LONG)) {
return std::make_shared<search::SingleIntegerExtAttribute>(name);
- } else if (fv.inherits(document::DoubleFieldValue::classId) || fv.inherits(document::FloatFieldValue::classId)) {
+ } else if (fv.isA(document::FieldValue::Type::DOUBLE) || fv.isA(document::FieldValue::Type::FLOAT)) {
return std::make_shared<search::SingleFloatExtAttribute>(name);
- } else if (fv.inherits(document::StringFieldValue::classId)) {
+ } else if (fv.isA(document::FieldValue::Type::STRING)) {
return std::make_shared<search::SingleStringExtAttribute>(name);
} else {
- LOG(debug, "Can not make an attribute out of %s of type '%s'.", name.c_str(), fv.getClass().name());
+ LOG(debug, "Can not make an attribute out of %s of type '%s'.", name.c_str(), fv.className());
}
return AttributeVector::SP();
}
@@ -761,14 +761,14 @@ void SearchVisitor::setupAttributeVector(const FieldPath &fieldPath) {
if (attr) {
LOG(debug, "Adding attribute '%s' for field '%s' with data type '%s' (%s)",
- attr->getName().c_str(), attrName.c_str(), fv.getDataType()->getName().c_str(), fv.getClass().name());
+ attr->getName().c_str(), attrName.c_str(), fv.getDataType()->getName().c_str(), fv.className());
if ( ! _attrMan.add(attr) ) {
LOG(warning, "Failed adding attribute '%s' for field '%s' with data type '%s' (%s)",
- attr->getName().c_str(), attrName.c_str(), fv.getDataType()->getName().c_str(), fv.getClass().name());
+ attr->getName().c_str(), attrName.c_str(), fv.getDataType()->getName().c_str(), fv.className());
}
} else {
LOG(debug, "Cannot setup attribute for field '%s' with data type '%s' (%s). Aggregation and sorting will not work for this field",
- attrName.c_str(), fv.getDataType()->getName().c_str(), fv.getClass().name());
+ attrName.c_str(), fv.getDataType()->getName().c_str(), fv.className());
}
}
diff --git a/tsan-suppressions.txt b/tsan-suppressions.txt
index a79340d887e..23b63b8945c 100644
--- a/tsan-suppressions.txt
+++ b/tsan-suppressions.txt
@@ -14,3 +14,5 @@ deadlock:proton::ImportedAttributesContext::getAttributeStableEnum
# creation and locking is not strictly enough ordered.
race:llvm::sys::MutexImpl
+race:llvm::sys::SmartMutex<false>::lock
+race:llvm::sys::SmartMutex<true>::lock
diff --git a/vdslib/src/vespa/vdslib/container/parameters.cpp b/vdslib/src/vespa/vdslib/container/parameters.cpp
index 85ba6318f7c..60527a00547 100644
--- a/vdslib/src/vespa/vdslib/container/parameters.cpp
+++ b/vdslib/src/vespa/vdslib/container/parameters.cpp
@@ -2,7 +2,6 @@
#include "parameters.hpp"
#include <vespa/document/util/bytebuffer.h>
-#include <vespa/vespalib/objects/nbostream.h>
#include <vespa/vespalib/objects/hexdump.h>
#include <vespa/vespalib/stllike/hash_map.hpp>
#include <vespa/vespalib/util/xmlstream.h>
@@ -60,7 +59,7 @@ void Parameters::deserialize(document::ByteBuffer& buffer)
}
void
-Parameters::printXml(document::XmlOutputStream& xos) const
+Parameters::printXml(vespalib::xml::XmlOutputStream& xos) const
{
using namespace vespalib::xml;
xos << XmlTag("parameters");
diff --git a/vdslib/src/vespa/vdslib/container/parameters.h b/vdslib/src/vespa/vdslib/container/parameters.h
index 34568cc85cb..41c95d14da4 100644
--- a/vdslib/src/vespa/vdslib/container/parameters.h
+++ b/vdslib/src/vespa/vdslib/container/parameters.h
@@ -14,7 +14,7 @@
#pragma once
-#include <vespa/document/util/xmlserializable.h>
+#include <vespa/vespalib/util/xmlserializable.h>
#include <vespa/vespalib/stllike/hash_map.h>
namespace vespalib { class GrowableByteBuffer; }
@@ -22,7 +22,7 @@ namespace document { class ByteBuffer; }
namespace vdslib {
-class Parameters : public document::XmlSerializable {
+class Parameters : public vespalib::xml::XmlSerializable {
public:
typedef vespalib::stringref KeyT;
class Value : public vespalib::string
@@ -39,7 +39,7 @@ public:
private:
ParametersMap _parameters;
- void printXml(document::XmlOutputStream& xos) const override;
+ void printXml(vespalib::xml::XmlOutputStream& xos) const override;
public:
Parameters();
diff --git a/vespamalloc/src/tests/test1/testatomic.cpp b/vespamalloc/src/tests/test1/testatomic.cpp
index 5ce52330f77..948616065e6 100644
--- a/vespamalloc/src/tests/test1/testatomic.cpp
+++ b/vespamalloc/src/tests/test1/testatomic.cpp
@@ -2,6 +2,7 @@
#include <vespa/vespalib/testkit/testapp.h>
#include <vespamalloc/malloc/allocchunk.h>
#include <vespamalloc/malloc/mmappool.h>
+#include <unistd.h>
TEST("verify lock freeness of atomics"){
{
@@ -23,29 +24,32 @@ TEST("verify lock freeness of atomics"){
TEST("test explicit mmap/munmap") {
vespamalloc::MMapPool mmapPool;
+ size_t page_size = getpagesize();
+ size_t mmap1_size = 3 * page_size;
+ size_t mmap2_size = 7 * page_size;
EXPECT_EQUAL(0u, mmapPool.getNumMappings());
EXPECT_EQUAL(0u, mmapPool.getMmappedBytes());
- void * mmap1 = mmapPool.mmap(0xe000);
+ void * mmap1 = mmapPool.mmap(mmap1_size);
EXPECT_EQUAL(1u, mmapPool.getNumMappings());
- EXPECT_EQUAL(0xe000u, mmapPool.getMmappedBytes());
- EXPECT_EQUAL(0xe000u, mmapPool.get_size(mmap1));
+ EXPECT_EQUAL(mmap1_size, mmapPool.getMmappedBytes());
+ EXPECT_EQUAL(mmap1_size, mmapPool.get_size(mmap1));
mmapPool.unmap(mmap1);
EXPECT_EQUAL(0u, mmapPool.getNumMappings());
EXPECT_EQUAL(0u, mmapPool.getMmappedBytes());
- mmap1 = mmapPool.mmap(0xe000);
+ mmap1 = mmapPool.mmap(mmap1_size);
EXPECT_EQUAL(1u, mmapPool.getNumMappings());
- EXPECT_EQUAL(0xe000u, mmapPool.getMmappedBytes());
- EXPECT_EQUAL(0xe000u, mmapPool.get_size(mmap1));
+ EXPECT_EQUAL(mmap1_size, mmapPool.getMmappedBytes());
+ EXPECT_EQUAL(mmap1_size, mmapPool.get_size(mmap1));
- void * mmap2 = mmapPool.mmap(0x1e000);
+ void * mmap2 = mmapPool.mmap(mmap2_size);
EXPECT_EQUAL(2u, mmapPool.getNumMappings());
- EXPECT_EQUAL(0x2c000u, mmapPool.getMmappedBytes());
- EXPECT_EQUAL(0xe000u, mmapPool.get_size(mmap1));
- EXPECT_EQUAL(0x1e000u, mmapPool.get_size(mmap2));
+ EXPECT_EQUAL(mmap1_size + mmap2_size, mmapPool.getMmappedBytes());
+ EXPECT_EQUAL(mmap1_size, mmapPool.get_size(mmap1));
+ EXPECT_EQUAL(mmap2_size, mmapPool.get_size(mmap2));
mmapPool.unmap(mmap1);
EXPECT_EQUAL(1u, mmapPool.getNumMappings());
- EXPECT_EQUAL(0x1e000u, mmapPool.getMmappedBytes());
+ EXPECT_EQUAL(mmap2_size, mmapPool.getMmappedBytes());
mmapPool.unmap(mmap2);
EXPECT_EQUAL(0u, mmapPool.getNumMappings());
EXPECT_EQUAL(0u, mmapPool.getMmappedBytes());
diff --git a/vsm/src/vespa/vsm/searcher/fieldsearcher.cpp b/vsm/src/vespa/vsm/searcher/fieldsearcher.cpp
index c587f9eadfb..e69999b160e 100644
--- a/vsm/src/vespa/vsm/searcher/fieldsearcher.cpp
+++ b/vsm/src/vespa/vsm/searcher/fieldsearcher.cpp
@@ -30,7 +30,7 @@ FieldSearcherBase::FieldSearcherBase() :
_qtl(),
_qtlFastBuffer(),
_qtlFastSize(0),
- _qtlFast(NULL)
+ _qtlFast(nullptr)
{
}
@@ -38,7 +38,7 @@ FieldSearcherBase::FieldSearcherBase(const FieldSearcherBase & org) :
_qtl(),
_qtlFastBuffer(),
_qtlFastSize(0),
- _qtlFast(NULL)
+ _qtlFast(nullptr)
{
prepare(org._qtl);
}
@@ -260,8 +260,7 @@ bool FieldSearcher::onSearch(const StorageDocument & doc)
bool retval(true);
size_t fNo(field());
const StorageDocument::SubDocument & sub = doc.getComplexField(fNo);
- if (sub.getFieldValue() != NULL) {
- LOG(spam, "onSearch %s : %s", sub.getFieldValue()->getClass().name(), sub.getFieldValue()->toString().c_str());
+ if (sub.getFieldValue() != nullptr) {
IteratorHandler ih(*this);
sub.getFieldValue()->iterateNested(sub.getRange(), ih);
}
@@ -282,10 +281,10 @@ FieldSearcher::IteratorHandler::onCollectionStart(const Content & c)
{
const document::FieldValue & fv = c.getValue();
LOG(spam, "onCollectionStart: field value '%s'", fv.toString().c_str());
- if (fv.inherits(document::ArrayFieldValue::classId)) {
+ if (fv.isA(document::FieldValue::Type::ARRAY)) {
const document::ArrayFieldValue & afv = static_cast<const document::ArrayFieldValue &>(fv);
LOG(spam, "onCollectionStart: Array size = '%zu'", afv.size());
- } else if (fv.inherits(document::WeightedSetFieldValue::classId)) {
+ } else if (fv.isA(document::FieldValue::Type::WSET)) {
const document::WeightedSetFieldValue & wsfv = static_cast<const document::WeightedSetFieldValue &>(fv);
LOG(spam, "onCollectionStart: WeightedSet size = '%zu'", wsfv.size());
}
diff --git a/vsm/src/vespa/vsm/vsm/docsumfilter.cpp b/vsm/src/vespa/vsm/vsm/docsumfilter.cpp
index a74e41dfb3f..bd16c687fc7 100644
--- a/vsm/src/vespa/vsm/vsm/docsumfilter.cpp
+++ b/vsm/src/vespa/vsm/vsm/docsumfilter.cpp
@@ -71,7 +71,7 @@ public:
StringResultHandler(ResType t, ResultPacker & p) : _type(t), _packer(p) {}
void onPrimitive(uint32_t, const Content & c) override {
const document::FieldValue & fv = c.getValue();
- if (fv.getClass().inherits(document::LiteralFieldValueB::classId)) {
+ if (fv.isLiteral()) {
const document::LiteralFieldValueB & lfv = static_cast<const document::LiteralFieldValueB &>(fv);
vespalib::stringref s = lfv.getValueRef();
addToPacker(s.data(), s.size());
diff --git a/vsm/src/vespa/vsm/vsm/flattendocsumwriter.cpp b/vsm/src/vespa/vsm/vsm/flattendocsumwriter.cpp
index 821434a4ed6..06b652d85e6 100644
--- a/vsm/src/vespa/vsm/vsm/flattendocsumwriter.cpp
+++ b/vsm/src/vespa/vsm/vsm/flattendocsumwriter.cpp
@@ -18,13 +18,12 @@ FlattenDocsumWriter::onPrimitive(uint32_t, const Content & c)
{
considerSeparator();
const document::FieldValue & fv = c.getValue();
- const auto & clazz = fv.getClass();
- if (clazz.inherits(document::LiteralFieldValueB::classId)) {
+ if (fv.isLiteral()) {
const document::LiteralFieldValueB & lfv = static_cast<const document::LiteralFieldValueB &>(fv);
vespalib::stringref value = lfv.getValueRef();
_output.put(value.data(), value.size());
- } else if (clazz.inherits(document::NumericFieldValueBase::classId) ||
- clazz.inherits(document::BoolFieldValue::classId))
+ } else if (fv.isNumeric() ||
+ fv.isA(document::FieldValue::Type::BOOL))
{
vespalib::string value = fv.getAsString();
_output.put(value.data(), value.size());
diff --git a/vsm/src/vespa/vsm/vsm/slimefieldwriter.cpp b/vsm/src/vespa/vsm/vsm/slimefieldwriter.cpp
index 405f2292f5d..5bc5798fb9d 100644
--- a/vsm/src/vespa/vsm/vsm/slimefieldwriter.cpp
+++ b/vsm/src/vespa/vsm/vsm/slimefieldwriter.cpp
@@ -48,13 +48,12 @@ namespace vsm {
void
SlimeFieldWriter::traverseRecursive(const document::FieldValue & fv, Inserter &inserter)
{
- const auto & clazz = fv.getClass();
LOG(debug, "traverseRecursive: class(%s), fieldValue(%s), currentPath(%s)",
- clazz.name(), fv.toString().c_str(), toString(_currPath).c_str());
+ fv.className(), fv.toString().c_str(), toString(_currPath).c_str());
- if (clazz.inherits(document::CollectionFieldValue::classId)) {
+ if (fv.isCollection()) {
const document::CollectionFieldValue & cfv = static_cast<const document::CollectionFieldValue &>(fv);
- if (cfv.inherits(document::ArrayFieldValue::classId)) {
+ if (cfv.isA(document::FieldValue::Type::ARRAY)) {
const document::ArrayFieldValue & afv = static_cast<const document::ArrayFieldValue &>(cfv);
Cursor &a = inserter.insertArray();
for (size_t i = 0; i < afv.size(); ++i) {
@@ -62,7 +61,8 @@ SlimeFieldWriter::traverseRecursive(const document::FieldValue & fv, Inserter &i
ArrayInserter ai(a);
traverseRecursive(nfv, ai);
}
- } else if (cfv.inherits(document::WeightedSetFieldValue::classId)) {
+ } else {
+ assert(cfv.isA(document::FieldValue::Type::WSET));
const document::WeightedSetFieldValue & wsfv = static_cast<const document::WeightedSetFieldValue &>(cfv);
Cursor &a = inserter.insertArray();
Symbol isym = a.resolve("item");
@@ -75,10 +75,8 @@ SlimeFieldWriter::traverseRecursive(const document::FieldValue & fv, Inserter &i
int weight = static_cast<const document::IntFieldValue &>(*entry.second).getValue();
o.setLong(wsym, weight);
}
- } else {
- LOG(warning, "traverseRecursive: Cannot handle collection field value of type '%s'", clazz.name());
}
- } else if (clazz.inherits(document::MapFieldValue::classId)) {
+ } else if (fv.isA(document::FieldValue::Type::MAP)) {
const document::MapFieldValue & mfv = static_cast<const document::MapFieldValue &>(fv);
Cursor &a = inserter.insertArray();
Symbol keysym = a.resolve("key");
@@ -92,7 +90,7 @@ SlimeFieldWriter::traverseRecursive(const document::FieldValue & fv, Inserter &i
traverseRecursive(*entry.second, vi);
_currPath.pop_back();
}
- } else if (clazz.inherits(document::StructuredFieldValue::classId)) {
+ } else if (fv.isStructured()) {
const document::StructuredFieldValue & sfv = static_cast<const document::StructuredFieldValue &>(fv);
Cursor &o = inserter.insertObject();
if (sfv.getDataType() == &document::PositionDataType::getInstance()
@@ -135,10 +133,10 @@ SlimeFieldWriter::traverseRecursive(const document::FieldValue & fv, Inserter &i
}
}
} else {
- if (clazz.inherits(document::LiteralFieldValueB::classId)) {
+ if (fv.isLiteral()) {
const document::LiteralFieldValueB & lfv = static_cast<const document::LiteralFieldValueB &>(fv);
inserter.insertString(lfv.getValueRef());
- } else if (clazz.inherits(document::NumericFieldValueBase::classId)) {
+ } else if (fv.isNumeric()) {
switch (fv.getDataType()->getId()) {
case document::DataType::T_BYTE:
case document::DataType::T_SHORT:
@@ -155,7 +153,7 @@ SlimeFieldWriter::traverseRecursive(const document::FieldValue & fv, Inserter &i
default:
inserter.insertString(fv.getAsString());
}
- } else if (clazz.inherits(document::BoolFieldValue::classId)) {
+ } else if (fv.isA(document::FieldValue::Type::BOOL)) {
const auto & bfv = static_cast<const document::BoolFieldValue &>(fv);
inserter.insertBool(bfv.getValue());
} else {