summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Musum <musum@verizonmedia.com>2020-10-12 07:43:17 +0200
committerHarald Musum <musum@verizonmedia.com>2020-10-12 07:43:17 +0200
commit99c036b9b5acafa0c3ea667132aaef4939c6fcf9 (patch)
tree7bd08ac6ec1a0f2c5aa7339867cc649bbce88ba9
parentf8cbda74df298dbe1c18dea3537251b5c0049a3a (diff)
parentc3f03aa13bfa7e34ae342df51fcfa043d11ea4d3 (diff)
Merge branch 'master' into hmusum/remove-unused-flag-7
-rw-r--r--build_settings.cmake2
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/FileRegistry.java1
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/ConfigChangeAction.java7
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/ServiceInfo.java5
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java2
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/derived/validation/Validator.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/AbstractService.java63
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/HostResource.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/Service.java37
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/LogserverContainer.java4
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/LogserverContainerCluster.java6
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/clustercontroller/ClusterControllerContainer.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/clustercontroller/ClusterControllerContainerCluster.java6
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsNodesConfigGenerator.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainer.java4
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerCluster.java6
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java7
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java26
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ChangeValidator.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidator.java5
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ConfigValueChangeValidator.java25
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ContainerRestartValidator.java27
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ContentClusterRemovalValidator.java3
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ContentTypeRemovalValidator.java3
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidator.java3
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexedSearchClusterChangeValidator.java7
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexingModeChangeValidator.java3
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/NodeResourceChangeValidator.java82
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidator.java5
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/StartupCommandChangeValidator.java17
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/StreamingSearchClusterChangeValidator.java39
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/VespaConfigChangeAction.java11
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/VespaRefeedAction.java16
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/VespaRestartAction.java20
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidator.java83
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidator.java43
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/DocumentTypeChangeValidator.java14
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidator.java11
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidator.java12
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java4
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/clients/ContainerDocumentApi.java4
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainer.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java10
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/Container.java12
-rwxr-xr-xconfig-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java24
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/ContainerThreadpool.java15
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/DefaultThreadpoolProvider.java52
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java21
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyHttpServerBuilder.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/SearchHandler.java4
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java25
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/content/storagecluster/StorageCluster.java17
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java2
-rw-r--r--config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java6
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ConfigChangeTestUtils.java30
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/IndexedSearchClusterChangeValidatorTest.java61
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/NodeResourceChangeValidatorTest.java129
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/StreamingSearchClusterChangeValidatorTest.java16
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidatorTest.java90
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidatorTest.java21
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/DocumentTypeChangeValidatorTest.java41
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidatorTest.java14
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidatorTestCase.java53
-rwxr-xr-xconfig-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java65
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/HostProvisionerWithCustomRealResource.java40
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerDocumentApiBuilderTest.java34
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/ProvisionLock.java32
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/Provisioner.java22
-rw-r--r--config/src/tests/api/api.cpp3
-rw-r--r--config/src/tests/configfetcher/configfetcher.cpp5
-rw-r--r--config/src/tests/configretriever/configretriever.cpp4
-rw-r--r--config/src/tests/configuri/configuri_test.cpp1
-rw-r--r--config/src/tests/failover/failover.cpp6
-rw-r--r--config/src/tests/file_subscription/file_subscription.cpp7
-rw-r--r--config/src/tests/getconfig/getconfig.cpp9
-rw-r--r--config/src/tests/raw_subscription/raw_subscription.cpp3
-rw-r--r--config/src/tests/unittest/unittest.cpp13
-rw-r--r--config/src/vespa/config/common/configcontext.cpp8
-rw-r--r--config/src/vespa/config/common/configcontext.h4
-rw-r--r--config/src/vespa/config/common/configholder.cpp18
-rw-r--r--config/src/vespa/config/common/configholder.h8
-rw-r--r--config/src/vespa/config/common/configmanager.cpp13
-rw-r--r--config/src/vespa/config/common/configmanager.h7
-rw-r--r--config/src/vespa/config/frt/frtconnection.h1
-rw-r--r--config/src/vespa/config/frt/frtsource.cpp7
-rw-r--r--config/src/vespa/config/frt/frtsource.h6
-rw-r--r--config/src/vespa/config/frt/protocol.cpp1
-rw-r--r--config/src/vespa/config/helper/configfetcher.cpp1
-rw-r--r--config/src/vespa/config/helper/legacysubscriber.hpp6
-rw-r--r--config/src/vespa/config/retriever/configretriever.cpp6
-rw-r--r--config/src/vespa/config/retriever/configretriever.h7
-rw-r--r--config/src/vespa/config/retriever/simpleconfigurer.cpp6
-rw-r--r--config/src/vespa/config/subscription/configsubscriber.cpp1
-rw-r--r--config/src/vespa/config/subscription/configsubscriber.h1
-rw-r--r--config/src/vespa/config/subscription/configsubscription.h3
-rw-r--r--config/src/vespa/config/subscription/configsubscriptionset.h5
-rw-r--r--config/src/vespa/config/subscription/sourcespec.cpp1
-rw-r--r--config/src/vespa/config/subscription/subscriptionid.h2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java24
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/metrics/ClusterDeploymentMetricsRetriever.java38
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/configchange/ConfigChangeActionsBuilder.java8
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java14
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/deploy/HostedDeployTest.java7
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/SessionHandlerTest.java16
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/MaintainerTester.java18
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java16
-rw-r--r--configutil/src/tests/config_status/config_status_test.cpp3
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java2
-rw-r--r--dist/vespa.spec6
-rw-r--r--docker-api/src/main/java/com/yahoo/vespa/hosted/dockerapi/DockerEngine.java1
-rw-r--r--document/src/vespa/document/base/field.h4
-rw-r--r--document/src/vespa/document/bucket/CMakeLists.txt1
-rw-r--r--document/src/vespa/document/bucket/bucketdistribution.cpp115
-rw-r--r--document/src/vespa/document/bucket/bucketdistribution.h136
-rw-r--r--document/src/vespa/document/datatype/positiondatatype.cpp14
-rw-r--r--document/src/vespa/document/datatype/positiondatatype.h4
-rw-r--r--document/src/vespa/document/datatype/urldatatype.cpp14
-rw-r--r--document/src/vespa/document/datatype/urldatatype.h4
-rw-r--r--document/src/vespa/document/repo/documenttyperepo.cpp5
-rw-r--r--document/src/vespa/document/repo/documenttyperepo.h4
-rw-r--r--document/src/vespa/document/repo/fixedtyperepo.cpp2
-rw-r--r--document/src/vespa/document/repo/fixedtyperepo.h8
-rw-r--r--document/src/vespa/document/select/valuenodes.cpp1
-rw-r--r--document/src/vespa/document/util/queue.h75
-rwxr-xr-xdocumentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/DocumentProtocol.java192
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/documentprotocol.cpp1
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/policies/asyncinitializationpolicy.cpp10
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/policies/asyncinitializationpolicy.h6
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/policies/documentrouteselectorpolicy.cpp6
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/policies/documentrouteselectorpolicy.h3
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/policies/externpolicy.cpp2
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/policies/externpolicy.h5
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/policies/externslobrokpolicy.cpp7
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/policies/externslobrokpolicy.h4
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/policies/localservicepolicy.cpp2
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/policies/localservicepolicy.h4
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/policies/roundrobinpolicy.cpp2
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/policies/roundrobinpolicy.h4
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/policies/storagepolicy.cpp1
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/policies/subsetservicepolicy.cpp2
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/policies/subsetservicepolicy.h7
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/routablerepository.cpp6
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/routablerepository.h10
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/routingpolicyrepository.cpp4
-rw-r--r--documentapi/src/vespa/documentapi/messagebus/routingpolicyrepository.h6
-rw-r--r--documentapi/test/crosslanguagefiles/6.221-cpp-MapVisitorMessage.datbin37 -> 37 bytes
-rw-r--r--eval/CMakeLists.txt5
-rw-r--r--eval/src/apps/tensor_conformance/tensor_conformance.cpp4
-rw-r--r--eval/src/tests/ann/hnsw-like.h2
-rw-r--r--eval/src/tests/ann/nns.h4
-rw-r--r--eval/src/tests/eval/fast_sparse_map/CMakeLists.txt9
-rw-r--r--eval/src/tests/eval/fast_sparse_map/fast_sparse_map_test.cpp (renamed from eval/src/tests/eval/simple_sparse_map/simple_sparse_map_test.cpp)57
-rw-r--r--eval/src/tests/eval/simple_sparse_map/CMakeLists.txt9
-rw-r--r--eval/src/tests/instruction/generic_concat/generic_concat_test.cpp92
-rw-r--r--eval/src/tests/instruction/generic_join/generic_join_test.cpp15
-rw-r--r--eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp2
-rw-r--r--eval/src/tests/tensor/dense_simple_join_function/dense_simple_join_function_test.cpp12
-rw-r--r--eval/src/tests/tensor/direct_dense_tensor_builder/direct_dense_tensor_builder_test.cpp5
-rw-r--r--eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp82
-rw-r--r--eval/src/tests/tensor/onnx_wrapper/onnx_wrapper_test.cpp6
-rw-r--r--eval/src/tests/tensor/partial_add/CMakeLists.txt9
-rw-r--r--eval/src/tests/tensor/partial_add/partial_add_test.cpp119
-rw-r--r--eval/src/tests/tensor/partial_modify/CMakeLists.txt9
-rw-r--r--eval/src/tests/tensor/partial_modify/partial_modify_test.cpp143
-rw-r--r--eval/src/tests/tensor/partial_remove/CMakeLists.txt9
-rw-r--r--eval/src/tests/tensor/partial_remove/partial_remove_test.cpp126
-rw-r--r--eval/src/tests/tensor/tensor_serialization/tensor_serialization_test.cpp1
-rw-r--r--eval/src/vespa/eval/eval/CMakeLists.txt3
-rw-r--r--eval/src/vespa/eval/eval/fast_sparse_map.cpp12
-rw-r--r--eval/src/vespa/eval/eval/fast_sparse_map.h153
-rw-r--r--eval/src/vespa/eval/eval/fast_value.cpp54
-rw-r--r--eval/src/vespa/eval/eval/fast_value.h28
-rw-r--r--eval/src/vespa/eval/eval/fast_value.hpp215
-rw-r--r--eval/src/vespa/eval/eval/simple_sparse_map.cpp12
-rw-r--r--eval/src/vespa/eval/eval/simple_sparse_map.h202
-rw-r--r--eval/src/vespa/eval/eval/simple_value.cpp115
-rw-r--r--eval/src/vespa/eval/eval/simple_value.h19
-rw-r--r--eval/src/vespa/eval/eval/tensor_spec.cpp11
-rw-r--r--eval/src/vespa/eval/eval/tensor_spec.h9
-rw-r--r--eval/src/vespa/eval/eval/value_codec.h3
-rw-r--r--eval/src/vespa/eval/instruction/generic_concat.cpp89
-rw-r--r--eval/src/vespa/eval/instruction/generic_concat.h9
-rw-r--r--eval/src/vespa/eval/instruction/generic_join.cpp90
-rw-r--r--eval/src/vespa/eval/instruction/generic_join.h22
-rw-r--r--eval/src/vespa/eval/tensor/CMakeLists.txt1
-rw-r--r--eval/src/vespa/eval/tensor/default_tensor_engine.cpp3
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_cell_range_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_dot_product_function.cpp12
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_generic_join.hpp12
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_lambda_peek_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_matmul_function.cpp12
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_multi_matmul_function.cpp8
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_number_join_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_replace_type_function.cpp7
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_simple_expand_function.cpp4
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_simple_join_function.cpp4
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_simple_map_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_tensor_peek_function.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp59
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_tensor_view.h6
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_xw_product_function.cpp12
-rw-r--r--eval/src/vespa/eval/tensor/dense/onnx_wrapper.cpp6
-rw-r--r--eval/src/vespa/eval/tensor/partial_update.cpp358
-rw-r--r--eval/src/vespa/eval/tensor/partial_update.h42
-rw-r--r--eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_ref.h2
-rw-r--r--eval/src/vespa/eval/tensor/wrapped_simple_tensor.cpp1
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/Flags.java13
-rw-r--r--fnet/src/tests/connect/connect_test.cpp1
-rw-r--r--fnet/src/tests/time/timespeed.cpp4
-rw-r--r--fnet/src/vespa/fnet/transport_thread.cpp1
-rw-r--r--fsa/src/vespa/fsa/fsa.h26
-rw-r--r--fsa/src/vespa/fsa/segmenter.h8
-rw-r--r--jdisc_http_service/abi-spec.json45
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLog.java50
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java4
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpResponseStatisticsCollector.java15
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscHttpServlet.java4
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscServerConnector.java8
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java150
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/MetricDefinitions.java71
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/RequestMetricReporter.java (renamed from jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/MetricReporter.java)46
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServerMetricReporter.java115
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletOutputStreamWriter.java4
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletRequestReader.java4
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletResponseController.java2
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/SslHandshakeFailedListener.java19
-rw-r--r--jdisc_http_service/src/main/resources/configdefinitions/jdisc.http.jdisc.http.server.def8
-rw-r--r--jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLogTest.java22
-rw-r--r--jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpResponseStatisticsCollectorTest.java39
-rw-r--r--jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java11
-rw-r--r--logd/src/tests/empty_forwarder/empty_forwarder_test.cpp2
-rw-r--r--logd/src/tests/rpc_forwarder/rpc_forwarder_test.cpp2
-rw-r--r--logd/src/tests/watcher/watcher_test.cpp1
-rw-r--r--messagebus/src/main/java/com/yahoo/messagebus/ErrorCode.java4
-rw-r--r--messagebus/src/main/java/com/yahoo/messagebus/Protocol.java33
-rw-r--r--messagebus/src/vespa/messagebus/messagebus.cpp13
-rw-r--r--messagebus/src/vespa/messagebus/messagebus.h3
-rw-r--r--messagebus/src/vespa/messagebus/network/rpcnetwork.cpp2
-rw-r--r--messagebus/src/vespa/messagebus/network/rpcnetwork.h4
-rw-r--r--messagebus/src/vespa/messagebus/network/rpctargetpool.h1
-rw-r--r--messagebus/src/vespa/messagebus/protocolrepository.cpp5
-rw-r--r--messagebus/src/vespa/messagebus/protocolrepository.h4
-rw-r--r--messagebus/src/vespa/messagebus/routing/resender.h1
-rw-r--r--messagebus/src/vespa/messagebus/routing/routingnode.cpp1
-rw-r--r--messagebus/src/vespa/messagebus/routing/routingnode.h1
-rw-r--r--messagebus/src/vespa/messagebus/sequencer.cpp7
-rw-r--r--messagebus/src/vespa/messagebus/sequencer.h6
-rw-r--r--messagebus_test/src/tests/speed/cpp-client.cpp8
-rw-r--r--metrics-proxy/src/main/java/ai/vespa/metricsproxy/rpc/RpcConnector.java6
-rw-r--r--metrics/src/vespa/metrics/metricmanager.cpp1
-rw-r--r--metrics/src/vespa/metrics/metricsnapshot.cpp3
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java2
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java18
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java17
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Applications.java10
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java17
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java6
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirer.java15
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporter.java1
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailer.java9
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java24
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java25
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImpl.java16
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java53
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java28
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/LocksResponse.java1
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockDeployer.java10
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java8
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockProvisioner.java19
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/applications/ApplicationsTest.java13
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java16
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirerTest.java8
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirerTest.java9
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporterTest.java1
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java8
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RebalancerTest.java3
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirerTest.java8
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImplTest.java20
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java26
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java12
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java28
-rw-r--r--persistence/src/vespa/persistence/dummyimpl/dummypersistence.cpp1
-rw-r--r--persistence/src/vespa/persistence/spi/bucket.h2
-rw-r--r--persistencetypes/src/persistence/spi/types.h8
-rw-r--r--searchcommon/src/vespa/searchcommon/attribute/iattributevector.h4
-rw-r--r--searchcore/src/apps/verify_ranksetup/verify_ranksetup.cpp3
-rw-r--r--searchcore/src/apps/vespa-feed-bm/bm_storage_link_context.h2
-rw-r--r--searchcore/src/apps/vespa-feed-bm/vespa_feed_bm.cpp1
-rw-r--r--searchcore/src/tests/proton/attribute/attribute_test.cpp27
-rw-r--r--searchcore/src/tests/proton/attribute/imported_attributes_context/imported_attributes_context_test.cpp4
-rw-r--r--searchcore/src/tests/proton/attribute/imported_attributes_repo/imported_attributes_repo_test.cpp5
-rw-r--r--searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp1
-rw-r--r--searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp15
-rw-r--r--searchcore/src/tests/proton/documentdb/lid_space_compaction/lid_space_compaction_test.cpp5
-rw-r--r--searchcore/src/tests/proton/documentdb/maintenancecontroller/maintenancecontroller_test.cpp2
-rw-r--r--searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp4
-rw-r--r--searchcore/src/tests/proton/documentmetastore/documentmetastore_test.cpp2
-rw-r--r--searchcore/src/tests/proton/flushengine/flushengine_test.cpp4
-rw-r--r--searchcore/src/tests/proton/flushengine/prepare_restart_flush_strategy/prepare_restart_flush_strategy_test.cpp6
-rw-r--r--searchcore/src/tests/proton/flushengine/shrink_lid_space_flush_target/shrink_lid_space_flush_target_test.cpp16
-rw-r--r--searchcore/src/tests/proton/matching/matching_test.cpp2
-rw-r--r--searchcore/src/tests/proton/proton_config_fetcher/proton_config_fetcher_test.cpp3
-rw-r--r--searchcore/src/tests/proton/reference/document_db_reference_resolver/document_db_reference_resolver_test.cpp2
-rw-r--r--searchcore/src/tests/proton/reference/gid_to_lid_change_handler/gid_to_lid_change_handler_test.cpp2
-rw-r--r--searchcore/src/tests/proton/reprocessing/reprocessing_runner/reprocessing_runner_test.cpp46
-rw-r--r--searchcore/src/tests/proton/server/feedstates_test.cpp2
-rw-r--r--searchcore/src/tests/proton/server/memoryflush/memoryflush_test.cpp29
-rw-r--r--searchcore/src/vespa/searchcore/config/proton.def2
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/attribute_populator.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/doctypename.cpp4
-rw-r--r--searchcore/src/vespa/searchcore/proton/common/doctypename.h6
-rw-r--r--searchcore/src/vespa/searchcore/proton/documentmetastore/gid_compare.h7
-rw-r--r--searchcore/src/vespa/searchcore/proton/flushengine/iflushhandler.h2
-rw-r--r--searchcore/src/vespa/searchcore/proton/initializer/task_runner.h2
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/partial_result.h3
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/sessionmanager.h2
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/documentdbconfigmanager.cpp1
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/feedstates.h4
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/move_operation_limiter.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/packetwrapper.h3
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/rpc_hooks.cpp4
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/threading_service_config.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/test/document_meta_store_observer.h51
-rw-r--r--searchcore/src/vespa/searchcore/proton/test/dummy_flush_handler.h19
-rw-r--r--searchcore/src/vespa/searchcore/proton/test/dummy_flush_target.h30
-rw-r--r--searchcore/src/vespa/searchcore/proton/test/mock_gid_to_lid_change_handler.h4
-rw-r--r--searchcore/src/vespa/searchcore/proton/test/thread_utils.h12
-rw-r--r--searchcorespi/CMakeLists.txt4
-rw-r--r--searchcorespi/src/tests/plugin/.gitignore5
-rw-r--r--searchcorespi/src/tests/plugin/CMakeLists.txt32
-rw-r--r--searchcorespi/src/tests/plugin/empty.cpp1
-rw-r--r--searchcorespi/src/tests/plugin/factoryregistry_test.cpp59
-rw-r--r--searchcorespi/src/tests/plugin/plugin.cpp78
-rw-r--r--searchcorespi/src/tests/plugin/plugin_test.cpp37
-rw-r--r--searchcorespi/src/vespa/searchcorespi/CMakeLists.txt1
-rw-r--r--searchcorespi/src/vespa/searchcorespi/flush/iflushtarget.h10
-rw-r--r--searchcorespi/src/vespa/searchcorespi/index/activediskindexes.cpp14
-rw-r--r--searchcorespi/src/vespa/searchcorespi/index/activediskindexes.h18
-rw-r--r--searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.cpp5
-rw-r--r--searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.h28
-rw-r--r--searchcorespi/src/vespa/searchcorespi/plugin/.gitignore2
-rw-r--r--searchcorespi/src/vespa/searchcorespi/plugin/CMakeLists.txt7
-rw-r--r--searchcorespi/src/vespa/searchcorespi/plugin/factoryloader.cpp32
-rw-r--r--searchcorespi/src/vespa/searchcorespi/plugin/factoryloader.h26
-rw-r--r--searchcorespi/src/vespa/searchcorespi/plugin/factoryregistry.cpp54
-rw-r--r--searchcorespi/src/vespa/searchcorespi/plugin/factoryregistry.h50
-rw-r--r--searchcorespi/src/vespa/searchcorespi/plugin/iindexmanagerfactory.h76
-rw-r--r--searchlib/src/apps/vespa-ranking-expression-analyzer/vespa-ranking-expression-analyzer.cpp5
-rw-r--r--searchlib/src/tests/attribute/posting_list_merger/posting_list_merger_test.cpp12
-rw-r--r--searchlib/src/tests/attribute/searchable/attribute_searchable_adapter_test.cpp9
-rw-r--r--searchlib/src/tests/docstore/file_chunk/file_chunk_test.cpp28
-rw-r--r--searchlib/src/tests/expression/attributenode/attribute_node_test.cpp2
-rw-r--r--searchlib/src/tests/memoryindex/field_index_remover/field_index_remover_test.cpp4
-rw-r--r--searchlib/src/tests/query/querybuilder_test.cpp4
-rw-r--r--searchlib/src/tests/queryeval/predicate/predicate_blueprint_test.cpp8
-rw-r--r--searchlib/src/tests/transactionlog/chunks_test.cpp2
-rw-r--r--searchlib/src/tests/transactionlog/translogclient_test.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.h10
-rw-r--r--searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/attribute/interlock.h12
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multivalue.h13
-rw-r--r--searchlib/src/vespa/searchlib/bitcompression/posocc_field_params.cpp1
-rw-r--r--searchlib/src/vespa/searchlib/common/gatecallback.h4
-rw-r--r--searchlib/src/vespa/searchlib/common/lid_usage_stats.h4
-rw-r--r--searchlib/src/vespa/searchlib/common/rankedhit.h14
-rw-r--r--searchlib/src/vespa/searchlib/common/scheduletaskcallback.h10
-rw-r--r--searchlib/src/vespa/searchlib/common/tunefileinfo.h22
-rw-r--r--searchlib/src/vespa/searchlib/diskindex/zc4_posting_writer_base.h2
-rw-r--r--searchlib/src/vespa/searchlib/docstore/compacter.h2
-rw-r--r--searchlib/src/vespa/searchlib/docstore/filechunk.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/docstore/filechunk.h13
-rw-r--r--searchlib/src/vespa/searchlib/docstore/lid_info.h17
-rw-r--r--searchlib/src/vespa/searchlib/docstore/logdatastore.cpp7
-rw-r--r--searchlib/src/vespa/searchlib/docstore/logdatastore.h31
-rw-r--r--searchlib/src/vespa/searchlib/docstore/randreaders.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/docstore/randreaders.h2
-rw-r--r--searchlib/src/vespa/searchlib/docstore/storebybucket.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/docstore/storebybucket.h13
-rw-r--r--searchlib/src/vespa/searchlib/docstore/visitcache.cpp5
-rw-r--r--searchlib/src/vespa/searchlib/docstore/visitcache.h8
-rw-r--r--searchlib/src/vespa/searchlib/docstore/writeablefilechunk.cpp31
-rw-r--r--searchlib/src/vespa/searchlib/docstore/writeablefilechunk.h7
-rw-r--r--searchlib/src/vespa/searchlib/engine/docsumreply.h6
-rw-r--r--searchlib/src/vespa/searchlib/engine/docsumrequest.h4
-rw-r--r--searchlib/src/vespa/searchlib/engine/searchreply.h8
-rw-r--r--searchlib/src/vespa/searchlib/features/array_parser.h2
-rw-r--r--searchlib/src/vespa/searchlib/features/bm25_feature.h2
-rw-r--r--searchlib/src/vespa/searchlib/features/fieldmatch/computer.h2
-rw-r--r--searchlib/src/vespa/searchlib/fef/rank_program.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/fef/tablemanager.cpp23
-rw-r--r--searchlib/src/vespa/searchlib/fef/tablemanager.h13
-rw-r--r--searchlib/src/vespa/searchlib/fef/termmatchdatamerger.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/fef/termmatchdatamerger.h22
-rw-r--r--searchlib/src/vespa/searchlib/grouping/hyperloglog.h2
-rw-r--r--searchlib/src/vespa/searchlib/grouping/sketch.h14
-rw-r--r--searchlib/src/vespa/searchlib/index/docidandfeatures.h18
-rw-r--r--searchlib/src/vespa/searchlib/index/schemautil.cpp1
-rw-r--r--searchlib/src/vespa/searchlib/index/uri_field.cpp1
-rw-r--r--searchlib/src/vespa/searchlib/memoryindex/field_index_remover.h8
-rw-r--r--searchlib/src/vespa/searchlib/memoryindex/field_inverter.h7
-rw-r--r--searchlib/src/vespa/searchlib/memoryindex/memory_index.cpp5
-rw-r--r--searchlib/src/vespa/searchlib/memoryindex/memory_index.h14
-rw-r--r--searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/predicate/predicate_tree_analyzer.cpp1
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/hit.h2
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/predicate_query_term.h10
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/queryreplicator.h2
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/global_filter.h6
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/sourceblendersearch.h2
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/wand/wand_parts.h11
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/wand/weak_and_heap.cpp4
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/wand/weak_and_heap.h4
-rw-r--r--searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/tensor/hnsw_index_utils.h4
-rw-r--r--searchlib/src/vespa/searchlib/tensor/nearest_neighbor_index.h6
-rw-r--r--searchlib/src/vespa/searchlib/test/imported_attribute_fixture.h2
-rw-r--r--searchlib/src/vespa/searchlib/transactionlog/client_session.cpp4
-rw-r--r--searchlib/src/vespa/searchlib/transactionlog/domain.cpp60
-rw-r--r--searchlib/src/vespa/searchlib/transactionlog/domain.h14
-rw-r--r--searchlib/src/vespa/searchlib/transactionlog/domainpart.cpp24
-rw-r--r--searchlib/src/vespa/searchlib/transactionlog/domainpart.h10
-rw-r--r--searchlib/src/vespa/searchlib/transactionlog/session.cpp3
-rw-r--r--searchlib/src/vespa/searchlib/transactionlog/session.h1
-rw-r--r--searchlib/src/vespa/searchlib/transactionlog/translogclient.h4
-rw-r--r--slobrok/src/tests/configure/configure.cpp4
-rw-r--r--slobrok/src/tests/mirrorapi/mirrorapi.cpp2
-rw-r--r--slobrok/src/vespa/slobrok/cfg.h4
-rw-r--r--slobrok/src/vespa/slobrok/sblist.cpp4
-rw-r--r--slobrok/src/vespa/slobrok/sblist.h3
-rw-r--r--slobrok/src/vespa/slobrok/sbmirror.cpp6
-rw-r--r--slobrok/src/vespa/slobrok/sbmirror.h2
-rw-r--r--staging_vespalib/CMakeLists.txt1
-rw-r--r--staging_vespalib/src/tests/librarypool/.gitignore1
-rw-r--r--staging_vespalib/src/tests/librarypool/CMakeLists.txt8
-rw-r--r--staging_vespalib/src/tests/librarypool/librarypool_test.cpp38
-rw-r--r--staging_vespalib/src/tests/metrics/mock_tick.h9
-rw-r--r--staging_vespalib/src/tests/polymorphicarray/polymorphicarray_test.cpp6
-rw-r--r--staging_vespalib/src/tests/sequencedtaskexecutor/adaptive_sequenced_executor_test.cpp2
-rw-r--r--staging_vespalib/src/tests/sequencedtaskexecutor/foregroundtaskexecutor_test.cpp2
-rw-r--r--staging_vespalib/src/tests/sequencedtaskexecutor/sequencedtaskexecutor_test.cpp2
-rw-r--r--staging_vespalib/src/vespa/vespalib/metrics/dummy_metrics_manager.cpp8
-rw-r--r--staging_vespalib/src/vespa/vespalib/metrics/dummy_metrics_manager.h10
-rw-r--r--staging_vespalib/src/vespa/vespalib/net/simple_component_config_producer.cpp13
-rw-r--r--staging_vespalib/src/vespa/vespalib/net/simple_component_config_producer.h5
-rw-r--r--staging_vespalib/src/vespa/vespalib/net/simple_health_producer.cpp11
-rw-r--r--staging_vespalib/src/vespa/vespalib/net/simple_health_producer.h6
-rw-r--r--staging_vespalib/src/vespa/vespalib/net/simple_metrics_producer.cpp12
-rw-r--r--staging_vespalib/src/vespa/vespalib/net/simple_metrics_producer.h10
-rw-r--r--staging_vespalib/src/vespa/vespalib/objects/identifiable.hpp10
-rw-r--r--staging_vespalib/src/vespa/vespalib/stllike/cache.h18
-rw-r--r--staging_vespalib/src/vespa/vespalib/stllike/cache.hpp49
-rw-r--r--staging_vespalib/src/vespa/vespalib/util/CMakeLists.txt1
-rw-r--r--staging_vespalib/src/vespa/vespalib/util/document_runnable.cpp1
-rw-r--r--staging_vespalib/src/vespa/vespalib/util/librarypool.cpp58
-rw-r--r--staging_vespalib/src/vespa/vespalib/util/librarypool.h39
-rw-r--r--staging_vespalib/src/vespa/vespalib/util/scheduledexecutor.cpp8
-rw-r--r--staging_vespalib/src/vespa/vespalib/util/scheduledexecutor.h5
-rw-r--r--staging_vespalib/src/vespa/vespalib/util/singleexecutor.cpp2
-rw-r--r--staging_vespalib/src/vespa/vespalib/util/varholder.h10
-rw-r--r--storage/src/tests/bucketdb/lockablemaptest.cpp2
-rw-r--r--storage/src/tests/common/dummystoragelink.cpp14
-rw-r--r--storage/src/tests/common/dummystoragelink.h16
-rw-r--r--storage/src/tests/common/teststorageapp.cpp52
-rw-r--r--storage/src/tests/common/teststorageapp.h8
-rw-r--r--storage/src/tests/persistence/filestorage/filestormanagertest.cpp20
-rw-r--r--storage/src/tests/persistence/persistencetestutils.h2
-rw-r--r--storage/src/tests/storageserver/mergethrottlertest.cpp2
-rw-r--r--storage/src/tests/storageserver/rpc/storage_api_rpc_service_test.cpp4
-rw-r--r--storage/src/tests/storageserver/testvisitormessagesession.h9
-rw-r--r--storage/src/tests/visiting/visitormanagertest.cpp2
-rw-r--r--storage/src/tests/visiting/visitortest.cpp4
-rw-r--r--storage/src/vespa/storage/bucketdb/abstract_bucket_map.h14
-rw-r--r--storage/src/vespa/storage/bucketdb/bucketcopy.h4
-rw-r--r--storage/src/vespa/storage/bucketdb/lockablemap.hpp2
-rw-r--r--storage/src/vespa/storage/common/distributorcomponent.h7
-rw-r--r--storage/src/vespa/storage/common/servicelayercomponent.h2
-rw-r--r--storage/src/vespa/storage/common/storagelinkqueued.hpp1
-rw-r--r--storage/src/vespa/storage/distributor/distributor.cpp12
-rw-r--r--storage/src/vespa/storage/distributor/distributor.h4
-rw-r--r--storage/src/vespa/storage/distributor/distributorcomponent.h1
-rw-r--r--storage/src/vespa/storage/distributor/messageguard.h6
-rw-r--r--storage/src/vespa/storage/distributor/messagetracker.h2
-rw-r--r--storage/src/vespa/storage/distributor/operation_sequencer.h2
-rw-r--r--storage/src/vespa/storage/distributor/operations/external/statbucketlistoperation.h1
-rw-r--r--storage/src/vespa/storage/distributor/operations/external/updateoperation.h2
-rw-r--r--storage/src/vespa/storage/distributor/operations/idealstate/mergemetadata.h14
-rw-r--r--storage/src/vespa/storage/distributor/sentmessagemap.h9
-rw-r--r--storage/src/vespa/storage/frameworkimpl/component/distributorcomponentregisterimpl.cpp12
-rw-r--r--storage/src/vespa/storage/frameworkimpl/component/distributorcomponentregisterimpl.h2
-rw-r--r--storage/src/vespa/storage/frameworkimpl/component/servicelayercomponentregisterimpl.cpp4
-rw-r--r--storage/src/vespa/storage/frameworkimpl/component/servicelayercomponentregisterimpl.h2
-rw-r--r--storage/src/vespa/storage/frameworkimpl/component/storagecomponentregisterimpl.cpp20
-rw-r--r--storage/src/vespa/storage/frameworkimpl/component/storagecomponentregisterimpl.h14
-rw-r--r--storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.cpp52
-rw-r--r--storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.h41
-rw-r--r--storage/src/vespa/storage/persistence/filestorage/filestormanager.cpp2
-rw-r--r--storage/src/vespa/storage/persistence/filestorage/filestormetrics.cpp41
-rw-r--r--storage/src/vespa/storage/persistence/filestorage/filestormetrics.h24
-rw-r--r--storage/src/vespa/storage/persistence/filestorage/modifiedbucketchecker.cpp10
-rw-r--r--storage/src/vespa/storage/persistence/filestorage/modifiedbucketchecker.h2
-rw-r--r--storage/src/vespa/storage/persistence/persistencethread.cpp5
-rw-r--r--storage/src/vespa/storage/persistence/persistenceutil.cpp18
-rw-r--r--storage/src/vespa/storage/persistence/persistenceutil.h3
-rw-r--r--storage/src/vespa/storage/storageserver/bouncer.cpp6
-rw-r--r--storage/src/vespa/storage/storageserver/bouncer.h5
-rw-r--r--storage/src/vespa/storage/storageserver/changedbucketownershiphandler.cpp8
-rw-r--r--storage/src/vespa/storage/storageserver/changedbucketownershiphandler.h5
-rw-r--r--storage/src/vespa/storage/storageserver/communicationmanager.cpp4
-rw-r--r--storage/src/vespa/storage/storageserver/communicationmanager.h4
-rw-r--r--storage/src/vespa/storage/storageserver/configurable_bucket_resolver.h2
-rw-r--r--storage/src/vespa/storage/storageserver/mergethrottler.cpp11
-rw-r--r--storage/src/vespa/storage/storageserver/mergethrottler.h4
-rw-r--r--storage/src/vespa/storage/storageserver/opslogger.cpp10
-rw-r--r--storage/src/vespa/storage/storageserver/opslogger.h9
-rw-r--r--storage/src/vespa/storage/storageserver/priorityconverter.cpp4
-rw-r--r--storage/src/vespa/storage/storageserver/priorityconverter.h8
-rw-r--r--storage/src/vespa/storage/storageserver/rpc/shared_rpc_resources.cpp4
-rw-r--r--storage/src/vespa/storage/storageserver/service_layer_error_listener.h2
-rw-r--r--storage/src/vespa/storage/storageserver/servicelayernode.cpp2
-rw-r--r--storage/src/vespa/storage/storageserver/statemanager.cpp8
-rw-r--r--storage/src/vespa/storage/storageserver/statemanager.h2
-rw-r--r--storage/src/vespa/storage/storageserver/storagenode.cpp18
-rw-r--r--storage/src/vespa/storage/storageserver/storagenode.h2
-rw-r--r--storage/src/vespa/storage/visiting/recoveryvisitor.cpp4
-rw-r--r--storage/src/vespa/storage/visiting/recoveryvisitor.h2
-rw-r--r--storage/src/vespa/storage/visiting/visitor.cpp1
-rw-r--r--storage/src/vespa/storage/visiting/visitormanager.cpp3
-rw-r--r--storage/src/vespa/storage/visiting/visitormanager.h5
-rw-r--r--storageapi/src/vespa/storageapi/buckets/bucketinfo.cpp16
-rw-r--r--storageapi/src/vespa/storageapi/buckets/bucketinfo.h14
-rw-r--r--storageapi/src/vespa/storageapi/defs.h4
-rw-r--r--storageapi/src/vespa/storageapi/message/bucket.h6
-rw-r--r--storageapi/src/vespa/storageapi/message/visitor.h12
-rw-r--r--storageapi/src/vespa/storageapi/messageapi/storagemessage.cpp1
-rw-r--r--storageframework/src/vespa/storageframework/defaultimplementation/clock/fakeclock.h26
-rw-r--r--storageframework/src/vespa/storageframework/defaultimplementation/component/componentregisterimpl.cpp21
-rw-r--r--storageframework/src/vespa/storageframework/defaultimplementation/component/componentregisterimpl.h3
-rw-r--r--storageframework/src/vespa/storageframework/defaultimplementation/component/testcomponentregister.cpp1
-rw-r--r--storageframework/src/vespa/storageframework/defaultimplementation/thread/threadpoolimpl.cpp10
-rw-r--r--storageframework/src/vespa/storageframework/defaultimplementation/thread/threadpoolimpl.h5
-rw-r--r--storageframework/src/vespa/storageframework/generic/component/component.cpp1
-rw-r--r--storageframework/src/vespa/storageframework/generic/component/component.h1
-rw-r--r--storageframework/src/vespa/storageframework/generic/thread/tickingthread.cpp3
-rw-r--r--storageframework/src/vespa/storageframework/generic/thread/tickingthread.h1
-rw-r--r--streamingvisitors/src/vespa/searchvisitor/matching_elements_filler.cpp2
-rw-r--r--streamingvisitors/src/vespa/searchvisitor/searchenvironment.cpp6
-rw-r--r--streamingvisitors/src/vespa/searchvisitor/searchenvironment.h4
-rw-r--r--streamingvisitors/src/vespa/searchvisitor/searchvisitor.h4
-rw-r--r--vbench/src/apps/vbench/vbench.cpp1
-rw-r--r--vbench/src/tests/http_connection_pool/http_connection_pool_test.cpp1
-rw-r--r--vbench/src/tests/time_queue/time_queue_test.cpp1
-rw-r--r--vbench/src/vbench/core/dispatcher.h7
-rw-r--r--vbench/src/vbench/core/dispatcher.hpp10
-rw-r--r--vbench/src/vbench/core/time_queue.h9
-rw-r--r--vbench/src/vbench/core/time_queue.hpp3
-rw-r--r--vbench/src/vbench/http/http_connection_pool.cpp4
-rw-r--r--vbench/src/vbench/http/http_connection_pool.h3
-rw-r--r--vbench/src/vbench/vbench/request_scheduler.h1
-rw-r--r--vdslib/CMakeLists.txt1
-rw-r--r--vdslib/src/tests/CMakeLists.txt1
-rw-r--r--vdslib/src/tests/bucketdistribution/.gitignore3
-rw-r--r--vdslib/src/tests/bucketdistribution/CMakeLists.txt8
-rw-r--r--vdslib/src/tests/bucketdistribution/bucketdistributiontest.cpp92
-rw-r--r--vdslib/src/tests/thread/taskschedulertest.cpp11
-rw-r--r--vdslib/src/vespa/vdslib/CMakeLists.txt1
-rw-r--r--vdslib/src/vespa/vdslib/bucketdistribution.cpp119
-rw-r--r--vdslib/src/vespa/vdslib/bucketdistribution.h123
-rw-r--r--vdslib/src/vespa/vdslib/distribution/distribution.cpp1
-rw-r--r--vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/DocumentOperationExecutorImpl.java22
-rw-r--r--vespaclient-container-plugin/src/main/resources/configdefinitions/document-operation-executor.def2
-rw-r--r--vespaclient/src/vespa/vespaclient/vdsstates/statesapp.cpp4
-rw-r--r--vespalib/CMakeLists.txt2
-rw-r--r--vespalib/src/tests/datastore/unique_store_dictionary/unique_store_dictionary_test.cpp2
-rw-r--r--vespalib/src/tests/delegatelist/.cvsignore3
-rw-r--r--vespalib/src/tests/delegatelist/.gitignore4
-rw-r--r--vespalib/src/tests/delegatelist/CMakeLists.txt8
-rw-r--r--vespalib/src/tests/delegatelist/delegatelist.cpp824
-rw-r--r--vespalib/src/tests/detect_type_benchmark/detect_type_benchmark.cpp2
-rw-r--r--vespalib/src/tests/executor/blocking_executor_stress.cpp3
-rw-r--r--vespalib/src/tests/executor/blockingthreadstackexecutor_test.cpp1
-rw-r--r--vespalib/src/tests/executor/threadstackexecutor_test.cpp1
-rw-r--r--vespalib/src/tests/explore_modern_cpp/explore_modern_cpp_test.cpp2
-rw-r--r--vespalib/src/tests/net/async_resolver/async_resolver_test.cpp5
-rw-r--r--vespalib/src/tests/portal/portal_test.cpp2
-rw-r--r--vespalib/src/tests/priority_queue/priority_queue_test.cpp10
-rw-r--r--vespalib/src/tests/rwlock/.gitignore4
-rw-r--r--vespalib/src/tests/rwlock/CMakeLists.txt8
-rw-r--r--vespalib/src/tests/rwlock/rwlock_test.cpp78
-rw-r--r--vespalib/src/tests/simple_thread_bundle/simple_thread_bundle_test.cpp1
-rw-r--r--vespalib/src/tests/stllike/hash_test.cpp14
-rw-r--r--vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp16
-rw-r--r--vespalib/src/tests/sync/sync_test.cpp179
-rw-r--r--vespalib/src/tests/time_tracer/time_tracer_test.cpp4
-rw-r--r--vespalib/src/tests/util/generationhandler_stress/generation_handler_stress_test.cpp2
-rw-r--r--vespalib/src/vespa/vespalib/btree/btree_key_data.h8
-rw-r--r--vespalib/src/vespa/vespalib/data/databuffer.cpp2
-rw-r--r--vespalib/src/vespa/vespalib/data/databuffer.h10
-rw-r--r--vespalib/src/vespa/vespalib/data/memorydatastore.cpp3
-rw-r--r--vespalib/src/vespa/vespalib/data/memorydatastore.h6
-rw-r--r--vespalib/src/vespa/vespalib/data/slime/json_format.cpp1
-rw-r--r--vespalib/src/vespa/vespalib/data/slime/slime.h2
-rw-r--r--vespalib/src/vespa/vespalib/datastore/entryref.h26
-rw-r--r--vespalib/src/vespa/vespalib/datastore/entryref.hpp2
-rw-r--r--vespalib/src/vespa/vespalib/net/socket_address.h2
-rw-r--r--vespalib/src/vespa/vespalib/portal/portal.h2
-rw-r--r--vespalib/src/vespa/vespalib/portal/reactor.h2
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hash_fun.cpp8
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hash_fun.h48
-rw-r--r--vespalib/src/vespa/vespalib/stllike/string.h2
-rw-r--r--vespalib/src/vespa/vespalib/testkit/test_hook.h1
-rw-r--r--vespalib/src/vespa/vespalib/testkit/test_master.cpp37
-rw-r--r--vespalib/src/vespa/vespalib/testkit/test_master.h19
-rw-r--r--vespalib/src/vespa/vespalib/testkit/test_master.hpp2
-rw-r--r--vespalib/src/vespa/vespalib/util/CMakeLists.txt2
-rw-r--r--vespalib/src/vespa/vespalib/util/alloc.cpp13
-rw-r--r--vespalib/src/vespa/vespalib/util/alloc.h14
-rw-r--r--vespalib/src/vespa/vespalib/util/arrayqueue.hpp15
-rw-r--r--vespalib/src/vespa/vespalib/util/child_process.cpp11
-rw-r--r--vespalib/src/vespa/vespalib/util/compressionconfig.h8
-rw-r--r--vespalib/src/vespa/vespalib/util/count_down_latch.h2
-rw-r--r--vespalib/src/vespa/vespalib/util/delegatelist.hpp309
-rw-r--r--vespalib/src/vespa/vespalib/util/gate.h2
-rw-r--r--vespalib/src/vespa/vespalib/util/memory.h18
-rw-r--r--vespalib/src/vespa/vespalib/util/ptrholder.h14
-rw-r--r--vespalib/src/vespa/vespalib/util/rwlock.cpp42
-rw-r--r--vespalib/src/vespa/vespalib/util/rwlock.h250
-rw-r--r--vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp7
-rw-r--r--vespalib/src/vespa/vespalib/util/simple_thread_bundle.h7
-rw-r--r--vespalib/src/vespa/vespalib/util/sync.cpp99
-rw-r--r--vespalib/src/vespa/vespalib/util/sync.h276
-rw-r--r--vespalib/src/vespa/vespalib/util/thread.cpp1
-rw-r--r--vespalib/src/vespa/vespalib/util/zstdcompressor.cpp2
-rw-r--r--vsm/src/vespa/vsm/vsm/vsm-adapter.cpp4
-rw-r--r--vsm/src/vespa/vsm/vsm/vsm-adapter.h2
-rw-r--r--zkfacade/src/main/java/com/yahoo/vespa/curator/stats/LockAttempt.java23
-rw-r--r--zkfacade/src/main/java/com/yahoo/vespa/curator/stats/LockMetrics.java55
-rw-r--r--zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockStats.java5
-rw-r--r--zkfacade/src/test/java/com/yahoo/vespa/curator/stats/LockAttemptSamplesTest.java2
-rw-r--r--zkfacade/src/test/java/com/yahoo/vespa/curator/stats/LockTest.java90
642 files changed, 5319 insertions, 6391 deletions
diff --git a/build_settings.cmake b/build_settings.cmake
index 1a05ffe5073..b4a19b2d684 100644
--- a/build_settings.cmake
+++ b/build_settings.cmake
@@ -53,7 +53,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" ST
endif()
endif()
else()
- set(CXX_SPECIFIC_WARN_OPTS "-Wsuggest-override -Wnon-virtual-dtor -Wformat-security")
+ set(CXX_SPECIFIC_WARN_OPTS "-Wnoexcept -Wsuggest-override -Wnon-virtual-dtor -Wformat-security")
if(VESPA_OS_DISTRO_COMBINED STREQUAL "centos 8" OR
(VESPA_OS_DISTRO STREQUAL "rhel" AND
VESPA_OS_DISTRO_VERSION VERSION_GREATER_EQUAL "8" AND
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/FileRegistry.java b/config-model-api/src/main/java/com/yahoo/config/application/api/FileRegistry.java
index 0d4c0ad76eb..8415781b827 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/FileRegistry.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/FileRegistry.java
@@ -11,7 +11,6 @@ import com.yahoo.config.FileReference;
*/
public interface FileRegistry {
-
FileReference addFile(String relativePath);
FileReference addUri(String uri);
default FileReference addApplicationPackage() { return addFile(""); }
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ConfigChangeAction.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ConfigChangeAction.java
index 2a798839752..ffe011af1e8 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/ConfigChangeAction.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ConfigChangeAction.java
@@ -1,7 +1,10 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.model.api;
+import com.yahoo.config.provision.ClusterSpec;
+
import java.util.List;
+import java.util.Optional;
/**
* Contains the action to be performed on the given services to handle a config change
@@ -38,6 +41,10 @@ public interface ConfigChangeAction {
/** Returns whether this change should be allowed */
boolean allowed();
+ /** The id of the cluster that needs this action applied */
+ // TODO: Remove this default implementation after October 2020
+ default ClusterSpec.Id clusterId() { return null; }
+
/** Returns whether this change should be ignored for internal redeploy */
default boolean ignoreForInternalRedeploy() {
return false;
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ServiceInfo.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ServiceInfo.java
index bbf14d7dcea..7899a6ff5b0 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/ServiceInfo.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ServiceInfo.java
@@ -85,4 +85,9 @@ public class ServiceInfo {
return result;
}
+ @Override
+ public String toString() {
+ return "service '" + serviceName + "' of type " + serviceType + " on " + hostName;
+ }
+
}
diff --git a/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java b/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java
index 10649df88e1..2594c64b951 100644
--- a/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java
+++ b/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java
@@ -140,7 +140,7 @@ public class MockApplicationPackage implements ApplicationPackage {
}
@Override
- public List<NamedReader> getFiles(Path dir,String fileSuffix,boolean recurse) {
+ public List<NamedReader> getFiles(Path dir, String fileSuffix, boolean recurse) {
return new ArrayList<>();
}
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/derived/validation/Validator.java b/config-model/src/main/java/com/yahoo/searchdefinition/derived/validation/Validator.java
index e3bbf78ec21..6189276707b 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/derived/validation/Validator.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/derived/validation/Validator.java
@@ -8,6 +8,7 @@ import com.yahoo.searchdefinition.derived.DerivedConfiguration;
* @author mathiasm
*/
public abstract class Validator {
+
protected DerivedConfiguration config;
protected Search search;
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/AbstractService.java b/config-model/src/main/java/com/yahoo/vespa/model/AbstractService.java
index 5ef01f986c0..e75a9f2b125 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/AbstractService.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/AbstractService.java
@@ -56,7 +56,7 @@ public abstract class AbstractService extends AbstractConfigProducer<AbstractCon
private String preload = Defaults.getDefaults().underVespaHome("lib64/vespa/malloc/libvespamalloc.so");
// If larger or equal to 0 it mean that explicit mmaps shall not be included in coredump.
- private long mmapNoCoreLimit = -1l;
+ private long mmapNoCoreLimit = -1L;
// If this is true it will dump core when OOM
private boolean coreOnOOM = false;
@@ -77,7 +77,7 @@ public abstract class AbstractService extends AbstractConfigProducer<AbstractCon
* more key/value pairs to the service-list dump.
* Supported key datatypes are String, and values may be String or Integer.
*/
- private Map<String, Object> serviceProperties = new LinkedHashMap<>();
+ private final Map<String, Object> serviceProperties = new LinkedHashMap<>();
/** The affinity properties of this service. */
private Optional<Affinity> affinity = Optional.empty();
@@ -176,15 +176,6 @@ public abstract class AbstractService extends AbstractConfigProducer<AbstractCon
} else {
// User defined from spec
wantedPort = userWantedPort;
-/* if ((wantedPort >= Host.BASE_PORT) &&
- (wantedPort <= (Host.BASE_PORT + Host.MAX_PORTS))) {
- throw new RuntimeException
- ("Attribute 'basePort=" + wantedPort +
- "' is not allowed to be inside Vespa's reserved port range "
- + Host.BASE_PORT + "-"
- + (Host.BASE_PORT + Host.MAX_PORTS) + ".");
- }
-*/
}
return wantedPort;
}
@@ -210,20 +201,18 @@ public abstract class AbstractService extends AbstractConfigProducer<AbstractCon
* Computes and returns the i'th port for this service, based on
* this Service's baseport.
*
- * @param i The offset from 'basePort' of the port to return
+ * @param i the offset from 'basePort' of the port to return
* @return the i'th port relative to the base port.
* @throws IllegalStateException if i is out of range.
*/
public int getRelativePort(int i) {
if (ports.size() < 1) {
- throw new IllegalStateException
- ("Requested port with offset " + i + " for service that " +
- "has not reserved any ports: " + this);
+ throw new IllegalStateException("Requested port with offset " + i + " for service that " +
+ "has not reserved any ports: " + this);
}
if (i >= ports.size()) {
- throw new IllegalStateException
- ("Requested port with offset " + i + " for service that " +
- "only has reserved " + ports.size() + " ports: " + this);
+ throw new IllegalStateException("Requested port with offset " + i + " for service that " +
+ "only has reserved " + ports.size() + " ports: " + this);
}
return ports.get(i);
}
@@ -269,20 +258,10 @@ public abstract class AbstractService extends AbstractConfigProducer<AbstractCon
return myClass.getName().substring(1 + myPackage.getName().length());
}
- /**
- * @return the physical host on which this service runs.
- */
- public Host getHost() {
- if (hostResource != null) {
- return hostResource.getHost();
- } else {
- return null;
- }
- }
+ @Override
+ public HostResource getHost() { return hostResource; }
- /**
- * @return The hostname on which this service runs.
- */
+ @Override
public String getHostName() {
return hostResource.getHostname();
}
@@ -306,7 +285,6 @@ public abstract class AbstractService extends AbstractConfigProducer<AbstractCon
protected int getIndex(HostResource host) {
int i = 0;
for (Service s : host.getServices()) {
- //if (s.getClass().equals(getClass()) && (s != this)) {
if (s.getServiceType().equals(getServiceType()) && (s != this)) {
i++;
}
@@ -448,7 +426,7 @@ public abstract class AbstractService extends AbstractConfigProducer<AbstractCon
}
/**
- * WARNING: should only be called before initService(), otherwise call at own risk!
+ * WARNING: should only be called before initService()
*/
public void setBasePort(int wantedPort) {
this.basePort = wantedPort;
@@ -465,27 +443,27 @@ public abstract class AbstractService extends AbstractConfigProducer<AbstractCon
/**
* Add the given file to the application's file distributor.
*
- * @param relativePath path to the file, relative to the app package.
+ * @param relativePath path to the file, relative to the app package
* @return the file reference hash
*/
public FileReference sendFile(String relativePath) {
- return getRoot().getFileDistributor().sendFileToHost(relativePath, getHost());
+ Host host = null;
+ if (getHost() != null) // false when running application tests without hosts
+ host = getHost().getHost();
+ return getRoot().getFileDistributor().sendFileToHost(relativePath, host);
}
public FileReference sendUri(String uri) {
- return getRoot().getFileDistributor().sendUriToHost(uri, getHost());
+ return getRoot().getFileDistributor().sendUriToHost(uri, getHost().getHost());
}
- /**
- *
- * The service HTTP port for health status
- * @return portnumber
- */
+ /** The service HTTP port for health status */
public int getHealthPort() { return -1;}
/**
* Overridden by subclasses. List of default dimensions to be added to this services metrics
- * @return The default dimensions for this service
+ *
+ * @return the default dimensions for this service
*/
public HashMap<String, String> getDefaultMetricDimensions(){ return new LinkedHashMap<>(); }
@@ -510,4 +488,5 @@ public abstract class AbstractService extends AbstractConfigProducer<AbstractCon
public String toString() {
return getServiceName() + " on " + (getHost() == null ? "no host" : getHost().toString());
}
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/HostResource.java b/config-model/src/main/java/com/yahoo/vespa/model/HostResource.java
index 1c73000cc24..27fb0f444ef 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/HostResource.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/HostResource.java
@@ -47,7 +47,7 @@ public class HostResource implements Comparable<HostResource> {
}
/**
- * Return the currently bounded {@link com.yahoo.vespa.model.Host}.
+ * Return the currently bound {@link com.yahoo.vespa.model.Host}.
*
* @return the {@link com.yahoo.vespa.model.Host} if bound, null if not.
*/
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/Service.java b/config-model/src/main/java/com/yahoo/vespa/model/Service.java
index 25128c5ab14..b102ccebee0 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/Service.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/Service.java
@@ -29,16 +29,11 @@ public interface Service extends ConfigProducer, NetworkPortRequestor {
*/
Optional<String> getPreShutdownCommand();
- /**
- * Returns a PortsMeta object, giving access to more information
- * about the different ports of this service.
- */
+ /** Returns a PortsMeta object, giving access to more information about the different ports of this service. */
PortsMeta getPortsMeta();
- /**
- * @return the physical host on which this service runs.
- */
- Host getHost();
+ /** Returns the physical host resource on which this service runs. */
+ HostResource getHost();
/**
* Get meta information about service.
@@ -46,21 +41,18 @@ public interface Service extends ConfigProducer, NetworkPortRequestor {
*/
ServiceInfo getServiceInfo();
- /**
- * @return The hostname on which this service runs.
- */
+ /** Returns the hostname on which this service runs. */
String getHostName();
/** Optional JVM execution options for this service */
String getJvmOptions();
/**
- * Computes and returns the i'th port for this service, based on
- * this Service's baseport.
+ * Computes and returns the i'th port for this service, based on this Service's baseport.
*
- * @param i The offset from 'basePort' of the port to return
- * @return the i'th port relative to the base port.
- * @throws IllegalStateException if i is out of range.
+ * @param i the offset from 'basePort' of the port to return
+ * @return the i'th port relative to the base port
+ * @throws IllegalStateException if i is out of range
*/
int getRelativePort(int i);
@@ -70,23 +62,16 @@ public interface Service extends ConfigProducer, NetworkPortRequestor {
*
* @param key a key used for lookup in the service properties
* @param defStr default String value returned if no value for key found
- * @return the associated String value for the given key, or
+ * @return the associated String value for the given key
*/
String getServicePropertyString(String key, String defStr);
int getHealthPort();
- /**
- *
- * @return HashMap of default dimensions for metrics.
- */
+ /** Returns a HashMap of default dimensions for metrics. */
HashMap<String,String> getDefaultMetricDimensions();
- /**
- * Return the Affinity of this service if it has.
- *
- * @return The {@link com.yahoo.vespa.model.Affinity} for this service.
- */
+ /** Returns the Affinity of this service if it has. */
Optional<Affinity> getAffinity();
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/LogserverContainer.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/LogserverContainer.java
index e94fa9bf040..b3ad8db0df1 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/LogserverContainer.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/LogserverContainer.java
@@ -12,8 +12,8 @@ import com.yahoo.vespa.model.container.component.AccessLogComponent;
*/
public class LogserverContainer extends Container {
- public LogserverContainer(AbstractConfigProducer parent) {
- super(parent, "" + 0, 0);
+ public LogserverContainer(AbstractConfigProducer parent, boolean isHostedVespa) {
+ super(parent, "" + 0, 0, isHostedVespa);
addComponent(new AccessLogComponent(AccessLogComponent.AccessLogType.jsonAccessLog, ((LogserverContainerCluster) parent).getName(), true));
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/LogserverContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/LogserverContainerCluster.java
index 9ae9a158631..0a61b5c91c6 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/LogserverContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/LogserverContainerCluster.java
@@ -3,7 +3,6 @@ package com.yahoo.vespa.model.admin;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.producer.AbstractConfigProducer;
-import com.yahoo.container.handler.ThreadpoolConfig;
import com.yahoo.search.config.QrStartConfig;
import com.yahoo.vespa.model.container.ContainerCluster;
import com.yahoo.vespa.model.container.component.Handler;
@@ -25,11 +24,6 @@ public class LogserverContainerCluster extends ContainerCluster<LogserverContain
protected void doPrepare(DeployState deployState) { }
@Override
- public void getConfig(ThreadpoolConfig.Builder builder) {
- builder.maxthreads(10);
- }
-
- @Override
public void getConfig(QrStartConfig.Builder builder) {
super.getConfig(builder);
builder.jvm.heapsize(384)
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/clustercontroller/ClusterControllerContainer.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/clustercontroller/ClusterControllerContainer.java
index 5b3e4e1479e..8bd4506aedc 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/clustercontroller/ClusterControllerContainer.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/clustercontroller/ClusterControllerContainer.java
@@ -34,7 +34,7 @@ public class ClusterControllerContainer extends Container implements
private final Set<String> bundles = new TreeSet<>();
public ClusterControllerContainer(AbstractConfigProducer parent, int index, boolean runStandaloneZooKeeper, boolean isHosted) {
- super(parent, "" + index, index);
+ super(parent, "" + index, index, isHosted);
addHandler("clustercontroller-status",
"com.yahoo.vespa.clustercontroller.apps.clustercontroller.StatusHandler",
"/clustercontroller-status/*");
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/clustercontroller/ClusterControllerContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/clustercontroller/ClusterControllerContainerCluster.java
index 41d9df414ea..5cee73dff1b 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/clustercontroller/ClusterControllerContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/clustercontroller/ClusterControllerContainerCluster.java
@@ -3,7 +3,6 @@ package com.yahoo.vespa.model.admin.clustercontroller;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.producer.AbstractConfigProducer;
-import com.yahoo.container.handler.ThreadpoolConfig;
import com.yahoo.vespa.model.container.ContainerCluster;
/**
@@ -19,11 +18,6 @@ public class ClusterControllerContainerCluster extends ContainerCluster<ClusterC
}
@Override
- public void getConfig(ThreadpoolConfig.Builder builder) {
- builder.maxthreads(10);
- }
-
- @Override
protected void doPrepare(DeployState deployState) { }
protected boolean messageBusEnabled() { return false; }
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsNodesConfigGenerator.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsNodesConfigGenerator.java
index 21fa05ceeab..bdd04dc1692 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsNodesConfigGenerator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsNodesConfigGenerator.java
@@ -22,7 +22,7 @@ public class MetricsNodesConfigGenerator {
private static MetricsNodesConfig.Node.Builder toNodeBuilder(MetricsProxyContainer container) {
var builder = new MetricsNodesConfig.Node.Builder()
- .role(container.getHost().getConfigId())
+ .role(container.getHost().getHost().getConfigId())
.hostname(container.getHostName())
.metricsPort(MetricsProxyContainer.BASEPORT)
.metricsPath(MetricsV1Handler.VALUES_PATH);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainer.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainer.java
index fccacc3210d..0a03f216913 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainer.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainer.java
@@ -40,7 +40,7 @@ public class MetricsProxyContainer extends Container implements
final boolean isHostedVespa;
public MetricsProxyContainer(AbstractConfigProducer parent, String hostname, int index, boolean isHostedVespa) {
- super(parent, hostname, index);
+ super(parent, hostname, index, isHostedVespa);
this.isHostedVespa = isHostedVespa;
setProp("clustertype", "admin");
setProp("index", String.valueOf(index));
@@ -132,7 +132,7 @@ public class MetricsProxyContainer extends Container implements
}
private String getNodeRole() {
- String hostConfigId = getHost().getConfigId();
+ String hostConfigId = getHost().getHost().getConfigId();
if (! isHostedVespa) return hostConfigId;
return getHostResource().spec().membership()
.map(ClusterMembership::stringValue)
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerCluster.java
index fbf6dcfd5eb..4b9e1c302b7 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerCluster.java
@@ -28,7 +28,6 @@ import com.yahoo.config.model.producer.AbstractConfigProducer;
import com.yahoo.config.model.producer.AbstractConfigProducerRoot;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Zone;
-import com.yahoo.container.handler.ThreadpoolConfig;
import com.yahoo.container.jdisc.ThreadedHttpRequestHandler;
import com.yahoo.osgi.provider.model.ComponentModel;
import com.yahoo.vespa.model.VespaModel;
@@ -198,11 +197,6 @@ public class MetricsProxyContainerCluster extends ContainerCluster<MetricsProxyC
}
}
- @Override
- public void getConfig(ThreadpoolConfig.Builder builder) {
- builder.maxthreads(10);
- }
-
protected boolean messageBusEnabled() { return false; }
private MetricSet getAdditionalDefaultMetrics() {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java
index 56b70bec24e..b492df3a251 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java
@@ -199,6 +199,13 @@ public class VespaMetricSet {
metrics.add(new Metric("jdisc.http.ssl.handshake.failure.unknown.rate"));
metrics.add(new Metric("jdisc.http.handler.unhandled_exceptions.rate"));
+
+ addMetric(metrics, "jdisc.http.jetty.threadpool.thread.max", List.of("last"));
+ addMetric(metrics, "jdisc.http.jetty.threadpool.thread.reserved", List.of("last"));
+ addMetric(metrics, "jdisc.http.jetty.threadpool.thread.busy", List.of("sum", "count", "min", "max"));
+ addMetric(metrics, "jdisc.http.jetty.threadpool.thread.total", List.of("sum", "count", "min", "max"));
+ addMetric(metrics, "jdisc.http.jetty.threadpool.queue.size", List.of("sum", "count", "min", "max"));
+
return metrics;
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
index fa72a4965b0..cc4653fc183 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
@@ -7,6 +7,7 @@ import com.yahoo.config.model.api.ConfigChangeAction;
import com.yahoo.config.model.api.Model;
import com.yahoo.config.model.api.ValidationParameters;
import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.model.VespaModel;
import com.yahoo.vespa.model.application.validation.change.ChangeValidator;
import com.yahoo.vespa.model.application.validation.change.ClusterSizeReductionValidator;
@@ -17,6 +18,7 @@ import com.yahoo.vespa.model.application.validation.change.ContentTypeRemovalVal
import com.yahoo.vespa.model.application.validation.change.GlobalDocumentChangeValidator;
import com.yahoo.vespa.model.application.validation.change.IndexedSearchClusterChangeValidator;
import com.yahoo.vespa.model.application.validation.change.IndexingModeChangeValidator;
+import com.yahoo.vespa.model.application.validation.change.NodeResourceChangeValidator;
import com.yahoo.vespa.model.application.validation.change.ResourcesReductionValidator;
import com.yahoo.vespa.model.application.validation.change.StartupCommandChangeValidator;
import com.yahoo.vespa.model.application.validation.change.StreamingSearchClusterChangeValidator;
@@ -27,6 +29,8 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
@@ -69,9 +73,11 @@ public class Validation {
validateFirstTimeDeployment(model, deployState);
} else {
Optional<Model> currentActiveModel = deployState.getPreviousModel();
- if (currentActiveModel.isPresent() && (currentActiveModel.get() instanceof VespaModel))
+ if (currentActiveModel.isPresent() && (currentActiveModel.get() instanceof VespaModel)) {
result = validateChanges((VespaModel) currentActiveModel.get(), model,
deployState.validationOverrides(), deployState.getDeployLogger(), deployState.now());
+ deferConfigChangesForClustersToBeRestarted(result, model);
+ }
}
return result;
}
@@ -91,6 +97,7 @@ public class Validation {
new ClusterSizeReductionValidator(),
new ResourcesReductionValidator(),
new ContainerRestartValidator(),
+ new NodeResourceChangeValidator()
};
return Arrays.stream(validators)
.flatMap(v -> v.validate(currentModel, nextModel, overrides, now).stream())
@@ -101,4 +108,21 @@ public class Validation {
new AccessControlOnFirstDeploymentValidator().validate(model, deployState);
}
+ private static void deferConfigChangesForClustersToBeRestarted(List<ConfigChangeAction> actions, VespaModel model) {
+ Set<ClusterSpec.Id> clustersToBeRestarted = actions.stream()
+ .filter(action -> action.getType() == ConfigChangeAction.Type.RESTART)
+ .filter(action -> action.clusterId() != null) // TODO: Remove this line after October 2020
+ .map(action -> action.clusterId())
+ .collect(Collectors.toSet());
+ for (var clusterToRestart : clustersToBeRestarted) {
+ var containerCluster = model.getContainerClusters().get(clusterToRestart.value());
+ if (containerCluster != null)
+ containerCluster.deferChangesUntilRestart();
+
+ var contentCluster = model.getContentClusters().get(clusterToRestart.value());
+ if (contentCluster != null)
+ contentCluster.deferChangesUntilRestart();
+ }
+ }
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ChangeValidator.java
index bec7fd1518f..b720cc13f42 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ChangeValidator.java
@@ -12,7 +12,6 @@ import java.util.List;
* Interface for validating changes between a current active and next config model.
*
* @author geirst
- * @since 2014-11-18
*/
public interface ChangeValidator {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidator.java
index 162f6798462..f223ba69f61 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidator.java
@@ -7,11 +7,8 @@ import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.model.VespaModel;
import com.yahoo.config.application.api.ValidationId;
import com.yahoo.config.application.api.ValidationOverrides;
-import com.yahoo.vespa.model.container.ContainerCluster;
-import com.yahoo.vespa.model.content.cluster.ContentCluster;
import java.time.Instant;
-import java.util.Collections;
import java.util.List;
/**
@@ -33,7 +30,7 @@ public class ClusterSizeReductionValidator implements ChangeValidator {
overrides,
now);
}
- return Collections.emptyList();
+ return List.of();
}
private void validate(Capacity current,
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ConfigValueChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ConfigValueChangeValidator.java
index d94cd57357d..a11628bb0ea 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ConfigValueChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ConfigValueChangeValidator.java
@@ -7,6 +7,7 @@ import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.config.model.api.ConfigChangeAction;
import com.yahoo.config.model.producer.AbstractConfigProducerRoot;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.model.Service;
import com.yahoo.vespa.model.VespaModel;
import com.yahoo.vespa.model.application.validation.RestartConfigs;
@@ -44,32 +45,32 @@ public class ConfigValueChangeValidator implements ChangeValidator {
return findConfigChangesFromModels(currentModel, nextModel).collect(Collectors.toList());
}
- public Stream<ConfigChangeAction> findConfigChangesFromModels(
- AbstractConfigProducerRoot currentModel,
- AbstractConfigProducerRoot nextModel) {
+ public Stream<ConfigChangeAction> findConfigChangesFromModels(AbstractConfigProducerRoot currentModel,
+ AbstractConfigProducerRoot nextModel) {
return nextModel.getDescendantServices().stream()
.map(service -> findConfigChangeActionForService(service, currentModel, nextModel))
.filter(Optional::isPresent)
.map(Optional::get);
}
- private Optional<ConfigChangeAction> findConfigChangeActionForService(
- Service service,
- AbstractConfigProducerRoot currentModel,
- AbstractConfigProducerRoot nextModel) {
+ private Optional<ConfigChangeAction> findConfigChangeActionForService(Service service,
+ AbstractConfigProducerRoot currentModel,
+ AbstractConfigProducerRoot nextModel) {
List<ChangesRequiringRestart> changes = findConfigChangesForService(service, currentModel, nextModel)
.collect(Collectors.toList());
if (changes.isEmpty()) {
return Optional.empty();
}
String description = createDescriptionOfConfigChanges(changes.stream());
- return Optional.of(new VespaRestartAction(description, service.getServiceInfo()));
+ ClusterSpec.Id id = service.getHost().spec().membership().isPresent() ?
+ service.getHost().spec().membership().get().cluster().id() :
+ ClusterSpec.Id.from(service.getConfigId());
+ return Optional.of(new VespaRestartAction(id, description, service.getServiceInfo()));
}
- private Stream<ChangesRequiringRestart> findConfigChangesForService(
- Service service,
- AbstractConfigProducerRoot currentModel,
- AbstractConfigProducerRoot nextModel) {
+ private Stream<ChangesRequiringRestart> findConfigChangesForService(Service service,
+ AbstractConfigProducerRoot currentModel,
+ AbstractConfigProducerRoot nextModel) {
Class<? extends Service> serviceClass = service.getClass();
if (!currentModel.getService(service.getConfigId()).isPresent()) {
// Service does not exist in the current model.
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ContainerRestartValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ContainerRestartValidator.java
index 3176ad9f912..17e4f031f3e 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ContainerRestartValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ContainerRestartValidator.java
@@ -2,18 +2,24 @@
package com.yahoo.vespa.model.application.validation.change;
import com.yahoo.config.model.api.ConfigChangeAction;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.container.QrConfig;
import com.yahoo.vespa.model.VespaModel;
import com.yahoo.config.application.api.ValidationOverrides;
+import com.yahoo.vespa.model.container.ApplicationContainer;
+import com.yahoo.vespa.model.container.ApplicationContainerCluster;
import com.yahoo.vespa.model.container.Container;
+import com.yahoo.vespa.model.container.ContainerCluster;
import java.time.Instant;
+import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
/**
- * Returns a restart action for each container that has turned on {@link QrConfig#restartOnDeploy}.
+ * Returns a restart action for each container that has turned on {@link QrConfig#restartOnDeploy()}.
*
* @author bjorncs
*/
@@ -22,16 +28,19 @@ public class ContainerRestartValidator implements ChangeValidator {
@Override
public List<ConfigChangeAction> validate(VespaModel currentModel, VespaModel nextModel, ValidationOverrides ignored,
Instant now) {
- return nextModel.getContainerClusters().values().stream()
- .flatMap(cluster -> cluster.getContainers().stream())
- .filter(container -> isExistingContainer(container, currentModel))
- .filter(container -> shouldContainerRestartOnDeploy(container, nextModel))
- .map(ContainerRestartValidator::createConfigChangeAction)
- .collect(toList());
+ List<ConfigChangeAction> actions = new ArrayList<>();
+ for (ContainerCluster<ApplicationContainer> cluster : nextModel.getContainerClusters().values()) {
+ actions.addAll(cluster.getContainers().stream()
+ .filter(container -> isExistingContainer(container, currentModel))
+ .filter(container -> shouldContainerRestartOnDeploy(container, nextModel))
+ .map(container -> createConfigChangeAction(cluster.id(), container))
+ .collect(Collectors.toList()));
+ }
+ return actions;
}
- private static ConfigChangeAction createConfigChangeAction(Container container) {
- return new VespaRestartAction(createMessage(container), container.getServiceInfo(), true);
+ private static ConfigChangeAction createConfigChangeAction(ClusterSpec.Id id, Container container) {
+ return new VespaRestartAction(id, createMessage(container), container.getServiceInfo(), true);
}
private static String createMessage(Container container) {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ContentClusterRemovalValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ContentClusterRemovalValidator.java
index 866f647a351..4a43a30c167 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ContentClusterRemovalValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ContentClusterRemovalValidator.java
@@ -8,7 +8,6 @@ import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.vespa.model.content.cluster.ContentCluster;
import java.time.Instant;
-import java.util.Collections;
import java.util.List;
/**
@@ -30,7 +29,7 @@ public class ContentClusterRemovalValidator implements ChangeValidator {
now);
}
- return Collections.emptyList();
+ return List.of();
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ContentTypeRemovalValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ContentTypeRemovalValidator.java
index a691c8bb5c4..f3a018f2cdd 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ContentTypeRemovalValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ContentTypeRemovalValidator.java
@@ -9,7 +9,6 @@ import com.yahoo.vespa.model.VespaModel;
import com.yahoo.vespa.model.content.cluster.ContentCluster;
import java.time.Instant;
-import java.util.Collections;
import java.util.List;
/**
@@ -36,7 +35,7 @@ public class ContentTypeRemovalValidator implements ChangeValidator {
}
}
}
- return Collections.emptyList();
+ return List.of();
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidator.java
index 198030d1f44..0b3f865c760 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidator.java
@@ -8,7 +8,6 @@ import com.yahoo.documentmodel.NewDocumentType;
import com.yahoo.vespa.model.VespaModel;
import com.yahoo.vespa.model.content.cluster.ContentCluster;
-import java.util.Collections;
import java.time.Instant;
import java.util.List;
import java.util.Map;
@@ -30,7 +29,7 @@ public class GlobalDocumentChangeValidator implements ChangeValidator {
validateContentCluster(currentEntry.getValue(), nextCluster);
}
}
- return Collections.emptyList();
+ return List.of();
}
private void validateContentCluster(ContentCluster currentCluster, ContentCluster nextCluster) {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexedSearchClusterChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexedSearchClusterChangeValidator.java
index 4ed28331467..b321d5f3fd7 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexedSearchClusterChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexedSearchClusterChangeValidator.java
@@ -20,7 +20,6 @@ import java.util.stream.Collectors;
* Validates the changes between all current and next indexed search clusters in a vespa model.
*
* @author geirst
- * @since 2014-11-18
*/
public class IndexedSearchClusterChangeValidator implements ChangeValidator {
@@ -40,9 +39,7 @@ public class IndexedSearchClusterChangeValidator implements ChangeValidator {
ContentCluster nextCluster,
ValidationOverrides overrides,
Instant now) {
- List<ConfigChangeAction> result = new ArrayList<>();
- result.addAll(validateDocumentDatabases(currentCluster, nextCluster, overrides, now));
- return result;
+ return validateDocumentDatabases(currentCluster, nextCluster, overrides, now);
}
private static List<ConfigChangeAction> validateDocumentDatabases(ContentCluster currentCluster,
@@ -72,7 +69,7 @@ public class IndexedSearchClusterChangeValidator implements ChangeValidator {
NewDocumentType currentDocType = currentCluster.getDocumentDefinitions().get(docTypeName);
NewDocumentType nextDocType = nextCluster.getDocumentDefinitions().get(docTypeName);
List<VespaConfigChangeAction> result =
- new DocumentDatabaseChangeValidator(currentDb, currentDocType, nextDb, nextDocType).validate(overrides, now);
+ new DocumentDatabaseChangeValidator(currentCluster.id(), currentDb, currentDocType, nextDb, nextDocType).validate(overrides, now);
return modifyActions(result, getSearchNodeServices(nextCluster.getSearch().getIndexed()), docTypeName);
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexingModeChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexingModeChangeValidator.java
index 908809b4b44..08b4b37968c 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexingModeChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/IndexingModeChangeValidator.java
@@ -42,7 +42,8 @@ public class IndexingModeChangeValidator implements ChangeValidator {
if (currentClusterIsIndexed == nextClusterIsIndexed) return Optional.empty();
- return Optional.of(VespaRefeedAction.of(ValidationId.indexModeChange.value(),
+ return Optional.of(VespaRefeedAction.of(currentCluster.id(),
+ ValidationId.indexModeChange.value(),
overrides,
"Cluster '" + currentCluster.getName() + "' changed indexing mode from '" +
indexingMode(currentClusterIsIndexed) + "' to '" + indexingMode(nextClusterIsIndexed) + "'",
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/NodeResourceChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/NodeResourceChangeValidator.java
new file mode 100644
index 00000000000..0add9f243fe
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/NodeResourceChangeValidator.java
@@ -0,0 +1,82 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.application.validation.change;
+
+import com.yahoo.config.application.api.ValidationOverrides;
+import com.yahoo.config.model.api.ConfigChangeAction;
+import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.NodeResources;
+import com.yahoo.vespa.model.VespaModel;
+import com.yahoo.vespa.model.container.ApplicationContainerCluster;
+import com.yahoo.vespa.model.content.cluster.ContentCluster;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * Emits restart change actions for clusters where the node resources are changed in a way
+ * which requires a "restart" (container recreation) to take effect.
+ * Nodes will restart on their own on this condition but we want to emit restart actions to
+ * defer applying new config until restart.
+ *
+ * @author bratseth
+ */
+public class NodeResourceChangeValidator implements ChangeValidator {
+
+ @Override
+ public List<ConfigChangeAction> validate(VespaModel current, VespaModel next, ValidationOverrides overrides, Instant now) {
+ var restartActions = new ArrayList<ConfigChangeAction>();
+ for (ClusterSpec.Id clusterId : current.allClusters()) {
+ Optional<NodeResources> currentResources = resourcesOf(clusterId, current);
+ Optional<NodeResources> nextResources = resourcesOf(clusterId, next);
+ if (currentResources.isEmpty() || nextResources.isEmpty()) continue; // new or removed cluster
+ if ( changeRequiresRestart(currentResources.get(), nextResources.get()))
+ restartActions.addAll(createRestartActionsFor(clusterId, current));
+ }
+ return restartActions;
+ }
+
+ private boolean changeRequiresRestart(NodeResources currentResources, NodeResources nextResources) {
+ return currentResources.memoryGb() != nextResources.memoryGb();
+ }
+
+ private Optional<NodeResources> resourcesOf(ClusterSpec.Id clusterId, VespaModel model) {
+ return model.allocatedHosts().getHosts().stream().filter(host -> host.membership().isPresent())
+ .filter(host -> host.membership().get().cluster().id().equals(clusterId))
+ .findFirst()
+ .map(host -> host.realResources());
+ }
+
+ private List<ConfigChangeAction> createRestartActionsFor(ClusterSpec.Id clusterId, VespaModel model) {
+ ApplicationContainerCluster containerCluster = model.getContainerClusters().get(clusterId.value());
+ if (containerCluster != null)
+ return createRestartActionsFor(containerCluster);
+
+ ContentCluster contentCluster = model.getContentClusters().get(clusterId.value());
+ if (contentCluster != null)
+ return createRestartActionsFor(contentCluster);
+
+ return List.of();
+ }
+
+ private List<ConfigChangeAction> createRestartActionsFor(ApplicationContainerCluster cluster) {
+ return cluster.getContainers().stream()
+ .map(container -> new VespaRestartAction(cluster.id(),
+ "Node resource change",
+ container.getServiceInfo(),
+ false))
+ .collect(Collectors.toList());
+ }
+
+ private List<ConfigChangeAction> createRestartActionsFor(ContentCluster cluster) {
+ return cluster.getSearch().getSearchNodes().stream()
+ .map(node -> new VespaRestartAction(cluster.id(),
+ "Node resource change",
+ node.getServiceInfo(),
+ false))
+ .collect(Collectors.toList());
+ }
+
+}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidator.java
index 24b7b0949f6..0fdfcd78323 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidator.java
@@ -1,22 +1,17 @@
// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.application.validation.change;
-import com.yahoo.collections.Pair;
import com.yahoo.config.application.api.ValidationId;
import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.config.model.api.ConfigChangeAction;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
-import com.yahoo.config.provision.NodeResources;
-import com.yahoo.vespa.model.HostResource;
import com.yahoo.vespa.model.VespaModel;
import java.time.Instant;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
import java.util.Optional;
-import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/StartupCommandChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/StartupCommandChangeValidator.java
index 840ab69ba08..54ce869eba1 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/StartupCommandChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/StartupCommandChangeValidator.java
@@ -3,6 +3,7 @@ package com.yahoo.vespa.model.application.validation.change;
import com.yahoo.config.model.api.ConfigChangeAction;
import com.yahoo.config.model.producer.AbstractConfigProducerRoot;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.model.Service;
import com.yahoo.vespa.model.VespaModel;
import com.yahoo.config.application.api.ValidationOverrides;
@@ -28,11 +29,11 @@ public class StartupCommandChangeValidator implements ChangeValidator {
return findServicesWithChangedStartupCommmand(currentModel, nextModel).collect(Collectors.toList());
}
- public Stream<ConfigChangeAction> findServicesWithChangedStartupCommmand(
- AbstractConfigProducerRoot currentModel, AbstractConfigProducerRoot nextModel) {
+ public Stream<ConfigChangeAction> findServicesWithChangedStartupCommmand(AbstractConfigProducerRoot currentModel,
+ AbstractConfigProducerRoot nextModel) {
return nextModel.getDescendantServices().stream()
.map(nextService -> currentModel.getService(nextService.getConfigId())
- .flatMap(currentService -> compareStartupCommand(currentService, nextService)))
+ .flatMap(currentService -> compareStartupCommand(currentService, nextService)))
.filter(Optional::isPresent)
.map(Optional::get);
}
@@ -41,13 +42,13 @@ public class StartupCommandChangeValidator implements ChangeValidator {
String currentCommand = currentService.getStartupCommand();
String nextCommand = nextService.getStartupCommand();
- // Objects.equals is null-aware
- if (Objects.equals(currentCommand, nextCommand)) {
- return Optional.empty();
- }
+ if (Objects.equals(currentCommand, nextCommand)) return Optional.empty();
+
String message = String.format("Startup command for '%s' has changed.\nNew command: %s.\nOld command: %s.",
currentService.getServiceName(), nextCommand, currentCommand);
- return Optional.of(new VespaRestartAction(message, currentService.getServiceInfo()));
+ return Optional.of(new VespaRestartAction(ClusterSpec.Id.from(currentService.getConfigId()),
+ message,
+ currentService.getServiceInfo()));
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/StreamingSearchClusterChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/StreamingSearchClusterChangeValidator.java
index a96275010bf..d85d9bd2db5 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/StreamingSearchClusterChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/StreamingSearchClusterChangeValidator.java
@@ -4,6 +4,7 @@ package com.yahoo.vespa.model.application.validation.change;
import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.config.model.api.ConfigChangeAction;
import com.yahoo.config.model.api.ServiceInfo;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.documentmodel.NewDocumentType;
import com.yahoo.searchdefinition.derived.AttributeFields;
import com.yahoo.searchdefinition.document.Attribute;
@@ -59,45 +60,51 @@ public class StreamingSearchClusterChangeValidator implements ChangeValidator {
Instant now) {
List<VespaConfigChangeAction> result = new ArrayList<>();
- result.addAll(validateDocumentTypeChanges(getDocumentType(currentCluster, currentStreamingCluster),
- getDocumentType(nextCluster, nextStreamingCluster), overrides, now));
- result.addAll(validateAttributeFastAccessAdded(currentStreamingCluster.getSdConfig().getAttributeFields(),
- nextStreamingCluster.getSdConfig().getAttributeFields()));
- result.addAll(validateAttributeFastAccessRemoved(currentStreamingCluster.getSdConfig().getAttributeFields(),
- nextStreamingCluster.getSdConfig().getAttributeFields()));
+ result.addAll(validateDocumentTypeChanges(currentCluster.id(),
+ getDocumentType(currentCluster, currentStreamingCluster),
+ getDocumentType(nextCluster, nextStreamingCluster), overrides, now));
+ result.addAll(validateAttributeFastAccessAdded(currentCluster.id(),
+ currentStreamingCluster.getSdConfig().getAttributeFields(),
+ nextStreamingCluster.getSdConfig().getAttributeFields()));
+ result.addAll(validateAttributeFastAccessRemoved(currentCluster.id(),
+ currentStreamingCluster.getSdConfig().getAttributeFields(),
+ nextStreamingCluster.getSdConfig().getAttributeFields()));
return modifyActions(result, getSearchNodeServices(nextCluster), nextStreamingCluster.getDocTypeName());
}
- private static List<VespaConfigChangeAction> validateDocumentTypeChanges(NewDocumentType currentDocType,
+ private static List<VespaConfigChangeAction> validateDocumentTypeChanges(ClusterSpec.Id id,
+ NewDocumentType currentDocType,
NewDocumentType nextDocType,
ValidationOverrides overrides,
Instant now) {
- return new DocumentTypeChangeValidator(currentDocType, nextDocType).validate(overrides, now);
+ return new DocumentTypeChangeValidator(id, currentDocType, nextDocType).validate(overrides, now);
}
private static NewDocumentType getDocumentType(ContentCluster cluster, StreamingSearchCluster streamingCluster) {
return cluster.getDocumentDefinitions().get(streamingCluster.getDocTypeName());
}
- private static List<VespaConfigChangeAction> validateAttributeFastAccessAdded(AttributeFields currentAttributes,
+ private static List<VespaConfigChangeAction> validateAttributeFastAccessAdded(ClusterSpec.Id id,
+ AttributeFields currentAttributes,
AttributeFields nextAttributes) {
- return validateAttributeFastAccessChanged(nextAttributes, currentAttributes, "add");
+ return validateAttributeFastAccessChanged(id, nextAttributes, currentAttributes, "add");
}
- private static List<VespaConfigChangeAction> validateAttributeFastAccessRemoved(AttributeFields currentAttributes,
+ private static List<VespaConfigChangeAction> validateAttributeFastAccessRemoved(ClusterSpec.Id id,
+ AttributeFields currentAttributes,
AttributeFields nextAttributes) {
- return validateAttributeFastAccessChanged(currentAttributes, nextAttributes, "remove");
+ return validateAttributeFastAccessChanged(id, currentAttributes, nextAttributes, "remove");
}
- private static List<VespaConfigChangeAction> validateAttributeFastAccessChanged(AttributeFields lhsAttributes,
+ private static List<VespaConfigChangeAction> validateAttributeFastAccessChanged(ClusterSpec.Id id,
+ AttributeFields lhsAttributes,
AttributeFields rhsAttributes,
String change) {
return lhsAttributes.attributes().stream()
.filter(attr -> attr.isFastAccess() &&
!hasFastAccessAttribute(attr.getName(), rhsAttributes))
- .map(attr -> new VespaRestartAction(new ChangeMessageBuilder(attr.getName())
- .addChange(change + " fast-access attribute").build()))
+ .map(attr -> new VespaRestartAction(id, new ChangeMessageBuilder(attr.getName()).addChange(change + " fast-access attribute").build()))
.collect(Collectors.toList());
}
@@ -117,7 +124,7 @@ public class StreamingSearchClusterChangeValidator implements ChangeValidator {
String docTypeName) {
return result.stream()
.map(action -> action.modifyAction("Document type '" + docTypeName + "': " + action.getMessage(),
- services, docTypeName))
+ services, docTypeName))
.collect(Collectors.toList());
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/VespaConfigChangeAction.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/VespaConfigChangeAction.java
index ea57b88ff4e..96c1a6a7b09 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/VespaConfigChangeAction.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/VespaConfigChangeAction.java
@@ -3,8 +3,10 @@ package com.yahoo.vespa.model.application.validation.change;
import com.yahoo.config.model.api.ConfigChangeAction;
import com.yahoo.config.model.api.ServiceInfo;
+import com.yahoo.config.provision.ClusterSpec;
import java.util.List;
+import java.util.Optional;
import java.util.stream.Collectors;
/**
@@ -12,14 +14,15 @@ import java.util.stream.Collectors;
* between the current active vespa model and the next vespa model to prepare.
*
* @author geirst
- * @since 2014-11-18
*/
public abstract class VespaConfigChangeAction implements ConfigChangeAction {
+ private final ClusterSpec.Id id;
private final String message;
private final List<ServiceInfo> services;
- protected VespaConfigChangeAction(String message, List<ServiceInfo> services) {
+ protected VespaConfigChangeAction(ClusterSpec.Id id, String message, List<ServiceInfo> services) {
+ this.id = id;
this.message = message;
this.services = services;
}
@@ -27,6 +30,9 @@ public abstract class VespaConfigChangeAction implements ConfigChangeAction {
public abstract VespaConfigChangeAction modifyAction(String newMessage, List<ServiceInfo> newServices, String documentType);
@Override
+ public ClusterSpec.Id clusterId() { return id; }
+
+ @Override
public String getMessage() {
return message;
}
@@ -63,4 +69,5 @@ public abstract class VespaConfigChangeAction implements ConfigChangeAction {
result = 31 * result + services.hashCode();
return result;
}
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/VespaRefeedAction.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/VespaRefeedAction.java
index be43c6eddfb..b61cd7af151 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/VespaRefeedAction.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/VespaRefeedAction.java
@@ -4,6 +4,7 @@ package com.yahoo.vespa.model.application.validation.change;
import com.yahoo.config.model.api.ConfigChangeRefeedAction;
import com.yahoo.config.model.api.ServiceInfo;
import com.yahoo.config.application.api.ValidationOverrides;
+import com.yahoo.config.provision.ClusterSpec;
import java.time.Instant;
import java.util.List;
@@ -13,7 +14,6 @@ import java.util.List;
*
* @author geirst
* @author bratseth
- * @since 5.43
*/
public class VespaRefeedAction extends VespaConfigChangeAction implements ConfigChangeRefeedAction {
@@ -27,8 +27,8 @@ public class VespaRefeedAction extends VespaConfigChangeAction implements Config
private final String documentType;
private final boolean allowed;
- private VespaRefeedAction(String name, String message, List<ServiceInfo> services, String documentType, boolean allowed) {
- super(message, services);
+ private VespaRefeedAction(ClusterSpec.Id id, String name, String message, List<ServiceInfo> services, String documentType, boolean allowed) {
+ super(id, message, services);
this.name = name;
this.documentType = documentType;
this.allowed = allowed;
@@ -36,19 +36,19 @@ public class VespaRefeedAction extends VespaConfigChangeAction implements Config
/** Creates a refeed action with some missing information */
// TODO: We should require document type or model its absence properly
- public static VespaRefeedAction of(String name, ValidationOverrides overrides, String message, Instant now) {
- return new VespaRefeedAction(name, message, List.of(), "", overrides.allows(name, now));
+ public static VespaRefeedAction of(ClusterSpec.Id id, String name, ValidationOverrides overrides, String message, Instant now) {
+ return new VespaRefeedAction(id, name, message, List.of(), "", overrides.allows(name, now));
}
/** Creates a refeed action */
- public static VespaRefeedAction of(String name, ValidationOverrides overrides, String message,
+ public static VespaRefeedAction of(ClusterSpec.Id id, String name, ValidationOverrides overrides, String message,
List<ServiceInfo> services, String documentType, Instant now) {
- return new VespaRefeedAction(name, message, services, documentType, overrides.allows(name, now));
+ return new VespaRefeedAction(id, name, message, services, documentType, overrides.allows(name, now));
}
@Override
public VespaConfigChangeAction modifyAction(String newMessage, List<ServiceInfo> newServices, String documentType) {
- return new VespaRefeedAction(name, newMessage, newServices, documentType, allowed);
+ return new VespaRefeedAction(clusterId(), name, newMessage, newServices, documentType, allowed);
}
@Override
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/VespaRestartAction.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/VespaRestartAction.java
index 3ea18cac1d6..ca3a408b2e0 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/VespaRestartAction.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/VespaRestartAction.java
@@ -3,8 +3,10 @@ package com.yahoo.vespa.model.application.validation.change;
import com.yahoo.config.model.api.ConfigChangeRestartAction;
import com.yahoo.config.model.api.ServiceInfo;
+import com.yahoo.config.provision.ClusterSpec;
import java.util.List;
+import java.util.Optional;
/**
* Represents an action to restart services in order to handle a config change.
@@ -15,27 +17,27 @@ public class VespaRestartAction extends VespaConfigChangeAction implements Confi
private final boolean ignoreForInternalRedeploy;
- public VespaRestartAction(String message) {
- this(message, List.of());
+ public VespaRestartAction(ClusterSpec.Id id, String message) {
+ this(id, message, List.of());
}
- public VespaRestartAction(String message, ServiceInfo service) {
- this(message, List.of(service));
+ public VespaRestartAction(ClusterSpec.Id id, String message, ServiceInfo service) {
+ this(id, message, List.of(service));
}
- public VespaRestartAction(String message, ServiceInfo services, boolean ignoreForInternalRedeploy) {
- super(message, List.of(services));
+ public VespaRestartAction(ClusterSpec.Id id, String message, ServiceInfo services, boolean ignoreForInternalRedeploy) {
+ super(id, message, List.of(services));
this.ignoreForInternalRedeploy = ignoreForInternalRedeploy;
}
- public VespaRestartAction(String message, List<ServiceInfo> services) {
- super(message, services);
+ public VespaRestartAction(ClusterSpec.Id id, String message, List<ServiceInfo> services) {
+ super(id, message, services);
this.ignoreForInternalRedeploy = false;
}
@Override
public VespaConfigChangeAction modifyAction(String newMessage, List<ServiceInfo> newServices, String documentType) {
- return new VespaRestartAction(newMessage, newServices);
+ return new VespaRestartAction(clusterId(), newMessage, newServices);
}
@Override
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidator.java
index 5d790c74f18..a10aac30298 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidator.java
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.application.validation.change.search;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.documentmodel.NewDocumentType;
import com.yahoo.searchdefinition.derived.AttributeFields;
import com.yahoo.searchdefinition.derived.IndexSchema;
@@ -26,6 +27,7 @@ import java.util.stream.Collectors;
*/
public class AttributeChangeValidator {
+ private final ClusterSpec.Id id;
private final AttributeFields currentFields;
private final IndexSchema currentIndexSchema;
private final NewDocumentType currentDocType;
@@ -33,12 +35,14 @@ public class AttributeChangeValidator {
private final IndexSchema nextIndexSchema;
private final NewDocumentType nextDocType;
- public AttributeChangeValidator(AttributeFields currentFields,
+ public AttributeChangeValidator(ClusterSpec.Id id,
+ AttributeFields currentFields,
IndexSchema currentIndexSchema,
NewDocumentType currentDocType,
AttributeFields nextFields,
IndexSchema nextIndexSchema,
NewDocumentType nextDocType) {
+ this.id = id;
this.currentFields = currentFields;
this.currentIndexSchema = currentIndexSchema;
this.currentDocType = currentDocType;
@@ -60,9 +64,8 @@ public class AttributeChangeValidator {
return nextFields.attributes().stream().
map(attr -> attr.getName()).
filter(attrName -> !currentFields.containsAttribute(attrName) &&
- currentDocType.containsField(attrName)).
- map(attrName -> new VespaRestartAction(new ChangeMessageBuilder(attrName).
- addChange("add attribute aspect").build())).
+ currentDocType.containsField(attrName)).
+ map(attrName -> new VespaRestartAction(id, new ChangeMessageBuilder(attrName).addChange("add attribute aspect").build())).
collect(Collectors.toList());
}
@@ -70,10 +73,9 @@ public class AttributeChangeValidator {
return currentFields.attributes().stream().
map(attr -> attr.getName()).
filter(attrName -> !nextFields.containsAttribute(attrName) &&
- nextDocType.containsField(attrName) &&
- !isIndexField(attrName)).
- map(attrName -> new VespaRestartAction(new ChangeMessageBuilder(attrName).
- addChange("remove attribute aspect").build())).
+ nextDocType.containsField(attrName) &&
+ !isIndexField(attrName)).
+ map(attrName -> new VespaRestartAction(id, new ChangeMessageBuilder(attrName).addChange("remove attribute aspect").build())).
collect(Collectors.toList());
}
@@ -90,60 +92,63 @@ public class AttributeChangeValidator {
for (Attribute nextAttr : nextFields.attributes()) {
Attribute currAttr = currentFields.getAttribute(nextAttr.getName());
if (currAttr != null) {
- validateAttributeSetting(currAttr, nextAttr, Attribute::isFastSearch, "fast-search", result);
- validateAttributeSetting(currAttr, nextAttr, Attribute::isFastAccess, "fast-access", result);
- validateAttributeSetting(currAttr, nextAttr, Attribute::isHuge, "huge", result);
- validateAttributeSetting(currAttr, nextAttr, Attribute::densePostingListThreshold, "dense-posting-list-threshold", result);
- validateAttributeSetting(currAttr, nextAttr, Attribute::isEnabledOnlyBitVector, "rank: filter", result);
- validateAttributeSetting(currAttr, nextAttr, AttributeChangeValidator::hasHnswIndex, "indexing: index", result);
- validateAttributeSetting(currAttr, nextAttr, Attribute::distanceMetric, "distance-metric", result);
+ validateAttributeSetting(id, currAttr, nextAttr, Attribute::isFastSearch, "fast-search", result);
+ validateAttributeSetting(id, currAttr, nextAttr, Attribute::isFastAccess, "fast-access", result);
+ validateAttributeSetting(id, currAttr, nextAttr, Attribute::isHuge, "huge", result);
+ validateAttributeSetting(id, currAttr, nextAttr, Attribute::densePostingListThreshold, "dense-posting-list-threshold", result);
+ validateAttributeSetting(id, currAttr, nextAttr, Attribute::isEnabledOnlyBitVector, "rank: filter", result);
+ validateAttributeSetting(id, currAttr, nextAttr, AttributeChangeValidator::hasHnswIndex, "indexing: index", result);
+ validateAttributeSetting(id, currAttr, nextAttr, Attribute::distanceMetric, "distance-metric", result);
if (hasHnswIndex(currAttr) && hasHnswIndex(nextAttr)) {
- validateAttributeHnswIndexSetting(currAttr, nextAttr, HnswIndexParams::maxLinksPerNode, "max-links-per-node", result);
- validateAttributeHnswIndexSetting(currAttr, nextAttr, HnswIndexParams::neighborsToExploreAtInsert, "neighbors-to-explore-at-insert", result);
+ validateAttributeHnswIndexSetting(id, currAttr, nextAttr, HnswIndexParams::maxLinksPerNode, "max-links-per-node", result);
+ validateAttributeHnswIndexSetting(id, currAttr, nextAttr, HnswIndexParams::neighborsToExploreAtInsert, "neighbors-to-explore-at-insert", result);
}
}
}
return result;
}
- private static void validateAttributeSetting(Attribute currentAttr, Attribute nextAttr,
+ private static void validateAttributeSetting(ClusterSpec.Id id,
+ Attribute currentAttr, Attribute nextAttr,
Predicate<Attribute> predicate, String setting,
List<VespaConfigChangeAction> result) {
- final boolean nextValue = predicate.test(nextAttr);
+ boolean nextValue = predicate.test(nextAttr);
if (predicate.test(currentAttr) != nextValue) {
String change = nextValue ? "add" : "remove";
- result.add(new VespaRestartAction(new ChangeMessageBuilder(nextAttr.getName()).
- addChange(change + " attribute '" + setting + "'").build()));
+ result.add(new VespaRestartAction(id, new ChangeMessageBuilder(nextAttr.getName()).addChange(change + " attribute '" + setting + "'").build()));
}
}
- private static <T> void validateAttributeSetting(Attribute currentAttr, Attribute nextAttr,
+ private static <T> void validateAttributeSetting(ClusterSpec.Id id,
+ Attribute currentAttr, Attribute nextAttr,
Function<Attribute, T> settingValueProvider, String setting,
List<VespaConfigChangeAction> result) {
T currentValue = settingValueProvider.apply(currentAttr);
T nextValue = settingValueProvider.apply(nextAttr);
if ( ! Objects.equals(currentValue, nextValue)) {
String message = String.format("change property '%s' from '%s' to '%s'", setting, currentValue, nextValue);
- result.add(new VespaRestartAction(new ChangeMessageBuilder(nextAttr.getName()).addChange(message).build()));
+ result.add(new VespaRestartAction(id, new ChangeMessageBuilder(nextAttr.getName()).addChange(message).build()));
}
}
- private static <T> void validateAttributeHnswIndexSetting(Attribute currentAttr, Attribute nextAttr,
- Function<HnswIndexParams, T> settingValueProvider, String setting,
+ private static <T> void validateAttributeHnswIndexSetting(ClusterSpec.Id id,
+ Attribute currentAttr, Attribute nextAttr,
+ Function<HnswIndexParams, T> settingValueProvider,
+ String setting,
List<VespaConfigChangeAction> result) {
T currentValue = settingValueProvider.apply(currentAttr.hnswIndexParams().get());
T nextValue = settingValueProvider.apply(nextAttr.hnswIndexParams().get());
if (!Objects.equals(currentValue, nextValue)) {
String message = String.format("change hnsw index property '%s' from '%s' to '%s'", setting, currentValue, nextValue);
- result.add(new VespaRestartAction(new ChangeMessageBuilder(nextAttr.getName()).addChange(message).build()));
+ result.add(new VespaRestartAction(id, new ChangeMessageBuilder(nextAttr.getName()).addChange(message).build()));
}
}
- private List<VespaConfigChangeAction> validateTensorTypes(final ValidationOverrides overrides, Instant now) {
- final List<VespaConfigChangeAction> result = new ArrayList<>();
+ private List<VespaConfigChangeAction> validateTensorTypes(ValidationOverrides overrides, Instant now) {
+ List<VespaConfigChangeAction> result = new ArrayList<>();
- for (final Attribute nextAttr : nextFields.attributes()) {
- final Attribute currentAttr = currentFields.getAttribute(nextAttr.getName());
+ for (Attribute nextAttr : nextFields.attributes()) {
+ Attribute currentAttr = currentFields.getAttribute(nextAttr.getName());
if (currentAttr != null && currentAttr.tensorType().isPresent()) {
// If the tensor attribute is not present on the new attribute, it means that the data type of the attribute
@@ -154,7 +159,7 @@ public class AttributeChangeValidator {
// Tensor attribute has changed type
if (!nextAttr.tensorType().get().equals(currentAttr.tensorType().get())) {
- result.add(createTensorTypeChangedRefeedAction(currentAttr, nextAttr, overrides, now));
+ result.add(createTensorTypeChangedRefeedAction(id, currentAttr, nextAttr, overrides, now));
}
}
}
@@ -162,15 +167,13 @@ public class AttributeChangeValidator {
return result;
}
- private static VespaRefeedAction createTensorTypeChangedRefeedAction(Attribute currentAttr, Attribute nextAttr, ValidationOverrides overrides, Instant now) {
- return VespaRefeedAction.of(
- "tensor-type-change",
- overrides,
- new ChangeMessageBuilder(nextAttr.getName())
- .addChange(
- "tensor type",
- currentAttr.tensorType().get().toString(),
- nextAttr.tensorType().get().toString()).build(), now);
+ private static VespaRefeedAction createTensorTypeChangedRefeedAction(ClusterSpec.Id id, Attribute currentAttr, Attribute nextAttr, ValidationOverrides overrides, Instant now) {
+ return VespaRefeedAction.of(id,
+ "tensor-type-change",
+ overrides,
+ new ChangeMessageBuilder(nextAttr.getName()).addChange("tensor type",
+ currentAttr.tensorType().get().toString(),
+ nextAttr.tensorType().get().toString()).build(), now);
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidator.java
index deae0a89c56..68a97f33dfd 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidator.java
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.application.validation.change.search;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.documentmodel.NewDocumentType;
import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.vespa.model.application.validation.change.VespaConfigChangeAction;
@@ -14,19 +15,21 @@ import java.util.List;
* Validates the changes between a current and next document database that is part of an indexed search cluster.
*
* @author geirst
- * @since 2014-11-18
*/
public class DocumentDatabaseChangeValidator {
- private DocumentDatabase currentDatabase;
- private NewDocumentType currentDocType;
- private DocumentDatabase nextDatabase;
- private NewDocumentType nextDocType;
+ private final ClusterSpec.Id id;
+ private final DocumentDatabase currentDatabase;
+ private final NewDocumentType currentDocType;
+ private final DocumentDatabase nextDatabase;
+ private final NewDocumentType nextDocType;
- public DocumentDatabaseChangeValidator(DocumentDatabase currentDatabase,
+ public DocumentDatabaseChangeValidator(ClusterSpec.Id id,
+ DocumentDatabase currentDatabase,
NewDocumentType currentDocType,
DocumentDatabase nextDatabase,
NewDocumentType nextDocType) {
+ this.id = id;
this.currentDatabase = currentDatabase;
this.currentDocType = currentDocType;
this.nextDatabase = nextDatabase;
@@ -43,25 +46,33 @@ public class DocumentDatabaseChangeValidator {
}
private List<VespaConfigChangeAction> validateAttributeChanges(ValidationOverrides overrides, Instant now) {
- return new AttributeChangeValidator(
- currentDatabase.getDerivedConfiguration().getAttributeFields(),
- currentDatabase.getDerivedConfiguration().getIndexSchema(), currentDocType,
- nextDatabase.getDerivedConfiguration().getAttributeFields(),
- nextDatabase.getDerivedConfiguration().getIndexSchema(), nextDocType).validate(overrides, now);
+ return new AttributeChangeValidator(id,
+ currentDatabase.getDerivedConfiguration().getAttributeFields(),
+ currentDatabase.getDerivedConfiguration().getIndexSchema(), currentDocType,
+ nextDatabase.getDerivedConfiguration().getAttributeFields(),
+ nextDatabase.getDerivedConfiguration().getIndexSchema(), nextDocType)
+ .validate(overrides, now);
}
private List<VespaConfigChangeAction> validateStructFieldAttributeChanges(ValidationOverrides overrides, Instant now) {
- return new StructFieldAttributeChangeValidator(currentDocType, currentDatabase.getDerivedConfiguration().getAttributeFields(),
- nextDocType, nextDatabase.getDerivedConfiguration().getAttributeFields()).validate(overrides, now);
+ return new StructFieldAttributeChangeValidator(id,
+ currentDocType,
+ currentDatabase.getDerivedConfiguration().getAttributeFields(),
+ nextDocType,
+ nextDatabase.getDerivedConfiguration().getAttributeFields())
+ .validate(overrides, now);
}
private List<VespaConfigChangeAction> validateIndexingScriptChanges(ValidationOverrides overrides, Instant now) {
- return new IndexingScriptChangeValidator(currentDatabase.getDerivedConfiguration().getSearch(),
- nextDatabase.getDerivedConfiguration().getSearch()).validate(overrides, now);
+ return new IndexingScriptChangeValidator(id,
+ currentDatabase.getDerivedConfiguration().getSearch(),
+ nextDatabase.getDerivedConfiguration().getSearch())
+ .validate(overrides, now);
}
private List<VespaConfigChangeAction> validateDocumentTypeChanges(ValidationOverrides overrides, Instant now) {
- return new DocumentTypeChangeValidator(currentDocType, nextDocType).validate(overrides, now);
+ return new DocumentTypeChangeValidator(id, currentDocType, nextDocType)
+ .validate(overrides, now);
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/DocumentTypeChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/DocumentTypeChangeValidator.java
index 4fd5e82e93f..b66145a10c5 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/DocumentTypeChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/DocumentTypeChangeValidator.java
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.application.validation.change.search;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.document.StructDataType;
import com.yahoo.documentmodel.NewDocumentType;
import com.yahoo.document.Field;
@@ -16,12 +17,12 @@ import java.util.stream.Collectors;
* Validates the changes between a current and next document type used in a document database.
*
* @author toregge
- * @since 2014-11-25
*/
public class DocumentTypeChangeValidator {
- private NewDocumentType currentDocType;
- private NewDocumentType nextDocType;
+ private final ClusterSpec.Id id;
+ private final NewDocumentType currentDocType;
+ private final NewDocumentType nextDocType;
private static abstract class FieldChange {
@@ -127,8 +128,10 @@ public class DocumentTypeChangeValidator {
}
}
- public DocumentTypeChangeValidator(NewDocumentType currentDocType,
+ public DocumentTypeChangeValidator(ClusterSpec.Id id,
+ NewDocumentType currentDocType,
NewDocumentType nextDocType) {
+ this.id = id;
this.currentDocType = currentDocType;
this.nextDocType = nextDocType;
}
@@ -137,7 +140,8 @@ public class DocumentTypeChangeValidator {
return currentDocType.getAllFields().stream().
map(field -> createFieldChange(field, nextDocType)).
filter(fieldChange -> fieldChange.valid() && fieldChange.changedType()).
- map(fieldChange -> VespaRefeedAction.of("field-type-change",
+ map(fieldChange -> VespaRefeedAction.of(id,
+ "field-type-change",
overrides,
new ChangeMessageBuilder(fieldChange.fieldName()).
addChange("data type", fieldChange.currentTypeName(),
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidator.java
index b03141fa5d9..4761d1613b8 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidator.java
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.application.validation.change.search;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.searchdefinition.Search;
import com.yahoo.searchdefinition.document.ImmutableSDField;
import com.yahoo.vespa.indexinglanguage.ExpressionConverter;
@@ -21,14 +22,15 @@ import java.util.Optional;
* Validates the indexing script changes in all fields in the current and next search model.
*
* @author geirst
- * @since 2014-12-08
*/
public class IndexingScriptChangeValidator {
+ private final ClusterSpec.Id id;
private final Search currentSearch;
private final Search nextSearch;
- public IndexingScriptChangeValidator(Search currentSearch, Search nextSearch) {
+ public IndexingScriptChangeValidator(ClusterSpec.Id id, Search currentSearch, Search nextSearch) {
+ this.id = id;
this.currentSearch = currentSearch;
this.nextSearch = nextSearch;
}
@@ -53,7 +55,7 @@ public class IndexingScriptChangeValidator {
ChangeMessageBuilder messageBuilder = new ChangeMessageBuilder(nextField.getName());
new IndexingScriptChangeMessageBuilder(currentSearch, currentField, nextSearch, nextField).populate(messageBuilder);
messageBuilder.addChange("indexing script", currentScript.toString(), nextScript.toString());
- return Optional.of(VespaRefeedAction.of(ValidationId.indexingChange.value(), overrides, messageBuilder.build(), now));
+ return Optional.of(VespaRefeedAction.of(id, ValidationId.indexingChange.value(), overrides, messageBuilder.build(), now));
}
return Optional.empty();
}
@@ -68,8 +70,7 @@ public class IndexingScriptChangeValidator {
}
private static ScriptExpression removeOutputExpressions(ScriptExpression script) {
- ScriptExpression retval = (ScriptExpression) new OutputExpressionRemover().convert(script);
- return retval;
+ return (ScriptExpression) new OutputExpressionRemover().convert(script);
}
private static class OutputExpressionRemover extends ExpressionConverter {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidator.java
index e3f9610d0a4..e8b2d593de6 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidator.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.model.application.validation.change.search;
import com.yahoo.config.application.api.ValidationOverrides;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.document.ArrayDataType;
import com.yahoo.document.DataType;
import com.yahoo.document.Field;
@@ -33,15 +34,18 @@ import java.util.stream.Collectors;
*/
public class StructFieldAttributeChangeValidator {
+ private final ClusterSpec.Id id;
private final NewDocumentType currentDocType;
private final AttributeFields currentAttributes;
private final NewDocumentType nextDocType;
private final AttributeFields nextAttributes;
- public StructFieldAttributeChangeValidator(NewDocumentType currentDocType,
+ public StructFieldAttributeChangeValidator(ClusterSpec.Id id,
+ NewDocumentType currentDocType,
AttributeFields currentAttributes,
NewDocumentType nextDocType,
AttributeFields nextAttributes) {
+ this.id = id;
this.currentDocType = currentDocType;
this.currentAttributes = currentAttributes;
this.nextDocType = nextDocType;
@@ -64,10 +68,8 @@ public class StructFieldAttributeChangeValidator {
private List<VespaConfigChangeAction> validateAddAttributeAspect(Context current, Context next, ValidationOverrides overrides, Instant now) {
return next.structFieldAttributes.stream()
.filter(nextAttr -> current.hasFieldForStructFieldAttribute(nextAttr) &&
- !current.hasStructFieldAttribute(nextAttr))
- .map(nextAttr -> new VespaRestartAction(
- new ChangeMessageBuilder(nextAttr.getName())
- .addChange("add attribute aspect").build()))
+ !current.hasStructFieldAttribute(nextAttr))
+ .map(nextAttr -> new VespaRestartAction(id, new ChangeMessageBuilder(nextAttr.getName()).addChange("add attribute aspect").build()))
.collect(Collectors.toList());
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java
index a47c9fdb15b..12d5e8d32ed 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java
@@ -6,7 +6,6 @@ import com.yahoo.config.model.ConfigModelContext;
import com.yahoo.config.model.api.ConfigServerSpec;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.provision.ClusterSpec;
-import java.util.logging.Level;
import com.yahoo.vespa.model.HostResource;
import com.yahoo.vespa.model.HostSystem;
import com.yahoo.vespa.model.admin.Admin;
@@ -22,6 +21,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
+import java.util.logging.Level;
import java.util.stream.Collectors;
/**
@@ -105,7 +105,7 @@ public class DomAdminV4Builder extends DomAdminBuilderBase {
ContainerModel logserverClusterModel = new ContainerModel(context.withParent(admin).withId(logServerCluster.getSubId()));
logserverClusterModel.setCluster(logServerCluster);
- LogserverContainer container = new LogserverContainer(logServerCluster);
+ LogserverContainer container = new LogserverContainer(logServerCluster, deployState.isHosted());
container.setHostResource(hostResource);
container.initService(deployState.getDeployLogger());
logServerCluster.addContainer(container);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/clients/ContainerDocumentApi.java b/config-model/src/main/java/com/yahoo/vespa/model/clients/ContainerDocumentApi.java
index 9018a0231db..bc2e5cc2b8a 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/clients/ContainerDocumentApi.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/clients/ContainerDocumentApi.java
@@ -122,13 +122,13 @@ public class ContainerDocumentApi {
}
private int maxPoolSize() {
- double vcpu = vcpu(cluster);
+ double vcpu = vcpu(cluster).orElse(0);
if (vcpu == 0) return FALLBACK_MAX_POOL_SIZE;
return Math.max(2, (int)Math.ceil(vcpu * feedThreadPoolSizeFactor));
}
private int minPoolSize() {
- double vcpu = vcpu(cluster);
+ double vcpu = vcpu(cluster).orElse(0);
if (vcpu == 0) return FALLBACK_CORE_POOL_SIZE;
return Math.max(1, (int)Math.ceil(vcpu * feedThreadPoolSizeFactor * 0.5));
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainer.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainer.java
index 232552ea4ce..cb8abb919ac 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainer.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainer.java
@@ -26,7 +26,7 @@ public final class ApplicationContainer extends Container implements QrStartConf
}
public ApplicationContainer(AbstractConfigProducer parent, String name, boolean retired, int index, boolean isHostedVespa) {
- super(parent, name, retired, index);
+ super(parent, name, retired, index, isHostedVespa);
this.isHostedVespa = isHostedVespa;
addComponent(getFS4ResourcePool()); // TODO Remove when FS4 based search protocol is gone
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
index 7822b03db08..93717f0f532 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
@@ -8,9 +8,9 @@ import com.yahoo.config.FileReference;
import com.yahoo.config.application.api.ComponentInfo;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.producer.AbstractConfigProducer;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.container.bundle.BundleInstantiationSpecification;
import com.yahoo.container.di.config.ApplicationBundlesConfig;
-import com.yahoo.container.handler.ThreadpoolConfig;
import com.yahoo.container.handler.metrics.MetricsProxyApiConfig;
import com.yahoo.container.handler.metrics.MetricsV2Handler;
import com.yahoo.container.handler.metrics.PrometheusV1Handler;
@@ -82,8 +82,8 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
private Integer memoryPercentage = null;
- public ApplicationContainerCluster(AbstractConfigProducer<?> parent, String subId, String name, DeployState deployState) {
- super(parent, subId, name, deployState);
+ public ApplicationContainerCluster(AbstractConfigProducer<?> parent, String configSubId, String clusterId, DeployState deployState) {
+ super(parent, configSubId, clusterId, deployState);
this.tlsClientAuthority = deployState.tlsClientAuthority();
restApiGroup = new ConfigProducerGroup<>(this, "rest-api");
servletGroup = new ConfigProducerGroup<>(this, "servlet");
@@ -274,10 +274,6 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
null))));
}
- @Override
- public void getConfig(ThreadpoolConfig.Builder builder) {
- }
-
public static class MbusParams {
// the amount of the maxpendingbytes to process concurrently, typically 0.2 (20%)
final Double maxConcurrentFactor;
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java b/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java
index c6de198c06a..ca4140fe5c5 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java
@@ -73,19 +73,19 @@ public abstract class Container extends AbstractService implements
private final ComponentGroup<Handler<?>> handlers = new ComponentGroup<>(this, "handler");
private final ComponentGroup<Component<?, ?>> components = new ComponentGroup<>(this, "components");
- private final JettyHttpServer defaultHttpServer = new JettyHttpServer(new ComponentId("DefaultHttpServer"));
+ private final JettyHttpServer defaultHttpServer;
- protected Container(AbstractConfigProducer parent, String name, int index) {
- this(parent, name, false, index);
+ protected Container(AbstractConfigProducer parent, String name, int index, boolean isHostedVespa) {
+ this(parent, name, false, index, isHostedVespa);
}
- protected Container(AbstractConfigProducer parent, String name, boolean retired, int index) {
+ protected Container(AbstractConfigProducer parent, String name, boolean retired, int index, boolean isHostedVespa) {
super(parent, name);
this.name = name;
this.parent = parent;
this.retired = retired;
this.index = index;
-
+ this.defaultHttpServer = new JettyHttpServer(new ComponentId("DefaultHttpServer"), isHostedVespa);
if (getHttp() == null) {
addChild(defaultHttpServer);
}
@@ -321,7 +321,7 @@ public abstract class Container extends AbstractService implements
FileDistributionConfigProducer fileDistribution = getRoot().getFileDistributionConfigProducer();
if (fileDistribution != null) {
- builder.configid(fileDistribution.getConfigProducer(getHost()).getConfigId());
+ builder.configid(fileDistribution.getConfigProducer(getHost().getHost()).getConfigId());
}
return builder;
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
index 87e8f16f88c..2d7d49f03ed 100755
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
@@ -11,15 +11,14 @@ import com.yahoo.config.docproc.SchemamappingConfig;
import com.yahoo.config.model.ApplicationConfigProducerRoot;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.producer.AbstractConfigProducer;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Zone;
import com.yahoo.container.ComponentsConfig;
import com.yahoo.container.QrSearchersConfig;
import com.yahoo.container.bundle.BundleInstantiationSpecification;
import com.yahoo.container.core.ApplicationMetadataConfig;
import com.yahoo.container.core.document.ContainerDocumentConfig;
-import com.yahoo.container.handler.ThreadPoolProvider;
import com.yahoo.container.di.config.PlatformBundlesConfig;
-import com.yahoo.container.handler.ThreadpoolConfig;
import com.yahoo.container.jdisc.JdiscBindingsConfig;
import com.yahoo.container.jdisc.config.HealthMonitorConfig;
import com.yahoo.container.jdisc.state.StateHandler;
@@ -100,8 +99,7 @@ public abstract class ContainerCluster<CONTAINER extends Container>
DocprocConfig.Producer,
ClusterInfoConfig.Producer,
RoutingProviderConfig.Producer,
- ConfigserverConfig.Producer,
- ThreadpoolConfig.Producer
+ ConfigserverConfig.Producer
{
/**
@@ -160,9 +158,9 @@ public abstract class ContainerCluster<CONTAINER extends Container>
private String jvmGCOptions = null;
private String environmentVars = null;
- public ContainerCluster(AbstractConfigProducer<?> parent, String subId, String name, DeployState deployState) {
- super(parent, subId);
- this.name = name;
+ public ContainerCluster(AbstractConfigProducer<?> parent, String configSubId, String clusterId, DeployState deployState) {
+ super(parent, configSubId);
+ this.name = clusterId;
this.isHostedVespa = stateIsHosted(deployState);
this.zone = (deployState != null) ? deployState.zone() : Zone.defaultZone();
@@ -170,7 +168,7 @@ public abstract class ContainerCluster<CONTAINER extends Container>
addComponent(new StatisticsComponent());
addSimpleComponent(AccessLog.class);
- addSimpleComponent(ThreadPoolProvider.class);
+ addComponent(new DefaultThreadpoolProvider(this, deployState));
addSimpleComponent(com.yahoo.concurrent.classlock.ClassLocking.class);
addSimpleComponent(SecurityFilterInvoker.class);
addSimpleComponent("com.yahoo.container.jdisc.metric.MetricConsumerProviderProvider");
@@ -186,6 +184,8 @@ public abstract class ContainerCluster<CONTAINER extends Container>
addJaxProviders();
}
+ public ClusterSpec.Id id() { return ClusterSpec.Id.from(getName()); }
+
public void setZone(Zone zone) {
this.zone = zone;
}
@@ -617,4 +617,12 @@ public abstract class ContainerCluster<CONTAINER extends Container>
protected abstract boolean messageBusEnabled();
+ /**
+ * Mark that the config emitted by this cluster currently should be applied by clients already running with
+ * a previous generation of it only by restarting the consuming processes.
+ */
+ public void deferChangesUntilRestart() {
+
+ }
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerThreadpool.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerThreadpool.java
index 869248edfbf..93a02833d26 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerThreadpool.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerThreadpool.java
@@ -10,9 +10,8 @@ import com.yahoo.text.XML;
import com.yahoo.vespa.model.container.component.SimpleComponent;
import org.w3c.dom.Element;
-import java.util.List;
import java.util.Optional;
-import java.util.stream.Collectors;
+import java.util.OptionalDouble;
/**
* Component definition for a {@link java.util.concurrent.Executor} using {@link ContainerThreadPool}.
@@ -49,15 +48,11 @@ public class ContainerThreadpool extends SimpleComponent implements ContainerThr
protected Optional<UserOptions> userOptions() { return Optional.ofNullable(userOptions); }
protected boolean hasUserOptions() { return userOptions().isPresent(); }
- protected static double vcpu(ContainerCluster<?> cluster) {
- List<Double> vcpus = cluster.getContainers().stream()
+ protected static OptionalDouble vcpu(ContainerCluster<?> cluster) {
+ return cluster.getContainers().stream()
.filter(c -> c.getHostResource() != null && c.getHostResource().realResources() != null)
- .map(c -> c.getHostResource().realResources().vcpu())
- .distinct()
- .collect(Collectors.toList());
- // We can only use host resource for calculation if all container nodes in the cluster are homogeneous (in terms of vcpu)
- if (vcpus.size() != 1 || vcpus.get(0) == 0) return 0;
- return vcpus.get(0);
+ .mapToDouble(c -> c.getHostResource().realResources().vcpu())
+ .max(); // Use highest vcpu as scale factor
}
public static class UserOptions {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/DefaultThreadpoolProvider.java b/config-model/src/main/java/com/yahoo/vespa/model/container/DefaultThreadpoolProvider.java
new file mode 100644
index 00000000000..17040caf5c2
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/DefaultThreadpoolProvider.java
@@ -0,0 +1,52 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.container;
+
+import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.container.bundle.BundleInstantiationSpecification;
+import com.yahoo.container.handler.ThreadPoolProvider;
+import com.yahoo.container.handler.ThreadpoolConfig;
+import com.yahoo.osgi.provider.model.ComponentModel;
+import com.yahoo.vespa.model.container.component.SimpleComponent;
+
+/**
+ * Component definition for the jdisc default threadpool provider ({@link ThreadPoolProvider}).
+ *
+ * @author bjorncs
+ */
+class DefaultThreadpoolProvider extends SimpleComponent implements ThreadpoolConfig.Producer {
+
+ private final ContainerCluster<?> cluster;
+ private final DeployState deployState;
+
+ DefaultThreadpoolProvider(ContainerCluster<?> cluster, DeployState deployState) {
+ super(new ComponentModel(
+ BundleInstantiationSpecification.getFromStrings(
+ "default-threadpool",
+ ThreadPoolProvider.class.getName(),
+ null)));
+ this.cluster = cluster;
+ this.deployState = deployState;
+ }
+
+ @Override
+ public void getConfig(ThreadpoolConfig.Builder builder) {
+ if (!(cluster instanceof ApplicationContainerCluster)) {
+ // Container clusters such as logserver, metricsproxy and clustercontroller
+ int defaultWorkerThreads = 10;
+ builder.maxthreads(defaultWorkerThreads);
+ builder.corePoolSize(defaultWorkerThreads);
+ builder.queueSize(50);
+ return;
+ }
+
+ double threadPoolSizeFactor = deployState.getProperties().threadPoolSizeFactor();
+ double vcpu = ContainerThreadpool.vcpu(cluster).orElse(0);
+ if (threadPoolSizeFactor <= 0 || vcpu == 0) return;
+
+ // Configuration is currently identical to the search handler's threadpool
+ int workerThreads = Math.max(16, (int)Math.ceil(vcpu * threadPoolSizeFactor)); // TODO(bjorncs): reduce minimum size
+ builder.maxthreads(workerThreads);
+ builder.corePoolSize(workerThreads);
+ builder.queueSize((int)(workerThreads * deployState.getProperties().queueSizeFactor()));
+ }
+}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java
index 1350e105406..98fde2e7859 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java
@@ -15,19 +15,21 @@ import java.util.List;
import static com.yahoo.component.ComponentSpecification.fromString;
/**
- * @author <a href="mailto:einarmr@yahoo-inc.com">Einar M R Rosenvinge</a>
- * @since 5.16.0
+ * @author Einar M R Rosenvinge
+ * @author bjorncs
*/
public class JettyHttpServer extends SimpleComponent implements ServerConfig.Producer {
- private List<ConnectorFactory> connectorFactories = new ArrayList<>();
+ private final boolean isHostedVespa;
+ private final List<ConnectorFactory> connectorFactories = new ArrayList<>();
- public JettyHttpServer(ComponentId id) {
+ public JettyHttpServer(ComponentId id, boolean isHostedVespa) {
super(new ComponentModel(
new BundleInstantiationSpecification(id,
fromString("com.yahoo.jdisc.http.server.jetty.JettyHttpServer"),
fromString("jdisc_http_service"))
));
+ this.isHostedVespa = isHostedVespa;
final FilterBindingsProviderComponent filterBindingsProviderComponent = new FilterBindingsProviderComponent(id);
addChild(filterBindingsProviderComponent);
inject(filterBindingsProviderComponent);
@@ -56,6 +58,17 @@ public class JettyHttpServer extends SimpleComponent implements ServerConfig.Pro
.monitoringHandlerPaths(List.of("/state/v1", "/status.html"))
.searchHandlerPaths(List.of("/search"))
);
+ if (isHostedVespa) {
+ // Proxy-protocol v1/v2 is used in hosted Vespa for remote address/port
+ builder.accessLog(new ServerConfig.AccessLog.Builder()
+ .remoteAddressHeaders(List.of())
+ .remotePortHeaders(List.of()));
+ } else {
+ // TODO Vespa 8: Remove legacy Yahoo headers
+ builder.accessLog(new ServerConfig.AccessLog.Builder()
+ .remoteAddressHeaders(List.of("x-forwarded-for", "y-ra", "yahooremoteip", "client-ip"))
+ .remotePortHeaders(List.of("X-Forwarded-Port", "y-rp")));
+ }
}
static ComponentModel providerComponentModel(final ComponentId parentId, String className) {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyHttpServerBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyHttpServerBuilder.java
index 3f38b2b16fa..cc9cd61df36 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyHttpServerBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyHttpServerBuilder.java
@@ -17,7 +17,7 @@ public class JettyHttpServerBuilder extends VespaDomBuilder.DomConfigProducerBui
@Override
protected JettyHttpServer doBuild(DeployState deployState, AbstractConfigProducer ancestor, Element http) {
- JettyHttpServer jettyHttpServer = new JettyHttpServer(new ComponentId("jdisc-jetty"));
+ JettyHttpServer jettyHttpServer = new JettyHttpServer(new ComponentId("jdisc-jetty"), deployState.isHosted());
for (Element serverSpec: XML.getChildren(http, "server")) {
ConnectorFactory connectorFactory = new JettyConnectorBuilder().build(deployState, ancestor, serverSpec);
jettyHttpServer.addConnector(connectorFactory);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
index 638c02caf55..dee03fb58d3 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
@@ -353,7 +353,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
cluster.setHttp(new Http(new FilterChains(cluster)));
}
if(cluster.getHttp().getHttpServer().isEmpty()) {
- JettyHttpServer defaultHttpServer = new JettyHttpServer(new ComponentId("DefaultHttpServer"));
+ JettyHttpServer defaultHttpServer = new JettyHttpServer(new ComponentId("DefaultHttpServer"), cluster.isHostedVespa());
cluster.getHttp().setHttpServer(defaultHttpServer);
defaultHttpServer.addConnector(new ConnectorFactory("SearchServer", Defaults.getDefaults().vespaWebServicePort()));
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/SearchHandler.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/SearchHandler.java
index 81ab2cc1503..8438214f1fd 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/SearchHandler.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/SearchHandler.java
@@ -57,14 +57,14 @@ class SearchHandler extends ProcessingHandler<SearchChains> {
if (hasUserOptions()) return;
double threadPoolSizeFactor = deployState.getProperties().threadPoolSizeFactor();
- double vcpu = vcpu(cluster);
+ double vcpu = vcpu(cluster).orElse(0);
if (threadPoolSizeFactor <= 0 || vcpu == 0) {
builder.maxThreads(500);
builder.minThreads(500);
builder.queueSize(0);
} else {
// Controls max number of concurrent requests per container
- int workerThreads = Math.max(2, (int)Math.ceil(vcpu * threadPoolSizeFactor));
+ int workerThreads = Math.max(16, (int)Math.ceil(vcpu * threadPoolSizeFactor)); // TODO(bjorncs): reduce minimum size
builder.maxThreads(workerThreads);
builder.minThreads(workerThreads);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java
index 9923cb2fece..1a994cd4636 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java
@@ -91,7 +91,7 @@ public class ContentCluster extends AbstractConfigProducer implements
private Redundancy redundancy;
private ClusterControllerConfig clusterControllerConfig;
private PersistenceEngine.PersistenceFactory persistenceFactory;
- private final String clusterName;
+ private final String clusterId;
private Integer maxNodesPerMerge;
private final Zone zone;
@@ -138,7 +138,7 @@ public class ContentCluster extends AbstractConfigProducer implements
c.storageNodes = new StorageCluster.Builder().build(deployState, c, w3cContentElement);
c.distributorNodes = new DistributorCluster.Builder(c).build(deployState, c, w3cContentElement);
c.rootGroup = new StorageGroup.Builder(contentElement, context).buildRootGroup(deployState, redundancyBuilder, c);
- validateThatGroupSiblingsAreUnique(c.clusterName, c.rootGroup);
+ validateThatGroupSiblingsAreUnique(c.clusterId, c.rootGroup);
c.search.handleRedundancy(c.redundancy);
setupSearchCluster(c.search, contentElement, deployState.getDeployLogger());
@@ -163,7 +163,7 @@ public class ContentCluster extends AbstractConfigProducer implements
if (context.getParentProducer().getRoot() == null) return c;
- addClusterControllers(containers, context, c.rootGroup, contentElement, c.clusterName, c);
+ addClusterControllers(containers, context, c.rootGroup, contentElement, c.clusterId, c);
return c;
}
@@ -492,19 +492,21 @@ public class ContentCluster extends AbstractConfigProducer implements
}
- private ContentCluster(AbstractConfigProducer parent, String clusterName,
+ private ContentCluster(AbstractConfigProducer parent, String clusterId,
Map<String, NewDocumentType> documentDefinitions,
Set<NewDocumentType> globallyDistributedDocuments,
String routingSelection, Zone zone, boolean isHosted) {
- super(parent, clusterName);
+ super(parent, clusterId);
this.isHosted = isHosted;
- this.clusterName = clusterName;
+ this.clusterId = clusterId;
this.documentDefinitions = documentDefinitions;
this.globallyDistributedDocuments = globallyDistributedDocuments;
this.documentSelection = routingSelection;
this.zone = zone;
}
+ public ClusterSpec.Id id() { return ClusterSpec.Id.from(clusterId); }
+
public void prepare(DeployState deployState) {
search.prepare();
@@ -525,7 +527,7 @@ public class ContentCluster extends AbstractConfigProducer implements
return clusterId != null ? clusterId : "content";
}
- public String getName() { return clusterName; }
+ public String getName() { return clusterId; }
public String getRoutingSelector() { return documentSelection; }
@@ -740,4 +742,13 @@ public class ContentCluster extends AbstractConfigProducer implements
builder.documenttype(docTypeBuilder);
}
}
+
+ /**
+ * Mark that the config emitted by this cluster currently should be applied by clients already running with
+ * a previous generation of it only by restarting the consuming processes.
+ */
+ public void deferChangesUntilRestart() {
+
+ }
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/storagecluster/StorageCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/content/storagecluster/StorageCluster.java
index 981ce1bc004..bacb22b0b89 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/content/storagecluster/StorageCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/content/storagecluster/StorageCluster.java
@@ -45,13 +45,12 @@ public class StorageCluster extends AbstractConfigProducer<StorageNode>
}
}
- private Integer bucketMoverMaxFillAboveAverage = null;
- private String clusterName;
- private FileStorProducer fileStorProducer;
- private IntegrityCheckerProducer integrityCheckerProducer;
- private StorServerProducer storServerProducer;
- private StorVisitorProducer storVisitorProducer;
- private PersistenceProducer persistenceProducer;
+ private final String clusterName;
+ private final FileStorProducer fileStorProducer;
+ private final IntegrityCheckerProducer integrityCheckerProducer;
+ private final StorServerProducer storServerProducer;
+ private final StorVisitorProducer storVisitorProducer;
+ private final PersistenceProducer persistenceProducer;
StorageCluster(AbstractConfigProducer parent,
String clusterName,
@@ -71,9 +70,6 @@ public class StorageCluster extends AbstractConfigProducer<StorageNode>
@Override
public void getConfig(StorBucketmoverConfig.Builder builder) {
- if (bucketMoverMaxFillAboveAverage != null) {
- builder.max_target_fill_rate_above_average(bucketMoverMaxFillAboveAverage);
- }
}
@Override
@@ -127,4 +123,5 @@ public class StorageCluster extends AbstractConfigProducer<StorageNode>
public void getConfig(StorFilestorConfig.Builder builder) {
fileStorProducer.getConfig(builder);
}
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java b/config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java
index b44040f843d..534bab4677c 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java
@@ -259,7 +259,7 @@ public class SearchNode extends AbstractService implements
public void getConfig(FiledistributorrpcConfig.Builder builder) {
FileDistributionConfigProducer fileDistribution = getRoot().getFileDistributionConfigProducer();
if (fileDistribution != null) {
- FileDistributionConfigProvider configProducer = fileDistribution.getConfigProducer(getHost());
+ FileDistributionConfigProvider configProducer = fileDistribution.getConfigProducer(getHost().getHost());
configProducer.getConfig(builder);
}
}
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 1be58564d1b..26d8a9b0eca 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
@@ -444,12 +444,14 @@ public class ModelProvisioningTest {
// Check container cluster
assertEquals(1, model.getContainerClusters().size());
- Set<com.yahoo.vespa.model.Host> containerHosts = model.getContainerClusters().get("foo").getContainers().stream().map(Container::getHost).collect(Collectors.toSet());
+ Set<HostResource> containerHosts = model.getContainerClusters().get("foo").getContainers().stream()
+ .map(Container::getHost)
+ .collect(Collectors.toSet());
assertEquals(10, containerHosts.size());
// Check admin clusters
Admin admin = model.getAdmin();
- Set<com.yahoo.vespa.model.Host> slobrokHosts = admin.getSlobroks().stream().map(Slobrok::getHost).collect(Collectors.toSet());
+ Set<HostResource> slobrokHosts = admin.getSlobroks().stream().map(Slobrok::getHost).collect(Collectors.toSet());
assertEquals(3, slobrokHosts.size());
assertTrue("Slobroks are assigned from container nodes", containerHosts.containsAll(slobrokHosts));
assertTrue("Logserver is assigned from container nodes", containerHosts.contains(admin.getLogserver().getHost()));
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ConfigChangeTestUtils.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ConfigChangeTestUtils.java
index 65ac6c7625e..4fd2609eb67 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ConfigChangeTestUtils.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ConfigChangeTestUtils.java
@@ -4,8 +4,10 @@ package com.yahoo.vespa.model.application.validation.change;
import com.yahoo.config.model.api.ConfigChangeAction;
import com.yahoo.config.model.api.ServiceInfo;
import com.yahoo.config.application.api.ValidationOverrides;
+import com.yahoo.config.provision.ClusterSpec;
import java.time.Instant;
+import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@@ -14,25 +16,25 @@ import static org.junit.Assert.assertThat;
public class ConfigChangeTestUtils {
- public static VespaConfigChangeAction newRestartAction(String message) {
- return new VespaRestartAction(message);
+ public static VespaConfigChangeAction newRestartAction(ClusterSpec.Id id, String message) {
+ return new VespaRestartAction(id, message);
}
- public static VespaConfigChangeAction newRestartAction(String message, List<ServiceInfo> services) {
- return new VespaRestartAction(message, services);
+ public static VespaConfigChangeAction newRestartAction(ClusterSpec.Id id, String message, List<ServiceInfo> services) {
+ return new VespaRestartAction(id, message, services);
}
- public static VespaConfigChangeAction newRefeedAction(String name, String message) {
- return VespaRefeedAction.of(name, ValidationOverrides.empty, message, Instant.now());
+ public static VespaConfigChangeAction newRefeedAction(ClusterSpec.Id id, String name, String message) {
+ return VespaRefeedAction.of(id, name, ValidationOverrides.empty, message, Instant.now());
}
- public static VespaConfigChangeAction newRefeedAction(String name, ValidationOverrides overrides, String message, Instant now) {
- return VespaRefeedAction.of(name, overrides, message, now);
+ public static VespaConfigChangeAction newRefeedAction(ClusterSpec.Id id, String name, ValidationOverrides overrides, String message, Instant now) {
+ return VespaRefeedAction.of(id, name, overrides, message, now);
}
- public static VespaConfigChangeAction newRefeedAction(String name, ValidationOverrides overrides, String message,
+ public static VespaConfigChangeAction newRefeedAction(ClusterSpec.Id id, String name, ValidationOverrides overrides, String message,
List<ServiceInfo> services, String documentType, Instant now) {
- return VespaRefeedAction.of(name, overrides, message, services, documentType, now);
+ return VespaRefeedAction.of(id, name, overrides, message, services, documentType, now);
}
public static List<ConfigChangeAction> normalizeServicesInActions(List<ConfigChangeAction> result) {
@@ -53,9 +55,11 @@ public class ConfigChangeTestUtils {
}
public static void assertEqualActions(List<ConfigChangeAction> exp, List<ConfigChangeAction> act) {
- exp.sort((lhs, rhs) -> lhs.getMessage().compareTo(rhs.getMessage()));
- act.sort((lhs, rhs) -> lhs.getMessage().compareTo(rhs.getMessage()));
- assertThat(act, equalTo(exp));
+ var mutableExp = new ArrayList<>(exp);
+ var mutableAct = new ArrayList<>(act);
+ mutableExp.sort((lhs, rhs) -> lhs.getMessage().compareTo(rhs.getMessage()));
+ mutableAct.sort((lhs, rhs) -> lhs.getMessage().compareTo(rhs.getMessage()));
+ assertThat(mutableAct, equalTo(mutableExp));
}
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/IndexedSearchClusterChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/IndexedSearchClusterChangeValidatorTest.java
index 80127ac6854..8d365f24c7f 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/IndexedSearchClusterChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/IndexedSearchClusterChangeValidatorTest.java
@@ -3,6 +3,7 @@ package com.yahoo.vespa.model.application.validation.change;
import com.yahoo.config.model.api.ConfigChangeAction;
import com.yahoo.config.model.api.ServiceInfo;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.model.VespaModel;
import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.vespa.model.content.utils.ApplicationPackageBuilder;
@@ -11,15 +12,13 @@ import com.yahoo.vespa.model.content.utils.SchemaBuilder;
import org.junit.Test;
import java.time.Instant;
-import java.util.Arrays;
import java.util.List;
import static com.yahoo.vespa.model.application.validation.change.ConfigChangeTestUtils.assertEqualActions;
import static com.yahoo.vespa.model.application.validation.change.ConfigChangeTestUtils.newRefeedAction;
import static com.yahoo.vespa.model.application.validation.change.ConfigChangeTestUtils.newRestartAction;
import static com.yahoo.vespa.model.application.validation.change.ConfigChangeTestUtils.normalizeServicesInActions;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
public class IndexedSearchClusterChangeValidatorTest {
@@ -40,9 +39,9 @@ public class IndexedSearchClusterChangeValidatorTest {
public static VespaModel newOneDocModel(String sdContent) {
return new ApplicationPackageBuilder().
- addCluster(new ContentClusterBuilder().name("foo").docTypes("d1")).
- addSchemas(new SchemaBuilder().
- name("d1").content(sdContent).build()).buildCreator().create();
+ addCluster(new ContentClusterBuilder().name("foo").docTypes("d1"))
+ .addSchemas(new SchemaBuilder().name("d1").content(sdContent).build())
+ .buildCreator().create();
}
public static Fixture newTwoDocFixture(String currentSd, String nextSd) {
@@ -51,11 +50,9 @@ public class IndexedSearchClusterChangeValidatorTest {
public static VespaModel newTwoDocModel(String d1Content, String d2Content) {
return new ApplicationPackageBuilder().
- addCluster(new ContentClusterBuilder().name("foo").docTypes("d1", "d2")).
- addSchemas(new SchemaBuilder().
- name("d1").content(d1Content).build()).
- addSchemas(new SchemaBuilder().
- name("d2").content(d2Content).build()).
+ addCluster(new ContentClusterBuilder().name("foo").docTypes("d1", "d2"))
+ .addSchemas(new SchemaBuilder().name("d1").content(d1Content).build())
+ .addSchemas(new SchemaBuilder().name("d2").content(d2Content).build()).
buildCreator().create();
}
@@ -66,25 +63,23 @@ public class IndexedSearchClusterChangeValidatorTest {
public static VespaModel newTwoClusterModel(String d1Content, String d2Content) {
return new ApplicationPackageBuilder().
addCluster(new ContentClusterBuilder().name("foo").docTypes("d1")).
- addCluster(new ContentClusterBuilder().name("bar").docTypes("d2")).
- addSchemas(new SchemaBuilder().
- name("d1").content(d1Content).build()).
- addSchemas(new SchemaBuilder().
- name("d2").content(d2Content).build()).
+ addCluster(new ContentClusterBuilder().name("bar").docTypes("d2"))
+ .addSchemas(new SchemaBuilder().name("d1").content(d1Content).build())
+ .addSchemas(new SchemaBuilder().name("d2").content(d2Content).build()).
buildCreator().create();
}
private List<ConfigChangeAction> validate() {
return normalizeServicesInActions(validator.validate(currentModel, nextModel,
- ValidationOverrides.empty, Instant.now()));
+ ValidationOverrides.empty, Instant.now()));
}
public void assertValidation() {
- assertThat(validate().size(), is(0));
+ assertTrue(validate().isEmpty());
}
public void assertValidation(ConfigChangeAction exp) {
- assertValidation(Arrays.asList(exp));
+ assertValidation(List.of(exp));
}
public void assertValidation(List<ConfigChangeAction> exp) {
@@ -97,31 +92,34 @@ public class IndexedSearchClusterChangeValidatorTest {
static String ATTRIBUTE_CHANGE_MSG = "Field 'f1' changed: add attribute aspect";
static String INT_FIELD = "field f1 type int { indexing: summary }";
static String FIELD_TYPE_CHANGE_MSG = "Field 'f1' changed: data type: 'string' -> 'int'";
- private static List<ServiceInfo> FOO_SERVICE = Arrays.asList(
+ private static final List<ServiceInfo> FOO_SERVICE = List.of(
new ServiceInfo("searchnode", "null", null, null, "foo/search/cluster.foo/0", "null"));
- private static List<ServiceInfo> BAR_SERVICE = Arrays.asList(
+ private static final List<ServiceInfo> BAR_SERVICE = List.of(
new ServiceInfo("searchnode2", "null", null, null, "bar/search/cluster.bar/0", "null"));
@Test
public void requireThatDocumentDatabaseChangeIsDiscovered() {
Fixture.newOneDocFixture(STRING_FIELD, ATTRIBUTE_FIELD).
- assertValidation(newRestartAction("Document type 'd1': " + ATTRIBUTE_CHANGE_MSG, FOO_SERVICE));
+ assertValidation(newRestartAction(ClusterSpec.Id.from("test"),
+ "Document type 'd1': " + ATTRIBUTE_CHANGE_MSG, FOO_SERVICE));
}
@Test
public void requireThatChangeInSeveralDocumentDatabasesAreDiscovered() {
Fixture.newTwoDocFixture(STRING_FIELD, ATTRIBUTE_FIELD).
- assertValidation(Arrays.asList(newRestartAction("Document type 'd1': "
- + ATTRIBUTE_CHANGE_MSG, FOO_SERVICE),
- newRestartAction("Document type 'd2': " + ATTRIBUTE_CHANGE_MSG, FOO_SERVICE)));
+ assertValidation(List.of(newRestartAction(ClusterSpec.Id.from("test"),
+ "Document type 'd1': " + ATTRIBUTE_CHANGE_MSG, FOO_SERVICE),
+ newRestartAction(ClusterSpec.Id.from("test"),
+ "Document type 'd2': " + ATTRIBUTE_CHANGE_MSG, FOO_SERVICE)));
}
@Test
public void requireThatChangeInSeveralContentClustersAreDiscovered() {
Fixture.newTwoClusterFixture(STRING_FIELD, ATTRIBUTE_FIELD).
- assertValidation(Arrays.asList(newRestartAction("Document type 'd1': "
- + ATTRIBUTE_CHANGE_MSG, FOO_SERVICE),
- newRestartAction("Document type 'd2': " + ATTRIBUTE_CHANGE_MSG, BAR_SERVICE)));
+ assertValidation(List.of(newRestartAction(ClusterSpec.Id.from("test"),
+ "Document type 'd1': " + ATTRIBUTE_CHANGE_MSG, FOO_SERVICE),
+ newRestartAction(ClusterSpec.Id.from("test"),
+ "Document type 'd2': " + ATTRIBUTE_CHANGE_MSG, BAR_SERVICE)));
}
@Test
@@ -147,9 +145,10 @@ public class IndexedSearchClusterChangeValidatorTest {
@Test
public void requireThatChangingFieldTypeIsDiscovered() {
Fixture f = Fixture.newOneDocFixture(STRING_FIELD, INT_FIELD);
- f.assertValidation(Arrays.asList(newRefeedAction("field-type-change",
- ValidationOverrides.empty,
- "Document type 'd1': " + FIELD_TYPE_CHANGE_MSG, FOO_SERVICE, "d1", Instant.now())));
+ f.assertValidation(List.of(newRefeedAction(ClusterSpec.Id.from("test"),
+ "field-type-change",
+ ValidationOverrides.empty,
+ "Document type 'd1': " + FIELD_TYPE_CHANGE_MSG, FOO_SERVICE, "d1", Instant.now())));
}
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/NodeResourceChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/NodeResourceChangeValidatorTest.java
new file mode 100644
index 00000000000..ecf026e7d88
--- /dev/null
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/NodeResourceChangeValidatorTest.java
@@ -0,0 +1,129 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.application.validation.change;
+
+import com.yahoo.config.application.api.ValidationOverrides;
+import com.yahoo.config.model.api.ConfigChangeAction;
+import com.yahoo.config.model.api.HostProvisioner;
+import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.config.model.deploy.TestProperties;
+import com.yahoo.config.provision.Capacity;
+import com.yahoo.config.provision.ClusterMembership;
+import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.HostSpec;
+import com.yahoo.config.provision.ProvisionLogger;
+import com.yahoo.vespa.model.VespaModel;
+import com.yahoo.vespa.model.test.utils.VespaModelCreatorWithMockPkg;
+import org.junit.Test;
+
+import java.time.Clock;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author bratseth
+ */
+public class NodeResourceChangeValidatorTest {
+
+ @Test
+ public void test_restart_action_count() {
+ assertEquals(0, validate(model(1, 1, 1, 1), model(1, 1, 1, 1)).size());
+ assertEquals(1, validate(model(1, 1, 1, 1), model(2, 1, 1, 1)).size());
+ assertEquals(2, validate(model(1, 1, 1, 1), model(1, 2, 1, 1)).size());
+ assertEquals(3, validate(model(1, 1, 1, 1), model(1, 1, 2, 1)).size());
+ assertEquals(4, validate(model(1, 1, 1, 1), model(1, 1, 1, 2)).size());
+ assertEquals(5, validate(model(1, 1, 1, 1), model(2, 1, 1, 2)).size());
+ assertEquals(6, validate(model(1, 1, 1, 1), model(1, 2, 1, 2)).size());
+ assertEquals(7, validate(model(1, 1, 1, 1), model(1, 1, 2, 2)).size());
+ assertEquals(8, validate(model(1, 1, 1, 1), model(2, 1, 2, 2)).size());
+ assertEquals(9, validate(model(1, 1, 1, 1), model(1, 2, 2, 2)).size());
+ assertEquals(10, validate(model(1, 1, 1, 1), model(2, 2, 2, 2)).size());
+ }
+
+ @Test
+ public void test_restart_action_details() {
+ ConfigChangeAction containerAction = validate(model(1, 1, 1, 1), model(2, 1, 1, 1)).get(0);
+ assertEquals(ConfigChangeAction.Type.RESTART, containerAction.getType());
+ assertEquals("service 'container' of type container on host0", containerAction.getServices().get(0).toString());
+ assertEquals(false, containerAction.ignoreForInternalRedeploy());
+
+ ConfigChangeAction contentAction = validate(model(1, 1, 1, 1), model(1, 1, 2, 1)).get(0);
+ assertEquals(ConfigChangeAction.Type.RESTART, contentAction.getType());
+ assertEquals("service 'searchnode' of type searchnode on host3", contentAction.getServices().get(0).toString());
+ assertEquals(false, contentAction.ignoreForInternalRedeploy());
+ }
+
+ private List<ConfigChangeAction> validate(VespaModel current, VespaModel next) {
+ return new NodeResourceChangeValidator().validate(current, next,
+ ValidationOverrides.empty,
+ Clock.systemUTC().instant());
+ }
+
+ private static VespaModel model(int mem1, int mem2, int mem3, int mem4) {
+ var properties = new TestProperties();
+ properties.setHostedVespa(true);
+ var deployState = new DeployState.Builder().properties(properties)
+ .modelHostProvisioner(new Provisioner());
+ return new VespaModelCreatorWithMockPkg(
+ null,
+ "<?xml version='1.0' encoding='utf-8' ?>\n" +
+ "<services version='1.0'>\n" +
+ " <container id='container1' version='1.0'>\n" +
+ " <nodes count='1'>\n" +
+ " <resources vcpu='1' memory='" + mem1 + "Gb' disk='100Gb'/>" +
+ " </nodes>\n" +
+ " </container>\n" +
+ " <container id='container2' version='1.0'>\n" +
+ " <nodes count='2'>\n" +
+ " <resources vcpu='1' memory='" + mem2 + "Gb' disk='100Gb'/>" +
+ " </nodes>\n" +
+ " </container>\n" +
+ " <content id='content1' version='1.0'>\n" +
+ " <nodes count='3'>\n" +
+ " <resources vcpu='1' memory='" + mem3 + "Gb' disk='100Gb'/>" +
+ " </nodes>\n" +
+ " <documents>\n" +
+ " <document mode='index' type='test'/>\n" +
+ " </documents>\n" +
+ " <redundancy>2</redundancy>\n" +
+ " </content>\n" +
+ " <content id='content2' version='1.0'>\n" +
+ " <nodes count='4'>\n" +
+ " <resources vcpu='1' memory='" + mem4 + "Gb' disk='100Gb'/>" +
+ " </nodes>\n" +
+ " <documents>\n" +
+ " <document mode='streaming' type='test'/>\n" +
+ " </documents>\n" +
+ " <redundancy>2</redundancy>\n" +
+ " </content>\n" +
+ "</services>",
+ List.of("schema test { document test {} }"))
+ .create(deployState);
+ }
+
+ private static class Provisioner implements HostProvisioner {
+
+ private int hostsCreated = 0;
+
+ @Override
+ public HostSpec allocateHost(String alias) {
+ return new HostSpec(alias, List.of(), Optional.empty());
+ }
+
+ @Override
+ public List<HostSpec> prepare(ClusterSpec cluster, Capacity capacity, ProvisionLogger logger) {
+ List<HostSpec> hosts = new ArrayList<>();
+ var resources = capacity.minResources().nodeResources();
+ for (int i = 0; i < capacity.minResources().nodes(); i++)
+ hosts.add(new HostSpec("host" + (hostsCreated++),
+ resources, resources, resources,
+ ClusterMembership.from(cluster, i),
+ Optional.empty(), Optional.empty(), Optional.empty()));
+ return hosts;
+ }
+
+ }
+
+}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/StreamingSearchClusterChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/StreamingSearchClusterChangeValidatorTest.java
index 8edbc964bfb..f5ef50ee3a4 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/StreamingSearchClusterChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/StreamingSearchClusterChangeValidatorTest.java
@@ -3,6 +3,7 @@ package com.yahoo.vespa.model.application.validation.change;
import com.yahoo.config.model.api.ConfigChangeAction;
import com.yahoo.config.model.api.ServiceInfo;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.model.VespaModel;
import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.vespa.model.content.utils.ApplicationPackageBuilder;
@@ -162,18 +163,23 @@ public class StreamingSearchClusterChangeValidatorTest {
}
private static VespaConfigChangeAction createFieldTypeChangeRefeedAction(String docType, List<ServiceInfo> service) {
- return ConfigChangeTestUtils.newRefeedAction("field-type-change",
- ValidationOverrides.empty,
+ return ConfigChangeTestUtils.newRefeedAction(ClusterSpec.Id.from("test"),
+ "field-type-change",
+ ValidationOverrides.empty,
"Document type '" + docType + "': Field 'f1' changed: data type: 'string' -> 'int'",
- service, docType, Instant.now());
+ service, docType, Instant.now());
}
private static VespaConfigChangeAction createAddFastAccessRestartAction() {
- return ConfigChangeTestUtils.newRestartAction("Document type 'd1': Field 'f1' changed: add fast-access attribute", FOO_SERVICE);
+ return ConfigChangeTestUtils.newRestartAction(ClusterSpec.Id.from("test"),
+ "Document type 'd1': Field 'f1' changed: add fast-access attribute",
+ FOO_SERVICE);
}
private static VespaConfigChangeAction createRemoveFastAccessRestartAction() {
- return ConfigChangeTestUtils.newRestartAction("Document type 'd1': Field 'f1' changed: remove fast-access attribute", FOO_SERVICE);
+ return ConfigChangeTestUtils.newRestartAction(ClusterSpec.Id.from("test"),
+ "Document type 'd1': Field 'f1' changed: remove fast-access attribute",
+ FOO_SERVICE);
}
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidatorTest.java
index e00b34d4a79..168ee797fbf 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidatorTest.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.model.application.validation.change.search;
import com.yahoo.config.application.api.ValidationOverrides;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.model.application.validation.change.VespaConfigChangeAction;
import org.junit.Test;
@@ -18,12 +19,13 @@ public class AttributeChangeValidatorTest {
public Fixture(String currentSd, String nextSd) throws Exception {
super(currentSd, nextSd);
- validator = new AttributeChangeValidator(currentDb().getDerivedConfiguration().getAttributeFields(),
- currentDb().getDerivedConfiguration().getIndexSchema(),
- currentDocType(),
- nextDb().getDerivedConfiguration().getAttributeFields(),
- nextDb().getDerivedConfiguration().getIndexSchema(),
- nextDocType());
+ validator = new AttributeChangeValidator(ClusterSpec.Id.from("test"),
+ currentDb().getDerivedConfiguration().getAttributeFields(),
+ currentDb().getDerivedConfiguration().getIndexSchema(),
+ currentDocType(),
+ nextDb().getDerivedConfiguration().getAttributeFields(),
+ nextDb().getDerivedConfiguration().getIndexSchema(),
+ nextDocType());
}
@Override
@@ -37,16 +39,16 @@ public class AttributeChangeValidatorTest {
public void adding_attribute_aspect_require_restart() throws Exception {
Fixture f = new Fixture("field f1 type string { indexing: summary }",
"field f1 type string { indexing: attribute | summary }");
- f.assertValidation(newRestartAction(
- "Field 'f1' changed: add attribute aspect"));
+ f.assertValidation(newRestartAction(ClusterSpec.Id.from("test"),
+ "Field 'f1' changed: add attribute aspect"));
}
@Test
public void removing_attribute_aspect_require_restart() throws Exception {
Fixture f = new Fixture("field f1 type string { indexing: attribute | summary }",
"field f1 type string { indexing: summary }");
- f.assertValidation(newRestartAction(
- "Field 'f1' changed: remove attribute aspect"));
+ f.assertValidation(newRestartAction(ClusterSpec.Id.from("test"),
+ "Field 'f1' changed: remove attribute aspect"));
}
@Test
@@ -65,24 +67,24 @@ public class AttributeChangeValidatorTest {
public void changing_fast_search_require_restart() throws Exception {
new Fixture("field f1 type string { indexing: attribute }",
"field f1 type string { indexing: attribute \n attribute: fast-search }").
- assertValidation(newRestartAction(
- "Field 'f1' changed: add attribute 'fast-search'"));
+ assertValidation(newRestartAction(ClusterSpec.Id.from("test"),
+ "Field 'f1' changed: add attribute 'fast-search'"));
}
@Test
public void changing_fast_access_require_restart() throws Exception {
new Fixture("field f1 type string { indexing: attribute \n attribute: fast-access }",
"field f1 type string { indexing: attribute }").
- assertValidation(newRestartAction(
- "Field 'f1' changed: remove attribute 'fast-access'"));
+ assertValidation(newRestartAction(ClusterSpec.Id.from("test"),
+ "Field 'f1' changed: remove attribute 'fast-access'"));
}
@Test
public void changing_huge_require_restart() throws Exception {
new Fixture("field f1 type string { indexing: attribute }",
"field f1 type string { indexing: attribute \n attribute: huge }").
- assertValidation(newRestartAction(
- "Field 'f1' changed: add attribute 'huge'"));
+ assertValidation(newRestartAction(ClusterSpec.Id.from("test"),
+ "Field 'f1' changed: add attribute 'huge'"));
}
@Test
@@ -90,8 +92,8 @@ public class AttributeChangeValidatorTest {
new Fixture(
"field f1 type predicate { indexing: attribute \n index { arity: 8 \n dense-posting-list-threshold: 0.2 } }",
"field f1 type predicate { indexing: attribute \n index { arity: 8 \n dense-posting-list-threshold: 0.4 } }").
- assertValidation(newRestartAction(
- "Field 'f1' changed: change property 'dense-posting-list-threshold' from '0.2' to '0.4'"));
+ assertValidation(newRestartAction(ClusterSpec.Id.from("test"),
+ "Field 'f1' changed: change property 'dense-posting-list-threshold' from '0.2' to '0.4'"));
}
@Test
@@ -113,18 +115,18 @@ public class AttributeChangeValidatorTest {
new Fixture(
"field f1 type tensor(x[2]) { indexing: attribute }",
"field f1 type tensor(x[3]) { indexing: attribute }")
- .assertValidation(newRefeedAction(
- "tensor-type-change",
- ValidationOverrides.empty,
- "Field 'f1' changed: tensor type: 'tensor(x[2])' -> 'tensor(x[3])'", Instant.now()));
+ .assertValidation(newRefeedAction(ClusterSpec.Id.from("test"),
+ "tensor-type-change",
+ ValidationOverrides.empty,
+ "Field 'f1' changed: tensor type: 'tensor(x[2])' -> 'tensor(x[3])'", Instant.now()));
new Fixture(
"field f1 type tensor(x[5]) { indexing: attribute }",
"field f1 type tensor(x[3]) { indexing: attribute }")
- .assertValidation(newRefeedAction(
- "tensor-type-change",
- ValidationOverrides.empty,
- "Field 'f1' changed: tensor type: 'tensor(x[5])' -> 'tensor(x[3])'", Instant.now()));
+ .assertValidation(newRefeedAction(ClusterSpec.Id.from("test"),
+ "tensor-type-change",
+ ValidationOverrides.empty,
+ "Field 'f1' changed: tensor type: 'tensor(x[5])' -> 'tensor(x[3])'", Instant.now()));
}
@Test
@@ -139,32 +141,32 @@ public class AttributeChangeValidatorTest {
public void adding_rank_filter_requires_restart() throws Exception {
new Fixture("field f1 type string { indexing: attribute }",
"field f1 type string { indexing: attribute \n rank: filter }").
- assertValidation(newRestartAction(
- "Field 'f1' changed: add attribute 'rank: filter'"));
+ assertValidation(newRestartAction(ClusterSpec.Id.from("test"),
+ "Field 'f1' changed: add attribute 'rank: filter'"));
}
@Test
public void removing_rank_filter_requires_restart() throws Exception {
new Fixture("field f1 type string { indexing: attribute \n rank: filter }",
"field f1 type string { indexing: attribute }").
- assertValidation(newRestartAction(
- "Field 'f1' changed: remove attribute 'rank: filter'"));
+ assertValidation(newRestartAction(ClusterSpec.Id.from("test"),
+ "Field 'f1' changed: remove attribute 'rank: filter'"));
}
@Test
public void adding_hnsw_index_requires_restart() throws Exception {
new Fixture("field f1 type tensor(x[2]) { indexing: attribute }",
"field f1 type tensor(x[2]) { indexing: attribute | index \n index { hnsw } }").
- assertValidation(newRestartAction(
- "Field 'f1' changed: add attribute 'indexing: index'"));
+ assertValidation(newRestartAction(ClusterSpec.Id.from("test"),
+ "Field 'f1' changed: add attribute 'indexing: index'"));
}
@Test
public void removing_hnsw_index_requres_restart() throws Exception {
new Fixture("field f1 type tensor(x[2]) { indexing: attribute | index \n index { hnsw } }",
"field f1 type tensor(x[2]) { indexing: attribute }").
- assertValidation(newRestartAction(
- "Field 'f1' changed: remove attribute 'indexing: index'"));
+ assertValidation(newRestartAction(ClusterSpec.Id.from("test"),
+ "Field 'f1' changed: remove attribute 'indexing: index'"));
}
@Test
@@ -172,8 +174,9 @@ public class AttributeChangeValidatorTest {
new Fixture("field f1 type tensor(x[2]) { indexing: attribute }",
"field f1 type tensor(x[2]) { indexing: attribute \n attribute { " +
"distance-metric: geodegrees \n } }").
- assertValidation(newRestartAction("Field 'f1' changed: change property " +
- "'distance-metric' from 'EUCLIDEAN' to 'GEODEGREES'"));
+ assertValidation(newRestartAction(ClusterSpec.Id.from("test"),
+ "Field 'f1' changed: change property " +
+ "'distance-metric' from 'EUCLIDEAN' to 'GEODEGREES'"));
}
@Test
@@ -181,8 +184,9 @@ public class AttributeChangeValidatorTest {
new Fixture("field f1 type tensor(x[2]) { indexing: attribute | index \n index { hnsw } }",
"field f1 type tensor(x[2]) { indexing: attribute | index \n attribute { " +
"distance-metric: geodegrees \n } }").
- assertValidation(newRestartAction("Field 'f1' changed: change property " +
- "'distance-metric' from 'EUCLIDEAN' to 'GEODEGREES'"));
+ assertValidation(newRestartAction(ClusterSpec.Id.from("test"),
+ "Field 'f1' changed: change property " +
+ "'distance-metric' from 'EUCLIDEAN' to 'GEODEGREES'"));
}
@Test
@@ -190,8 +194,9 @@ public class AttributeChangeValidatorTest {
new Fixture("field f1 type tensor(x[2]) { indexing: attribute | index \n index { hnsw } }",
"field f1 type tensor(x[2]) { indexing: attribute | index \n index { " +
"hnsw { max-links-per-node: 4 } } }").
- assertValidation(newRestartAction("Field 'f1' changed: change hnsw index property " +
- "'max-links-per-node' from '16' to '4'"));
+ assertValidation(newRestartAction(ClusterSpec.Id.from("test"),
+ "Field 'f1' changed: change hnsw index property " +
+ "'max-links-per-node' from '16' to '4'"));
}
@Test
@@ -199,7 +204,8 @@ public class AttributeChangeValidatorTest {
new Fixture("field f1 type tensor(x[2]) { indexing: attribute | index \n index { hnsw } }",
"field f1 type tensor(x[2]) { indexing: attribute | index \n index { " +
"hnsw { neighbors-to-explore-at-insert: 100 } } }").
- assertValidation(newRestartAction("Field 'f1' changed: change hnsw index property " +
- "'neighbors-to-explore-at-insert' from '200' to '100'"));
+ assertValidation(newRestartAction(ClusterSpec.Id.from("test"),
+ "Field 'f1' changed: change hnsw index property " +
+ "'neighbors-to-explore-at-insert' from '200' to '100'"));
}
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidatorTest.java
index c24b5250a5d..60b17142340 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/DocumentDatabaseChangeValidatorTest.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.model.application.validation.change.search;
import com.yahoo.config.application.api.ValidationOverrides;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.model.application.validation.change.VespaConfigChangeAction;
import org.junit.Test;
@@ -19,7 +20,11 @@ public class DocumentDatabaseChangeValidatorTest {
public Fixture(String currentSd, String nextSd) throws Exception {
super(currentSd, nextSd);
- validator = new DocumentDatabaseChangeValidator(currentDb(), currentDocType(), nextDb(), nextDocType());
+ validator = new DocumentDatabaseChangeValidator(ClusterSpec.Id.from("test"),
+ currentDb(),
+ currentDocType(),
+ nextDb(),
+ nextDocType());
}
@Override
@@ -42,13 +47,17 @@ public class DocumentDatabaseChangeValidatorTest {
"field f3 type string { indexing: summary } " +
"field f4 type array<s> { struct-field s1 { indexing: attribute } }");
f.assertValidation(Arrays.asList(
- newRestartAction("Field 'f1' changed: add attribute aspect"),
- newRestartAction("Field 'f4.s1' changed: add attribute aspect"),
- newRefeedAction("indexing-change",
+ newRestartAction(ClusterSpec.Id.from("test"),
+ "Field 'f1' changed: add attribute aspect"),
+ newRestartAction(ClusterSpec.Id.from("test"),
+ "Field 'f4.s1' changed: add attribute aspect"),
+ newRefeedAction(ClusterSpec.Id.from("test"),
+ "indexing-change",
ValidationOverrides.empty,
"Field 'f2' changed: add index aspect, indexing script: '{ input f2 | summary f2; }' -> " +
"'{ input f2 | tokenize normalize stem:\"BEST\" | index f2 | summary f2; }'", Instant.now()),
- newRefeedAction("field-type-change",
+ newRefeedAction(ClusterSpec.Id.from("test"),
+ "field-type-change",
ValidationOverrides.empty,
"Field 'f3' changed: data type: 'int' -> 'string'", Instant.now())));
}
@@ -56,7 +65,7 @@ public class DocumentDatabaseChangeValidatorTest {
@Test
public void requireThatRemovingAttributeAspectFromIndexFieldIsOk() throws Exception {
Fixture f = new Fixture("field f1 type string { indexing: index | attribute }",
- "field f1 type string { indexing: index }");
+ "field f1 type string { indexing: index }");
f.assertValidation();
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/DocumentTypeChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/DocumentTypeChangeValidatorTest.java
index 4bba66f0fb3..190c2c8c645 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/DocumentTypeChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/DocumentTypeChangeValidatorTest.java
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.application.validation.change.search;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.document.DocumentType;
import com.yahoo.document.Field;
import com.yahoo.document.ReferenceDataType;
@@ -34,7 +35,9 @@ public class DocumentTypeChangeValidatorTest {
public Fixture(String currentSd, String nextSd) throws Exception {
super(currentSd, nextSd);
- validator = new DocumentTypeChangeValidator(currentDocType(), nextDocType());
+ validator = new DocumentTypeChangeValidator(ClusterSpec.Id.from("test"),
+ currentDocType(),
+ nextDocType());
}
@Override
@@ -62,7 +65,8 @@ public class DocumentTypeChangeValidatorTest {
public void requireThatDataTypeChangeIsNotOK() throws Exception {
Fixture f = new Fixture("field f1 type string { indexing: summary }",
"field f1 type int { indexing: summary }");
- f.assertValidation(newRefeedAction("field-type-change",
+ f.assertValidation(newRefeedAction(ClusterSpec.Id.from("test"),
+ "field-type-change",
ValidationOverrides.empty,
"Field 'f1' changed: data type: 'string' -> 'int'",
Instant.now()));
@@ -72,7 +76,8 @@ public class DocumentTypeChangeValidatorTest {
public void requireThatAddingCollectionTypeIsNotOK() throws Exception {
Fixture f = new Fixture("field f1 type string { indexing: summary }",
"field f1 type array<string> { indexing: summary }");
- f.assertValidation(newRefeedAction("field-type-change",
+ f.assertValidation(newRefeedAction(ClusterSpec.Id.from("test"),
+ "field-type-change",
ValidationOverrides.empty,
"Field 'f1' changed: data type: 'string' -> 'Array<string>'", Instant.now()));
}
@@ -89,7 +94,8 @@ public class DocumentTypeChangeValidatorTest {
public void requireThatNestedDataTypeChangeIsNotOK() throws Exception {
Fixture f = new Fixture("field f1 type array<string> { indexing: summary }",
"field f1 type array<int> { indexing: summary }");
- f.assertValidation(newRefeedAction("field-type-change",
+ f.assertValidation(newRefeedAction(ClusterSpec.Id.from("test"),
+ "field-type-change",
ValidationOverrides.empty,
"Field 'f1' changed: data type: 'Array<string>' -> 'Array<int>'", Instant.now()));
}
@@ -98,7 +104,8 @@ public class DocumentTypeChangeValidatorTest {
public void requireThatChangedCollectionTypeIsNotOK() throws Exception {
Fixture f = new Fixture("field f1 type array<string> { indexing: summary }",
"field f1 type weightedset<string> { indexing: summary }");
- f.assertValidation(newRefeedAction("field-type-change",
+ f.assertValidation(newRefeedAction(ClusterSpec.Id.from("test"),
+ "field-type-change",
ValidationOverrides.empty,
"Field 'f1' changed: data type: 'Array<string>' -> 'WeightedSet<string>'", Instant.now()));
}
@@ -107,10 +114,12 @@ public class DocumentTypeChangeValidatorTest {
public void requireThatMultipleDataTypeChangesIsNotOK() throws Exception {
Fixture f = new Fixture("field f1 type string { indexing: summary } field f2 type int { indexing: summary }" ,
"field f2 type string { indexing: summary } field f1 type int { indexing: summary }");
- f.assertValidation(Arrays.asList(newRefeedAction("field-type-change",
+ f.assertValidation(Arrays.asList(newRefeedAction(ClusterSpec.Id.from("test"),
+ "field-type-change",
ValidationOverrides.empty,
"Field 'f1' changed: data type: 'string' -> 'int'", Instant.now()),
- newRefeedAction("field-type-change",
+ newRefeedAction(ClusterSpec.Id.from("test"),
+ "field-type-change",
ValidationOverrides.empty,
"Field 'f2' changed: data type: 'int' -> 'string'", Instant.now())));
}
@@ -147,7 +156,8 @@ public class DocumentTypeChangeValidatorTest {
public void requireThatDataTypeChangeInStructFieldIsNotOK() throws Exception {
Fixture f = new Fixture("struct s1 { field f1 type string {} } field f2 type s1 { indexing: summary }",
"struct s1 { field f1 type int {} } field f2 type s1 { indexing: summary }");
- f.assertValidation(newRefeedAction("field-type-change",
+ f.assertValidation(newRefeedAction(ClusterSpec.Id.from("test"),
+ "field-type-change",
ValidationOverrides.empty,
"Field 'f2' changed: data type: 's1:{f1:string}' -> 's1:{f1:int}'", Instant.now()));
}
@@ -156,7 +166,8 @@ public class DocumentTypeChangeValidatorTest {
public void requireThatNestedDataTypeChangeInStructFieldIsNotOK() throws Exception {
Fixture f = new Fixture("struct s1 { field f1 type array<string> {} } field f2 type s1 { indexing: summary }",
"struct s1 { field f1 type array<int> {} } field f2 type s1 { indexing: summary }");
- f.assertValidation(newRefeedAction("field-type-change",
+ f.assertValidation(newRefeedAction(ClusterSpec.Id.from("test"),
+ "field-type-change",
ValidationOverrides.empty,
"Field 'f2' changed: data type: 's1:{f1:Array<string>}' -> 's1:{f1:Array<int>}'", Instant.now()));
}
@@ -165,7 +176,8 @@ public class DocumentTypeChangeValidatorTest {
public void requireThatDataTypeChangeInNestedStructFieldIsNotOK() throws Exception {
Fixture f = new Fixture("struct s1 { field f1 type string {} } struct s2 { field f2 type s1 {} } field f3 type s2 { indexing: summary }",
"struct s1 { field f1 type int {} } struct s2 { field f2 type s1 {} } field f3 type s2 { indexing: summary }");
- f.assertValidation(newRefeedAction("field-type-change",
+ f.assertValidation(newRefeedAction(ClusterSpec.Id.from("test"),
+ "field-type-change",
ValidationOverrides.empty,
"Field 'f3' changed: data type: 's2:{s1:{f1:string}}' -> 's2:{s1:{f1:int}}'", Instant.now()));
}
@@ -174,16 +186,17 @@ public class DocumentTypeChangeValidatorTest {
public void requireThatMultipleDataTypeChangesInStructFieldIsNotOK() throws Exception {
Fixture f = new Fixture("struct s1 { field f1 type string {} field f2 type int {} } field f3 type s1 { indexing: summary }",
"struct s1 { field f1 type int {} field f2 type string {} } field f3 type s1 { indexing: summary }");
- f.assertValidation(newRefeedAction("field-type-change",
+ f.assertValidation(newRefeedAction(ClusterSpec.Id.from("test"),
+ "field-type-change",
ValidationOverrides.empty,
"Field 'f3' changed: data type: 's1:{f1:string,f2:int}' -> 's1:{f1:int,f2:string}'", Instant.now()));
}
@Test
public void requireThatChangingTargetTypeOfReferenceFieldIsNotOK() {
- DocumentTypeChangeValidator validator = new DocumentTypeChangeValidator(
- createDocumentTypeWithReferenceField("oldDoc"),
- createDocumentTypeWithReferenceField("newDoc"));
+ var validator = new DocumentTypeChangeValidator(ClusterSpec.Id.from("test"),
+ createDocumentTypeWithReferenceField("oldDoc"),
+ createDocumentTypeWithReferenceField("newDoc"));
List<VespaConfigChangeAction> result = validator.validate(ValidationOverrides.empty, Instant.now());
assertEquals(1, result.size());
VespaConfigChangeAction action = result.get(0);
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidatorTest.java
index 7a5b235737a..8ffd02a4381 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/IndexingScriptChangeValidatorTest.java
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.application.validation.change.search;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.indexinglanguage.expressions.ScriptExpression;
import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.vespa.model.application.validation.change.VespaConfigChangeAction;
@@ -20,8 +21,9 @@ public class IndexingScriptChangeValidatorTest {
public Fixture(String currentSd, String nextSd) throws Exception {
super(currentSd, nextSd);
- validator = new IndexingScriptChangeValidator(currentDb().getDerivedConfiguration().getSearch(),
- nextDb().getDerivedConfiguration().getSearch());
+ validator = new IndexingScriptChangeValidator(ClusterSpec.Id.from("test"),
+ currentDb().getDerivedConfiguration().getSearch(),
+ nextDb().getDerivedConfiguration().getSearch());
}
@Override
@@ -31,6 +33,7 @@ public class IndexingScriptChangeValidatorTest {
}
private static class ScriptFixture {
+
private final ScriptExpression currentScript;
private final ScriptExpression nextScript;
@@ -44,15 +47,16 @@ public class IndexingScriptChangeValidatorTest {
}
}
- private static String FIELD = "field f1 type string";
- private static String FIELD_F2 = "field f2 type string";
+ private static final String FIELD = "field f1 type string";
+ private static final String FIELD_F2 = "field f2 type string";
private static VespaConfigChangeAction expectedAction(String changedMsg, String fromScript, String toScript) {
return expectedAction("f1", changedMsg, fromScript, toScript);
}
private static VespaConfigChangeAction expectedAction(String field, String changedMsg, String fromScript, String toScript) {
- return VespaRefeedAction.of("indexing-change",
+ return VespaRefeedAction.of(ClusterSpec.Id.from("test"),
+ "indexing-change",
ValidationOverrides.empty,
"Field '" + field + "' changed: " +
(changedMsg.isEmpty() ? "" : changedMsg + ", ") +
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidatorTestCase.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidatorTestCase.java
index 2d68284c9a5..04efffab438 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidatorTestCase.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidatorTestCase.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.model.application.validation.change.search;
import com.yahoo.config.application.api.ValidationOverrides;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.model.application.validation.change.VespaConfigChangeAction;
import org.junit.Test;
@@ -17,16 +18,18 @@ import static com.yahoo.vespa.model.application.validation.change.ConfigChangeTe
public class StructFieldAttributeChangeValidatorTestCase {
private static class Fixture extends ContentClusterFixture {
- private StructFieldAttributeChangeValidator structFieldAttributeValidator;
- private DocumentTypeChangeValidator docTypeValidator;
+
+ private final StructFieldAttributeChangeValidator structFieldAttributeValidator;
+ private final DocumentTypeChangeValidator docTypeValidator;
public Fixture(String currentSd, String nextSd) throws Exception {
super(currentSd, nextSd);
- structFieldAttributeValidator = new StructFieldAttributeChangeValidator(currentDocType(),
- currentDb().getDerivedConfiguration().getAttributeFields(),
- nextDocType(),
- nextDb().getDerivedConfiguration().getAttributeFields());
- docTypeValidator = new DocumentTypeChangeValidator(currentDocType(), nextDocType());
+ structFieldAttributeValidator = new StructFieldAttributeChangeValidator(ClusterSpec.Id.from("test"),
+ currentDocType(),
+ currentDb().getDerivedConfiguration().getAttributeFields(),
+ nextDocType(),
+ nextDb().getDerivedConfiguration().getAttributeFields());
+ docTypeValidator = new DocumentTypeChangeValidator(ClusterSpec.Id.from("test"), currentDocType(), nextDocType());
}
@Override
@@ -49,34 +52,34 @@ public class StructFieldAttributeChangeValidatorTestCase {
@Test
public void adding_attribute_aspect_to_struct_field_requires_restart() throws Exception {
validate(arrayOfStruct(oneFieldStruct(), ""),
- arrayOfStruct(oneFieldStruct(), structAttribute("s1")),
- newRestartAction("Field 'f1.s1' changed: add attribute aspect"));
+ arrayOfStruct(oneFieldStruct(), structAttribute("s1")),
+ newRestartAction(ClusterSpec.Id.from("test"), "Field 'f1.s1' changed: add attribute aspect"));
validate(mapOfStruct(oneFieldStruct(), ""),
- mapOfStruct(oneFieldStruct(), structAttribute("key")),
- newRestartAction("Field 'f1.key' changed: add attribute aspect"));
+ mapOfStruct(oneFieldStruct(), structAttribute("key")),
+ newRestartAction(ClusterSpec.Id.from("test"), "Field 'f1.key' changed: add attribute aspect"));
validate(mapOfStruct(oneFieldStruct(), ""),
- mapOfStruct(oneFieldStruct(), structAttribute("value.s1")),
- newRestartAction("Field 'f1.value.s1' changed: add attribute aspect"));
+ mapOfStruct(oneFieldStruct(), structAttribute("value.s1")),
+ newRestartAction(ClusterSpec.Id.from("test"), "Field 'f1.value.s1' changed: add attribute aspect"));
validate(mapOfPrimitive(""), mapOfPrimitive(structAttribute("key")),
- newRestartAction("Field 'f1.key' changed: add attribute aspect"));
+ newRestartAction(ClusterSpec.Id.from("test"), "Field 'f1.key' changed: add attribute aspect"));
validate(mapOfPrimitive(""), mapOfPrimitive(structAttribute("value")),
- newRestartAction("Field 'f1.value' changed: add attribute aspect"));
+ newRestartAction(ClusterSpec.Id.from("test"), "Field 'f1.value' changed: add attribute aspect"));
}
@Test
public void removing_attribute_aspect_from_struct_field_is_ok() throws Exception {
validate(arrayOfStruct(oneFieldStruct(), structAttribute("s1")),
- arrayOfStruct(oneFieldStruct(), ""));
+ arrayOfStruct(oneFieldStruct(), ""));
validate(mapOfStruct(oneFieldStruct(), structAttribute("key")),
- mapOfStruct(oneFieldStruct(), ""));
+ mapOfStruct(oneFieldStruct(), ""));
validate(mapOfStruct(oneFieldStruct(), structAttribute("value.s1")),
- mapOfStruct(oneFieldStruct(), ""));
+ mapOfStruct(oneFieldStruct(), ""));
validate(mapOfPrimitive(structAttribute("key")), mapOfPrimitive(""));
@@ -89,34 +92,34 @@ public class StructFieldAttributeChangeValidatorTestCase {
arrayOfStruct(twoFieldStruct(), structAttribute("s2")));
validate(mapOfStruct(oneFieldStruct(), ""),
- mapOfStruct(twoFieldStruct(), structAttribute("value.s2")));
+ mapOfStruct(twoFieldStruct(), structAttribute("value.s2")));
}
@Test
public void removing_struct_field_with_attribute_aspect_is_ok() throws Exception {
validate(arrayOfStruct(twoFieldStruct(), structAttribute("s2")),
- arrayOfStruct(oneFieldStruct(), ""));
+ arrayOfStruct(oneFieldStruct(), ""));
validate(mapOfStruct(twoFieldStruct(), structAttribute("value.s2")),
- mapOfStruct(oneFieldStruct(), ""));
+ mapOfStruct(oneFieldStruct(), ""));
}
@Test
public void adding_struct_field_without_attribute_aspect_is_ok() throws Exception {
validate(arrayOfStruct(oneFieldStruct(), ""),
- arrayOfStruct(twoFieldStruct(), ""));
+ arrayOfStruct(twoFieldStruct(), ""));
validate(mapOfStruct(oneFieldStruct(), ""),
- mapOfStruct(twoFieldStruct(), ""));
+ mapOfStruct(twoFieldStruct(), ""));
}
@Test
public void removing_struct_field_without_attribute_aspect_is_ok() throws Exception {
validate(arrayOfStruct(twoFieldStruct(), ""),
- arrayOfStruct(oneFieldStruct(), ""));
+ arrayOfStruct(oneFieldStruct(), ""));
validate(mapOfStruct(twoFieldStruct(), ""),
- mapOfStruct(oneFieldStruct(), ""));
+ mapOfStruct(oneFieldStruct(), ""));
}
private static String oneFieldStruct() {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
index d493afd9c1f..3515efb7bc1 100755
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
@@ -4,9 +4,11 @@ package com.yahoo.vespa.model.container;
import com.yahoo.cloud.config.ClusterInfoConfig;
import com.yahoo.cloud.config.ConfigserverConfig;
import com.yahoo.cloud.config.RoutingProviderConfig;
+import com.yahoo.component.ComponentId;
import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.deploy.TestProperties;
+import com.yahoo.config.model.test.MockApplicationPackage;
import com.yahoo.config.model.test.MockRoot;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Environment;
@@ -14,6 +16,7 @@ import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.Zone;
import com.yahoo.container.di.config.PlatformBundlesConfig;
+import com.yahoo.container.handler.ThreadPoolProvider;
import com.yahoo.container.handler.ThreadpoolConfig;
import com.yahoo.search.config.QrStartConfig;
import com.yahoo.vespa.model.Host;
@@ -33,6 +36,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
+import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -167,12 +171,11 @@ public class ContainerClusterTest {
assertEquals(512, qrStartConfig.jvm().heapsize());
assertEquals(32, qrStartConfig.jvm().compressedClassSpaceSize());
assertEquals(0, qrStartConfig.jvm().heapSizeAsPercentageOfPhysicalMemory());
+ root.freezeModelTopology();
- ThreadpoolConfig.Builder tpBuilder = new ThreadpoolConfig.Builder();
- cluster.getConfig(tpBuilder);
- ThreadpoolConfig threadpoolConfig = new ThreadpoolConfig(tpBuilder);
+ ThreadpoolConfig threadpoolConfig = root.getConfig(ThreadpoolConfig.class, "container0/component/default-threadpool");
assertEquals(10, threadpoolConfig.maxthreads());
- assertEquals(0, threadpoolConfig.queueSize());
+ assertEquals(50, threadpoolConfig.queueSize());
}
@Test
@@ -219,10 +222,9 @@ public class ContainerClusterTest {
MockRoot root = new MockRoot("foo", state);
ApplicationContainerCluster cluster = createContainerCluster(root, false);
addContainer(root.deployLogger(), cluster, "c1", "host-c1");
+ root.freezeModelTopology();
- ThreadpoolConfig.Builder tpBuilder = new ThreadpoolConfig.Builder();
- cluster.getConfig(tpBuilder);
- ThreadpoolConfig threadpoolConfig = new ThreadpoolConfig(tpBuilder);
+ ThreadpoolConfig threadpoolConfig = root.getConfig(ThreadpoolConfig.class, "container0/component/default-threadpool");
assertEquals(500, threadpoolConfig.maxthreads());
assertEquals(0, threadpoolConfig.queueSize());
}
@@ -232,15 +234,52 @@ public class ContainerClusterTest {
MockRoot root = new MockRoot("foo");
ApplicationContainerCluster cluster = createContainerCluster(root, false);
addContainer(root.deployLogger(), cluster, "c1", "host-c1");
+ root.freezeModelTopology();
- ThreadpoolConfig.Builder tpBuilder = new ThreadpoolConfig.Builder();
- cluster.getConfig(tpBuilder);
- ThreadpoolConfig threadpoolConfig = new ThreadpoolConfig(tpBuilder);
+ ThreadpoolConfig threadpoolConfig = root.getConfig(ThreadpoolConfig.class, "container0/component/default-threadpool");
assertEquals(500, threadpoolConfig.maxthreads());
assertEquals(0, threadpoolConfig.queueSize());
}
@Test
+ public void container_cluster_has_default_threadpool_provider() {
+ MockRoot root = new MockRoot("foo");
+ ApplicationContainerCluster cluster = createContainerCluster(root, false);
+ addContainer(root.deployLogger(), cluster, "c1", "host-c1");
+ root.freezeModelTopology();
+
+ ComponentId expectedComponentId = new ComponentId("default-threadpool");
+ var components = cluster.getComponentsMap();
+ assertThat(components, hasKey(expectedComponentId));
+ Component<?, ?> component = components.get(expectedComponentId);
+ assertEquals(ThreadPoolProvider.class.getName(), component.getClassId().getName());
+ }
+
+ @Test
+ public void config_for_default_threadpool_provider_scales_with_node_resources() {
+ HostProvisionerWithCustomRealResource hostProvisioner = new HostProvisionerWithCustomRealResource();
+ MockRoot root = new MockRoot(
+ "foo",
+ new DeployState.Builder()
+ .properties(new TestProperties()
+ .setThreadPoolSizeFactor(4)
+ .setQueueSizeFactor(20))
+ .applicationPackage(new MockApplicationPackage.Builder().build())
+ .modelHostProvisioner(hostProvisioner)
+ .build());
+ ApplicationContainerCluster cluster = createContainerCluster(root, false);
+ HostResource hostResource = new HostResource(
+ new Host(null, "host-c1"),
+ hostProvisioner.allocateHost("host-c1"));
+ addContainerWithHostResource(root.deployLogger(), cluster, "c1", hostResource);
+ root.freezeModelTopology();
+
+ ThreadpoolConfig threadpoolConfig = root.getConfig(ThreadpoolConfig.class, "container0/component/default-threadpool");
+ assertEquals(16, threadpoolConfig.maxthreads());
+ assertEquals(320, threadpoolConfig.queueSize());
+ }
+
+ @Test
public void requireThatRoutingProviderIsDisabledForNonHosted() {
DeployState state = new DeployState.Builder().properties(new TestProperties().setHostedVespa(false)).build();
MockRoot root = new MockRoot("foo", state);
@@ -287,8 +326,12 @@ public class ContainerClusterTest {
private static void addContainer(DeployLogger deployLogger, ApplicationContainerCluster cluster, String name, String hostName) {
+ addContainerWithHostResource(deployLogger, cluster, name, new HostResource(new Host(null, hostName)));
+ }
+
+ private static void addContainerWithHostResource(DeployLogger deployLogger, ApplicationContainerCluster cluster, String name, HostResource hostResource) {
ApplicationContainer container = new ApplicationContainer(cluster, name, 0, cluster.isHostedVespa());
- container.setHostResource(new HostResource(new Host(null, hostName)));
+ container.setHostResource(hostResource);
container.initService(deployLogger);
cluster.addContainer(container);
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/HostProvisionerWithCustomRealResource.java b/config-model/src/test/java/com/yahoo/vespa/model/container/HostProvisionerWithCustomRealResource.java
new file mode 100644
index 00000000000..450049ffe99
--- /dev/null
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/HostProvisionerWithCustomRealResource.java
@@ -0,0 +1,40 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.container;
+
+import com.yahoo.config.model.api.HostProvisioner;
+import com.yahoo.config.model.provision.Host;
+import com.yahoo.config.provision.Capacity;
+import com.yahoo.config.provision.ClusterMembership;
+import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.HostSpec;
+import com.yahoo.config.provision.NodeResources;
+import com.yahoo.config.provision.ProvisionLogger;
+import com.yahoo.net.HostName;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author bjorncs
+ */
+public class HostProvisionerWithCustomRealResource implements HostProvisioner {
+
+ @Override
+ public HostSpec allocateHost(String alias) {
+ Host host = new Host(HostName.getLocalhost());
+ ClusterMembership membership = ClusterMembership.from(
+ ClusterSpec
+ .specification(
+ ClusterSpec.Type.container,
+ ClusterSpec.Id.from("id"))
+ .vespaVersion("")
+ .group(ClusterSpec.Group.from(0))
+ .build(),
+ 0);
+ return new HostSpec(
+ host.hostname(), new NodeResources(4, 0, 0, 0), NodeResources.unspecified(), NodeResources.unspecified(),
+ membership, Optional.empty(), Optional.empty(), Optional.empty());
+ }
+
+ @Override public List<HostSpec> prepare(ClusterSpec cluster, Capacity capacity, ProvisionLogger logger) { return List.of(); }
+}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerDocumentApiBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerDocumentApiBuilderTest.java
index def5da3a9c2..9f061dcbd0a 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerDocumentApiBuilderTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerDocumentApiBuilderTest.java
@@ -1,20 +1,12 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.container.xml;
-import com.yahoo.config.model.api.HostProvisioner;
import com.yahoo.config.model.builder.xml.test.DomBuilderTest;
-import com.yahoo.config.model.provision.Host;
import com.yahoo.config.model.test.MockApplicationPackage;
import com.yahoo.config.model.test.MockRoot;
-import com.yahoo.config.provision.Capacity;
-import com.yahoo.config.provision.ClusterMembership;
-import com.yahoo.config.provision.ClusterSpec;
-import com.yahoo.config.provision.HostSpec;
-import com.yahoo.config.provision.NodeResources;
-import com.yahoo.config.provision.ProvisionLogger;
import com.yahoo.container.handler.threadpool.ContainerThreadpoolConfig;
-import com.yahoo.net.HostName;
import com.yahoo.vespa.model.container.ContainerCluster;
+import com.yahoo.vespa.model.container.HostProvisionerWithCustomRealResource;
import com.yahoo.vespa.model.container.component.Handler;
import com.yahoo.vespa.model.container.component.SystemBindingPattern;
import com.yahoo.vespa.model.container.component.UserBindingPattern;
@@ -23,9 +15,7 @@ import org.w3c.dom.Element;
import java.util.Collection;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.Set;
import static org.hamcrest.CoreMatchers.equalTo;
@@ -158,26 +148,4 @@ public class ContainerDocumentApiBuilderTest extends ContainerModelBuilderTestBa
assertEquals(1000, feedThreadpoolConfig.queueSize());
}
- private static class HostProvisionerWithCustomRealResource implements HostProvisioner {
-
- @Override
- public HostSpec allocateHost(String alias) {
- Host host = new Host(HostName.getLocalhost());
- ClusterMembership membership = ClusterMembership.from(
- ClusterSpec
- .specification(
- ClusterSpec.Type.container,
- ClusterSpec.Id.from("id"))
- .vespaVersion("")
- .group(ClusterSpec.Group.from(0))
- .build(),
- 0);
- return new HostSpec(
- host.hostname(), new NodeResources(4, 0, 0, 0), NodeResources.unspecified(), NodeResources.unspecified(),
- membership, Optional.empty(), Optional.empty(), Optional.empty());
- }
-
- @Override public List<HostSpec> prepare(ClusterSpec cluster, Capacity capacity, ProvisionLogger logger) { return List.of(); }
- }
-
}
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/ProvisionLock.java b/config-provisioning/src/main/java/com/yahoo/config/provision/ProvisionLock.java
new file mode 100644
index 00000000000..633c8520e72
--- /dev/null
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/ProvisionLock.java
@@ -0,0 +1,32 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.config.provision;
+
+import com.yahoo.transaction.Mutex;
+
+import java.util.Objects;
+
+/**
+ * A type-safe wrapper for an application's provision lock.
+ *
+ * @author mpolden
+ */
+public class ProvisionLock implements AutoCloseable {
+
+ private final ApplicationId application;
+ private final Mutex lock;
+
+ public ProvisionLock(ApplicationId application, Mutex lock) {
+ this.application = Objects.requireNonNull(application);
+ this.lock = Objects.requireNonNull(lock);
+ }
+
+ public ApplicationId application() {
+ return application;
+ }
+
+ @Override
+ public void close() {
+ lock.close();
+ }
+
+}
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/Provisioner.java b/config-provisioning/src/main/java/com/yahoo/config/provision/Provisioner.java
index 2a1528f5368..1eb2c1e61b2 100644
--- a/config-provisioning/src/main/java/com/yahoo/config/provision/Provisioner.java
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/Provisioner.java
@@ -31,17 +31,36 @@ public interface Provisioner {
* @param application The {@link ApplicationId} that was activated.
* @param hosts a set of {@link HostSpec}.
*/
+ // TODO(mpolden): Remove
void activate(NestedTransaction transaction, ApplicationId application, Collection<HostSpec> hosts);
/**
+ * Activates the allocation of nodes to this application captured in the hosts argument.
+ *
+ * @param transaction Transaction with operations to commit together with any operations done within the provisioner.
+ * @param hosts a set of {@link HostSpec}.
+ * @param lock A provision lock for the relevant application. This must be held when calling this.
+ */
+ void activate(NestedTransaction transaction, Collection<HostSpec> hosts, ProvisionLock lock);
+
+ /**
* Transactionally remove this application.
*
* @param transaction Transaction with operations to commit together with any operations done within the provisioner.
* @param application the application to remove
*/
+ // TODO(mpolden): Remove
void remove(NestedTransaction transaction, ApplicationId application);
/**
+ * Transactionally remove application guarded by given lock.
+ *
+ * @param transaction Transaction with operations to commit together with any operations done within the provisioner.
+ * @param lock A provision lock for the relevant application. This must be held when calling this.
+ */
+ void remove(NestedTransaction transaction, ProvisionLock lock);
+
+ /**
* Requests a restart of the services of the given application
*
* @param application the application to restart
@@ -49,4 +68,7 @@ public interface Provisioner {
*/
void restart(ApplicationId application, HostFilter filter);
+ /** Returns a provision lock for the given application */
+ ProvisionLock lock(ApplicationId application);
+
}
diff --git a/config/src/tests/api/api.cpp b/config/src/tests/api/api.cpp
index 0af2b848ea5..a48f36aea9a 100644
--- a/config/src/tests/api/api.cpp
+++ b/config/src/tests/api/api.cpp
@@ -1,13 +1,14 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/config/config.h>
+#include <vespa/config/common/configcontext.h>
#include <config-my.h>
using namespace config;
TEST("require that can subscribe with empty config id") {
ConfigSet set;
- ConfigContext::SP ctx(new ConfigContext(set));
+ auto ctx = std::make_shared<ConfigContext>(set);
MyConfigBuilder builder;
builder.myField = "myfoo";
set.addBuilder("", &builder);
diff --git a/config/src/tests/configfetcher/configfetcher.cpp b/config/src/tests/configfetcher/configfetcher.cpp
index 856b1198ce8..508322bb74e 100644
--- a/config/src/tests/configfetcher/configfetcher.cpp
+++ b/config/src/tests/configfetcher/configfetcher.cpp
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/config/helper/configfetcher.h>
+#include <vespa/config/common/configcontext.h>
#include <vespa/vespalib/util/exception.h>
#include "config-my.h"
#include <atomic>
@@ -12,7 +13,7 @@ class MyCallback : public IFetcherCallback<MyConfig>
{
public:
MyCallback(const std::string & badConfig="");
- ~MyCallback();
+ ~MyCallback() override;
void configure(std::unique_ptr<MyConfig> config) override
{
_config = std::move(config);
@@ -126,7 +127,7 @@ struct ConfigFixture {
ConfigContext::SP context;
ConfigFixture() : builder(), set(), context() {
set.addBuilder("cfgid", &builder);
- context.reset(new ConfigContext(set));
+ context = std::make_shared<ConfigContext>(set);
}
};
diff --git a/config/src/tests/configretriever/configretriever.cpp b/config/src/tests/configretriever/configretriever.cpp
index 2c1954bcd95..d4ebe2da994 100644
--- a/config/src/tests/configretriever/configretriever.cpp
+++ b/config/src/tests/configretriever/configretriever.cpp
@@ -7,7 +7,9 @@
#include <vespa/config/retriever/simpleconfigretriever.h>
#include <vespa/config/retriever/simpleconfigurer.h>
#include <vespa/config/common/configholder.h>
+#include <vespa/config/common/configcontext.h>
#include <vespa/config/subscription/configsubscription.h>
+#include <vespa/config/subscription/sourcespec.h>
#include <vespa/config/common/exceptions.h>
#include "config-bootstrap.h"
#include "config-foo.h"
@@ -39,7 +41,7 @@ struct ConfigTestFixture {
bootstrapBuilder(),
componentConfig(),
set(),
- context(new ConfigContext(set)),
+ context(std::make_shared<ConfigContext>(set)),
idcounter(-1)
{
set.addBuilder(configId, &bootstrapBuilder);
diff --git a/config/src/tests/configuri/configuri_test.cpp b/config/src/tests/configuri/configuri_test.cpp
index c813761e763..38d49848596 100644
--- a/config/src/tests/configuri/configuri_test.cpp
+++ b/config/src/tests/configuri/configuri_test.cpp
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/config/config.h>
+#include <vespa/config/common/configcontext.h>
#include "config-my.h"
using namespace config;
diff --git a/config/src/tests/failover/failover.cpp b/config/src/tests/failover/failover.cpp
index 0ca09b228f3..99b6967c929 100644
--- a/config/src/tests/failover/failover.cpp
+++ b/config/src/tests/failover/failover.cpp
@@ -4,10 +4,12 @@
#include <vespa/config/common/misc.h>
#include <vespa/config/frt/protocol.h>
#include <vespa/config/config.h>
+#include <vespa/config/common/configcontext.h>
#include <vespa/fnet/frt/frt.h>
#include "config-my.h"
#include <vespa/vespalib/data/slime/slime.h>
#include <vespa/vespalib/data/simple_buffer.h>
+
#include <vespa/log/log.h>
LOG_SETUP("failover");
@@ -189,7 +191,7 @@ struct ConfigCheckFixture {
NetworkFixture & nf;
ConfigCheckFixture(NetworkFixture & f2)
- : ctx(new ConfigContext(testTimingValues, f2.spec)),
+ : ctx(std::make_shared<ConfigContext>(testTimingValues, f2.spec)),
nf(f2)
{
}
@@ -223,7 +225,7 @@ struct ConfigReloadFixture {
ConfigHandle<MyConfig>::UP handle;
ConfigReloadFixture(NetworkFixture & f2)
- : ctx(new ConfigContext(testTimingValues, f2.spec)),
+ : ctx(std::make_shared<ConfigContext>(testTimingValues, f2.spec)),
nf(f2),
s(ctx),
handle(s.subscribe<MyConfig>("myId"))
diff --git a/config/src/tests/file_subscription/file_subscription.cpp b/config/src/tests/file_subscription/file_subscription.cpp
index ceaf16c9191..468180cd78f 100644
--- a/config/src/tests/file_subscription/file_subscription.cpp
+++ b/config/src/tests/file_subscription/file_subscription.cpp
@@ -4,7 +4,8 @@
#include <vespa/config/common/configholder.h>
#include <vespa/config/file/filesource.h>
#include <vespa/config/common/exceptions.h>
-#include <vespa/vespalib/util/sync.h>
+#include <vespa/config/common/sourcefactory.h>
+#include <vespa/config/common/configcontext.h>
#include <fstream>
#include <config-my.h>
#include <config-foo.h>
@@ -61,7 +62,7 @@ TEST("requireThatFileSpecGivesCorrectSource") {
SourceFactory::UP factory(spec.createSourceFactory(TimingValues()));
ASSERT_TRUE(factory);
- IConfigHolder::SP holder(new ConfigHolder());
+ auto holder = std::make_shared<ConfigHolder>();
Source::UP src = factory->createSource(holder, ConfigKey("my", "my", "bar", "foo"));
ASSERT_TRUE(src);
@@ -89,7 +90,7 @@ TEST("requireThatFileSubscriptionReturnsCorrectConfig") {
TEST("requireThatReconfigIsCalledWhenConfigChanges") {
writeFile("my.cfg", "foo");
{
- IConfigContext::SP context(new ConfigContext(FileSpec("my.cfg")));
+ auto context = std::make_shared<ConfigContext>(FileSpec("my.cfg"));
ConfigSubscriber s(context);
std::unique_ptr<ConfigHandle<MyConfig> > handle = s.subscribe<MyConfig>("");
s.nextConfigNow();
diff --git a/config/src/tests/getconfig/getconfig.cpp b/config/src/tests/getconfig/getconfig.cpp
index 0cbac7aa456..b091e347ff2 100644
--- a/config/src/tests/getconfig/getconfig.cpp
+++ b/config/src/tests/getconfig/getconfig.cpp
@@ -1,9 +1,8 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/vespalib/testkit/test_kit.h>
-#include <vespa/config/config.h>
#include <vespa/config/helper/configgetter.hpp>
-#include <vespa/config/raw/rawsource.h>
+#include <vespa/config/common/configcontext.h>
#include "config-my.h"
using namespace config;
@@ -16,7 +15,7 @@ struct ConfigFixture {
ConfigContext::SP context;
ConfigFixture() : builder(), set(), context() {
set.addBuilder("cfgid", &builder);
- context.reset(new ConfigContext(set));
+ context = std::make_shared<ConfigContext>(set);
}
};
@@ -27,7 +26,7 @@ TEST("requireThatGetConfigReturnsCorrectConfig")
RawSpec spec("myField \"foo\"\n");
std::unique_ptr<MyConfig> cfg = ConfigGetter<MyConfig>::getConfig("myid", spec);
- ASSERT_TRUE(cfg.get() != NULL);
+ ASSERT_TRUE(cfg);
ASSERT_EQUAL("my", cfg->defName());
ASSERT_EQUAL("foo", cfg->myField);
}
@@ -37,7 +36,7 @@ TEST("requireThatGetConfigReturnsCorrectConfig")
{
FileSpec spec(TEST_PATH("my.cfg"));
std::unique_ptr<MyConfig> cfg = ConfigGetter<MyConfig>::getConfig("", spec);
- ASSERT_TRUE(cfg.get() != NULL);
+ ASSERT_TRUE(cfg);
ASSERT_EQUAL("my", cfg->defName());
ASSERT_EQUAL("foobar", cfg->myField);
}
diff --git a/config/src/tests/raw_subscription/raw_subscription.cpp b/config/src/tests/raw_subscription/raw_subscription.cpp
index 478b4611bac..39062f4e7ac 100644
--- a/config/src/tests/raw_subscription/raw_subscription.cpp
+++ b/config/src/tests/raw_subscription/raw_subscription.cpp
@@ -2,6 +2,7 @@
#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/config/config.h>
#include <vespa/config/common/configholder.h>
+#include <vespa/config/common/sourcefactory.h>
#include <vespa/config/raw/rawsource.h>
#include "config-my.h"
@@ -10,7 +11,7 @@ using namespace config;
TEST("require that raw spec can create source factory")
{
RawSpec spec("myField \"foo\"\n");
- SourceFactory::UP raw = spec.createSourceFactory(TimingValues());
+ auto raw = spec.createSourceFactory(TimingValues());
ASSERT_TRUE(raw);
IConfigHolder::SP holder(new ConfigHolder());
Source::UP src = raw->createSource(holder, ConfigKey("myid", "my", "bar", "foo"));
diff --git a/config/src/tests/unittest/unittest.cpp b/config/src/tests/unittest/unittest.cpp
index 4b46dcef900..46aefe152af 100644
--- a/config/src/tests/unittest/unittest.cpp
+++ b/config/src/tests/unittest/unittest.cpp
@@ -2,6 +2,7 @@
#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/config/config.h>
+#include <vespa/config/common/configcontext.h>
#include "config-my.h"
#include "config-foo.h"
#include "config-bar.h"
@@ -15,13 +16,13 @@ using namespace std::chrono_literals;
namespace {
void verifyConfig(const std::string & expected, std::unique_ptr<FooConfig> cfg)
{
- ASSERT_TRUE(cfg.get() != NULL);
+ ASSERT_TRUE(cfg);
ASSERT_EQUAL(expected, cfg->fooValue);
}
void verifyConfig(const std::string & expected, std::unique_ptr<BarConfig> cfg)
{
- ASSERT_TRUE(cfg.get() != NULL);
+ ASSERT_TRUE(cfg);
ASSERT_EQUAL(expected, cfg->barValue);
}
}
@@ -37,7 +38,7 @@ TEST("requireThatUnitTestsCanBeCreated") {
TEST("requireThatConfigCanBeReloaded") {
ConfigSet set;
- ConfigContext::SP ctx(new ConfigContext(set));
+ auto ctx = std::make_shared<ConfigContext>(set);
MyConfigBuilder builder;
builder.myField = "myfoo";
set.addBuilder("myid", &builder);
@@ -46,7 +47,7 @@ TEST("requireThatConfigCanBeReloaded") {
ConfigHandle<MyConfig>::UP handle = subscriber.subscribe<MyConfig>("myid");
ASSERT_TRUE(subscriber.nextConfigNow());
std::unique_ptr<MyConfig> cfg(handle->getConfig());
- ASSERT_TRUE(cfg.get() != NULL);
+ ASSERT_TRUE(cfg);
ASSERT_EQUAL("myfoo", cfg->myField);
ctx->reload();
ASSERT_FALSE(subscriber.nextConfig(1000ms));
@@ -54,13 +55,13 @@ TEST("requireThatConfigCanBeReloaded") {
ctx->reload();
ASSERT_TRUE(subscriber.nextConfig(10000ms));
cfg = handle->getConfig();
- ASSERT_TRUE(cfg.get() != NULL);
+ ASSERT_TRUE(cfg);
ASSERT_EQUAL("foobar", cfg->myField);
}
TEST("requireThatCanSubscribeWithSameIdToDifferentDefs") {
ConfigSet set;
- ConfigContext::SP ctx(new ConfigContext(set));
+ auto ctx = std::make_shared<ConfigContext>(set);
FooConfigBuilder fooBuilder;
BarConfigBuilder barBuilder;
diff --git a/config/src/vespa/config/common/configcontext.cpp b/config/src/vespa/config/common/configcontext.cpp
index ed549f0cb6a..0eed91296a6 100644
--- a/config/src/vespa/config/common/configcontext.cpp
+++ b/config/src/vespa/config/common/configcontext.cpp
@@ -8,26 +8,26 @@ namespace config {
ConfigContext::ConfigContext(const SourceSpec & spec)
: _timingValues(),
_generation(1),
- _manager(spec.createSourceFactory(_timingValues), _generation)
+ _manager(std::make_unique<ConfigManager>(spec.createSourceFactory(_timingValues), _generation))
{ }
ConfigContext::ConfigContext(const TimingValues & timingValues, const SourceSpec & spec)
: _timingValues(timingValues),
_generation(1),
- _manager(spec.createSourceFactory(_timingValues), _generation)
+ _manager(std::make_unique<ConfigManager>(spec.createSourceFactory(_timingValues), _generation))
{ }
IConfigManager &
ConfigContext::getManagerInstance()
{
- return _manager;
+ return *_manager;
}
void
ConfigContext::reload()
{
_generation++;
- _manager.reload(_generation);
+ _manager->reload(_generation);
}
} // namespace config
diff --git a/config/src/vespa/config/common/configcontext.h b/config/src/vespa/config/common/configcontext.h
index 7d9836fe70b..dd3296a9b01 100644
--- a/config/src/vespa/config/common/configcontext.h
+++ b/config/src/vespa/config/common/configcontext.h
@@ -3,7 +3,7 @@
#include "iconfigcontext.h"
#include "timingvalues.h"
-#include "configmanager.h"
+#include "iconfigmanager.h"
#include <vespa/config/subscription/sourcespec.h>
namespace config {
@@ -19,7 +19,7 @@ public:
private:
TimingValues _timingValues;
int64_t _generation;
- ConfigManager _manager;
+ std::unique_ptr<IConfigManager> _manager;
};
diff --git a/config/src/vespa/config/common/configholder.cpp b/config/src/vespa/config/common/configholder.cpp
index c2839b4a123..66c214f470b 100644
--- a/config/src/vespa/config/common/configholder.cpp
+++ b/config/src/vespa/config/common/configholder.cpp
@@ -5,7 +5,8 @@
namespace config {
ConfigHolder::ConfigHolder()
- : _monitor(),
+ : _lock(),
+ _cond(),
_current()
{
}
@@ -15,40 +16,39 @@ ConfigHolder::~ConfigHolder() = default;
ConfigUpdate::UP
ConfigHolder::provide()
{
- vespalib::MonitorGuard guard(_monitor);
+ std::lock_guard guard(_lock);
return std::move(_current);
}
void
ConfigHolder::handle(ConfigUpdate::UP update)
{
- vespalib::MonitorGuard guard(_monitor);
+ std::lock_guard guard(_lock);
if (_current) {
update->merge(*_current);
}
_current = std::move(update);
- guard.broadcast();
+ _cond.notify_all();
}
bool
ConfigHolder::wait(milliseconds timeoutInMillis)
{
- vespalib::MonitorGuard guard(_monitor);
- return static_cast<bool>(_current) || guard.wait(timeoutInMillis);
+ std::unique_lock guard(_lock);
+ return static_cast<bool>(_current) || (_cond.wait_for(guard, timeoutInMillis) == std::cv_status::no_timeout);
}
bool
ConfigHolder::poll()
{
- vespalib::MonitorGuard guard(_monitor);
+ std::lock_guard guard(_lock);
return static_cast<bool>(_current);
}
void
ConfigHolder::interrupt()
{
- vespalib::MonitorGuard guard(_monitor);
- guard.broadcast();
+ _cond.notify_all();
}
} // namespace config
diff --git a/config/src/vespa/config/common/configholder.h b/config/src/vespa/config/common/configholder.h
index be65d6cff39..35bb6a8ccc2 100644
--- a/config/src/vespa/config/common/configholder.h
+++ b/config/src/vespa/config/common/configholder.h
@@ -2,7 +2,8 @@
#pragma once
#include "iconfigholder.h"
-#include <vespa/vespalib/util/sync.h>
+#include <mutex>
+#include <condition_variable>
namespace config {
@@ -21,8 +22,9 @@ public:
bool poll() override;
void interrupt() override;
public:
- vespalib::Monitor _monitor;
- ConfigUpdate::UP _current;
+ std::mutex _lock;
+ std::condition_variable _cond;
+ ConfigUpdate::UP _current;
};
} // namespace config
diff --git a/config/src/vespa/config/common/configmanager.cpp b/config/src/vespa/config/common/configmanager.cpp
index 11fe66a1c64..df8615c9c40 100644
--- a/config/src/vespa/config/common/configmanager.cpp
+++ b/config/src/vespa/config/common/configmanager.cpp
@@ -18,8 +18,7 @@ ConfigManager::ConfigManager(SourceFactory::UP sourceFactory, int64_t initialGen
_sourceFactory(std::move(sourceFactory)),
_generation(initialGeneration),
_subscriptionMap(),
- _lock(),
- _firstLock()
+ _lock()
{ }
ConfigManager::~ConfigManager() = default;
@@ -50,7 +49,7 @@ ConfigManager::subscribe(const ConfigKey & key, milliseconds timeoutInMillis)
throw ConfigTimeoutException(oss.str());
}
LOG(debug, "done subscribing");
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_subscriptionMap[id] = subscription;
return subscription;
}
@@ -58,7 +57,7 @@ ConfigManager::subscribe(const ConfigKey & key, milliseconds timeoutInMillis)
void
ConfigManager::unsubscribe(const ConfigSubscription::SP & subscription)
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
const SubscriptionId id(subscription->getSubscriptionId());
if (_subscriptionMap.find(id) != _subscriptionMap.end())
_subscriptionMap.erase(id);
@@ -68,9 +67,9 @@ void
ConfigManager::reload(int64_t generation)
{
_generation = generation;
- vespalib::LockGuard guard(_lock);
- for (SubscriptionMap::iterator it(_subscriptionMap.begin()), mt(_subscriptionMap.end()); it != mt; it++) {
- it->second->reload(_generation);
+ std::lock_guard guard(_lock);
+ for (auto & entry : _subscriptionMap) {
+ entry.second->reload(_generation);
}
}
diff --git a/config/src/vespa/config/common/configmanager.h b/config/src/vespa/config/common/configmanager.h
index 6210a03c0d1..0252c6aa572 100644
--- a/config/src/vespa/config/common/configmanager.h
+++ b/config/src/vespa/config/common/configmanager.h
@@ -4,8 +4,8 @@
#include <vespa/config/subscription/configsubscription.h>
#include "iconfigmanager.h"
#include "sourcefactory.h"
-#include <vespa/vespalib/util/sync.h>
#include <map>
+#include <mutex>
namespace config {
@@ -22,7 +22,7 @@ class ConfigManager : public IConfigManager
{
public:
ConfigManager(SourceFactory::UP sourceFactory, int64_t initialGeneration);
- ~ConfigManager();
+ ~ConfigManager() override;
// Implements IConfigManager
ConfigSubscription::SP subscribe(const ConfigKey & key, milliseconds timeoutInMillis) override;
@@ -40,8 +40,7 @@ private:
typedef std::map<SubscriptionId, ConfigSubscription::SP> SubscriptionMap;
SubscriptionMap _subscriptionMap;
- vespalib::Lock _lock;
- vespalib::Lock _firstLock;
+ std::mutex _lock;
};
} // namespace config
diff --git a/config/src/vespa/config/frt/frtconnection.h b/config/src/vespa/config/frt/frtconnection.h
index bde3e79b83c..9e6ef688607 100644
--- a/config/src/vespa/config/frt/frtconnection.h
+++ b/config/src/vespa/config/frt/frtconnection.h
@@ -2,7 +2,6 @@
#pragma once
#include "connection.h"
-#include <vespa/vespalib/util/sync.h>
#include <vespa/config/common/timingvalues.h>
#include <atomic>
diff --git a/config/src/vespa/config/frt/frtsource.cpp b/config/src/vespa/config/frt/frtsource.cpp
index 94acabc5926..bee5158ecb8 100644
--- a/config/src/vespa/config/frt/frtsource.cpp
+++ b/config/src/vespa/config/frt/frtsource.cpp
@@ -3,6 +3,7 @@
#include "frtconfigresponse.h"
#include "frtsource.h"
#include <vespa/vespalib/util/closuretask.h>
+#include <cassert>
#include <vespa/log/log.h>
LOG_SETUP(".config.frt.frtsource");
@@ -73,7 +74,7 @@ FRTSource::RequestDone(FRT_RPCRequest * request)
LOG(debug, "request aborted, stopping");
return;
}
- assert(_currentRequest.get() != NULL);
+ assert(_currentRequest);
// If this was error from FRT side and nothing to do with config, notify
// connection about the error.
if (request->IsError()) {
@@ -88,7 +89,7 @@ void
FRTSource::close()
{
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
if (_closed)
return;
LOG(spam, "Killing task");
@@ -106,7 +107,7 @@ FRTSource::close()
void
FRTSource::scheduleNextGetConfig()
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
if (_closed)
return;
double sec = _agent->getWaitTime() / 1000.0;
diff --git a/config/src/vespa/config/frt/frtsource.h b/config/src/vespa/config/frt/frtsource.h
index 16e1bfac37a..eabac3bf012 100644
--- a/config/src/vespa/config/frt/frtsource.h
+++ b/config/src/vespa/config/frt/frtsource.h
@@ -9,8 +9,6 @@
#include <vespa/config/common/source.h>
#include <vespa/fnet/frt/invoker.h>
-#include <vespa/vespalib/util/sync.h>
-
namespace config {
/**
@@ -21,7 +19,7 @@ class FRTSource : public Source,
{
public:
FRTSource(const ConnectionFactory::SP & connectionFactory, const FRTConfigRequestFactory & requestFactory, ConfigAgent::UP agent, const ConfigKey & key);
- ~FRTSource();
+ ~FRTSource() override;
void RequestDone(FRT_RPCRequest * request) override;
void close() override;
@@ -40,7 +38,7 @@ private:
const ConfigKey _key;
std::unique_ptr<FNET_Task> _task;
- vespalib::Lock _lock; // Protects _task and _closed
+ std::mutex _lock; // Protects _task and _closed
bool _closed;
};
diff --git a/config/src/vespa/config/frt/protocol.cpp b/config/src/vespa/config/frt/protocol.cpp
index 4ad55726863..cfd248e5d86 100644
--- a/config/src/vespa/config/frt/protocol.cpp
+++ b/config/src/vespa/config/frt/protocol.cpp
@@ -4,6 +4,7 @@
#include <vespa/vespalib/util/stringfmt.h>
#include <vespa/vespalib/data/slime/slime.h>
#include <sstream>
+#include <cassert>
#include <vespa/log/log.h>
LOG_SETUP(".config.frt.protocol");
diff --git a/config/src/vespa/config/helper/configfetcher.cpp b/config/src/vespa/config/helper/configfetcher.cpp
index b013c137c2c..dda9c67f056 100644
--- a/config/src/vespa/config/helper/configfetcher.cpp
+++ b/config/src/vespa/config/helper/configfetcher.cpp
@@ -2,6 +2,7 @@
#include "configfetcher.h"
#include <vespa/config/common/exceptions.h>
+#include <vespa/config/common/configcontext.h>
#include <vespa/vespalib/util/thread.h>
#include <vespa/log/log.h>
LOG_SETUP(".config.helper.configfetcher");
diff --git a/config/src/vespa/config/helper/legacysubscriber.hpp b/config/src/vespa/config/helper/legacysubscriber.hpp
index bffe1d3feca..4aa383c6f9b 100644
--- a/config/src/vespa/config/helper/legacysubscriber.hpp
+++ b/config/src/vespa/config/helper/legacysubscriber.hpp
@@ -1,5 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include <vespa/config/common/configcontext.h>
+
namespace config {
template <typename ConfigType>
@@ -9,10 +11,10 @@ LegacySubscriber::subscribe(const std::string & configId, IFetcherCallback<Confi
if (isLegacyConfigId(configId)) {
std::string legacyId(legacyConfigId2ConfigId(configId));
std::unique_ptr<SourceSpec> spec(legacyConfigId2Spec(configId));
- _fetcher.reset(new ConfigFetcher(IConfigContext::SP(new ConfigContext(*spec))));
+ _fetcher = std::make_unique<ConfigFetcher>(std::make_shared<ConfigContext>(*spec));
_fetcher->subscribe<ConfigType>(legacyId, callback);
} else {
- _fetcher.reset(new ConfigFetcher());
+ _fetcher = std::make_unique<ConfigFetcher>();
_fetcher->subscribe<ConfigType>(configId, callback);
}
_configId = configId;
diff --git a/config/src/vespa/config/retriever/configretriever.cpp b/config/src/vespa/config/retriever/configretriever.cpp
index 08e7f15f0c5..a77c8114322 100644
--- a/config/src/vespa/config/retriever/configretriever.cpp
+++ b/config/src/vespa/config/retriever/configretriever.cpp
@@ -2,6 +2,8 @@
#include "configretriever.h"
#include <vespa/config/common/exceptions.h>
+#include <vespa/config/subscription/sourcespec.h>
+#include <cassert>
using std::chrono::milliseconds;
@@ -51,7 +53,7 @@ ConfigRetriever::getConfigs(const ConfigKeySet & keySet, milliseconds timeoutInM
if (keySet != _lastKeySet) {
_lastKeySet = keySet;
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
if (_closed)
return ConfigSnapshot();
_configSubscriber = std::make_unique<GenericConfigSubscriber>(_context);
@@ -82,7 +84,7 @@ ConfigRetriever::getConfigs(const ConfigKeySet & keySet, milliseconds timeoutInM
void
ConfigRetriever::close()
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_closed = true;
_bootstrapSubscriber.close();
if (_configSubscriber)
diff --git a/config/src/vespa/config/retriever/configretriever.h b/config/src/vespa/config/retriever/configretriever.h
index 14e3171fc62..1207a17af97 100644
--- a/config/src/vespa/config/retriever/configretriever.h
+++ b/config/src/vespa/config/retriever/configretriever.h
@@ -1,17 +1,18 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
-#include "configkeyset.h"
#include "configsnapshot.h"
#include "genericconfigsubscriber.h"
#include "fixedconfigsubscriber.h"
#include <vespa/config/common/configkey.h>
#include <vespa/config/subscription/configsubscription.h>
#include <vespa/vespalib/stllike/string.h>
-
+#include <mutex>
namespace config {
+class SourceSpec;
+
/**
* A ConfigRetriever is a helper class for retrieving a set of dynamically
* changing and depending configs. You should use this class whenever you have a
@@ -94,7 +95,7 @@ public:
private:
FixedConfigSubscriber _bootstrapSubscriber;
std::unique_ptr<GenericConfigSubscriber> _configSubscriber;
- vespalib::Lock _lock;
+ std::mutex _lock;
std::vector<ConfigSubscription::SP> _subscriptionList;
ConfigKeySet _lastKeySet;
IConfigContext::SP _context;
diff --git a/config/src/vespa/config/retriever/simpleconfigurer.cpp b/config/src/vespa/config/retriever/simpleconfigurer.cpp
index 1f8868f9d6a..0091fa7bfd5 100644
--- a/config/src/vespa/config/retriever/simpleconfigurer.cpp
+++ b/config/src/vespa/config/retriever/simpleconfigurer.cpp
@@ -1,8 +1,10 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include "simpleconfigurer.h"
+#include <cassert>
+
#include <vespa/log/log.h>
LOG_SETUP(".config.retriever.simpleconfigurer");
-#include "simpleconfigurer.h"
namespace config {
@@ -12,7 +14,7 @@ SimpleConfigurer::SimpleConfigurer(SimpleConfigRetriever::UP retriever, SimpleCo
_thread(*this),
_started(false)
{
- assert(_retriever.get() != NULL);
+ assert(_retriever);
}
void
diff --git a/config/src/vespa/config/subscription/configsubscriber.cpp b/config/src/vespa/config/subscription/configsubscriber.cpp
index b226c149b9e..cb735e4353a 100644
--- a/config/src/vespa/config/subscription/configsubscriber.cpp
+++ b/config/src/vespa/config/subscription/configsubscriber.cpp
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "configsubscriber.h"
+#include <vespa/config/common/configcontext.h>
namespace config {
diff --git a/config/src/vespa/config/subscription/configsubscriber.h b/config/src/vespa/config/subscription/configsubscriber.h
index 4787c6cd858..d7139b5d61f 100644
--- a/config/src/vespa/config/subscription/configsubscriber.h
+++ b/config/src/vespa/config/subscription/configsubscriber.h
@@ -7,6 +7,7 @@
#include "configsubscriptionset.h"
#include "configprovider.h"
#include "sourcespec.h"
+#include <vespa/config/common/timingvalues.h>
namespace config {
diff --git a/config/src/vespa/config/subscription/configsubscription.h b/config/src/vespa/config/subscription/configsubscription.h
index 80051edb86b..a48fddaa41c 100644
--- a/config/src/vespa/config/subscription/configsubscription.h
+++ b/config/src/vespa/config/subscription/configsubscription.h
@@ -1,10 +1,9 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
-#include <memory>
+#include "subscriptionid.h"
#include <vespa/config/common/iconfigholder.h>
#include <vespa/config/common/configkey.h>
#include <vespa/config/common/source.h>
-#include "subscriptionid.h"
#include <atomic>
#include <chrono>
diff --git a/config/src/vespa/config/subscription/configsubscriptionset.h b/config/src/vespa/config/subscription/configsubscriptionset.h
index 181f79f0ef2..3e91f1cc68d 100644
--- a/config/src/vespa/config/subscription/configsubscriptionset.h
+++ b/config/src/vespa/config/subscription/configsubscriptionset.h
@@ -2,13 +2,12 @@
//
#pragma once
-#include <vespa/config/common/iconfigholder.h>
-#include <vespa/config/common/configcontext.h>
#include "confighandle.h"
#include "subscriptionid.h"
#include "configsubscription.h"
#include "configprovider.h"
-
+#include <vespa/config/common/iconfigcontext.h>
+#include <vespa/config/common/iconfigmanager.h>
#include <atomic>
namespace config {
diff --git a/config/src/vespa/config/subscription/sourcespec.cpp b/config/src/vespa/config/subscription/sourcespec.cpp
index 30926d75465..326b3191fd0 100644
--- a/config/src/vespa/config/subscription/sourcespec.cpp
+++ b/config/src/vespa/config/subscription/sourcespec.cpp
@@ -10,6 +10,7 @@
#include <vespa/config/set/configinstancesourcefactory.h>
#include <vespa/vespalib/text/stringtokenizer.h>
#include <vespa/config/print/asciiconfigwriter.h>
+#include <cassert>
namespace config {
diff --git a/config/src/vespa/config/subscription/subscriptionid.h b/config/src/vespa/config/subscription/subscriptionid.h
index fe87debb58f..67dd905f523 100644
--- a/config/src/vespa/config/subscription/subscriptionid.h
+++ b/config/src/vespa/config/subscription/subscriptionid.h
@@ -1,6 +1,8 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
+#include <cstdint>
+
namespace config {
typedef uint64_t SubscriptionId;
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
index 4fba0204f55..083112d8456 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
@@ -132,6 +132,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
private final TesterClient testerClient;
private final Metric metric;
private final BooleanFlag deployWithInternalRestart;
+ private final BooleanFlag acquireProvisionLock;
@Inject
public ApplicationRepository(TenantRepository tenantRepository,
@@ -182,6 +183,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
this.testerClient = Objects.requireNonNull(testerClient);
this.metric = Objects.requireNonNull(metric);
this.deployWithInternalRestart = Flags.DEPLOY_WITH_INTERNAL_RESTART.bindTo(flagSource);
+ this.acquireProvisionLock = Flags.ALWAYS_ACQUIRE_PROVISION_LOCK.bindTo(flagSource);
}
public static class Builder {
@@ -508,7 +510,15 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
// and allocated hosts in model and handlers in RPC server
transaction.add(tenantApplications.createDeleteTransaction(applicationId));
- hostProvisioner.ifPresent(provisioner -> provisioner.remove(transaction, applicationId));
+ hostProvisioner.ifPresent(provisioner -> {
+ if (acquireProvisionLock.value()) {
+ try (var provisionLock = provisioner.lock(applicationId)) {
+ provisioner.remove(transaction, provisionLock);
+ }
+ } else {
+ provisioner.remove(transaction, applicationId);
+ }
+ });
transaction.onCommitted(() -> log.log(Level.INFO, "Deleted " + applicationId));
transaction.commit();
return true;
@@ -722,13 +732,19 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
// ---------------- Session operations ----------------------------------------------------------------
-
-
public CompletionWaiter activate(LocalSession session, Session previousActiveSession, ApplicationId applicationId, boolean force) {
CompletionWaiter waiter = session.getSessionZooKeeperClient().createActiveWaiter();
NestedTransaction transaction = new NestedTransaction();
transaction.add(deactivateCurrentActivateNew(previousActiveSession, session, force));
- hostProvisioner.ifPresent(provisioner -> provisioner.activate(transaction, applicationId, session.getAllocatedHosts().getHosts()));
+ hostProvisioner.ifPresent(provisioner -> {
+ if (acquireProvisionLock.value()) {
+ try (var lock = provisioner.lock(applicationId)) {
+ provisioner.activate(transaction, session.getAllocatedHosts().getHosts(), lock);
+ }
+ } else {
+ provisioner.activate(transaction, applicationId, session.getAllocatedHosts().getHosts());
+ }
+ });
transaction.commit();
return waiter;
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/metrics/ClusterDeploymentMetricsRetriever.java b/configserver/src/main/java/com/yahoo/vespa/config/server/metrics/ClusterDeploymentMetricsRetriever.java
index 8e7e4eec9b0..a185bcaab8a 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/metrics/ClusterDeploymentMetricsRetriever.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/metrics/ClusterDeploymentMetricsRetriever.java
@@ -2,7 +2,7 @@
package com.yahoo.vespa.config.server.metrics;
import ai.vespa.util.http.VespaHttpClientBuilder;
-import java.util.logging.Level;
+import com.yahoo.concurrent.DaemonThreadFactory;
import com.yahoo.slime.ArrayTraverser;
import com.yahoo.slime.Inspector;
import com.yahoo.slime.Slime;
@@ -13,13 +13,18 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import java.io.IOException;
import java.net.URI;
+import java.time.Duration;
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
import java.util.logging.Logger;
+import java.util.stream.Collectors;
/**
@@ -39,13 +44,15 @@ public class ClusterDeploymentMetricsRetriever {
private static final List<String> WANTED_METRIC_SERVICES = List.of(VESPA_CONTAINER, VESPA_QRSERVER, VESPA_DISTRIBUTOR);
+ private static final ExecutorService executor = Executors.newFixedThreadPool(10, new DaemonThreadFactory("cluster-deployment-metrics-retriever-"));
private static final CloseableHttpClient httpClient = VespaHttpClientBuilder
.create(PoolingHttpClientConnectionManager::new)
.setDefaultRequestConfig(
RequestConfig.custom()
- .setConnectTimeout(10 * 1000)
- .setSocketTimeout(10 * 1000)
+ .setConnectionRequestTimeout((int)Duration.ofSeconds(60).toMillis())
+ .setConnectTimeout((int)Duration.ofSeconds(10).toMillis())
+ .setSocketTimeout((int)Duration.ofSeconds(10).toMillis())
.build())
.build();
@@ -57,19 +64,20 @@ public class ClusterDeploymentMetricsRetriever {
Map<ClusterInfo, DeploymentMetricsAggregator> clusterMetricsMap = new ConcurrentHashMap<>();
long startTime = System.currentTimeMillis();
- Runnable retrieveMetricsJob = () ->
- hosts.parallelStream().forEach(host ->
- getHostMetrics(host, clusterMetricsMap)
- );
-
- ForkJoinPool threadPool = new ForkJoinPool(10);
- threadPool.submit(retrieveMetricsJob);
- threadPool.shutdown();
-
+ List<Callable<Void>> jobs = hosts.stream()
+ .map(hostUri -> (Callable<Void>) () -> {
+ try {
+ getHostMetrics(hostUri, clusterMetricsMap);
+ } catch (Exception e) {
+ log.log(Level.FINE, e, () -> "Failed to download metrics: " + e.getMessage());
+ }
+ return null;
+ })
+ .collect(Collectors.toList());
try {
- threadPool.awaitTermination(1, TimeUnit.MINUTES);
+ executor.invokeAll(jobs, 1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
- throw new RuntimeException(e);
+ throw new RuntimeException("Failed to retrieve metrics in time: " + e.getMessage(), e);
}
log.log(Level.FINE, () ->
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/configchange/ConfigChangeActionsBuilder.java b/configserver/src/test/java/com/yahoo/vespa/config/server/configchange/ConfigChangeActionsBuilder.java
index ead1e79a416..fe3155b251c 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/configchange/ConfigChangeActionsBuilder.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/configchange/ConfigChangeActionsBuilder.java
@@ -4,6 +4,7 @@ package com.yahoo.vespa.config.server.configchange;
import com.google.common.collect.ImmutableMap;
import com.yahoo.config.model.api.ConfigChangeAction;
import com.yahoo.config.model.api.ServiceInfo;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.model.application.validation.change.VespaRestartAction;
import java.util.ArrayList;
@@ -27,9 +28,10 @@ public class ConfigChangeActionsBuilder {
}
public ConfigChangeActionsBuilder restart(String message, String clusterName, String clusterType, String serviceType, String serviceName, boolean ignoreForInternalRedeploy) {
- actions.add(new VespaRestartAction(message,
- createService(clusterName, clusterType, serviceType, serviceName),
- ignoreForInternalRedeploy));
+ actions.add(new VespaRestartAction(ClusterSpec.Id.from(clusterName),
+ message,
+ createService(clusterName, clusterType, serviceType, serviceName),
+ ignoreForInternalRedeploy));
return this;
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java
index 7553583e70c..87122fdba45 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java
@@ -22,6 +22,7 @@ import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.HostFilter;
import com.yahoo.config.provision.HostSpec;
+import com.yahoo.config.provision.ProvisionLock;
import com.yahoo.config.provision.ProvisionLogger;
import com.yahoo.config.provision.Provisioner;
import com.yahoo.config.provision.TenantName;
@@ -227,15 +228,28 @@ public class DeployTester {
}
@Override
+ public void activate(NestedTransaction transaction, Collection<HostSpec> hosts, ProvisionLock lock) {
+ }
+
+ @Override
public void remove(NestedTransaction transaction, ApplicationId application) {
// noop
}
@Override
+ public void remove(NestedTransaction transaction, ProvisionLock lock) {
+ }
+
+ @Override
public void restart(ApplicationId application, HostFilter filter) {
// noop
}
+ @Override
+ public ProvisionLock lock(ApplicationId application) {
+ return null;
+ }
+
}
private static class FailingModelFactory implements ModelFactory {
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/HostedDeployTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/HostedDeployTest.java
index 18ca54e8c11..52fdb3e7c1f 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/HostedDeployTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/HostedDeployTest.java
@@ -15,6 +15,7 @@ import com.yahoo.config.model.provision.Hosts;
import com.yahoo.config.model.provision.InMemoryProvisioner;
import com.yahoo.config.model.test.HostedConfigModelRegistry;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.RegionName;
@@ -377,8 +378,10 @@ public class HostedDeployTest {
new ServiceInfo("serviceName", "serviceType", null, new HashMap<>(), "configId", "hostName"));
List<ModelFactory> modelFactories = List.of(
- new ConfigChangeActionsModelFactory(Version.fromString("6.1.0"), new VespaRestartAction("change", services)),
- new ConfigChangeActionsModelFactory(Version.fromString("6.2.0"), new VespaRestartAction("other change", services)));
+ new ConfigChangeActionsModelFactory(Version.fromString("6.1.0"),
+ new VespaRestartAction(ClusterSpec.Id.from("test"), "change", services)),
+ new ConfigChangeActionsModelFactory(Version.fromString("6.2.0"),
+ new VespaRestartAction(ClusterSpec.Id.from("test"), "other change", services)));
DeployTester tester = createTester(hosts, modelFactories, prodZone);
PrepareResult prepareResult = tester.deployApp("src/test/apps/hosted/", "6.2.0");
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/SessionHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/SessionHandlerTest.java
index 9d696ae34e7..32a9e867684 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/SessionHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/SessionHandlerTest.java
@@ -6,6 +6,7 @@ import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.HostFilter;
import com.yahoo.config.provision.HostSpec;
+import com.yahoo.config.provision.ProvisionLock;
import com.yahoo.config.provision.ProvisionLogger;
import com.yahoo.config.provision.Provisioner;
import com.yahoo.container.jdisc.HttpRequest;
@@ -102,17 +103,32 @@ public class SessionHandlerTest {
}
@Override
+ public void activate(NestedTransaction transaction, Collection<HostSpec> hosts, ProvisionLock lock) {
+
+ }
+
+ @Override
public void remove(NestedTransaction transaction, ApplicationId application) {
removed = true;
lastApplicationId = application;
}
@Override
+ public void remove(NestedTransaction transaction, ProvisionLock lock) {
+
+ }
+
+ @Override
public void restart(ApplicationId application, HostFilter filter) {
restarted = true;
lastApplicationId = application;
}
+ @Override
+ public ProvisionLock lock(ApplicationId application) {
+ return null;
+ }
+
}
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/MaintainerTester.java b/configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/MaintainerTester.java
index 712242a69e6..d092a3139a0 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/MaintainerTester.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/MaintainerTester.java
@@ -9,6 +9,7 @@ import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.HostFilter;
import com.yahoo.config.provision.HostSpec;
+import com.yahoo.config.provision.ProvisionLock;
import com.yahoo.config.provision.ProvisionLogger;
import com.yahoo.config.provision.Provisioner;
import com.yahoo.transaction.NestedTransaction;
@@ -95,15 +96,30 @@ class MaintainerTester {
}
@Override
+ public void activate(NestedTransaction transaction, Collection<HostSpec> hosts, ProvisionLock lock) {
+
+ }
+
+ @Override
public void remove(NestedTransaction transaction, ApplicationId application) {
// noop
}
@Override
+ public void remove(NestedTransaction transaction, ProvisionLock lock) {
+
+ }
+
+ @Override
public void restart(ApplicationId application, HostFilter filter) {
// noop
}
+ @Override
+ public ProvisionLock lock(ApplicationId application) {
+ return null;
+ }
+
}
-} \ No newline at end of file
+}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java
index 3858388ed39..43504988d67 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/session/SessionPreparerTest.java
@@ -17,6 +17,7 @@ import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.HostFilter;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.InstanceName;
+import com.yahoo.config.provision.ProvisionLock;
import com.yahoo.config.provision.ProvisionLogger;
import com.yahoo.config.provision.Provisioner;
import com.yahoo.config.provision.TenantName;
@@ -422,11 +423,26 @@ public class SessionPreparerTest {
public void activate(NestedTransaction transaction, ApplicationId application, Collection<HostSpec> hosts) { }
@Override
+ public void activate(NestedTransaction transaction, Collection<HostSpec> hosts, ProvisionLock lock) {
+
+ }
+
+ @Override
public void remove(NestedTransaction transaction, ApplicationId application) { }
@Override
+ public void remove(NestedTransaction transaction, ProvisionLock lock) {
+
+ }
+
+ @Override
public void restart(ApplicationId application, HostFilter filter) { }
+ @Override
+ public ProvisionLock lock(ApplicationId application) {
+ return null;
+ }
+
}
}
diff --git a/configutil/src/tests/config_status/config_status_test.cpp b/configutil/src/tests/config_status/config_status_test.cpp
index 3cc5b2f4525..4d85b22a5c4 100644
--- a/configutil/src/tests/config_status/config_status_test.cpp
+++ b/configutil/src/tests/config_status/config_status_test.cpp
@@ -5,6 +5,7 @@
#include <vespa/config-model.h>
#include <vespa/config/config.h>
#include <vespa/config/subscription/sourcespec.h>
+#include <vespa/config/common/configcontext.h>
using namespace config;
using vespalib::Portal;
@@ -54,7 +55,7 @@ public:
{
flags.verbose = true;
ConfigSet set;
- ConfigContext::SP ctx(new ConfigContext(set));
+ auto ctx = std::make_shared<ConfigContext>(set);
cloud::config::ModelConfigBuilder builder;
cloud::config::ModelConfigBuilder::Hosts::Services::Ports port;
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java
index 548ad0af484..8c21e6facec 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java
@@ -166,7 +166,7 @@ enum Policy {
/** Read the generated bills */
billingInformationRead(Privilege.grant(Action.read)
.on(PathGroup.billingList)
- .in(SystemName.PublicCd)),
+ .in(SystemName.PublicCd, SystemName.Public)),
/** Invoice management */
hostedAccountant(Privilege.grant(Action.all())
diff --git a/dist/vespa.spec b/dist/vespa.spec
index 71fd3170338..b41a4e420a0 100644
--- a/dist/vespa.spec
+++ b/dist/vespa.spec
@@ -110,7 +110,7 @@ BuildRequires: gtest-devel
BuildRequires: gmock-devel
%endif
%endif
-BuildRequires: xxhash-devel >= 0.7.3
+BuildRequires: xxhash-devel >= 0.8.0
BuildRequires: openblas-devel
BuildRequires: zlib-devel
BuildRequires: re2-devel
@@ -151,7 +151,7 @@ Requires: valgrind
%endif
Requires: Judy
Requires: xxhash
-Requires: xxhash-libs >= 0.7.3
+Requires: xxhash-libs >= 0.8.0
%if 0%{?el8}
Requires: openblas
%else
@@ -252,7 +252,7 @@ Vespa - The open big data serving engine - base
Summary: Vespa - The open big data serving engine - base C++ libs
-Requires: xxhash-libs >= 0.7.3
+Requires: xxhash-libs >= 0.8.0
%if 0%{?el7}
Requires: vespa-openssl >= 1.1.1g-1
%else
diff --git a/docker-api/src/main/java/com/yahoo/vespa/hosted/dockerapi/DockerEngine.java b/docker-api/src/main/java/com/yahoo/vespa/hosted/dockerapi/DockerEngine.java
index 6c831cef7d7..1f2a35a2a38 100644
--- a/docker-api/src/main/java/com/yahoo/vespa/hosted/dockerapi/DockerEngine.java
+++ b/docker-api/src/main/java/com/yahoo/vespa/hosted/dockerapi/DockerEngine.java
@@ -44,6 +44,7 @@ import java.util.logging.Logger;
import java.util.stream.Stream;
public class DockerEngine implements ContainerEngine {
+
private static final Logger logger = Logger.getLogger(DockerEngine.class.getName());
static final String LABEL_NAME_MANAGEDBY = "com.yahoo.vespa.managedby";
diff --git a/document/src/vespa/document/base/field.h b/document/src/vespa/document/base/field.h
index 613fcd9df1b..3a0c9b82136 100644
--- a/document/src/vespa/document/base/field.h
+++ b/document/src/vespa/document/base/field.h
@@ -97,13 +97,13 @@ public:
const DataType &getDataType() const { return *_dataType; }
- int getId() const { return _fieldId; }
+ int getId() const noexcept { return _fieldId; }
vespalib::string toString(bool verbose=false) const;
bool contains(const FieldSet& fields) const override;
Type getType() const override { return Type::FIELD; }
bool valid() const { return _fieldId != 0; }
- uint32_t hash() const { return getId(); }
+ uint32_t hash() const noexcept { return getId(); }
private:
int calculateIdV7();
diff --git a/document/src/vespa/document/bucket/CMakeLists.txt b/document/src/vespa/document/bucket/CMakeLists.txt
index 7704fe94bd0..fbbfe8b8466 100644
--- a/document/src/vespa/document/bucket/CMakeLists.txt
+++ b/document/src/vespa/document/bucket/CMakeLists.txt
@@ -2,7 +2,6 @@
vespa_add_library(document_bucket OBJECT
SOURCES
bucket.cpp
- bucketdistribution.cpp
bucketid.cpp
bucketidfactory.cpp
bucketidlist.cpp
diff --git a/document/src/vespa/document/bucket/bucketdistribution.cpp b/document/src/vespa/document/bucket/bucketdistribution.cpp
deleted file mode 100644
index 34ce9a9eccf..00000000000
--- a/document/src/vespa/document/bucket/bucketdistribution.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include "bucketdistribution.h"
-#include <vespa/log/log.h>
-
-LOG_SETUP(".bucketdistribution");
-
-namespace document {
-
-BucketDistribution::BucketDistribution(uint32_t numColumns, uint32_t numBucketBits) :
- _numColumns(0),
- _numBucketBits(numBucketBits),
- _bucketToColumn(),
- _lock()
-{
- _bucketToColumn.resize(getNumBuckets());
- reset();
- setNumColumns(numColumns);
-}
-
-void
-BucketDistribution::getBucketCount(uint32_t numColumns, uint32_t numBucketBits, std::vector<uint32_t> &ret)
-{
- ret.resize(numColumns);
- uint32_t cnt = getNumBuckets(numBucketBits) / numColumns;
- uint32_t rst = getNumBuckets(numBucketBits) % numColumns;
- for (uint32_t i = 0; i < numColumns; ++i) {
- ret[i] = cnt + (i < rst ? 1 : 0);
- }
-}
-
-void
-BucketDistribution::getBucketMigrateCount(uint32_t numColumns, uint32_t numBucketBits, std::vector<uint32_t> &ret)
-{
- getBucketCount(numColumns++, numBucketBits, ret);
- uint32_t cnt = getNumBuckets(numBucketBits) / numColumns;
- uint32_t rst = getNumBuckets(numBucketBits) % numColumns;
- for (uint32_t i = 0; i < numColumns - 1; ++i) {
- ret[i] -= cnt + (i < rst ? 1 : 0);
- }
-}
-
-void
-BucketDistribution::reset()
-{
- for (std::vector<uint32_t>::iterator it = _bucketToColumn.begin();
- it != _bucketToColumn.end(); ++it) {
- *it = 0;
- }
- _numColumns = 1;
-}
-
-void
-BucketDistribution::addColumn()
-{
- uint32_t newColumns = _numColumns + 1;
- std::vector<uint32_t> migrate;
- getBucketMigrateCount(_numColumns, _numBucketBits, migrate);
- uint32_t numBuckets = getNumBuckets(_numBucketBits);
- for (uint32_t i = 0; i < numBuckets; ++i) {
- uint32_t old = _bucketToColumn[i];
- if (migrate[old] > 0) {
- _bucketToColumn[i] = _numColumns; // move this bucket to the new column
- migrate[old]--;
- }
- }
- _numColumns = newColumns;
-}
-
-void
-BucketDistribution::setNumColumns(uint32_t numColumns)
-{
- vespalib::LockGuard guard(_lock);
- if (numColumns < _numColumns) {
- reset();
- }
- if (numColumns == _numColumns) {
- return;
- }
- for (int i = numColumns - _numColumns; --i >= 0; ) {
- addColumn();
- }
-}
-
-void
-BucketDistribution::setNumBucketBits(uint32_t numBucketBits)
-{
- uint32_t numColumns;
- {
- vespalib::LockGuard guard(_lock);
- if (numBucketBits == _numBucketBits) {
- return;
- }
- _numBucketBits = numBucketBits;
- _bucketToColumn.resize(getNumBuckets(numBucketBits));
- numColumns = _numColumns;
- reset();
- }
- setNumColumns(numColumns);
-}
-
-uint32_t
-BucketDistribution::getColumn(const document::BucketId &bucketId) const
-{
- uint32_t ret = (uint32_t)(bucketId.getId() & (getNumBuckets(_numBucketBits) - 1));
- if (ret >= _bucketToColumn.size()) {
- LOG(error,
- "The bucket distribution map is not in sync with the number of bucket bits. "
- "This should never happen! Distribution is broken!!");
- return 0;
- }
- return _bucketToColumn[ret];
-}
-
-}
diff --git a/document/src/vespa/document/bucket/bucketdistribution.h b/document/src/vespa/document/bucket/bucketdistribution.h
deleted file mode 100644
index c451ed9b9a7..00000000000
--- a/document/src/vespa/document/bucket/bucketdistribution.h
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-/**
- * \class document::BucketDistribution
- * \ingroup bucket
- *
- * Stable algorithmic hash distribution; this class assigns hash buckets to
- * targets. The number of hash buckets should be large compared to the number
- * of targets. The mapping from hash value to hash bucket is performed outside
- * this class.
- *
- * This is used to determine which search column a bucket should go to.
- */
-#pragma once
-
-#include "bucketid.h"
-#include <vector>
-#include <vespa/vespalib/util/sync.h>
-
-namespace document {
-
-class BucketDistribution {
-public:
- /**
- * Constructs a new bucket distribution object with a given number of
- * columns and buckets.
- *
- * @param numColumns The number of columns to distribute to.
- * @param numBucketBits The number of bits to use for bucket id.
- */
- BucketDistribution(uint32_t numColumns, uint32_t numBucketBits);
-
- /**
- * Returns the number of buckets that the given number of bucket bits will
- * allow.
- *
- * @param numBucketBits The number of bits to use for bucket id.
- * @return The number of buckets allowed.
- */
- static uint32_t getNumBuckets(uint32_t numBucketBits) { return 1 << numBucketBits; }
-
- /**
- * This method returns a list that contains the distributions of the given
- * number of buckets over the given number of columns.
- *
- * @param numColumns The number of columns to distribute to.
- * @param numBucketBits The number of bits to use for bucket id.
- * @param ret List to fill with the bucket distribution.
- */
- static void getBucketCount(uint32_t numColumns, uint32_t numBucketBits,
- std::vector<uint32_t> &ret);
-
- /**
- * This method returns a list similar to getBucketCount(int,int), except
- * that the returned list contains the number of buckets that will have to
- * be migrated from each column if an additional column was added.
- *
- * @param numColumns The original number of columns.
- * @param numBucketBits The number of bits to use for bucket id.
- * @param ret List to fill with the number of buckets to migrate,
- * one value per column.
- */
- static void getBucketMigrateCount(uint32_t numColumns,
- uint32_t numBucketBits, std::vector<uint32_t> &ret);
-
- /**
- * Sets the number of columns to distribute to to 1, and resets the content
- * of the internal bucket-to-column map so that it all buckets point to
- * that single column.
- */
- void reset();
-
- /**
- * Sets the number of columns to use for this document distribution object.
- * This will reset and setup this object from scratch. The original number
- * of buckets is maintained.
- *
- * @param numColumns The new number of columns to distribute to.
- */
- void setNumColumns(uint32_t numColumns);
-
- /**
- * Returns the number of columns to distribute to.
- *
- * @return The number of columns.
- */
- uint32_t getNumColumns() const { return _numColumns; }
-
- /**
- * Sets the number of buckets to use for this document distribution object.
- * This will reset and setup this object from scratch. The original number
- * of columns is maintained.
- *
- * @param numBucketBits The new number of bits to use for bucket id.
- */
- void setNumBucketBits(uint32_t numBucketBits);
-
- /**
- * Returns the number of bits used for bucket identifiers.
- *
- * @return The number of bits.
- */
- uint32_t getNumBucketBits() const { return _numBucketBits; }
-
- /**
- * Returns the number of buckets available using the configured number of
- * bucket bits.
- *
- * @return The number of buckets.
- */
- uint32_t getNumBuckets() const { return getNumBuckets(_numBucketBits); }
-
- /**
- * This method maps the given bucket id to its corresponding column.
- *
- * @param bucketId The bucket whose column to lookup.
- * @return The column to distribute the bucket to.
- */
- uint32_t getColumn(const document::BucketId &bucketId) const;
-
-private:
- /**
- * Adds a single column to this bucket distribution object. This will
- * modify the internal bucket-to-column map so that it takes into account
- * the new column.
- */
- void addColumn();
-
-private:
- uint32_t _numColumns; // The number of columns to distribute to.
- uint32_t _numBucketBits; // The number of bits to use for bucket identification.
- std::vector<uint32_t> _bucketToColumn; // A map from bucket id to column index.
- vespalib::Lock _lock;
-};
-
-} // document
-
diff --git a/document/src/vespa/document/datatype/positiondatatype.cpp b/document/src/vespa/document/datatype/positiondatatype.cpp
index a8e9c81c895..69e63d2ff72 100644
--- a/document/src/vespa/document/datatype/positiondatatype.cpp
+++ b/document/src/vespa/document/datatype/positiondatatype.cpp
@@ -10,9 +10,6 @@ const vespalib::string ZCURVE("_zcurve");
}
-StructDataType::UP PositionDataType::_instance;
-vespalib::Lock PositionDataType::_lock;
-
const vespalib::string PositionDataType::STRUCT_NAME("position");
const vespalib::string PositionDataType::FIELD_X("x");
const vespalib::string PositionDataType::FIELD_Y("y");
@@ -20,7 +17,7 @@ const vespalib::string PositionDataType::FIELD_Y("y");
StructDataType::UP
PositionDataType::createInstance()
{
- StructDataType::UP type(new StructDataType(PositionDataType::STRUCT_NAME));
+ auto type = std::make_unique<StructDataType>(PositionDataType::STRUCT_NAME);
type->addField(Field(PositionDataType::FIELD_X, *DataType::INT));
type->addField(Field(PositionDataType::FIELD_Y, *DataType::INT));
return type;
@@ -29,13 +26,8 @@ PositionDataType::createInstance()
const StructDataType &
PositionDataType::getInstance()
{
- if ( ! _instance) {
- vespalib::LockGuard guard(_lock);
- if ( ! _instance) {
- _instance = createInstance();
- }
- }
- return *_instance;
+ static StructDataType::UP instance = createInstance();
+ return *instance;
}
vespalib::string
diff --git a/document/src/vespa/document/datatype/positiondatatype.h b/document/src/vespa/document/datatype/positiondatatype.h
index fa8e44ad847..45ac35b1388 100644
--- a/document/src/vespa/document/datatype/positiondatatype.h
+++ b/document/src/vespa/document/datatype/positiondatatype.h
@@ -2,15 +2,11 @@
#pragma once
#include <vespa/document/datatype/structdatatype.h>
-#include <vespa/vespalib/util/sync.h>
namespace document {
class PositionDataType {
private:
- static StructDataType::UP _instance;
- static vespalib::Lock _lock;
-
PositionDataType();
static StructDataType::UP createInstance();
diff --git a/document/src/vespa/document/datatype/urldatatype.cpp b/document/src/vespa/document/datatype/urldatatype.cpp
index 00ea31408af..4db16f4705d 100644
--- a/document/src/vespa/document/datatype/urldatatype.cpp
+++ b/document/src/vespa/document/datatype/urldatatype.cpp
@@ -4,9 +4,6 @@
namespace document {
-StructDataType::UP UrlDataType::_instance;
-vespalib::Lock UrlDataType::_lock;
-
const vespalib::string UrlDataType::STRUCT_NAME("url");
const vespalib::string UrlDataType::FIELD_ALL("all");
const vespalib::string UrlDataType::FIELD_SCHEME("scheme");
@@ -19,7 +16,7 @@ const vespalib::string UrlDataType::FIELD_FRAGMENT("fragment");
StructDataType::UP
UrlDataType::createInstance()
{
- StructDataType::UP type(new StructDataType(UrlDataType::STRUCT_NAME));
+ auto type = std::make_unique<StructDataType>(UrlDataType::STRUCT_NAME);
type->addField(Field(UrlDataType::FIELD_ALL, *DataType::STRING));
type->addField(Field(UrlDataType::FIELD_SCHEME, *DataType::STRING));
type->addField(Field(UrlDataType::FIELD_HOST, *DataType::STRING));
@@ -33,13 +30,8 @@ UrlDataType::createInstance()
const StructDataType &
UrlDataType::getInstance()
{
- if ( ! _instance ) {
- vespalib::LockGuard guard(_lock);
- if ( ! _instance ) {
- _instance = createInstance();
- }
- }
- return *_instance;
+ static StructDataType::UP instance = createInstance();
+ return *instance;
}
} // document
diff --git a/document/src/vespa/document/datatype/urldatatype.h b/document/src/vespa/document/datatype/urldatatype.h
index 902abd940e3..19ae6dde2e1 100644
--- a/document/src/vespa/document/datatype/urldatatype.h
+++ b/document/src/vespa/document/datatype/urldatatype.h
@@ -2,15 +2,11 @@
#pragma once
#include <vespa/document/datatype/structdatatype.h>
-#include <vespa/vespalib/util/sync.h>
namespace document {
class UrlDataType {
private:
- static StructDataType::UP _instance;
- static vespalib::Lock _lock;
-
UrlDataType() { /* hide */ }
static StructDataType::UP createInstance();
diff --git a/document/src/vespa/document/repo/documenttyperepo.cpp b/document/src/vespa/document/repo/documenttyperepo.cpp
index bcd4edb3ab8..578d2999038 100644
--- a/document/src/vespa/document/repo/documenttyperepo.cpp
+++ b/document/src/vespa/document/repo/documenttyperepo.cpp
@@ -15,6 +15,7 @@
#include <vespa/vespalib/util/exceptions.h>
#include <vespa/document/config/config-documenttypes.h>
#include <fstream>
+#include <cassert>
#include <vespa/log/log.h>
LOG_SETUP(".documenttyperepo");
@@ -547,13 +548,13 @@ DocumentTypeRepo::~DocumentTypeRepo() {
}
const DocumentType *
-DocumentTypeRepo::getDocumentType(int32_t type_id) const {
+DocumentTypeRepo::getDocumentType(int32_t type_id) const noexcept {
const DataTypeRepo *repo = FindPtr(*_doc_types, type_id);
return repo ? repo->doc_type : nullptr;
}
const DocumentType *
-DocumentTypeRepo::getDocumentType(stringref name) const {
+DocumentTypeRepo::getDocumentType(stringref name) const noexcept {
DocumentTypeMap::const_iterator it = _doc_types->find(DocumentType::createId(name));
if (it != _doc_types->end() && it->second->doc_type->getName() == name) {
diff --git a/document/src/vespa/document/repo/documenttyperepo.h b/document/src/vespa/document/repo/documenttyperepo.h
index f0c59918a74..fd17bd5640a 100644
--- a/document/src/vespa/document/repo/documenttyperepo.h
+++ b/document/src/vespa/document/repo/documenttyperepo.h
@@ -34,8 +34,8 @@ public:
explicit DocumentTypeRepo(const DocumenttypesConfig & config);
~DocumentTypeRepo();
- const DocumentType *getDocumentType(int32_t doc_type_id) const;
- const DocumentType *getDocumentType(vespalib::stringref name) const;
+ const DocumentType *getDocumentType(int32_t doc_type_id) const noexcept;
+ const DocumentType *getDocumentType(vespalib::stringref name) const noexcept;
const DataType *getDataType(const DocumentType &doc_type, int32_t id) const;
const DataType *getDataType(const DocumentType &doc_type, vespalib::stringref name) const;
const AnnotationType *getAnnotationType(const DocumentType &doc_type, int32_t id) const;
diff --git a/document/src/vespa/document/repo/fixedtyperepo.cpp b/document/src/vespa/document/repo/fixedtyperepo.cpp
index 81a26265830..20865a8a6ca 100644
--- a/document/src/vespa/document/repo/fixedtyperepo.cpp
+++ b/document/src/vespa/document/repo/fixedtyperepo.cpp
@@ -5,7 +5,7 @@
namespace document {
-FixedTypeRepo::FixedTypeRepo(const DocumentTypeRepo &repo, const vespalib::string &type)
+FixedTypeRepo::FixedTypeRepo(const DocumentTypeRepo &repo, const vespalib::string &type) noexcept
: _repo(&repo), _doc_type(repo.getDocumentType(type))
{
assert(_doc_type);
diff --git a/document/src/vespa/document/repo/fixedtyperepo.h b/document/src/vespa/document/repo/fixedtyperepo.h
index 67e7571e31d..29bef846e36 100644
--- a/document/src/vespa/document/repo/fixedtyperepo.h
+++ b/document/src/vespa/document/repo/fixedtyperepo.h
@@ -13,17 +13,17 @@ class FixedTypeRepo {
const DocumentType *_doc_type;
public:
- explicit FixedTypeRepo(const DocumentTypeRepo &repo)
+ explicit FixedTypeRepo(const DocumentTypeRepo &repo) noexcept
: _repo(&repo), _doc_type(repo.getDefaultDocType()) {}
- FixedTypeRepo(const DocumentTypeRepo &repo, const DocumentType &doc_type)
+ FixedTypeRepo(const DocumentTypeRepo &repo, const DocumentType &doc_type) noexcept
: _repo(&repo), _doc_type(&doc_type) {}
- FixedTypeRepo(const DocumentTypeRepo &repo, const vespalib::string &type);
+ FixedTypeRepo(const DocumentTypeRepo &repo, const vespalib::string &type) noexcept;
const DataType *getDataType(int32_t id) const { return _repo->getDataType(*_doc_type, id); }
const DataType *getDataType(const vespalib::string &name) const { return _repo->getDataType(*_doc_type, name); }
const AnnotationType *getAnnotationType(int32_t id) const { return _repo->getAnnotationType(*_doc_type, id); }
const DocumentTypeRepo &getDocumentTypeRepo() const { return *_repo; }
- const DocumentType &getDocumentType() const { return *_doc_type; }
+ const DocumentType &getDocumentType() const noexcept { return *_doc_type; }
};
} // namespace document
diff --git a/document/src/vespa/document/select/valuenodes.cpp b/document/src/vespa/document/select/valuenodes.cpp
index 73fc1c6486b..36cb92dfe33 100644
--- a/document/src/vespa/document/select/valuenodes.cpp
+++ b/document/src/vespa/document/select/valuenodes.cpp
@@ -2,7 +2,6 @@
#include "valuenodes.h"
#include "visitor.h"
#include "parser.h"
-#include <vespa/document/bucket/bucketdistribution.h>
#include <vespa/document/base/exceptions.h>
#include <vespa/document/update/documentupdate.h>
#include <vespa/document/fieldvalue/fieldvalues.h>
diff --git a/document/src/vespa/document/util/queue.h b/document/src/vespa/document/util/queue.h
index af0ce85fad1..7e3c98333c8 100644
--- a/document/src/vespa/document/util/queue.h
+++ b/document/src/vespa/document/util/queue.h
@@ -5,8 +5,7 @@
#include <vespa/vespalib/util/sync.h>
#define UNUSED_PARAM(p)
-namespace document
-{
+namespace document {
// XXX move to vespalib (or remove)
/**
@@ -202,79 +201,7 @@ public:
}
return retval;
}
-#if 0
-// XXX unused?
- size_t max() const { return _max; }
- size_t lowWaterMark() const { return _lowWaterMark; }
- void max(size_t v)
- {
- vespalib::MonitorGuard guard(this->_cond);
- _max = v; _lowWaterMark = _max/2;
- }
- void lowWaterMark(size_t v)
- {
- vespalib::MonitorGuard guard(this->_cond);
- _lowWaterMark = v;
- }
-#endif
-};
-
-template <typename T, typename Q=std::queue<T> >
-class QueueWithMaxSerialized : public QueueWithMax<T, Q>
-{
-public:
- QueueWithMaxSerialized(size_t max_=1000000, size_t lowWaterMark_=500000) : QueueWithMax<T, Q>(max_, lowWaterMark_) { }
- virtual void add(const T& msg)
- {
- if (msg != NULL) {
- this->_size += msg->getSerializedSize();
- }
- }
- virtual void sub(const T& msg)
- {
- if (msg != NULL) {
- this->_size -= msg->getSerializedSize();
- }
- }
-};
-
-#if 0
-
-/**
- This is an fast Q that reduces lock/unlock to a minimum and ditto with
- context swithes on notify/wait. enque/deque have no atomic operations
- unless it is empty/full. This limits the use to situations where there are
- both single consumers and single producers.
-*/
-template <typename T>
-class QueueSingleProducerConsumer {
-private:
- typedef std::vector<T> Q;
-public:
- typedef typename Q::iterator iterator;
- enum { end=-1 };
- QueueSingleProducerConsumer(size_t max=1000,
- size_t highWaterMark=999,
- size_t lowWaterMark=1);
- T * wait(int timeOut=-1)
- {
- T * retval(NULL);
- if (empty()) {
- _cond.Wait(timeOut);
- }
- return retval;
- }
- const T & head() const { return _q[_readPos]; }
- void removeHead() { ~_q[_readPos](); _readPos++; }
- bool deque();
-private:
- std::vector<T> _q;
- size_t _readPos;
- size_t _writePos;
- FastOS_Condition _cond;
};
-#endif
-
} // namespace document
diff --git a/documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/DocumentProtocol.java b/documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/DocumentProtocol.java
index e49cf021fe3..29db9e318d8 100755
--- a/documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/DocumentProtocol.java
+++ b/documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/DocumentProtocol.java
@@ -21,6 +21,7 @@ import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
+import java.util.logging.Level;
import java.util.logging.Logger;
/**
@@ -35,14 +36,10 @@ public class DocumentProtocol implements Protocol {
private final RoutableRepository routableRepository;
private final DocumentTypeManager docMan;
- /**
- * The name of this protocol.
- */
+ /** The name of this protocol. */
public static final Utf8String NAME = new Utf8String("document");
- /**
- * All message types that are implemented by this protocol.
- */
+ // All message types that are implemented by this protocol.
public static final int DOCUMENT_MESSAGE = 100000;
public static final int MESSAGE_GETDOCUMENT = DOCUMENT_MESSAGE + 3;
public static final int MESSAGE_PUTDOCUMENT = DOCUMENT_MESSAGE + 4;
@@ -62,9 +59,7 @@ public class DocumentProtocol implements Protocol {
public static final int MESSAGE_REMOVELOCATION = DOCUMENT_MESSAGE + 24;
public static final int MESSAGE_QUERYRESULT = DOCUMENT_MESSAGE + 25;
- /**
- * All reply types that are implemented by this protocol.
- */
+ // All reply types that are implemented by this protocol.
public static final int DOCUMENT_REPLY = 200000;
public static final int REPLY_GETDOCUMENT = DOCUMENT_REPLY + 3;
public static final int REPLY_PUTDOCUMENT = DOCUMENT_REPLY + 4;
@@ -86,7 +81,7 @@ public class DocumentProtocol implements Protocol {
public static final int REPLY_WRONGDISTRIBUTION = DOCUMENT_REPLY + 1000;
public static final int REPLY_DOCUMENTIGNORED = DOCUMENT_REPLY + 1001;
- /**
+ /*
* Important note on adding new error codes to the Document protocol:
*
* Changes to this protocol must be reflected in both the Java and C++ versions
@@ -95,117 +90,94 @@ public class DocumentProtocol implements Protocol {
* longer be guaranteed.
*/
- /**
- * Used by policies to indicate an inappropriate message.
- */
+ /** Used by policies to indicate an inappropriate message. */
public static final int ERROR_MESSAGE_IGNORED = ErrorCode.APP_FATAL_ERROR + 1;
- /**
- * Used for error policy when policy creation failed.
- */
+
+ /** Used for error policy when policy creation failed. */
public static final int ERROR_POLICY_FAILURE = ErrorCode.APP_FATAL_ERROR + 2;
- /**
- * Document in operation cannot be found. (VDS Get and Remove)
- */
+
+ /** Document in operation cannot be found. (VDS Get and Remove) */
public static final int ERROR_DOCUMENT_NOT_FOUND = ErrorCode.APP_FATAL_ERROR + 1001;
- /**
- * Operation cannot be performed because token already exist. (Create bucket, create visitor)
- */
+
+ /** Operation cannot be performed because token already exist. (Create bucket, create visitor) */
public static final int ERROR_DOCUMENT_EXISTS = ErrorCode.APP_FATAL_ERROR + 1002;
- /**
- * Node have not implemented support for the given operation.
- */
+
+ /** Node have not implemented support for the given operation. */
public static final int ERROR_NOT_IMPLEMENTED = ErrorCode.APP_FATAL_ERROR + 1004;
- /**
- * Parameters given in request is illegal.
- */
+
+ /** Parameters given in request is illegal. */
public static final int ERROR_ILLEGAL_PARAMETERS = ErrorCode.APP_FATAL_ERROR + 1005;
- /**
- * Unknown request received. (New client requesting from old server)
- */
+
+ /** Unknown request received. (New client requesting from old server) */
public static final int ERROR_UNKNOWN_COMMAND = ErrorCode.APP_FATAL_ERROR + 1007;
- /**
- * Request cannot be decoded.
- */
+
+ /** Request cannot be decoded. */
public static final int ERROR_UNPARSEABLE = ErrorCode.APP_FATAL_ERROR + 1008;
- /**
- * Not enough free space on disk to perform operation.
- */
+
+ /** Not enough free space on disk to perform operation. */
public static final int ERROR_NO_SPACE = ErrorCode.APP_FATAL_ERROR + 1009;
- /**
- * Request was not handled correctly.
- */
+
+ /** Request was not handled correctly. */
public static final int ERROR_IGNORED = ErrorCode.APP_FATAL_ERROR + 1010;
- /**
- * We failed in some way we didn't expect to fail.
- */
+
+ /** We failed in some way we didn't expect to fail. */
public static final int ERROR_INTERNAL_FAILURE = ErrorCode.APP_FATAL_ERROR + 1011;
- /**
- * Node refuse to perform operation. (Illegally formed message?)
- */
+
+ /** Node refuse to perform operation. (Illegally formed message?) */
public static final int ERROR_REJECTED = ErrorCode.APP_FATAL_ERROR + 1012;
- /**
- * Test and set condition (selection) failed.
- */
+
+ /** Test and set condition (selection) failed. */
public static final int ERROR_TEST_AND_SET_CONDITION_FAILED = ErrorCode.APP_FATAL_ERROR + 1013;
- /**
- * Failed to process the given request. (Used by docproc)
- */
+ /** Failed to process the given request. (Used by docproc) */
public static final int ERROR_PROCESSING_FAILURE = ErrorCode.APP_FATAL_ERROR + 2001;
+
/** Unique timestamp specified for new operation is already in use. */
public static final int ERROR_TIMESTAMP_EXIST = ErrorCode.APP_FATAL_ERROR + 2002;
- /**
- * Node not ready to perform operation. (Initializing VDS nodes)
- */
+
+ /** Node not ready to perform operation. (Initializing VDS nodes) */
public static final int ERROR_NODE_NOT_READY = ErrorCode.APP_TRANSIENT_ERROR + 1001;
- /**
- * Wrong node to talk to in current state. (VDS system state disagreement)
- */
+
+ /** Wrong node to talk to in current state. (VDS system state disagreement) */
public static final int ERROR_WRONG_DISTRIBUTION = ErrorCode.APP_TRANSIENT_ERROR + 1002;
- /**
- * Operation cut short and aborted. (Destroy visitor, node stopping)
- */
+
+ /** Operation cut short and aborted. (Destroy visitor, node stopping) */
public static final int ERROR_ABORTED = ErrorCode.APP_TRANSIENT_ERROR + 1004;
- /**
- * Node too busy to process request (Typically full queues)
- */
+
+ /** Node too busy to process request (Typically full queues) */
public static final int ERROR_BUSY = ErrorCode.APP_TRANSIENT_ERROR + 1005;
- /**
- * Lost connection with the node we requested something from.
- */
+
+ /** Lost connection with the node we requested something from. */
public static final int ERROR_NOT_CONNECTED = ErrorCode.APP_TRANSIENT_ERROR + 1006;
- /**
- * We failed accessing the disk, which we think is a disk hardware problem.
- */
+
+ /** We failed accessing the disk, which we think is a disk hardware problem. */
public static final int ERROR_DISK_FAILURE = ErrorCode.APP_TRANSIENT_ERROR + 1007;
- /**
- * We failed during an IO operation, we dont think is a specific disk hardware problem.
- */
+
+ /** We failed during an IO operation, we dont think is a specific disk hardware problem. */
public static final int ERROR_IO_FAILURE = ErrorCode.APP_TRANSIENT_ERROR + 1008;
+
/**
* Bucket given in operation not found due to bucket database
* inconsistencies between storage and distributor nodes.
*/
public static final int ERROR_BUCKET_NOT_FOUND = ErrorCode.APP_TRANSIENT_ERROR + 1009;
+
/**
* Bucket recently removed, such that operation cannot be performed.
* Differs from BUCKET_NOT_FOUND in that there is no db inconsistency.
*/
public static final int ERROR_BUCKET_DELETED = ErrorCode.APP_TRANSIENT_ERROR + 1012;
- /**
- * Storage node received a timestamp that is stale. Likely clock skew.
- */
+
+ /** Storage node received a timestamp that is stale. Likely clock skew. */
public static final int ERROR_STALE_TIMESTAMP = ErrorCode.APP_TRANSIENT_ERROR + 1013;
- /**
- * The given node have gotten a critical error and have suspended itself.
- */
+ /** The given node have gotten a critical error and have suspended itself. */
public static final int ERROR_SUSPENDED = ErrorCode.APP_TRANSIENT_ERROR + 2001;
/**
- * <p>Define the different priorities allowed for document api messages. Most user traffic should be fit into the
+ * Defines the different priorities allowed for document api messages. Most user traffic should be fit into the
* NORMAL categories. Traffic in the HIGH end will be usually be prioritized over important maintenance operations.
- * Traffic in the LOW end will be prioritized after these operations.</p>
+ * Traffic in the LOW end will be prioritized after these operations.
*/
public enum Priority {
HIGHEST(0),
@@ -239,9 +211,9 @@ public class DocumentProtocol implements Protocol {
/**
* Get a priority enum instance by its value.
*
- * @param val The value of the priority to return.
- * @return The priority enum instance.
- * @throws IllegalArgumentException If priority value is unknown.
+ * @param val the value of the priority to return
+ * @return the priority enum instance
+ * @throws IllegalArgumentException if the priority value is unknown
*/
public static Priority getPriority(int val) {
for (Priority pri : Priority.values()) {
@@ -255,9 +227,9 @@ public class DocumentProtocol implements Protocol {
/**
* Get priority enum instance by its name.
*
- * @param name Name of priority.
- * @return Priority enum instance, given that <code>name</code> is valid.
- * @throws IllegalArgumentException If priority name is unknown.
+ * @param name name of priority.
+ * @return priority enum instance, given that <code>name</code> is valid
+ * @throws IllegalArgumentException if priority name is unknown
*/
public static Priority getPriorityByName(String name) {
return Priority.valueOf(name);
@@ -344,9 +316,9 @@ public class DocumentProtocol implements Protocol {
* that is already in use by a message bus instance. Notice that the name you supply for a factory is the
* case-sensitive name that will be referenced by routes.
*
- * @param name The name of the factory to add.
- * @param factory The factory to add.
- * @return This, to allow chaining.
+ * @param name the name of the factory to add
+ * @param factory the factory to add
+ * @return this, to allow chaining
*/
public DocumentProtocol putRoutingPolicyFactory(String name, RoutingPolicyFactory factory) {
routingPolicyRepository.putFactory(name, factory);
@@ -359,10 +331,10 @@ public class DocumentProtocol implements Protocol {
* supported version. You can always bypass this by passing a default version specification object to this function,
* because that object will match any version.
*
- * @param type The routable type to assign a factory to.
- * @param factory The factory to add.
- * @param version The version for which this factory can be used.
- * @return This, to allow chaining.
+ * @param type the routable type to assign a factory to
+ * @param factory the factory to add
+ * @param version the version for which this factory can be used
+ * @return this, to allow chaining
*/
public DocumentProtocol putRoutableFactory(int type, RoutableFactory factory, VersionSpecification version) {
routableRepository.putFactory(version, type, factory);
@@ -373,10 +345,10 @@ public class DocumentProtocol implements Protocol {
* Convenience method to call {@link #putRoutableFactory(int, RoutableFactory, com.yahoo.component.VersionSpecification)}
* for multiple version specifications.
*
- * @param type The routable type to assign a factory to.
- * @param factory The factory to add.
- * @param versions The versions for which this factory can be used.
- * @return This, to allow chaining.
+ * @param type the routable type to assign a factory to
+ * @param factory the factory to add
+ * @param versions the versions for which this factory can be used
+ * @return this, to allow chaining
*/
public DocumentProtocol putRoutableFactory(int type, RoutableFactory factory, List<VersionSpecification> versions) {
for (VersionSpecification version : versions) {
@@ -454,7 +426,7 @@ public class DocumentProtocol implements Protocol {
* This is a convenient entry to the {@link #merge(RoutingContext,Set)} method by way of a routing context object.
* The replies of all child contexts are merged and stored in the context.
*
- * @param ctx The context whose children to merge.
+ * @param ctx the context whose children to merge
*/
public static void merge(RoutingContext ctx) {
merge(ctx, new HashSet<Integer>(0));
@@ -465,8 +437,8 @@ public class DocumentProtocol implements Protocol {
* in any of the replies, it will prepare an EmptyReply() and add all errors to it. If there are no errors, this
* method will use the first reply in the list and transfer whatever feed answers might exist in the replies to it.
*
- * @param ctx The context whose children to merge.
- * @param mask The indexes of the children to skip.
+ * @param ctx the context whose children to merge
+ * @param mask the indexes of the children to skip
*/
public static void merge(RoutingContext ctx, Set<Integer> mask) {
List<Reply> replies = new LinkedList<>();
@@ -499,8 +471,8 @@ public class DocumentProtocol implements Protocol {
* method will use the first reply in the list and transfer whatever feed answers might exist in the replies to it.
*
*
- * @param replies The replies to merge.
- * @return The merged Reply.
+ * @param replies the replies to merge
+ * @return the merged Reply
*/
public static Reply merge(List<Reply> replies) {
return merge(replies, new HashSet<Integer>(0)).second;
@@ -509,9 +481,9 @@ public class DocumentProtocol implements Protocol {
/**
* Returns true if the given reply has at least one error, and all errors are of the given type.
*
- * @param reply The reply to check for error.
- * @param errCode The error code to check for.
- * @return Whether or not the reply has only the given error code.
+ * @param reply the reply to check for error
+ * @param errCode the error code to check for
+ * @return whether or not the reply has only the given error code
*/
public static boolean hasOnlyErrorsOfType(Reply reply, int errCode) {
if (!reply.hasErrors()) {
@@ -541,8 +513,7 @@ public class DocumentProtocol implements Protocol {
try {
return routableRepository.decode(docMan, version, data);
} catch (RuntimeException e) {
- e.printStackTrace();
- log.warning(e.getMessage());
+ log.log(Level.WARNING, "Failed to decode document data", e);
return null;
}
}
@@ -550,12 +521,13 @@ public class DocumentProtocol implements Protocol {
/**
* Returns a list of routable types that support the given version.
*
- * @param version The version to return types for.
- * @return The list of supported types.
+ * @param version the version to return types for
+ * @return the list of supported types
*/
public List<Integer> getRoutableTypes(Version version) {
return routableRepository.getRoutableTypes(version);
}
final public DocumentTypeManager getDocumentTypeManager() { return docMan; }
+
}
diff --git a/documentapi/src/vespa/documentapi/messagebus/documentprotocol.cpp b/documentapi/src/vespa/documentapi/messagebus/documentprotocol.cpp
index 7d7153e8461..dcfc0fa5f6e 100644
--- a/documentapi/src/vespa/documentapi/messagebus/documentprotocol.cpp
+++ b/documentapi/src/vespa/documentapi/messagebus/documentprotocol.cpp
@@ -9,6 +9,7 @@
#include <vespa/documentapi/documentapi.h>
#include <vespa/vespalib/util/exceptions.h>
#include <sstream>
+#include <cassert>
#include <vespa/log/log.h>
LOG_SETUP(".documentprotocol");
diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/asyncinitializationpolicy.cpp b/documentapi/src/vespa/documentapi/messagebus/policies/asyncinitializationpolicy.cpp
index 8b303d10e0a..82cda6c773f 100644
--- a/documentapi/src/vespa/documentapi/messagebus/policies/asyncinitializationpolicy.cpp
+++ b/documentapi/src/vespa/documentapi/messagebus/policies/asyncinitializationpolicy.cpp
@@ -41,9 +41,7 @@ AsyncInitializationPolicy::AsyncInitializationPolicy(
{
}
-AsyncInitializationPolicy::~AsyncInitializationPolicy()
-{
-}
+AsyncInitializationPolicy::~AsyncInitializationPolicy() = default;
void
AsyncInitializationPolicy::initSynchronous()
@@ -74,7 +72,7 @@ AsyncInitializationPolicy::select(mbus::RoutingContext& context)
}
{
- vespalib::MonitorGuard lock(_lock);
+ std::lock_guard lock(_lock);
if (_state == State::NOT_STARTED || _state == State::FAILED) {
// Only 1 task may be queued to the executor at any point in time.
@@ -88,7 +86,7 @@ AsyncInitializationPolicy::select(mbus::RoutingContext& context)
}
if (_state != State::DONE) {
- mbus::Reply::UP reply(new mbus::EmptyReply());
+ auto reply = std::make_unique<mbus::EmptyReply>();
reply->addError(currentPolicyInitError());
context.setReply(std::move(reply));
return;
@@ -117,7 +115,7 @@ AsyncInitializationPolicy::Task::run()
using State = AsyncInitializationPolicy::State;
- vespalib::MonitorGuard lock(_owner._lock);
+ std::lock_guard lock(_owner._lock);
_owner._error = error;
_owner._state = error.empty() ? State::DONE : State::FAILED;
}
diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/asyncinitializationpolicy.h b/documentapi/src/vespa/documentapi/messagebus/policies/asyncinitializationpolicy.h
index f056bb3b329..0e30da8e7c8 100644
--- a/documentapi/src/vespa/documentapi/messagebus/policies/asyncinitializationpolicy.h
+++ b/documentapi/src/vespa/documentapi/messagebus/policies/asyncinitializationpolicy.h
@@ -5,15 +5,15 @@
#include <vespa/messagebus/error.h>
#include <vespa/vespalib/util/executor.h>
#include <vespa/documentapi/common.h>
-#include <vespa/vespalib/util/sync.h>
#include <map>
+#include <mutex>
namespace documentapi {
class AsyncInitializationPolicy : public mbus::IRoutingPolicy {
public:
AsyncInitializationPolicy(const std::map<string, string>& parameters);
- virtual ~AsyncInitializationPolicy();
+ ~AsyncInitializationPolicy() override;
static std::map<string, string> parse(string parameters);
@@ -64,7 +64,7 @@ private:
friend class Task;
std::unique_ptr<vespalib::Executor> _executor;
- vespalib::Monitor _lock;
+ std::mutex _lock;
enum class State {
NOT_STARTED,
diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/documentrouteselectorpolicy.cpp b/documentapi/src/vespa/documentapi/messagebus/policies/documentrouteselectorpolicy.cpp
index 378f12b5138..01245843e3b 100644
--- a/documentapi/src/vespa/documentapi/messagebus/policies/documentrouteselectorpolicy.cpp
+++ b/documentapi/src/vespa/documentapi/messagebus/policies/documentrouteselectorpolicy.cpp
@@ -60,7 +60,7 @@ DocumentRouteSelectorPolicy::configure(std::unique_ptr<messagebus::protocol::Doc
}
config[string(route.name)] = selector;
}
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_config.swap(config);
_error.swap(error);
}
@@ -68,7 +68,7 @@ DocumentRouteSelectorPolicy::configure(std::unique_ptr<messagebus::protocol::Doc
const string &
DocumentRouteSelectorPolicy::getError() const
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
return _error;
}
@@ -84,7 +84,7 @@ DocumentRouteSelectorPolicy::select(mbus::RoutingContext &context)
// Invoke private select method for each candidate recipient.
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
if (!_error.empty()) {
context.setError(DocumentProtocol::ERROR_POLICY_FAILURE, _error);
return;
diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/documentrouteselectorpolicy.h b/documentapi/src/vespa/documentapi/messagebus/policies/documentrouteselectorpolicy.h
index 6e13f615a35..02e8e4ff282 100644
--- a/documentapi/src/vespa/documentapi/messagebus/policies/documentrouteselectorpolicy.h
+++ b/documentapi/src/vespa/documentapi/messagebus/policies/documentrouteselectorpolicy.h
@@ -5,7 +5,6 @@
#include <vespa/document/select/node.h>
#include <map>
#include <vespa/messagebus/routing/iroutingpolicy.h>
-#include <vespa/vespalib/util/sync.h>
#include <vespa/documentapi/common.h>
#include <vespa/config/config.h>
#include <vespa/config/helper/configfetcher.h>
@@ -33,7 +32,7 @@ private:
typedef std::map<string, SelectorPtr> ConfigMap;
const document::DocumentTypeRepo &_repo;
- vespalib::Lock _lock;
+ mutable std::mutex _lock;
ConfigMap _config;
string _error;
config::ConfigFetcher _fetcher;
diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/externpolicy.cpp b/documentapi/src/vespa/documentapi/messagebus/policies/externpolicy.cpp
index 6c4523fa34f..25112a00b99 100644
--- a/documentapi/src/vespa/documentapi/messagebus/policies/externpolicy.cpp
+++ b/documentapi/src/vespa/documentapi/messagebus/policies/externpolicy.cpp
@@ -118,7 +118,7 @@ ExternPolicy::merge(mbus::RoutingContext &ctx)
mbus::Hop
ExternPolicy::getRecipient()
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
update();
if (_recipients.empty()) {
return mbus::Hop();
diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/externpolicy.h b/documentapi/src/vespa/documentapi/messagebus/policies/externpolicy.h
index c56f8f214ec..cb0c4428e60 100644
--- a/documentapi/src/vespa/documentapi/messagebus/policies/externpolicy.h
+++ b/documentapi/src/vespa/documentapi/messagebus/policies/externpolicy.h
@@ -4,9 +4,8 @@
#include <vespa/messagebus/routing/hop.h>
#include <vespa/messagebus/routing/iroutingpolicy.h>
#include <vespa/slobrok/imirrorapi.h>
-#include <vector>
-#include <vespa/vespalib/util/sync.h>
#include <vespa/documentapi/common.h>
+#include <mutex>
class FRT_Supervisor;
class FNET_Transport;
@@ -21,7 +20,7 @@ namespace documentapi {
class ExternPolicy : public mbus::IRoutingPolicy {
private:
using IMirrorAPI = slobrok::api::IMirrorAPI;
- vespalib::Lock _lock;
+ std::mutex _lock;
std::unique_ptr<FastOS_ThreadPool> _threadPool;
std::unique_ptr<FNET_Transport> _transport;
std::unique_ptr<FRT_Supervisor> _orb;
diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/externslobrokpolicy.cpp b/documentapi/src/vespa/documentapi/messagebus/policies/externslobrokpolicy.cpp
index e82a184d8b2..800aa8c4520 100644
--- a/documentapi/src/vespa/documentapi/messagebus/policies/externslobrokpolicy.cpp
+++ b/documentapi/src/vespa/documentapi/messagebus/policies/externslobrokpolicy.cpp
@@ -2,6 +2,7 @@
#include "externslobrokpolicy.h"
#include <vespa/messagebus/routing/routingcontext.h>
+#include <vespa/config/common/configcontext.h>
#include <vespa/vespalib/text/stringtokenizer.h>
#include <vespa/vespalib/util/time.h>
#include <vespa/fnet/frt/frt.h>
@@ -61,8 +62,8 @@ string ExternSlobrokPolicy::init() {
} else if (_configSources.size() != 0) {
slobrok::ConfiguratorFactory config(
config::ConfigUri(_slobrokConfigId,
- std::make_unique<config::ConfigContext>(config::ServerSpec(_configSources))));
- _mirror.reset(new MirrorAPI(*_orb, config));
+ std::make_shared<config::ConfigContext>(config::ServerSpec(_configSources))));
+ _mirror = std::make_unique<MirrorAPI>(*_orb, config);
}
if (_mirror.get()) {
@@ -74,7 +75,7 @@ string ExternSlobrokPolicy::init() {
IMirrorAPI::SpecList
ExternSlobrokPolicy::lookup(mbus::RoutingContext& context, const string& pattern) {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
const IMirrorAPI& mirror(_mirror.get()? *_mirror : context.getMirror());
diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/externslobrokpolicy.h b/documentapi/src/vespa/documentapi/messagebus/policies/externslobrokpolicy.h
index d2966f852d5..865709daf7f 100644
--- a/documentapi/src/vespa/documentapi/messagebus/policies/externslobrokpolicy.h
+++ b/documentapi/src/vespa/documentapi/messagebus/policies/externslobrokpolicy.h
@@ -23,7 +23,7 @@ class ExternSlobrokPolicy : public AsyncInitializationPolicy
protected:
bool _firstTry;
config::ServerSpec::HostSpecList _configSources;
- vespalib::Lock _lock;
+ std::mutex _lock;
std::unique_ptr<FastOS_ThreadPool> _threadPool;
std::unique_ptr<FNET_Transport> _transport;
std::unique_ptr<FRT_Supervisor> _orb;
@@ -33,7 +33,7 @@ protected:
public:
ExternSlobrokPolicy(const std::map<string, string>& params);
- ~ExternSlobrokPolicy();
+ ~ExternSlobrokPolicy() override;
/**
* @return a pointer to the slobrok mirror owned by this policy, if any.
diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/localservicepolicy.cpp b/documentapi/src/vespa/documentapi/messagebus/policies/localservicepolicy.cpp
index 7db941a12f2..9b23d593e82 100644
--- a/documentapi/src/vespa/documentapi/messagebus/policies/localservicepolicy.cpp
+++ b/documentapi/src/vespa/documentapi/messagebus/policies/localservicepolicy.cpp
@@ -49,7 +49,7 @@ LocalServicePolicy::getCacheKey(const mbus::RoutingContext &ctx) const
mbus::Hop
LocalServicePolicy::getRecipient(mbus::RoutingContext &ctx)
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
CacheEntry &entry = update(ctx);
if (entry._recipients.empty()) {
mbus::Hop hop = ctx.getRoute().getHop(0);
diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/localservicepolicy.h b/documentapi/src/vespa/documentapi/messagebus/policies/localservicepolicy.h
index 4dd22a77069..c188c9f5c4b 100644
--- a/documentapi/src/vespa/documentapi/messagebus/policies/localservicepolicy.h
+++ b/documentapi/src/vespa/documentapi/messagebus/policies/localservicepolicy.h
@@ -4,9 +4,9 @@
#include <vespa/documentapi/common.h>
#include <vespa/messagebus/routing/hop.h>
#include <vespa/messagebus/routing/iroutingpolicy.h>
-#include <vespa/vespalib/util/sync.h>
#include <vector>
#include <map>
+#include <mutex>
namespace documentapi {
@@ -26,7 +26,7 @@ private:
CacheEntry();
};
- vespalib::Lock _lock;
+ std::mutex _lock;
string _address;
std::map<string, CacheEntry> _cache;
diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/roundrobinpolicy.cpp b/documentapi/src/vespa/documentapi/messagebus/policies/roundrobinpolicy.cpp
index 6f778a3e4d0..a58f3439df2 100644
--- a/documentapi/src/vespa/documentapi/messagebus/policies/roundrobinpolicy.cpp
+++ b/documentapi/src/vespa/documentapi/messagebus/policies/roundrobinpolicy.cpp
@@ -56,7 +56,7 @@ RoundRobinPolicy::getCacheKey(const mbus::RoutingContext &ctx) const
mbus::Hop
RoundRobinPolicy::getRecipient(mbus::RoutingContext &ctx)
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
CacheEntry &entry = update(ctx);
if (entry._recipients.empty()) {
return mbus::Hop();
diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/roundrobinpolicy.h b/documentapi/src/vespa/documentapi/messagebus/policies/roundrobinpolicy.h
index 0bfd2f04ea7..98e61fd1a1c 100644
--- a/documentapi/src/vespa/documentapi/messagebus/policies/roundrobinpolicy.h
+++ b/documentapi/src/vespa/documentapi/messagebus/policies/roundrobinpolicy.h
@@ -4,8 +4,8 @@
#include <vespa/documentapi/common.h>
#include <vespa/messagebus/routing/hop.h>
#include <vespa/messagebus/routing/iroutingpolicy.h>
-#include <vespa/vespalib/util/sync.h>
#include <map>
+#include <mutex>
namespace documentapi {
@@ -25,7 +25,7 @@ private:
CacheEntry();
};
- vespalib::Lock _lock;
+ std::mutex _lock;
std::map<string, CacheEntry> _cache;
/**
diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/storagepolicy.cpp b/documentapi/src/vespa/documentapi/messagebus/policies/storagepolicy.cpp
index 166c3be5e66..e49d412fee1 100644
--- a/documentapi/src/vespa/documentapi/messagebus/policies/storagepolicy.cpp
+++ b/documentapi/src/vespa/documentapi/messagebus/policies/storagepolicy.cpp
@@ -11,6 +11,7 @@
#include <vespa/vespalib/util/stringfmt.h>
#include <vespa/config-stor-distribution.h>
#include <vespa/config/subscription/configuri.h>
+#include <cassert>
#include <vespa/log/log.h>
LOG_SETUP(".storagepolicy");
diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/subsetservicepolicy.cpp b/documentapi/src/vespa/documentapi/messagebus/policies/subsetservicepolicy.cpp
index 7e324468ae5..375cdc23ba2 100644
--- a/documentapi/src/vespa/documentapi/messagebus/policies/subsetservicepolicy.cpp
+++ b/documentapi/src/vespa/documentapi/messagebus/policies/subsetservicepolicy.cpp
@@ -64,7 +64,7 @@ SubsetServicePolicy::getRecipient(mbus::RoutingContext &ctx)
{
mbus::Hop hop;
if (_subsetSize > 0) {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
CacheEntry &entry = update(ctx);
if (!entry._recipients.empty()) {
if (++entry._offset >= entry._recipients.size()) {
diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/subsetservicepolicy.h b/documentapi/src/vespa/documentapi/messagebus/policies/subsetservicepolicy.h
index bf44afa318f..a6c2e0d6cae 100644
--- a/documentapi/src/vespa/documentapi/messagebus/policies/subsetservicepolicy.h
+++ b/documentapi/src/vespa/documentapi/messagebus/policies/subsetservicepolicy.h
@@ -4,9 +4,8 @@
#include <vespa/documentapi/common.h>
#include <vespa/messagebus/routing/hop.h>
#include <vespa/messagebus/routing/iroutingpolicy.h>
-#include <vespa/vespalib/util/sync.h>
-#include <vector>
#include <map>
+#include <mutex>
namespace documentapi {
@@ -26,8 +25,8 @@ private:
CacheEntry();
};
- vespalib::Lock _lock;
- uint32_t _subsetSize;
+ std::mutex _lock;
+ uint32_t _subsetSize;
std::map<string, CacheEntry> _cache;
/**
diff --git a/documentapi/src/vespa/documentapi/messagebus/routablerepository.cpp b/documentapi/src/vespa/documentapi/messagebus/routablerepository.cpp
index c7f3401d3e1..6ed33cda060 100644
--- a/documentapi/src/vespa/documentapi/messagebus/routablerepository.cpp
+++ b/documentapi/src/vespa/documentapi/messagebus/routablerepository.cpp
@@ -109,7 +109,7 @@ void
RoutableRepository::putFactory(const vespalib::VersionSpecification &version,
uint32_t type, IRoutableFactory::SP factory)
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
if (_factoryTypes[type].putFactory(version, factory)) {
_cache.clear();
}
@@ -118,7 +118,7 @@ RoutableRepository::putFactory(const vespalib::VersionSpecification &version,
IRoutableFactory::SP
RoutableRepository::getFactory(const vespalib::Version &version, uint32_t type) const
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
CacheKey cacheKey(version, type);
FactoryCache::const_iterator cit = _cache.find(cacheKey);
if (cit != _cache.end()) {
@@ -139,7 +139,7 @@ RoutableRepository::getFactory(const vespalib::Version &version, uint32_t type)
uint32_t
RoutableRepository::getRoutableTypes(const vespalib::Version &version, std::vector<uint32_t> &out) const
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
for (const auto & type : _factoryTypes) {
if (type.second.getFactory(version)) {
out.push_back(type.first);
diff --git a/documentapi/src/vespa/documentapi/messagebus/routablerepository.h b/documentapi/src/vespa/documentapi/messagebus/routablerepository.h
index f4bddad45b4..7e73f3929b8 100644
--- a/documentapi/src/vespa/documentapi/messagebus/routablerepository.h
+++ b/documentapi/src/vespa/documentapi/messagebus/routablerepository.h
@@ -1,11 +1,11 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
-#include <map>
+#include "iroutablefactory.h"
#include <vespa/messagebus/blobref.h>
-#include <vespa/vespalib/util/sync.h>
#include <vespa/vespalib/component/versionspecification.h>
-#include "iroutablefactory.h"
+#include <mutex>
+#include <map>
namespace documentapi {
@@ -37,7 +37,7 @@ private:
typedef std::map<CacheKey, IRoutableFactory::SP> FactoryCache;
typedef std::map<uint32_t, VersionMap> TypeMap;
- vespalib::Lock _lock;
+ mutable std::mutex _lock;
TypeMap _factoryTypes;
mutable FactoryCache _cache;
const LoadTypeSet& _loadTypes;
@@ -48,7 +48,7 @@ public:
/**
* Constructs a new routable repository.
*/
- RoutableRepository(const LoadTypeSet& loadTypes);
+ explicit RoutableRepository(const LoadTypeSet& loadTypes);
/**
* Decodes a {@link Routable} from the given byte array. This uses the content of the byte array to
diff --git a/documentapi/src/vespa/documentapi/messagebus/routingpolicyrepository.cpp b/documentapi/src/vespa/documentapi/messagebus/routingpolicyrepository.cpp
index 3c73cda786d..c21d8e97880 100644
--- a/documentapi/src/vespa/documentapi/messagebus/routingpolicyrepository.cpp
+++ b/documentapi/src/vespa/documentapi/messagebus/routingpolicyrepository.cpp
@@ -17,14 +17,14 @@ RoutingPolicyRepository::RoutingPolicyRepository() :
void
RoutingPolicyRepository::putFactory(const string &name, IRoutingPolicyFactory::SP factory)
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_factories[name] = factory;
}
IRoutingPolicyFactory::SP
RoutingPolicyRepository::getFactory(const string &name) const
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
FactoryMap::const_iterator it = _factories.find(name);
if (it != _factories.end()) {
return it->second;
diff --git a/documentapi/src/vespa/documentapi/messagebus/routingpolicyrepository.h b/documentapi/src/vespa/documentapi/messagebus/routingpolicyrepository.h
index ca6057ef8b1..beeb176c88b 100644
--- a/documentapi/src/vespa/documentapi/messagebus/routingpolicyrepository.h
+++ b/documentapi/src/vespa/documentapi/messagebus/routingpolicyrepository.h
@@ -2,8 +2,8 @@
#pragma once
#include "iroutingpolicyfactory.h"
-#include <vespa/vespalib/util/sync.h>
#include <map>
+#include <mutex>
namespace documentapi {
@@ -11,8 +11,8 @@ class RoutingPolicyRepository {
private:
typedef std::map<string, IRoutingPolicyFactory::SP> FactoryMap;
- vespalib::Lock _lock;
- FactoryMap _factories;
+ mutable std::mutex _lock;
+ FactoryMap _factories;
public:
RoutingPolicyRepository(const RoutingPolicyRepository &) = delete;
diff --git a/documentapi/test/crosslanguagefiles/6.221-cpp-MapVisitorMessage.dat b/documentapi/test/crosslanguagefiles/6.221-cpp-MapVisitorMessage.dat
index 1a8a837ea16..c9201fe780d 100644
--- a/documentapi/test/crosslanguagefiles/6.221-cpp-MapVisitorMessage.dat
+++ b/documentapi/test/crosslanguagefiles/6.221-cpp-MapVisitorMessage.dat
Binary files differ
diff --git a/eval/CMakeLists.txt b/eval/CMakeLists.txt
index 18c3676c366..230c90009f5 100644
--- a/eval/CMakeLists.txt
+++ b/eval/CMakeLists.txt
@@ -14,6 +14,7 @@ vespa_define_module(
src/tests/eval/aggr
src/tests/eval/compile_cache
src/tests/eval/compiled_function
+ src/tests/eval/fast_sparse_map
src/tests/eval/function
src/tests/eval/function_speed
src/tests/eval/gbdt
@@ -24,7 +25,6 @@ vespa_define_module(
src/tests/eval/node_tools
src/tests/eval/node_types
src/tests/eval/param_usage
- src/tests/eval/simple_sparse_map
src/tests/eval/simple_tensor
src/tests/eval/simple_value
src/tests/eval/tensor_function
@@ -65,6 +65,9 @@ vespa_define_module(
src/tests/tensor/instruction_benchmark
src/tests/tensor/onnx_wrapper
src/tests/tensor/packed_mappings
+ src/tests/tensor/partial_add
+ src/tests/tensor/partial_modify
+ src/tests/tensor/partial_remove
src/tests/tensor/tensor_add_operation
src/tests/tensor/tensor_address
src/tests/tensor/tensor_conformance
diff --git a/eval/src/apps/tensor_conformance/tensor_conformance.cpp b/eval/src/apps/tensor_conformance/tensor_conformance.cpp
index 59fe2960dbb..6099e543922 100644
--- a/eval/src/apps/tensor_conformance/tensor_conformance.cpp
+++ b/eval/src/apps/tensor_conformance/tensor_conformance.cpp
@@ -278,8 +278,8 @@ void compare_test(const Inspector &expect_in, const Inspector &actual_in) {
void compare(Input &expect, Input &actual) {
TestList expect_tests;
TestList actual_tests;
- for_each_test(expect, std::bind(&TestList::add_test, &expect_tests, _1), [](Slime &){});
- for_each_test(actual, std::bind(&TestList::add_test, &actual_tests, _1), [](Slime &){});
+ for_each_test(expect, std::bind(&TestList::add_test, &expect_tests, _1), [](Slime &) noexcept {});
+ for_each_test(actual, std::bind(&TestList::add_test, &actual_tests, _1), [](Slime &) noexcept {});
ASSERT_TRUE(!expect_tests.list.empty());
ASSERT_TRUE(!actual_tests.list.empty());
ASSERT_EQUAL(expect_tests.list.size(), actual_tests.list.size());
diff --git a/eval/src/tests/ann/hnsw-like.h b/eval/src/tests/ann/hnsw-like.h
index 841957c1ccb..ac4a346993d 100644
--- a/eval/src/tests/ann/hnsw-like.h
+++ b/eval/src/tests/ann/hnsw-like.h
@@ -86,7 +86,7 @@ struct VisitedSetPool
struct HnswHit {
double dist;
uint32_t docid;
- HnswHit(uint32_t di, SqDist sq) : dist(sq.distance), docid(di) {}
+ HnswHit(uint32_t di, SqDist sq) noexcept : dist(sq.distance), docid(di) {}
};
struct GreaterDist {
diff --git a/eval/src/tests/ann/nns.h b/eval/src/tests/ann/nns.h
index 7a20a132248..6351733fb59 100644
--- a/eval/src/tests/ann/nns.h
+++ b/eval/src/tests/ann/nns.h
@@ -8,13 +8,13 @@
struct SqDist {
double distance;
- explicit SqDist(double d) : distance(d) {}
+ explicit SqDist(double d) noexcept : distance(d) {}
};
struct NnsHit {
uint32_t docid;
SqDist sq;
- NnsHit(uint32_t di, SqDist sqD)
+ NnsHit(uint32_t di, SqDist sqD) noexcept
: docid(di), sq(sqD) {}
};
struct NnsHitComparatorLessDistance {
diff --git a/eval/src/tests/eval/fast_sparse_map/CMakeLists.txt b/eval/src/tests/eval/fast_sparse_map/CMakeLists.txt
new file mode 100644
index 00000000000..fd9c1d37d43
--- /dev/null
+++ b/eval/src/tests/eval/fast_sparse_map/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+vespa_add_executable(eval_fast_sparse_map_test_app TEST
+ SOURCES
+ fast_sparse_map_test.cpp
+ DEPENDS
+ vespaeval
+ GTest::GTest
+)
+vespa_add_test(NAME eval_fast_sparse_map_test_app COMMAND eval_fast_sparse_map_test_app)
diff --git a/eval/src/tests/eval/simple_sparse_map/simple_sparse_map_test.cpp b/eval/src/tests/eval/fast_sparse_map/fast_sparse_map_test.cpp
index 8062881ced9..3d98ec67aa8 100644
--- a/eval/src/tests/eval/simple_sparse_map/simple_sparse_map_test.cpp
+++ b/eval/src/tests/eval/fast_sparse_map/fast_sparse_map_test.cpp
@@ -1,6 +1,6 @@
// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/eval/eval/simple_sparse_map.h>
+#include <vespa/eval/eval/fast_sparse_map.h>
#include <vespa/vespalib/stllike/hash_map.hpp>
#include <vespa/vespalib/gtest/gtest.h>
@@ -24,19 +24,30 @@ public:
}
}
~StringList();
- const std::vector<vespalib::string> direct_str() const { return _str_list; }
+ ConstArrayRef<vespalib::string> direct_str() const { return _str_list; }
ConstArrayRef<vespalib::stringref> direct_ref() const { return _ref_list; }
ConstArrayRef<const vespalib::stringref *> indirect_ref() const { return _ref_ptr_list; }
+ bool is_eq(ConstArrayRef<FastSparseMap::HashedLabel> addr) const {
+ if (addr.size() != _str_list.size()) {
+ return false;
+ }
+ for (size_t i = 0; i < addr.size(); ++i) {
+ if (addr[i].label != _str_list[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
};
StringList::~StringList() = default;
using SL = StringList;
-TEST(SimpleSparseMapTest, simple_sparse_map_basic_usage_works) {
+TEST(FastSparseMapTest, fast_sparse_map_basic_usage_works) {
SL a1({"a","a","a"});
SL a2({"a","a","b"});
SL a3({"a","b","a"});
SL a4({"b","a","a"});
- SimpleSparseMap map(3, 128);
+ FastSparseMap map(3, 128);
EXPECT_EQ(map.size(), 0);
map.add_mapping(a1.direct_str());
map.add_mapping(a2.direct_ref());
@@ -54,18 +65,34 @@ TEST(SimpleSparseMapTest, simple_sparse_map_basic_usage_works) {
EXPECT_EQ(map.lookup(a4.direct_str()), map.npos());
EXPECT_EQ(map.lookup(a4.direct_ref()), map.npos());
EXPECT_EQ(map.lookup(a4.indirect_ref()), map.npos());
- EXPECT_EQ(SimpleSparseMap::npos(), map.npos());
- SL expect_labels({"a","a","a",
- "a","a","b",
- "a","b","a"});
- EXPECT_EQ(map.labels(), expect_labels.direct_str());
+ EXPECT_EQ(FastSparseMap::npos(), map.npos());
+ EXPECT_EQ(map.labels().size(), 9);
+ std::set<uint64_t> seen_hashes;
+ std::map<uint32_t, uint32_t> addr_map;
+ auto my_fun = [&](uint32_t subspace, uint64_t hash) {
+ uint32_t addr_tag = subspace * 3;
+ addr_map[addr_tag] = subspace;
+ seen_hashes.insert(hash);
+ };
+ map.each_map_entry(my_fun);
+ EXPECT_EQ(seen_hashes.size(), 3);
+ EXPECT_EQ(addr_map.size(), 3);
+ EXPECT_NE(addr_map.find(0), addr_map.end());
+ EXPECT_EQ(addr_map[0], 0);
+ EXPECT_EQ(addr_map[3], 1);
+ EXPECT_EQ(addr_map[6], 2);
+ EXPECT_EQ(addr_map.size(), 3);
+ EXPECT_TRUE(a1.is_eq(map.make_addr(0)));
+ EXPECT_FALSE(a2.is_eq(map.make_addr(0)));
+ EXPECT_TRUE(a2.is_eq(map.make_addr(1)));
+ EXPECT_TRUE(a3.is_eq(map.make_addr(2)));
}
-TEST(SimpleSparseMapTest, simple_sparse_map_works_with_no_labels) {
+TEST(FastSparseMapTest, fast_sparse_map_works_with_no_labels) {
SL empty({});
- SimpleSparseMap map1(0, 1);
- SimpleSparseMap map2(0, 1);
- SimpleSparseMap map3(0, 1);
+ FastSparseMap map1(0, 1);
+ FastSparseMap map2(0, 1);
+ FastSparseMap map3(0, 1);
EXPECT_EQ(map1.size(), 0);
EXPECT_EQ(map2.size(), 0);
EXPECT_EQ(map3.size(), 0);
@@ -89,8 +116,8 @@ TEST(SimpleSparseMapTest, simple_sparse_map_works_with_no_labels) {
EXPECT_EQ(map3.labels().size(), 0);
}
-TEST(SimpleSparseMapTest, size_of_internal_types) {
- fprintf(stderr, "simple sparse map hash node size: %zu\n", sizeof(hash_node<SimpleSparseMap::MapType::value_type>));
+TEST(FastSparseMapTest, size_of_internal_types) {
+ fprintf(stderr, "fast sparse map hash node size: %zu\n", sizeof(hash_node<FastSparseMap::MapType::value_type>));
}
GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/eval/src/tests/eval/simple_sparse_map/CMakeLists.txt b/eval/src/tests/eval/simple_sparse_map/CMakeLists.txt
deleted file mode 100644
index e3d2885e426..00000000000
--- a/eval/src/tests/eval/simple_sparse_map/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_executable(eval_simple_sparse_map_test_app TEST
- SOURCES
- simple_sparse_map_test.cpp
- DEPENDS
- vespaeval
- GTest::GTest
-)
-vespa_add_test(NAME eval_simple_sparse_map_test_app COMMAND eval_simple_sparse_map_test_app)
diff --git a/eval/src/tests/instruction/generic_concat/generic_concat_test.cpp b/eval/src/tests/instruction/generic_concat/generic_concat_test.cpp
index a2510fdd2fa..dc69bce30f6 100644
--- a/eval/src/tests/instruction/generic_concat/generic_concat_test.cpp
+++ b/eval/src/tests/instruction/generic_concat/generic_concat_test.cpp
@@ -20,29 +20,40 @@ using vespalib::make_string_short::fmt;
std::vector<Layout> concat_layouts = {
{}, {},
- {}, {x(5)},
- {x(5)}, {},
- {x(2)}, {x(3)},
- {x(2)}, {y(3)},
- {y(2)}, {z(3)},
- {x(5)}, {x(2),y(5)},
- {y(3)}, {x(2),z(3)},
- {x(2)}, {x(3),y(5),z(2)},
- {x(2),y(5),z(2)}, {x(3),y(5),z(2)},
- {x(3),y(5)}, {y(5),z(7)},
- float_cells({x(3),y(5)}), {y(5),z(7)},
- {x(3),y(5)}, float_cells({y(5),z(7)}),
- float_cells({x(3),y(5)}), float_cells({y(5),z(7)}),
- {y({"a","b","c"})}, {y({"a","b","c"})},
- {y({"a","b","c"})}, {y({"a","b"})},
- {y({"a","b","c"})}, {y({"b","c","d"})},
- float_cells({y({"a","b","c"})}), {y({"b","c","d"})},
- {y({"a","b","c"})}, float_cells({y({"b","c","d"})}),
- float_cells({y({"a","b","c"})}), float_cells({z({"foo","bar","baz"})}),
- {y({"a","b","c"})}, {y({"a","b","c"}),z({"foo","bar","baz"})},
- {y({"a","b"}),z({"foo","bar","baz"})}, {y({"a","b","c"}),z({"foo","bar"})},
- {x(2),y({"a","b","c"})}, {x(3),y({"b","c","d"})},
- {x(2),y({"a","b"})}, {x(3),z({"c","d"})}
+ {}, {y(5)},
+ float_cells({y(5)}), {},
+ {}, float_cells({y(5)}),
+ {y(5)}, {},
+ {y(2)}, {y(3)},
+ {y(2)}, {x(3)},
+ {x(2)}, {z(3)},
+ {x(2),y(3)}, {x(2),y(3)},
+ {x(2),y(3)}, {x(2),y(4)},
+ {y(3),z(5)}, {y(3),z(5)},
+ {y(3),z(5)}, {y(4),z(5)},
+ {x(2),y(3),z(5)}, {x(2),y(3),z(5)},
+ {x(2),y(3),z(5)}, {x(2),y(4),z(5)},
+ {x(2),y(3),z({"a","b"})}, {x(2),y(3),z({"b","c"})},
+ {x(2),y(3),z({"a","b"})}, {x(2),y(4),z({"b","c"})},
+ {y(5)}, {y(2),x(5)},
+ {x(3)}, {y(2),z(3)},
+ {y(2)}, {y(3),x(5),z(2)},
+ {y(2),x(5),z(2)}, {y(3),x(5),z(2)},
+ {y(3),x(5)}, {x(5),z(7)},
+ float_cells({y(3),x(5)}), {x(5),z(7)},
+ float_cells({y(3),x(5)}), {},
+ {y(3),x(5)}, float_cells({x(5),z(7)}),
+ float_cells({y(3),x(5)}), float_cells({x(5),z(7)}),
+ {x({"a","b","c"})}, {x({"a","b","c"})},
+ {x({"a","b","c"})}, {x({"a","b"})},
+ {x({"a","b","c"})}, {x({"b","c","d"})},
+ float_cells({x({"a","b","c"})}), {x({"b","c","d"})},
+ {x({"a","b","c"})}, float_cells({x({"b","c","d"})}),
+ float_cells({x({"a","b","c"})}), float_cells({z({"foo","bar","baz"})}),
+ {x({"a","b","c"})}, {x({"a","b","c"}),z({"foo","bar","baz"})},
+ {x({"a","b"}),z({"foo","bar","baz"})}, {x({"a","b","c"}),z({"foo","bar"})},
+ {y(2),x({"a","b","c"})}, {y(3),x({"b","c","d"})},
+ {y(2),x({"a","b"})}, {y(3),z({"c","d"})}
};
TensorSpec perform_simpletensor_concat(const TensorSpec &a, const TensorSpec &b, const std::string &dimension) {
@@ -101,8 +112,8 @@ TensorSpec reference_concat(const TensorSpec &a, const TensorSpec &b, const std:
TensorSpec::Address addr_a;
TensorSpec::Address addr_b;
if (concat_addresses(cell_a.first, cell_b.first, concat_dim, b_offset, addr_a, addr_b)) {
- result.set(addr_a, cell_a.second);
- result.set(addr_b, cell_b.second);
+ result.add(addr_a, cell_a.second);
+ result.add(addr_b, cell_b.second);
}
}
}
@@ -125,8 +136,8 @@ TEST(GenericConcatTest, generic_reference_concat_works) {
const TensorSpec lhs = spec(concat_layouts[i], N());
const TensorSpec rhs = spec(concat_layouts[i + 1], Div16(N()));
SCOPED_TRACE(fmt("\n===\nin LHS: %s\nin RHS: %s\n===\n", lhs.to_string().c_str(), rhs.to_string().c_str()));
- auto actual = reference_concat(lhs, rhs, "x");
- auto expect = perform_simpletensor_concat(lhs, rhs, "x");
+ auto actual = reference_concat(lhs, rhs, "y");
+ auto expect = perform_simpletensor_concat(lhs, rhs, "y");
EXPECT_EQ(actual, expect);
}
}
@@ -137,10 +148,33 @@ TEST(GenericConcatTest, generic_concat_works_for_simple_values) {
const TensorSpec lhs = spec(concat_layouts[i], N());
const TensorSpec rhs = spec(concat_layouts[i + 1], Div16(N()));
SCOPED_TRACE(fmt("\n===\nin LHS: %s\nin RHS: %s\n===\n", lhs.to_string().c_str(), rhs.to_string().c_str()));
- auto actual = perform_generic_concat(lhs, rhs, "x");
- auto expect = reference_concat(lhs, rhs, "x");
+ auto actual = perform_generic_concat(lhs, rhs, "y");
+ auto expect = reference_concat(lhs, rhs, "y");
EXPECT_EQ(actual, expect);
}
}
+TEST(GenericConcatTest, dense_concat_plan_can_be_created) {
+ auto lhs = ValueType::from_spec("tensor(a[2],b[3],c[5],d{},f[2],g[3])");
+ auto rhs = ValueType::from_spec("tensor(a[2],b[3],c[7],e{},h[3],i[4])");
+ auto res_type = ValueType::concat(lhs, rhs, "c");
+ auto plan = DenseConcatPlan(lhs, rhs, "c", res_type);
+ EXPECT_EQ(plan.right_offset, 5*2*3*3*4);
+ EXPECT_EQ(plan.output_size, 2*3*12*2*3*3*4);
+ EXPECT_EQ(plan.left.input_size, 2*3*5*2*3);
+ std::vector<size_t> expect_left_loop = { 6, 5, 6, 12 };
+ std::vector<size_t> expect_left_in_s = { 30, 6, 1, 0 };
+ std::vector<size_t> expect_left_out_s = { 864, 72, 12, 1 };
+ EXPECT_EQ(plan.left.in_loop_cnt, expect_left_loop);
+ EXPECT_EQ(plan.left.in_stride, expect_left_in_s);
+ EXPECT_EQ(plan.left.out_stride, expect_left_out_s);
+ EXPECT_EQ(plan.right.input_size, 2*3*7*3*4);
+ std::vector<size_t> expect_right_loop = { 6, 7, 6, 12 };
+ std::vector<size_t> expect_right_in_s = { 84, 12, 0, 1 };
+ std::vector<size_t> expect_right_out_s = { 864, 72, 12, 1 };
+ EXPECT_EQ(plan.right.in_loop_cnt, expect_right_loop);
+ EXPECT_EQ(plan.right.in_stride, expect_right_in_s);
+ EXPECT_EQ(plan.right.out_stride, expect_right_out_s);
+}
+
GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/eval/src/tests/instruction/generic_join/generic_join_test.cpp b/eval/src/tests/instruction/generic_join/generic_join_test.cpp
index 4821bf092da..25715f07bea 100644
--- a/eval/src/tests/instruction/generic_join/generic_join_test.cpp
+++ b/eval/src/tests/instruction/generic_join/generic_join_test.cpp
@@ -1,6 +1,7 @@
// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/eval/eval/simple_value.h>
+#include <vespa/eval/eval/fast_value.h>
#include <vespa/eval/eval/value_codec.h>
#include <vespa/eval/instruction/generic_join.h>
#include <vespa/eval/eval/interpreted_function.h>
@@ -79,6 +80,16 @@ TensorSpec perform_generic_join(const TensorSpec &a, const TensorSpec &b, join_f
return spec_from_value(single.eval(std::vector<Value::CREF>({*lhs,*rhs})));
}
+TensorSpec perform_generic_join_fast(const TensorSpec &a, const TensorSpec &b, join_fun_t function) {
+ Stash stash;
+ const auto &factory = FastValueBuilderFactory::get();
+ auto lhs = value_from_spec(a, factory);
+ auto rhs = value_from_spec(b, factory);
+ auto my_op = GenericJoin::make_instruction(lhs->type(), rhs->type(), function, factory, stash);
+ InterpretedFunction::EvalSingle single(my_op);
+ return spec_from_value(single.eval(std::vector<Value::CREF>({*lhs,*rhs})));
+}
+
TEST(GenericJoinTest, dense_join_plan_can_be_created) {
auto lhs = ValueType::from_spec("tensor(a{},b[6],c[5],e[3],f[2],g{})");
auto rhs = ValueType::from_spec("tensor(a{},b[6],c[5],d[4],h{})");
@@ -121,7 +132,7 @@ TEST(GenericJoinTest, dense_join_plan_can_be_executed) {
EXPECT_EQ(c, expect);
}
-TEST(GenericJoinTest, generic_join_works_for_simple_values) {
+TEST(GenericJoinTest, generic_join_works_for_simple_and_fast_values) {
ASSERT_TRUE((join_layouts.size() % 2) == 0);
for (size_t i = 0; i < join_layouts.size(); i += 2) {
TensorSpec lhs = spec(join_layouts[i], Div16(N()));
@@ -130,7 +141,9 @@ TEST(GenericJoinTest, generic_join_works_for_simple_values) {
SCOPED_TRACE(fmt("\n===\nLHS: %s\nRHS: %s\n===\n", lhs.to_string().c_str(), rhs.to_string().c_str()));
auto expect = reference_join(lhs, rhs, fun);
auto actual = perform_generic_join(lhs, rhs, fun);
+ auto fast = perform_generic_join_fast(lhs, rhs, fun);
EXPECT_EQ(actual, expect);
+ EXPECT_EQ(fast, expect);
}
}
}
diff --git a/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp b/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp
index 732fc9c3e69..9ebcb0ec77c 100644
--- a/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp
+++ b/eval/src/tests/tensor/dense_replace_type_function/dense_replace_type_function_test.cpp
@@ -16,7 +16,7 @@ using namespace vespalib;
const TensorEngine &engine = DefaultTensorEngine::ref();
TypedCells getCellsRef(const eval::Value &value) {
- return static_cast<const DenseTensorView &>(value).cellsRef();
+ return value.cells();
}
struct ChildMock : Leaf {
diff --git a/eval/src/tests/tensor/dense_simple_join_function/dense_simple_join_function_test.cpp b/eval/src/tests/tensor/dense_simple_join_function/dense_simple_join_function_test.cpp
index b0927fd7e90..34e5363d313 100644
--- a/eval/src/tests/tensor/dense_simple_join_function/dense_simple_join_function_test.cpp
+++ b/eval/src/tests/tensor/dense_simple_join_function/dense_simple_join_function_test.cpp
@@ -59,12 +59,12 @@ EvalFixture::ParamRepo make_params() {
.add_vector("x", 5)
.add_dense({{"c", 5}, {"d", 1}})
.add_dense({{"b", 1}, {"c", 5}})
- .add_matrix("x", 3, "y", 5, [](size_t idx){ return double((idx * 2) + 3); })
- .add_matrix("x", 3, "y", 5, [](size_t idx){ return double((idx * 3) + 2); })
- .add_vector("y", 5, [](size_t idx){ return double((idx * 2) + 3); })
- .add_vector("y", 5, [](size_t idx){ return double((idx * 3) + 2); })
- .add_matrix("y", 5, "z", 3, [](size_t idx){ return double((idx * 2) + 3); })
- .add_matrix("y", 5, "z", 3, [](size_t idx){ return double((idx * 3) + 2); });
+ .add_matrix("x", 3, "y", 5, [](size_t idx) noexcept { return double((idx * 2) + 3); })
+ .add_matrix("x", 3, "y", 5, [](size_t idx) noexcept { return double((idx * 3) + 2); })
+ .add_vector("y", 5, [](size_t idx) noexcept { return double((idx * 2) + 3); })
+ .add_vector("y", 5, [](size_t idx) noexcept { return double((idx * 3) + 2); })
+ .add_matrix("y", 5, "z", 3, [](size_t idx) noexcept { return double((idx * 2) + 3); })
+ .add_matrix("y", 5, "z", 3, [](size_t idx) noexcept { return double((idx * 3) + 2); });
}
EvalFixture::ParamRepo param_repo = make_params();
diff --git a/eval/src/tests/tensor/direct_dense_tensor_builder/direct_dense_tensor_builder_test.cpp b/eval/src/tests/tensor/direct_dense_tensor_builder/direct_dense_tensor_builder_test.cpp
index 75e9c7868ce..4c96145862c 100644
--- a/eval/src/tests/tensor/direct_dense_tensor_builder/direct_dense_tensor_builder_test.cpp
+++ b/eval/src/tests/tensor/direct_dense_tensor_builder/direct_dense_tensor_builder_test.cpp
@@ -29,9 +29,8 @@ void assertTensor(const vespalib::string &type_spec,
const std::vector<double> &expCells,
const Tensor &tensor)
{
- const DenseTensorView &realTensor = dynamic_cast<const DenseTensorView &>(tensor);
- EXPECT_EQUAL(ValueType::from_spec(type_spec), realTensor.type());
- EXPECT_EQUAL(expCells, dispatch_1<CallMakeVector>(realTensor.cellsRef()));
+ EXPECT_EQUAL(ValueType::from_spec(type_spec), tensor.type());
+ EXPECT_EQUAL(expCells, dispatch_1<CallMakeVector>(tensor.cells()));
}
void assertTensorSpec(const TensorSpec &expSpec, const Tensor &tensor) {
diff --git a/eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp b/eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp
index 2c5b262ee0d..953415f9f71 100644
--- a/eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp
+++ b/eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp
@@ -21,7 +21,9 @@
// verifying that all implementations produce the same result.
#include <vespa/eval/eval/simple_value.h>
+#include <vespa/eval/eval/fast_value.h>
#include <vespa/eval/eval/interpreted_function.h>
+#include <vespa/eval/instruction/generic_concat.h>
#include <vespa/eval/instruction/generic_join.h>
#include <vespa/eval/instruction/generic_reduce.h>
#include <vespa/eval/instruction/generic_rename.h>
@@ -66,6 +68,7 @@ struct Impl {
virtual Instruction create_reduce(const ValueType &lhs, Aggr aggr, const std::vector<vespalib::string> &dims, Stash &stash) const = 0;
virtual Instruction create_rename(const ValueType &lhs, const std::vector<vespalib::string> &from, const std::vector<vespalib::string> &to, Stash &stash) const = 0;
virtual Instruction create_merge(const ValueType &lhs, const ValueType &rhs, operation::op2_t function, Stash &stash) const = 0;
+ virtual Instruction create_concat(const ValueType &lhs, const ValueType &rhs, const std::string &dimension, Stash &stash) const = 0;
virtual const TensorEngine &engine() const { return SimpleTensorEngine::ref(); } // engine used by EvalSingle
virtual ~Impl() {}
};
@@ -88,6 +91,9 @@ struct ValueImpl : Impl {
Instruction create_merge(const ValueType &lhs, const ValueType &rhs, operation::op2_t function, Stash &stash) const override {
return GenericMerge::make_instruction(lhs, rhs, function, my_factory, stash);
}
+ Instruction create_concat(const ValueType &lhs, const ValueType &rhs, const std::string &dimension, Stash &stash) const override {
+ return GenericConcat::make_instruction(lhs, rhs, dimension, my_factory, stash);
+ }
};
struct EngineImpl : Impl {
@@ -122,16 +128,24 @@ struct EngineImpl : Impl {
const auto &merge_node = tensor_function::merge(lhs_node, rhs_node, function, stash);
return merge_node.compile_self(my_engine, stash);
}
+ Instruction create_concat(const ValueType &lhs, const ValueType &rhs, const std::string &dimension, Stash &stash) const override {
+ // create a complete tensor function, but only compile the relevant instruction
+ const auto &lhs_node = tensor_function::inject(lhs, 0, stash);
+ const auto &rhs_node = tensor_function::inject(rhs, 1, stash);
+ const auto &concat_node = tensor_function::concat(lhs_node, rhs_node, dimension, stash);
+ return concat_node.compile_self(my_engine, stash);
+ }
const TensorEngine &engine() const override { return my_engine; }
};
//-----------------------------------------------------------------------------
-EngineImpl simple_tensor_engine_impl(4, " SimpleTensorEngine", " SimpleT", SimpleTensorEngine::ref());
+EngineImpl simple_tensor_engine_impl(5, " SimpleTensorEngine", " SimpleT", SimpleTensorEngine::ref());
EngineImpl default_tensor_engine_impl(1, "DefaultTensorEngine", "OLD PROD", DefaultTensorEngine::ref());
-ValueImpl simple_value_impl(3, " SimpleValue", " SimpleV", SimpleValueBuilderFactory::get());
-ValueImpl packed_mixed_tensor_impl(2, " PackedMixedTensor", " Packed", PackedMixedTensorBuilderFactory::get());
-ValueImpl default_tensor_value_impl(0, " DefaultValue", "NEW PROD", DefaultValueBuilderFactory::get());
+ValueImpl simple_value_impl(2, " SimpleValue", " SimpleV", SimpleValueBuilderFactory::get());
+ValueImpl fast_value_impl(0, " FastValue", "NEW PROD", FastValueBuilderFactory::get());
+ValueImpl packed_mixed_tensor_impl(4, " PackedMixedTensor", " Packed", PackedMixedTensorBuilderFactory::get());
+ValueImpl default_tensor_value_impl(3, " DefaultValue", "DefaultV", DefaultValueBuilderFactory::get());
vespalib::string short_header("--------");
constexpr double budget = 5.0;
@@ -142,6 +156,7 @@ constexpr double good_limit = 1.10; // GOOD: new prod has performance higher tha
std::vector<CREF<Impl>> impl_list = {simple_tensor_engine_impl,
default_tensor_engine_impl,
simple_value_impl,
+ fast_value_impl,
packed_mixed_tensor_impl,
default_tensor_value_impl};
@@ -344,6 +359,27 @@ void benchmark_merge(const vespalib::string &desc, const TensorSpec &lhs,
//-----------------------------------------------------------------------------
+void benchmark_concat(const vespalib::string &desc, const TensorSpec &lhs,
+ const TensorSpec &rhs, const std::string &dimension)
+{
+ Stash stash;
+ ValueType lhs_type = ValueType::from_spec(lhs.type());
+ ValueType rhs_type = ValueType::from_spec(rhs.type());
+ ValueType res_type = ValueType::concat(lhs_type, rhs_type, dimension);
+ ASSERT_FALSE(lhs_type.is_error());
+ ASSERT_FALSE(rhs_type.is_error());
+ ASSERT_FALSE(res_type.is_error());
+ std::vector<EvalOp::UP> list;
+ for (const Impl &impl: impl_list) {
+ auto op = impl.create_concat(lhs_type, rhs_type, dimension, stash);
+ std::vector<CREF<TensorSpec>> stack_spec({lhs, rhs});
+ list.push_back(std::make_unique<EvalOp>(op, stack_spec, impl));
+ }
+ benchmark(desc, list);
+}
+
+//-----------------------------------------------------------------------------
+
struct D {
vespalib::string name;
bool mapped;
@@ -406,6 +442,44 @@ TEST(MakeInputTest, print_some_test_input) {
//-----------------------------------------------------------------------------
+TEST(DenseConcat, small_vectors) {
+ auto lhs = make_vector(D::idx("x", 10), 1.0);
+ auto rhs = make_vector(D::idx("x", 10), 2.0);
+ benchmark_concat("small dense vector append concat", lhs, rhs, "x");
+}
+
+TEST(DenseConcat, cross_vectors) {
+ auto lhs = make_vector(D::idx("x", 10), 1.0);
+ auto rhs = make_vector(D::idx("x", 10), 2.0);
+ benchmark_concat("small dense vector cross concat", lhs, rhs, "y");
+}
+
+TEST(DenseConcat, cube_and_vector) {
+ auto lhs = make_cube(D::idx("a", 16), D::idx("b", 16), D::idx("c", 16), 1.0);
+ auto rhs = make_vector(D::idx("a", 16), 42.0);
+ benchmark_concat("cube vs vector concat", lhs, rhs, "a");
+}
+
+TEST(SparseConcat, small_vectors) {
+ auto lhs = make_vector(D::map("x", 10, 1), 1.0);
+ auto rhs = make_vector(D::map("x", 10, 2), 2.0);
+ benchmark_concat("small sparse concat", lhs, rhs, "y");
+}
+
+TEST(MixedConcat, large_mixed_a) {
+ auto lhs = make_cube(D::idx("a", 16), D::idx("b", 16), D::map("c", 16, 1), 1.0);
+ auto rhs = make_cube(D::idx("a", 16), D::idx("b", 16), D::map("c", 16, 2), 2.0);
+ benchmark_concat("mixed append concat a", lhs, rhs, "a");
+}
+
+TEST(MixedConcat, large_mixed_b) {
+ auto lhs = make_cube(D::idx("a", 16), D::idx("b", 16), D::map("c", 16, 1), 1.0);
+ auto rhs = make_cube(D::idx("a", 16), D::idx("b", 16), D::map("c", 16, 2), 2.0);
+ benchmark_concat("mixed append concat b", lhs, rhs, "b");
+}
+
+//-----------------------------------------------------------------------------
+
TEST(NumberJoin, plain_op2) {
auto lhs = make_spec(2.0);
auto rhs = make_spec(3.0);
diff --git a/eval/src/tests/tensor/onnx_wrapper/onnx_wrapper_test.cpp b/eval/src/tests/tensor/onnx_wrapper/onnx_wrapper_test.cpp
index d1d8bc796ba..fce7ccc6411 100644
--- a/eval/src/tests/tensor/onnx_wrapper/onnx_wrapper_test.cpp
+++ b/eval/src/tests/tensor/onnx_wrapper/onnx_wrapper_test.cpp
@@ -162,7 +162,7 @@ TEST(OnnxTest, simple_onnx_model_can_be_evaluated)
ctx.bind_param(1, attribute);
ctx.bind_param(2, bias);
ctx.eval();
- auto cells = static_cast<const DenseTensorView&>(output).cellsRef();
+ auto cells = output.cells();
EXPECT_EQ(cells.type, ValueType::CellType::FLOAT);
EXPECT_EQ(cells.size, 1);
EXPECT_EQ(GetCell::from(cells, 0), 79.0);
@@ -208,7 +208,7 @@ TEST(OnnxTest, dynamic_onnx_model_can_be_evaluated)
ctx.bind_param(1, attribute);
ctx.bind_param(2, bias);
ctx.eval();
- auto cells = static_cast<const DenseTensorView&>(output).cellsRef();
+ auto cells = output.cells();
EXPECT_EQ(cells.type, ValueType::CellType::FLOAT);
EXPECT_EQ(cells.size, 1);
EXPECT_EQ(GetCell::from(cells, 0), 79.0);
@@ -254,7 +254,7 @@ TEST(OnnxTest, int_types_onnx_model_can_be_evaluated)
ctx.bind_param(1, attribute);
ctx.bind_param(2, bias);
ctx.eval();
- auto cells = static_cast<const DenseTensorView&>(output).cellsRef();
+ auto cells = output.cells();
EXPECT_EQ(cells.type, ValueType::CellType::DOUBLE);
EXPECT_EQ(cells.size, 1);
EXPECT_EQ(GetCell::from(cells, 0), 79.0);
diff --git a/eval/src/tests/tensor/partial_add/CMakeLists.txt b/eval/src/tests/tensor/partial_add/CMakeLists.txt
new file mode 100644
index 00000000000..f0d07a8e9cf
--- /dev/null
+++ b/eval/src/tests/tensor/partial_add/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+vespa_add_executable(eval_partial_add_test_app TEST
+ SOURCES
+ partial_add_test.cpp
+ DEPENDS
+ vespaeval
+ GTest::GTest
+)
+vespa_add_test(NAME eval_partial_add_test_app COMMAND eval_partial_add_test_app)
diff --git a/eval/src/tests/tensor/partial_add/partial_add_test.cpp b/eval/src/tests/tensor/partial_add/partial_add_test.cpp
new file mode 100644
index 00000000000..4546ae42a5e
--- /dev/null
+++ b/eval/src/tests/tensor/partial_add/partial_add_test.cpp
@@ -0,0 +1,119 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <vespa/eval/eval/simple_value.h>
+#include <vespa/eval/eval/test/tensor_model.hpp>
+#include <vespa/eval/eval/value_codec.h>
+#include <vespa/eval/tensor/cell_values.h>
+#include <vespa/eval/tensor/default_tensor_engine.h>
+#include <vespa/eval/tensor/partial_update.h>
+#include <vespa/eval/tensor/sparse/sparse_tensor.h>
+#include <vespa/eval/tensor/tensor.h>
+#include <vespa/vespalib/util/stringfmt.h>
+#include <vespa/vespalib/gtest/gtest.h>
+#include <optional>
+
+using namespace vespalib;
+using namespace vespalib::eval;
+using namespace vespalib::eval::test;
+
+using vespalib::make_string_short::fmt;
+
+std::vector<Layout> add_layouts = {
+ {x({"a"})}, {x({"b"})},
+ {x({"a","b"})}, {x({"a","c"})},
+ float_cells({x({"a","b"})}), {x({"a","c"})},
+ {x({"a","b"})}, float_cells({x({"a","c"})}),
+ float_cells({x({"a","b"})}), float_cells({x({"a","c"})}),
+ {x({"a","b","c"}),y({"d","e"})}, {x({"b","f"}),y({"d","g"})},
+ {x(3),y({"a","b"})}, {x(3),y({"b","c"})}
+};
+
+TensorSpec reference_add(const TensorSpec &a, const TensorSpec &b) {
+ TensorSpec result(a.type());
+ for (const auto &cell: b.cells()) {
+ result.add(cell.first, cell.second);
+ }
+ auto end_iter = b.cells().end();
+ for (const auto &cell: a.cells()) {
+ auto iter = b.cells().find(cell.first);
+ if (iter == end_iter) {
+ result.add(cell.first, cell.second);
+ }
+ }
+ return result;
+}
+
+Value::UP try_partial_add(const TensorSpec &a, const TensorSpec &b) {
+ const auto &factory = SimpleValueBuilderFactory::get();
+ auto lhs = value_from_spec(a, factory);
+ auto rhs = value_from_spec(b, factory);
+ return tensor::TensorPartialUpdate::add(*lhs, *rhs, factory);
+}
+
+TensorSpec perform_partial_add(const TensorSpec &a, const TensorSpec &b) {
+ auto up = try_partial_add(a, b);
+ EXPECT_TRUE(up);
+ return spec_from_value(*up);
+}
+
+TensorSpec perform_old_add(const TensorSpec &a, const TensorSpec &b) {
+ const auto &engine = tensor::DefaultTensorEngine::ref();
+ auto lhs = engine.from_spec(a);
+ auto rhs = engine.from_spec(b);
+ auto lhs_tensor = dynamic_cast<tensor::Tensor *>(lhs.get());
+ EXPECT_TRUE(lhs_tensor);
+ auto rhs_tensor = dynamic_cast<tensor::Tensor *>(rhs.get());
+ EXPECT_TRUE(rhs_tensor);
+ auto up = lhs_tensor->add(*rhs_tensor);
+ EXPECT_TRUE(up);
+ return engine.to_spec(*up);
+}
+
+
+TEST(PartialAddTest, partial_add_works_for_simple_values) {
+ ASSERT_TRUE((add_layouts.size() % 2) == 0);
+ for (size_t i = 0; i < add_layouts.size(); i += 2) {
+ TensorSpec lhs = spec(add_layouts[i], N());
+ TensorSpec rhs = spec(add_layouts[i + 1], Div16(N()));
+ SCOPED_TRACE(fmt("\n===\nLHS: %s\nRHS: %s\n===\n", lhs.to_string().c_str(), rhs.to_string().c_str()));
+ auto expect = reference_add(lhs, rhs);
+ auto actual = perform_partial_add(lhs, rhs);
+ EXPECT_EQ(actual, expect);
+ }
+}
+
+TEST(PartialAddTest, partial_add_works_like_old_add) {
+ ASSERT_TRUE((add_layouts.size() % 2) == 0);
+ for (size_t i = 0; i < add_layouts.size(); i += 2) {
+ TensorSpec lhs = spec(add_layouts[i], N());
+ TensorSpec rhs = spec(add_layouts[i + 1], Div16(N()));
+ SCOPED_TRACE(fmt("\n===\nLHS: %s\nRHS: %s\n===\n", lhs.to_string().c_str(), rhs.to_string().c_str()));
+ auto expect = perform_old_add(lhs, rhs);
+ auto actual = perform_partial_add(lhs, rhs);
+ EXPECT_EQ(actual, expect);
+ }
+}
+
+std::vector<Layout> bad_layouts = {
+ {x(3)}, {x(3),y(1)},
+ {x(3),y(1)}, {x(3)},
+ {x(3),y(3)}, {x(3),y({"a"})},
+ {x(3),y({"a"})}, {x(3),y(3)},
+ {x({"a"})}, {x({"a"}),y({"b"})},
+ {x({"a"}),y({"b"})}, {x({"a"})},
+ {x({"a"})}, {x({"a"}),y(1)}
+};
+
+TEST(PartialAddTest, partial_add_returns_nullptr_on_invalid_inputs) {
+ ASSERT_TRUE((bad_layouts.size() % 2) == 0);
+ for (size_t i = 0; i < bad_layouts.size(); i += 2) {
+ TensorSpec lhs = spec(bad_layouts[i], N());
+ TensorSpec rhs = spec(bad_layouts[i + 1], Div16(N()));
+ SCOPED_TRACE(fmt("\n===\nLHS: %s\nRHS: %s\n===\n", lhs.to_string().c_str(), rhs.to_string().c_str()));
+ auto actual = try_partial_add(lhs, rhs);
+ auto expect = Value::UP();
+ EXPECT_EQ(actual, expect);
+ }
+}
+
+GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/eval/src/tests/tensor/partial_modify/CMakeLists.txt b/eval/src/tests/tensor/partial_modify/CMakeLists.txt
new file mode 100644
index 00000000000..42a08acaae6
--- /dev/null
+++ b/eval/src/tests/tensor/partial_modify/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+vespa_add_executable(eval_partial_modify_test_app TEST
+ SOURCES
+ partial_modify_test.cpp
+ DEPENDS
+ vespaeval
+ GTest::GTest
+)
+vespa_add_test(NAME eval_partial_modify_test_app COMMAND eval_partial_modify_test_app)
diff --git a/eval/src/tests/tensor/partial_modify/partial_modify_test.cpp b/eval/src/tests/tensor/partial_modify/partial_modify_test.cpp
new file mode 100644
index 00000000000..677d6d71ee1
--- /dev/null
+++ b/eval/src/tests/tensor/partial_modify/partial_modify_test.cpp
@@ -0,0 +1,143 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <vespa/eval/eval/simple_value.h>
+#include <vespa/eval/eval/test/tensor_model.hpp>
+#include <vespa/eval/eval/value_codec.h>
+#include <vespa/eval/tensor/cell_values.h>
+#include <vespa/eval/tensor/default_tensor_engine.h>
+#include <vespa/eval/tensor/partial_update.h>
+#include <vespa/eval/tensor/sparse/sparse_tensor.h>
+#include <vespa/eval/tensor/tensor.h>
+#include <vespa/vespalib/util/stringfmt.h>
+#include <vespa/vespalib/gtest/gtest.h>
+#include <optional>
+
+using namespace vespalib;
+using namespace vespalib::eval;
+using namespace vespalib::eval::test;
+
+using vespalib::make_string_short::fmt;
+
+std::vector<Layout> modify_layouts = {
+ {x({"a"})}, {x({"a"})},
+ {x({"a",""})}, {x({"b","c","d","e"})},
+ {x(5)}, {x({"1","2","foo","17"})},
+ {x({"a","b","c"}),y({"d","e"})}, {x({"b"}),y({"d"})},
+ {x({"a","b","c"})}, {x({"b","c","d"})},
+ {x(4),y({"a","b","c","d"}),z(5)}, {x({"1","2"}),y({"b","d"}),z({"1","3"})},
+ {x(3),y(2)}, {x({"0","1"}),y({"0","1"})},
+ {x({"a","","b"})}, {x({""})}
+};
+
+TensorSpec::Address sparsify(const TensorSpec::Address &input) {
+ TensorSpec::Address output;
+ for (const auto & kv : input) {
+ if (kv.second.is_indexed()) {
+ auto val = fmt("%zu", kv.second.index);
+ output.emplace(kv.first, val);
+ } else {
+ output.emplace(kv.first, kv.second);
+ }
+ }
+ return output;
+}
+
+TensorSpec reference_modify(const TensorSpec &a, const TensorSpec &b, join_fun_t fun) {
+ TensorSpec result(a.type());
+ auto end_iter = b.cells().end();
+ for (const auto &cell: a.cells()) {
+ double v = cell.second;
+ auto sparse_addr = sparsify(cell.first);
+ auto iter = b.cells().find(sparse_addr);
+ if (iter == end_iter) {
+ result.add(cell.first, v);
+ } else {
+ result.add(cell.first, fun(v, iter->second));
+ }
+ }
+ return result;
+}
+
+Value::UP try_partial_modify(const TensorSpec &a, const TensorSpec &b, join_fun_t fun) {
+ const auto &factory = SimpleValueBuilderFactory::get();
+ auto lhs = value_from_spec(a, factory);
+ auto rhs = value_from_spec(b, factory);
+ return tensor::TensorPartialUpdate::modify(*lhs, fun, *rhs, factory);
+}
+
+TensorSpec perform_partial_modify(const TensorSpec &a, const TensorSpec &b, join_fun_t fun) {
+ auto up = try_partial_modify(a, b, fun);
+ EXPECT_TRUE(up);
+ return spec_from_value(*up);
+}
+
+TensorSpec perform_old_modify(const TensorSpec &a, const TensorSpec &b, join_fun_t fun) {
+ const auto &engine = tensor::DefaultTensorEngine::ref();
+ auto lhs = engine.from_spec(a);
+ auto rhs = engine.from_spec(b);
+ auto lhs_tensor = dynamic_cast<tensor::Tensor *>(lhs.get());
+ EXPECT_TRUE(lhs_tensor);
+ auto rhs_sparse = dynamic_cast<tensor::SparseTensor *>(rhs.get());
+ EXPECT_TRUE(rhs_sparse);
+ tensor::CellValues cell_values(*rhs_sparse);
+ auto up = lhs_tensor->modify(fun, cell_values);
+ EXPECT_TRUE(up);
+ return engine.to_spec(*up);
+}
+
+
+TEST(PartialModifyTest, partial_modify_works_for_simple_values) {
+ ASSERT_TRUE((modify_layouts.size() % 2) == 0);
+ for (size_t i = 0; i < modify_layouts.size(); i += 2) {
+ TensorSpec lhs = spec(modify_layouts[i], N());
+ TensorSpec rhs = spec(modify_layouts[i + 1], Div16(N()));
+ SCOPED_TRACE(fmt("\n===\nLHS: %s\nRHS: %s\n===\n", lhs.to_string().c_str(), rhs.to_string().c_str()));
+ for (auto fun: {operation::Add::f, operation::Mul::f, operation::Sub::f}) {
+ auto expect = reference_modify(lhs, rhs, fun);
+ auto actual = perform_partial_modify(lhs, rhs, fun);
+ EXPECT_EQ(actual, expect);
+ }
+ auto fun = [](double, double keep) { return keep; };
+ auto expect = reference_modify(lhs, rhs, fun);
+ auto actual = perform_partial_modify(lhs, rhs, fun);
+ EXPECT_EQ(actual, expect);
+ }
+}
+
+TEST(PartialModifyTest, partial_modify_works_like_old_modify) {
+ ASSERT_TRUE((modify_layouts.size() % 2) == 0);
+ for (size_t i = 0; i < modify_layouts.size(); i += 2) {
+ TensorSpec lhs = spec(modify_layouts[i], N());
+ TensorSpec rhs = spec(modify_layouts[i + 1], Div16(N()));
+ SCOPED_TRACE(fmt("\n===\nLHS: %s\nRHS: %s\n===\n", lhs.to_string().c_str(), rhs.to_string().c_str()));
+ for (auto fun: {operation::Add::f, operation::Mul::f, operation::Sub::f}) {
+ auto expect = perform_old_modify(lhs, rhs, fun);
+ auto actual = perform_partial_modify(lhs, rhs, fun);
+ EXPECT_EQ(actual, expect);
+ }
+ }
+}
+
+std::vector<Layout> bad_layouts = {
+ {x(3)}, {x(3)},
+ {x(3),y({"a"})}, {x(3),y({"a"})},
+ {x({"a"})}, {x({"a"}),y({"b"})},
+ {x({"a"}),y({"b"})}, {x({"a"})},
+ {x({"a"})}, {x({"a"}),y(1)}
+};
+
+TEST(PartialModifyTest, partial_modify_returns_nullptr_on_invalid_inputs) {
+ ASSERT_TRUE((bad_layouts.size() % 2) == 0);
+ for (size_t i = 0; i < bad_layouts.size(); i += 2) {
+ TensorSpec lhs = spec(bad_layouts[i], N());
+ TensorSpec rhs = spec(bad_layouts[i + 1], Div16(N()));
+ SCOPED_TRACE(fmt("\n===\nLHS: %s\nRHS: %s\n===\n", lhs.to_string().c_str(), rhs.to_string().c_str()));
+ for (auto fun: {operation::Add::f}) {
+ auto actual = try_partial_modify(lhs, rhs, fun);
+ auto expect = Value::UP();
+ EXPECT_EQ(actual, expect);
+ }
+ }
+}
+
+GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/eval/src/tests/tensor/partial_remove/CMakeLists.txt b/eval/src/tests/tensor/partial_remove/CMakeLists.txt
new file mode 100644
index 00000000000..1680324f574
--- /dev/null
+++ b/eval/src/tests/tensor/partial_remove/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+vespa_add_executable(eval_partial_remove_test_app TEST
+ SOURCES
+ partial_remove_test.cpp
+ DEPENDS
+ vespaeval
+ GTest::GTest
+)
+vespa_add_test(NAME eval_partial_remove_test_app COMMAND eval_partial_remove_test_app)
diff --git a/eval/src/tests/tensor/partial_remove/partial_remove_test.cpp b/eval/src/tests/tensor/partial_remove/partial_remove_test.cpp
new file mode 100644
index 00000000000..7d1611b7f64
--- /dev/null
+++ b/eval/src/tests/tensor/partial_remove/partial_remove_test.cpp
@@ -0,0 +1,126 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <vespa/eval/eval/simple_value.h>
+#include <vespa/eval/eval/test/tensor_model.hpp>
+#include <vespa/eval/eval/value_codec.h>
+#include <vespa/eval/tensor/cell_values.h>
+#include <vespa/eval/tensor/default_tensor_engine.h>
+#include <vespa/eval/tensor/partial_update.h>
+#include <vespa/eval/tensor/sparse/sparse_tensor.h>
+#include <vespa/eval/tensor/tensor.h>
+#include <vespa/vespalib/util/stringfmt.h>
+#include <vespa/vespalib/gtest/gtest.h>
+#include <optional>
+
+using namespace vespalib;
+using namespace vespalib::eval;
+using namespace vespalib::eval::test;
+
+using vespalib::make_string_short::fmt;
+
+std::vector<Layout> remove_layouts = {
+ {x({"a"})}, {x({"b"})},
+ {x({"a","b"})}, {x({"a","c"})},
+ {x({"a","b"})}, {x({"a","b"})},
+ float_cells({x({"a","b"})}), {x({"a","c"})},
+ {x({"a","b"})}, float_cells({x({"a","c"})}),
+ float_cells({x({"a","b"})}), float_cells({x({"a","c"})}),
+ {x({"a","b","c"}),y({"d","e"})}, {x({"b","f"}),y({"d","g"})},
+ {x(3),y({"a","b"})}, {y({"b","c"})}
+};
+
+TensorSpec::Address only_sparse(const TensorSpec::Address &input) {
+ TensorSpec::Address output;
+ for (const auto & kv : input) {
+ if (kv.second.is_mapped()) {
+ output.emplace(kv.first, kv.second);
+ }
+ }
+ return output;
+}
+
+TensorSpec reference_remove(const TensorSpec &a, const TensorSpec &b) {
+ TensorSpec result(a.type());
+ auto end_iter = b.cells().end();
+ for (const auto &cell: a.cells()) {
+ auto iter = b.cells().find(only_sparse(cell.first));
+ if (iter == end_iter) {
+ result.add(cell.first, cell.second);
+ }
+ }
+ return result;
+}
+
+Value::UP try_partial_remove(const TensorSpec &a, const TensorSpec &b) {
+ const auto &factory = SimpleValueBuilderFactory::get();
+ auto lhs = value_from_spec(a, factory);
+ auto rhs = value_from_spec(b, factory);
+ return tensor::TensorPartialUpdate::remove(*lhs, *rhs, factory);
+}
+
+TensorSpec perform_partial_remove(const TensorSpec &a, const TensorSpec &b) {
+ auto up = try_partial_remove(a, b);
+ EXPECT_TRUE(up);
+ return spec_from_value(*up);
+}
+
+TensorSpec perform_old_remove(const TensorSpec &a, const TensorSpec &b) {
+ const auto &engine = tensor::DefaultTensorEngine::ref();
+ auto lhs = engine.from_spec(a);
+ auto rhs = engine.from_spec(b);
+ auto lhs_tensor = dynamic_cast<tensor::Tensor *>(lhs.get());
+ EXPECT_TRUE(lhs_tensor);
+ auto rhs_sparse = dynamic_cast<tensor::SparseTensor *>(rhs.get());
+ EXPECT_TRUE(rhs_sparse);
+ tensor::CellValues cell_values(*rhs_sparse);
+ auto up = lhs_tensor->remove(cell_values);
+ EXPECT_TRUE(up);
+ return engine.to_spec(*up);
+}
+
+
+TEST(PartialRemoveTest, partial_remove_works_for_simple_values) {
+ ASSERT_TRUE((remove_layouts.size() % 2) == 0);
+ for (size_t i = 0; i < remove_layouts.size(); i += 2) {
+ TensorSpec lhs = spec(remove_layouts[i], N());
+ TensorSpec rhs = spec(remove_layouts[i + 1], Div16(N()));
+ SCOPED_TRACE(fmt("\n===\nLHS: %s\nRHS: %s\n===\n", lhs.to_string().c_str(), rhs.to_string().c_str()));
+ auto expect = reference_remove(lhs, rhs);
+ auto actual = perform_partial_remove(lhs, rhs);
+ EXPECT_EQ(actual, expect);
+ }
+}
+
+TEST(PartialRemoveTest, partial_remove_works_like_old_remove) {
+ ASSERT_TRUE((remove_layouts.size() % 2) == 0);
+ for (size_t i = 0; i < remove_layouts.size(); i += 2) {
+ TensorSpec lhs = spec(remove_layouts[i], N());
+ TensorSpec rhs = spec(remove_layouts[i + 1], Div16(N()));
+ SCOPED_TRACE(fmt("\n===\nLHS: %s\nRHS: %s\n===\n", lhs.to_string().c_str(), rhs.to_string().c_str()));
+ auto expect = perform_old_remove(lhs, rhs);
+ auto actual = perform_partial_remove(lhs, rhs);
+ EXPECT_EQ(actual, expect);
+ }
+}
+
+std::vector<Layout> bad_layouts = {
+ {x(3)}, {x(3)},
+ {x(3),y({"a"})}, {x(3)},
+ {x(3),y({"a"})}, {x(3),y({"a"})},
+ {x({"a"})}, {y({"a"})},
+ {x({"a"})}, {x({"a"}),y({"b"})}
+};
+
+TEST(PartialRemoveTest, partial_remove_returns_nullptr_on_invalid_inputs) {
+ ASSERT_TRUE((bad_layouts.size() % 2) == 0);
+ for (size_t i = 0; i < bad_layouts.size(); i += 2) {
+ TensorSpec lhs = spec(bad_layouts[i], N());
+ TensorSpec rhs = spec(bad_layouts[i + 1], Div16(N()));
+ SCOPED_TRACE(fmt("\n===\nLHS: %s\nRHS: %s\n===\n", lhs.to_string().c_str(), rhs.to_string().c_str()));
+ auto actual = try_partial_remove(lhs, rhs);
+ auto expect = Value::UP();
+ EXPECT_EQ(actual, expect);
+ }
+}
+
+GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/eval/src/tests/tensor/tensor_serialization/tensor_serialization_test.cpp b/eval/src/tests/tensor/tensor_serialization/tensor_serialization_test.cpp
index e1009969b43..358f5d36101 100644
--- a/eval/src/tests/tensor/tensor_serialization/tensor_serialization_test.cpp
+++ b/eval/src/tests/tensor/tensor_serialization/tensor_serialization_test.cpp
@@ -11,6 +11,7 @@
#include <ostream>
#include <vespa/eval/tensor/dense/dense_tensor_view.h>
#include <vespa/eval/eval/value_codec.h>
+#include <vespa/eval/eval/simple_value.h>
using namespace vespalib::tensor;
using vespalib::eval::TensorSpec;
diff --git a/eval/src/vespa/eval/eval/CMakeLists.txt b/eval/src/vespa/eval/eval/CMakeLists.txt
index e2bcee94498..244966fc992 100644
--- a/eval/src/vespa/eval/eval/CMakeLists.txt
+++ b/eval/src/vespa/eval/eval/CMakeLists.txt
@@ -8,6 +8,8 @@ vespa_add_library(eval_eval OBJECT
delete_node.cpp
double_value_builder.cpp
fast_forest.cpp
+ fast_sparse_map.cpp
+ fast_value.cpp
function.cpp
gbdt.cpp
interpreted_function.cpp
@@ -19,7 +21,6 @@ vespa_add_library(eval_eval OBJECT
operation.cpp
operator_nodes.cpp
param_usage.cpp
- simple_sparse_map.cpp
simple_tensor.cpp
simple_tensor_engine.cpp
simple_value.cpp
diff --git a/eval/src/vespa/eval/eval/fast_sparse_map.cpp b/eval/src/vespa/eval/eval/fast_sparse_map.cpp
new file mode 100644
index 00000000000..3215b5f8995
--- /dev/null
+++ b/eval/src/vespa/eval/eval/fast_sparse_map.cpp
@@ -0,0 +1,12 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "fast_sparse_map.h"
+#include <vespa/vespalib/stllike/hash_map.hpp>
+
+namespace vespalib::eval {
+
+FastSparseMap::~FastSparseMap() = default;
+
+}
+
+VESPALIB_HASH_MAP_INSTANTIATE_H_E(vespalib::eval::FastSparseMap::Key, uint32_t, vespalib::eval::FastSparseMap::Hash, vespalib::eval::FastSparseMap::Equal);
diff --git a/eval/src/vespa/eval/eval/fast_sparse_map.h b/eval/src/vespa/eval/eval/fast_sparse_map.h
new file mode 100644
index 00000000000..666a9db4140
--- /dev/null
+++ b/eval/src/vespa/eval/eval/fast_sparse_map.h
@@ -0,0 +1,153 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include <vespa/vespalib/util/arrayref.h>
+#include <vespa/vespalib/stllike/string.h>
+#include <vespa/vespalib/stllike/hash_map.h>
+#include <vector>
+#include <xxhash.h>
+#include <type_traits>
+
+namespace vespalib::eval {
+
+/**
+ * A wrapper around vespalib::hash_map, using it to map a list of
+ * labels (a sparse address) to an integer value (dense subspace
+ * index). Labels are stored in a separate vector to avoid
+ * fragmentation caused by hash keys being vectors of values. Labels
+ * can be specified in different ways during lookup and insert in
+ * order to reduce the need for data restructuring when used to
+ * integrate with the Value api. All labels are stored with a 64-bit
+ * hash. This hash is used as label equality (assuming no
+ * collisions). A order-sensitive 64bit hash constructed from
+ * individual label hashes is used for address equality (also assuming
+ * no collisions). The hash algorithm currently used is XXH3.
+ *
+ * 'add_mapping' will will bind the given address to an integer value
+ * equal to the current (pre-insert) size of the map. The given
+ * address MUST NOT already be in the map.
+ *
+ * 'lookup' will return the integer value associated with the
+ * given address or a special npos value if the value is not found.
+ **/
+class FastSparseMap
+{
+public:
+ static uint64_t hash_label(const vespalib::string &str) {
+ return XXH3_64bits(str.data(), str.size());
+ }
+ static uint64_t hash_label(vespalib::stringref str) {
+ return XXH3_64bits(str.data(), str.size());
+ }
+ static uint64_t hash_label(const vespalib::stringref *str) {
+ return XXH3_64bits(str->data(), str->size());
+ }
+
+ struct HashedLabel {
+ vespalib::string label;
+ uint64_t hash;
+ HashedLabel() : label(), hash(0) {}
+ HashedLabel(const HashedLabel &rhs) = default;
+ HashedLabel &operator=(const HashedLabel &rhs) = default;
+ HashedLabel(HashedLabel &&rhs) = default;
+ HashedLabel &operator=(HashedLabel &&rhs) = default;
+ HashedLabel(const vespalib::string &str) : label(str), hash(hash_label(str)) {}
+ HashedLabel(vespalib::stringref str) : label(str), hash(hash_label(str)) {}
+ HashedLabel(const vespalib::stringref *str) : label(*str), hash(hash_label(*str)) {}
+ };
+
+ static uint64_t hash_label(const HashedLabel &label) {
+ return label.hash;
+ }
+
+ struct Key {
+ uint64_t hash;
+ Key() : hash(0) {}
+ Key(uint64_t hash_in)
+ : hash(hash_in) {}
+ } __attribute__((packed,aligned(4)));
+
+ struct Hash {
+ uint64_t operator()(const Key &key) const { return key.hash; }
+ uint64_t operator()(uint64_t hash) const { return hash; }
+ };
+
+ struct Equal {
+ bool operator()(const Key &a, uint64_t b) const { return (a.hash == b); }
+ bool operator()(const Key &a, const Key &b) const { return (a.hash == b.hash); }
+ };
+
+ using MapType = vespalib::hash_map<Key,uint32_t,Hash,Equal>;
+
+private:
+ size_t _num_dims;
+ std::vector<HashedLabel> _labels;
+ MapType _map;
+
+public:
+ FastSparseMap(size_t num_dims_in, size_t expected_subspaces)
+ : _num_dims(num_dims_in), _labels(), _map(expected_subspaces * 2)
+ {
+ static_assert(std::is_same_v<XXH64_hash_t, uint64_t>);
+ _labels.reserve(_num_dims * expected_subspaces);
+ }
+ ~FastSparseMap();
+ size_t size() const { return _map.size(); }
+ size_t num_dims() const { return _num_dims; }
+ static constexpr size_t npos() { return -1; }
+ const std::vector<HashedLabel> &labels() const { return _labels; }
+
+ ConstArrayRef<HashedLabel> make_addr(uint32_t index) const {
+ return ConstArrayRef<HashedLabel>(&_labels[index * _num_dims], _num_dims);
+ }
+
+ template <typename T>
+ uint64_t hash_addr(ConstArrayRef<T> addr) const {
+ uint64_t h = 0;
+ for (const auto &label: addr) {
+ h = 31 * h + hash_label(label);
+ }
+ return h;
+ }
+
+ template <typename T>
+ void add_mapping(ConstArrayRef<T> addr, uint64_t hash) {
+ uint32_t value = _map.size();
+ for (const auto &label: addr) {
+ _labels.emplace_back(label);
+ }
+ _map.insert(std::make_pair(Key(hash), value));
+ }
+
+ template <typename T>
+ void add_mapping(ConstArrayRef<T> addr) {
+ uint64_t h = 0;
+ uint32_t value = _map.size();
+ for (const auto &label: addr) {
+ _labels.emplace_back(label);
+ h = 31 * h + hash_label(_labels.back());
+ }
+ _map.insert(std::make_pair(Key(h), value));
+ }
+
+ size_t lookup(uint64_t hash) const {
+ auto pos = _map.find(hash);
+ return (pos == _map.end()) ? npos() : pos->second;
+ }
+
+ template <typename T>
+ size_t lookup(ConstArrayRef<T> addr) const {
+ return lookup(hash_addr(addr));
+ }
+
+ template <typename F>
+ void each_map_entry(F &&f) const {
+ _map.for_each([&](const auto &entry)
+ {
+ f(entry.second, entry.first.hash);
+ });
+ }
+};
+
+}
diff --git a/eval/src/vespa/eval/eval/fast_value.cpp b/eval/src/vespa/eval/eval/fast_value.cpp
new file mode 100644
index 00000000000..2e8226257a4
--- /dev/null
+++ b/eval/src/vespa/eval/eval/fast_value.cpp
@@ -0,0 +1,54 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "fast_value.h"
+#include <vespa/vespalib/util/typify.h>
+#include "fast_value.hpp"
+
+namespace vespalib::eval {
+
+//-----------------------------------------------------------------------------
+
+namespace {
+
+struct CreateFastValueBuilderBase {
+ template <typename T> static std::unique_ptr<ValueBuilderBase> invoke(const ValueType &type,
+ size_t num_mapped_dims, size_t subspace_size, size_t expected_subspaces)
+ {
+ assert(check_cell_type<T>(type.cell_type()));
+ return std::make_unique<FastValue<T>>(type, num_mapped_dims, subspace_size, expected_subspaces);
+ }
+};
+
+} // namespace <unnamed>
+
+//-----------------------------------------------------------------------------
+
+std::unique_ptr<Value::Index::View>
+FastValueIndex::create_view(const std::vector<size_t> &dims) const
+{
+ if (map.num_dims() == 0) {
+ return TrivialIndex::get().create_view(dims);
+ } else if (dims.empty()) {
+ return std::make_unique<IterateView>(map);
+ } else if (dims.size() == map.num_dims()) {
+ return std::make_unique<LookupView>(map);
+ } else {
+ return std::make_unique<FilterView>(map, dims);
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+FastValueBuilderFactory::FastValueBuilderFactory() = default;
+FastValueBuilderFactory FastValueBuilderFactory::_factory;
+
+std::unique_ptr<ValueBuilderBase>
+FastValueBuilderFactory::create_value_builder_base(const ValueType &type, size_t num_mapped_dims, size_t subspace_size,
+ size_t expected_subspaces) const
+{
+ return typify_invoke<1,TypifyCellType,CreateFastValueBuilderBase>(type.cell_type(), type, num_mapped_dims, subspace_size, expected_subspaces);
+}
+
+//-----------------------------------------------------------------------------
+
+}
diff --git a/eval/src/vespa/eval/eval/fast_value.h b/eval/src/vespa/eval/eval/fast_value.h
new file mode 100644
index 00000000000..ac924ecc6eb
--- /dev/null
+++ b/eval/src/vespa/eval/eval/fast_value.h
@@ -0,0 +1,28 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include "value.h"
+
+namespace vespalib::eval {
+
+/**
+ * A fast value is a value that uses a FastValueIndex to store its
+ * sparse mappings. The FastValueIndex class contains inlined
+ * functions that can be called directly from instruction
+ * implementations to speed up sparse operations. Also, the
+ * FastSparseMap used by the FastValueIndex is a highly optimized
+ * alternative to the map used by SimpleValue, which means that normal
+ * Value API usage will also have improved performance.
+ **/
+class FastValueBuilderFactory : public ValueBuilderFactory {
+private:
+ FastValueBuilderFactory();
+ static FastValueBuilderFactory _factory;
+ std::unique_ptr<ValueBuilderBase> create_value_builder_base(const ValueType &type,
+ size_t num_mapped_dims, size_t subspace_size, size_t expected_subspaces) const override;
+public:
+ static const FastValueBuilderFactory &get() { return _factory; }
+};
+
+}
diff --git a/eval/src/vespa/eval/eval/fast_value.hpp b/eval/src/vespa/eval/eval/fast_value.hpp
new file mode 100644
index 00000000000..4efb56ee0c4
--- /dev/null
+++ b/eval/src/vespa/eval/eval/fast_value.hpp
@@ -0,0 +1,215 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "value.h"
+#include "fast_sparse_map.h"
+#include "inline_operation.h"
+#include <vespa/eval/instruction/generic_join.h>
+#include <vespa/vespalib/stllike/hash_map.hpp>
+
+namespace vespalib::eval {
+
+//-----------------------------------------------------------------------------
+
+namespace {
+
+//-----------------------------------------------------------------------------
+
+// look up a full address in the map directly
+struct LookupView : public Value::Index::View {
+
+ const FastSparseMap &map;
+ size_t subspace;
+
+ LookupView(const FastSparseMap &map_in)
+ : map(map_in), subspace(FastSparseMap::npos()) {}
+
+ void lookup(ConstArrayRef<const vespalib::stringref*> addr) override {
+ subspace = map.lookup(addr);
+ }
+
+ bool next_result(ConstArrayRef<vespalib::stringref*>, size_t &idx_out) override {
+ if (subspace == FastSparseMap::npos()) {
+ return false;
+ }
+ idx_out = subspace;
+ subspace = FastSparseMap::npos();
+ return true;
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+// find matching mappings for a partial address with brute force filtering
+struct FilterView : public Value::Index::View {
+
+ using Label = FastSparseMap::HashedLabel;
+
+ size_t num_mapped_dims;
+ const std::vector<Label> &labels;
+ std::vector<size_t> match_dims;
+ std::vector<size_t> extract_dims;
+ std::vector<Label> query;
+ size_t pos;
+
+ bool is_match() const {
+ for (size_t i = 0; i < query.size(); ++i) {
+ if (query[i].hash != labels[pos + match_dims[i]].hash) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ FilterView(const FastSparseMap &map, const std::vector<size_t> &match_dims_in)
+ : num_mapped_dims(map.num_dims()), labels(map.labels()), match_dims(match_dims_in),
+ extract_dims(), query(match_dims.size(), Label()), pos(labels.size())
+ {
+ auto my_pos = match_dims.begin();
+ for (size_t i = 0; i < num_mapped_dims; ++i) {
+ if ((my_pos == match_dims.end()) || (*my_pos != i)) {
+ extract_dims.push_back(i);
+ } else {
+ ++my_pos;
+ }
+ }
+ assert(my_pos == match_dims.end());
+ assert((match_dims.size() + extract_dims.size()) == num_mapped_dims);
+ }
+
+ void lookup(ConstArrayRef<const vespalib::stringref*> addr) override {
+ assert(addr.size() == query.size());
+ for (size_t i = 0; i < addr.size(); ++i) {
+ query[i] = Label(*addr[i]);
+ }
+ pos = 0;
+ }
+
+ bool next_result(ConstArrayRef<vespalib::stringref*> addr_out, size_t &idx_out) override {
+ while (pos < labels.size()) {
+ if (is_match()) {
+ assert(addr_out.size() == extract_dims.size());
+ for (size_t i = 0; i < extract_dims.size(); ++i) {
+ *addr_out[i] = labels[pos + extract_dims[i]].label;
+ }
+ idx_out = (pos / num_mapped_dims); // is this expensive?
+ pos += num_mapped_dims;
+ return true;
+ }
+ pos += num_mapped_dims;
+ }
+ return false;
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+// iterate all mappings
+struct IterateView : public Value::Index::View {
+
+ using Labels = std::vector<FastSparseMap::HashedLabel>;
+
+ size_t num_mapped_dims;
+ const Labels &labels;
+ size_t pos;
+
+ IterateView(const FastSparseMap &map)
+ : num_mapped_dims(map.num_dims()), labels(map.labels()), pos(labels.size()) {}
+
+ void lookup(ConstArrayRef<const vespalib::stringref*>) override {
+ pos = 0;
+ }
+
+ bool next_result(ConstArrayRef<vespalib::stringref*> addr_out, size_t &idx_out) override {
+ if (pos >= labels.size()) {
+ return false;
+ }
+ assert(addr_out.size() == num_mapped_dims);
+ for (size_t i = 0; i < num_mapped_dims; ++i) {
+ *addr_out[i] = labels[pos + i].label;
+ }
+ idx_out = (pos / num_mapped_dims); // is this expensive?
+ pos += num_mapped_dims;
+ return true;
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+} // namespace <unnamed>
+
+//-----------------------------------------------------------------------------
+
+// This is the class instructions will look for when optimizing sparse
+// operations by calling inline functions directly.
+
+struct FastValueIndex final : Value::Index {
+ FastSparseMap map;
+ FastValueIndex(size_t num_mapped_dims_in, size_t expected_subspaces_in)
+ : map(num_mapped_dims_in, expected_subspaces_in) {}
+
+ template <typename LCT, typename RCT, typename OCT, typename Fun>
+ static const Value &sparse_full_overlap_join(const ValueType &res_type, const Fun &fun,
+ const FastValueIndex &lhs, const FastValueIndex &rhs,
+ ConstArrayRef<LCT> lhs_cells, ConstArrayRef<RCT> rhs_cells, Stash &stash);
+
+ size_t size() const override { return map.size(); }
+ std::unique_ptr<View> create_view(const std::vector<size_t> &dims) const override;
+};
+
+//-----------------------------------------------------------------------------
+
+template <typename T>
+struct FastValue final : Value, ValueBuilder<T> {
+
+ ValueType my_type;
+ size_t my_subspace_size;
+ FastValueIndex my_index;
+ std::vector<T> my_cells;
+
+ FastValue(const ValueType &type_in, size_t num_mapped_dims_in, size_t subspace_size_in, size_t expected_subspaces_in)
+ : my_type(type_in), my_subspace_size(subspace_size_in), my_index(num_mapped_dims_in, expected_subspaces_in), my_cells()
+ {
+ my_cells.reserve(subspace_size_in * expected_subspaces_in);
+ }
+ ~FastValue() override;
+ const ValueType &type() const override { return my_type; }
+ const Value::Index &index() const override { return my_index; }
+ TypedCells cells() const override { return TypedCells(ConstArrayRef<T>(my_cells)); }
+ ArrayRef<T> add_subspace(ConstArrayRef<vespalib::stringref> addr) override {
+ size_t old_size = my_cells.size();
+ my_index.map.add_mapping(addr);
+ my_cells.resize(old_size + my_subspace_size);
+ return ArrayRef<T>(&my_cells[old_size], my_subspace_size);
+ }
+ std::unique_ptr<Value> build(std::unique_ptr<ValueBuilder<T>> self) override {
+ ValueBuilder<T>* me = this;
+ assert(me == self.get());
+ self.release();
+ return std::unique_ptr<Value>(this);
+ }
+};
+template <typename T> FastValue<T>::~FastValue() = default;
+
+//-----------------------------------------------------------------------------
+
+template <typename LCT, typename RCT, typename OCT, typename Fun>
+const Value &
+FastValueIndex::sparse_full_overlap_join(const ValueType &res_type, const Fun &fun,
+ const FastValueIndex &lhs, const FastValueIndex &rhs,
+ ConstArrayRef<LCT> lhs_cells, ConstArrayRef<RCT> rhs_cells, Stash &stash)
+{
+ auto &result = stash.create<FastValue<OCT>>(res_type, lhs.map.num_dims(), 1, lhs.map.size());
+ lhs.map.each_map_entry([&](auto lhs_subspace, auto hash)
+ {
+ auto rhs_subspace = rhs.map.lookup(hash);
+ if (rhs_subspace != FastSparseMap::npos()) {
+ result.my_index.map.add_mapping(lhs.map.make_addr(lhs_subspace), hash);
+ result.my_cells.push_back(fun(lhs_cells[lhs_subspace], rhs_cells[rhs_subspace]));
+ }
+ });
+ return result;
+}
+
+//-----------------------------------------------------------------------------
+
+}
diff --git a/eval/src/vespa/eval/eval/simple_sparse_map.cpp b/eval/src/vespa/eval/eval/simple_sparse_map.cpp
deleted file mode 100644
index 18d3bffd47d..00000000000
--- a/eval/src/vespa/eval/eval/simple_sparse_map.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include "simple_sparse_map.h"
-#include <vespa/vespalib/stllike/hash_map.hpp>
-
-namespace vespalib::eval {
-
-SimpleSparseMap::~SimpleSparseMap() = default;
-
-}
-
-VESPALIB_HASH_MAP_INSTANTIATE_H_E(vespalib::eval::SimpleSparseMap::Key, uint32_t, vespalib::eval::SimpleSparseMap::Hash, vespalib::eval::SimpleSparseMap::Equal);
diff --git a/eval/src/vespa/eval/eval/simple_sparse_map.h b/eval/src/vespa/eval/eval/simple_sparse_map.h
deleted file mode 100644
index 61ff9f326e2..00000000000
--- a/eval/src/vespa/eval/eval/simple_sparse_map.h
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#pragma once
-
-#include <vespa/vespalib/util/arrayref.h>
-#include <vespa/vespalib/stllike/string.h>
-#include <vespa/vespalib/stllike/hash_map.h>
-#include <vector>
-#include <cassert>
-
-namespace vespalib::eval {
-
-/**
- * A simple wrapper around vespalib::hash_map, using it to map a list
- * of labels (a sparse address) to an integer value (dense subspace
- * index). Labels are stored in a separate vector and the map keys
- * reference a slice of this vector. This is to avoid fragmentation
- * caused by hash keys being vectors of values. In addition, labels
- * can be specified in different ways during lookup and insert in
- * order to reduce the need for data restructuring when using the
- * map. To keep things simple, map iterators are kept away from the
- * api. This will have a minor overhead during lookup since the end
- * iterator needs to be translated to npos. All added mappings are
- * checked for uniqueness with an assert. There is no real need for
- * map entry iteration since you can just iterate the labels vector
- * directly.
- *
- * 'add_mapping' will will bind the given address to an integer value
- * equal to the current (pre-insert) size of the map. The given
- * address MUST NOT already be in the map.
- *
- * 'lookup' will return the integer value associated with the
- * given address or a special npos value if the value is not found.
- **/
-class SimpleSparseMap
-{
-public:
- using DirectStr = ConstArrayRef<vespalib::string>;
- using DirectRef = ConstArrayRef<vespalib::stringref>;
- using IndirectRef = ConstArrayRef<const vespalib::stringref *>;
-
- struct Key {
- uint32_t start;
- uint32_t end;
- Key() : start(0), end(0) {}
- Key(uint32_t start_in, uint32_t end_in)
- : start(start_in), end(end_in) {}
- };
-
- struct Hash {
- const std::vector<vespalib::string> *labels;
- const vespalib::string &get_label(size_t i) const { return (*labels)[i]; }
- Hash() : labels(nullptr) {}
- Hash(const Hash &rhs) = default;
- Hash &operator=(const Hash &rhs) = default;
- Hash(const std::vector<vespalib::string> &labels_in) : labels(&labels_in) {}
- size_t operator()(const Key &key) const {
- size_t h = 0;
- for (size_t i = key.start; i < key.end; ++i) {
- const vespalib::string &str = get_label(i);
- h = h * 31 + hashValue(str.data(), str.size());
- }
- return h;
- }
- size_t operator()(const DirectStr &addr) const {
- size_t h = 0;
- for (const auto &str: addr) {
- h = h * 31 + hashValue(str.data(), str.size());
- }
- return h;
- }
- size_t operator()(const DirectRef &addr) const {
- size_t h = 0;
- for (const auto &str: addr) {
- h = h * 31 + hashValue(str.data(), str.size());
- }
- return h;
- }
- size_t operator()(const IndirectRef &addr) const {
- size_t h = 0;
- for (const auto *str: addr) {
- h = h * 31 + hashValue(str->data(), str->size());
- }
- return h;
- }
- };
-
- struct Equal {
- const std::vector<vespalib::string> *labels;
- const vespalib::string &get_label(size_t i) const { return (*labels)[i]; }
- Equal() : labels(nullptr) {}
- Equal(const Equal &rhs) = default;
- Equal &operator=(const Equal &rhs) = default;
- Equal(const std::vector<vespalib::string> &labels_in) : labels(&labels_in) {}
- bool operator()(const Key &a, const Key &b) const {
- size_t len = (a.end - a.start);
- if ((b.end - b.start) != len) {
- return false;
- }
- for (size_t i = 0; i < len; ++i) {
- if (get_label(a.start + i) != get_label(b.start + i)) {
- return false;
- }
- }
- return true;
- }
- bool operator()(const Key &a, const DirectStr &addr) const {
- if (addr.size() != (a.end - a.start)) {
- return false;
- }
- for (size_t i = 0; i < addr.size(); ++i) {
- if (get_label(a.start + i) != addr[i]) {
- return false;
- }
- }
- return true;
- }
- bool operator()(const Key &a, const DirectRef &addr) const {
- if (addr.size() != (a.end - a.start)) {
- return false;
- }
- for (size_t i = 0; i < addr.size(); ++i) {
- if (get_label(a.start + i) != addr[i]) {
- return false;
- }
- }
- return true;
- }
- bool operator()(const Key &a, const IndirectRef &addr) const {
- if (addr.size() != (a.end - a.start)) {
- return false;
- }
- for (size_t i = 0; i < addr.size(); ++i) {
- if (get_label(a.start + i) != *addr[i]) {
- return false;
- }
- }
- return true;
- }
- };
-
- using MapType = vespalib::hash_map<Key,uint32_t,Hash,Equal>;
-
-private:
- std::vector<vespalib::string> _labels;
- MapType _map;
-
-public:
- SimpleSparseMap(size_t num_mapped_dims, size_t expected_subspaces)
- : _labels(), _map(expected_subspaces * 2, Hash(_labels), Equal(_labels))
- {
- _labels.reserve(num_mapped_dims * expected_subspaces);
- }
- ~SimpleSparseMap();
- size_t size() const { return _map.size(); }
- static constexpr size_t npos() { return -1; }
- const std::vector<vespalib::string> &labels() const { return _labels; }
- void add_mapping(DirectStr addr) {
- uint32_t value = _map.size();
- uint32_t start = _labels.size();
- for (const auto &label: addr) {
- _labels.emplace_back(label);
- }
- uint32_t end = _labels.size();
- auto [ignore, was_inserted] = _map.insert(std::make_pair(Key(start, end), value));
- assert(was_inserted);
- }
- void add_mapping(DirectRef addr) {
- uint32_t value = _map.size();
- uint32_t start = _labels.size();
- for (const auto &label: addr) {
- _labels.emplace_back(label);
- }
- uint32_t end = _labels.size();
- auto [ignore, was_inserted] = _map.insert(std::make_pair(Key(start, end), value));
- assert(was_inserted);
- }
- void add_mapping(IndirectRef addr) {
- uint32_t value = _map.size();
- uint32_t start = _labels.size();
- for (const auto *label: addr) {
- _labels.emplace_back(*label);
- }
- uint32_t end = _labels.size();
- auto [ignore, was_inserted] = _map.insert(std::make_pair(Key(start, end), value));
- assert(was_inserted);
- }
- size_t lookup(DirectStr addr) const {
- auto pos = _map.find(addr);
- return (pos == _map.end()) ? npos() : pos->second;
- }
- size_t lookup(DirectRef addr) const {
- auto pos = _map.find(addr);
- return (pos == _map.end()) ? npos() : pos->second;
- }
- size_t lookup(IndirectRef addr) const {
- auto pos = _map.find(addr);
- return (pos == _map.end()) ? npos() : pos->second;
- }
-};
-
-}
diff --git a/eval/src/vespa/eval/eval/simple_value.cpp b/eval/src/vespa/eval/eval/simple_value.cpp
index 84ba35404fd..cca4c6c7d51 100644
--- a/eval/src/vespa/eval/eval/simple_value.cpp
+++ b/eval/src/vespa/eval/eval/simple_value.cpp
@@ -30,22 +30,30 @@ struct CreateSimpleValueBuilderBase {
// look up a full address in the map directly
struct LookupView : public Value::Index::View {
- const SimpleSparseMap &index;
- size_t subspace;
+ using Labels = std::vector<vespalib::string>;
+ using Map = std::map<Labels, size_t>;
- LookupView(const SimpleSparseMap &index_in)
- : index(index_in), subspace(SimpleSparseMap::npos()) {}
+ const Map &map;
+ Labels my_addr;
+ Map::const_iterator pos;
+
+ LookupView(const Map &map_in, size_t num_dims)
+ : map(map_in), my_addr(num_dims, ""), pos(map.end()) {}
void lookup(ConstArrayRef<const vespalib::stringref*> addr) override {
- subspace = index.lookup(addr);
+ assert(addr.size() == my_addr.size());
+ for (size_t i = 0; i < my_addr.size(); ++i) {
+ my_addr[i] = *addr[i];
+ }
+ pos = map.find(my_addr);
}
bool next_result(ConstArrayRef<vespalib::stringref*>, size_t &idx_out) override {
- if (subspace == SimpleSparseMap::npos()) {
+ if (pos == map.end()) {
return false;
}
- idx_out = subspace;
- subspace = SimpleSparseMap::npos();
+ idx_out = pos->second;
+ pos = map.end();
return true;
}
};
@@ -55,28 +63,29 @@ struct LookupView : public Value::Index::View {
// find matching mappings for a partial address with brute force filtering
struct FilterView : public Value::Index::View {
- size_t num_mapped_dims;
- const std::vector<vespalib::string> &labels;
- std::vector<size_t> match_dims;
- std::vector<size_t> extract_dims;
- std::vector<vespalib::string> query;
- size_t pos;
+ using Labels = std::vector<vespalib::string>;
+ using Map = std::map<Labels, size_t>;
+
+ const Map &map;
+ std::vector<size_t> match_dims;
+ std::vector<size_t> extract_dims;
+ std::vector<vespalib::string> query;
+ Map::const_iterator pos;
bool is_match() const {
for (size_t i = 0; i < query.size(); ++i) {
- if (query[i] != labels[pos + match_dims[i]]) {
+ if (query[i] != pos->first[match_dims[i]]) {
return false;
}
}
return true;
}
- FilterView(const std::vector<vespalib::string> &labels_in, const std::vector<size_t> &match_dims_in, size_t num_mapped_dims_in)
- : num_mapped_dims(num_mapped_dims_in), labels(labels_in), match_dims(match_dims_in),
- extract_dims(), query(match_dims.size(), ""), pos(labels.size())
+ FilterView(const Map &map_in, const std::vector<size_t> &match_dims_in, size_t num_dims)
+ : map(map_in), match_dims(match_dims_in), extract_dims(), query(match_dims.size(), ""), pos(map.end())
{
auto my_pos = match_dims.begin();
- for (size_t i = 0; i < num_mapped_dims; ++i) {
+ for (size_t i = 0; i < num_dims; ++i) {
if ((my_pos == match_dims.end()) || (*my_pos != i)) {
extract_dims.push_back(i);
} else {
@@ -84,7 +93,7 @@ struct FilterView : public Value::Index::View {
}
}
assert(my_pos == match_dims.end());
- assert((match_dims.size() + extract_dims.size()) == num_mapped_dims);
+ assert((match_dims.size() + extract_dims.size()) == num_dims);
}
void lookup(ConstArrayRef<const vespalib::stringref*> addr) override {
@@ -92,21 +101,21 @@ struct FilterView : public Value::Index::View {
for (size_t i = 0; i < addr.size(); ++i) {
query[i] = *addr[i];
}
- pos = 0;
+ pos = map.begin();
}
bool next_result(ConstArrayRef<vespalib::stringref*> addr_out, size_t &idx_out) override {
- while (pos < labels.size()) {
+ while (pos != map.end()) {
if (is_match()) {
assert(addr_out.size() == extract_dims.size());
for (size_t i = 0; i < extract_dims.size(); ++i) {
- *addr_out[i] = labels[pos + extract_dims[i]];
+ *addr_out[i] = pos->first[extract_dims[i]];
}
- idx_out = (pos / num_mapped_dims); // is this expensive?
- pos += num_mapped_dims;
+ idx_out = pos->second;
+ ++pos;
return true;
}
- pos += num_mapped_dims;
+ ++pos;
}
return false;
}
@@ -117,27 +126,29 @@ struct FilterView : public Value::Index::View {
// iterate all mappings
struct IterateView : public Value::Index::View {
- size_t num_mapped_dims;
- const std::vector<vespalib::string> &labels;
- size_t pos;
+ using Labels = std::vector<vespalib::string>;
+ using Map = std::map<Labels, size_t>;
+
+ const Map &map;
+ Map::const_iterator pos;
- IterateView(const std::vector<vespalib::string> &labels_in, size_t num_mapped_dims_in)
- : num_mapped_dims(num_mapped_dims_in), labels(labels_in), pos(labels.size()) {}
+ IterateView(const Map &map_in)
+ : map(map_in), pos(map.end()) {}
void lookup(ConstArrayRef<const vespalib::stringref*>) override {
- pos = 0;
+ pos = map.begin();
}
bool next_result(ConstArrayRef<vespalib::stringref*> addr_out, size_t &idx_out) override {
- if (pos >= labels.size()) {
+ if (pos == map.end()) {
return false;
}
- assert(addr_out.size() == num_mapped_dims);
- for (size_t i = 0; i < num_mapped_dims; ++i) {
- *addr_out[i] = labels[pos + i];
+ assert(addr_out.size() == pos->first.size());
+ for (size_t i = 0; i < addr_out.size(); ++i) {
+ *addr_out[i] = pos->first[i];
}
- idx_out = (pos / num_mapped_dims); // is this expensive?
- pos += num_mapped_dims;
+ idx_out = pos->second;
+ ++pos;
return true;
}
};
@@ -148,11 +159,11 @@ struct IterateView : public Value::Index::View {
//-----------------------------------------------------------------------------
-SimpleValue::SimpleValue(const ValueType &type, size_t num_mapped_dims_in, size_t subspace_size_in, size_t expected_subspaces_in)
+SimpleValue::SimpleValue(const ValueType &type, size_t num_mapped_dims_in, size_t subspace_size_in)
: _type(type),
_num_mapped_dims(num_mapped_dims_in),
_subspace_size(subspace_size_in),
- _index(num_mapped_dims_in, expected_subspaces_in)
+ _index()
{
assert(_type.count_mapped_dimensions() == _num_mapped_dims);
assert(_type.dense_subspace_size() == _subspace_size);
@@ -160,17 +171,26 @@ SimpleValue::SimpleValue(const ValueType &type, size_t num_mapped_dims_in, size_
SimpleValue::~SimpleValue() = default;
+void
+SimpleValue::add_mapping(ConstArrayRef<vespalib::stringref> addr)
+{
+ Labels my_addr;
+ for(const auto &label: addr) {
+ my_addr.emplace_back(label);
+ }
+ auto [ignore, was_inserted] = _index.emplace(my_addr, _index.size());
+ assert(was_inserted);
+}
+
std::unique_ptr<Value::Index::View>
SimpleValue::create_view(const std::vector<size_t> &dims) const
{
- if (_num_mapped_dims == 0) {
- return TrivialIndex::get().create_view(dims);
- } else if (dims.empty()) {
- return std::make_unique<IterateView>(_index.labels(), _num_mapped_dims);
+ if (dims.empty()) {
+ return std::make_unique<IterateView>(_index);
} else if (dims.size() == _num_mapped_dims) {
- return std::make_unique<LookupView>(_index);
+ return std::make_unique<LookupView>(_index, _num_mapped_dims);
} else {
- return std::make_unique<FilterView>(_index.labels(), dims, _num_mapped_dims);
+ return std::make_unique<FilterView>(_index, dims, _num_mapped_dims);
}
}
@@ -178,7 +198,7 @@ SimpleValue::create_view(const std::vector<size_t> &dims) const
template <typename T>
SimpleValueT<T>::SimpleValueT(const ValueType &type, size_t num_mapped_dims_in, size_t subspace_size_in, size_t expected_subspaces_in)
- : SimpleValue(type, num_mapped_dims_in, subspace_size_in, expected_subspaces_in),
+ : SimpleValue(type, num_mapped_dims_in, subspace_size_in),
_cells()
{
_cells.reserve(subspace_size_in * expected_subspaces_in);
@@ -194,6 +214,7 @@ SimpleValueT<T>::add_subspace(ConstArrayRef<vespalib::stringref> addr)
size_t old_size = _cells.size();
add_mapping(addr);
_cells.resize(old_size + subspace_size());
+ assert(_cells.size() == (size() * subspace_size()));
return ArrayRef<T>(&_cells[old_size], subspace_size());
}
diff --git a/eval/src/vespa/eval/eval/simple_value.h b/eval/src/vespa/eval/eval/simple_value.h
index f2df087cf37..81f65eee061 100644
--- a/eval/src/vespa/eval/eval/simple_value.h
+++ b/eval/src/vespa/eval/eval/simple_value.h
@@ -3,7 +3,6 @@
#pragma once
#include "value.h"
-#include "simple_sparse_map.h"
#include <vespa/vespalib/stllike/string.h>
#include <vector>
#include <map>
@@ -12,27 +11,27 @@ namespace vespalib { class Stash; }
namespace vespalib::eval {
-class TensorSpec;
-
/**
* A simple implementation of a generic value that can also be used to
- * build new values. This class focuses on simplicity and is intended
- * as a reference implementation that can also be used to test the
- * correctness of tensor operations as they are moved away from the
- * implementation of individual tensor classes.
+ * build new values. This class focuses on simplicity over speed and
+ * is intended as a reference implementation that can also be used to
+ * test the correctness of tensor operations as they are moved away
+ * from the implementation of individual tensor classes.
**/
class SimpleValue : public Value, public Value::Index
{
private:
+ using Labels = std::vector<vespalib::string>;
+
ValueType _type;
size_t _num_mapped_dims;
size_t _subspace_size;
- SimpleSparseMap _index;
+ std::map<Labels,size_t> _index;
protected:
size_t subspace_size() const { return _subspace_size; }
- void add_mapping(ConstArrayRef<vespalib::stringref> addr) { _index.add_mapping(addr); }
+ void add_mapping(ConstArrayRef<vespalib::stringref> addr);
public:
- SimpleValue(const ValueType &type, size_t num_mapped_dims_in, size_t subspace_size_in, size_t expected_subspaces_in);
+ SimpleValue(const ValueType &type, size_t num_mapped_dims_in, size_t subspace_size_in);
~SimpleValue() override;
const ValueType &type() const override { return _type; }
const Value::Index &index() const override { return *this; }
diff --git a/eval/src/vespa/eval/eval/tensor_spec.cpp b/eval/src/vespa/eval/eval/tensor_spec.cpp
index d3aafc7632a..1a6a9520e58 100644
--- a/eval/src/vespa/eval/eval/tensor_spec.cpp
+++ b/eval/src/vespa/eval/eval/tensor_spec.cpp
@@ -46,9 +46,14 @@ TensorSpec & TensorSpec::operator = (const TensorSpec &) = default;
TensorSpec::~TensorSpec() { }
TensorSpec &
-TensorSpec::set(Address address, double value) {
- auto res = _cells.emplace(std::move(address), value);
- if (!res.second) { assert(res.first->second.value == value); }
+TensorSpec::add(Address address, double value) {
+ auto [iter, inserted] = _cells.emplace(std::move(address), value);
+ if (! inserted) {
+ // to simplify reference implementations, allow
+ // adding the same address several times to a Spec, but
+ // only with the same value every time:
+ assert(iter->second.value == value);
+ }
return *this;
}
diff --git a/eval/src/vespa/eval/eval/tensor_spec.h b/eval/src/vespa/eval/eval/tensor_spec.h
index 8a4343b3faa..8f02e56f860 100644
--- a/eval/src/vespa/eval/eval/tensor_spec.h
+++ b/eval/src/vespa/eval/eval/tensor_spec.h
@@ -68,14 +68,7 @@ public:
TensorSpec(const TensorSpec &);
TensorSpec & operator = (const TensorSpec &);
~TensorSpec();
- TensorSpec &set(Address address, double value);
- TensorSpec &add(Address address, double value) {
- auto res = _cells.emplace(std::move(address), value);
- if (!res.second) {
- res.first->second.value += value;
- }
- return *this;
- }
+ TensorSpec &add(Address address, double value);
const vespalib::string &type() const { return _type; }
const Cells &cells() const { return _cells; }
vespalib::string to_string() const;
diff --git a/eval/src/vespa/eval/eval/value_codec.h b/eval/src/vespa/eval/eval/value_codec.h
index 3644f952a6c..058b2d7bf4f 100644
--- a/eval/src/vespa/eval/eval/value_codec.h
+++ b/eval/src/vespa/eval/eval/value_codec.h
@@ -2,7 +2,8 @@
#pragma once
-#include "simple_value.h"
+#include "value.h"
+#include "tensor_spec.h"
#include <vespa/vespalib/stllike/string.h>
namespace vespalib { class nbostream; }
diff --git a/eval/src/vespa/eval/instruction/generic_concat.cpp b/eval/src/vespa/eval/instruction/generic_concat.cpp
index e3b3a3f0331..7c55afafcc1 100644
--- a/eval/src/vespa/eval/instruction/generic_concat.cpp
+++ b/eval/src/vespa/eval/instruction/generic_concat.cpp
@@ -3,6 +3,7 @@
#include "generic_concat.h"
#include "generic_join.h"
#include <vespa/eval/eval/value.h>
+#include <vespa/eval/tensor/dense/dense_tensor_view.h>
#include <vespa/vespalib/util/overload.h>
#include <vespa/vespalib/util/stash.h>
#include <vespa/vespalib/util/typify.h>
@@ -44,20 +45,19 @@ struct ConcatParam
}
};
-template <typename LCT, typename RCT>
+template <typename LCT, typename RCT, typename OCT>
std::unique_ptr<Value>
generic_concat(const Value &a, const Value &b,
const SparseJoinPlan &sparse_plan,
const DenseConcatPlan &dense_plan,
const ValueType &res_type, const ValueBuilderFactory &factory)
{
- using OCT = typename eval::UnifyCellTypes<LCT, RCT>::type;
auto a_cells = a.cells().typify<LCT>();
auto b_cells = b.cells().typify<RCT>();
SparseJoinState sparse(sparse_plan, a.index(), b.index());
auto builder = factory.create_value_builder<OCT>(res_type,
sparse_plan.sources.size(),
- dense_plan.right.output_size,
+ dense_plan.output_size,
sparse.first_index.size());
auto outer = sparse.first_index.create_view({});
auto inner = sparse.second_index.create_view(sparse.second_view_dims);
@@ -81,29 +81,59 @@ generic_concat(const Value &a, const Value &b,
return builder->build(std::move(builder));
}
-template <typename LCT, typename RCT>
+template <typename LCT, typename RCT, typename OCT>
void my_generic_concat_op(State &state, uint64_t param_in) {
const auto &param = unwrap_param<ConcatParam>(param_in);
const Value &lhs = state.peek(1);
const Value &rhs = state.peek(0);
- auto res_value = generic_concat<LCT, RCT>(lhs, rhs, param.sparse_plan, param.dense_plan,
- param.res_type, param.factory);
+ auto res_value = generic_concat<LCT, RCT, OCT>(
+ lhs, rhs,
+ param.sparse_plan, param.dense_plan,
+ param.res_type, param.factory);
auto &result = state.stash.create<std::unique_ptr<Value>>(std::move(res_value));
const Value &result_ref = *(result.get());
state.pop_pop_push(result_ref);
}
+template <typename LCT, typename RCT, typename OCT>
+void my_dense_simple_concat_op(State &state, uint64_t param_in) {
+ const auto &param = unwrap_param<ConcatParam>(param_in);
+ const Value &lhs = state.peek(1);
+ const Value &rhs = state.peek(0);
+ const auto a = lhs.cells().typify<LCT>();
+ const auto b = rhs.cells().typify<RCT>();
+ ArrayRef<OCT> result = state.stash.create_array<OCT>(a.size() + b.size());
+ auto pos = result.begin();
+ for (size_t i = 0; i < a.size(); ++i) {
+ *pos++ = a[i];
+ }
+ for (size_t i = 0; i < b.size(); ++i) {
+ *pos++ = b[i];
+ }
+ Value &ref = state.stash.create<tensor::DenseTensorView>(param.res_type, TypedCells(result));
+ state.pop_pop_push(ref);
+}
+
struct SelectGenericConcatOp {
- template <typename LCT, typename RCT> static auto invoke() {
- return my_generic_concat_op<LCT, RCT>;
+ template <typename LCT, typename RCT, typename OCT> static auto invoke(const ConcatParam &param) {
+ if (param.sparse_plan.sources.empty() && param.res_type.is_dense()) {
+ auto & dp = param.dense_plan;
+ if ((dp.output_size == (dp.left.input_size + dp.right.input_size))
+ && (dp.right_offset == dp.left.input_size))
+ {
+ return my_dense_simple_concat_op<LCT, RCT, OCT>;
+ }
+ }
+ return my_generic_concat_op<LCT, RCT, OCT>;
}
};
-enum class Case { NONE, OUT, BOTH };
+enum class Case { NONE, OUT, CONCAT, BOTH };
} // namespace <unnamed>
-DenseConcatPlan::InOutLoop::InOutLoop(const ValueType &in_type,
+std::pair<size_t, size_t>
+DenseConcatPlan::InOutLoop::fill_from(const ValueType &in_type,
std::string concat_dimension,
const ValueType &out_type)
{
@@ -126,19 +156,21 @@ DenseConcatPlan::InOutLoop::InOutLoop(const ValueType &in_type,
{
[&](visit_ranges_first, const auto &) { abort(); },
[&](visit_ranges_second, const auto &b) {
- if (b.name == concat_dimension) { update_plan(Case::OUT, 1, b.size, 0, 1);
+ if (b.name == concat_dimension) { update_plan(Case::CONCAT, 1, b.size, 0, 1);
} else { update_plan(Case::OUT, b.size, b.size, 0, 1); }
},
- [&](visit_ranges_both, const auto &a, const auto &b) { update_plan(Case::BOTH, a.size, b.size, 1, 1); }
+ [&](visit_ranges_both, const auto &a, const auto &b) {
+ if (b.name == concat_dimension) { update_plan(Case::CONCAT, a.size, b.size, 1, 1);
+ } else { update_plan(Case::BOTH, a.size, b.size, 1, 1); }
+ }
};
-
const auto input_dimensions = in_type.nontrivial_indexed_dimensions();
const auto output_dimensions = out_type.nontrivial_indexed_dimensions();
visit_ranges(visitor, input_dimensions.begin(), input_dimensions.end(), output_dimensions.begin(), output_dimensions.end(),
[](const auto &a, const auto &b){ return (a.name < b.name); });
-
input_size = 1;
- output_size = 1;
+ size_t output_size = 1;
+ size_t offset_for_concat = 0;
for (size_t i = in_loop_cnt.size(); i-- > 0; ) {
if (in_stride[i] != 0) {
in_stride[i] = input_size;
@@ -148,7 +180,14 @@ DenseConcatPlan::InOutLoop::InOutLoop(const ValueType &in_type,
assert(out_loop_cnt[i] != 0);
out_stride[i] = output_size;
output_size *= out_loop_cnt[i];
+ // loop counts are different if and only if this is the concat dimension
+ if (in_loop_cnt[i] != out_loop_cnt[i]) {
+ assert(offset_for_concat == 0);
+ offset_for_concat = in_loop_cnt[i] * out_stride[i];
+ }
}
+ assert(offset_for_concat != 0);
+ return std::make_pair(offset_for_concat, output_size);
}
InterpretedFunction::Instruction
@@ -157,8 +196,9 @@ GenericConcat::make_instruction(const ValueType &lhs_type, const ValueType &rhs_
const ValueBuilderFactory &factory, Stash &stash)
{
auto &param = stash.create<ConcatParam>(lhs_type, rhs_type, dimension, factory);
- auto fun = typify_invoke<2,TypifyCellType,SelectGenericConcatOp>(
- lhs_type.cell_type(), rhs_type.cell_type());
+ auto fun = typify_invoke<3,TypifyCellType,SelectGenericConcatOp>(
+ lhs_type.cell_type(), rhs_type.cell_type(), param.res_type.cell_type(),
+ param);
return Instruction(fun, wrap_param<ConcatParam>(param));
}
@@ -166,18 +206,11 @@ DenseConcatPlan::DenseConcatPlan(const ValueType &lhs_type,
const ValueType &rhs_type,
std::string concat_dimension,
const ValueType &out_type)
- : right_offset(0),
- left(lhs_type, concat_dimension, out_type),
- right(rhs_type, concat_dimension, out_type)
{
- const auto output_dimensions = out_type.nontrivial_indexed_dimensions();
- for (size_t i = 0; i < output_dimensions.size(); ++i) {
- if (output_dimensions[i].name == concat_dimension) {
- right_offset = left.in_loop_cnt[i] * left.out_stride[i];
- }
- }
- assert(right_offset > 0);
- assert(left.output_size == right.output_size);
+ std::tie(right_offset, output_size) = left.fill_from(lhs_type, concat_dimension, out_type);
+ auto [ other_offset, other_size ] = right.fill_from(rhs_type, concat_dimension, out_type);
+ assert(other_offset > 0);
+ assert(output_size == other_size);
}
DenseConcatPlan::~DenseConcatPlan() = default;
diff --git a/eval/src/vespa/eval/instruction/generic_concat.h b/eval/src/vespa/eval/instruction/generic_concat.h
index c2636fb7678..5578c5a0dca 100644
--- a/eval/src/vespa/eval/instruction/generic_concat.h
+++ b/eval/src/vespa/eval/instruction/generic_concat.h
@@ -21,18 +21,19 @@ struct GenericConcat {
struct DenseConcatPlan {
size_t right_offset;
+ size_t output_size;
struct InOutLoop {
size_t input_size;
- size_t output_size;
std::vector<size_t> in_loop_cnt;
std::vector<size_t> in_stride;
std::vector<size_t> out_stride;
+ // returns computed concat offset and output size
+ std::pair<size_t, size_t> fill_from(const ValueType &in_type,
+ std::string concat_dimension,
+ const ValueType &out_type);
template <typename F> void execute(size_t in_off, size_t out_off, const F &f) const {
run_nested_loop(in_off, out_off, in_loop_cnt, in_stride, out_stride, f);
}
- InOutLoop(const ValueType &in_type,
- std::string concat_dimension,
- const ValueType &out_type);
~InOutLoop();
};
InOutLoop left;
diff --git a/eval/src/vespa/eval/instruction/generic_join.cpp b/eval/src/vespa/eval/instruction/generic_join.cpp
index 53324924bdd..4e9dd8ded35 100644
--- a/eval/src/vespa/eval/instruction/generic_join.cpp
+++ b/eval/src/vespa/eval/instruction/generic_join.cpp
@@ -2,14 +2,17 @@
#include "generic_join.h"
#include <vespa/eval/eval/inline_operation.h>
+#include <vespa/eval/eval/fast_value.hpp>
#include <vespa/vespalib/util/overload.h>
#include <vespa/vespalib/util/stash.h>
#include <vespa/vespalib/util/typify.h>
#include <vespa/vespalib/util/visit_ranges.h>
+#include <typeindex>
#include <cassert>
namespace vespalib::eval::instruction {
+using operation::SwapArgs2;
using State = InterpretedFunction::State;
using Instruction = InterpretedFunction::Instruction;
@@ -29,48 +32,70 @@ template <typename T> const T &unwrap_param(uint64_t param) {
//-----------------------------------------------------------------------------
-struct JoinParam {
- ValueType res_type;
- SparseJoinPlan sparse_plan;
- DenseJoinPlan dense_plan;
- join_fun_t function;
- const ValueBuilderFactory &factory;
- JoinParam(const ValueType &lhs_type, const ValueType &rhs_type,
- join_fun_t function_in, const ValueBuilderFactory &factory_in)
- : res_type(ValueType::join(lhs_type, rhs_type)),
- sparse_plan(lhs_type, rhs_type),
- dense_plan(lhs_type, rhs_type),
- function(function_in),
- factory(factory_in)
- {
- assert(!res_type.is_error());
+template <typename LCT, typename RCT, typename OCT, typename Fun>
+void my_mixed_join_op(State &state, uint64_t param_in) {
+ const auto &param = unwrap_param<JoinParam>(param_in);
+ Fun fun(param.function);
+ auto dense_join = [&](const LCT *my_lhs, const RCT *my_rhs, OCT *my_res)
+ {
+ param.dense_plan.execute(0, 0, [&](size_t lhs_idx, size_t rhs_idx) {
+ *my_res++ = fun(my_lhs[lhs_idx], my_rhs[rhs_idx]);
+ });
+ };
+ const Value &lhs = state.peek(1);
+ const Value &rhs = state.peek(0);
+ auto lhs_cells = lhs.cells().typify<LCT>();
+ auto rhs_cells = rhs.cells().typify<RCT>();
+ SparseJoinState sparse(param.sparse_plan, lhs.index(), rhs.index());
+ auto builder = param.factory.create_value_builder<OCT>(param.res_type, param.sparse_plan.sources.size(), param.dense_plan.out_size, sparse.first_index.size());
+ auto outer = sparse.first_index.create_view({});
+ auto inner = sparse.second_index.create_view(sparse.second_view_dims);
+ outer->lookup({});
+ while (outer->next_result(sparse.first_address, sparse.first_subspace)) {
+ inner->lookup(sparse.address_overlap);
+ while (inner->next_result(sparse.second_only_address, sparse.second_subspace)) {
+ dense_join(lhs_cells.begin() + param.dense_plan.lhs_size * sparse.lhs_subspace,
+ rhs_cells.begin() + param.dense_plan.rhs_size * sparse.rhs_subspace,
+ builder->add_subspace(sparse.full_address).begin());
+ }
}
- ~JoinParam();
+ auto &result = state.stash.create<std::unique_ptr<Value>>(builder->build(std::move(builder)));
+ const Value &result_ref = *(result.get());
+ state.pop_pop_push(result_ref);
};
-JoinParam::~JoinParam() = default;
//-----------------------------------------------------------------------------
-
template <typename LCT, typename RCT, typename OCT, typename Fun>
-void my_mixed_join_op(State &state, uint64_t param_in) {
+void my_sparse_full_overlap_join_op(State &state, uint64_t param_in) {
const auto &param = unwrap_param<JoinParam>(param_in);
- Fun fun(param.function);
const Value &lhs = state.peek(1);
const Value &rhs = state.peek(0);
auto lhs_cells = lhs.cells().typify<LCT>();
auto rhs_cells = rhs.cells().typify<RCT>();
- SparseJoinState sparse(param.sparse_plan, lhs.index(), rhs.index());
+ const Value::Index &lhs_index = lhs.index();
+ const Value::Index &rhs_index = rhs.index();
+ if ((std::type_index(typeid(lhs_index)) == std::type_index(typeid(FastValueIndex))) &&
+ (std::type_index(typeid(rhs_index)) == std::type_index(typeid(FastValueIndex))))
+ {
+ const FastValueIndex &lhs_fast = static_cast<const FastValueIndex&>(lhs_index);
+ const FastValueIndex &rhs_fast = static_cast<const FastValueIndex&>(rhs_index);
+ return (rhs_fast.map.size() < lhs_fast.map.size())
+ ? state.pop_pop_push(FastValueIndex::sparse_full_overlap_join<RCT,LCT,OCT,SwapArgs2<Fun>>
+ (param.res_type, SwapArgs2<Fun>(param.function), rhs_fast, lhs_fast, rhs_cells, lhs_cells, state.stash))
+ : state.pop_pop_push(FastValueIndex::sparse_full_overlap_join<LCT,RCT,OCT,Fun>
+ (param.res_type, Fun(param.function), lhs_fast, rhs_fast, lhs_cells, rhs_cells, state.stash));
+ }
+ Fun fun(param.function);
+ SparseJoinState sparse(param.sparse_plan, lhs_index, rhs_index);
auto builder = param.factory.create_value_builder<OCT>(param.res_type, param.sparse_plan.sources.size(), param.dense_plan.out_size, sparse.first_index.size());
auto outer = sparse.first_index.create_view({});
auto inner = sparse.second_index.create_view(sparse.second_view_dims);
outer->lookup({});
while (outer->next_result(sparse.first_address, sparse.first_subspace)) {
inner->lookup(sparse.address_overlap);
- while (inner->next_result(sparse.second_only_address, sparse.second_subspace)) {
- OCT *dst = builder->add_subspace(sparse.full_address).begin();
- auto join_cells = [&](size_t lhs_idx, size_t rhs_idx) { *dst++ = fun(lhs_cells[lhs_idx], rhs_cells[rhs_idx]); };
- param.dense_plan.execute(param.dense_plan.lhs_size * sparse.lhs_subspace, param.dense_plan.rhs_size * sparse.rhs_subspace, join_cells);
+ if (inner->next_result(sparse.second_only_address, sparse.second_subspace)) {
+ builder->add_subspace(sparse.full_address)[0] = fun(lhs_cells[sparse.lhs_subspace], rhs_cells[sparse.rhs_subspace]);
}
}
auto &result = state.stash.create<std::unique_ptr<Value>>(builder->build(std::move(builder)));
@@ -78,6 +103,8 @@ void my_mixed_join_op(State &state, uint64_t param_in) {
state.pop_pop_push(result_ref);
};
+//-----------------------------------------------------------------------------
+
template <typename LCT, typename RCT, typename OCT, typename Fun>
void my_dense_join_op(State &state, uint64_t param_in) {
const auto &param = unwrap_param<JoinParam>(param_in);
@@ -91,6 +118,8 @@ void my_dense_join_op(State &state, uint64_t param_in) {
state.pop_pop_push(state.stash.create<DenseValueView>(param.res_type, TypedCells(out_cells)));
};
+//-----------------------------------------------------------------------------
+
template <typename Fun>
void my_double_join_op(State &state, uint64_t param_in) {
Fun fun(unwrap_param<JoinParam>(param_in).function);
@@ -98,6 +127,8 @@ void my_double_join_op(State &state, uint64_t param_in) {
state.peek(0).cells().typify<double>()[0])));
};
+//-----------------------------------------------------------------------------
+
struct SelectGenericJoinOp {
template <typename LCT, typename RCT, typename OCT, typename Fun> static auto invoke(const JoinParam &param) {
if (param.res_type.is_double()) {
@@ -110,6 +141,11 @@ struct SelectGenericJoinOp {
if (param.sparse_plan.sources.empty()) {
return my_dense_join_op<LCT,RCT,OCT,Fun>;
}
+ if ((param.dense_plan.out_size == 1) &&
+ (param.sparse_plan.sources.size() == param.sparse_plan.lhs_overlap.size()))
+ {
+ return my_sparse_full_overlap_join_op<LCT,RCT,OCT,Fun>;
+ }
return my_mixed_join_op<LCT,RCT,OCT,Fun>;
}
};
@@ -221,6 +257,10 @@ SparseJoinState::~SparseJoinState() = default;
//-----------------------------------------------------------------------------
+JoinParam::~JoinParam() = default;
+
+//-----------------------------------------------------------------------------
+
using JoinTypify = TypifyValue<TypifyCellType,operation::TypifyOp2>;
Instruction
diff --git a/eval/src/vespa/eval/instruction/generic_join.h b/eval/src/vespa/eval/instruction/generic_join.h
index 30e78b52510..8e878fc759f 100644
--- a/eval/src/vespa/eval/instruction/generic_join.h
+++ b/eval/src/vespa/eval/instruction/generic_join.h
@@ -79,6 +79,28 @@ struct SparseJoinState {
~SparseJoinState();
};
+/**
+ * Full set of parameters passed to low-level generic join function
+ **/
+struct JoinParam {
+ ValueType res_type;
+ SparseJoinPlan sparse_plan;
+ DenseJoinPlan dense_plan;
+ join_fun_t function;
+ const ValueBuilderFactory &factory;
+ JoinParam(const ValueType &lhs_type, const ValueType &rhs_type,
+ join_fun_t function_in, const ValueBuilderFactory &factory_in)
+ : res_type(ValueType::join(lhs_type, rhs_type)),
+ sparse_plan(lhs_type, rhs_type),
+ dense_plan(lhs_type, rhs_type),
+ function(function_in),
+ factory(factory_in)
+ {
+ assert(!res_type.is_error());
+ }
+ ~JoinParam();
+};
+
//-----------------------------------------------------------------------------
} // namespace
diff --git a/eval/src/vespa/eval/tensor/CMakeLists.txt b/eval/src/vespa/eval/tensor/CMakeLists.txt
index 79f6f7e2a4f..b75b34098f5 100644
--- a/eval/src/vespa/eval/tensor/CMakeLists.txt
+++ b/eval/src/vespa/eval/tensor/CMakeLists.txt
@@ -3,6 +3,7 @@ vespa_add_library(eval_tensor OBJECT
SOURCES
default_tensor_engine.cpp
default_value_builder_factory.cpp
+ partial_update.cpp
tensor.cpp
tensor_address.cpp
wrapped_simple_tensor.cpp
diff --git a/eval/src/vespa/eval/tensor/default_tensor_engine.cpp b/eval/src/vespa/eval/tensor/default_tensor_engine.cpp
index 7d4bff21380..11c1ce74eca 100644
--- a/eval/src/vespa/eval/tensor/default_tensor_engine.cpp
+++ b/eval/src/vespa/eval/tensor/default_tensor_engine.cpp
@@ -445,8 +445,7 @@ struct CallAppendVector {
template <typename OCT>
void append_vector(OCT *&pos, const Value &value) {
if (auto tensor = value.as_tensor()) {
- const DenseTensorView *view = static_cast<const DenseTensorView *>(tensor);
- dispatch_1<CallAppendVector<OCT> >(view->cellsRef(), pos);
+ dispatch_1<CallAppendVector<OCT> >(tensor->cells(), pos);
} else {
*pos++ = value.as_double();
}
diff --git a/eval/src/vespa/eval/tensor/dense/dense_cell_range_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_cell_range_function.cpp
index 84da53c8488..988116f53a6 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_cell_range_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_cell_range_function.cpp
@@ -18,7 +18,7 @@ namespace {
template <typename CT>
void my_cell_range_op(eval::InterpretedFunction::State &state, uint64_t param) {
const auto *self = (const DenseCellRangeFunction *)(param);
- auto old_cells = DenseTensorView::typify_cells<CT>(state.peek(0));
+ auto old_cells = state.peek(0).cells().typify<CT>();
ConstArrayRef<CT> new_cells(&old_cells[self->offset()], self->length());
state.pop_push(state.stash.create<DenseTensorView>(self->result_type(), TypedCells(new_cells)));
}
diff --git a/eval/src/vespa/eval/tensor/dense/dense_dot_product_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_dot_product_function.cpp
index 9e30451cd67..09530beb0b1 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_dot_product_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_dot_product_function.cpp
@@ -21,8 +21,8 @@ namespace {
template <typename LCT, typename RCT>
void my_dot_product_op(eval::InterpretedFunction::State &state, uint64_t) {
- auto lhs_cells = DenseTensorView::typify_cells<LCT>(state.peek(1));
- auto rhs_cells = DenseTensorView::typify_cells<RCT>(state.peek(0));
+ auto lhs_cells = state.peek(1).cells().typify<LCT>();
+ auto rhs_cells = state.peek(0).cells().typify<RCT>();
double result = 0.0;
const LCT *lhs = lhs_cells.cbegin();
const RCT *rhs = rhs_cells.cbegin();
@@ -33,15 +33,15 @@ void my_dot_product_op(eval::InterpretedFunction::State &state, uint64_t) {
}
void my_cblas_double_dot_product_op(eval::InterpretedFunction::State &state, uint64_t) {
- auto lhs_cells = DenseTensorView::typify_cells<double>(state.peek(1));
- auto rhs_cells = DenseTensorView::typify_cells<double>(state.peek(0));
+ auto lhs_cells = state.peek(1).cells().typify<double>();
+ auto rhs_cells = state.peek(0).cells().typify<double>();
double result = cblas_ddot(lhs_cells.size(), lhs_cells.cbegin(), 1, rhs_cells.cbegin(), 1);
state.pop_pop_push(state.stash.create<eval::DoubleValue>(result));
}
void my_cblas_float_dot_product_op(eval::InterpretedFunction::State &state, uint64_t) {
- auto lhs_cells = DenseTensorView::typify_cells<float>(state.peek(1));
- auto rhs_cells = DenseTensorView::typify_cells<float>(state.peek(0));
+ auto lhs_cells = state.peek(1).cells().typify<float>();
+ auto rhs_cells = state.peek(0).cells().typify<float>();
double result = cblas_sdot(lhs_cells.size(), lhs_cells.cbegin(), 1, rhs_cells.cbegin(), 1);
state.pop_pop_push(state.stash.create<eval::DoubleValue>(result));
}
diff --git a/eval/src/vespa/eval/tensor/dense/dense_generic_join.hpp b/eval/src/vespa/eval/tensor/dense/dense_generic_join.hpp
index cdc89b30fff..033ea3631be 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_generic_join.hpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_generic_join.hpp
@@ -53,14 +53,10 @@ template <typename Function>
std::unique_ptr<Tensor>
generic_join(const DenseTensorView &lhs, const Tensor &rhs, Function &&func)
{
- const DenseTensorView *view = dynamic_cast<const DenseTensorView *>(&rhs);
- if (view) {
- DenseDimensionCombiner combiner(lhs.fast_type(), view->fast_type());
- TypedCells lhsCells = lhs.cellsRef();
- TypedCells rhsCells = view->cellsRef();
- return dispatch_2<CallGenericJoin>(lhsCells, rhsCells, combiner, std::move(func));
- }
- return Tensor::UP();
+ DenseDimensionCombiner combiner(lhs.fast_type(), rhs.type());
+ TypedCells lhsCells = lhs.cells();
+ TypedCells rhsCells = rhs.cells();
+ return dispatch_2<CallGenericJoin>(lhsCells, rhsCells, combiner, std::move(func));
}
}
diff --git a/eval/src/vespa/eval/tensor/dense/dense_lambda_peek_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_lambda_peek_function.cpp
index 70bdc8ae7d6..95cc702f85f 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_lambda_peek_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_lambda_peek_function.cpp
@@ -34,7 +34,7 @@ template <typename DST_CT, typename SRC_CT>
void my_lambda_peek_op(InterpretedFunction::State &state, uint64_t param) {
const auto *self = (const Self *)(param);
const std::vector<uint32_t> &lookup_table = self->table_token->get();
- auto src_cells = DenseTensorView::typify_cells<SRC_CT>(state.peek(0));
+ auto src_cells = state.peek(0).cells().typify<SRC_CT>();
ArrayRef<DST_CT> dst_cells = state.stash.create_array<DST_CT>(lookup_table.size());
DST_CT *dst = &dst_cells[0];
for (uint32_t idx: lookup_table) {
diff --git a/eval/src/vespa/eval/tensor/dense/dense_matmul_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_matmul_function.cpp
index 9c18cf285d4..2973e190f79 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_matmul_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_matmul_function.cpp
@@ -36,8 +36,8 @@ template <typename LCT, typename RCT, bool lhs_common_inner, bool rhs_common_inn
void my_matmul_op(eval::InterpretedFunction::State &state, uint64_t param) {
const DenseMatMulFunction::Self &self = *((const DenseMatMulFunction::Self *)(param));
using OCT = typename eval::UnifyCellTypes<LCT,RCT>::type;
- auto lhs_cells = DenseTensorView::typify_cells<LCT>(state.peek(1));
- auto rhs_cells = DenseTensorView::typify_cells<RCT>(state.peek(0));
+ auto lhs_cells = state.peek(1).cells().typify<LCT>();
+ auto rhs_cells = state.peek(0).cells().typify<RCT>();
auto dst_cells = state.stash.create_array<OCT>(self.lhs_size * self.rhs_size);
OCT *dst = dst_cells.begin();
const LCT *lhs = lhs_cells.cbegin();
@@ -55,8 +55,8 @@ void my_matmul_op(eval::InterpretedFunction::State &state, uint64_t param) {
template <bool lhs_common_inner, bool rhs_common_inner>
void my_cblas_double_matmul_op(eval::InterpretedFunction::State &state, uint64_t param) {
const DenseMatMulFunction::Self &self = *((const DenseMatMulFunction::Self *)(param));
- auto lhs_cells = DenseTensorView::typify_cells<double>(state.peek(1));
- auto rhs_cells = DenseTensorView::typify_cells<double>(state.peek(0));
+ auto lhs_cells = state.peek(1).cells().typify<double>();
+ auto rhs_cells = state.peek(0).cells().typify<double>();
auto dst_cells = state.stash.create_array<double>(self.lhs_size * self.rhs_size);
cblas_dgemm(CblasRowMajor, lhs_common_inner ? CblasNoTrans : CblasTrans, rhs_common_inner ? CblasTrans : CblasNoTrans,
self.lhs_size, self.rhs_size, self.common_size, 1.0,
@@ -69,8 +69,8 @@ void my_cblas_double_matmul_op(eval::InterpretedFunction::State &state, uint64_t
template <bool lhs_common_inner, bool rhs_common_inner>
void my_cblas_float_matmul_op(eval::InterpretedFunction::State &state, uint64_t param) {
const DenseMatMulFunction::Self &self = *((const DenseMatMulFunction::Self *)(param));
- auto lhs_cells = DenseTensorView::typify_cells<float>(state.peek(1));
- auto rhs_cells = DenseTensorView::typify_cells<float>(state.peek(0));
+ auto lhs_cells = state.peek(1).cells().typify<float>();
+ auto rhs_cells = state.peek(0).cells().typify<float>();
auto dst_cells = state.stash.create_array<float>(self.lhs_size * self.rhs_size);
cblas_sgemm(CblasRowMajor, lhs_common_inner ? CblasNoTrans : CblasTrans, rhs_common_inner ? CblasTrans : CblasNoTrans,
self.lhs_size, self.rhs_size, self.common_size, 1.0,
diff --git a/eval/src/vespa/eval/tensor/dense/dense_multi_matmul_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_multi_matmul_function.cpp
index b8832305640..5b4bcd9e23e 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_multi_matmul_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_multi_matmul_function.cpp
@@ -32,8 +32,8 @@ void my_cblas_double_multi_matmul_op(InterpretedFunction::State &state, uint64_t
size_t rhs_block_size = self.rhs_size() * self.common_size();
size_t dst_block_size = self.lhs_size() * self.rhs_size();
size_t num_blocks = self.matmul_cnt();
- const CT *lhs = DenseTensorView::typify_cells<CT>(state.peek(1)).cbegin();
- const CT *rhs = DenseTensorView::typify_cells<CT>(state.peek(0)).cbegin();
+ const CT *lhs = state.peek(1).cells().typify<CT>().cbegin();
+ const CT *rhs = state.peek(0).cells().typify<CT>().cbegin();
auto dst_cells = state.stash.create_array<CT>(dst_block_size * num_blocks);
CT *dst = dst_cells.begin();
for (size_t i = 0; i < num_blocks; ++i, lhs += lhs_block_size, rhs += rhs_block_size, dst += dst_block_size) {
@@ -53,8 +53,8 @@ void my_cblas_float_multi_matmul_op(InterpretedFunction::State &state, uint64_t
size_t rhs_block_size = self.rhs_size() * self.common_size();
size_t dst_block_size = self.lhs_size() * self.rhs_size();
size_t num_blocks = self.matmul_cnt();
- const CT *lhs = DenseTensorView::typify_cells<CT>(state.peek(1)).cbegin();
- const CT *rhs = DenseTensorView::typify_cells<CT>(state.peek(0)).cbegin();
+ const CT *lhs = state.peek(1).cells().typify<CT>().cbegin();
+ const CT *rhs = state.peek(0).cells().typify<CT>().cbegin();
auto dst_cells = state.stash.create_array<CT>(dst_block_size * num_blocks);
CT *dst = dst_cells.begin();
for (size_t i = 0; i < num_blocks; ++i, lhs += lhs_block_size, rhs += rhs_block_size, dst += dst_block_size) {
diff --git a/eval/src/vespa/eval/tensor/dense/dense_number_join_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_number_join_function.cpp
index 925627c5684..c6636a6a583 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_number_join_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_number_join_function.cpp
@@ -44,7 +44,7 @@ void my_number_join_op(State &state, uint64_t param) {
OP my_op((join_fun_t)param);
const Value &tensor = state.peek(swap ? 0 : 1);
CT number = state.peek(swap ? 1 : 0).as_double();
- auto src_cells = DenseTensorView::typify_cells<CT>(tensor);
+ auto src_cells = tensor.cells().typify<CT>();
auto dst_cells = make_dst_cells<CT, inplace>(src_cells, state.stash);
apply_op2_vec_num(dst_cells.begin(), src_cells.begin(), number, dst_cells.size(), my_op);
if (inplace) {
diff --git a/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.cpp
index e2dc2241555..6e4756dbe3c 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_replace_type_function.cpp
@@ -15,14 +15,9 @@ using namespace eval::tensor_function;
namespace {
-TypedCells getCellsRef(const eval::Value &value) {
- const DenseTensorView &denseTensor = static_cast<const DenseTensorView &>(value);
- return denseTensor.cellsRef();
-}
-
void my_replace_type_op(eval::InterpretedFunction::State &state, uint64_t param) {
const ValueType *type = (const ValueType *)(param);
- TypedCells cells = getCellsRef(state.peek(0));
+ TypedCells cells = state.peek(0).cells();
state.pop_push(state.stash.create<DenseTensorView>(*type, cells));
}
diff --git a/eval/src/vespa/eval/tensor/dense/dense_simple_expand_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_simple_expand_function.cpp
index e57cfd25325..5105ebab4ff 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_simple_expand_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_simple_expand_function.cpp
@@ -48,8 +48,8 @@ void my_simple_expand_op(State &state, uint64_t param) {
using OP = typename std::conditional<rhs_inner,SwapArgs2<Fun>,Fun>::type;
const ExpandParams &params = *(ExpandParams*)param;
OP my_op(params.function);
- auto inner_cells = DenseTensorView::typify_cells<ICT>(state.peek(rhs_inner ? 0 : 1));
- auto outer_cells = DenseTensorView::typify_cells<OCT>(state.peek(rhs_inner ? 1 : 0));
+ auto inner_cells = state.peek(rhs_inner ? 0 : 1).cells().typify<ICT>();
+ auto outer_cells = state.peek(rhs_inner ? 1 : 0).cells().typify<OCT>();
auto dst_cells = state.stash.create_array<DCT>(params.result_size);
DCT *dst = dst_cells.begin();
for (OCT outer_cell: outer_cells) {
diff --git a/eval/src/vespa/eval/tensor/dense/dense_simple_join_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_simple_join_function.cpp
index 05de3d07c96..f6c072708cb 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_simple_join_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_simple_join_function.cpp
@@ -70,8 +70,8 @@ void my_simple_join_op(State &state, uint64_t param) {
using OP = typename std::conditional<swap,SwapArgs2<Fun>,Fun>::type;
const JoinParams &params = *(JoinParams*)param;
OP my_op(params.function);
- auto pri_cells = DenseTensorView::typify_cells<PCT>(state.peek(swap ? 0 : 1));
- auto sec_cells = DenseTensorView::typify_cells<SCT>(state.peek(swap ? 1 : 0));
+ auto pri_cells = state.peek(swap ? 0 : 1).cells().typify<PCT>();
+ auto sec_cells = state.peek(swap ? 1 : 0).cells().typify<SCT>();
auto dst_cells = make_dst_cells<OCT, pri_mut>(pri_cells, state.stash);
if (overlap == Overlap::FULL) {
apply_op2_vec_vec(dst_cells.begin(), pri_cells.begin(), sec_cells.begin(), dst_cells.size(), my_op);
diff --git a/eval/src/vespa/eval/tensor/dense/dense_simple_map_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_simple_map_function.cpp
index b5f46fca70c..da9b681019e 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_simple_map_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_simple_map_function.cpp
@@ -40,7 +40,7 @@ template <typename CT, typename Fun, bool inplace>
void my_simple_map_op(State &state, uint64_t param) {
Fun my_fun((map_fun_t)param);
auto const &child = state.peek(0);
- auto src_cells = DenseTensorView::typify_cells<CT>(child);
+ auto src_cells = child.cells().typify<CT>();
auto dst_cells = make_dst_cells<CT, inplace>(src_cells, state.stash);
apply_op1_vec(dst_cells.begin(), src_cells.begin(), dst_cells.size(), my_fun);
if (!inplace) {
diff --git a/eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.cpp
index 571bcb79c9f..0ae40c8dac6 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_single_reduce_function.cpp
@@ -55,7 +55,7 @@ CT reduce_cells(const CT *src, size_t dim_size, size_t stride, AGGR &aggr) {
template <typename CT, typename AGGR>
void my_single_reduce_op(InterpretedFunction::State &state, uint64_t param) {
const auto &params = *(const Params *)(param);
- const CT *src = DenseTensorView::typify_cells<CT>(state.peek(0)).cbegin();
+ const CT *src = state.peek(0).cells().typify<CT>().cbegin();
auto dst_cells = state.stash.create_array<CT>(params.outer_size * params.inner_size);
AGGR aggr;
CT *dst = dst_cells.begin();
diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_peek_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_peek_function.cpp
index 16c0b01b169..477062ba9a3 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_tensor_peek_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_peek_function.cpp
@@ -36,7 +36,7 @@ void my_tensor_peek_op(eval::InterpretedFunction::State &state, uint64_t param)
}
factor *= dim.second;
}
- auto cells = DenseTensorView::typify_cells<CT>(state.peek(0));
+ auto cells = state.peek(0).cells().typify<CT>();
state.stack.pop_back();
const Value &result = state.stash.create<DoubleValue>(valid ? cells[idx] : 0.0);
state.stack.emplace_back(result);
diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp
index b845ccf93a5..9303488bbc5 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp
@@ -39,48 +39,34 @@ dimensionsAsString(const eval::ValueType &type)
return oss.str();
}
-size_t
-calcCellsSize(const eval::ValueType &type)
-{
- size_t cellsSize = 1;
- for (const auto &dim : type.dimensions()) {
- cellsSize *= dim.size;
- }
- return cellsSize;
-}
-
-
void
-checkCellsSize(const DenseTensorView &arg)
+checkCellsSize(const eval::ValueType &type, TypedCells cells)
{
- auto cellsSize = calcCellsSize(arg.fast_type());
- if (arg.cellsRef().size != cellsSize) {
+ auto cellsSize = type.dense_subspace_size();
+ if (cells.size != cellsSize) {
throw IllegalStateException(make_string("wrong cell size, "
"expected=%zu, "
"actual=%zu",
cellsSize,
- arg.cellsRef().size));
+ cells.size));
}
}
void
-checkDimensions(const DenseTensorView &lhs, const DenseTensorView &rhs,
+checkDimensions(const eval::ValueType &lhs, const eval::ValueType &rhs,
vespalib::stringref operation)
{
- if (lhs.fast_type().dimensions() != rhs.fast_type().dimensions()) {
+ if (lhs.dimensions() != rhs.dimensions()) {
throw IllegalStateException(make_string("mismatching dimensions for "
"dense tensor %s, "
"lhs dimensions = '%s', "
"rhs dimensions = '%s'",
operation.data(),
- dimensionsAsString(lhs.fast_type()).c_str(),
- dimensionsAsString(rhs.fast_type()).c_str()));
+ dimensionsAsString(lhs).c_str(),
+ dimensionsAsString(rhs).c_str()));
}
- checkCellsSize(lhs);
- checkCellsSize(rhs);
}
-
/*
* Join the cells of two tensors.
*
@@ -124,26 +110,18 @@ struct CallJoin
template <typename Function>
Tensor::UP
-joinDenseTensors(const DenseTensorView &lhs, const DenseTensorView &rhs,
- Function &&func)
-{
- TypedCells lhsCells = lhs.cellsRef();
- TypedCells rhsCells = rhs.cellsRef();
- return dispatch_2<CallJoin>(lhsCells, rhsCells, lhs.fast_type().dimensions(), std::move(func));
-}
-
-template <typename Function>
-Tensor::UP
joinDenseTensors(const DenseTensorView &lhs, const Tensor &rhs,
vespalib::stringref operation,
Function &&func)
{
- auto view = dynamic_cast<const DenseTensorView *>(&rhs);
- if (view) {
- checkDimensions(lhs, *view, operation);
- return joinDenseTensors(lhs, *view, func);
- }
- return Tensor::UP();
+ const auto & lhs_type = lhs.fast_type();
+ const auto & rhs_type = rhs.type();
+ TypedCells lhs_cells = lhs.cells();
+ TypedCells rhs_cells = rhs.cells();
+ checkDimensions(lhs_type, rhs_type, operation);
+ checkCellsSize(lhs_type, lhs_cells);
+ checkCellsSize(rhs_type, rhs_cells);
+ return dispatch_2<CallJoin>(lhs_cells, rhs_cells, lhs_type.dimensions(), std::move(func));
}
bool sameCells(TypedCells lhs, TypedCells rhs)
@@ -215,9 +193,8 @@ DenseTensorView::apply(const CellFunction &func) const
bool
DenseTensorView::equals(const Tensor &arg) const
{
- auto view = dynamic_cast<const DenseTensorView *>(&arg);
- if (view) {
- return *this == *view;
+ if (fast_type() == arg.type()) {
+ return sameCells(cells(), arg.cells());
}
return false;
}
diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_view.h b/eval/src/vespa/eval/tensor/dense/dense_tensor_view.h
index 2cea3c855a6..27a032b784f 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_tensor_view.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_view.h
@@ -51,12 +51,6 @@ public:
return MemoryUsage(sz, sz, 0, 0);
}
- template <typename T> static ConstArrayRef<T> typify_cells(const eval::Value &self) {
- return static_cast<const DenseTensorView &>(self).cellsRef().typify<T>();
- }
- template <typename T> static ConstArrayRef<T> unsafe_typify_cells(const eval::Value &self) {
- return static_cast<const DenseTensorView &>(self).cellsRef().unsafe_typify<T>();
- }
protected:
explicit DenseTensorView(const eval::ValueType &type_in)
: _typeRef(type_in),
diff --git a/eval/src/vespa/eval/tensor/dense/dense_xw_product_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_xw_product_function.cpp
index 968308d69c9..33c674fc4ab 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_xw_product_function.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_xw_product_function.cpp
@@ -36,8 +36,8 @@ template <typename LCT, typename RCT, bool common_inner>
void my_xw_product_op(eval::InterpretedFunction::State &state, uint64_t param) {
const DenseXWProductFunction::Self &self = *((const DenseXWProductFunction::Self *)(param));
using OCT = typename eval::UnifyCellTypes<LCT,RCT>::type;
- auto vector_cells = DenseTensorView::typify_cells<LCT>(state.peek(1));
- auto matrix_cells = DenseTensorView::typify_cells<RCT>(state.peek(0));
+ auto vector_cells = state.peek(1).cells().typify<LCT>();
+ auto matrix_cells = state.peek(0).cells().typify<RCT>();
auto dst_cells = state.stash.create_array<OCT>(self.result_size);
OCT *dst = dst_cells.begin();
const RCT *matrix = matrix_cells.cbegin();
@@ -51,8 +51,8 @@ void my_xw_product_op(eval::InterpretedFunction::State &state, uint64_t param) {
template <bool common_inner>
void my_cblas_double_xw_product_op(eval::InterpretedFunction::State &state, uint64_t param) {
const DenseXWProductFunction::Self &self = *((const DenseXWProductFunction::Self *)(param));
- auto vector_cells = DenseTensorView::typify_cells<double>(state.peek(1));
- auto matrix_cells = DenseTensorView::typify_cells<double>(state.peek(0));
+ auto vector_cells = state.peek(1).cells().typify<double>();
+ auto matrix_cells = state.peek(0).cells().typify<double>();
auto dst_cells = state.stash.create_array<double>(self.result_size);
cblas_dgemv(CblasRowMajor, common_inner ? CblasNoTrans : CblasTrans,
common_inner ? self.result_size : self.vector_size,
@@ -65,8 +65,8 @@ void my_cblas_double_xw_product_op(eval::InterpretedFunction::State &state, uint
template <bool common_inner>
void my_cblas_float_xw_product_op(eval::InterpretedFunction::State &state, uint64_t param) {
const DenseXWProductFunction::Self &self = *((const DenseXWProductFunction::Self *)(param));
- auto vector_cells = DenseTensorView::typify_cells<float>(state.peek(1));
- auto matrix_cells = DenseTensorView::typify_cells<float>(state.peek(0));
+ auto vector_cells = state.peek(1).cells().typify<float>();
+ auto matrix_cells = state.peek(0).cells().typify<float>();
auto dst_cells = state.stash.create_array<float>(self.result_size);
cblas_sgemv(CblasRowMajor, common_inner ? CblasNoTrans : CblasTrans,
common_inner ? self.result_size : self.vector_size,
diff --git a/eval/src/vespa/eval/tensor/dense/onnx_wrapper.cpp b/eval/src/vespa/eval/tensor/dense/onnx_wrapper.cpp
index b581ce787e3..5db533a4655 100644
--- a/eval/src/vespa/eval/tensor/dense/onnx_wrapper.cpp
+++ b/eval/src/vespa/eval/tensor/dense/onnx_wrapper.cpp
@@ -346,7 +346,7 @@ template <typename T>
void
Onnx::EvalContext::adapt_param(EvalContext &self, size_t idx, const eval::Value &param)
{
- const auto &cells_ref = static_cast<const DenseTensorView &>(param).cellsRef();
+ const auto &cells_ref = param.cells();
auto cells = unconstify(cells_ref.typify<T>());
const auto &sizes = self._wire_info.onnx_inputs[idx].dimensions;
self._param_values[idx] = Ort::Value::CreateTensor<T>(self._cpu_memory, cells.begin(), cells.size(), sizes.data(), sizes.size());
@@ -356,7 +356,7 @@ template <typename SRC, typename DST>
void
Onnx::EvalContext::convert_param(EvalContext &self, size_t idx, const eval::Value &param)
{
- auto cells = static_cast<const DenseTensorView &>(param).cellsRef().typify<SRC>();
+ auto cells = param.cells().typify<SRC>();
size_t n = cells.size();
const SRC *src = cells.begin();
DST *dst = self._param_values[idx].GetTensorMutableData<DST>();
@@ -369,7 +369,7 @@ template <typename SRC, typename DST>
void
Onnx::EvalContext::convert_result(EvalContext &self, size_t idx)
{
- const auto &cells_ref = static_cast<const DenseTensorView &>(*self._results[idx]).cellsRef();
+ const auto &cells_ref = (*self._results[idx]).cells();
auto cells = unconstify(cells_ref.typify<DST>());
size_t n = cells.size();
DST *dst = cells.begin();
diff --git a/eval/src/vespa/eval/tensor/partial_update.cpp b/eval/src/vespa/eval/tensor/partial_update.cpp
new file mode 100644
index 00000000000..60d3dd638d1
--- /dev/null
+++ b/eval/src/vespa/eval/tensor/partial_update.cpp
@@ -0,0 +1,358 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "partial_update.h"
+#include <vespa/vespalib/util/overload.h>
+#include <vespa/vespalib/util/typify.h>
+#include <vespa/vespalib/util/visit_ranges.h>
+#include <cassert>
+#include <set>
+
+#include <vespa/log/log.h>
+LOG_SETUP(".eval.tensor.partial_update");
+
+using namespace vespalib::eval;
+
+namespace vespalib::tensor {
+
+namespace {
+
+using join_fun_t = double (*)(double, double);
+
+static constexpr size_t npos() { return -1; }
+
+enum class DimCase {
+ MAPPED_MATCH, CONV_TO_INDEXED
+};
+
+struct DenseCoords {
+ std::vector<size_t> dim_sizes;
+ size_t total_size;
+ size_t offset;
+ size_t current;
+ DenseCoords(const ValueType &output_type)
+ : total_size(1), offset(0), current(0)
+ {
+ for (const auto & dim : output_type.dimensions()) {
+ if (dim.is_indexed()) {
+ dim_sizes.push_back(dim.size);
+ total_size *= dim.size;
+ }
+ }
+ }
+ ~DenseCoords();
+ void clear() { offset = 0; current = 0; }
+ void convert_label(vespalib::stringref label) {
+ uint32_t coord = 0;
+ for (char c : label) {
+ if (c < '0' || c > '9') { // bad char
+ offset = npos();
+ break;
+ }
+ coord = coord * 10 + (c - '0');
+ }
+ size_t cur_dim_size = dim_sizes[current];
+ if (coord < cur_dim_size) {
+ if (offset != npos()) {
+ offset *= cur_dim_size;
+ offset += coord;
+ }
+ } else {
+ offset = npos();
+ }
+ ++current;
+ }
+ size_t get_dense_index() const {
+ assert(current == dim_sizes.size());
+ return offset;
+ }
+};
+DenseCoords::~DenseCoords() = default;
+
+struct SparseCoords {
+ std::vector<vespalib::stringref> addr;
+ std::vector<vespalib::stringref *> next_result_refs;
+ std::vector<const vespalib::stringref *> lookup_refs;
+ std::vector<size_t> lookup_view_dims;
+ SparseCoords(size_t sz)
+ : addr(sz), next_result_refs(sz), lookup_refs(sz), lookup_view_dims(sz)
+ {
+ for (size_t i = 0; i < sz; ++i) {
+ next_result_refs[i] = &addr[i];
+ lookup_refs[i] = &addr[i];
+ lookup_view_dims[i] = i;
+ }
+ }
+ ~SparseCoords();
+};
+SparseCoords::~SparseCoords() = default;
+
+/**
+ * Helper class that converts a fully-sparse address from the modifier
+ * tensor into a subset sparse address for the output and an offset
+ * in the dense subspace.
+ **/
+struct AddressHandler {
+ std::vector<DimCase> dimension_plan;
+ DenseCoords dense_converter;
+ SparseCoords for_output;
+ SparseCoords from_modifier;
+ bool valid;
+
+ AddressHandler(const ValueType &output_type,
+ const ValueType &modifier_type)
+ : dimension_plan(), dense_converter(output_type),
+ for_output(output_type.count_mapped_dimensions()),
+ from_modifier(modifier_type.count_mapped_dimensions()),
+ valid(true)
+ {
+ if (! modifier_type.is_sparse()) {
+ LOG(error, "Unexpected non-sparse modifier tensor, type is %s",
+ modifier_type.to_spec().c_str());
+ valid = false;
+ return;
+ }
+ // analyse dimensions
+ auto visitor = overload {
+ [&](visit_ranges_either, const auto &) { valid = false; },
+ [&](visit_ranges_both, const auto &a, const auto &) {
+ dimension_plan.push_back(a.is_mapped() ? DimCase::MAPPED_MATCH : DimCase::CONV_TO_INDEXED);
+ }
+ };
+ const auto & input_dims = output_type.dimensions();
+ const auto & modifier_dims = modifier_type.dimensions();
+ visit_ranges(visitor,
+ input_dims.begin(), input_dims.end(),
+ modifier_dims.begin(), modifier_dims.end(),
+ [](const auto &a, const auto &b){ return (a.name < b.name); });
+ if (! valid) {
+ LOG(error, "Value type %s does not match modifier type %s (should have same dimensions)",
+ output_type.to_spec().c_str(), modifier_type.to_spec().c_str());
+ return;
+ }
+ // implicitly checked above, must hold:
+ assert(input_dims.size() == modifier_dims.size());
+ // the plan should now be fully built:
+ assert(input_dims.size() == dimension_plan.size());
+ }
+
+ void handle_address()
+ {
+ dense_converter.clear();
+ auto out = for_output.addr.begin();
+ for (size_t i = 0; i < dimension_plan.size(); ++i) {
+ if (dimension_plan[i] == DimCase::CONV_TO_INDEXED) {
+ dense_converter.convert_label(from_modifier.addr[i]);
+ } else {
+ *out++ = from_modifier.addr[i];
+ }
+ }
+ assert(out == for_output.addr.end());
+ assert(dense_converter.current == dense_converter.dim_sizes.size());
+ }
+
+ ~AddressHandler();
+};
+AddressHandler::~AddressHandler() = default;
+
+template <typename CT, typename ICT = CT, typename KeepFun>
+void copy_tensor_with_filter(const Value &input,
+ size_t dsss,
+ SparseCoords &addrs,
+ ValueBuilder<CT> &builder,
+ KeepFun && keep_subspace)
+{
+ const auto input_cells = input.cells().typify<ICT>();
+ auto input_view = input.index().create_view({});
+ input_view->lookup({});
+ size_t input_subspace_index;
+ while (input_view->next_result(addrs.next_result_refs, input_subspace_index)) {
+ if (keep_subspace(addrs.lookup_refs, input_subspace_index)) {
+ size_t input_offset = dsss * input_subspace_index;
+ auto src = input_cells.begin() + input_offset;
+ auto dst = builder.add_subspace(addrs.addr).begin();
+ for (size_t i = 0; i < dsss; ++i) {
+ dst[i] = src[i];
+ }
+ }
+ }
+}
+
+template <typename CT>
+Value::UP
+copy_tensor(const Value &input, const ValueType &input_type, SparseCoords &helper, const ValueBuilderFactory &factory)
+{
+ const size_t num_mapped_in_input = input_type.count_mapped_dimensions();
+ const size_t dsss = input_type.dense_subspace_size();
+ const size_t expected_subspaces = input.index().size();
+ auto builder = factory.create_value_builder<CT>(input_type, num_mapped_in_input, dsss, expected_subspaces);
+ auto no_filter = [] (const auto &, size_t) {
+ return true;
+ };
+ copy_tensor_with_filter<CT>(input, dsss, helper, *builder, no_filter);
+ return builder->build(std::move(builder));
+}
+
+//-----------------------------------------------------------------------------
+
+struct PerformModify {
+ template<typename ICT, typename MCT>
+ static Value::UP invoke(const Value &input,
+ join_fun_t function,
+ const Value &modifier,
+ const ValueBuilderFactory &factory);
+};
+
+template <typename ICT, typename MCT>
+Value::UP
+PerformModify::invoke(const Value &input, join_fun_t function, const Value &modifier, const ValueBuilderFactory &factory)
+{
+ const ValueType &input_type = input.type();
+ const size_t dsss = input_type.dense_subspace_size();
+ const ValueType &modifier_type = modifier.type();
+ AddressHandler handler(input_type, modifier_type);
+ if (! handler.valid) {
+ return Value::UP();
+ }
+ // copy input to output
+ auto out = copy_tensor<ICT>(input, input_type, handler.for_output, factory);
+ // need to overwrite some cells
+ auto output_cells = unconstify(out->cells().template typify<ICT>());
+ const auto modifier_cells = modifier.cells().typify<MCT>();
+ auto modifier_view = modifier.index().create_view({});
+ auto lookup_view = out->index().create_view(handler.for_output.lookup_view_dims);
+ modifier_view->lookup({});
+ size_t modifier_subspace_index;
+ while (modifier_view->next_result(handler.from_modifier.next_result_refs, modifier_subspace_index)) {
+ handler.handle_address();
+ size_t dense_idx = handler.dense_converter.get_dense_index();
+ if (dense_idx == npos()) {
+ continue;
+ }
+ lookup_view->lookup(handler.for_output.lookup_refs);
+ size_t output_subspace_index;
+ if (lookup_view->next_result({}, output_subspace_index)) {
+ size_t subspace_offset = dsss * output_subspace_index;
+ auto dst = output_cells.begin() + subspace_offset;
+ ICT lhs = dst[dense_idx];
+ MCT rhs = modifier_cells[modifier_subspace_index];
+ dst[dense_idx] = function(lhs, rhs);
+ }
+ }
+ return out;
+}
+
+//-----------------------------------------------------------------------------
+
+struct PerformAdd {
+ template<typename ICT, typename MCT>
+ static Value::UP invoke(const Value &input,
+ const Value &modifier,
+ const ValueBuilderFactory &factory);
+};
+
+template <typename ICT, typename MCT>
+Value::UP
+PerformAdd::invoke(const Value &input, const Value &modifier, const ValueBuilderFactory &factory)
+{
+ const ValueType &input_type = input.type();
+ const ValueType &modifier_type = modifier.type();
+ if (input_type.dimensions() != modifier_type.dimensions()) {
+ LOG(error, "when adding cells to a tensor, dimensions must be equal. "
+ "Got input type %s != modifier type %s",
+ input_type.to_spec().c_str(), modifier_type.to_spec().c_str());
+ return Value::UP();
+ }
+ const size_t num_mapped_in_input = input_type.count_mapped_dimensions();
+ const size_t dsss = input_type.dense_subspace_size();
+ const size_t expected_subspaces = input.index().size() + modifier.index().size();
+ auto builder = factory.create_value_builder<ICT>(input_type, num_mapped_in_input, dsss, expected_subspaces);
+ SparseCoords addrs(num_mapped_in_input);
+ auto lookup_view = input.index().create_view(addrs.lookup_view_dims);
+ std::vector<bool> overwritten(input.index().size(), false);
+ auto remember_subspaces = [&] (const auto & lookup_refs, size_t) {
+ lookup_view->lookup(lookup_refs);
+ size_t input_subspace_index;
+ if (lookup_view->next_result({}, input_subspace_index)) {
+ overwritten[input_subspace_index] = true;
+ }
+ return true;
+ };
+ copy_tensor_with_filter<ICT, MCT>(modifier, dsss, addrs, *builder, remember_subspaces);
+ auto filter = [&] (const auto &, size_t input_subspace) {
+ return ! overwritten[input_subspace];
+ };
+ copy_tensor_with_filter<ICT>(input, dsss, addrs, *builder, filter);
+ return builder->build(std::move(builder));
+}
+
+//-----------------------------------------------------------------------------
+
+struct PerformRemove {
+ template<typename ICT>
+ static Value::UP invoke(const Value &input,
+ const Value &modifier,
+ const ValueBuilderFactory &factory);
+};
+
+template <typename ICT>
+Value::UP
+PerformRemove::invoke(const Value &input, const Value &modifier, const ValueBuilderFactory &factory)
+{
+ const ValueType &input_type = input.type();
+ const ValueType &modifier_type = modifier.type();
+ if (input_type.mapped_dimensions() != modifier_type.dimensions()) {
+ LOG(error, "when removing cells from a tensor, mapped dimensions must be equal. "
+ "Got input type %s versus modifier type %s",
+ input_type.to_spec().c_str(), modifier_type.to_spec().c_str());
+ return Value::UP();
+ }
+ const size_t num_mapped_in_input = input_type.count_mapped_dimensions();
+ if (num_mapped_in_input == 0) {
+ LOG(error, "cannot remove cells from a dense tensor of type %s",
+ input_type.to_spec().c_str());
+ return Value::UP();
+ }
+ SparseCoords addrs(num_mapped_in_input);
+ auto modifier_view = modifier.index().create_view(addrs.lookup_view_dims);
+ const size_t expected_subspaces = input.index().size();
+ const size_t dsss = input_type.dense_subspace_size();
+ auto builder = factory.create_value_builder<ICT>(input_type, num_mapped_in_input, dsss, expected_subspaces);
+ auto filter_by_modifier = [&] (const auto & lookup_refs, size_t) {
+ modifier_view->lookup(lookup_refs);
+ size_t modifier_subspace_index;
+ return !(modifier_view->next_result({}, modifier_subspace_index));
+ };
+ copy_tensor_with_filter<ICT>(input, dsss, addrs, *builder, filter_by_modifier);
+ return builder->build(std::move(builder));
+}
+
+} // namespace <unnamed>
+
+//-----------------------------------------------------------------------------
+
+Value::UP
+TensorPartialUpdate::modify(const Value &input, join_fun_t function,
+ const Value &modifier, const ValueBuilderFactory &factory)
+{
+ return typify_invoke<2, TypifyCellType, PerformModify>(
+ input.cells().type, modifier.cells().type,
+ input, function, modifier, factory);
+}
+
+Value::UP
+TensorPartialUpdate::add(const Value &input, const Value &add_cells, const ValueBuilderFactory &factory)
+{
+ return typify_invoke<2, TypifyCellType, PerformAdd>(
+ input.cells().type, add_cells.cells().type,
+ input, add_cells, factory);
+}
+
+Value::UP
+TensorPartialUpdate::remove(const Value &input, const Value &remove_spec, const ValueBuilderFactory &factory)
+{
+ return typify_invoke<1, TypifyCellType, PerformRemove>(
+ input.cells().type,
+ input, remove_spec, factory);
+}
+
+} // namespace
diff --git a/eval/src/vespa/eval/tensor/partial_update.h b/eval/src/vespa/eval/tensor/partial_update.h
new file mode 100644
index 00000000000..8f997bde56c
--- /dev/null
+++ b/eval/src/vespa/eval/tensor/partial_update.h
@@ -0,0 +1,42 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include <vespa/eval/eval/value.h>
+
+namespace vespalib::tensor {
+
+struct TensorPartialUpdate {
+ using join_fun_t = double (*)(double, double);
+ using Value = vespalib::eval::Value;
+ using ValueBuilderFactory = vespalib::eval::ValueBuilderFactory;
+
+ /**
+ * Make a copy of the input, but apply function(oldvalue, modifier.cellvalue)
+ * to cells which also exist in the "modifier".
+ * The modifier type must be sparse with exactly the same dimension names
+ * as the input type.
+ * Returns null pointer if this constraint is violated.
+ **/
+ static Value::UP modify(const Value &input, join_fun_t function,
+ const Value &modifier, const ValueBuilderFactory &factory);
+
+ /**
+ * Make a copy of the input, but add or overwrite cells from add_cells.
+ * Requires same type for input and add_cells.
+ * Returns null pointer if this constraint is violated.
+ **/
+ static Value::UP add(const Value &input, const Value &add_cells, const ValueBuilderFactory &factory);
+
+ /**
+ * Make a copy of the input, but remove cells present in remove_spec.
+ * The remove_spec must be a sparse tensor, with exactly the mapped dimensions
+ * that the input value has.
+ * Cell values in remove_spec are ignored.
+ * Not valid for dense tensors, since removing cells for those are impossible.
+ * Returns null pointer if these constraints are violated.
+ **/
+ static Value::UP remove(const Value &input, const Value &remove_spec, const ValueBuilderFactory &factory);
+};
+
+} // namespace
diff --git a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_ref.h b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_ref.h
index 45fb7236152..e8838b1acdb 100644
--- a/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_ref.h
+++ b/eval/src/vespa/eval/tensor/sparse/sparse_tensor_address_ref.h
@@ -38,7 +38,7 @@ public:
_hash(rhs._hash)
{}
- uint32_t hash() const { return _hash; }
+ uint32_t hash() const noexcept { return _hash; }
uint32_t calcHash() const noexcept;
diff --git a/eval/src/vespa/eval/tensor/wrapped_simple_tensor.cpp b/eval/src/vespa/eval/tensor/wrapped_simple_tensor.cpp
index 241b8026b59..178935fce00 100644
--- a/eval/src/vespa/eval/tensor/wrapped_simple_tensor.cpp
+++ b/eval/src/vespa/eval/tensor/wrapped_simple_tensor.cpp
@@ -145,7 +145,6 @@ WrappedSimpleTensor::add(const Tensor &arg) const
if (!rhs || type() != rhs->type()) {
return Tensor::UP();
}
-
TensorSpec oldTensor = toSpec();
TensorSpec argTensor = rhs->toSpec();
TensorSpec result(type().to_spec());
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 a49daf94f01..8d27c723b89 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
@@ -325,13 +325,6 @@ public class Flags {
APPLICATION_ID
);
- public static final UnboundBooleanFlag WEIGHTED_DNS_PER_REGION = defineFeatureFlag(
- "weighted-dns-per-region", true,
- "Whether to create weighted DNS records per region in global endpoints",
- "Takes effect on next deployment through controller",
- APPLICATION_ID
- );
-
public static final UnboundBooleanFlag ONLY_PUBLIC_ACCESS = defineFeatureFlag(
"enable-public-only", false,
"Only access public hosts from container",
@@ -391,6 +384,12 @@ public class Flags {
"Whether application containers should use the new restapi handler implementation",
"Takes effect on next internal redeployment");
+ public static final UnboundBooleanFlag ALWAYS_ACQUIRE_PROVISION_LOCK = defineFeatureFlag(
+ "always-acquire-provision-lock",
+ false,
+ "Whether provision lock should always be taken when writing nodes",
+ "Takes effect on config server restart");
+
/** WARNING: public for testing: All flags should be defined in {@link Flags}. */
public static UnboundBooleanFlag defineFeatureFlag(String flagId, boolean defaultValue, String description,
String modificationEffect, FetchVector.Dimension... dimensions) {
diff --git a/fnet/src/tests/connect/connect_test.cpp b/fnet/src/tests/connect/connect_test.cpp
index 62000efb682..3fe7b5b7614 100644
--- a/fnet/src/tests/connect/connect_test.cpp
+++ b/fnet/src/tests/connect/connect_test.cpp
@@ -4,7 +4,6 @@
#include <vespa/fnet/fnet.h>
#include <vespa/vespalib/net/server_socket.h>
#include <vespa/vespalib/net/crypto_engine.h>
-#include <vespa/vespalib/util/sync.h>
#include <vespa/vespalib/util/stringfmt.h>
using namespace vespalib;
diff --git a/fnet/src/tests/time/timespeed.cpp b/fnet/src/tests/time/timespeed.cpp
index 1204b0ff334..e6d2af5a278 100644
--- a/fnet/src/tests/time/timespeed.cpp
+++ b/fnet/src/tests/time/timespeed.cpp
@@ -9,14 +9,14 @@ using vespalib::BenchmarkTimer;
TEST("steady clock speed") {
using clock = std::chrono::steady_clock;
clock::time_point t;
- double min_time_us = BenchmarkTimer::benchmark([&t](){t = clock::now();}, 1.0) * 1000000.0;
+ double min_time_us = BenchmarkTimer::benchmark([&t]() noexcept {t = clock::now();}, 1.0) * 1000000.0;
fprintf(stderr, "approx overhead per sample (steady clock): %f us\n", min_time_us);
}
TEST("system clock speed") {
using clock = std::chrono::system_clock;
clock::time_point t;
- double min_time_us = BenchmarkTimer::benchmark([&t](){t = clock::now();}, 1.0) * 1000000.0;
+ double min_time_us = BenchmarkTimer::benchmark([&t]() noexcept {t = clock::now();}, 1.0) * 1000000.0;
fprintf(stderr, "approx overhead per sample (system clock): %f us\n", min_time_us);
}
diff --git a/fnet/src/vespa/fnet/transport_thread.cpp b/fnet/src/vespa/fnet/transport_thread.cpp
index 158524d1214..a20de880f15 100644
--- a/fnet/src/vespa/fnet/transport_thread.cpp
+++ b/fnet/src/vespa/fnet/transport_thread.cpp
@@ -7,7 +7,6 @@
#include "connector.h"
#include "connection.h"
#include "transport.h"
-#include <vespa/vespalib/util/sync.h>
#include <vespa/vespalib/net/socket_spec.h>
#include <vespa/vespalib/net/server_socket.h>
#include <csignal>
diff --git a/fsa/src/vespa/fsa/fsa.h b/fsa/src/vespa/fsa/fsa.h
index e4d3246d924..9c668f1f85f 100644
--- a/fsa/src/vespa/fsa/fsa.h
+++ b/fsa/src/vespa/fsa/fsa.h
@@ -304,7 +304,7 @@ public:
*
* @param f Reference to FSA.
*/
- State(const FSA& f) : _fsa(&f), _state(_fsa->start()) {}
+ State(const FSA& f) noexcept : _fsa(&f), _state(_fsa->start()) {}
/**
* @brief Constructor.
@@ -314,7 +314,7 @@ public:
*
* @param f Pointer to FSA.
*/
- State(const FSA* f) : _fsa(f), _state(_fsa->start()) {}
+ State(const FSA* f) noexcept : _fsa(f), _state(_fsa->start()) {}
/**
* @brief Copy constructor.
@@ -325,14 +325,14 @@ public:
*
* @param s Reference to state to be duplicated.
*/
- State(const State& s) : _fsa(s._fsa), _state(s._state) {}
+ State(const State& s) noexcept : _fsa(s._fsa), _state(s._state) {}
/**
* @brief Destructor.
*
* Destructor, does nothing special.
*/
- virtual ~State() {}
+ virtual ~State() = default;
/**
* @brief Check if the automaton has perfect hash built in.
@@ -1043,7 +1043,7 @@ public:
*
* @param f Reference to FSA.
*/
- WordCounterState(const FSA& f) : State(f), _counter(0) {}
+ WordCounterState(const FSA& f) noexcept : State(f), _counter(0) {}
/**
* @brief Constructor.
@@ -1053,7 +1053,7 @@ public:
*
* @param f Pointer to FSA.
*/
- WordCounterState(const FSA* f) : State(f), _counter(0) {}
+ WordCounterState(const FSA* f) noexcept : State(f), _counter(0) {}
/**
* @brief Copy constructor.
@@ -1062,12 +1062,12 @@ public:
*
* @param s Reference to hashed state to copy.
*/
- WordCounterState(const WordCounterState& s) : State(s), _counter(s._counter) {}
+ WordCounterState(const WordCounterState& s) noexcept : State(s), _counter(s._counter) {}
/**
* @brief Destructor.
*/
- virtual ~WordCounterState() {}
+ virtual ~WordCounterState() = default;
/**
* @brief Set the state to the starting state of the automaton.
@@ -1798,7 +1798,7 @@ public:
*
* @param f Reference to FSA.
*/
- HashedWordCounterState(const FSA& f) : State(f), _hash(0), _counter(0) {}
+ HashedWordCounterState(const FSA& f) noexcept : State(f), _hash(0), _counter(0) {}
/**
* @brief Constructor.
@@ -1808,7 +1808,7 @@ public:
*
* @param f Pointer to FSA.
*/
- HashedWordCounterState(const FSA* f) : State(f), _hash(0), _counter(0) {}
+ HashedWordCounterState(const FSA* f) noexcept : State(f), _hash(0), _counter(0) {}
/**
* @brief Copy constructor.
@@ -1817,12 +1817,12 @@ public:
*
* @param s Reference to hashed state to copy.
*/
- HashedWordCounterState(const HashedWordCounterState& s) : State(s), _hash(s._hash), _counter(s._counter) {}
+ HashedWordCounterState(const HashedWordCounterState& s) noexcept : State(s), _hash(s._hash), _counter(s._counter) {}
/**
* @brief Destructor.
*/
- virtual ~HashedWordCounterState() {}
+ virtual ~HashedWordCounterState() = default;
/**
* @brief Set the state to the starting state of the automaton.
@@ -2120,7 +2120,7 @@ public:
*
* @return Index of the start state (0 if the %FSA is empty).
*/
- state_t start() const
+ state_t start() const noexcept
{
return _start;
}
diff --git a/fsa/src/vespa/fsa/segmenter.h b/fsa/src/vespa/fsa/segmenter.h
index a2720c6de0c..f2826f9c967 100644
--- a/fsa/src/vespa/fsa/segmenter.h
+++ b/fsa/src/vespa/fsa/segmenter.h
@@ -147,7 +147,7 @@ public:
*
* Null segment at postion zero.
*/
- Segment() : _beg(0), _end(0), _conn(0) {}
+ Segment() noexcept : _beg(0), _end(0), _conn(0) {}
/**
* @brief Constructor.
@@ -156,7 +156,7 @@ public:
* @param e End of the segment (the position after the last term).
* @param c Connexity of the segment.
*/
- Segment(unsigned int b, unsigned int e, unsigned int c) :
+ Segment(unsigned int b, unsigned int e, unsigned int c) noexcept :
_beg(b), _end(e), _conn(c) {}
/**
@@ -164,12 +164,12 @@ public:
*
* @param s Segment object to copy.
*/
- Segment(const Segment &s) : _beg(s._beg), _end(s._end), _conn(s._conn) {}
+ Segment(const Segment &s) noexcept : _beg(s._beg), _end(s._end), _conn(s._conn) {}
/**
* @brief Destructor.
*/
- ~Segment() {}
+ ~Segment() = default;
/**
* @brief Set the segment parameters.
diff --git a/jdisc_http_service/abi-spec.json b/jdisc_http_service/abi-spec.json
index f6bfe769997..3f68009cd42 100644
--- a/jdisc_http_service/abi-spec.json
+++ b/jdisc_http_service/abi-spec.json
@@ -682,6 +682,44 @@
],
"fields": []
},
+ "com.yahoo.jdisc.http.ServerConfig$AccessLog$Builder": {
+ "superClass": "java.lang.Object",
+ "interfaces": [
+ "com.yahoo.config.ConfigBuilder"
+ ],
+ "attributes": [
+ "public"
+ ],
+ "methods": [
+ "public void <init>()",
+ "public void <init>(com.yahoo.jdisc.http.ServerConfig$AccessLog)",
+ "public com.yahoo.jdisc.http.ServerConfig$AccessLog$Builder remoteAddressHeaders(java.lang.String)",
+ "public com.yahoo.jdisc.http.ServerConfig$AccessLog$Builder remoteAddressHeaders(java.util.Collection)",
+ "public com.yahoo.jdisc.http.ServerConfig$AccessLog$Builder remotePortHeaders(java.lang.String)",
+ "public com.yahoo.jdisc.http.ServerConfig$AccessLog$Builder remotePortHeaders(java.util.Collection)",
+ "public com.yahoo.jdisc.http.ServerConfig$AccessLog build()"
+ ],
+ "fields": [
+ "public java.util.List remoteAddressHeaders",
+ "public java.util.List remotePortHeaders"
+ ]
+ },
+ "com.yahoo.jdisc.http.ServerConfig$AccessLog": {
+ "superClass": "com.yahoo.config.InnerNode",
+ "interfaces": [],
+ "attributes": [
+ "public",
+ "final"
+ ],
+ "methods": [
+ "public void <init>(com.yahoo.jdisc.http.ServerConfig$AccessLog$Builder)",
+ "public java.util.List remoteAddressHeaders()",
+ "public java.lang.String remoteAddressHeaders(int)",
+ "public java.util.List remotePortHeaders()",
+ "public java.lang.String remotePortHeaders(int)"
+ ],
+ "fields": []
+ },
"com.yahoo.jdisc.http.ServerConfig$Builder": {
"superClass": "java.lang.Object",
"interfaces": [
@@ -704,6 +742,7 @@
"public com.yahoo.jdisc.http.ServerConfig$Builder stopTimeout(double)",
"public com.yahoo.jdisc.http.ServerConfig$Builder jmx(com.yahoo.jdisc.http.ServerConfig$Jmx$Builder)",
"public com.yahoo.jdisc.http.ServerConfig$Builder metric(com.yahoo.jdisc.http.ServerConfig$Metric$Builder)",
+ "public com.yahoo.jdisc.http.ServerConfig$Builder accessLog(com.yahoo.jdisc.http.ServerConfig$AccessLog$Builder)",
"public final boolean dispatchGetConfig(com.yahoo.config.ConfigInstance$Producer)",
"public final java.lang.String getDefMd5()",
"public final java.lang.String getDefName()",
@@ -713,7 +752,8 @@
"fields": [
"public java.util.List filter",
"public com.yahoo.jdisc.http.ServerConfig$Jmx$Builder jmx",
- "public com.yahoo.jdisc.http.ServerConfig$Metric$Builder metric"
+ "public com.yahoo.jdisc.http.ServerConfig$Metric$Builder metric",
+ "public com.yahoo.jdisc.http.ServerConfig$AccessLog$Builder accessLog"
]
},
"com.yahoo.jdisc.http.ServerConfig$Filter$Builder": {
@@ -854,7 +894,8 @@
"public int maxWorkerThreads()",
"public double stopTimeout()",
"public com.yahoo.jdisc.http.ServerConfig$Jmx jmx()",
- "public com.yahoo.jdisc.http.ServerConfig$Metric metric()"
+ "public com.yahoo.jdisc.http.ServerConfig$Metric metric()",
+ "public com.yahoo.jdisc.http.ServerConfig$AccessLog accessLog()"
],
"fields": [
"public static final java.lang.String CONFIG_DEF_MD5",
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLog.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLog.java
index 7085f07585a..e8fd92f8e19 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLog.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLog.java
@@ -4,6 +4,7 @@ package com.yahoo.jdisc.http.server.jetty;
import com.google.common.base.Objects;
import com.yahoo.container.logging.AccessLog;
import com.yahoo.container.logging.AccessLogEntry;
+import com.yahoo.jdisc.http.ServerConfig;
import com.yahoo.jdisc.http.servlet.ServletRequest;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.RequestLog;
@@ -15,6 +16,7 @@ import java.security.Principal;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Optional;
+import java.util.OptionalInt;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -27,25 +29,21 @@ import static com.yahoo.jdisc.http.core.HttpServletRequestUtils.getConnectorLoca
* @author Oyvind Bakksjo
* @author bjorncs
*/
-public class AccessLogRequestLog extends AbstractLifeCycle implements RequestLog {
+class AccessLogRequestLog extends AbstractLifeCycle implements RequestLog {
private static final Logger logger = Logger.getLogger(AccessLogRequestLog.class.getName());
- // TODO These hardcoded headers should be provided by config instead
- private static final String HEADER_NAME_X_FORWARDED_FOR = "x-forwarded-for";
- private static final String HEADER_NAME_X_FORWARDED_PORT = "X-Forwarded-Port";
- private static final String HEADER_NAME_Y_RA = "y-ra";
- private static final String HEADER_NAME_Y_RP = "y-rp";
- private static final String HEADER_NAME_YAHOOREMOTEIP = "yahooremoteip";
- private static final String HEADER_NAME_CLIENT_IP = "client-ip";
-
// HTTP headers that are logged as extra key-value-pairs in access log entries
private static final List<String> LOGGED_REQUEST_HEADERS = List.of("Vespa-Client-Version");
private final AccessLog accessLog;
+ private final List<String> remoteAddressHeaders;
+ private final List<String> remotePortHeaders;
- public AccessLogRequestLog(AccessLog accessLog) {
+ AccessLogRequestLog(AccessLog accessLog, ServerConfig.AccessLog config) {
this.accessLog = accessLog;
+ this.remoteAddressHeaders = config.remoteAddressHeaders();
+ this.remotePortHeaders = config.remotePortHeaders();
}
@Override
@@ -121,26 +119,30 @@ public class AccessLogRequestLog extends AbstractLifeCycle implements RequestLog
}
}
- private static String getRemoteAddress(HttpServletRequest request) {
- return Optional.ofNullable(request.getHeader(HEADER_NAME_X_FORWARDED_FOR))
- .or(() -> Optional.ofNullable(request.getHeader(HEADER_NAME_Y_RA)))
- .or(() -> Optional.ofNullable(request.getHeader(HEADER_NAME_YAHOOREMOTEIP)))
- .or(() -> Optional.ofNullable(request.getHeader(HEADER_NAME_CLIENT_IP)))
- .orElseGet(request::getRemoteAddr);
+ private String getRemoteAddress(HttpServletRequest request) {
+ for (String header : remoteAddressHeaders) {
+ String value = request.getHeader(header);
+ if (value != null) return value;
+ }
+ return request.getRemoteAddr();
}
- private static int getRemotePort(HttpServletRequest request) {
- return Optional.ofNullable(request.getHeader(HEADER_NAME_X_FORWARDED_PORT))
- .or(() -> Optional.ofNullable(request.getHeader(HEADER_NAME_Y_RP)))
- .flatMap(AccessLogRequestLog::parsePort)
- .orElseGet(request::getRemotePort);
+ private int getRemotePort(HttpServletRequest request) {
+ for (String header : remotePortHeaders) {
+ String value = request.getHeader(header);
+ if (value != null) {
+ OptionalInt maybePort = parsePort(value);
+ if (maybePort.isPresent()) return maybePort.getAsInt();
+ }
+ }
+ return request.getRemotePort();
}
- private static Optional<Integer> parsePort(String port) {
+ private static OptionalInt parsePort(String port) {
try {
- return Optional.of(Integer.valueOf(port));
+ return OptionalInt.of(Integer.parseInt(port));
} catch (IllegalArgumentException e) {
- return Optional.empty();
+ return OptionalInt.empty();
}
}
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java
index cc7ed7ac3e0..2cab06e9e23 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java
@@ -54,7 +54,7 @@ class HttpRequestDispatch {
private final ServletResponseController servletResponseController;
private final RequestHandler requestHandler;
- private final MetricReporter metricReporter;
+ private final RequestMetricReporter metricReporter;
public HttpRequestDispatch(JDiscContext jDiscContext,
AccessLogEntry accessLogEntry,
@@ -66,7 +66,7 @@ class HttpRequestDispatch {
requestHandler = newRequestHandler(jDiscContext, accessLogEntry, servletRequest);
this.jettyRequest = (Request) servletRequest;
- this.metricReporter = new MetricReporter(jDiscContext.metric, metricContext, jettyRequest.getTimeStamp());
+ this.metricReporter = new RequestMetricReporter(jDiscContext.metric, metricContext, jettyRequest.getTimeStamp());
this.servletResponseController = new ServletResponseController(servletRequest,
servletResponse,
jDiscContext.janitor,
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpResponseStatisticsCollector.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpResponseStatisticsCollector.java
index 31a8303ab4b..82c445c7ca9 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpResponseStatisticsCollector.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpResponseStatisticsCollector.java
@@ -2,7 +2,6 @@
package com.yahoo.jdisc.http.server.jetty;
import com.yahoo.jdisc.http.HttpRequest;
-import com.yahoo.jdisc.http.server.jetty.JettyHttpServer.Metrics;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.AsyncContextEvent;
import org.eclipse.jetty.server.Handler;
@@ -51,13 +50,13 @@ public class HttpResponseStatisticsCollector extends HandlerWrapper implements G
}
private static final String[] HTTP_RESPONSE_GROUPS = {
- Metrics.RESPONSES_1XX,
- Metrics.RESPONSES_2XX,
- Metrics.RESPONSES_3XX,
- Metrics.RESPONSES_4XX,
- Metrics.RESPONSES_5XX,
- Metrics.RESPONSES_401,
- Metrics.RESPONSES_403
+ MetricDefinitions.RESPONSES_1XX,
+ MetricDefinitions.RESPONSES_2XX,
+ MetricDefinitions.RESPONSES_3XX,
+ MetricDefinitions.RESPONSES_4XX,
+ MetricDefinitions.RESPONSES_5XX,
+ MetricDefinitions.RESPONSES_401,
+ MetricDefinitions.RESPONSES_403
};
private final AtomicLong inFlight = new AtomicLong();
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscHttpServlet.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscHttpServlet.java
index dfbcfb741f5..8ffc6759ae7 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscHttpServlet.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscHttpServlet.java
@@ -87,8 +87,8 @@ class JDiscHttpServlet extends HttpServlet {
request.setAttribute(JDiscServerConnector.REQUEST_ATTRIBUTE, getConnector(request));
Metric.Context metricContext = getMetricContext(request);
- context.metric.add(JettyHttpServer.Metrics.NUM_REQUESTS, 1, metricContext);
- context.metric.add(JettyHttpServer.Metrics.JDISC_HTTP_REQUESTS, 1, metricContext);
+ context.metric.add(MetricDefinitions.NUM_REQUESTS, 1, metricContext);
+ context.metric.add(MetricDefinitions.JDISC_HTTP_REQUESTS, 1, metricContext);
String method = request.getMethod().toUpperCase();
if (servletSupportedMethods.contains(method)) {
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscServerConnector.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscServerConnector.java
index 824a8cda330..f82b51804a9 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscServerConnector.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscServerConnector.java
@@ -75,8 +75,8 @@ class JDiscServerConnector extends ServerConnector {
var requestDimensions = new RequestDimensions(method, scheme);
return requestMetricContextCache.computeIfAbsent(requestDimensions, ignored -> {
Map<String, Object> dimensions = createConnectorDimensions(listenPort, connectorName);
- dimensions.put(JettyHttpServer.Metrics.METHOD_DIMENSION, method);
- dimensions.put(JettyHttpServer.Metrics.SCHEME_DIMENSION, scheme);
+ dimensions.put(MetricDefinitions.METHOD_DIMENSION, method);
+ dimensions.put(MetricDefinitions.SCHEME_DIMENSION, scheme);
return metric.createContext(dimensions);
});
}
@@ -95,8 +95,8 @@ class JDiscServerConnector extends ServerConnector {
private static Map<String, Object> createConnectorDimensions(int listenPort, String connectorName) {
Map<String, Object> props = new HashMap<>();
- props.put(JettyHttpServer.Metrics.NAME_DIMENSION, connectorName);
- props.put(JettyHttpServer.Metrics.PORT_DIMENSION, listenPort);
+ props.put(MetricDefinitions.NAME_DIMENSION, connectorName);
+ props.put(MetricDefinitions.PORT_DIMENSION, listenPort);
return props;
}
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java
index c826f52a865..303b36430a5 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java
@@ -1,11 +1,10 @@
// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.jdisc.http.server.jetty;
-import com.google.common.annotations.Beta;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.inject.Inject;
import com.yahoo.component.ComponentId;
import com.yahoo.component.provider.ComponentRegistry;
+import com.yahoo.concurrent.DaemonThreadFactory;
import com.yahoo.container.logging.AccessLog;
import com.yahoo.jdisc.Metric;
import com.yahoo.jdisc.http.ConnectorConfig;
@@ -15,7 +14,6 @@ import com.yahoo.jdisc.http.server.FilterBindings;
import com.yahoo.jdisc.service.AbstractServerProvider;
import com.yahoo.jdisc.service.CurrentContainer;
import org.eclipse.jetty.http.HttpField;
-import org.eclipse.jetty.io.ConnectionStatistics;
import org.eclipse.jetty.jmx.ConnectorServer;
import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.server.Connector;
@@ -23,7 +21,6 @@ import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
-import org.eclipse.jetty.server.handler.AbstractHandlerContainer;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.StatisticsHandler;
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
@@ -44,14 +41,9 @@ import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -62,77 +54,21 @@ import static java.util.stream.Collectors.toList;
* @author Simon Thoresen Hult
* @author bjorncs
*/
-@Beta
public class JettyHttpServer extends AbstractServerProvider {
- public interface Metrics {
- String NAME_DIMENSION = "serverName";
- String PORT_DIMENSION = "serverPort";
- String METHOD_DIMENSION = "httpMethod";
- String SCHEME_DIMENSION = "scheme";
- String REQUEST_TYPE_DIMENSION = "requestType";
- String CLIENT_IP_DIMENSION = "clientIp";
-
- String NUM_OPEN_CONNECTIONS = "serverNumOpenConnections";
- String NUM_CONNECTIONS_OPEN_MAX = "serverConnectionsOpenMax";
- String CONNECTION_DURATION_MAX = "serverConnectionDurationMax";
- String CONNECTION_DURATION_MEAN = "serverConnectionDurationMean";
- String CONNECTION_DURATION_STD_DEV = "serverConnectionDurationStdDev";
- String NUM_PREMATURELY_CLOSED_CONNECTIONS = "jdisc.http.request.prematurely_closed";
-
- String NUM_BYTES_RECEIVED = "serverBytesReceived";
- String NUM_BYTES_SENT = "serverBytesSent";
-
- String NUM_CONNECTIONS = "serverNumConnections";
-
- /* For historical reasons, these are all aliases for the same metric. 'jdisc.http' should ideally be the only one. */
- String JDISC_HTTP_REQUESTS = "jdisc.http.requests";
- String NUM_REQUESTS = "serverNumRequests";
-
- String NUM_SUCCESSFUL_RESPONSES = "serverNumSuccessfulResponses";
- String NUM_FAILED_RESPONSES = "serverNumFailedResponses";
- String NUM_SUCCESSFUL_WRITES = "serverNumSuccessfulResponseWrites";
- String NUM_FAILED_WRITES = "serverNumFailedResponseWrites";
-
- String TOTAL_SUCCESSFUL_LATENCY = "serverTotalSuccessfulResponseLatency";
- String TOTAL_FAILED_LATENCY = "serverTotalFailedResponseLatency";
- String TIME_TO_FIRST_BYTE = "serverTimeToFirstByte";
-
- String RESPONSES_1XX = "http.status.1xx";
- String RESPONSES_2XX = "http.status.2xx";
- String RESPONSES_3XX = "http.status.3xx";
- String RESPONSES_4XX = "http.status.4xx";
- String RESPONSES_5XX = "http.status.5xx";
- String RESPONSES_401 = "http.status.401";
- String RESPONSES_403 = "http.status.403";
-
- String STARTED_MILLIS = "serverStartedMillis";
-
- String URI_LENGTH = "jdisc.http.request.uri_length";
- String CONTENT_SIZE = "jdisc.http.request.content_size";
-
- String SSL_HANDSHAKE_FAILURE_MISSING_CLIENT_CERT = "jdisc.http.ssl.handshake.failure.missing_client_cert";
- String SSL_HANDSHAKE_FAILURE_EXPIRED_CLIENT_CERT = "jdisc.http.ssl.handshake.failure.expired_client_cert";
- String SSL_HANDSHAKE_FAILURE_INVALID_CLIENT_CERT = "jdisc.http.ssl.handshake.failure.invalid_client_cert";
- String SSL_HANDSHAKE_FAILURE_INCOMPATIBLE_PROTOCOLS = "jdisc.http.ssl.handshake.failure.incompatible_protocols";
- String SSL_HANDSHAKE_FAILURE_INCOMPATIBLE_CIPHERS = "jdisc.http.ssl.handshake.failure.incompatible_ciphers";
- String SSL_HANDSHAKE_FAILURE_UNKNOWN = "jdisc.http.ssl.handshake.failure.unknown";
- }
-
private final static Logger log = Logger.getLogger(JettyHttpServer.class.getName());
- private final long timeStarted = System.currentTimeMillis();
+
private final ExecutorService janitor;
- private final ScheduledExecutorService metricReporterExecutor;
- private final Metric metric;
+
private final Server server;
private final List<Integer> listenedPorts = new ArrayList<>();
+ private final ServerMetricReporter metricsReporter;
@Inject
public JettyHttpServer(CurrentContainer container,
Metric metric,
ServerConfig serverConfig,
ServletPathsConfig servletPathsConfig,
- ThreadFactory threadFactory,
FilterBindings filterBindings,
ComponentRegistry<ConnectorFactory> connectorFactories,
ComponentRegistry<ServletHolder> servletHolders,
@@ -141,13 +77,12 @@ public class JettyHttpServer extends AbstractServerProvider {
super(container);
if (connectorFactories.allComponents().isEmpty())
throw new IllegalArgumentException("No connectors configured.");
- this.metric = metric;
initializeJettyLogging();
server = new Server();
server.setStopTimeout((long)(serverConfig.stopTimeout() * 1000.0));
- server.setRequestLog(new AccessLogRequestLog(accessLog));
+ server.setRequestLog(new AccessLogRequestLog(accessLog, serverConfig.accessLog()));
setupJmx(server, serverConfig);
((QueuedThreadPool)server.getThreadPool()).setMaxThreads(serverConfig.maxWorkerThreads());
@@ -157,7 +92,7 @@ public class JettyHttpServer extends AbstractServerProvider {
listenedPorts.add(connectorConfig.listenPort());
}
- janitor = newJanitor(threadFactory);
+ janitor = newJanitor();
JDiscContext jDiscContext = new JDiscContext(filterBindings.getRequestFilters().activate(),
filterBindings.getResponseFilters().activate(),
@@ -179,16 +114,7 @@ public class JettyHttpServer extends AbstractServerProvider {
jdiscServlet,
servletHolders,
jDiscFilterInvokerFilter));
-
- int numMetricReporterThreads = 1;
- metricReporterExecutor =
- Executors.newScheduledThreadPool(numMetricReporterThreads,
- new ThreadFactoryBuilder()
- .setDaemon(true)
- .setNameFormat(JettyHttpServer.class.getName() + "-MetricReporter-%d")
- .setThreadFactory(threadFactory)
- .build());
- metricReporterExecutor.scheduleAtFixedRate(new MetricTask(), 0, 2, TimeUnit.SECONDS);
+ this.metricsReporter = new ServerMetricReporter(metric, server);
}
private static void initializeJettyLogging() {
@@ -274,23 +200,19 @@ public class JettyHttpServer extends AbstractServerProvider {
return ports.stream().map(Object::toString).collect(Collectors.joining(":"));
}
- private static ExecutorService newJanitor(ThreadFactory factory) {
+ private static ExecutorService newJanitor() {
int threadPoolSize = Runtime.getRuntime().availableProcessors();
log.info("Creating janitor executor with " + threadPoolSize + " threads");
return Executors.newFixedThreadPool(
threadPoolSize,
- new ThreadFactoryBuilder()
- .setDaemon(true)
- .setNameFormat(JettyHttpServer.class.getName() + "-Janitor-%d")
- .setThreadFactory(factory)
- .build()
- );
+ new DaemonThreadFactory(JettyHttpServer.class.getName() + "-Janitor-"));
}
@Override
public void start() {
try {
server.start();
+ metricsReporter.start();
logEffectiveSslConfiguration();
} catch (final Exception e) {
if (e instanceof IOException && e.getCause() instanceof BindException) {
@@ -326,7 +248,7 @@ public class JettyHttpServer extends AbstractServerProvider {
log.log(Level.SEVERE, "Server shutdown threw an unexpected exception.", e);
}
- metricReporterExecutor.shutdown();
+ metricsReporter.shutdown();
janitor.shutdown();
}
@@ -340,56 +262,6 @@ public class JettyHttpServer extends AbstractServerProvider {
Server server() { return server; }
- private class MetricTask implements Runnable {
- @Override
- public void run() {
- HttpResponseStatisticsCollector statisticsCollector = ((AbstractHandlerContainer) server.getHandler())
- .getChildHandlerByClass(HttpResponseStatisticsCollector.class);
- if (statisticsCollector != null) {
- setServerMetrics(statisticsCollector);
- }
-
- // reset statisticsHandler to preserve earlier behavior
- StatisticsHandler statisticsHandler = ((AbstractHandlerContainer) server.getHandler())
- .getChildHandlerByClass(StatisticsHandler.class);
- if (statisticsHandler != null) {
- statisticsHandler.statsReset();
- }
-
- for (Connector connector : server.getConnectors()) {
- setConnectorMetrics((JDiscServerConnector)connector);
- }
- }
-
- }
-
- private void setServerMetrics(HttpResponseStatisticsCollector statisticsCollector) {
- long timeSinceStarted = System.currentTimeMillis() - timeStarted;
- metric.set(Metrics.STARTED_MILLIS, timeSinceStarted, null);
-
- addResponseMetrics(statisticsCollector);
- }
-
- private void addResponseMetrics(HttpResponseStatisticsCollector statisticsCollector) {
- for (var metricEntry : statisticsCollector.takeStatistics()) {
- Map<String, Object> dimensions = new HashMap<>();
- dimensions.put(Metrics.METHOD_DIMENSION, metricEntry.method);
- dimensions.put(Metrics.SCHEME_DIMENSION, metricEntry.scheme);
- dimensions.put(Metrics.REQUEST_TYPE_DIMENSION, metricEntry.requestType);
- metric.add(metricEntry.name, metricEntry.value, metric.createContext(dimensions));
- }
- }
-
- private void setConnectorMetrics(JDiscServerConnector connector) {
- ConnectionStatistics statistics = connector.getStatistics();
- metric.set(Metrics.NUM_CONNECTIONS, statistics.getConnectionsTotal(), connector.getConnectorMetricContext());
- metric.set(Metrics.NUM_OPEN_CONNECTIONS, statistics.getConnections(), connector.getConnectorMetricContext());
- metric.set(Metrics.NUM_CONNECTIONS_OPEN_MAX, statistics.getConnectionsMax(), connector.getConnectorMetricContext());
- metric.set(Metrics.CONNECTION_DURATION_MAX, statistics.getConnectionDurationMax(), connector.getConnectorMetricContext());
- metric.set(Metrics.CONNECTION_DURATION_MEAN, statistics.getConnectionDurationMean(), connector.getConnectorMetricContext());
- metric.set(Metrics.CONNECTION_DURATION_STD_DEV, statistics.getConnectionDurationStdDev(), connector.getConnectorMetricContext());
- }
-
private StatisticsHandler newStatisticsHandler() {
StatisticsHandler statisticsHandler = new StatisticsHandler();
statisticsHandler.statsReset();
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/MetricDefinitions.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/MetricDefinitions.java
new file mode 100644
index 00000000000..a55a6e8a734
--- /dev/null
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/MetricDefinitions.java
@@ -0,0 +1,71 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jdisc.http.server.jetty;
+
+/**
+ * Name and dimensions for jdisc/container metrics
+ *
+ * @author bjorncs
+ */
+class MetricDefinitions {
+ static final String NAME_DIMENSION = "serverName";
+ static final String PORT_DIMENSION = "serverPort";
+ static final String METHOD_DIMENSION = "httpMethod";
+ static final String SCHEME_DIMENSION = "scheme";
+ static final String REQUEST_TYPE_DIMENSION = "requestType";
+ static final String CLIENT_IP_DIMENSION = "clientIp";
+
+ static final String NUM_OPEN_CONNECTIONS = "serverNumOpenConnections";
+ static final String NUM_CONNECTIONS_OPEN_MAX = "serverConnectionsOpenMax";
+ static final String CONNECTION_DURATION_MAX = "serverConnectionDurationMax";
+ static final String CONNECTION_DURATION_MEAN = "serverConnectionDurationMean";
+ static final String CONNECTION_DURATION_STD_DEV = "serverConnectionDurationStdDev";
+ static final String NUM_PREMATURELY_CLOSED_CONNECTIONS = "jdisc.http.request.prematurely_closed";
+
+ static final String NUM_BYTES_RECEIVED = "serverBytesReceived";
+ static final String NUM_BYTES_SENT = "serverBytesSent";
+
+ static final String NUM_CONNECTIONS = "serverNumConnections";
+
+ /* For historical reasons, these are all aliases for the same metric. 'jdisc.http' should ideally be the only one. */
+ static final String JDISC_HTTP_REQUESTS = "jdisc.http.requests";
+ static final String NUM_REQUESTS = "serverNumRequests";
+
+ static final String NUM_SUCCESSFUL_RESPONSES = "serverNumSuccessfulResponses";
+ static final String NUM_FAILED_RESPONSES = "serverNumFailedResponses";
+ static final String NUM_SUCCESSFUL_WRITES = "serverNumSuccessfulResponseWrites";
+ static final String NUM_FAILED_WRITES = "serverNumFailedResponseWrites";
+
+ static final String TOTAL_SUCCESSFUL_LATENCY = "serverTotalSuccessfulResponseLatency";
+ static final String TOTAL_FAILED_LATENCY = "serverTotalFailedResponseLatency";
+ static final String TIME_TO_FIRST_BYTE = "serverTimeToFirstByte";
+
+ static final String RESPONSES_1XX = "http.status.1xx";
+ static final String RESPONSES_2XX = "http.status.2xx";
+ static final String RESPONSES_3XX = "http.status.3xx";
+ static final String RESPONSES_4XX = "http.status.4xx";
+ static final String RESPONSES_5XX = "http.status.5xx";
+ static final String RESPONSES_401 = "http.status.401";
+ static final String RESPONSES_403 = "http.status.403";
+
+ static final String STARTED_MILLIS = "serverStartedMillis";
+
+ static final String URI_LENGTH = "jdisc.http.request.uri_length";
+ static final String CONTENT_SIZE = "jdisc.http.request.content_size";
+
+ static final String SSL_HANDSHAKE_FAILURE_MISSING_CLIENT_CERT = "jdisc.http.ssl.handshake.failure.missing_client_cert";
+ static final String SSL_HANDSHAKE_FAILURE_EXPIRED_CLIENT_CERT = "jdisc.http.ssl.handshake.failure.expired_client_cert";
+ static final String SSL_HANDSHAKE_FAILURE_INVALID_CLIENT_CERT = "jdisc.http.ssl.handshake.failure.invalid_client_cert";
+ static final String SSL_HANDSHAKE_FAILURE_INCOMPATIBLE_PROTOCOLS = "jdisc.http.ssl.handshake.failure.incompatible_protocols";
+ static final String SSL_HANDSHAKE_FAILURE_INCOMPATIBLE_CIPHERS = "jdisc.http.ssl.handshake.failure.incompatible_ciphers";
+ static final String SSL_HANDSHAKE_FAILURE_UNKNOWN = "jdisc.http.ssl.handshake.failure.unknown";
+
+ static final String JETTY_THREADPOOL_MAX_THREADS = "jdisc.http.jetty.threadpool.thread.max";
+ static final String JETTY_THREADPOOL_MIN_THREADS = "jdisc.http.jetty.threadpool.thread.min";
+ static final String JETTY_THREADPOOL_RESERVED_THREADS = "jdisc.http.jetty.threadpool.thread.reserved";
+ static final String JETTY_THREADPOOL_BUSY_THREADS = "jdisc.http.jetty.threadpool.thread.busy";
+ static final String JETTY_THREADPOOL_IDLE_THREADS = "jdisc.http.jetty.threadpool.thread.idle";
+ static final String JETTY_THREADPOOL_TOTAL_THREADS = "jdisc.http.jetty.threadpool.thread.total";
+ static final String JETTY_THREADPOOL_QUEUE_SIZE = "jdisc.http.jetty.threadpool.queue.size";
+
+ private MetricDefinitions() {}
+}
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/MetricReporter.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/RequestMetricReporter.java
index 21a64792731..7596be0415a 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/MetricReporter.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/RequestMetricReporter.java
@@ -4,8 +4,6 @@ package com.yahoo.jdisc.http.server.jetty;
import com.yahoo.jdisc.Metric;
import com.yahoo.jdisc.Metric.Context;
-import com.yahoo.jdisc.http.server.jetty.JettyHttpServer.Metrics;
-
import java.util.concurrent.atomic.AtomicBoolean;
@@ -13,7 +11,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
* Responsible for metric reporting for JDisc http request handler support.
* @author Tony Vaagenes
*/
-public class MetricReporter {
+class RequestMetricReporter {
private final Metric metric;
private final Context context;
@@ -23,65 +21,65 @@ public class MetricReporter {
private final AtomicBoolean firstSetOfTimeToFirstByte = new AtomicBoolean(true);
- public MetricReporter(Metric metric, Context context, long requestStartTime) {
+ RequestMetricReporter(Metric metric, Context context, long requestStartTime) {
this.metric = metric;
this.context = context;
this.requestStartTime = requestStartTime;
}
- public void successfulWrite(int numBytes) {
+ void successfulWrite(int numBytes) {
setTimeToFirstByteFirstTime();
- metric.add(Metrics.NUM_SUCCESSFUL_WRITES, 1, context);
- metric.set(Metrics.NUM_BYTES_SENT, numBytes, context);
+ metric.add(MetricDefinitions.NUM_SUCCESSFUL_WRITES, 1, context);
+ metric.set(MetricDefinitions.NUM_BYTES_SENT, numBytes, context);
}
private void setTimeToFirstByteFirstTime() {
boolean isFirstWrite = firstSetOfTimeToFirstByte.getAndSet(false);
if (isFirstWrite) {
long timeToFirstByte = getRequestLatency();
- metric.set(Metrics.TIME_TO_FIRST_BYTE, timeToFirstByte, context);
+ metric.set(MetricDefinitions.TIME_TO_FIRST_BYTE, timeToFirstByte, context);
}
}
- public void failedWrite() {
- metric.add(Metrics.NUM_FAILED_WRITES, 1, context);
+ void failedWrite() {
+ metric.add(MetricDefinitions.NUM_FAILED_WRITES, 1, context);
}
- public void successfulResponse() {
+ void successfulResponse() {
setTimeToFirstByteFirstTime();
long requestLatency = getRequestLatency();
- metric.set(Metrics.TOTAL_SUCCESSFUL_LATENCY, requestLatency, context);
+ metric.set(MetricDefinitions.TOTAL_SUCCESSFUL_LATENCY, requestLatency, context);
- metric.add(Metrics.NUM_SUCCESSFUL_RESPONSES, 1, context);
+ metric.add(MetricDefinitions.NUM_SUCCESSFUL_RESPONSES, 1, context);
}
- public void failedResponse() {
+ void failedResponse() {
setTimeToFirstByteFirstTime();
- metric.set(Metrics.TOTAL_FAILED_LATENCY, getRequestLatency(), context);
- metric.add(Metrics.NUM_FAILED_RESPONSES, 1, context);
+ metric.set(MetricDefinitions.TOTAL_FAILED_LATENCY, getRequestLatency(), context);
+ metric.add(MetricDefinitions.NUM_FAILED_RESPONSES, 1, context);
}
- public void prematurelyClosed() {
- metric.add(Metrics.NUM_PREMATURELY_CLOSED_CONNECTIONS, 1, context);
+ void prematurelyClosed() {
+ metric.add(MetricDefinitions.NUM_PREMATURELY_CLOSED_CONNECTIONS, 1, context);
}
- public void successfulRead(int bytes_received) {
- metric.set(JettyHttpServer.Metrics.NUM_BYTES_RECEIVED, bytes_received, context);
+ void successfulRead(int bytes_received) {
+ metric.set(MetricDefinitions.NUM_BYTES_RECEIVED, bytes_received, context);
}
private long getRequestLatency() {
return System.currentTimeMillis() - requestStartTime;
}
- public void uriLength(int length) {
- metric.set(Metrics.URI_LENGTH, length, context);
+ void uriLength(int length) {
+ metric.set(MetricDefinitions.URI_LENGTH, length, context);
}
- public void contentSize(int size) {
- metric.set(Metrics.CONTENT_SIZE, size, context);
+ void contentSize(int size) {
+ metric.set(MetricDefinitions.CONTENT_SIZE, size, context);
}
}
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServerMetricReporter.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServerMetricReporter.java
new file mode 100644
index 00000000000..ba3694ffc2f
--- /dev/null
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServerMetricReporter.java
@@ -0,0 +1,115 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jdisc.http.server.jetty;
+
+import com.yahoo.concurrent.DaemonThreadFactory;
+import com.yahoo.jdisc.Metric;
+import org.eclipse.jetty.io.ConnectionStatistics;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.AbstractHandlerContainer;
+import org.eclipse.jetty.server.handler.StatisticsHandler;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+
+import java.time.Instant;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Reports server/connector specific metrics for Jdisc and Jetty
+ *
+ * @author bjorncs
+ */
+class ServerMetricReporter {
+
+ private final ScheduledExecutorService executor =
+ Executors.newScheduledThreadPool(1, new DaemonThreadFactory("jdisc-jetty-metric-reporter-"));
+ private final Metric metric;
+ private final Server jetty;
+
+ ServerMetricReporter(Metric metric, Server jetty) {
+ this.metric = metric;
+ this.jetty = jetty;
+ }
+
+ void start() {
+ executor.scheduleAtFixedRate(new ReporterTask(), 0, 2, TimeUnit.SECONDS);
+ }
+
+ void shutdown() {
+ try {
+ executor.shutdownNow();
+ executor.awaitTermination(10, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ private class ReporterTask implements Runnable {
+
+ private final Instant timeStarted = Instant.now();
+
+ @Override
+ public void run() {
+ HttpResponseStatisticsCollector statisticsCollector = ((AbstractHandlerContainer) jetty.getHandler())
+ .getChildHandlerByClass(HttpResponseStatisticsCollector.class);
+ if (statisticsCollector != null) {
+ setServerMetrics(statisticsCollector);
+ }
+
+ // reset statisticsHandler to preserve earlier behavior
+ StatisticsHandler statisticsHandler = ((AbstractHandlerContainer) jetty.getHandler())
+ .getChildHandlerByClass(StatisticsHandler.class);
+ if (statisticsHandler != null) {
+ statisticsHandler.statsReset();
+ }
+
+ for (Connector connector : jetty.getConnectors()) {
+ setConnectorMetrics((JDiscServerConnector)connector);
+ }
+
+ setJettyThreadpoolMetrics();
+ }
+
+ private void setServerMetrics(HttpResponseStatisticsCollector statisticsCollector) {
+ long timeSinceStarted = System.currentTimeMillis() - timeStarted.toEpochMilli();
+ metric.set(MetricDefinitions.STARTED_MILLIS, timeSinceStarted, null);
+
+ addResponseMetrics(statisticsCollector);
+ }
+
+ private void addResponseMetrics(HttpResponseStatisticsCollector statisticsCollector) {
+ for (var metricEntry : statisticsCollector.takeStatistics()) {
+ Map<String, Object> dimensions = new HashMap<>();
+ dimensions.put(MetricDefinitions.METHOD_DIMENSION, metricEntry.method);
+ dimensions.put(MetricDefinitions.SCHEME_DIMENSION, metricEntry.scheme);
+ dimensions.put(MetricDefinitions.REQUEST_TYPE_DIMENSION, metricEntry.requestType);
+ metric.add(metricEntry.name, metricEntry.value, metric.createContext(dimensions));
+ }
+ }
+
+ private void setJettyThreadpoolMetrics() {
+ QueuedThreadPool threadpool = (QueuedThreadPool) jetty.getThreadPool();
+ metric.set(MetricDefinitions.JETTY_THREADPOOL_MAX_THREADS, threadpool.getMaxThreads(), null);
+ metric.set(MetricDefinitions.JETTY_THREADPOOL_MIN_THREADS, threadpool.getMinThreads(), null);
+ metric.set(MetricDefinitions.JETTY_THREADPOOL_RESERVED_THREADS, threadpool.getReservedThreads(), null);
+ metric.set(MetricDefinitions.JETTY_THREADPOOL_BUSY_THREADS, threadpool.getBusyThreads(), null);
+ metric.set(MetricDefinitions.JETTY_THREADPOOL_IDLE_THREADS, threadpool.getIdleThreads(), null);
+ metric.set(MetricDefinitions.JETTY_THREADPOOL_TOTAL_THREADS, threadpool.getThreads(), null);
+ metric.set(MetricDefinitions.JETTY_THREADPOOL_QUEUE_SIZE, threadpool.getQueueSize(), null);
+ }
+
+ private void setConnectorMetrics(JDiscServerConnector connector) {
+ ConnectionStatistics statistics = connector.getStatistics();
+ metric.set(MetricDefinitions.NUM_CONNECTIONS, statistics.getConnectionsTotal(), connector.getConnectorMetricContext());
+ metric.set(MetricDefinitions.NUM_OPEN_CONNECTIONS, statistics.getConnections(), connector.getConnectorMetricContext());
+ metric.set(MetricDefinitions.NUM_CONNECTIONS_OPEN_MAX, statistics.getConnectionsMax(), connector.getConnectorMetricContext());
+ metric.set(MetricDefinitions.CONNECTION_DURATION_MAX, statistics.getConnectionDurationMax(), connector.getConnectorMetricContext());
+ metric.set(MetricDefinitions.CONNECTION_DURATION_MEAN, statistics.getConnectionDurationMean(), connector.getConnectorMetricContext());
+ metric.set(MetricDefinitions.CONNECTION_DURATION_STD_DEV, statistics.getConnectionDurationStdDev(), connector.getConnectorMetricContext());
+ }
+
+ }
+}
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletOutputStreamWriter.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletOutputStreamWriter.java
index a764c75f766..b4d03385c3b 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletOutputStreamWriter.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletOutputStreamWriter.java
@@ -59,7 +59,7 @@ public class ServletOutputStreamWriter {
// GuardedBy("monitor")
private final Deque<ResponseContentPart> responseContentQueue = new ArrayDeque<>();
- private final MetricReporter metricReporter;
+ private final RequestMetricReporter metricReporter;
/**
* When this future completes there will be no more calls against the servlet output stream or servlet response.
@@ -70,7 +70,7 @@ public class ServletOutputStreamWriter {
final CompletableFuture<Void> finishedFuture = new CompletableFuture<>();
- public ServletOutputStreamWriter(ServletOutputStream outputStream, Executor executor, MetricReporter metricReporter) {
+ public ServletOutputStreamWriter(ServletOutputStream outputStream, Executor executor, RequestMetricReporter metricReporter) {
this.outputStream = outputStream;
this.executor = executor;
this.metricReporter = metricReporter;
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletRequestReader.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletRequestReader.java
index fd1f84f7d49..9e7912f2dc1 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletRequestReader.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletRequestReader.java
@@ -43,7 +43,7 @@ class ServletRequestReader implements ReadListener {
private final ContentChannel requestContentChannel;
private final Executor executor;
- private final MetricReporter metricReporter;
+ private final RequestMetricReporter metricReporter;
private int bytesRead;
@@ -94,7 +94,7 @@ class ServletRequestReader implements ReadListener {
ServletInputStream servletInputStream,
ContentChannel requestContentChannel,
Executor executor,
- MetricReporter metricReporter) {
+ RequestMetricReporter metricReporter) {
Preconditions.checkNotNull(servletInputStream);
Preconditions.checkNotNull(requestContentChannel);
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletResponseController.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletResponseController.java
index 5dd6b72dc20..60b7878156f 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletResponseController.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletResponseController.java
@@ -58,7 +58,7 @@ public class ServletResponseController {
HttpServletRequest servletRequest,
HttpServletResponse servletResponse,
Executor executor,
- MetricReporter metricReporter,
+ RequestMetricReporter metricReporter,
boolean developerMode) throws IOException {
this.servletRequest = servletRequest;
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/SslHandshakeFailedListener.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/SslHandshakeFailedListener.java
index fc9a6fc03be..4c9059b5b37 100644
--- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/SslHandshakeFailedListener.java
+++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/SslHandshakeFailedListener.java
@@ -2,7 +2,6 @@
package com.yahoo.jdisc.http.server.jetty;
import com.yahoo.jdisc.Metric;
-import com.yahoo.jdisc.http.server.jetty.JettyHttpServer.Metrics;
import org.eclipse.jetty.io.ssl.SslHandshakeListener;
import javax.net.ssl.SSLHandshakeException;
@@ -38,36 +37,36 @@ class SslHandshakeFailedListener implements SslHandshakeListener {
log.log(Level.FINE, throwable, () -> "Ssl handshake failed: " + throwable.getMessage());
String metricName = SslHandshakeFailure.fromSslHandshakeException((SSLHandshakeException) throwable)
.map(SslHandshakeFailure::metricName)
- .orElse(Metrics.SSL_HANDSHAKE_FAILURE_UNKNOWN);
+ .orElse(MetricDefinitions.SSL_HANDSHAKE_FAILURE_UNKNOWN);
metric.add(metricName, 1L, metric.createContext(createDimensions(event)));
}
private Map<String, Object> createDimensions(Event event) {
Map<String, Object> dimensions = new HashMap<>();
- dimensions.put(Metrics.NAME_DIMENSION, connectorName);
- dimensions.put(Metrics.PORT_DIMENSION, listenPort);
+ dimensions.put(MetricDefinitions.NAME_DIMENSION, connectorName);
+ dimensions.put(MetricDefinitions.PORT_DIMENSION, listenPort);
Optional.ofNullable(event.getSSLEngine().getPeerHost())
- .ifPresent(clientIp -> dimensions.put(Metrics.CLIENT_IP_DIMENSION, clientIp));
+ .ifPresent(clientIp -> dimensions.put(MetricDefinitions.CLIENT_IP_DIMENSION, clientIp));
return Map.copyOf(dimensions);
}
private enum SslHandshakeFailure {
INCOMPATIBLE_PROTOCOLS(
- Metrics.SSL_HANDSHAKE_FAILURE_INCOMPATIBLE_PROTOCOLS,
+ MetricDefinitions.SSL_HANDSHAKE_FAILURE_INCOMPATIBLE_PROTOCOLS,
"(Client requested protocol \\S+? is not enabled or supported in server context" +
"|The client supported protocol versions \\[\\S+?\\] are not accepted by server preferences \\[\\S+?\\])"),
INCOMPATIBLE_CIPHERS(
- Metrics.SSL_HANDSHAKE_FAILURE_INCOMPATIBLE_CIPHERS,
+ MetricDefinitions.SSL_HANDSHAKE_FAILURE_INCOMPATIBLE_CIPHERS,
"no cipher suites in common"),
MISSING_CLIENT_CERT(
- Metrics.SSL_HANDSHAKE_FAILURE_MISSING_CLIENT_CERT,
+ MetricDefinitions.SSL_HANDSHAKE_FAILURE_MISSING_CLIENT_CERT,
"Empty server certificate chain"),
EXPIRED_CLIENT_CERTIFICATE(
- Metrics.SSL_HANDSHAKE_FAILURE_EXPIRED_CLIENT_CERT,
+ MetricDefinitions.SSL_HANDSHAKE_FAILURE_EXPIRED_CLIENT_CERT,
// Note: this pattern will match certificates with too late notBefore as well
"PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed"),
INVALID_CLIENT_CERT(
- Metrics.SSL_HANDSHAKE_FAILURE_INVALID_CLIENT_CERT, // Includes mismatch of client certificate and private key
+ MetricDefinitions.SSL_HANDSHAKE_FAILURE_INVALID_CLIENT_CERT, // Includes mismatch of client certificate and private key
"(PKIX path (building|validation) failed: .+)|(Invalid CertificateVerify signature)");
private final String metricName;
diff --git a/jdisc_http_service/src/main/resources/configdefinitions/jdisc.http.jdisc.http.server.def b/jdisc_http_service/src/main/resources/configdefinitions/jdisc.http.jdisc.http.server.def
index 0cb5b89b20c..3118a7dea64 100644
--- a/jdisc_http_service/src/main/resources/configdefinitions/jdisc.http.jdisc.http.server.def
+++ b/jdisc_http_service/src/main/resources/configdefinitions/jdisc.http.jdisc.http.server.def
@@ -43,4 +43,10 @@ jmx.listenPort int default = 1099
metric.monitoringHandlerPaths[] string
# Paths that should be reported with search dimensions where applicable
-metric.searchHandlerPaths[] string \ No newline at end of file
+metric.searchHandlerPaths[] string
+
+# HTTP request headers that contain remote address
+accessLog.remoteAddressHeaders[] string
+
+# HTTP request headers that contain remote port
+accessLog.remotePortHeaders[] string
diff --git a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLogTest.java b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLogTest.java
index 69535be034c..a4fd7c9bc5f 100644
--- a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLogTest.java
+++ b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLogTest.java
@@ -3,6 +3,7 @@ package com.yahoo.jdisc.http.server.jetty;
import com.yahoo.container.logging.AccessLog;
import com.yahoo.container.logging.AccessLogEntry;
+import com.yahoo.jdisc.http.ServerConfig;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpConnection;
@@ -11,6 +12,7 @@ import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.ServerConnector;
import org.junit.Test;
+import java.util.List;
import java.util.Optional;
import static org.hamcrest.CoreMatchers.is;
@@ -33,7 +35,7 @@ public class AccessLogRequestLogTest {
when(jettyRequest.getRequestURI()).thenReturn("/search/");
when(jettyRequest.getQueryString()).thenReturn("query=year:>2010");
- new AccessLogRequestLog(mock(AccessLog.class)).log(jettyRequest, createResponseMock());
+ doAccessLoggingOfRequest(jettyRequest);
assertThat(accessLogEntry.getRawPath(), is(not(nullValue())));
assertTrue(accessLogEntry.getRawQuery().isPresent());
@@ -48,7 +50,7 @@ public class AccessLogRequestLogTest {
final String query = "query=year%252010+%3B&customParameter=something";
when(jettyRequest.getQueryString()).thenReturn(query);
- new AccessLogRequestLog(mock(AccessLog.class)).log(jettyRequest, createResponseMock());
+ doAccessLoggingOfRequest(jettyRequest);
assertThat(accessLogEntry.getRawPath(), is(path));
assertThat(accessLogEntry.getRawQuery().get(), is(query));
@@ -64,7 +66,7 @@ public class AccessLogRequestLogTest {
String rawQuery = "q=%%2";
when(jettyRequest.getQueryString()).thenReturn(rawQuery);
- new AccessLogRequestLog(mock(AccessLog.class)).log(jettyRequest, createResponseMock());
+ doAccessLoggingOfRequest(jettyRequest);
assertThat(accessLogEntry.getRawPath(), is(rawPath));
Optional<String> actualRawQuery = accessLogEntry.getRawQuery();
assertThat(actualRawQuery.isPresent(), is(true));
@@ -80,7 +82,7 @@ public class AccessLogRequestLogTest {
when(jettyRequest.getHeader("x-forwarded-for")).thenReturn("1.2.3.4");
when(jettyRequest.getHeader("y-ra")).thenReturn("2.3.4.5");
- new AccessLogRequestLog(mock(AccessLog.class)).log(jettyRequest, createResponseMock());
+ doAccessLoggingOfRequest(jettyRequest);
assertThat(accessLogEntry.getRemoteAddress(), is("1.2.3.4"));
}
@@ -93,7 +95,7 @@ public class AccessLogRequestLogTest {
when(jettyRequest.getHeader("X-Forwarded-Port")).thenReturn("80");
when(jettyRequest.getHeader("y-rp")).thenReturn("8080");
- new AccessLogRequestLog(mock(AccessLog.class)).log(jettyRequest, createResponseMock());
+ doAccessLoggingOfRequest(jettyRequest);
assertThat(accessLogEntry.getRemotePort(), is(80));
}
@@ -105,11 +107,19 @@ public class AccessLogRequestLogTest {
when(jettyRequest.getHeader("X-Forwarded-Port")).thenReturn("8o8o");
when(jettyRequest.getRemotePort()).thenReturn(80);
- new AccessLogRequestLog(mock(AccessLog.class)).log(jettyRequest, createResponseMock());
+ doAccessLoggingOfRequest(jettyRequest);
assertThat(accessLogEntry.getRemotePort(), is(0));
assertThat(accessLogEntry.getPeerPort(), is(80));
}
+ private void doAccessLoggingOfRequest(Request jettyRequest) {
+ ServerConfig.AccessLog config = new ServerConfig.AccessLog(
+ new ServerConfig.AccessLog.Builder()
+ .remoteAddressHeaders(List.of("x-forwarded-for", "y-ra"))
+ .remotePortHeaders(List.of("X-Forwarded-Port", "y-rp")));
+ new AccessLogRequestLog(mock(AccessLog.class), config).log(jettyRequest, createResponseMock());
+ }
+
private static Request createRequestMock(AccessLogEntry entry) {
ServerConnector serverConnector = mock(ServerConnector.class);
when(serverConnector.getLocalPort()).thenReturn(1234);
diff --git a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpResponseStatisticsCollectorTest.java b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpResponseStatisticsCollectorTest.java
index 4ae824e2b7a..bb92d75bed5 100644
--- a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpResponseStatisticsCollectorTest.java
+++ b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpResponseStatisticsCollectorTest.java
@@ -2,7 +2,6 @@
package com.yahoo.jdisc.http.server.jetty;
import com.yahoo.jdisc.http.server.jetty.HttpResponseStatisticsCollector.StatisticsEntry;
-import com.yahoo.jdisc.http.server.jetty.JettyHttpServer.Metrics;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
@@ -48,8 +47,8 @@ public class HttpResponseStatisticsCollectorTest {
testRequest("http", 200, "GET");
var stats = collector.takeStatistics();
- assertStatisticsEntryPresent(stats, "http", "GET", Metrics.RESPONSES_2XX, 1L);
- assertStatisticsEntryPresent(stats, "http", "GET", Metrics.RESPONSES_3XX, 2L);
+ assertStatisticsEntryPresent(stats, "http", "GET", MetricDefinitions.RESPONSES_2XX, 1L);
+ assertStatisticsEntryPresent(stats, "http", "GET", MetricDefinitions.RESPONSES_3XX, 2L);
}
@Test
@@ -66,12 +65,12 @@ public class HttpResponseStatisticsCollectorTest {
testRequest("https", 200, "POST");
var stats = collector.takeStatistics();
- assertStatisticsEntryPresent(stats, "http", "GET", Metrics.RESPONSES_2XX, 1L);
- assertStatisticsEntryPresent(stats, "http", "GET", Metrics.RESPONSES_4XX, 1L);
- assertStatisticsEntryPresent(stats, "http", "PUT", Metrics.RESPONSES_2XX, 1L);
- assertStatisticsEntryPresent(stats, "http", "POST", Metrics.RESPONSES_2XX, 2L);
- assertStatisticsEntryPresent(stats, "https", "GET", Metrics.RESPONSES_4XX, 1L);
- assertStatisticsEntryPresent(stats, "https", "POST", Metrics.RESPONSES_2XX, 4L);
+ assertStatisticsEntryPresent(stats, "http", "GET", MetricDefinitions.RESPONSES_2XX, 1L);
+ assertStatisticsEntryPresent(stats, "http", "GET", MetricDefinitions.RESPONSES_4XX, 1L);
+ assertStatisticsEntryPresent(stats, "http", "PUT", MetricDefinitions.RESPONSES_2XX, 1L);
+ assertStatisticsEntryPresent(stats, "http", "POST", MetricDefinitions.RESPONSES_2XX, 2L);
+ assertStatisticsEntryPresent(stats, "https", "GET", MetricDefinitions.RESPONSES_4XX, 1L);
+ assertStatisticsEntryPresent(stats, "https", "POST", MetricDefinitions.RESPONSES_2XX, 4L);
}
@Test
@@ -81,9 +80,9 @@ public class HttpResponseStatisticsCollectorTest {
testRequest("http", 403, "GET");
var stats = collector.takeStatistics();
- assertStatisticsEntryPresent(stats, "http", "GET", Metrics.RESPONSES_4XX, 3L);
- assertStatisticsEntryPresent(stats, "http", "GET", Metrics.RESPONSES_401, 1L);
- assertStatisticsEntryPresent(stats, "http", "GET", Metrics.RESPONSES_403, 1L);
+ assertStatisticsEntryPresent(stats, "http", "GET", MetricDefinitions.RESPONSES_4XX, 3L);
+ assertStatisticsEntryPresent(stats, "http", "GET", MetricDefinitions.RESPONSES_401, 1L);
+ assertStatisticsEntryPresent(stats, "http", "GET", MetricDefinitions.RESPONSES_403, 1L);
}
@@ -93,12 +92,12 @@ public class HttpResponseStatisticsCollectorTest {
testRequest("http", 200, "GET");
var stats = collector.takeStatistics();
- assertStatisticsEntryPresent(stats, "http", "GET", Metrics.RESPONSES_2XX, 2L);
+ assertStatisticsEntryPresent(stats, "http", "GET", MetricDefinitions.RESPONSES_2XX, 2L);
testRequest("http", 200, "GET");
stats = collector.takeStatistics();
- assertStatisticsEntryPresent(stats, "http", "GET", Metrics.RESPONSES_2XX, 1L);
+ assertStatisticsEntryPresent(stats, "http", "GET", MetricDefinitions.RESPONSES_2XX, 1L);
}
@Test
@@ -109,15 +108,15 @@ public class HttpResponseStatisticsCollectorTest {
testRequest("http", 200, "GET", "/status.html?foo=bar");
var stats = collector.takeStatistics();
- assertStatisticsEntryWithRequestTypePresent(stats, "http", "GET", Metrics.RESPONSES_2XX, "monitoring", 1L);
- assertStatisticsEntryWithRequestTypePresent(stats, "http", "GET", Metrics.RESPONSES_2XX, "read", 1L);
- assertStatisticsEntryWithRequestTypePresent(stats, "http", "POST", Metrics.RESPONSES_2XX, "read", 1L);
- assertStatisticsEntryWithRequestTypePresent(stats, "http", "POST", Metrics.RESPONSES_2XX, "write", 1L);
+ assertStatisticsEntryWithRequestTypePresent(stats, "http", "GET", MetricDefinitions.RESPONSES_2XX, "monitoring", 1L);
+ assertStatisticsEntryWithRequestTypePresent(stats, "http", "GET", MetricDefinitions.RESPONSES_2XX, "read", 1L);
+ assertStatisticsEntryWithRequestTypePresent(stats, "http", "POST", MetricDefinitions.RESPONSES_2XX, "read", 1L);
+ assertStatisticsEntryWithRequestTypePresent(stats, "http", "POST", MetricDefinitions.RESPONSES_2XX, "write", 1L);
testRequest("http", 200, "GET");
stats = collector.takeStatistics();
- assertStatisticsEntryPresent(stats, "http", "GET", Metrics.RESPONSES_2XX, 1L);
+ assertStatisticsEntryPresent(stats, "http", "GET", MetricDefinitions.RESPONSES_2XX, 1L);
}
@Test
@@ -125,7 +124,7 @@ public class HttpResponseStatisticsCollectorTest {
testRequest("http", 200, "GET", "/search", com.yahoo.jdisc.Request.RequestType.WRITE);
var stats = collector.takeStatistics();
- assertStatisticsEntryWithRequestTypePresent(stats, "http", "GET", Metrics.RESPONSES_2XX, "write", 1L);
+ assertStatisticsEntryWithRequestTypePresent(stats, "http", "GET", MetricDefinitions.RESPONSES_2XX, "write", 1L);
}
@Before
diff --git a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java
index 96cf1d4c01f..01ba776fbf0 100644
--- a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java
+++ b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java
@@ -23,7 +23,6 @@ import com.yahoo.jdisc.http.Cookie;
import com.yahoo.jdisc.http.HttpRequest;
import com.yahoo.jdisc.http.HttpResponse;
import com.yahoo.jdisc.http.ServerConfig;
-import com.yahoo.jdisc.http.server.jetty.JettyHttpServer.Metrics;
import com.yahoo.jdisc.http.server.jetty.TestDrivers.TlsClientAuth;
import com.yahoo.jdisc.service.BindingSetNotFoundException;
import com.yahoo.security.KeyUtils;
@@ -657,7 +656,7 @@ public class HttpServerTest {
assertHttpsRequestTriggersSslHandshakeException(
driver, clientCtx, null, null, "Received fatal alert: bad_certificate");
verify(metricConsumer.mockitoMock())
- .add(Metrics.SSL_HANDSHAKE_FAILURE_MISSING_CLIENT_CERT, 1L, MetricConsumerMock.STATIC_CONTEXT);
+ .add(MetricDefinitions.SSL_HANDSHAKE_FAILURE_MISSING_CLIENT_CERT, 1L, MetricConsumerMock.STATIC_CONTEXT);
assertTrue(driver.close());
}
@@ -677,7 +676,7 @@ public class HttpServerTest {
assertHttpsRequestTriggersSslHandshakeException(
driver, clientCtx, "TLSv1.3", null, "Received fatal alert: protocol_version");
verify(metricConsumer.mockitoMock())
- .add(Metrics.SSL_HANDSHAKE_FAILURE_INCOMPATIBLE_PROTOCOLS, 1L, MetricConsumerMock.STATIC_CONTEXT);
+ .add(MetricDefinitions.SSL_HANDSHAKE_FAILURE_INCOMPATIBLE_PROTOCOLS, 1L, MetricConsumerMock.STATIC_CONTEXT);
assertTrue(driver.close());
}
@@ -697,7 +696,7 @@ public class HttpServerTest {
assertHttpsRequestTriggersSslHandshakeException(
driver, clientCtx, null, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "Received fatal alert: handshake_failure");
verify(metricConsumer.mockitoMock())
- .add(Metrics.SSL_HANDSHAKE_FAILURE_INCOMPATIBLE_CIPHERS, 1L, MetricConsumerMock.STATIC_CONTEXT);
+ .add(MetricDefinitions.SSL_HANDSHAKE_FAILURE_INCOMPATIBLE_CIPHERS, 1L, MetricConsumerMock.STATIC_CONTEXT);
assertTrue(driver.close());
}
@@ -721,7 +720,7 @@ public class HttpServerTest {
assertHttpsRequestTriggersSslHandshakeException(
driver, clientCtx, null, null, "Received fatal alert: certificate_unknown");
verify(metricConsumer.mockitoMock())
- .add(Metrics.SSL_HANDSHAKE_FAILURE_INVALID_CLIENT_CERT, 1L, MetricConsumerMock.STATIC_CONTEXT);
+ .add(MetricDefinitions.SSL_HANDSHAKE_FAILURE_INVALID_CLIENT_CERT, 1L, MetricConsumerMock.STATIC_CONTEXT);
assertTrue(driver.close());
}
@@ -744,7 +743,7 @@ public class HttpServerTest {
assertHttpsRequestTriggersSslHandshakeException(
driver, clientCtx, null, null, "Received fatal alert: certificate_unknown");
verify(metricConsumer.mockitoMock())
- .add(Metrics.SSL_HANDSHAKE_FAILURE_EXPIRED_CLIENT_CERT, 1L, MetricConsumerMock.STATIC_CONTEXT);
+ .add(MetricDefinitions.SSL_HANDSHAKE_FAILURE_EXPIRED_CLIENT_CERT, 1L, MetricConsumerMock.STATIC_CONTEXT);
assertTrue(driver.close());
}
diff --git a/logd/src/tests/empty_forwarder/empty_forwarder_test.cpp b/logd/src/tests/empty_forwarder/empty_forwarder_test.cpp
index d1194f30c40..dbc76e694f2 100644
--- a/logd/src/tests/empty_forwarder/empty_forwarder_test.cpp
+++ b/logd/src/tests/empty_forwarder/empty_forwarder_test.cpp
@@ -11,7 +11,7 @@ using vespalib::metrics::DummyMetricsManager;
struct MockMetricsManager : public DummyMetricsManager {
int add_count;
- MockMetricsManager() : DummyMetricsManager(), add_count(0) {}
+ MockMetricsManager() noexcept : DummyMetricsManager(), add_count(0) {}
void add(Counter::Increment) override {
++add_count;
}
diff --git a/logd/src/tests/rpc_forwarder/rpc_forwarder_test.cpp b/logd/src/tests/rpc_forwarder/rpc_forwarder_test.cpp
index 15a1dc36a87..d39a9ade0a8 100644
--- a/logd/src/tests/rpc_forwarder/rpc_forwarder_test.cpp
+++ b/logd/src/tests/rpc_forwarder/rpc_forwarder_test.cpp
@@ -85,7 +85,7 @@ make_log_line(const std::string& level, const std::string& payload)
struct MockMetricsManager : public DummyMetricsManager {
int add_count;
- MockMetricsManager() : DummyMetricsManager(), add_count(0) {}
+ MockMetricsManager() noexcept : DummyMetricsManager(), add_count(0) {}
void add(Counter::Increment) override {
++add_count;
}
diff --git a/logd/src/tests/watcher/watcher_test.cpp b/logd/src/tests/watcher/watcher_test.cpp
index 7e7585f9209..f74564b23f4 100644
--- a/logd/src/tests/watcher/watcher_test.cpp
+++ b/logd/src/tests/watcher/watcher_test.cpp
@@ -2,6 +2,7 @@
#include <vespa/vespalib/gtest/gtest.h>
#include <logd/config_subscriber.h>
+#include <vespa/config/common/configcontext.h>
#include <logd/watcher.h>
#include <vespa/vespalib/io/fileutil.h>
#include <vespa/vespalib/util/threadstackexecutor.h>
diff --git a/messagebus/src/main/java/com/yahoo/messagebus/ErrorCode.java b/messagebus/src/main/java/com/yahoo/messagebus/ErrorCode.java
index 460783457af..9bde5e32fd7 100644
--- a/messagebus/src/main/java/com/yahoo/messagebus/ErrorCode.java
+++ b/messagebus/src/main/java/com/yahoo/messagebus/ErrorCode.java
@@ -59,10 +59,10 @@ public final class ErrorCode {
/** The protocol specified for the message is unknown. */
public static final int UNKNOWN_PROTOCOL = FATAL_ERROR + 7;
- /** An error occured while decoding the message. */
+ /** An error occurred while decoding the message. */
public static final int DECODE_ERROR = FATAL_ERROR + 8;
- /** A timeout occured while sending. */
+ /** A timeout occurred while sending. */
public static final int TIMEOUT = FATAL_ERROR + 9;
/** The target is running an incompatible version. */
diff --git a/messagebus/src/main/java/com/yahoo/messagebus/Protocol.java b/messagebus/src/main/java/com/yahoo/messagebus/Protocol.java
index 3801308d38f..d1c19cda88c 100644
--- a/messagebus/src/main/java/com/yahoo/messagebus/Protocol.java
+++ b/messagebus/src/main/java/com/yahoo/messagebus/Protocol.java
@@ -12,37 +12,34 @@ import com.yahoo.messagebus.routing.RoutingPolicy;
*/
public interface Protocol {
- /**
- * Returns a global unique name for this protocol.
- *
- * @return The name.
- */
- public String getName();
+ /** Returns a global unique name for this protocol. */
+ String getName();
/**
* Encodes the protocol specific data of a routable into a byte array.
*
- * @param version The version to encode for.
- * @param routable The routable to encode.
- * @return The encoded data.
+ * @param version the version to encode for
+ * @param routable the routable to encode
+ * @return the encoded data
*/
- public byte[] encode(Version version, Routable routable);
+ byte[] encode(Version version, Routable routable);
/**
* Decodes the protocol specific data into a routable of the correct type.
*
- * @param version The version of the serialized routable.
- * @param payload The payload to decode from.
- * @return The decoded routable.
+ * @param version the version of the serialized routable
+ * @param payload the payload to decode from
+ * @return the decoded routable, or null if it could not be decoded
*/
- public Routable decode(Version version, byte[] payload);
+ Routable decode(Version version, byte[] payload);
/**
* Create a policy of the named type with the named param passed to the constructor of that policy.
*
- * @param name The name of the policy to create.
- * @param param The parameter to that policy's constructor.
- * @return The created policy.
+ * @param name the name of the policy to create
+ * @param param the parameter to that policy's constructor
+ * @return the created policy
*/
- public RoutingPolicy createPolicy(String name, String param);
+ RoutingPolicy createPolicy(String name, String param);
+
}
diff --git a/messagebus/src/vespa/messagebus/messagebus.cpp b/messagebus/src/vespa/messagebus/messagebus.cpp
index c3d6b28b318..ce60f1a3969 100644
--- a/messagebus/src/vespa/messagebus/messagebus.cpp
+++ b/messagebus/src/vespa/messagebus/messagebus.cpp
@@ -13,7 +13,6 @@
#include <vespa/log/log.h>
LOG_SETUP(".messagebus");
-using vespalib::LockGuard;
using vespalib::make_string;
using namespace std::chrono_literals;
@@ -201,7 +200,7 @@ MessageBus::createIntermediateSession(const string &name,
IntermediateSession::UP
MessageBus::createIntermediateSession(const IntermediateSessionParams &params)
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
IntermediateSession::UP ret(new IntermediateSession(*this, params));
_sessions[params.getName()] = ret.get();
if (params.getBroadcastName()) {
@@ -224,7 +223,7 @@ MessageBus::createDestinationSession(const string &name,
DestinationSession::UP
MessageBus::createDestinationSession(const DestinationSessionParams &params)
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
DestinationSession::UP ret(new DestinationSession(*this, params));
_sessions[params.getName()] = ret.get();
if (params.getBroadcastName()) {
@@ -236,7 +235,7 @@ MessageBus::createDestinationSession(const DestinationSessionParams &params)
void
MessageBus::unregisterSession(const string &sessionName)
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_network.unregisterSession(sessionName);
_sessions.erase(sessionName);
}
@@ -245,7 +244,7 @@ RoutingTable::SP
MessageBus::getRoutingTable(const string &protocol)
{
typedef std::map<string, RoutingTable::SP>::iterator ITR;
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
ITR itr = _routingTables.find(protocol);
if (itr == _routingTables.end()) {
return RoutingTable::SP(); // not found
@@ -293,7 +292,7 @@ MessageBus::setupRouting(const RoutingSpec &spec)
rtm[cfg.getProtocol()] = std::make_shared<RoutingTable>(cfg);
}
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
std::swap(_routingTables, rtm);
}
_protocolRepository->clearPolicyCache();
@@ -360,7 +359,7 @@ MessageBus::deliverMessage(Message::UP msg, const string &session)
{
IMessageHandler *msgHandler = nullptr;
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
std::map<string, IMessageHandler*>::iterator it = _sessions.find(session);
if (it != _sessions.end()) {
msgHandler = it->second;
diff --git a/messagebus/src/vespa/messagebus/messagebus.h b/messagebus/src/vespa/messagebus/messagebus.h
index c0682967db9..b12054f7006 100644
--- a/messagebus/src/vespa/messagebus/messagebus.h
+++ b/messagebus/src/vespa/messagebus/messagebus.h
@@ -10,7 +10,6 @@
#include "sourcesession.h"
#include <vespa/messagebus/network/inetworkowner.h>
#include <vespa/messagebus/routing/routingspec.h>
-#include <vespa/vespalib/util/sync.h>
#include <map>
#include <string>
#include <atomic>
@@ -38,7 +37,7 @@ class MessageBus : public IMessageHandler,
private:
using RoutingTableSP = std::shared_ptr<RoutingTable>;
INetwork &_network;
- vespalib::Lock _lock;
+ std::mutex _lock;
std::map<string, RoutingTableSP> _routingTables;
std::map<string, IMessageHandler*> _sessions;
std::unique_ptr<ProtocolRepository> _protocolRepository;
diff --git a/messagebus/src/vespa/messagebus/network/rpcnetwork.cpp b/messagebus/src/vespa/messagebus/network/rpcnetwork.cpp
index de3be2ffa01..eb94ab5ff5c 100644
--- a/messagebus/src/vespa/messagebus/network/rpcnetwork.cpp
+++ b/messagebus/src/vespa/messagebus/network/rpcnetwork.cpp
@@ -96,7 +96,7 @@ RPCNetwork::SendContext::handleVersion(const vespalib::Version *version)
{
bool shouldSend = false;
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
if (version == nullptr) {
_hasError = true;
} else if (*version < _version) {
diff --git a/messagebus/src/vespa/messagebus/network/rpcnetwork.h b/messagebus/src/vespa/messagebus/network/rpcnetwork.h
index a8eb514387c..2780c3e8770 100644
--- a/messagebus/src/vespa/messagebus/network/rpcnetwork.h
+++ b/messagebus/src/vespa/messagebus/network/rpcnetwork.h
@@ -37,7 +37,7 @@ class RPCNetwork : public INetwork,
private:
using CompressionConfig = vespalib::compression::CompressionConfig;
struct SendContext : public RPCTarget::IVersionHandler {
- vespalib::Lock _lock;
+ std::mutex _lock;
RPCNetwork &_net;
const Message &_msg;
uint32_t _traceLevel;
@@ -128,7 +128,7 @@ public:
*
* @param params A complete set of parameters.
*/
- RPCNetwork(const RPCNetworkParams &params);
+ explicit RPCNetwork(const RPCNetworkParams &params);
/**
* Destruct
diff --git a/messagebus/src/vespa/messagebus/network/rpctargetpool.h b/messagebus/src/vespa/messagebus/network/rpctargetpool.h
index d47fd977356..bc9e1a4b19f 100644
--- a/messagebus/src/vespa/messagebus/network/rpctargetpool.h
+++ b/messagebus/src/vespa/messagebus/network/rpctargetpool.h
@@ -4,7 +4,6 @@
#include "rpcserviceaddress.h"
#include "rpctarget.h"
#include <vespa/messagebus/itimer.h>
-#include <vespa/vespalib/util/sync.h>
#include <map>
class FRT_Supervisor;
diff --git a/messagebus/src/vespa/messagebus/protocolrepository.cpp b/messagebus/src/vespa/messagebus/protocolrepository.cpp
index a9891069c44..f23ef0e2ff7 100644
--- a/messagebus/src/vespa/messagebus/protocolrepository.cpp
+++ b/messagebus/src/vespa/messagebus/protocolrepository.cpp
@@ -1,5 +1,6 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "protocolrepository.h"
+#include <cassert>
#include <vespa/log/log.h>
LOG_SETUP(".protocolrepository");
@@ -12,7 +13,7 @@ ProtocolRepository::~ProtocolRepository() = default;
void
ProtocolRepository::clearPolicyCache()
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_routingPolicyCache.clear();
}
@@ -66,7 +67,7 @@ ProtocolRepository::getRoutingPolicy(const string &protocolName,
{
string cacheKey = protocolName;
cacheKey.append('.').append(policyName).append(".").append(policyParam);
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
RoutingPolicyCache::iterator cit = _routingPolicyCache.find(cacheKey);
if (cit != _routingPolicyCache.end()) {
return cit->second;
diff --git a/messagebus/src/vespa/messagebus/protocolrepository.h b/messagebus/src/vespa/messagebus/protocolrepository.h
index b310ba3586a..28163149e2e 100644
--- a/messagebus/src/vespa/messagebus/protocolrepository.h
+++ b/messagebus/src/vespa/messagebus/protocolrepository.h
@@ -2,9 +2,9 @@
#pragma once
#include "iprotocol.h"
-#include <vespa/vespalib/util/sync.h>
#include <map>
#include <atomic>
+#include <mutex>
namespace mbus {
@@ -19,7 +19,7 @@ private:
using ProtocolMap = std::map<string, IProtocol::SP>;
using RoutingPolicyCache = std::map<string, IRoutingPolicy::SP>;
- vespalib::Lock _lock; // Only guards the cache,
+ std::mutex _lock; // Only guards the cache,
// not the protocols as they are set up during messagebus construction.
static constexpr size_t MAX_PROTOCOLS = 16;
std::pair<string, std::atomic<IProtocol *>> _protocols[MAX_PROTOCOLS];
diff --git a/messagebus/src/vespa/messagebus/routing/resender.h b/messagebus/src/vespa/messagebus/routing/resender.h
index 68b49cde606..f70fd57265c 100644
--- a/messagebus/src/vespa/messagebus/routing/resender.h
+++ b/messagebus/src/vespa/messagebus/routing/resender.h
@@ -4,7 +4,6 @@
#include "iretrypolicy.h"
#include <vespa/messagebus/queue.h>
#include <vespa/messagebus/reply.h>
-#include <vespa/vespalib/util/sync.h>
#include <queue>
#include <vector>
diff --git a/messagebus/src/vespa/messagebus/routing/routingnode.cpp b/messagebus/src/vespa/messagebus/routing/routingnode.cpp
index a47abe185cc..f24afbc07ca 100644
--- a/messagebus/src/vespa/messagebus/routing/routingnode.cpp
+++ b/messagebus/src/vespa/messagebus/routing/routingnode.cpp
@@ -10,6 +10,7 @@
#include <vespa/vespalib/util/stringfmt.h>
#include <vespa/messagebus/network/inetwork.h>
#include <stack>
+#include <cassert>
using vespalib::make_string;
diff --git a/messagebus/src/vespa/messagebus/routing/routingnode.h b/messagebus/src/vespa/messagebus/routing/routingnode.h
index 3902e4ef699..2f82eb0ff92 100644
--- a/messagebus/src/vespa/messagebus/routing/routingnode.h
+++ b/messagebus/src/vespa/messagebus/routing/routingnode.h
@@ -12,7 +12,6 @@
#include <vespa/messagebus/messagebus.h>
#include <vespa/messagebus/network/iserviceaddress.h>
#include <vespa/messagebus/reply.h>
-#include <vespa/vespalib/util/sync.h>
#include <vector>
#include <map>
diff --git a/messagebus/src/vespa/messagebus/sequencer.cpp b/messagebus/src/vespa/messagebus/sequencer.cpp
index 2d7a36a28ef..6270284b9e2 100644
--- a/messagebus/src/vespa/messagebus/sequencer.cpp
+++ b/messagebus/src/vespa/messagebus/sequencer.cpp
@@ -2,6 +2,7 @@
#include "sequencer.h"
#include "tracelevel.h"
#include <vespa/vespalib/util/stringfmt.h>
+#include <cassert>
using vespalib::make_string;
@@ -37,7 +38,7 @@ Sequencer::filter(Message::UP msg)
uint64_t seqId = msg->getSequenceId();
msg->setContext(Context(seqId));
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
QueueMap::iterator it = _seqMap.find(seqId);
if (it != _seqMap.end()) {
if (it->second == nullptr) {
@@ -85,7 +86,7 @@ Sequencer::handleReply(Reply::UP reply)
make_string("Sequencer received reply with sequence id '%" PRIu64 "'.", seq));
Message::UP msg;
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
QueueMap::iterator it = _seqMap.find(seq);
MessageQueue *que = it->second;
assert(it != _seqMap.end());
@@ -99,7 +100,7 @@ Sequencer::handleReply(Reply::UP reply)
que->pop();
}
}
- if (msg.get() != nullptr) {
+ if (msg) {
sequencedSend(std::move(msg));
}
IReplyHandler &handler = reply->getCallStack().pop(*reply);
diff --git a/messagebus/src/vespa/messagebus/sequencer.h b/messagebus/src/vespa/messagebus/sequencer.h
index 7aae32fc744..54ac4ce5007 100644
--- a/messagebus/src/vespa/messagebus/sequencer.h
+++ b/messagebus/src/vespa/messagebus/sequencer.h
@@ -2,13 +2,13 @@
#pragma once
-#include <map>
-#include <vespa/vespalib/util/sync.h>
#include "imessagehandler.h"
#include "ireplyhandler.h"
#include "message.h"
#include "reply.h"
#include "queue.h"
+#include <mutex>
+#include <map>
namespace mbus {
@@ -21,7 +21,7 @@ class Sequencer : public IMessageHandler,
public IReplyHandler
{
private:
- vespalib::Lock _lock;
+ std::mutex _lock;
IMessageHandler &_sender;
typedef Queue<Message*> MessageQueue;
diff --git a/messagebus_test/src/tests/speed/cpp-client.cpp b/messagebus_test/src/tests/speed/cpp-client.cpp
index b5829c76c08..2c20b35c597 100644
--- a/messagebus_test/src/tests/speed/cpp-client.cpp
+++ b/messagebus_test/src/tests/speed/cpp-client.cpp
@@ -17,7 +17,7 @@ using namespace std::chrono_literals;
class Client : public IReplyHandler
{
private:
- vespalib::Lock _lock;
+ std::mutex _lock;
uint32_t _okCnt;
uint32_t _failCnt;
SourceSession::UP _session;
@@ -58,7 +58,7 @@ Client::send(uint64_t seq) {
void
Client::sample(uint32_t &okCnt, uint32_t &failCnt) {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
okCnt = _okCnt;
failCnt = _failCnt;
}
@@ -69,7 +69,7 @@ Client::handleReply(Reply::UP reply) {
&& (reply->getType() == SimpleProtocol::REPLY)
&& (static_cast<SimpleReply&>(*reply).getValue() == "OK"))
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
++_okCnt;
} else {
fprintf(stderr, "BAD REPLY\n");
@@ -78,7 +78,7 @@ Client::handleReply(Reply::UP reply) {
reply->getError(i).getCode(),
reply->getError(i).getMessage().c_str());
}
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
++_failCnt;
}
send();
diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/rpc/RpcConnector.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/rpc/RpcConnector.java
index c9d4ad2a5ac..9408c9b917a 100644
--- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/rpc/RpcConnector.java
+++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/rpc/RpcConnector.java
@@ -52,8 +52,10 @@ public class RpcConnector extends AbstractComponent {
}
public void stop() {
- acceptor.shutdown().join();
- supervisor.transport().shutdown().join();
+ if (acceptor != null)
+ acceptor.shutdown().join();
+ if (supervisor != null)
+ supervisor.transport().shutdown().join();
}
@Override
diff --git a/metrics/src/vespa/metrics/metricmanager.cpp b/metrics/src/vespa/metrics/metricmanager.cpp
index 84e92c2c316..7db9686d5c8 100644
--- a/metrics/src/vespa/metrics/metricmanager.cpp
+++ b/metrics/src/vespa/metrics/metricmanager.cpp
@@ -13,6 +13,7 @@
#include <vespa/vespalib/stllike/hashtable.hpp>
#include <sstream>
#include <algorithm>
+#include <cassert>
#include <vespa/log/bufferedlogger.h>
LOG_SETUP(".metrics.manager");
diff --git a/metrics/src/vespa/metrics/metricsnapshot.cpp b/metrics/src/vespa/metrics/metricsnapshot.cpp
index 86a33f0993f..f7460c8b6ad 100644
--- a/metrics/src/vespa/metrics/metricsnapshot.cpp
+++ b/metrics/src/vespa/metrics/metricsnapshot.cpp
@@ -1,8 +1,9 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "metricsnapshot.h"
#include "metricmanager.h"
-#include <vespa/log/log.h>
+#include <cassert>
+#include <vespa/log/log.h>
LOG_SETUP(".metrics.snapshot");
namespace metrics {
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java
index 6b7b72f2746..f09598a6fb0 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java
@@ -363,8 +363,6 @@ public class NodeAgentImpl implements NodeAgent {
context.log(logger, "Container should be running with different CPU allocation, wanted: %s, current: %s",
wantedContainerResources.toStringCpu(), existingContainer.resources.toStringCpu());
- orchestratorSuspendNode(context);
-
// Only update CPU resources
containerOperations.updateContainer(context, wantedContainerResources.withMemoryBytes(existingContainer.resources.memoryBytes()));
return containerOperations.getContainer(context).orElseThrow(() ->
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java
index fdd950f7428..7880209bbc8 100644
--- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java
+++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java
@@ -223,25 +223,25 @@ public class NodeAgentImplTest {
ContainerResources resourcesAfterThird = ContainerResources.from(0, 4, 16);
mockGetContainer(dockerImage, resourcesAfterThird, true);
- inOrder.verify(orchestrator).suspend(any(String.class));
+ inOrder.verify(orchestrator, never()).suspend(any());
inOrder.verify(containerOperations).updateContainer(eq(thirdContext), eq(resourcesAfterThird));
inOrder.verify(containerOperations, never()).removeContainer(any(), any());
inOrder.verify(containerOperations, never()).startContainer(any());
- inOrder.verify(orchestrator).resume(any(String.class));
+ inOrder.verify(orchestrator, never()).resume(any());
// No changes
nodeAgent.converge(thirdContext);
- inOrder.verify(orchestrator, never()).suspend(any(String.class));
+ inOrder.verify(orchestrator, never()).suspend(any());
inOrder.verify(containerOperations, never()).updateContainer(eq(thirdContext), any());
inOrder.verify(containerOperations, never()).removeContainer(any(), any());
- inOrder.verify(orchestrator, never()).resume(any(String.class));
+ inOrder.verify(orchestrator, never()).resume(any());
// Set the feature flag
flagSource.withDoubleFlag(Flags.CONTAINER_CPU_CAP.id(), 2.3);
nodeAgent.doConverge(thirdContext);
inOrder.verify(containerOperations).updateContainer(eq(thirdContext), eq(ContainerResources.from(9.2, 4, 16)));
- inOrder.verify(orchestrator).resume(any(String.class));
+ inOrder.verify(orchestrator, never()).resume(any());
}
@Test
@@ -645,18 +645,18 @@ public class NodeAgentImplTest {
clock.advance(Duration.ofSeconds(31));
nodeAgent.doConverge(context);
- inOrder.verify(orchestrator).suspend(hostName);
+ inOrder.verify(orchestrator, never()).suspend(any());
inOrder.verify(containerOperations).updateContainer(eq(context), eq(ContainerResources.from(0, 2, 16)));
inOrder.verify(containerOperations, never()).removeContainer(any(), any());
inOrder.verify(containerOperations, never()).startContainer(any());
- inOrder.verify(orchestrator).resume(any(String.class));
+ inOrder.verify(orchestrator, never()).resume(any());
// No changes
nodeAgent.converge(context);
- inOrder.verify(orchestrator, never()).suspend(any(String.class));
+ inOrder.verify(orchestrator, never()).suspend(any());
inOrder.verify(containerOperations, never()).updateContainer(eq(context), any());
inOrder.verify(containerOperations, never()).removeContainer(any(), any());
- inOrder.verify(orchestrator, never()).resume(any(String.class));
+ inOrder.verify(orchestrator, never()).resume(any());
}
@Test
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java
index 455d9e59734..e92f039ad01 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java
@@ -11,6 +11,7 @@ import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.Flavor;
import com.yahoo.config.provision.NodeFlavors;
import com.yahoo.config.provision.NodeType;
+import com.yahoo.config.provision.ProvisionLock;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
import com.yahoo.config.provisioning.NodeRepositoryConfig;
@@ -502,19 +503,17 @@ public class NodeRepository extends AbstractComponent {
}
}
- public void deactivate(ApplicationId application, NestedTransaction transaction) {
- try (Mutex lock = lock(application)) {
- deactivate(db.readNodes(application, State.reserved, State.active), transaction);
- applications.remove(application, transaction, lock);
- }
+ /** Deactivate nodes owned by application guarded by given lock */
+ public void deactivate(NestedTransaction transaction, ProvisionLock lock) {
+ deactivate(db.readNodes(lock.application(), State.reserved, State.active), transaction, lock);
+ applications.remove(lock.application(), transaction, lock);
}
/**
- * Deactivates these nodes in a transaction and returns
- * the nodes in the new state which will hold if the transaction commits.
- * This method does <b>not</b> lock
+ * Deactivates these nodes in a transaction and returns the nodes in the new state which will hold if the
+ * transaction commits.
*/
- public List<Node> deactivate(List<Node> nodes, NestedTransaction transaction) {
+ public List<Node> deactivate(List<Node> nodes, NestedTransaction transaction, @SuppressWarnings("unused") ProvisionLock lock) {
return db.writeTo(State.inactive, nodes, Agent.application, Optional.empty(), transaction);
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Applications.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Applications.java
index 56e52d9f658..9f45839f1c3 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Applications.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Applications.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.hosted.provision.applications;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ProvisionLock;
import com.yahoo.transaction.Mutex;
import com.yahoo.transaction.NestedTransaction;
import com.yahoo.vespa.hosted.provision.persistence.CuratorDatabaseClient;
@@ -25,10 +26,7 @@ public class Applications {
// read and write all to make sure they are stored in the latest version of the serialized format
for (ApplicationId id : ids()) {
try (Mutex lock = db.lock(id)) {
- // TODO(mpolden): Remove inner lock
- try (Mutex innerLock = db.configLock(id)) {
- get(id).ifPresent(application -> put(application, lock));
- }
+ get(id).ifPresent(application -> put(application, lock));
}
}
}
@@ -41,17 +39,19 @@ public class Applications {
return db.readApplication(id);
}
+ // TODO: Require ProvisionLock instead of Mutex
public void put(Application application, Mutex applicationLock) {
NestedTransaction transaction = new NestedTransaction();
put(application, transaction, applicationLock);
transaction.commit();
}
+ // TODO: Require ProvisionLock instead of Mutex
public void put(Application application, NestedTransaction transaction, Mutex applicationLock) {
db.writeApplication(application, transaction);
}
- public void remove(ApplicationId application, NestedTransaction transaction, Mutex applicationLock) {
+ public void remove(ApplicationId application, NestedTransaction transaction, @SuppressWarnings("unused") ProvisionLock lock) {
db.deleteApplication(application, transaction);
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java
index 267bfefa332..d1d15baa5dc 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java
@@ -138,21 +138,20 @@ public class AllocatableClusterResources {
Limits applicationLimits,
NodeRepository nodeRepository) {
var systemLimits = new NodeResourceLimits(nodeRepository);
- if ( !exclusive && nodeRepository.zone().getCloud().allowHostSharing()) { // Check if any flavor can fit these hosts
+ if ( !exclusive && nodeRepository.zone().getCloud().allowHostSharing()) {
// We decide resources: Add overhead to what we'll request (advertised) to make sure real becomes (at least) cappedNodeResources
NodeResources advertisedResources = nodeRepository.resourcesCalculator().realToRequest(wantedResources.nodeResources());
advertisedResources = systemLimits.enlargeToLegal(advertisedResources, clusterType); // Attempt to ask for something legal
advertisedResources = applicationLimits.cap(advertisedResources); // Overrides other conditions, even if it will then fail
NodeResources realResources = nodeRepository.resourcesCalculator().requestToReal(advertisedResources); // ... thus, what we really get may change
if ( ! systemLimits.isWithinRealLimits(realResources, clusterType)) return Optional.empty();
- for (Flavor flavor : nodeRepository.flavors().getFlavors()) {
- if (flavor.resources().satisfies(advertisedResources))
+ if (matchesAny(nodeRepository.flavors().getFlavors(), advertisedResources))
return Optional.of(new AllocatableClusterResources(wantedResources.with(realResources),
advertisedResources,
wantedResources.nodeResources(),
clusterType));
- }
- return Optional.empty();
+ else
+ return Optional.empty();
}
else { // Return the cheapest flavor satisfying the requested resources, if any
NodeResources cappedWantedResources = applicationLimits.cap(wantedResources.nodeResources());
@@ -185,6 +184,14 @@ public class AllocatableClusterResources {
}
}
+ /** Returns true if the given resources could be allocated on any of the given flavors */
+ private static boolean matchesAny(List<Flavor> flavors, NodeResources advertisedResources) {
+ // Tenant nodes should not consume more than half the resources of the biggest hosts
+ // to make it easier to shift them between hosts.
+ return flavors.stream().anyMatch(flavor -> flavor.resources().withVcpu(flavor.resources().vcpu() / 2)
+ .satisfies(advertisedResources));
+ }
+
private static boolean between(NodeResources min, NodeResources max, NodeResources r) {
if ( ! min.isUnspecified() && ! min.justNonNumbers().compatibleWith(r.justNonNumbers())) return false;
if ( ! max.isUnspecified() && ! max.justNonNumbers().compatibleWith(r.justNonNumbers())) return false;
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java
index d359b86ae85..a267d59f1dc 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java
@@ -1,7 +1,6 @@
// Copyright Verizon Media. 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.ClusterResources;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.hosted.provision.Node;
@@ -9,13 +8,8 @@ import com.yahoo.vespa.hosted.provision.NodeRepository;
import com.yahoo.vespa.hosted.provision.applications.Cluster;
import java.time.Duration;
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.Optional;
-import java.util.stream.Collectors;
/**
* The autoscaler makes decisions about the flavor and node count that should be allocated to a cluster
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirer.java
index 55d17f3e080..ca2a59ca6d4 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirer.java
@@ -22,7 +22,7 @@ import java.util.logging.Level;
import java.util.stream.Collectors;
/**
- * Periodically expire load balancers.
+ * Periodically expire load balancers and de-provision inactive ones.
*
* Load balancers expire from the following states:
*
@@ -123,14 +123,11 @@ public class LoadBalancerExpirer extends NodeRepositoryMaintainer {
/** Apply operation to all load balancers that exist in given state, while holding lock */
private void withLoadBalancersIn(LoadBalancer.State state, Consumer<LoadBalancer> operation) {
for (var id : db.readLoadBalancerIds()) {
- try (var lock = db.lock(id.application())) {
- // TODO(mpolden): Remove inner lock
- try (var innerLock = db.configLock(id.application())) {
- var loadBalancer = db.readLoadBalancer(id);
- if (loadBalancer.isEmpty()) continue; // Load balancer was removed during loop
- if (loadBalancer.get().state() != state) continue; // Wrong state
- operation.accept(loadBalancer.get());
- }
+ try (var lock = db.lock(id.application(), Duration.ofSeconds(1))) {
+ var loadBalancer = db.readLoadBalancer(id);
+ if (loadBalancer.isEmpty()) continue; // Load balancer was removed during loop
+ if (loadBalancer.get().state() != state) continue; // Wrong state
+ operation.accept(loadBalancer.get());
}
}
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporter.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporter.java
index 1cf1bb91d0c..160e448aeab 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporter.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporter.java
@@ -244,6 +244,7 @@ public class MetricsReporter extends NodeRepositoryMaintainer {
metric.set("lockAttempt.locked", lockMetrics.getAndResetAcquireSucceededCount(), context);
metric.set("lockAttempt.release", lockMetrics.getAndResetReleaseCount(), context);
metric.set("lockAttempt.releaseFailed", lockMetrics.getAndResetReleaseFailedCount(), context);
+ metric.set("lockAttempt.reentry", lockMetrics.getAndResetReentryCount(), context);
setLockLatencyMetrics("acquire", lockMetrics.getAndResetAcquireLatencyMetrics(), context);
setLockLatencyMetrics("locked", lockMetrics.getAndResetLockedLatencyMetrics(), context);
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailer.java
index 2ce3fa6c0f6..38511db6c4d 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailer.java
@@ -1,8 +1,8 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.provision.maintenance;
-import com.google.common.util.concurrent.UncheckedTimeoutException;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ApplicationLockException;
import com.yahoo.config.provision.Deployer;
import com.yahoo.config.provision.Deployment;
import com.yahoo.config.provision.HostLivenessTracker;
@@ -199,7 +199,7 @@ public class NodeFailer extends NodeRepositoryMaintainer {
// Lock and update status
ApplicationId owner = node.get().allocation().get().owner();
- try (var lock = nodeRepository().lock(owner, Duration.ofSeconds(1))) {
+ try (var lock = nodeRepository().lock(owner)) {
node = getNode(hostname.toString(), owner, lock); // Re-get inside lock
if (node.isEmpty()) return; // Node disappeared or changed allocation
if (badNode) {
@@ -207,8 +207,9 @@ public class NodeFailer extends NodeRepositoryMaintainer {
} else {
clearDownRecord(node.get(), lock);
}
- } catch (UncheckedTimeoutException ignored) {
- // Fine, we'll try updating this node in the next run
+ } catch (ApplicationLockException e) {
+ // Fine, carry on with other nodes. We'll try updating this one in the next run
+ log.log(Level.WARNING, "Could not lock " + owner + ": " + Exceptions.toMessageString(e));
}
});
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java
index 2c00b4bab68..91c683d139e 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java
@@ -61,7 +61,6 @@ public class CuratorDatabaseClient {
private static final Path root = Path.fromString("/provision/v1");
private static final Path lockPath = root.append("locks");
- private static final Path configLockPath = Path.fromString("/config/v2/locks/");
private static final Path loadBalancersPath = root.append("loadBalancers");
private static final Path applicationsPath = root.append("applications");
private static final Path inactiveJobsPath = root.append("inactiveJobs");
@@ -328,15 +327,6 @@ public class CuratorDatabaseClient {
return lockPath;
}
- /** Creates and returns the config lock path for this application */
- // TODO(mpolden): Remove
- private Path configLockPath(ApplicationId application) {
- // This must match the lock path used by com.yahoo.vespa.config.server.application.TenantApplications
- Path lockPath = configLockPath.append(application.tenant().value()).append(application.serializedForm());
- db.create(lockPath);
- return lockPath;
- }
-
private String toDir(Node.State state) {
switch (state) {
case active: return "allocated"; // legacy name
@@ -372,20 +362,6 @@ public class CuratorDatabaseClient {
}
}
- // TODO(mpolden): Remove
- private Lock configLock(ApplicationId application, Duration timeout) {
- try {
- return db.lock(configLockPath(application), timeout);
- } catch (UncheckedTimeoutException e) {
- throw new ApplicationLockException(e);
- }
- }
-
- // TODO(mpolden): Remove
- public Lock configLock(ApplicationId application) {
- return configLock(application, defaultLockTimeout);
- }
-
// Applications -----------------------------------------------------------
public List<ApplicationId> readApplicationIds() {
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java
index e36d5fa4075..b85862446a8 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java
@@ -7,6 +7,7 @@ import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Flavor;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.ParentHostUnavailableException;
+import com.yahoo.config.provision.ProvisionLock;
import com.yahoo.transaction.Mutex;
import com.yahoo.transaction.NestedTransaction;
import com.yahoo.vespa.hosted.provision.Node;
@@ -37,12 +38,10 @@ class Activator {
this.loadBalancerProvisioner = loadBalancerProvisioner;
}
- /** Activate required resources for given application */
- public void activate(ApplicationId application, Collection<HostSpec> hosts, NestedTransaction transaction) {
- try (Mutex lock = nodeRepository.lock(application)) {
- activateNodes(application, hosts, transaction, lock);
- activateLoadBalancers(application, hosts, transaction, lock);
- }
+ /** Activate required resources for application guarded by given lock */
+ public void activate(Collection<HostSpec> hosts, NestedTransaction transaction, ProvisionLock lock) {
+ activateNodes(hosts, transaction, lock);
+ activateLoadBalancers(hosts, transaction, lock);
}
/**
@@ -55,12 +54,11 @@ class Activator {
* Nodes in active which are not present in <code>hosts</code> are moved to inactive.
*
* @param transaction Transaction with operations to commit together with any operations done within the repository.
- * @param application the application to allocate nodes for
* @param hosts the hosts to make the set of active nodes of this
- * @param applicationLock application lock that must be held when calling this
+ * @param lock provision lock that must be held when calling this
*/
- private void activateNodes(ApplicationId application, Collection<HostSpec> hosts, NestedTransaction transaction,
- @SuppressWarnings("unused") Mutex applicationLock) {
+ private void activateNodes(Collection<HostSpec> hosts, NestedTransaction transaction, ProvisionLock lock) {
+ ApplicationId application = lock.application();
Set<String> hostnames = hosts.stream().map(HostSpec::hostname).collect(Collectors.toSet());
NodeList allNodes = nodeRepository.list();
NodeList applicationNodes = allNodes.owner(application);
@@ -84,7 +82,7 @@ class Activator {
List<Node> activeToRemove = removeHostsFromList(hostnames, active);
activeToRemove = activeToRemove.stream().map(Node::unretire).collect(Collectors.toList()); // only active nodes can be retired
- nodeRepository.deactivate(activeToRemove, transaction);
+ nodeRepository.deactivate(activeToRemove, transaction, lock);
nodeRepository.activate(updateFrom(hosts, continuedActive), transaction); // update active with any changes
nodeRepository.activate(updatePortsFrom(hosts, reservedToActivate), transaction);
unreserveParentsOf(reservedToActivate);
@@ -106,9 +104,8 @@ class Activator {
}
/** Activate load balancers */
- private void activateLoadBalancers(ApplicationId application, Collection<HostSpec> hosts, NestedTransaction transaction,
- @SuppressWarnings("unused") Mutex applicationLock) {
- loadBalancerProvisioner.ifPresent(provisioner -> provisioner.activate(application, allClustersOf(hosts), applicationLock, transaction));
+ private void activateLoadBalancers(Collection<HostSpec> hosts, NestedTransaction transaction, ProvisionLock lock) {
+ loadBalancerProvisioner.ifPresent(provisioner -> provisioner.activate(transaction, allClustersOf(hosts), lock));
}
private static Set<ClusterSpec> allClustersOf(Collection<HostSpec> hosts) {
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImpl.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImpl.java
index e6ace49cacd..b3506a0c102 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImpl.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImpl.java
@@ -11,7 +11,6 @@ import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.InfraDeployer;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.Provisioner;
-import java.util.logging.Level;
import com.yahoo.transaction.Mutex;
import com.yahoo.transaction.NestedTransaction;
import com.yahoo.vespa.hosted.provision.NodeRepository;
@@ -21,6 +20,7 @@ import com.yahoo.vespa.service.monitor.InfraApplicationApi;
import java.util.List;
import java.util.Optional;
+import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -97,7 +97,7 @@ public class InfraDeployerImpl implements InfraDeployer {
@Override
public long activate() {
- try (Mutex lock = nodeRepository.lock(application.getApplicationId())) {
+ try (var lock = provisioner.lock(application.getApplicationId())) {
prepare();
if (hostSpecs.isEmpty()) {
@@ -105,7 +105,7 @@ public class InfraDeployerImpl implements InfraDeployer {
removeApplication(application.getApplicationId());
} else {
NestedTransaction nestedTransaction = new NestedTransaction();
- provisioner.activate(nestedTransaction, application.getApplicationId(), hostSpecs);
+ provisioner.activate(nestedTransaction, hostSpecs, lock);
nestedTransaction.commit();
duperModel.infraApplicationActivated(
@@ -128,10 +128,12 @@ public class InfraDeployerImpl implements InfraDeployer {
private void removeApplication(ApplicationId applicationId) {
// Use the DuperModel as source-of-truth on whether it has also been activated (to avoid periodic removals)
if (duperModel.infraApplicationIsActive(applicationId)) {
- NestedTransaction nestedTransaction = new NestedTransaction();
- provisioner.remove(nestedTransaction, applicationId);
- nestedTransaction.commit();
- duperModel.infraApplicationRemoved(applicationId);
+ try (var lock = provisioner.lock(applicationId)) {
+ NestedTransaction nestedTransaction = new NestedTransaction();
+ provisioner.remove(nestedTransaction, lock);
+ nestedTransaction.commit();
+ duperModel.infraApplicationRemoved(applicationId);
+ }
}
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java
index 09a33093654..634726f9d71 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java
@@ -5,8 +5,8 @@ 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.config.provision.ProvisionLock;
import com.yahoo.config.provision.exception.LoadBalancerServiceException;
-import com.yahoo.transaction.Mutex;
import com.yahoo.transaction.NestedTransaction;
import com.yahoo.vespa.flags.BooleanFlag;
import com.yahoo.vespa.flags.FlagSource;
@@ -60,11 +60,8 @@ public class LoadBalancerProvisioner {
// Read and write all load balancers to make sure they are stored in the latest version of the serialization format
for (var id : db.readLoadBalancerIds()) {
try (var lock = db.lock(id.application())) {
- // TODO(mpolden): Remove inner lock
- try (var innerLock = db.configLock(id.application())) {
- var loadBalancer = db.readLoadBalancer(id);
- loadBalancer.ifPresent(db::writeLoadBalancer);
- }
+ var loadBalancer = db.readLoadBalancer(id);
+ loadBalancer.ifPresent(db::writeLoadBalancer);
}
}
}
@@ -83,12 +80,9 @@ public class LoadBalancerProvisioner {
if (!canForwardTo(requestedNodes.type(), cluster)) return; // Nothing to provision for this node and cluster type
if (application.instance().isTester()) return; // Do not provision for tester instances
try (var lock = db.lock(application)) {
- // TODO(mpolden): Remove inner lock
- try (var innerLock = db.configLock(application)) {
- ClusterSpec.Id clusterId = effectiveId(cluster);
- List<Node> nodes = nodesOf(clusterId, application);
- provision(application, clusterId, nodes, false, lock);
- }
+ ClusterSpec.Id clusterId = effectiveId(cluster);
+ List<Node> nodes = nodesOf(clusterId, application);
+ provision(application, clusterId, nodes, false, new ProvisionLock(application, lock));
}
}
@@ -102,35 +96,24 @@ public class LoadBalancerProvisioner {
*
* Calling this when no load balancer has been prepared for given cluster is a no-op.
*/
- public void activate(ApplicationId application, Set<ClusterSpec> clusters,
- @SuppressWarnings("unused") Mutex applicationLock, NestedTransaction transaction) {
- try (var lock = db.lock(application)) {
- // TODO(mpolden): Remove inner lock
- try (var innerLock = db.configLock(application)) {
- for (var cluster : loadBalancedClustersOf(application).entrySet()) {
- // Provision again to ensure that load balancer instance is re-configured with correct nodes
- provision(application, cluster.getKey(), cluster.getValue(), true, lock);
- }
- // Deactivate any surplus load balancers, i.e. load balancers for clusters that have been removed
- var surplusLoadBalancers = surplusLoadBalancersOf(application, clusters.stream()
- .map(LoadBalancerProvisioner::effectiveId)
- .collect(Collectors.toSet()));
- deactivate(surplusLoadBalancers, transaction);
- }
+ public void activate(NestedTransaction transaction, Set<ClusterSpec> clusters, ProvisionLock lock) {
+ for (var cluster : loadBalancedClustersOf(lock.application()).entrySet()) {
+ // Provision again to ensure that load balancer instance is re-configured with correct nodes
+ provision(lock.application(), cluster.getKey(), cluster.getValue(), true, lock);
}
+ // Deactivate any surplus load balancers, i.e. load balancers for clusters that have been removed
+ var surplusLoadBalancers = surplusLoadBalancersOf(lock.application(), clusters.stream()
+ .map(LoadBalancerProvisioner::effectiveId)
+ .collect(Collectors.toSet()));
+ deactivate(surplusLoadBalancers, transaction);
}
/**
* Deactivate all load balancers assigned to given application. This is a no-op if an application does not have any
* load balancer(s).
*/
- public void deactivate(ApplicationId application, NestedTransaction transaction) {
- try (var lock = nodeRepository.lock(application)) {
- // TODO(mpolden): Remove inner lock
- try (var innerLock = db.configLock(application)) {
- deactivate(nodeRepository.loadBalancers(application).asList(), transaction);
- }
- }
+ public void deactivate(NestedTransaction transaction, ProvisionLock lock) {
+ deactivate(nodeRepository.loadBalancers(lock.application()).asList(), transaction);
}
/** Returns load balancers of given application that are no longer referenced by given clusters */
@@ -168,7 +151,7 @@ public class LoadBalancerProvisioner {
/** Idempotently provision a load balancer for given application and cluster */
private void provision(ApplicationId application, ClusterSpec.Id clusterId, List<Node> nodes, boolean activate,
- @SuppressWarnings("unused") Mutex loadBalancersLock) {
+ @SuppressWarnings("unused") ProvisionLock lock) {
var id = new LoadBalancerId(application, clusterId);
var now = nodeRepository.clock().instant();
var loadBalancer = db.readLoadBalancer(id);
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 aea85729d6d..b79b87ae86c 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
@@ -10,6 +10,7 @@ import com.yahoo.config.provision.HostFilter;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
+import com.yahoo.config.provision.ProvisionLock;
import com.yahoo.config.provision.ProvisionLogger;
import com.yahoo.config.provision.Provisioner;
import com.yahoo.config.provision.Zone;
@@ -118,9 +119,17 @@ public class NodeRepositoryProvisioner implements Provisioner {
}
@Override
+ // TODO(mpolden): Remove
public void activate(NestedTransaction transaction, ApplicationId application, Collection<HostSpec> hosts) {
+ try (var lock = lock(application)) {
+ activate(transaction, hosts, lock);
+ }
+ }
+
+ @Override
+ public void activate(NestedTransaction transaction, Collection<HostSpec> hosts, ProvisionLock lock) {
validate(hosts);
- activator.activate(application, hosts, transaction);
+ activator.activate(hosts, transaction, lock);
}
@Override
@@ -129,9 +138,22 @@ public class NodeRepositoryProvisioner implements Provisioner {
}
@Override
+ // TODO(mpolden): Remove
public void remove(NestedTransaction transaction, ApplicationId application) {
- nodeRepository.deactivate(application, transaction);
- loadBalancerProvisioner.ifPresent(lbProvisioner -> lbProvisioner.deactivate(application, transaction));
+ try (var lock = lock(application)) {
+ remove(transaction, lock);
+ }
+ }
+
+ @Override
+ public void remove(NestedTransaction transaction, ProvisionLock lock) {
+ nodeRepository.deactivate(transaction, lock);
+ loadBalancerProvisioner.ifPresent(lbProvisioner -> lbProvisioner.deactivate(transaction, lock));
+ }
+
+ @Override
+ public ProvisionLock lock(ApplicationId application) {
+ return new ProvisionLock(application, nodeRepository.lock(application));
}
/**
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/LocksResponse.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/LocksResponse.java
index 9b498677827..e84a43cd1aa 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/LocksResponse.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/LocksResponse.java
@@ -61,6 +61,7 @@ public class LocksResponse extends HttpResponse {
lockPathCursor.setLong("lockedCount", lockMetrics.getCumulativeAcquireSucceededCount());
lockPathCursor.setLong("releaseCount", lockMetrics.getCumulativeReleaseCount());
lockPathCursor.setLong("releaseFailedCount", lockMetrics.getCumulativeReleaseFailedCount());
+ lockPathCursor.setLong("reentryCount", lockMetrics.getCumulativeReentryCount());
setLatency(lockPathCursor, "acquire", lockMetrics.getAcquireLatencyMetrics());
setLatency(lockPathCursor, "locked", lockMetrics.getLockedLatencyMetrics());
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockDeployer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockDeployer.java
index 7f613c85cf5..4baaeb12167 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockDeployer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockDeployer.java
@@ -155,10 +155,12 @@ public class MockDeployer implements Deployer {
prepare();
if (failActivate)
throw new IllegalStateException("failActivate is true");
- try (NestedTransaction t = new NestedTransaction()) {
- provisioner.activate(t, application.id(), preparedHosts);
- t.commit();
- lastDeployTimes.put(application.id, clock.instant());
+ try (var lock = provisioner.lock(application.id)) {
+ try (NestedTransaction t = new NestedTransaction()) {
+ provisioner.activate(t, preparedHosts, lock);
+ t.commit();
+ lastDeployTimes.put(application.id, clock.instant());
+ }
}
return redeployments++;
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
index e3a3c0f4fce..042b4aa049c 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
@@ -197,9 +197,11 @@ public class MockNodeRepository extends NodeRepository {
}
private void activate(List<HostSpec> hosts, ApplicationId application, NodeRepositoryProvisioner provisioner) {
- NestedTransaction transaction = new NestedTransaction();
- provisioner.activate(transaction, application, hosts);
- transaction.commit();
+ try (var lock = provisioner.lock(application)) {
+ NestedTransaction transaction = new NestedTransaction();
+ provisioner.activate(transaction, hosts, lock);
+ transaction.commit();
+ }
}
private void addRecord(String name, String ipAddress) {
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockProvisioner.java
index 12731e30f46..3dc96e0011b 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockProvisioner.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockProvisioner.java
@@ -6,12 +6,12 @@ import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.HostFilter;
import com.yahoo.config.provision.HostSpec;
+import com.yahoo.config.provision.ProvisionLock;
import com.yahoo.config.provision.ProvisionLogger;
import com.yahoo.config.provision.Provisioner;
import com.yahoo.transaction.NestedTransaction;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
/**
@@ -21,7 +21,7 @@ public class MockProvisioner implements Provisioner {
@Override
public List<HostSpec> prepare(ApplicationId applicationId, ClusterSpec cluster, Capacity capacity, ProvisionLogger logger) {
- return Collections.emptyList();
+ return List.of();
}
@Override
@@ -30,13 +30,28 @@ public class MockProvisioner implements Provisioner {
}
@Override
+ public void activate(NestedTransaction transaction, Collection<HostSpec> hosts, ProvisionLock lock) {
+
+ }
+
+ @Override
public void remove(NestedTransaction transaction, ApplicationId application) {
}
@Override
+ public void remove(NestedTransaction transaction, ProvisionLock lock) {
+
+ }
+
+ @Override
public void restart(ApplicationId application, HostFilter filter) {
}
+ @Override
+ public ProvisionLock lock(ApplicationId application) {
+ return null;
+ }
+
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/applications/ApplicationsTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/applications/ApplicationsTest.java
index bdb14a868bd..ea304233f8a 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/applications/ApplicationsTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/applications/ApplicationsTest.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.hosted.provision.applications;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ProvisionLock;
import com.yahoo.transaction.NestedTransaction;
import com.yahoo.vespa.hosted.provision.NodeRepositoryTester;
import org.junit.Test;
@@ -30,7 +31,7 @@ public class ApplicationsTest {
assertEquals(app1, applications.get(app1).get().id());
assertEquals(List.of(app1), applications.ids());
NestedTransaction t = new NestedTransaction();
- applications.remove(app1, t, tester.nodeRepository().lock(app1));
+ applications.remove(app1, t, provisionLock(app1, tester));
t.commit();
assertTrue(applications.get(app1).isEmpty());
assertEquals(List.of(), applications.ids());
@@ -43,13 +44,17 @@ public class ApplicationsTest {
t.commit();
assertEquals(List.of(app1, app2, app3), applications.ids());
t = new NestedTransaction();
- applications.remove(app1, t, tester.nodeRepository().lock(app1));
- applications.remove(app2, t, tester.nodeRepository().lock(app2));
- applications.remove(app3, t, tester.nodeRepository().lock(app3));
+ applications.remove(app1, t, provisionLock(app1, tester));
+ applications.remove(app2, t, provisionLock(app2, tester));
+ applications.remove(app3, t, provisionLock(app3, tester));
assertEquals(List.of(app1, app2, app3), applications.ids());
t.commit();
assertTrue(applications.get(app1).isEmpty());
assertEquals(List.of(), applications.ids());
}
+ private ProvisionLock provisionLock(ApplicationId application, NodeRepositoryTester tester) {
+ return new ProvisionLock(application, tester.nodeRepository().lock(application));
+ }
+
}
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 5b4b0b5bcb2..d615d418c50 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
@@ -78,7 +78,7 @@ public class AutoscalingTest {
NodeResources resources = new NodeResources(3, 100, 100, 1);
ClusterResources min = new ClusterResources( 2, 1, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources(20, 1, new NodeResources(100, 1000, 1000, 1));
- AutoscalingTester tester = new AutoscalingTester(resources);
+ AutoscalingTester tester = new AutoscalingTester(resources.withVcpu(resources.vcpu() * 2));
ApplicationId application1 = tester.applicationId("application1");
ClusterSpec cluster1 = tester.clusterSpec(ClusterSpec.Type.container, "cluster1");
@@ -131,7 +131,7 @@ public class AutoscalingTest {
@Test
public void autoscaling_respects_upper_limit() {
- NodeResources hostResources = new NodeResources(3, 100, 100, 1);
+ NodeResources hostResources = new NodeResources(6, 100, 100, 1);
ClusterResources min = new ClusterResources( 2, 1, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources( 6, 1, new NodeResources(2.4, 78, 79, 1));
AutoscalingTester tester = new AutoscalingTester(hostResources);
@@ -155,7 +155,7 @@ public class AutoscalingTest {
NodeResources resources = new NodeResources(3, 100, 100, 1);
ClusterResources min = new ClusterResources( 4, 1, new NodeResources(1.8, 7.4, 8.5, 1));
ClusterResources max = new ClusterResources( 6, 1, new NodeResources(2.4, 78, 79, 1));
- AutoscalingTester tester = new AutoscalingTester(resources);
+ AutoscalingTester tester = new AutoscalingTester(resources.withVcpu(resources.vcpu() * 2));
ApplicationId application1 = tester.applicationId("application1");
ClusterSpec cluster1 = tester.clusterSpec(ClusterSpec.Type.container, "cluster1");
@@ -209,7 +209,7 @@ public class AutoscalingTest {
NodeResources resources = new NodeResources(3, 100, 100, 1);
ClusterResources min = new ClusterResources( 2, 1, new NodeResources(1, 1, 1, 1));
ClusterResources max = min;
- AutoscalingTester tester = new AutoscalingTester(resources);
+ AutoscalingTester tester = new AutoscalingTester(resources.withVcpu(resources.vcpu() * 2));
ApplicationId application1 = tester.applicationId("application1");
ClusterSpec cluster1 = tester.clusterSpec(ClusterSpec.Type.container, "cluster1");
@@ -227,7 +227,7 @@ public class AutoscalingTest {
NodeResources resources = new NodeResources(3, 100, 100, 1);
ClusterResources min = new ClusterResources( 2, 2, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources(20, 20, new NodeResources(100, 1000, 1000, 1));
- AutoscalingTester tester = new AutoscalingTester(resources);
+ AutoscalingTester tester = new AutoscalingTester(resources.withVcpu(resources.vcpu() * 2));
ApplicationId application1 = tester.applicationId("application1");
ClusterSpec cluster1 = tester.clusterSpec(ClusterSpec.Type.container, "cluster1");
@@ -245,7 +245,7 @@ public class AutoscalingTest {
NodeResources resources = new NodeResources(3, 100, 100, 1);
ClusterResources min = new ClusterResources( 3, 1, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources(21, 7, new NodeResources(100, 1000, 1000, 1));
- AutoscalingTester tester = new AutoscalingTester(resources);
+ AutoscalingTester tester = new AutoscalingTester(resources.withVcpu(resources.vcpu() * 2));
ApplicationId application1 = tester.applicationId("application1");
ClusterSpec cluster1 = tester.clusterSpec(ClusterSpec.Type.container, "cluster1");
@@ -278,7 +278,7 @@ public class AutoscalingTest {
@Test
public void autoscaling_avoids_illegal_configurations() {
- NodeResources hostResources = new NodeResources(3, 100, 100, 1);
+ NodeResources hostResources = new NodeResources(6, 100, 100, 1);
ClusterResources min = new ClusterResources( 2, 1, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources(20, 1, new NodeResources(100, 1000, 1000, 1));
AutoscalingTester tester = new AutoscalingTester(hostResources);
@@ -287,7 +287,7 @@ public class AutoscalingTest {
ClusterSpec cluster1 = tester.clusterSpec(ClusterSpec.Type.content, "cluster1");
// deploy
- tester.deploy(application1, cluster1, 6, 1, hostResources);
+ tester.deploy(application1, cluster1, 6, 1, hostResources.withVcpu(hostResources.vcpu() / 2));
tester.addMeasurements(Resource.memory, 0.02f, 0.95f, 120, application1);
tester.assertResources("Scaling down",
6, 1, 2.8, 4.0, 95.0,
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirerTest.java
index a817cc4f413..258e2c7cd42 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirerTest.java
@@ -338,9 +338,11 @@ public class FailedExpirerTest {
public FailureScenario allocate(ApplicationId applicationId, ClusterSpec clusterSpec, Capacity capacity) {
List<HostSpec> preparedNodes = provisioner.prepare(applicationId, clusterSpec, capacity,
(level, message) -> System.out.println(level + ": " + message) );
- NestedTransaction transaction = new NestedTransaction().add(new CuratorTransaction(curator));
- provisioner.activate(transaction, applicationId, Set.copyOf(preparedNodes));
- transaction.commit();
+ try (var lock = provisioner.lock(applicationId)) {
+ NestedTransaction transaction = new NestedTransaction().add(new CuratorTransaction(curator));
+ provisioner.activate(transaction, Set.copyOf(preparedNodes), lock);
+ transaction.commit();
+ }
return this;
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirerTest.java
index 4185ff2c25c..de0e5d4223a 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirerTest.java
@@ -6,7 +6,6 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.NodeResources;
-import com.yahoo.transaction.NestedTransaction;
import com.yahoo.vespa.hosted.provision.lb.LoadBalancer;
import com.yahoo.vespa.hosted.provision.lb.LoadBalancerId;
import com.yahoo.vespa.hosted.provision.node.Agent;
@@ -55,7 +54,7 @@ public class LoadBalancerExpirerTest {
assertEquals(3, loadBalancers.get().size());
// Remove one application deactivates load balancers for that application
- removeApplication(app1);
+ tester.remove(app1);
assertSame(LoadBalancer.State.inactive, loadBalancers.get().get(lb1).state());
assertNotSame(LoadBalancer.State.inactive, loadBalancers.get().get(lb2).state());
@@ -146,12 +145,6 @@ public class LoadBalancerExpirerTest {
Agent.system, this.getClass().getSimpleName());
}
- private void removeApplication(ApplicationId application) {
- NestedTransaction transaction = new NestedTransaction();
- tester.provisioner().remove(transaction, application);
- transaction.commit();
- }
-
private void deployApplication(ApplicationId application, ClusterSpec.Id... clusters) {
deployApplication(application, true, clusters);
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporterTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporterTest.java
index 4d79726fd19..5d5c447ef74 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporterTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporterTest.java
@@ -159,6 +159,7 @@ public class MetricsReporterTest {
verifyAndRemoveIntegerMetricSum(metric, "lockAttempt.locked", 3);
verifyAndRemoveIntegerMetricSum(metric, "lockAttempt.release", 3);
verifyAndRemoveIntegerMetricSum(metric, "lockAttempt.releaseFailed", 0);
+ verifyAndRemoveIntegerMetricSum(metric, "lockAttempt.reentry", 0);
metric.remove("lockAttempt.acquireLatency");
metric.remove("lockAttempt.acquireMaxActiveLatency");
metric.remove("lockAttempt.acquireHz");
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java
index 84b04e040e7..250555ae4fb 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java
@@ -265,9 +265,11 @@ public class NodeFailTester {
private void activate(ApplicationId applicationId, ClusterSpec cluster, Capacity capacity) {
List<HostSpec> hosts = provisioner.prepare(applicationId, cluster, capacity, null);
- NestedTransaction transaction = new NestedTransaction().add(new CuratorTransaction(curator));
- provisioner.activate(transaction, applicationId, hosts);
- transaction.commit();
+ try (var lock = provisioner.lock(applicationId)) {
+ NestedTransaction transaction = new NestedTransaction().add(new CuratorTransaction(curator));
+ provisioner.activate(transaction, hosts, lock);
+ transaction.commit();
+ }
}
/** Returns the node with the highest membership index from the given set of allocated nodes */
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RebalancerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RebalancerTest.java
index 65b79c2df04..390c1213718 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RebalancerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RebalancerTest.java
@@ -9,6 +9,7 @@ import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.Flavor;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
+import com.yahoo.config.provision.ProvisionLock;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.Zone;
import com.yahoo.config.provisioning.FlavorsConfig;
@@ -81,7 +82,7 @@ public class RebalancerTest {
// --- Making the system stable enables rebalancing
NestedTransaction tx = new NestedTransaction();
- tester.nodeRepository().deactivate(List.of(cpuSkewedNode), tx);
+ tester.nodeRepository().deactivate(List.of(cpuSkewedNode), tx, new ProvisionLock(cpuApp, () -> {}));
tx.commit();
// ... if activation fails when trying, we clean up the state
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirerTest.java
index 6062b501513..8de769ae113 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirerTest.java
@@ -183,9 +183,11 @@ public class RetiredExpirerTest {
private void activate(ApplicationId applicationId, ClusterSpec cluster, int nodes, int groups, NodeRepositoryProvisioner provisioner) {
List<HostSpec> hosts = provisioner.prepare(applicationId, cluster, Capacity.from(new ClusterResources(nodes, groups, nodeResources)), null);
- NestedTransaction transaction = new NestedTransaction().add(new CuratorTransaction(curator));
- provisioner.activate(transaction, applicationId, hosts);
- transaction.commit();
+ try (var lock = provisioner.lock(applicationId)) {
+ NestedTransaction transaction = new NestedTransaction().add(new CuratorTransaction(curator));
+ provisioner.activate(transaction, hosts, lock);
+ transaction.commit();
+ }
}
private void createReadyNodes(int count, NodeResources nodeResources, NodeRepository nodeRepository) {
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImplTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImplTest.java
index edbbb3ed2e3..4fae7cf0ab9 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImplTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImplTest.java
@@ -7,6 +7,7 @@ import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.NodeType;
+import com.yahoo.config.provision.ProvisionLock;
import com.yahoo.config.provision.Provisioner;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.flags.InMemoryFlagSource;
@@ -24,7 +25,9 @@ import com.yahoo.vespa.service.monitor.InfraApplicationApi;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
+import org.mockito.ArgumentMatcher;
+import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@@ -98,10 +101,14 @@ public class InfraDeployerImplTest {
verify(duperModelInfraApi, never()).infraApplicationActivated(any(), any());
if (applicationIsActive) {
verify(duperModelInfraApi).infraApplicationRemoved(application.getApplicationId());
- verify(provisioner).remove(any(), eq(application.getApplicationId()));
+ ArgumentMatcher<ProvisionLock> lockMatcher = lock -> {
+ assertEquals(application.getApplicationId(), lock.application());
+ return true;
+ };
+ verify(provisioner).remove(any(), argThat(lockMatcher));
verify(duperModelInfraApi).infraApplicationRemoved(eq(application.getApplicationId()));
} else {
- verify(provisioner, never()).remove(any(), any());
+ verify(provisioner, never()).remove(any(), any(ProvisionLock.class));
verify(duperModelInfraApi, never()).infraApplicationRemoved(any());
}
}
@@ -129,10 +136,15 @@ public class InfraDeployerImplTest {
private void verifyActivated(String... hostnames) {
verify(duperModelInfraApi).infraApplicationActivated(
eq(application.getApplicationId()), eq(Stream.of(hostnames).map(HostName::from).collect(Collectors.toList())));
- verify(provisioner).activate(any(), eq(application.getApplicationId()), argThat(hostSpecs -> {
+ ArgumentMatcher<ProvisionLock> lockMatcher = lock -> {
+ assertEquals(application.getApplicationId(), lock.application());
+ return true;
+ };
+ ArgumentMatcher<Collection<HostSpec>> hostsMatcher = hostSpecs -> {
assertEquals(Set.of(hostnames), hostSpecs.stream().map(HostSpec::hostname).collect(Collectors.toSet()));
return true;
- }));
+ };
+ verify(provisioner).activate(any(), argThat(hostsMatcher), argThat(lockMatcher));
}
private Node addNode(int id, Node.State state, Optional<Version> wantedVespaVersion) {
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java
index 3d784c403f3..735ef2f0fcb 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java
@@ -6,12 +6,10 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterResources;
import com.yahoo.config.provision.ClusterSpec;
-import com.yahoo.config.provision.Flavor;
import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
-import com.yahoo.transaction.NestedTransaction;
import com.yahoo.vespa.flags.Flags;
import com.yahoo.vespa.flags.InMemoryFlagSource;
import com.yahoo.vespa.hosted.provision.Node;
@@ -22,7 +20,6 @@ import com.yahoo.vespa.hosted.provision.node.Agent;
import com.yahoo.vespa.hosted.provision.node.IP;
import org.junit.Test;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
@@ -136,9 +133,7 @@ public class LoadBalancerProvisionerTest {
.get());
// Application is removed, nodes and load balancer are deactivated
- NestedTransaction removeTransaction = new NestedTransaction();
- tester.provisioner().remove(removeTransaction, app1);
- removeTransaction.commit();
+ tester.remove(app1);
dirtyNodesOf(app1);
assertTrue("No nodes are allocated to " + app1, tester.nodeRepository().getNodes(app1, Node.State.reserved, Node.State.active).isEmpty());
assertEquals(2, lbApp1.get().size());
@@ -170,9 +165,7 @@ public class LoadBalancerProvisionerTest {
assertFalse("Load balancer is reconfigured with reals", tester.loadBalancerService().instances().get(lb.get().id()).reals().isEmpty());
// Application is removed, nodes are deleted and load balancer is deactivated
- NestedTransaction removeTransaction = new NestedTransaction();
- tester.provisioner().remove(removeTransaction, app1);
- removeTransaction.commit();
+ tester.remove(app1);
tester.nodeRepository().database().removeNodes(tester.nodeRepository().getNodes(NodeType.tenant));
assertTrue("Nodes are deleted", tester.nodeRepository().getNodes(NodeType.tenant).isEmpty());
assertSame("Load balancer is deactivated", LoadBalancer.State.inactive, lb.get().state());
@@ -260,21 +253,6 @@ public class LoadBalancerProvisionerTest {
return allNodes;
}
- private void makeDynamicDockerNodes(int n, NodeType nodeType) {
- tester.makeReadyHosts(n, new NodeResources(1, 4, 10, 0.3));
- List<Node> nodes = new ArrayList<>(n);
- for (int i = 1; i <= n; i++) {
- var node = Node.createDockerNode(Set.of(), "vnode" + i,
- tester.nodeRepository().getNodes(NodeType.host).get(n - 1).hostname(),
- new NodeResources(1, 4, 10, 0.3),
- nodeType);
- nodes.add(node);
- }
- nodes = tester.nodeRepository().database().addNodesInState(nodes, Node.State.reserved, Agent.system);
- nodes = tester.nodeRepository().setDirty(nodes, Agent.system, getClass().getSimpleName());
- tester.nodeRepository().setReady(nodes, Agent.system, getClass().getSimpleName());
- }
-
private void assignIps(List<Node> nodes) {
try (var lock = tester.nodeRepository().lockUnallocated()) {
for (int i = 0; i < nodes.size(); i++) {
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java
index 1c03bbc6a56..567ec78576c 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java
@@ -98,9 +98,7 @@ public class ProvisioningTest {
assertEquals(5, tester.getNodes(application1, Node.State.inactive).size());
// delete app
- NestedTransaction removeTransaction = new NestedTransaction();
- tester.provisioner().remove(removeTransaction, application1);
- removeTransaction.commit();
+ tester.remove(application1);
assertEquals(tester.toHostNames(state1.allHosts), tester.toHostNames(tester.nodeRepository().getNodes(application1, Node.State.inactive)));
assertEquals(0, tester.getNodes(application1, Node.State.active).size());
@@ -250,9 +248,7 @@ public class ProvisioningTest {
SystemState state7 = prepare(application1, 8, 2, 2, 2, defaultResources, tester);
// delete app
- NestedTransaction removeTransaction = new NestedTransaction();
- tester.provisioner().remove(removeTransaction, application1);
- removeTransaction.commit();
+ tester.remove(application1);
assertEquals(0, tester.getNodes(application1, Node.State.active).size());
assertEquals(0, tester.getNodes(application1, Node.State.reserved).size());
}
@@ -600,9 +596,7 @@ public class ProvisioningTest {
SystemState state = prepare(application, 2, 2, 3, 3, defaultResources, tester);
// Simulate expiry
- NestedTransaction deactivateTransaction = new NestedTransaction();
- tester.nodeRepository().deactivate(application, deactivateTransaction);
- deactivateTransaction.commit();
+ tester.deactivate(application);
try {
tester.activate(application, state.allHosts);
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java
index a176b28182e..6b7b979e083 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java
@@ -17,6 +17,7 @@ import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeResources.DiskSpeed;
import com.yahoo.config.provision.NodeResources.StorageType;
import com.yahoo.config.provision.NodeType;
+import com.yahoo.config.provision.ProvisionLock;
import com.yahoo.config.provision.ProvisionLogger;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
@@ -203,14 +204,25 @@ public class ProvisioningTester {
}
public Collection<HostSpec> activate(ApplicationId application, Collection<HostSpec> hosts) {
- NestedTransaction transaction = new NestedTransaction();
- transaction.add(new CuratorTransaction(curator));
- provisioner.activate(transaction, application, hosts);
- transaction.commit();
+ try (var lock = provisioner.lock(application)) {
+ NestedTransaction transaction = new NestedTransaction();
+ transaction.add(new CuratorTransaction(curator));
+ provisioner.activate(transaction, hosts, lock);
+ transaction.commit();
+ }
assertEquals(toHostNames(hosts), toHostNames(nodeRepository.getNodes(application, Node.State.active)));
return hosts;
}
+ /** Remove all resources allocated to application */
+ public void remove(ApplicationId application) {
+ try (var lock = provisioner.lock(application)) {
+ NestedTransaction transaction = new NestedTransaction();
+ provisioner.remove(transaction, lock);
+ transaction.commit();
+ }
+ }
+
public void prepareAndActivateInfraApplication(ApplicationId application, NodeType nodeType, Version version) {
ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from(nodeType.toString())).vespaVersion(version).build();
Capacity capacity = Capacity.fromRequiredNodeType(nodeType);
@@ -223,9 +235,11 @@ public class ProvisioningTester {
}
public void deactivate(ApplicationId applicationId) {
- NestedTransaction deactivateTransaction = new NestedTransaction();
- nodeRepository.deactivate(applicationId, deactivateTransaction);
- deactivateTransaction.commit();
+ try (var lock = nodeRepository.lock(applicationId)) {
+ NestedTransaction deactivateTransaction = new NestedTransaction();
+ nodeRepository.deactivate(deactivateTransaction, new ProvisionLock(applicationId, lock));
+ deactivateTransaction.commit();
+ }
}
public Collection<String> toHostNames(Collection<HostSpec> hosts) {
diff --git a/persistence/src/vespa/persistence/dummyimpl/dummypersistence.cpp b/persistence/src/vespa/persistence/dummyimpl/dummypersistence.cpp
index 297a3319939..3285e03db67 100644
--- a/persistence/src/vespa/persistence/dummyimpl/dummypersistence.cpp
+++ b/persistence/src/vespa/persistence/dummyimpl/dummypersistence.cpp
@@ -12,6 +12,7 @@
#include <vespa/vespalib/util/exceptions.h>
#include <vespa/vespalib/stllike/hash_map.hpp>
#include <algorithm>
+#include <cassert>
#include <vespa/log/log.h>
LOG_SETUP(".dummypersistence");
diff --git a/persistence/src/vespa/persistence/spi/bucket.h b/persistence/src/vespa/persistence/spi/bucket.h
index 175aba376a9..b7d04150108 100644
--- a/persistence/src/vespa/persistence/spi/bucket.h
+++ b/persistence/src/vespa/persistence/spi/bucket.h
@@ -36,7 +36,7 @@ public:
/** Convert easily to a document bucket id to make class easy to use. */
operator document::BucketId() const { return _bucket.getBucketId(); }
- bool operator==(const Bucket& o) const {
+ bool operator==(const Bucket& o) const noexcept {
return (_bucket == o._bucket && _partition == o._partition);
}
diff --git a/persistencetypes/src/persistence/spi/types.h b/persistencetypes/src/persistence/spi/types.h
index c11f3dacf06..59891e04710 100644
--- a/persistencetypes/src/persistence/spi/types.h
+++ b/persistencetypes/src/persistence/spi/types.h
@@ -29,10 +29,10 @@ namespace document {
typedef type Type; \
name() noexcept : _value() {} \
explicit name(type v) noexcept : _value(v) {} \
- operator type() const { return _value; } \
- operator type&() { return _value; } \
- type getValue() const { return _value; } \
- name& operator=(type val) { _value = val; return *this; } \
+ operator type() const noexcept { return _value; } \
+ operator type&() noexcept { return _value; } \
+ type getValue() const noexcept { return _value; } \
+ name& operator=(type val) noexcept { _value = val; return *this; } \
friend vespalib::nbostream & \
operator<<(vespalib::nbostream &os, const name &wrapped); \
friend vespalib::nbostream & \
diff --git a/searchcommon/src/vespa/searchcommon/attribute/iattributevector.h b/searchcommon/src/vespa/searchcommon/attribute/iattributevector.h
index 71319d782f1..c26906ac7c0 100644
--- a/searchcommon/src/vespa/searchcommon/attribute/iattributevector.h
+++ b/searchcommon/src/vespa/searchcommon/attribute/iattributevector.h
@@ -36,8 +36,8 @@ private:
int32_t _weight;
public:
- WeightedType() : _value(T()), _weight(1) { }
- WeightedType(T value_, int32_t weight_ = 1) : _value(value_), _weight(weight_) { }
+ WeightedType() noexcept : _value(T()), _weight(1) { }
+ WeightedType(T value_, int32_t weight_ = 1) noexcept : _value(value_), _weight(weight_) { }
const T & getValue() const { return _value; }
const T & value() const { return _value; }
void setValue(const T & v) { _value = v; }
diff --git a/searchcore/src/apps/verify_ranksetup/verify_ranksetup.cpp b/searchcore/src/apps/verify_ranksetup/verify_ranksetup.cpp
index 1d492cb558f..533e8881d27 100644
--- a/searchcore/src/apps/verify_ranksetup/verify_ranksetup.cpp
+++ b/searchcore/src/apps/verify_ranksetup/verify_ranksetup.cpp
@@ -7,6 +7,7 @@
#include <vespa/config-rank-profiles.h>
#include <vespa/config/config.h>
#include <vespa/config/helper/legacy.h>
+#include <vespa/config/common/configcontext.h>
#include <vespa/config/common/exceptions.h>
#include <vespa/eval/eval/tensor_spec.h>
#include <vespa/eval/eval/value_cache/constant_value.h>
@@ -186,7 +187,7 @@ App::Main()
bool ok = false;
try {
- IConfigContext::SP ctx(new ConfigContext(*config::legacyConfigId2Spec(configid)));
+ auto ctx = std::make_shared<ConfigContext>(*config::legacyConfigId2Spec(configid));
vespalib::string cfgId(config::legacyConfigId2ConfigId(configid));
ConfigSubscriber subscriber(ctx);
ConfigHandle<VerifyRanksetupConfig>::UP myHandle = subscriber.subscribe<VerifyRanksetupConfig>(cfgId);
diff --git a/searchcore/src/apps/vespa-feed-bm/bm_storage_link_context.h b/searchcore/src/apps/vespa-feed-bm/bm_storage_link_context.h
index adb2a13ec10..f2df20f1f66 100644
--- a/searchcore/src/apps/vespa-feed-bm/bm_storage_link_context.h
+++ b/searchcore/src/apps/vespa-feed-bm/bm_storage_link_context.h
@@ -10,7 +10,7 @@ class BmStorageLink;
struct BmStorageLinkContext
{
BmStorageLink* bm_link;
- BmStorageLinkContext()
+ BmStorageLinkContext() noexcept
: bm_link(nullptr)
{
}
diff --git a/searchcore/src/apps/vespa-feed-bm/vespa_feed_bm.cpp b/searchcore/src/apps/vespa-feed-bm/vespa_feed_bm.cpp
index 585a493559d..dc2dca4d9c8 100644
--- a/searchcore/src/apps/vespa-feed-bm/vespa_feed_bm.cpp
+++ b/searchcore/src/apps/vespa-feed-bm/vespa_feed_bm.cpp
@@ -24,6 +24,7 @@
#include <vespa/config-summary.h>
#include <vespa/config-summarymap.h>
#include <vespa/config-upgrading.h>
+#include <vespa/config/common/configcontext.h>
#include <vespa/document/datatype/documenttype.h>
#include <vespa/document/fieldvalue/intfieldvalue.h>
#include <vespa/document/repo/configbuilder.h>
diff --git a/searchcore/src/tests/proton/attribute/attribute_test.cpp b/searchcore/src/tests/proton/attribute/attribute_test.cpp
index 8711a21e5e6..a647085e3d1 100644
--- a/searchcore/src/tests/proton/attribute/attribute_test.cpp
+++ b/searchcore/src/tests/proton/attribute/attribute_test.cpp
@@ -739,24 +739,31 @@ assertPutDone(AttributeVector &attr, int32_t expVal)
void
putAttributes(AttributeWriterTest &t, std::vector<uint32_t> expExecuteHistory)
{
+ // Since executor distribution depends on the unspecified hash function in vespalib,
+ // decouple attribute names from their usage to allow for picking names that hash
+ // more evenly for a particular implementation.
+ vespalib::string a1_name = "a1";
+ vespalib::string a2_name = "a2x";
+ vespalib::string a3_name = "a3y";
+
Schema s;
- s.addAttributeField(Schema::AttributeField("a1", schema::DataType::INT32, CollectionType::SINGLE));
- s.addAttributeField(Schema::AttributeField("a2", schema::DataType::INT32, CollectionType::SINGLE));
- s.addAttributeField(Schema::AttributeField("a3", schema::DataType::INT32, CollectionType::SINGLE));
+ s.addAttributeField(Schema::AttributeField(a1_name, schema::DataType::INT32, CollectionType::SINGLE));
+ s.addAttributeField(Schema::AttributeField(a2_name, schema::DataType::INT32, CollectionType::SINGLE));
+ s.addAttributeField(Schema::AttributeField(a3_name, schema::DataType::INT32, CollectionType::SINGLE));
DocBuilder idb(s);
- auto a1 = t.addAttribute("a1");
- auto a2 = t.addAttribute("a2");
- auto a3 = t.addAttribute("a3");
+ auto a1 = t.addAttribute(a1_name);
+ auto a2 = t.addAttribute(a2_name);
+ auto a3 = t.addAttribute(a3_name);
EXPECT_EQ(1u, a1->getNumDocs());
EXPECT_EQ(1u, a2->getNumDocs());
EXPECT_EQ(1u, a3->getNumDocs());
t.put(1, *idb.startDocument("id:ns:searchdocument::1").
- startAttributeField("a1").addInt(10).endField().
- startAttributeField("a2").addInt(15).endField().
- startAttributeField("a3").addInt(20).endField().
+ startAttributeField(a1_name).addInt(10).endField().
+ startAttributeField(a2_name).addInt(15).endField().
+ startAttributeField(a3_name).addInt(20).endField().
endDocument(), 1);
assertPutDone(*a1, 10);
assertPutDone(*a2, 15);
@@ -780,7 +787,7 @@ TEST_F(AttributeWriterTest, spreads_write_over_2_write_contexts)
TEST_F(AttributeWriterTest, spreads_write_over_3_write_contexts)
{
setup(8);
- putAttributes(*this, {0, 1, 3});
+ putAttributes(*this, {4, 5, 6});
}
struct MockPrepareResult : public PrepareResult {
diff --git a/searchcore/src/tests/proton/attribute/imported_attributes_context/imported_attributes_context_test.cpp b/searchcore/src/tests/proton/attribute/imported_attributes_context/imported_attributes_context_test.cpp
index 2dc51d4577e..494b37297f4 100644
--- a/searchcore/src/tests/proton/attribute/imported_attributes_context/imported_attributes_context_test.cpp
+++ b/searchcore/src/tests/proton/attribute/imported_attributes_context/imported_attributes_context_test.cpp
@@ -120,6 +120,10 @@ TEST_F("require that all attributes can be retrieved", Fixture)
std::vector<const IAttributeVector *> list;
f.ctx->getAttributeList(list);
EXPECT_EQUAL(2u, list.size());
+ // Don't depend on internal (unspecified) ordering
+ std::sort(list.begin(), list.end(), [](auto* lhs, auto* rhs){
+ return lhs->getName() < rhs->getName();
+ });
EXPECT_EQUAL("bar", list[0]->getName());
EXPECT_EQUAL("foo", list[1]->getName());
}
diff --git a/searchcore/src/tests/proton/attribute/imported_attributes_repo/imported_attributes_repo_test.cpp b/searchcore/src/tests/proton/attribute/imported_attributes_repo/imported_attributes_repo_test.cpp
index d92392ec8df..3155d7930e1 100644
--- a/searchcore/src/tests/proton/attribute/imported_attributes_repo/imported_attributes_repo_test.cpp
+++ b/searchcore/src/tests/proton/attribute/imported_attributes_repo/imported_attributes_repo_test.cpp
@@ -9,6 +9,7 @@ LOG_SETUP("imported_attributes_repo_test");
#include <vespa/searchlib/attribute/imported_attribute_vector.h>
#include <vespa/searchlib/attribute/imported_attribute_vector_factory.h>
#include <vespa/searchlib/attribute/reference_attribute.h>
+#include <algorithm>
using proton::ImportedAttributesRepo;
using search::AttributeVector;
@@ -74,6 +75,10 @@ TEST_F("require that all attributes can be retrieved", Fixture)
std::vector<ImportedAttributeVector::SP> list;
f.repo.getAll(list);
EXPECT_EQUAL(2u, list.size());
+ // Don't depend on internal (unspecified) ordering
+ std::sort(list.begin(), list.end(), [](auto& lhs, auto& rhs){
+ return lhs->getName() < rhs->getName();
+ });
EXPECT_EQUAL("bar", list[0]->getName());
EXPECT_EQUAL("foo", list[1]->getName());
}
diff --git a/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp b/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp
index aebe5a61198..43f16e87986 100644
--- a/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp
@@ -24,7 +24,6 @@
#include <vespa/searchcore/proton/matching/querylimiter.h>
#include <vespa/searchcore/proton/test/test.h>
#include <vespa/searchcore/proton/test/thread_utils.h>
-#include <vespa/searchcorespi/plugin/iindexmanagerfactory.h>
#include <vespa/searchlib/common/idestructorcallback.h>
#include <vespa/searchlib/index/docbuilder.h>
#include <vespa/searchlib/test/directory_handler.h>
diff --git a/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp b/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp
index b275064c0f2..9122ea7850f 100644
--- a/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp
@@ -176,7 +176,7 @@ struct MyGidToLidChangeHandler : public MockGidToLidChangeHandler
uint32_t _changes;
std::map<document::GlobalId, uint32_t> _gidToLid;
public:
- MyGidToLidChangeHandler()
+ MyGidToLidChangeHandler() noexcept
: MockGidToLidChangeHandler(),
_changeGid(),
_changeLid(std::numeric_limits<uint32_t>::max()),
@@ -594,7 +594,8 @@ struct FixtureBase
void putAndWait(const DocumentContext &docCtx) {
FeedTokenContext token(_tracer);
PutOperation op(docCtx.bid, docCtx.ts, docCtx.doc);
- runInMaster([&] () { performPut(token.ft, op); });
+ runInMaster([this, ft=std::move(token.ft), &op] () mutable { performPut(std::move(ft), op); });
+ token.mt.await();
}
void performUpdate(FeedToken token, UpdateOperation &op) {
@@ -606,7 +607,8 @@ struct FixtureBase
void updateAndWait(const DocumentContext &docCtx) {
FeedTokenContext token(_tracer);
UpdateOperation op(docCtx.bid, docCtx.ts, docCtx.upd);
- runInMaster([&] () { performUpdate(token.ft, op); });
+ runInMaster([this, ft=std::move(token.ft), &op] () mutable { performUpdate(std::move(ft), op); });
+ token.mt.await();
}
void performRemove(FeedToken token, RemoveOperation &op) {
@@ -620,7 +622,8 @@ struct FixtureBase
void removeAndWait(const DocumentContext &docCtx) {
FeedTokenContext token(_tracer);
RemoveOperationWithDocId op(docCtx.bid, docCtx.ts, docCtx.doc->getId());
- runInMaster([&] () { performRemove(token.ft, op); });
+ runInMaster([this, ft=std::move(token.ft), &op] () mutable { performRemove(std::move(ft), op); });
+ token.mt.await();
}
void removeAndWait(const DocumentContext::List &docs) {
@@ -647,7 +650,9 @@ struct FixtureBase
}
void performForceCommit() { getFeedView().forceCommit(serial); }
- void forceCommitAndWait() { runInMaster([&]() { performForceCommit(); }); }
+ void forceCommitAndWait() {
+ runInMaster([&]() { performForceCommit(); });
+ }
bool assertTrace(const vespalib::string &exp) {
return EXPECT_EQUAL(exp, _tracer._os.str());
diff --git a/searchcore/src/tests/proton/documentdb/lid_space_compaction/lid_space_compaction_test.cpp b/searchcore/src/tests/proton/documentdb/lid_space_compaction/lid_space_compaction_test.cpp
index 04444647b5d..8890a6cfdda 100644
--- a/searchcore/src/tests/proton/documentdb/lid_space_compaction/lid_space_compaction_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/lid_space_compaction/lid_space_compaction_test.cpp
@@ -212,11 +212,10 @@ MyDocumentStore::~MyDocumentStore() = default;
struct MyDocumentRetriever : public DocumentRetrieverBaseForTest {
std::shared_ptr<const DocumentTypeRepo> repo;
const MyDocumentStore& store;
- MyDocumentRetriever(std::shared_ptr<const DocumentTypeRepo> repo_in, const MyDocumentStore& store_in)
+ MyDocumentRetriever(std::shared_ptr<const DocumentTypeRepo> repo_in, const MyDocumentStore& store_in) noexcept
: repo(std::move(repo_in)),
store(store_in)
- {
- }
+ {}
const document::DocumentTypeRepo& getDocumentTypeRepo() const override { return *repo; }
void getBucketMetaData(const storage::spi::Bucket&, DocumentMetaData::Vector&) const override { abort(); }
DocumentMetaData getDocumentMetaData(const DocumentId&) const override { abort(); }
diff --git a/searchcore/src/tests/proton/documentdb/maintenancecontroller/maintenancecontroller_test.cpp b/searchcore/src/tests/proton/documentdb/maintenancecontroller/maintenancecontroller_test.cpp
index 70b2100521f..63c7a873eaf 100644
--- a/searchcore/src/tests/proton/documentdb/maintenancecontroller/maintenancecontroller_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/maintenancecontroller/maintenancecontroller_test.cpp
@@ -147,7 +147,7 @@ struct MyDocumentRetriever : public DocumentRetrieverBaseForTest
{
MyDocumentSubDB &_subDB;
- explicit MyDocumentRetriever(MyDocumentSubDB &subDB)
+ explicit MyDocumentRetriever(MyDocumentSubDB &subDB) noexcept
: _subDB(subDB)
{
}
diff --git a/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp b/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp
index 8d1276497bd..e6e71d51e47 100644
--- a/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp
@@ -171,7 +171,7 @@ struct MoveOperationFeedView : public MyMinimalFeedView {
struct MoveOperationCallback : public IDestructorCallback {
int &outstandingMoveOps;
- MoveOperationCallback(int &outstandingMoveOps_) : outstandingMoveOps(outstandingMoveOps_) {
+ explicit MoveOperationCallback(int &outstandingMoveOps_) noexcept : outstandingMoveOps(outstandingMoveOps_) {
++outstandingMoveOps;
}
~MoveOperationCallback() override {
@@ -194,7 +194,7 @@ struct FixtureBase {
documentmetastore::LidReuseDelayerConfig lidReuseDelayerConfig;
typename FeedViewType::UP feedview;
- FixtureBase(SubDbType subDbType = SubDbType::READY)
+ explicit FixtureBase(SubDbType subDbType = SubDbType::READY)
: removeCount(0),
putCount(0),
heartbeatCount(0),
diff --git a/searchcore/src/tests/proton/documentmetastore/documentmetastore_test.cpp b/searchcore/src/tests/proton/documentmetastore/documentmetastore_test.cpp
index 9ca22bafe9a..60d96e37e15 100644
--- a/searchcore/src/tests/proton/documentmetastore/documentmetastore_test.cpp
+++ b/searchcore/src/tests/proton/documentmetastore/documentmetastore_test.cpp
@@ -2090,7 +2090,7 @@ public:
size_t remove_batch_cnt;
size_t remove_cnt;
- MockOperationListener()
+ MockOperationListener() noexcept
: remove_batch_cnt(0),
remove_cnt(0)
{
diff --git a/searchcore/src/tests/proton/flushengine/flushengine_test.cpp b/searchcore/src/tests/proton/flushengine/flushengine_test.cpp
index 08fa1b11229..38fca35ea87 100644
--- a/searchcore/src/tests/proton/flushengine/flushengine_test.cpp
+++ b/searchcore/src/tests/proton/flushengine/flushengine_test.cpp
@@ -361,14 +361,14 @@ public:
public:
typedef std::shared_ptr<SimpleStrategy> SP;
- SimpleStrategy() {}
+ SimpleStrategy() noexcept : _targets() {}
uint32_t
indexOf(const IFlushTarget::SP &target) const
{
IFlushTarget *raw = target.get();
CachedFlushTarget *cached = dynamic_cast<CachedFlushTarget*>(raw);
- if (cached != NULL) {
+ if (cached != nullptr) {
raw = cached->getFlushTarget().get();
}
WrappedFlushTarget *wrapped = dynamic_cast<WrappedFlushTarget *>(raw);
diff --git a/searchcore/src/tests/proton/flushengine/prepare_restart_flush_strategy/prepare_restart_flush_strategy_test.cpp b/searchcore/src/tests/proton/flushengine/prepare_restart_flush_strategy/prepare_restart_flush_strategy_test.cpp
index 5f93f97f165..1b8be388c13 100644
--- a/searchcore/src/tests/proton/flushengine/prepare_restart_flush_strategy/prepare_restart_flush_strategy_test.cpp
+++ b/searchcore/src/tests/proton/flushengine/prepare_restart_flush_strategy/prepare_restart_flush_strategy_test.cpp
@@ -27,16 +27,16 @@ struct SimpleFlushTarget : public test::DummyFlushTarget
const Type &type,
SerialNum flushedSerial_,
uint64_t approxDiskBytes_,
- double replay_operation_cost_)
+ double replay_operation_cost_) noexcept
: test::DummyFlushTarget(name, type, Component::OTHER),
flushedSerial(flushedSerial_),
approxDiskBytes(approxDiskBytes_),
replay_operation_cost(replay_operation_cost_)
{}
- virtual SerialNum getFlushedSerialNum() const override {
+ SerialNum getFlushedSerialNum() const override {
return flushedSerial;
}
- virtual uint64_t getApproxBytesToWriteToDisk() const override {
+ uint64_t getApproxBytesToWriteToDisk() const override {
return approxDiskBytes;
}
double get_replay_operation_cost() const override {
diff --git a/searchcore/src/tests/proton/flushengine/shrink_lid_space_flush_target/shrink_lid_space_flush_target_test.cpp b/searchcore/src/tests/proton/flushengine/shrink_lid_space_flush_target/shrink_lid_space_flush_target_test.cpp
index 964cd47afa5..6c502bccce1 100644
--- a/searchcore/src/tests/proton/flushengine/shrink_lid_space_flush_target/shrink_lid_space_flush_target_test.cpp
+++ b/searchcore/src/tests/proton/flushengine/shrink_lid_space_flush_target/shrink_lid_space_flush_target_test.cpp
@@ -18,26 +18,26 @@ class MyLidSpace : public search::common::ICompactableLidSpace
bool _canShrink;
size_t _canFree;
public:
- MyLidSpace()
+ MyLidSpace() noexcept
: _canShrink(true),
_canFree(16)
{
}
- virtual ~MyLidSpace() override {}
+ ~MyLidSpace() override = default;
- virtual void compactLidSpace(uint32_t wantedDocLidLimit) override {
+ void compactLidSpace(uint32_t wantedDocLidLimit) override {
(void) wantedDocLidLimit;
}
- virtual bool canShrinkLidSpace() const override {
+ bool canShrinkLidSpace() const override {
return _canShrink;
}
- virtual size_t getEstimatedShrinkLidSpaceGain() const override {
+ size_t getEstimatedShrinkLidSpaceGain() const override {
return _canShrink ? _canFree : 0;
}
- virtual void shrinkLidSpace() override {
+ void shrinkLidSpace() override {
if (_canShrink) {
_canFree = 0;
_canShrink = false;
@@ -62,9 +62,11 @@ struct Fixture
{
}
- ~Fixture() { }
+ ~Fixture();
};
+Fixture::~Fixture() = default;
+
TEST_F("require that flush target returns estimated memory gain", Fixture)
{
auto memoryGain = f._ft->getApproxMemoryGain();
diff --git a/searchcore/src/tests/proton/matching/matching_test.cpp b/searchcore/src/tests/proton/matching/matching_test.cpp
index 22dc19167f6..30f83273bd7 100644
--- a/searchcore/src/tests/proton/matching/matching_test.cpp
+++ b/searchcore/src/tests/proton/matching/matching_test.cpp
@@ -284,7 +284,7 @@ struct MyWorld {
struct MySearchHandler : ISearchHandler {
Matcher::SP _matcher;
- MySearchHandler(Matcher::SP matcher) : _matcher(matcher) {}
+ MySearchHandler(Matcher::SP matcher) noexcept : _matcher(std::move(matcher)) {}
DocsumReply::UP getDocsums(const DocsumRequest &) override {
return DocsumReply::UP();
diff --git a/searchcore/src/tests/proton/proton_config_fetcher/proton_config_fetcher_test.cpp b/searchcore/src/tests/proton/proton_config_fetcher/proton_config_fetcher_test.cpp
index 1e64a8f4ecb..93fe2f0ae24 100644
--- a/searchcore/src/tests/proton/proton_config_fetcher/proton_config_fetcher_test.cpp
+++ b/searchcore/src/tests/proton/proton_config_fetcher/proton_config_fetcher_test.cpp
@@ -14,6 +14,7 @@
#include <vespa/fileacquirer/config-filedistributorrpc.h>
#include <vespa/vespalib/util/varholder.h>
#include <vespa/vespalib/testkit/testapp.h>
+#include <vespa/config/common/configcontext.h>
#include <vespa/config-bucketspaces.h>
#include <vespa/config-attributes.h>
#include <vespa/config-imported-fields.h>
@@ -73,7 +74,7 @@ struct ConfigTestFixture {
bucketspacesBuilder(),
dbConfig(),
set(),
- context(new ConfigContext(set)),
+ context(std::make_shared<ConfigContext>(set)),
idcounter(-1)
{
set.addBuilder(configId, &protonBuilder);
diff --git a/searchcore/src/tests/proton/reference/document_db_reference_resolver/document_db_reference_resolver_test.cpp b/searchcore/src/tests/proton/reference/document_db_reference_resolver/document_db_reference_resolver_test.cpp
index 48b2a269f6b..bacdd85dcc5 100644
--- a/searchcore/src/tests/proton/reference/document_db_reference_resolver/document_db_reference_resolver_test.cpp
+++ b/searchcore/src/tests/proton/reference/document_db_reference_resolver/document_db_reference_resolver_test.cpp
@@ -61,7 +61,7 @@ struct MyDocumentDBReference : public MockDocumentDBReference {
std::shared_ptr<MockGidToLidChangeHandler> _gidToLidChangeHandler;
MyDocumentDBReference(MyGidToLidMapperFactory::SP factory_,
- std::shared_ptr<MockGidToLidChangeHandler> gidToLidChangeHandler)
+ std::shared_ptr<MockGidToLidChangeHandler> gidToLidChangeHandler) noexcept
: factory(std::move(factory_)),
_gidToLidChangeHandler(std::move(gidToLidChangeHandler))
{
diff --git a/searchcore/src/tests/proton/reference/gid_to_lid_change_handler/gid_to_lid_change_handler_test.cpp b/searchcore/src/tests/proton/reference/gid_to_lid_change_handler/gid_to_lid_change_handler_test.cpp
index 920472c6a01..a10d48ee7fe 100644
--- a/searchcore/src/tests/proton/reference/gid_to_lid_change_handler/gid_to_lid_change_handler_test.cpp
+++ b/searchcore/src/tests/proton/reference/gid_to_lid_change_handler/gid_to_lid_change_handler_test.cpp
@@ -39,7 +39,7 @@ class ListenerStats {
uint32_t _destroyedListeners;
public:
- ListenerStats()
+ ListenerStats() noexcept
: _lock(),
_putChanges(0u),
_removeChanges(0u),
diff --git a/searchcore/src/tests/proton/reprocessing/reprocessing_runner/reprocessing_runner_test.cpp b/searchcore/src/tests/proton/reprocessing/reprocessing_runner/reprocessing_runner_test.cpp
index 0053a03105f..242ad91271e 100644
--- a/searchcore/src/tests/proton/reprocessing/reprocessing_runner/reprocessing_runner_test.cpp
+++ b/searchcore/src/tests/proton/reprocessing/reprocessing_runner/reprocessing_runner_test.cpp
@@ -32,7 +32,7 @@ struct MyTask : public IReprocessingTask
double initProgress,
double middleProgress,
double finalProgress,
- double weight)
+ double weight) noexcept
: _runner(runner),
_initProgress(initProgress),
_middleProgress(middleProgress),
@@ -42,9 +42,7 @@ struct MyTask : public IReprocessingTask
{
}
- virtual void
- run() override
- {
+ void run() override {
ASSERT_EQUAL(_initProgress, _runner.getProgress());
_myProgress = 0.5;
ASSERT_EQUAL(_middleProgress, _runner.getProgress());
@@ -52,9 +50,7 @@ struct MyTask : public IReprocessingTask
ASSERT_EQUAL(_finalProgress, _runner.getProgress());
}
- virtual Progress
- getProgress() const override
- {
+ Progress getProgress() const override {
return Progress(_myProgress, _weight);
}
@@ -65,11 +61,7 @@ struct MyTask : public IReprocessingTask
double finalProgress,
double weight)
{
- return std::make_shared<MyTask>(runner,
- initProgress,
- middleProgress,
- finalProgress,
- weight);
+ return std::make_shared<MyTask>(runner, initProgress, middleProgress, finalProgress, weight);
}
};
@@ -77,16 +69,8 @@ TEST_F("require that progress is calculated when tasks are executed", Fixture)
{
TaskList tasks;
EXPECT_EQUAL(0.0, f._runner.getProgress());
- tasks.push_back(MyTask::create(f._runner,
- 0.0,
- 0.1,
- 0.2,
- 1.0));
- tasks.push_back(MyTask::create(f._runner,
- 0.2,
- 0.6,
- 1.0,
- 4.0));
+ tasks.push_back(MyTask::create(f._runner, 0.0, 0.1, 0.2, 1.0));
+ tasks.push_back(MyTask::create(f._runner, 0.2, 0.6, 1.0, 4.0));
f._runner.addTasks(tasks);
tasks.clear();
EXPECT_EQUAL(0.0, f._runner.getProgress());
@@ -99,11 +83,7 @@ TEST_F("require that runner can be reset", Fixture)
{
TaskList tasks;
EXPECT_EQUAL(0.0, f._runner.getProgress());
- tasks.push_back(MyTask::create(f._runner,
- 0.0,
- 0.5,
- 1.0,
- 1.0));
+ tasks.push_back(MyTask::create(f._runner, 0.0, 0.5, 1.0, 1.0));
f._runner.addTasks(tasks);
tasks.clear();
EXPECT_EQUAL(0.0, f._runner.getProgress());
@@ -111,21 +91,13 @@ TEST_F("require that runner can be reset", Fixture)
EXPECT_EQUAL(1.0, f._runner.getProgress());
f._runner.reset();
EXPECT_EQUAL(0.0, f._runner.getProgress());
- tasks.push_back(MyTask::create(f._runner,
- 0.0,
- 0.5,
- 1.0,
- 1.0));
+ tasks.push_back(MyTask::create(f._runner, 0.0, 0.5, 1.0, 1.0));
f._runner.addTasks(tasks);
tasks.clear();
EXPECT_EQUAL(0.0, f._runner.getProgress());
f._runner.reset();
EXPECT_EQUAL(0.0, f._runner.getProgress());
- tasks.push_back(MyTask::create(f._runner,
- 0.0,
- 0.5,
- 1.0,
- 4.0));
+ tasks.push_back(MyTask::create(f._runner, 0.0, 0.5, 1.0, 4.0));
f._runner.addTasks(tasks);
tasks.clear();
EXPECT_EQUAL(0.0, f._runner.getProgress());
diff --git a/searchcore/src/tests/proton/server/feedstates_test.cpp b/searchcore/src/tests/proton/server/feedstates_test.cpp
index 42d88328d14..59e504de6ce 100644
--- a/searchcore/src/tests/proton/server/feedstates_test.cpp
+++ b/searchcore/src/tests/proton/server/feedstates_test.cpp
@@ -124,7 +124,7 @@ TEST_F("require that replay progress is tracked", Fixture)
{
RemoveOperationContext opCtx(10);
TlsReplayProgress progress("test", 5, 15);
- PacketWrapper::SP wrap(new PacketWrapper(*opCtx.packet, &progress));
+ auto wrap = std::make_shared<PacketWrapper>(*opCtx.packet, &progress);
ForegroundThreadExecutor executor;
f.state.receive(wrap, executor);
diff --git a/searchcore/src/tests/proton/server/memoryflush/memoryflush_test.cpp b/searchcore/src/tests/proton/server/memoryflush/memoryflush_test.cpp
index 7f650847183..305f5d8c9ba 100644
--- a/searchcore/src/tests/proton/server/memoryflush/memoryflush_test.cpp
+++ b/searchcore/src/tests/proton/server/memoryflush/memoryflush_test.cpp
@@ -22,19 +22,13 @@ typedef IFlushTarget::DiskGain DiskGain;
class MyFlushHandler : public IFlushHandler {
public:
- MyFlushHandler(const vespalib::string &name) : IFlushHandler(name) {}
- // Implements IFlushHandler
- virtual std::vector<IFlushTarget::SP> getFlushTargets() override {
+ MyFlushHandler(const vespalib::string &name) noexcept : IFlushHandler(name) {}
+ std::vector<IFlushTarget::SP> getFlushTargets() override {
return std::vector<IFlushTarget::SP>();
}
- virtual SerialNum getCurrentSerialNumber() const override { return 0; }
- virtual void flushDone(SerialNum oldestSerial) override { (void) oldestSerial; }
-
- virtual void
- syncTls(search::SerialNum syncTo) override
- {
- (void) syncTo;
- }
+ SerialNum getCurrentSerialNumber() const override { return 0; }
+ void flushDone(SerialNum oldestSerial) override { (void) oldestSerial; }
+ void syncTls(search::SerialNum syncTo) override {(void) syncTo;}
};
class MyFlushTarget : public test::DummyFlushTarget {
@@ -47,7 +41,7 @@ private:
public:
MyFlushTarget(const vespalib::string &name, MemoryGain memoryGain,
DiskGain diskGain, SerialNum flushedSerial,
- system_time lastFlushTime, bool urgentFlush) :
+ system_time lastFlushTime, bool urgentFlush) noexcept :
test::DummyFlushTarget(name),
_memoryGain(memoryGain),
_diskGain(diskGain),
@@ -56,12 +50,11 @@ public:
_urgentFlush(urgentFlush)
{
}
- // Implements IFlushTarget
- virtual MemoryGain getApproxMemoryGain() const override { return _memoryGain; }
- virtual DiskGain getApproxDiskGain() const override { return _diskGain; }
- virtual SerialNum getFlushedSerialNum() const override { return _flushedSerial; }
- virtual system_time getLastFlushTime() const override { return _lastFlushTime; }
- virtual bool needUrgentFlush() const override { return _urgentFlush; }
+ MemoryGain getApproxMemoryGain() const override { return _memoryGain; }
+ DiskGain getApproxDiskGain() const override { return _diskGain; }
+ SerialNum getFlushedSerialNum() const override { return _flushedSerial; }
+ system_time getLastFlushTime() const override { return _lastFlushTime; }
+ bool needUrgentFlush() const override { return _urgentFlush; }
};
struct StringList : public std::vector<vespalib::string> {
diff --git a/searchcore/src/vespa/searchcore/config/proton.def b/searchcore/src/vespa/searchcore/config/proton.def
index fd60781d868..bcc35204efd 100644
--- a/searchcore/src/vespa/searchcore/config/proton.def
+++ b/searchcore/src/vespa/searchcore/config/proton.def
@@ -135,7 +135,7 @@ indexing.tasklimit int default=1000 restart
## nonzero. The number is divided by the number of indexing threads,
## i.e. when indexing.threads is 4 and indexing.semiunboundtasklimit
## is 40000 then effective task limit is 10000.
-indexing.semiunboundtasklimit int default = 40000 restart
+indexing.semiunboundtasklimit int default = 1000 restart
## Kind of watermark for when to activate extra manpower
## Utilized if optimize is set to either THROUGHPUT or ADAPTIVE
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attribute_populator.cpp b/searchcore/src/vespa/searchcore/proton/attribute/attribute_populator.cpp
index 5208195a968..33a5776cb8a 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/attribute_populator.cpp
+++ b/searchcore/src/vespa/searchcore/proton/attribute/attribute_populator.cpp
@@ -18,7 +18,7 @@ class PopulateDoneContext : public IDestructorCallback
{
std::shared_ptr<document::Document> _doc;
public:
- PopulateDoneContext(std::shared_ptr<document::Document> doc)
+ PopulateDoneContext(std::shared_ptr<document::Document> doc) noexcept
: _doc(std::move(doc))
{
}
diff --git a/searchcore/src/vespa/searchcore/proton/common/doctypename.cpp b/searchcore/src/vespa/searchcore/proton/common/doctypename.cpp
index 21b27ef6ffd..4d76018d66b 100644
--- a/searchcore/src/vespa/searchcore/proton/common/doctypename.cpp
+++ b/searchcore/src/vespa/searchcore/proton/common/doctypename.cpp
@@ -7,12 +7,12 @@
namespace proton {
-DocTypeName::DocTypeName(const search::engine::Request &request)
+DocTypeName::DocTypeName(const search::engine::Request &request) noexcept
: _name(request.propertiesMap.matchProperties().lookup("documentdb", "searchdoctype").get(""))
{}
-DocTypeName::DocTypeName(const document::DocumentType &docType)
+DocTypeName::DocTypeName(const document::DocumentType &docType) noexcept
: _name(docType.getName())
{}
diff --git a/searchcore/src/vespa/searchcore/proton/common/doctypename.h b/searchcore/src/vespa/searchcore/proton/common/doctypename.h
index 661d54ab8d4..f0fa3c72ee9 100644
--- a/searchcore/src/vespa/searchcore/proton/common/doctypename.h
+++ b/searchcore/src/vespa/searchcore/proton/common/doctypename.h
@@ -13,9 +13,9 @@ class DocTypeName
vespalib::string _name;
public:
- explicit DocTypeName(const vespalib::string &name) : _name(name) { }
- explicit DocTypeName(const search::engine::Request &request);
- explicit DocTypeName(const document::DocumentType &docType);
+ explicit DocTypeName(const vespalib::string &name) noexcept : _name(name) { }
+ explicit DocTypeName(const search::engine::Request &request) noexcept;
+ explicit DocTypeName(const document::DocumentType &docType) noexcept;
const vespalib::string & getName() const { return _name; }
diff --git a/searchcore/src/vespa/searchcore/proton/documentmetastore/gid_compare.h b/searchcore/src/vespa/searchcore/proton/documentmetastore/gid_compare.h
index dd32abcab6e..c16dd8a7292 100644
--- a/searchcore/src/vespa/searchcore/proton/documentmetastore/gid_compare.h
+++ b/searchcore/src/vespa/searchcore/proton/documentmetastore/gid_compare.h
@@ -14,7 +14,7 @@ class IGidCompare
public:
typedef std::shared_ptr<IGidCompare> SP;
- virtual ~IGidCompare() {}
+ virtual ~IGidCompare() = default;
virtual bool operator()(const document::GlobalId &lhs,
const document::GlobalId &rhs) const = 0;
@@ -30,14 +30,13 @@ private:
document::GlobalId::BucketOrderCmp _comp;
public:
- DefaultGidCompare()
+ DefaultGidCompare() noexcept
: IGidCompare(),
_comp()
{
}
- virtual bool operator()(const document::GlobalId &lhs,
- const document::GlobalId &rhs) const override {
+ bool operator()(const document::GlobalId &lhs, const document::GlobalId &rhs) const override {
return _comp(lhs, rhs);
}
};
diff --git a/searchcore/src/vespa/searchcore/proton/flushengine/iflushhandler.h b/searchcore/src/vespa/searchcore/proton/flushengine/iflushhandler.h
index 914de9df30c..ca23f27ed49 100644
--- a/searchcore/src/vespa/searchcore/proton/flushengine/iflushhandler.h
+++ b/searchcore/src/vespa/searchcore/proton/flushengine/iflushhandler.h
@@ -28,7 +28,7 @@ public:
*
* @param name The unique name of this handler.
*/
- IFlushHandler(const vespalib::string &name)
+ IFlushHandler(const vespalib::string &name) noexcept
: _name(name)
{ }
diff --git a/searchcore/src/vespa/searchcore/proton/initializer/task_runner.h b/searchcore/src/vespa/searchcore/proton/initializer/task_runner.h
index f28c46334bc..bd0d82b0b2c 100644
--- a/searchcore/src/vespa/searchcore/proton/initializer/task_runner.h
+++ b/searchcore/src/vespa/searchcore/proton/initializer/task_runner.h
@@ -28,7 +28,7 @@ class TaskRunner {
using SP = std::shared_ptr<Context>;
Context(InitializerTask::SP rootTask,
vespalib::Executor &contextExecutor,
- vespalib::Executor::Task::UP doneTask)
+ vespalib::Executor::Task::UP doneTask) noexcept
: _rootTask(rootTask),
_contextExecutor(contextExecutor),
_doneTask(std::move(doneTask))
diff --git a/searchcore/src/vespa/searchcore/proton/matching/partial_result.h b/searchcore/src/vespa/searchcore/proton/matching/partial_result.h
index 5bcc8dafea2..ac3c6ab5e0f 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/partial_result.h
+++ b/searchcore/src/vespa/searchcore/proton/matching/partial_result.h
@@ -5,6 +5,7 @@
#include <vespa/vespalib/util/dual_merge_director.h>
#include <vespa/searchlib/common/rankedhit.h>
#include <vector>
+#include <cassert>
namespace proton::matching {
@@ -28,7 +29,7 @@ private:
public:
PartialResult(size_t maxSize_in, bool hasSortData_in);
- ~PartialResult();
+ ~PartialResult() override;
size_t size() const { return _hits.size(); }
size_t maxSize() const { return _maxSize; }
size_t totalHits() const { return _totalHits; }
diff --git a/searchcore/src/vespa/searchcore/proton/matching/sessionmanager.h b/searchcore/src/vespa/searchcore/proton/matching/sessionmanager.h
index 96c83270735..0cff5583bbd 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/sessionmanager.h
+++ b/searchcore/src/vespa/searchcore/proton/matching/sessionmanager.h
@@ -37,7 +37,7 @@ public:
vespalib::steady_time doom;
SearchSessionInfo(const vespalib::string &id_in,
vespalib::steady_time created_in,
- vespalib::steady_time doom_in)
+ vespalib::steady_time doom_in) noexcept
: id(id_in), created(created_in), doom(doom_in) {}
};
diff --git a/searchcore/src/vespa/searchcore/proton/server/documentdbconfigmanager.cpp b/searchcore/src/vespa/searchcore/proton/server/documentdbconfigmanager.cpp
index c8b701e82f8..e842e3cdc41 100644
--- a/searchcore/src/vespa/searchcore/proton/server/documentdbconfigmanager.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/documentdbconfigmanager.cpp
@@ -9,6 +9,7 @@
#include <vespa/config-rank-profiles.h>
#include <vespa/config-summarymap.h>
#include <vespa/config/file_acquirer/file_acquirer.h>
+#include <vespa/config/common/configcontext.h>
#include <vespa/config/helper/legacy.h>
#include <vespa/config-attributes.h>
#include <vespa/config-indexschema.h>
diff --git a/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp b/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp
index 174ba090842..a52be734c13 100644
--- a/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp
@@ -111,7 +111,7 @@ TlsMgrWriter::sync(SerialNum syncTo)
class OnCommitDone : public search::IDestructorCallback {
public:
- OnCommitDone(Executor & executor, std::unique_ptr<Executor::Task> task)
+ OnCommitDone(Executor & executor, std::unique_ptr<Executor::Task> task) noexcept
: _executor(executor),
_task(std::move(task))
{}
diff --git a/searchcore/src/vespa/searchcore/proton/server/feedstates.h b/searchcore/src/vespa/searchcore/proton/server/feedstates.h
index 0c2e9109cce..3d24f4068a2 100644
--- a/searchcore/src/vespa/searchcore/proton/server/feedstates.h
+++ b/searchcore/src/vespa/searchcore/proton/server/feedstates.h
@@ -24,7 +24,7 @@ class InitState : public FeedState {
vespalib::string _doc_type_name;
public:
- InitState(const vespalib::string &name)
+ InitState(const vespalib::string &name) noexcept
: FeedState(INIT),
_doc_type_name(name)
{
@@ -73,7 +73,7 @@ class NormalState : public FeedState {
FeedHandler &_handler;
public:
- NormalState(FeedHandler &handler)
+ NormalState(FeedHandler &handler) noexcept
: FeedState(NORMAL),
_handler(handler) {
}
diff --git a/searchcore/src/vespa/searchcore/proton/server/move_operation_limiter.cpp b/searchcore/src/vespa/searchcore/proton/server/move_operation_limiter.cpp
index e535b05393c..c84abb373f8 100644
--- a/searchcore/src/vespa/searchcore/proton/server/move_operation_limiter.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/move_operation_limiter.cpp
@@ -10,7 +10,7 @@ using BlockedReason = IBlockableMaintenanceJob::BlockedReason;
struct MoveOperationLimiter::Callback : public search::IDestructorCallback {
MoveOperationLimiter::SP _limiter;
- Callback(MoveOperationLimiter::SP limiter) : _limiter(std::move(limiter)) {}
+ Callback(MoveOperationLimiter::SP limiter) noexcept : _limiter(std::move(limiter)) {}
virtual ~Callback() { _limiter->endOperation(); }
};
diff --git a/searchcore/src/vespa/searchcore/proton/server/packetwrapper.h b/searchcore/src/vespa/searchcore/proton/server/packetwrapper.h
index c36652ec847..6f132604662 100644
--- a/searchcore/src/vespa/searchcore/proton/server/packetwrapper.h
+++ b/searchcore/src/vespa/searchcore/proton/server/packetwrapper.h
@@ -20,8 +20,7 @@ struct PacketWrapper {
search::transactionlog::client::RPC::Result result;
vespalib::Gate gate;
- PacketWrapper(const search::transactionlog::Packet &p,
- TlsReplayProgress *progress_)
+ PacketWrapper(const search::transactionlog::Packet &p, TlsReplayProgress *progress_) noexcept
: packet(p),
progress(progress_),
result(search::transactionlog::client::RPC::ERROR),
diff --git a/searchcore/src/vespa/searchcore/proton/server/rpc_hooks.cpp b/searchcore/src/vespa/searchcore/proton/server/rpc_hooks.cpp
index c724e1065e9..428aba1a6b5 100644
--- a/searchcore/src/vespa/searchcore/proton/server/rpc_hooks.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/rpc_hooks.cpp
@@ -19,7 +19,7 @@ namespace {
struct Pair {
string key;
string value;
- Pair(const string &k, const string &v)
+ Pair(const string &k, const string &v) noexcept
: key(k),
value(v)
{
@@ -200,7 +200,7 @@ RPCHooksBase::RPCHooksBase(Params &params)
_proton.get_search_server(),
_proton.get_docsum_server(),
_proton.get_monitor_server(), *_orb)),
- _regAPI(*_orb, params.slobrok_config),
+ _regAPI(*_orb, slobrok::ConfiguratorFactory(params.slobrok_config)),
_stateLock(),
_stateCond(),
_executor(48, 128 * 1024)
diff --git a/searchcore/src/vespa/searchcore/proton/server/threading_service_config.cpp b/searchcore/src/vespa/searchcore/proton/server/threading_service_config.cpp
index cf9f27a94af..3b268835331 100644
--- a/searchcore/src/vespa/searchcore/proton/server/threading_service_config.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/threading_service_config.cpp
@@ -60,7 +60,7 @@ ThreadingServiceConfig::make(const ProtonConfig &cfg, double concurrency, const
{
uint32_t indexingThreads = calculateIndexingThreads(cfg.indexing, concurrency, cpuInfo);
return ThreadingServiceConfig(indexingThreads, cfg.indexing.tasklimit,
- (cfg.indexing.semiunboundtasklimit / indexingThreads),
+ std::max(uint32_t(cfg.indexing.tasklimit), (cfg.indexing.semiunboundtasklimit / indexingThreads)),
selectOptimization(cfg.indexing.optimize),
cfg.indexing.kindOfWatermark,
vespalib::from_s(cfg.indexing.reactiontime));
diff --git a/searchcore/src/vespa/searchcore/proton/test/document_meta_store_observer.h b/searchcore/src/vespa/searchcore/proton/test/document_meta_store_observer.h
index 66cc5ed0fea..a6ff6d86d0d 100644
--- a/searchcore/src/vespa/searchcore/proton/test/document_meta_store_observer.h
+++ b/searchcore/src/vespa/searchcore/proton/test/document_meta_store_observer.h
@@ -15,38 +15,36 @@ struct DocumentMetaStoreObserver : public IDocumentMetaStore
DocId _compactLidSpaceLidLimit;
uint32_t _holdUnblockShrinkLidSpaceCnt;
- DocumentMetaStoreObserver(IDocumentMetaStore &store)
+ DocumentMetaStoreObserver(IDocumentMetaStore &store) noexcept
: _store(store),
_removeCompleteCnt(0),
_removeCompleteLid(0),
_compactLidSpaceLidLimit(0),
_holdUnblockShrinkLidSpaceCnt(0)
- {
- }
+ {}
/**
* Implements search::IDocumentMetaStore
**/
- virtual bool getGid(DocId lid, GlobalId &gid) const override {
+ bool getGid(DocId lid, GlobalId &gid) const override {
return _store.getGid(lid, gid);
}
- virtual bool getGidEvenIfMoved(DocId lid, GlobalId &gid) const override {
+ bool getGidEvenIfMoved(DocId lid, GlobalId &gid) const override {
return _store.getGidEvenIfMoved(lid, gid);
}
- virtual bool getLid(const GlobalId &gid, DocId &lid) const override {
+ bool getLid(const GlobalId &gid, DocId &lid) const override {
return _store.getLid(gid, lid);
}
- virtual search::DocumentMetaData getMetaData(const GlobalId &gid) const override {
+ search::DocumentMetaData getMetaData(const GlobalId &gid) const override {
return _store.getMetaData(gid);
}
- virtual void getMetaData(const BucketId &bucketId,
- search::DocumentMetaData::Vector &result) const override {
+ void getMetaData(const BucketId &bucketId, search::DocumentMetaData::Vector &result) const override {
_store.getMetaData(bucketId, result);
}
- virtual search::LidUsageStats getLidUsageStats() const override {
+ search::LidUsageStats getLidUsageStats() const override {
return _store.getLidUsageStats();
}
- virtual search::queryeval::Blueprint::UP createWhiteListBlueprint() const override {
+ search::queryeval::Blueprint::UP createWhiteListBlueprint() const override {
return _store.createWhiteListBlueprint();
}
uint64_t getCurrentGeneration() const override {
@@ -57,40 +55,39 @@ struct DocumentMetaStoreObserver : public IDocumentMetaStore
/**
* Implements documentmetastore::IStore.
*/
- virtual Result inspectExisting(const GlobalId &gid, uint64_t prepare_serial_num) override {
+ Result inspectExisting(const GlobalId &gid, uint64_t prepare_serial_num) override {
return _store.inspectExisting(gid, prepare_serial_num);
}
- virtual Result inspect(const GlobalId &gid, uint64_t prepare_serial_num) override {
+ Result inspect(const GlobalId &gid, uint64_t prepare_serial_num) override {
return _store.inspect(gid, prepare_serial_num);
}
- virtual Result put(const GlobalId &gid,
- const BucketId &bucketId,
- const Timestamp &timestamp,
- uint32_t docSize,
- DocId lid,
- uint64_t prepare_serial_num) override {
+ Result put(const GlobalId &gid,
+ const BucketId &bucketId,
+ const Timestamp &timestamp,
+ uint32_t docSize,
+ DocId lid,
+ uint64_t prepare_serial_num) override
+ {
return _store.put(gid, bucketId, timestamp, docSize, lid, prepare_serial_num);
}
- virtual bool updateMetaData(DocId lid,
- const BucketId &bucketId,
- const Timestamp &timestamp) override {
+ bool updateMetaData(DocId lid, const BucketId &bucketId, const Timestamp &timestamp) override {
return _store.updateMetaData(lid, bucketId, timestamp);
}
- virtual bool remove(DocId lid, uint64_t prepare_serial_num) override {
+ bool remove(DocId lid, uint64_t prepare_serial_num) override {
return _store.remove(lid, prepare_serial_num);
}
- virtual void removeComplete(DocId lid) override {
+ void removeComplete(DocId lid) override {
++_removeCompleteCnt;
_removeCompleteLid = lid;
_store.removeComplete(lid);
}
- virtual void move(DocId fromLid, DocId toLid, uint64_t prepare_serial_num) override {
+ void move(DocId fromLid, DocId toLid, uint64_t prepare_serial_num) override {
_store.move(fromLid, toLid, prepare_serial_num);
}
- virtual bool validLid(DocId lid) const override {
+ bool validLid(DocId lid) const override {
return _store.validLid(lid);
}
- virtual void removeBatch(const std::vector<DocId> &lidsToRemove,
+ void removeBatch(const std::vector<DocId> &lidsToRemove,
const DocId docIdLimit) override {
_store.removeBatch(lidsToRemove, docIdLimit);
}
diff --git a/searchcore/src/vespa/searchcore/proton/test/dummy_flush_handler.h b/searchcore/src/vespa/searchcore/proton/test/dummy_flush_handler.h
index 53fa8a9c3fb..af2f4c63443 100644
--- a/searchcore/src/vespa/searchcore/proton/test/dummy_flush_handler.h
+++ b/searchcore/src/vespa/searchcore/proton/test/dummy_flush_handler.h
@@ -3,37 +3,32 @@
#include <vespa/searchcore/proton/flushengine/iflushhandler.h>
-namespace proton {
-
-namespace test {
+namespace proton::test {
/**
* Default implementation used for testing.
*/
struct DummyFlushHandler : public IFlushHandler
{
- DummyFlushHandler(const vespalib::string &name)
+ DummyFlushHandler(const vespalib::string &name) noexcept
: IFlushHandler(name)
{}
- // Implements IFlushHandler
- virtual std::vector<IFlushTarget::SP> getFlushTargets() override {
+ std::vector<IFlushTarget::SP> getFlushTargets() override {
return std::vector<IFlushTarget::SP>();
}
- virtual SerialNum getCurrentSerialNumber() const override {
+ SerialNum getCurrentSerialNumber() const override {
return 0;
}
- virtual void flushDone(SerialNum oldestSerial) override {
+ void flushDone(SerialNum oldestSerial) override {
(void) oldestSerial;
}
- virtual void syncTls(SerialNum syncTo) override {
+ void syncTls(SerialNum syncTo) override {
(void) syncTo;
}
};
-} // namespace test
-
-} // namespace proton
+}
diff --git a/searchcore/src/vespa/searchcore/proton/test/dummy_flush_target.h b/searchcore/src/vespa/searchcore/proton/test/dummy_flush_target.h
index 8e291126430..dd3cd49df2f 100644
--- a/searchcore/src/vespa/searchcore/proton/test/dummy_flush_target.h
+++ b/searchcore/src/vespa/searchcore/proton/test/dummy_flush_target.h
@@ -3,39 +3,33 @@
#include <vespa/searchcorespi/flush/iflushtarget.h>
-namespace proton {
-
-namespace test {
+namespace proton::test {
struct DummyFlushTarget : public searchcorespi::IFlushTarget
{
- DummyFlushTarget(const vespalib::string &name)
+ DummyFlushTarget(const vespalib::string &name) noexcept
: searchcorespi::IFlushTarget(name)
{}
DummyFlushTarget(const vespalib::string &name,
const Type &type,
- const Component &component)
+ const Component &component) noexcept
: searchcorespi::IFlushTarget(name, type, component)
{}
- // Implements searchcorespi::IFlushTarget
- virtual MemoryGain getApproxMemoryGain() const override { return MemoryGain(0, 0); }
- virtual DiskGain getApproxDiskGain() const override { return DiskGain(0, 0); }
- virtual SerialNum getFlushedSerialNum() const override { return 0; }
- virtual Time getLastFlushTime() const override { return Time(); }
- virtual bool needUrgentFlush() const override { return false; }
- virtual searchcorespi::FlushTask::UP initFlush(SerialNum) override {
+ MemoryGain getApproxMemoryGain() const override { return MemoryGain(0, 0); }
+ DiskGain getApproxDiskGain() const override { return DiskGain(0, 0); }
+ SerialNum getFlushedSerialNum() const override { return 0; }
+ Time getLastFlushTime() const override { return Time(); }
+ bool needUrgentFlush() const override { return false; }
+ searchcorespi::FlushTask::UP initFlush(SerialNum) override {
return searchcorespi::FlushTask::UP();
}
- virtual searchcorespi::FlushStats getLastFlushStats() const override {
+ searchcorespi::FlushStats getLastFlushStats() const override {
return searchcorespi::FlushStats();
}
- virtual uint64_t getApproxBytesToWriteToDisk() const override {
+ uint64_t getApproxBytesToWriteToDisk() const override {
return 0;
}
};
-} // namespace test
-
-} // namespace proton
-
+}
diff --git a/searchcore/src/vespa/searchcore/proton/test/mock_gid_to_lid_change_handler.h b/searchcore/src/vespa/searchcore/proton/test/mock_gid_to_lid_change_handler.h
index e808f721e83..f9531486e9b 100644
--- a/searchcore/src/vespa/searchcore/proton/test/mock_gid_to_lid_change_handler.h
+++ b/searchcore/src/vespa/searchcore/proton/test/mock_gid_to_lid_change_handler.h
@@ -23,7 +23,7 @@ private:
std::vector<std::unique_ptr<IGidToLidChangeListener>> _listeners;
public:
- MockGidToLidChangeHandler()
+ MockGidToLidChangeHandler() noexcept
: IGidToLidChangeHandler(),
_adds(),
_removes(),
@@ -31,7 +31,7 @@ public:
{
}
- ~MockGidToLidChangeHandler() override { }
+ ~MockGidToLidChangeHandler() override = default;
void addListener(std::unique_ptr<IGidToLidChangeListener> listener) override {
_adds.emplace_back(listener->getDocTypeName(), listener->getName());
diff --git a/searchcore/src/vespa/searchcore/proton/test/thread_utils.h b/searchcore/src/vespa/searchcore/proton/test/thread_utils.h
index 4dac300d614..340d3b08441 100644
--- a/searchcore/src/vespa/searchcore/proton/test/thread_utils.h
+++ b/searchcore/src/vespa/searchcore/proton/test/thread_utils.h
@@ -4,9 +4,7 @@
#include <vespa/searchcorespi/index/ithreadingservice.h>
#include <vespa/vespalib/util/closuretask.h>
-namespace proton {
-
-namespace test {
+namespace proton::test {
template <typename FunctionType>
void
@@ -20,15 +18,11 @@ runFunction(FunctionType *func)
*/
template <typename FunctionType>
void
-runInMaster(searchcorespi::index::IThreadingService &writeService,
- FunctionType func)
+runInMaster(searchcorespi::index::IThreadingService &writeService, FunctionType func)
{
writeService.master().execute(vespalib::makeTask
(vespalib::makeClosure(&runFunction<FunctionType>, &func)));
writeService.sync();
}
-} // namespace test
-
-} // namespace proton
-
+}
diff --git a/searchcorespi/CMakeLists.txt b/searchcorespi/CMakeLists.txt
index 32469886bf8..2faa2be3b82 100644
--- a/searchcorespi/CMakeLists.txt
+++ b/searchcorespi/CMakeLists.txt
@@ -18,8 +18,4 @@ vespa_define_module(
src/vespa/searchcorespi
src/vespa/searchcorespi/flush
src/vespa/searchcorespi/index
- src/vespa/searchcorespi/plugin
-
- TESTS
- src/tests/plugin
)
diff --git a/searchcorespi/src/tests/plugin/.gitignore b/searchcorespi/src/tests/plugin/.gitignore
deleted file mode 100644
index e49000038ad..00000000000
--- a/searchcorespi/src/tests/plugin/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-Makefile
-.depend
-*_test
-searchcorespi_factoryregistry_test_app
-searchcorespi_plugin_test_app
diff --git a/searchcorespi/src/tests/plugin/CMakeLists.txt b/searchcorespi/src/tests/plugin/CMakeLists.txt
deleted file mode 100644
index da785b09b6a..00000000000
--- a/searchcorespi/src/tests/plugin/CMakeLists.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_library(searchcorespi_tplugin
- SOURCES
- plugin.cpp
- DEPENDS
- searchcorespi
-)
-vespa_add_library(searchcorespi_illegal-plugin
- SOURCES
- empty.cpp
- DEPENDS
- searchcorespi
-)
-vespa_add_executable(searchcorespi_plugin_test_app TEST
- SOURCES
- plugin_test.cpp
- DEPENDS
- searchcorespi
-)
-vespa_add_test(
- NAME searchcorespi_plugin_test_app
- COMMAND searchcorespi_plugin_test_app
- ENVIRONMENT "LD_LIBRARY_PATH=."
- DEPENDS searchcorespi_tplugin searchcorespi_illegal-plugin
-)
-vespa_add_executable(searchcorespi_factoryregistry_test_app TEST
- SOURCES
- factoryregistry_test.cpp
- DEPENDS
- searchcorespi
-)
-vespa_add_test(NAME searchcorespi_factoryregistry_test_app COMMAND searchcorespi_factoryregistry_test_app)
diff --git a/searchcorespi/src/tests/plugin/empty.cpp b/searchcorespi/src/tests/plugin/empty.cpp
deleted file mode 100644
index c7c47fc98c5..00000000000
--- a/searchcorespi/src/tests/plugin/empty.cpp
+++ /dev/null
@@ -1 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
diff --git a/searchcorespi/src/tests/plugin/factoryregistry_test.cpp b/searchcorespi/src/tests/plugin/factoryregistry_test.cpp
deleted file mode 100644
index 10a1c95f191..00000000000
--- a/searchcorespi/src/tests/plugin/factoryregistry_test.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include <vespa/searchcorespi/plugin/factoryregistry.h>
-#include <vespa/searchcorespi/plugin/iindexmanagerfactory.h>
-#include <vespa/vespalib/stllike/string.h>
-#include <vespa/vespalib/testkit/testapp.h>
-#include <vespa/vespalib/util/exceptions.h>
-
-using vespalib::string;
-using namespace searchcorespi;
-
-namespace {
-
-struct MyFactory : IIndexManagerFactory {
-
- virtual IIndexManager::UP createIndexManager(const IndexManagerConfig &,
- const index::IndexMaintainerConfig &,
- const index::IndexMaintainerContext &) override {
- return IIndexManager::UP();
- }
- virtual config::ConfigKeySet getConfigKeys(
- const string &,
- const search::index::Schema &,
- const config::ConfigInstance &) override {
- return config::ConfigKeySet();
- }
-};
-
-const string name = "factory";
-
-TEST("require that factories can be added and removed") {
- FactoryRegistry registry;
- EXPECT_FALSE(registry.isRegistered(name));
- registry.add(name, IIndexManagerFactory::SP(new MyFactory));
- EXPECT_TRUE(registry.get(name).get());
- EXPECT_TRUE(registry.isRegistered(name));
- registry.remove(name);
- EXPECT_EXCEPTION(registry.get(name), vespalib::IllegalArgumentException,
- "No factory is registered with the name");
-}
-
-TEST("require that two factories with the same name cannot be added") {
- FactoryRegistry registry;
- registry.add(name, IIndexManagerFactory::SP(new MyFactory));
- EXPECT_EXCEPTION(
- registry.add(name, IIndexManagerFactory::SP(new MyFactory)),
- vespalib::IllegalArgumentException,
- "A factory is already registered with the same name");
-}
-
-TEST("require that a non-existent factory cannot be removed") {
- FactoryRegistry registry;
- EXPECT_EXCEPTION(registry.remove(name), vespalib::IllegalArgumentException,
- "No factory is registered with the name");
-}
-
-} // namespace
-
-TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/searchcorespi/src/tests/plugin/plugin.cpp b/searchcorespi/src/tests/plugin/plugin.cpp
deleted file mode 100644
index d32b02f45fd..00000000000
--- a/searchcorespi/src/tests/plugin/plugin.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/searchcorespi/plugin/iindexmanagerfactory.h>
-
-using namespace search;
-using namespace search::index;
-using namespace vespalib;
-using namespace config;
-
-namespace searchcorespi {
-class IndexManager : public searchcorespi::IIndexManager
-{
-public:
-
- typedef search::SerialNum SerialNum;
- typedef search::index::Schema Schema;
- typedef document::Document Document;
- using OnWriteDoneType =
- const std::shared_ptr<search::IDestructorCallback> &;
- virtual void putDocument(uint32_t, const Document &, SerialNum) override { }
- virtual void removeDocument(uint32_t, SerialNum) override { }
- virtual void commit(SerialNum, OnWriteDoneType) override { }
- virtual void heartBeat(SerialNum ) override {}
- void compactLidSpace(uint32_t, SerialNum) override {}
- virtual SerialNum getCurrentSerialNum() const override { return 0; }
- virtual SerialNum getFlushedSerialNum() const override { return 0; }
- virtual IndexSearchable::SP getSearchable() const override {
- IndexSearchable::SP s;
- return s;
- }
- virtual SearchableStats getSearchableStats() const override {
- SearchableStats s;
- return s;
- }
- virtual searchcorespi::IFlushTarget::List getFlushTargets() override {
- searchcorespi::IFlushTarget::List l;
- return l;
- }
- virtual void setSchema(const Schema &, SerialNum) override { }
- virtual void setMaxFlushed(uint32_t) override { }
-};
-
-class IndexManagerFactory : public searchcorespi::IIndexManagerFactory
-{
-public:
- virtual IIndexManager::UP createIndexManager(const IndexManagerConfig &managerCfg,
- const index::IndexMaintainerConfig &maintainerConfig,
- const index::IndexMaintainerContext &maintainerContext) override;
-
- virtual ConfigKeySet getConfigKeys(const string &configId,
- const Schema &schema,
- const ConfigInstance &rootConfig) override;
-};
-
-IIndexManager::UP
-IndexManagerFactory::createIndexManager(const IndexManagerConfig &,
- const index::IndexMaintainerConfig &,
- const index::IndexMaintainerContext &)
-{
- return IIndexManager::UP(new IndexManager());
-}
-
-ConfigKeySet
-IndexManagerFactory::getConfigKeys(const string &,
- const Schema &,
- const ConfigInstance &)
-{
- ConfigKeySet keys;
- return keys;
-}
-
-}
-
-searchcorespi::IIndexManagerFactory *
-createIndexManagerFactory()
-{
- return new searchcorespi::IndexManagerFactory();
-}
-
diff --git a/searchcorespi/src/tests/plugin/plugin_test.cpp b/searchcorespi/src/tests/plugin/plugin_test.cpp
deleted file mode 100644
index 733c2834c24..00000000000
--- a/searchcorespi/src/tests/plugin/plugin_test.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include <vespa/vespalib/testkit/testapp.h>
-#include <vespa/searchcorespi/plugin/factoryloader.h>
-#include <vespa/vespalib/util/exceptions.h>
-
-using namespace searchcorespi;
-
-namespace {
-TEST("require that plugins can be loaded.") {
- FactoryLoader fl;
- IIndexManagerFactory::UP f = fl.create("searchcorespi_tplugin");
- ASSERT_TRUE(f.get());
-}
-
-TEST("require that non-existent plugin causes failure") {
- FactoryLoader fl;
-#ifdef __APPLE__
- EXPECT_EXCEPTION(fl.create("no-such-plugin"),
- vespalib::IllegalArgumentException,
- "image not found");
-#else
- EXPECT_EXCEPTION(fl.create("no-such-plugin"),
- vespalib::IllegalArgumentException,
- "cannot open shared object file");
-#endif
-}
-
-TEST("require that missing factory function causes failure") {
- FactoryLoader fl;
- EXPECT_EXCEPTION(fl.create("searchcorespi_illegal-plugin"),
- vespalib::IllegalArgumentException,
- "Failed locating symbol 'createIndexManagerFactory'");
-}
-} // namespace
-
-TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/searchcorespi/src/vespa/searchcorespi/CMakeLists.txt b/searchcorespi/src/vespa/searchcorespi/CMakeLists.txt
index 3cbe1265136..bee83a7f936 100644
--- a/searchcorespi/src/vespa/searchcorespi/CMakeLists.txt
+++ b/searchcorespi/src/vespa/searchcorespi/CMakeLists.txt
@@ -3,7 +3,6 @@ vespa_add_library(searchcorespi
SOURCES
$<TARGET_OBJECTS:searchcorespi_flush>
$<TARGET_OBJECTS:searchcorespi_index>
- $<TARGET_OBJECTS:searchcorespi_plugin>
INSTALL lib64
DEPENDS
)
diff --git a/searchcorespi/src/vespa/searchcorespi/flush/iflushtarget.h b/searchcorespi/src/vespa/searchcorespi/flush/iflushtarget.h
index 10ed19a7244..3a67333c9d5 100644
--- a/searchcorespi/src/vespa/searchcorespi/flush/iflushtarget.h
+++ b/searchcorespi/src/vespa/searchcorespi/flush/iflushtarget.h
@@ -45,8 +45,8 @@ public:
template<typename T>
class Gain {
public:
- Gain() : _before(0), _after(0) { }
- Gain(T before, T after) : _before(before), _after(after) { }
+ Gain() noexcept : _before(0), _after(0) { }
+ Gain(T before, T after) noexcept : _before(before), _after(after) { }
T getBefore() const { return _before; }
T getAfter() const { return _after; }
T gain() const { return _before - _after; }
@@ -74,7 +74,7 @@ public:
*
* @param name The handler-wide unique name of this target.
*/
- IFlushTarget(const vespalib::string &name)
+ IFlushTarget(const vespalib::string &name) noexcept
: _name(name),
_type(Type::OTHER),
_component(Component::OTHER)
@@ -89,7 +89,7 @@ public:
*/
IFlushTarget(const vespalib::string &name,
const Type &type,
- const Component &component)
+ const Component &component) noexcept
: _name(name),
_type(type),
_component(component)
@@ -98,7 +98,7 @@ public:
/**
* Virtual destructor required for inheritance.
*/
- virtual ~IFlushTarget() { }
+ virtual ~IFlushTarget() = default;
/**
* Returns the handler-wide unique name of this target.
diff --git a/searchcorespi/src/vespa/searchcorespi/index/activediskindexes.cpp b/searchcorespi/src/vespa/searchcorespi/index/activediskindexes.cpp
index b8572541f36..bec6f02324a 100644
--- a/searchcorespi/src/vespa/searchcorespi/index/activediskindexes.cpp
+++ b/searchcorespi/src/vespa/searchcorespi/index/activediskindexes.cpp
@@ -1,27 +1,29 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "activediskindexes.h"
+#include <cassert>
-using std::set;
using vespalib::string;
-using vespalib::LockGuard;
namespace searchcorespi::index {
+ActiveDiskIndexes::ActiveDiskIndexes() = default;
+ActiveDiskIndexes::~ActiveDiskIndexes() = default;
+
void ActiveDiskIndexes::setActive(const string &index) {
- LockGuard lock(_lock);
+ std::lock_guard lock(_lock);
_active.insert(index);
}
void ActiveDiskIndexes::notActive(const string & index) {
- LockGuard lock(_lock);
- set<string>::iterator it = _active.find(index);
+ std::lock_guard lock(_lock);
+ auto it = _active.find(index);
assert(it != _active.end());
_active.erase(it);
}
bool ActiveDiskIndexes::isActive(const string &index) const {
- LockGuard lock(_lock);
+ std::lock_guard lock(_lock);
return _active.find(index) != _active.end();
}
diff --git a/searchcorespi/src/vespa/searchcorespi/index/activediskindexes.h b/searchcorespi/src/vespa/searchcorespi/index/activediskindexes.h
index dff25906559..c1c0e4e4d88 100644
--- a/searchcorespi/src/vespa/searchcorespi/index/activediskindexes.h
+++ b/searchcorespi/src/vespa/searchcorespi/index/activediskindexes.h
@@ -3,11 +3,10 @@
#pragma once
#include <vespa/vespalib/stllike/string.h>
-#include <vespa/vespalib/util/sync.h>
#include <set>
+#include <mutex>
-namespace searchcorespi {
-namespace index {
+namespace searchcorespi::index {
/**
* Class used to keep track of the set of active disk indexes in an index maintainer.
@@ -15,16 +14,17 @@ namespace index {
*/
class ActiveDiskIndexes {
std::multiset<vespalib::string> _active;
- vespalib::Lock _lock;
+ mutable std::mutex _lock;
public:
- typedef std::shared_ptr<ActiveDiskIndexes> SP;
-
+ using SP = std::shared_ptr<ActiveDiskIndexes>;
+ ActiveDiskIndexes();
+ ~ActiveDiskIndexes();
+ ActiveDiskIndexes(const ActiveDiskIndexes &) = delete;
+ ActiveDiskIndexes & operator = (const ActiveDiskIndexes &) = delete;
void setActive(const vespalib::string & index);
void notActive(const vespalib::string & index);
bool isActive(const vespalib::string & index) const;
};
-} // namespace index
-} // namespace searchcorespi
-
+}
diff --git a/searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.cpp b/searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.cpp
index 32dc2531061..c75a74ff141 100644
--- a/searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.cpp
+++ b/searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.cpp
@@ -41,7 +41,6 @@ using vespalib::makeTask;
using vespalib::string;
using vespalib::Closure0;
using vespalib::Executor;
-using vespalib::LockGuard;
using vespalib::Runnable;
namespace searchcorespi::index {
@@ -349,10 +348,12 @@ IndexMaintainer::loadDiskIndexes(const FusionSpec &spec, ISearchableIndexCollect
namespace {
+ using LockGuard = std::lock_guard<std::mutex>;
+
ISearchableIndexCollection::SP
getLeaf(const LockGuard &newSearchLock, const ISearchableIndexCollection::SP & is, bool warn=false)
{
- if (dynamic_cast<const WarmupIndexCollection *>(is.get()) != NULL) {
+ if (dynamic_cast<const WarmupIndexCollection *>(is.get()) != nullptr) {
if (warn) {
LOG(info, "Already warming up an index '%s'. Start using it immediately."
" This is an indication that you have configured your warmup interval too long.",
diff --git a/searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.h b/searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.h
index 671f87ff35b..5ff805b53f7 100644
--- a/searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.h
+++ b/searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.h
@@ -18,9 +18,6 @@
#include <vespa/searchcorespi/flush/flushstats.h>
#include <vespa/searchlib/attribute/fixedsourceselector.h>
#include <vespa/searchlib/common/serialnum.h>
-#include <vespa/vespalib/util/sync.h>
-#include <memory>
-#include <vector>
namespace document { class Document; }
@@ -74,6 +71,7 @@ class IndexMaintainer : public IIndexManager,
using FlushIds = std::vector<uint32_t>;
using FrozenMemoryIndexRefs = std::vector<FrozenMemoryIndexRef>;
using ISourceSelector = search::queryeval::ISourceSelector;
+ using LockGuard = std::lock_guard<std::mutex>;
const vespalib::string _base_dir;
const WarmupConfig _warmupConfig;
@@ -129,17 +127,17 @@ class IndexMaintainer : public IIndexManager,
* and pruning of removed fields, since this will trigger more retries for
* some of the operations.
*/
- vespalib::Lock _state_lock; // Outer lock (SL)
- vespalib::Lock _index_update_lock; // Inner lock (IUL)
- vespalib::Lock _new_search_lock; // Inner lock (NSL)
- vespalib::Lock _remove_lock; // Lock for removing indexes.
+ std::mutex _state_lock; // Outer lock (SL)
+ mutable std::mutex _index_update_lock; // Inner lock (IUL)
+ mutable std::mutex _new_search_lock; // Inner lock (NSL)
+ std::mutex _remove_lock; // Lock for removing indexes.
// Protected by SL + IUL
- FusionSpec _fusion_spec; // Protected by FL
- vespalib::Lock _fusion_lock; // Fusion spec lock (FL)
+ FusionSpec _fusion_spec; // Protected by FL
+ mutable std::mutex _fusion_lock; // Fusion spec lock (FL)
uint32_t _maxFlushed;
uint32_t _maxFrozen;
ChangeGens _changeGens; // Protected by SL + IUL
- vespalib::Lock _schemaUpdateLock; // Serialize rewrite of schema
+ std::mutex _schemaUpdateLock; // Serialize rewrite of schema
const search::TuneFileAttributes _tuneFileAttributes;
const IndexMaintainerContext _ctx;
IIndexMaintainerOperations &_operations;
@@ -179,8 +177,8 @@ class IndexMaintainer : public IIndexManager,
ISearchableIndexCollection::UP loadDiskIndexes(const FusionSpec &spec, ISearchableIndexCollection::UP sourceList);
void replaceSource(uint32_t sourceId, const IndexSearchable::SP &source);
void appendSource(uint32_t sourceId, const IndexSearchable::SP &source);
- void swapInNewIndex(vespalib::LockGuard & guard, ISearchableIndexCollection::SP indexes, IndexSearchable & source);
- ISearchableIndexCollection::UP createNewSourceCollection(const vespalib::LockGuard &newSearchLock);
+ void swapInNewIndex(LockGuard & guard, ISearchableIndexCollection::SP indexes, IndexSearchable & source);
+ ISearchableIndexCollection::UP createNewSourceCollection(const LockGuard &newSearchLock);
struct FlushArgs {
IMemoryIndex::SP old_index; // Last memory index
@@ -353,17 +351,17 @@ public:
}
IIndexCollection::SP getSourceCollection() const {
- vespalib::LockGuard lock(_new_search_lock);
+ LockGuard lock(_new_search_lock);
return _source_list;
}
searchcorespi::IndexSearchable::SP getSearchable() const override {
- vespalib::LockGuard lock(_new_search_lock);
+ LockGuard lock(_new_search_lock);
return _source_list;
}
search::SearchableStats getSearchableStats() const override {
- vespalib::LockGuard lock(_new_search_lock);
+ LockGuard lock(_new_search_lock);
return _source_list->getSearchableStats();
}
diff --git a/searchcorespi/src/vespa/searchcorespi/plugin/.gitignore b/searchcorespi/src/vespa/searchcorespi/plugin/.gitignore
deleted file mode 100644
index 7e7c0fe7fae..00000000000
--- a/searchcorespi/src/vespa/searchcorespi/plugin/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/.depend
-/Makefile
diff --git a/searchcorespi/src/vespa/searchcorespi/plugin/CMakeLists.txt b/searchcorespi/src/vespa/searchcorespi/plugin/CMakeLists.txt
deleted file mode 100644
index b564a593e4e..00000000000
--- a/searchcorespi/src/vespa/searchcorespi/plugin/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_library(searchcorespi_plugin OBJECT
- SOURCES
- factoryregistry.cpp
- factoryloader.cpp
- DEPENDS
-)
diff --git a/searchcorespi/src/vespa/searchcorespi/plugin/factoryloader.cpp b/searchcorespi/src/vespa/searchcorespi/plugin/factoryloader.cpp
deleted file mode 100644
index ba2b0b962f6..00000000000
--- a/searchcorespi/src/vespa/searchcorespi/plugin/factoryloader.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include "factoryloader.h"
-#include <vespa/vespalib/util/exceptions.h>
-
-using vespalib::stringref;
-using vespalib::make_string;
-using vespalib::IllegalArgumentException;
-
-namespace searchcorespi {
-
-FactoryLoader::FactoryLoader() :
- _libraries()
-{
-}
-
-FactoryLoader::~FactoryLoader() = default;
-
-IIndexManagerFactory::UP
-FactoryLoader::create(stringref factory)
-{
- typedef IIndexManagerFactory* (*FuncT)();
- _libraries.loadLibrary(factory);
- const FastOS_DynamicLibrary & lib = *_libraries.get(factory);
- FuncT registrationMethod = reinterpret_cast<FuncT>(lib.GetSymbol("createIndexManagerFactory"));
- if (registrationMethod == nullptr) {
- throw IllegalArgumentException(make_string("Failed locating symbol 'createIndexManagerFactory' in library '%s' for factory '%s'.",
- lib.GetLibName(), vespalib::string(factory).c_str()));
- }
- return IIndexManagerFactory::UP(registrationMethod());
-}
-
-}
diff --git a/searchcorespi/src/vespa/searchcorespi/plugin/factoryloader.h b/searchcorespi/src/vespa/searchcorespi/plugin/factoryloader.h
deleted file mode 100644
index 3eda6557fa0..00000000000
--- a/searchcorespi/src/vespa/searchcorespi/plugin/factoryloader.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#pragma once
-
-#include <vespa/searchcorespi/plugin/iindexmanagerfactory.h>
-#include <vespa/vespalib/util/librarypool.h>
-
-namespace searchcorespi {
-
-class FactoryLoader
-{
-public:
- FactoryLoader();
- ~FactoryLoader();
- /**
- * Will load the library containing the factory. It will then locate the 'createIndexManagerFactory'
- * symbol and run it to create the factory.
- * @param the name of the library. Like 'vesparise'.
- * @return the factory that is created.
- */
- IIndexManagerFactory::UP create(vespalib::stringref factory);
-private:
- vespalib::LibraryPool _libraries;
-};
-
-} // namespace searchcorespi
-
diff --git a/searchcorespi/src/vespa/searchcorespi/plugin/factoryregistry.cpp b/searchcorespi/src/vespa/searchcorespi/plugin/factoryregistry.cpp
deleted file mode 100644
index bd1b914cf39..00000000000
--- a/searchcorespi/src/vespa/searchcorespi/plugin/factoryregistry.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/searchcorespi/plugin/factoryregistry.h>
-#include <vespa/vespalib/util/exceptions.h>
-
-using vespalib::LockGuard;
-using vespalib::IllegalArgumentException;
-using vespalib::stringref;
-using vespalib::string;
-
-namespace searchcorespi {
-
-FactoryRegistry::FactoryRegistry() = default;
-
-FactoryRegistry::~FactoryRegistry() = default;
-
-void FactoryRegistry::add(stringref uniqueName, const IIndexManagerFactory::SP & factory)
-{
- LockGuard guard(_lock);
- if (_registry.find(uniqueName) == _registry.end()) {
- _registry[uniqueName] = factory;
- } else {
- throw IllegalArgumentException("A factory is already registered with the same name as '" + uniqueName + "'.", VESPA_STRLOC);
- }
-}
-
-void FactoryRegistry::remove(stringref uniqueName)
-{
- LockGuard guard(_lock);
- if (_registry.find(uniqueName) == _registry.end()) {
- throw IllegalArgumentException("No factory is registered with the name of '" + uniqueName + "'.", VESPA_STRLOC);
- }
- _registry.erase(uniqueName);
-}
-
-const IIndexManagerFactory::SP &
-FactoryRegistry::get(stringref uniqueName) const
-{
- LockGuard guard(_lock);
- Registry::const_iterator found = _registry.find(uniqueName);
- if (found == _registry.end()) {
- throw IllegalArgumentException("No factory is registered with the name of '" + uniqueName + "'.", VESPA_STRLOC);
- }
- return found->second;
-}
-
-bool
-FactoryRegistry::isRegistered(vespalib::stringref uniqueName) const
-{
- LockGuard guard(_lock);
- Registry::const_iterator found = _registry.find(uniqueName);
- return found != _registry.end();
-}
-
-}
diff --git a/searchcorespi/src/vespa/searchcorespi/plugin/factoryregistry.h b/searchcorespi/src/vespa/searchcorespi/plugin/factoryregistry.h
deleted file mode 100644
index feb27d62950..00000000000
--- a/searchcorespi/src/vespa/searchcorespi/plugin/factoryregistry.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#pragma once
-
-#include <vespa/searchcorespi/plugin/iindexmanagerfactory.h>
-
-namespace searchcorespi {
-
-/**
- */
-class FactoryRegistry
-{
-public:
- FactoryRegistry();
- ~FactoryRegistry();
- /**
- * This will register the plugged in factory under its official
- * name. The plugin should call this method when it is loaded. E.g.
- * by using either '__attribute__((constructor))' or using a
- * global static object that will use its constructor to register
- * the factory.
- * @param uniqueName This is a name that is unique over all IndexManager factories.
- * @param factory The factory instance for producing IndexManagers.
- * @throws vespalib::IllegalArgument if factory is already registered.
- */
- void add(vespalib::stringref uniqueName, const IIndexManagerFactory::SP & factory);
- /**
- * Will unregister a factory. Should be called when a sharedlibrary is being unloaded.
- * @param uniqueName Unique name of factory to remove from registry.
- * @throws vespalib::IllegalArgument if factory is already registered.
- */
- void remove(vespalib::stringref uniqueName);
- /**
- * This method will fetch a factory given its unique name.
- * @param name The name of the factory to return.
- * @return The factory.
- */
- const IIndexManagerFactory::SP & get(vespalib::stringref uniqueName) const;
- /**
- * Returns true if a factory with the given name has been registered.
- */
- bool isRegistered(vespalib::stringref uniqueName) const;
-
-private:
- typedef std::map<vespalib::string, IIndexManagerFactory::SP> Registry;
- Registry _registry;
- vespalib::Lock _lock;
-};
-
-} // namespace searchcorespi
-
diff --git a/searchcorespi/src/vespa/searchcorespi/plugin/iindexmanagerfactory.h b/searchcorespi/src/vespa/searchcorespi/plugin/iindexmanagerfactory.h
deleted file mode 100644
index c2eddc15cde..00000000000
--- a/searchcorespi/src/vespa/searchcorespi/plugin/iindexmanagerfactory.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#pragma once
-
-#include <vespa/searchcorespi/index/iindexmanager.h>
-#include <vespa/searchcorespi/index/indexmaintainerconfig.h>
-#include <vespa/searchcorespi/index/indexmaintainercontext.h>
-#include <vespa/searchcorespi/index/indexmanagerconfig.h>
-#include <vespa/config/configgen/configinstance.h>
-#include <vespa/config/retriever/configsnapshot.h>
-#include <vespa/config/retriever/configkeyset.h>
-
-namespace searchcorespi {
-
-/**
- * Interface for an index manager factory. Every provider of an index manager is supposed to provide a
- * factory for producing them. It is given the basedir, the schema and a collection of configs.
- * The factory implementation must pick the config it needs and return an IIndexManager instance.
- * The factory is registered by using the registerFactory() method.
- */
-class IIndexManagerFactory
-{
-public:
- typedef std::shared_ptr<IIndexManagerFactory> SP;
- typedef std::unique_ptr<IIndexManagerFactory> UP;
-
- virtual ~IIndexManagerFactory() {}
-
- /**
- * This method will be called by a document db when it needs to create an index manager that
- * uses an index maintainer (with source selector) in its implementation.
- * The factory implementation must use RTTI to figure out what configs are what.
- * It should receive all configs it needs, but wise to do sanity checking.
- *
- * @param managerConfig The config that will be used to construct an index manager.
- * Note that if the factory used a different config id when populating the
- * ConfigKeySet compared to the one in this config instance, it must
- * also override the config id when fetching from the config snapshot.
- * The root config received in the @ref getConfigKeys() call will also be
- * part of the config snapshot in this config instance.
- * @param maintainerConfig The config needed to construct an index maintainer.
- * @param maintainerContext The context object used by an index maintainer during its lifetime.
- * @return The index manager created or NULL if not, fx if configs are not as expected.
- */
- virtual IIndexManager::UP createIndexManager(const IndexManagerConfig &managerConfig,
- const index::IndexMaintainerConfig &maintainerConfig,
- const index::IndexMaintainerContext &maintainerContext) = 0;
-
- /**
- * The factory must return the set of config keys that it will require the config from.
- * This will facilitate that the searchcore can fetch all configs needed in a pluggable way.
- *
- * @param configId The config id to use when generating the config keys.
- * @param schema This is the initial index schema to be used.
- * @param rootConfig This is an config instance that is the root config for the factory.
- * Based on this config it must be able to tell if it needs any other config,
- * and in that case provide the config keys.
- * @return The set containing keys for all configs required.
- */
- virtual config::ConfigKeySet getConfigKeys(const vespalib::string &configId,
- const search::index::Schema &schema,
- const config::ConfigInstance &rootConfig) = 0;
-};
-
-} // namespace searchcorespi
-
-extern "C" {
-/**
- * This is a method that each shared library must have in order provide a factory.
- * This will be called by the one loading the library.
- * @return The created factory that the caller will take ownership of.
- */
-searchcorespi::IIndexManagerFactory * createIndexManagerFactory();
-
-}
-
-
diff --git a/searchlib/src/apps/vespa-ranking-expression-analyzer/vespa-ranking-expression-analyzer.cpp b/searchlib/src/apps/vespa-ranking-expression-analyzer/vespa-ranking-expression-analyzer.cpp
index 65b27dd411a..ae4b55948dc 100644
--- a/searchlib/src/apps/vespa-ranking-expression-analyzer/vespa-ranking-expression-analyzer.cpp
+++ b/searchlib/src/apps/vespa-ranking-expression-analyzer/vespa-ranking-expression-analyzer.cpp
@@ -62,8 +62,9 @@ struct InputInfo {
std::vector<double> cmp_with;
double usage_probability;
double expected_usage;
- InputInfo(vespalib::stringref name_in, double usage_probability_in, double expected_usage_in)
- : name(name_in), cmp_with(), usage_probability(usage_probability_in), expected_usage(expected_usage_in) {}
+ InputInfo(vespalib::stringref name_in, double usage_probability_in, double expected_usage_in) noexcept
+ : name(name_in), cmp_with(), usage_probability(usage_probability_in), expected_usage(expected_usage_in)
+ {}
double select_value() const {
return cmp_with.empty() ? 0.5 : cmp_with[(cmp_with.size()-1)/2];
}
diff --git a/searchlib/src/tests/attribute/posting_list_merger/posting_list_merger_test.cpp b/searchlib/src/tests/attribute/posting_list_merger/posting_list_merger_test.cpp
index 99b22e02e2e..5976b02c5cf 100644
--- a/searchlib/src/tests/attribute/posting_list_merger/posting_list_merger_test.cpp
+++ b/searchlib/src/tests/attribute/posting_list_merger/posting_list_merger_test.cpp
@@ -11,17 +11,17 @@ using search::attribute::PostingListMerger;
struct Posting {
uint32_t lid;
int32_t weight;
- Posting(uint32_t lid_, int32_t weight_)
+ Posting(uint32_t lid_, int32_t weight_) noexcept
: lid(lid_),
weight(weight_)
{
}
- bool operator==(const Posting &rhs) const {
+ bool operator==(const Posting &rhs) const noexcept {
return ((lid == rhs.lid) && (weight == rhs.weight));
}
- bool operator<(const Posting &rhs) const { return lid < rhs.lid; }
+ bool operator<(const Posting &rhs) const noexcept { return lid < rhs.lid; }
};
std::ostream &operator<<(std::ostream &os, const Posting &posting)
@@ -35,11 +35,11 @@ class WeightedPostingList
{
std::vector<Posting> _entries;
public:
- WeightedPostingList(std::vector<Posting> entries)
+ WeightedPostingList(std::vector<Posting> entries) noexcept
: _entries(std::move(entries))
{
}
- ~WeightedPostingList() { }
+ ~WeightedPostingList() = default;
template <typename Func>
void foreach(Func func) const {
@@ -67,7 +67,7 @@ struct WeightedFixture
{
}
- ~WeightedFixture() { }
+ ~WeightedFixture() = default;
void reserveArray(uint32_t postingsCount, size_t postingsSize) { _merger.reserveArray(postingsCount, postingsSize); }
diff --git a/searchlib/src/tests/attribute/searchable/attribute_searchable_adapter_test.cpp b/searchlib/src/tests/attribute/searchable/attribute_searchable_adapter_test.cpp
index 87aea2e3e8c..7328fe2c7ff 100644
--- a/searchlib/src/tests/attribute/searchable/attribute_searchable_adapter_test.cpp
+++ b/searchlib/src/tests/attribute/searchable/attribute_searchable_adapter_test.cpp
@@ -140,8 +140,9 @@ struct Result {
uint32_t docid;
double raw_score;
int32_t match_weight;
- Hit(uint32_t id, double raw, int32_t match_weight_in)
- : docid(id), raw_score(raw), match_weight(match_weight_in) {}
+ Hit(uint32_t id, double raw, int32_t match_weight_in) noexcept
+ : docid(id), raw_score(raw), match_weight(match_weight_in)
+ {}
};
size_t est_hits;
bool est_empty;
@@ -590,7 +591,7 @@ TEST("require that attribute weighted set term works") {
TEST("require that predicate query in non-predicate field yields empty.") {
MyAttributeManager attribute_manager = makeAttributeManager("foo");
- PredicateQueryTerm::UP term(new PredicateQueryTerm);
+ auto term = std::make_unique<PredicateQueryTerm>();
SimplePredicateQuery node(std::move(term), field, 0, Weight(1));
Result result = do_search(attribute_manager, node, true);
EXPECT_TRUE(result.est_empty);
@@ -605,7 +606,7 @@ TEST("require that predicate query in predicate field yields results.") {
const_cast<PredicateAttribute::IntervalRange *>(attr->getIntervalRangeVector())[2] = 1u;
MyAttributeManager attribute_manager(attr);
- PredicateQueryTerm::UP term(new PredicateQueryTerm);
+ auto term = std::make_unique<PredicateQueryTerm>();
SimplePredicateQuery node(std::move(term), field, 0, Weight(1));
Result result = do_search(attribute_manager, node, true);
EXPECT_FALSE(result.est_empty);
diff --git a/searchlib/src/tests/docstore/file_chunk/file_chunk_test.cpp b/searchlib/src/tests/docstore/file_chunk/file_chunk_test.cpp
index 70c23dc4191..1e99221551f 100644
--- a/searchlib/src/tests/docstore/file_chunk/file_chunk_test.cpp
+++ b/searchlib/src/tests/docstore/file_chunk/file_chunk_test.cpp
@@ -21,7 +21,7 @@ using common::FileHeaderContext;
using vespalib::ThreadStackExecutor;
struct MyFileHeaderContext : public FileHeaderContext {
- virtual void addTags(vespalib::GenericHeader &header, const vespalib::string &name) const override {
+ void addTags(vespalib::GenericHeader &header, const vespalib::string &name) const override {
(void) header;
(void) name;
}
@@ -29,7 +29,7 @@ struct MyFileHeaderContext : public FileHeaderContext {
struct SetLidObserver : public ISetLid {
std::vector<uint32_t> lids;
- virtual void setLid(const vespalib::LockGuard &guard, uint32_t lid, const LidInfo &lidInfo) override {
+ void setLid(const LockGuard &guard, uint32_t lid, const LidInfo &lidInfo) override {
(void) guard;
(void) lidInfo;
lids.push_back(lid);
@@ -38,12 +38,12 @@ struct SetLidObserver : public ISetLid {
struct BucketizerObserver : public IBucketizer {
mutable std::vector<uint32_t> lids;
- virtual document::BucketId getBucketOf(const vespalib::GenerationHandler::Guard &guard, uint32_t lid) const override {
+ document::BucketId getBucketOf(const vespalib::GenerationHandler::Guard &guard, uint32_t lid) const override {
(void) guard;
lids.push_back(lid);
return document::BucketId();
}
- virtual vespalib::GenerationHandler::Guard getGuard() const override {
+ vespalib::GenerationHandler::Guard getGuard() const override {
return vespalib::GenerationHandler::Guard();
}
};
@@ -62,7 +62,7 @@ struct FixtureBase {
uint64_t serialNum;
TuneFileSummary tuneFile;
MyFileHeaderContext fileHeaderCtx;
- vespalib::Lock updateLock;
+ std::mutex updateLock;
SetLidObserver lidObserver;
BucketizerObserver bucketizer;
@@ -70,8 +70,7 @@ struct FixtureBase {
return serialNum++;
};
- FixtureBase(const vespalib::string &baseName,
- bool dirCleanup = true)
+ explicit FixtureBase(const vespalib::string &baseName, bool dirCleanup = true)
: dir(baseName),
executor(1, 0x10000),
serialNum(1),
@@ -83,20 +82,21 @@ struct FixtureBase {
{
dir.cleanup(dirCleanup);
}
- ~FixtureBase() {}
- void assertLidMap(const std::vector<uint32_t> &expLids) {
+ ~FixtureBase();
+ void assertLidMap(const std::vector<uint32_t> &expLids) const {
EXPECT_EQUAL(expLids, lidObserver.lids);
}
- void assertBucketizer(const std::vector<uint32_t> &expLids) {
+ void assertBucketizer(const std::vector<uint32_t> &expLids) const {
EXPECT_EQUAL(expLids, bucketizer.lids);
}
};
+FixtureBase::~FixtureBase() = default;
+
struct ReadFixture : public FixtureBase {
FileChunk chunk;
- ReadFixture(const vespalib::string &baseName,
- bool dirCleanup = true)
+ explicit ReadFixture(const vespalib::string &baseName, bool dirCleanup = true)
: FixtureBase(baseName, dirCleanup),
chunk(FileChunk::FileId(0),
FileChunk::NameId(1234),
@@ -108,7 +108,7 @@ struct ReadFixture : public FixtureBase {
dir.cleanup(dirCleanup);
}
void updateLidMap(uint32_t docIdLimit) {
- vespalib::LockGuard guard(updateLock);
+ std::unique_lock guard(updateLock);
chunk.updateLidMap(guard, lidObserver, serialNum, docIdLimit);
}
};
@@ -145,7 +145,7 @@ struct WriteFixture : public FixtureBase {
return *this;
}
void updateLidMap(uint32_t docIdLimit) {
- vespalib::LockGuard guard(updateLock);
+ std::unique_lock guard(updateLock);
chunk.updateLidMap(guard, lidObserver, serialNum, docIdLimit);
serialNum = chunk.getSerialNum();
}
diff --git a/searchlib/src/tests/expression/attributenode/attribute_node_test.cpp b/searchlib/src/tests/expression/attributenode/attribute_node_test.cpp
index 5592edcc514..ab45ca0bdbe 100644
--- a/searchlib/src/tests/expression/attributenode/attribute_node_test.cpp
+++ b/searchlib/src/tests/expression/attributenode/attribute_node_test.cpp
@@ -114,7 +114,7 @@ AttributeManagerFixture::buildAttribute(const vespalib::string &name, BasicType
auto attr = std::dynamic_pointer_cast<AttributeType>(attrBase);
EXPECT_TRUE(attr);
attr->addReservedDoc();
- for (const auto &value : values) {
+ for (const std::conditional_t<std::is_same_v<bool, ValueType>, bool, ValueType&> value : values) {
uint32_t docId = 0;
EXPECT_TRUE(attr->addDoc(docId));
EXPECT_NOT_EQUAL(0u, docId);
diff --git a/searchlib/src/tests/memoryindex/field_index_remover/field_index_remover_test.cpp b/searchlib/src/tests/memoryindex/field_index_remover/field_index_remover_test.cpp
index af7ea9be481..584a8121b16 100644
--- a/searchlib/src/tests/memoryindex/field_index_remover/field_index_remover_test.cpp
+++ b/searchlib/src/tests/memoryindex/field_index_remover/field_index_remover_test.cpp
@@ -16,10 +16,10 @@ using namespace search::memoryindex;
struct WordFieldPair {
vespalib::string _word;
uint32_t _fieldId;
- WordFieldPair(vespalib::stringref word, uint32_t fieldId)
+ WordFieldPair(vespalib::stringref word, uint32_t fieldId) noexcept
: _word(word), _fieldId(fieldId)
{}
- bool operator<(const WordFieldPair &rhs) const {
+ bool operator<(const WordFieldPair &rhs) const noexcept {
if (_word != rhs._word) {
return _word < rhs._word;
}
diff --git a/searchlib/src/tests/query/querybuilder_test.cpp b/searchlib/src/tests/query/querybuilder_test.cpp
index 269600d26d4..5a5a5eafb2c 100644
--- a/searchlib/src/tests/query/querybuilder_test.cpp
+++ b/searchlib/src/tests/query/querybuilder_test.cpp
@@ -38,7 +38,7 @@ const uint32_t x_aspect = 0;
const Location location(position, max_distance, x_aspect);
PredicateQueryTerm::UP getPredicateQueryTerm() {
- PredicateQueryTerm::UP pqt(new PredicateQueryTerm);
+ auto pqt = std::make_unique<PredicateQueryTerm>();
pqt->addFeature("key", "value");
pqt->addRangeFeature("key2", 42, 0xfff);
return pqt;
@@ -242,7 +242,7 @@ void checkQueryTreeTypes(Node *node) {
EXPECT_TRUE(checkTerm(string_term, str[5], view[5], id[5], weight[5]));
auto* predicateQuery = as_node<PredicateQuery>(and_node->getChildren()[5]);
- PredicateQueryTerm::UP pqt(new PredicateQueryTerm);
+ auto pqt = std::make_unique<PredicateQueryTerm>();
EXPECT_TRUE(checkTerm(predicateQuery, getPredicateQueryTerm(), view[3], id[3], weight[3]));
auto* dotProduct = as_node<DotProduct>(and_node->getChildren()[6]);
diff --git a/searchlib/src/tests/queryeval/predicate/predicate_blueprint_test.cpp b/searchlib/src/tests/queryeval/predicate/predicate_blueprint_test.cpp
index 28b0d103040..3dd2ec26dea 100644
--- a/searchlib/src/tests/queryeval/predicate/predicate_blueprint_test.cpp
+++ b/searchlib/src/tests/queryeval/predicate/predicate_blueprint_test.cpp
@@ -40,9 +40,9 @@ struct Fixture {
Fixture()
: field(42, 0),
- attribute(new PredicateAttribute("f", attribute::Config(attribute::BasicType::PREDICATE))),
- query(PredicateQueryTerm::UP(new PredicateQueryTerm),
- "view", 0, Weight(1)) {
+ attribute(std::make_shared<PredicateAttribute>("f", attribute::Config(attribute::BasicType::PREDICATE))),
+ query(std::make_unique<PredicateQueryTerm>(),"view", 0, Weight(1))
+ {
query.getTerm()->addFeature("key", "value");
query.getTerm()->addRangeFeature("range_key", 42);
}
@@ -219,7 +219,7 @@ TEST_F("require that blueprint can set up search with subqueries", Fixture) {
std::vector<Interval>{{0x0002ffff}};
f.indexDocument(doc_id, annotations);
- SimplePredicateQuery query(PredicateQueryTerm::UP(new PredicateQueryTerm),
+ SimplePredicateQuery query(std::make_unique<PredicateQueryTerm>(),
"view", 0, Weight(1));
query.getTerm()->addFeature("key", "value", 1);
query.getTerm()->addFeature("key2", "value", 2);
diff --git a/searchlib/src/tests/transactionlog/chunks_test.cpp b/searchlib/src/tests/transactionlog/chunks_test.cpp
index 4a74dd7f5bc..a3cf9f8bd92 100644
--- a/searchlib/src/tests/transactionlog/chunks_test.cpp
+++ b/searchlib/src/tests/transactionlog/chunks_test.cpp
@@ -79,7 +79,7 @@ TEST("test empty commitchunk") {
struct Counter : public search::IDestructorCallback {
std::atomic<uint32_t> & _counter;
- Counter(std::atomic<uint32_t> & counter) : _counter(counter) { _counter++; }
+ Counter(std::atomic<uint32_t> & counter) noexcept : _counter(counter) { _counter++; }
~Counter() override { _counter--; }
};
diff --git a/searchlib/src/tests/transactionlog/translogclient_test.cpp b/searchlib/src/tests/transactionlog/translogclient_test.cpp
index fffb70467a3..e097eebd42c 100644
--- a/searchlib/src/tests/transactionlog/translogclient_test.cpp
+++ b/searchlib/src/tests/transactionlog/translogclient_test.cpp
@@ -311,7 +311,7 @@ using Counter = std::atomic<size_t>;
class CountDone : public IDestructorCallback {
public:
- explicit CountDone(Counter & inFlight) : _inFlight(inFlight) { ++_inFlight; }
+ explicit CountDone(Counter & inFlight) noexcept : _inFlight(inFlight) { ++_inFlight; }
~CountDone() override { --_inFlight; }
private:
Counter & _inFlight;
diff --git a/searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.h b/searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.h
index a889120f8df..1cd07cf4e23 100644
--- a/searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.h
+++ b/searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.h
@@ -8,11 +8,8 @@
#include <memory>
#include <mutex>
-namespace search {
-
-class BitVector;
-
-namespace attribute {
+namespace search { class BitVector; }
+namespace search::attribute {
/**
* Class that caches posting lists (as bit vectors) for a set of search terms.
@@ -31,7 +28,7 @@ public:
ReadGuardUP dmsReadGuard;
BitVectorSP bitVector;
uint32_t docIdLimit;
- Entry(ReadGuardUP dmsReadGuard_, BitVectorSP bitVector_, uint32_t docIdLimit_)
+ Entry(ReadGuardUP dmsReadGuard_, BitVectorSP bitVector_, uint32_t docIdLimit_) noexcept
: dmsReadGuard(std::move(dmsReadGuard_)), bitVector(std::move(bitVector_)), docIdLimit(docIdLimit_) {}
};
@@ -52,4 +49,3 @@ public:
};
}
-}
diff --git a/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp b/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp
index bc0d965bcc1..9c40de26db6 100644
--- a/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/imported_search_context.cpp
@@ -93,7 +93,7 @@ struct WeightedRef {
EntryRef revMapIdx;
int32_t weight;
- WeightedRef(EntryRef revMapIdx_, int32_t weight_)
+ WeightedRef(EntryRef revMapIdx_, int32_t weight_) noexcept
: revMapIdx(revMapIdx_),
weight(weight_)
{
@@ -118,11 +118,11 @@ class ReverseMappingBitVector
const ReverseMapping &_reverseMapping;
EntryRef _revMapIdx;
public:
- ReverseMappingBitVector(const ReverseMapping &reverseMapping, EntryRef revMapIdx)
+ ReverseMappingBitVector(const ReverseMapping &reverseMapping, EntryRef revMapIdx) noexcept
: _reverseMapping(reverseMapping),
_revMapIdx(revMapIdx)
{}
- ~ReverseMappingBitVector() { }
+ ~ReverseMappingBitVector() = default;
template <typename Func>
void foreach_key(Func func) const {
diff --git a/searchlib/src/vespa/searchlib/attribute/interlock.h b/searchlib/src/vespa/searchlib/attribute/interlock.h
index cf9298686c3..30efeaf32fd 100644
--- a/searchlib/src/vespa/searchlib/attribute/interlock.h
+++ b/searchlib/src/vespa/searchlib/attribute/interlock.h
@@ -4,11 +4,7 @@
#include <mutex>
-namespace search
-{
-
-namespace attribute
-{
+namespace search::attribute {
class InterlockGuard;
@@ -35,7 +31,7 @@ class Interlock {
std::mutex _mutex;
friend class InterlockGuard;
public:
- Interlock()
+ Interlock() noexcept
: _mutex()
{
}
@@ -60,6 +56,4 @@ public:
};
-}
-
-}
+} \ No newline at end of file
diff --git a/searchlib/src/vespa/searchlib/attribute/multivalue.h b/searchlib/src/vespa/searchlib/attribute/multivalue.h
index c59f975e00a..54c10bdc7cf 100644
--- a/searchlib/src/vespa/searchlib/attribute/multivalue.h
+++ b/searchlib/src/vespa/searchlib/attribute/multivalue.h
@@ -10,12 +10,9 @@ template <typename T>
class Value {
public:
typedef T ValueType;
- Value()
- : _v()
- {
- }
- Value(T v) : _v(v) { }
- Value(T v, int32_t w) : _v(v) { (void) w; }
+ Value() noexcept : _v() {}
+ Value(T v) noexcept : _v(v) { }
+ Value(T v, int32_t w) noexcept : _v(v) { (void) w; }
T value() const { return _v; }
operator T () const { return _v; }
operator T & () { return _v; }
@@ -36,8 +33,8 @@ template <typename T>
class WeightedValue {
public:
typedef T ValueType;
- WeightedValue() : _v(), _w(1) { }
- WeightedValue(T v, int32_t w) : _v(v), _w(w) { }
+ WeightedValue() noexcept : _v(), _w(1) { }
+ WeightedValue(T v, int32_t w) noexcept : _v(v), _w(w) { }
T value() const { return _v; }
operator T () const { return _v; }
operator T & () { return _v; }
diff --git a/searchlib/src/vespa/searchlib/bitcompression/posocc_field_params.cpp b/searchlib/src/vespa/searchlib/bitcompression/posocc_field_params.cpp
index b789bf16947..751c1db50b2 100644
--- a/searchlib/src/vespa/searchlib/bitcompression/posocc_field_params.cpp
+++ b/searchlib/src/vespa/searchlib/bitcompression/posocc_field_params.cpp
@@ -5,6 +5,7 @@
#include <vespa/searchlib/index/postinglistparams.h>
#include <vespa/vespalib/data/fileheader.h>
#include <vespa/vespalib/stllike/asciistream.h>
+#include <cassert>
#include <vespa/log/log.h>
LOG_SETUP(".posocc_field_params");
diff --git a/searchlib/src/vespa/searchlib/common/gatecallback.h b/searchlib/src/vespa/searchlib/common/gatecallback.h
index 1e85d796089..b6e7690f820 100644
--- a/searchlib/src/vespa/searchlib/common/gatecallback.h
+++ b/searchlib/src/vespa/searchlib/common/gatecallback.h
@@ -9,7 +9,7 @@ namespace search {
class GateCallback : public IDestructorCallback {
public:
- GateCallback(vespalib::Gate & gate) : _gate(gate) {}
+ GateCallback(vespalib::Gate & gate) noexcept : _gate(gate) {}
~GateCallback() override;
private:
vespalib::Gate & _gate;
@@ -17,7 +17,7 @@ private:
class IgnoreCallback : public IDestructorCallback {
public:
- IgnoreCallback() { }
+ IgnoreCallback() noexcept { }
~IgnoreCallback() override = default;
};
diff --git a/searchlib/src/vespa/searchlib/common/lid_usage_stats.h b/searchlib/src/vespa/searchlib/common/lid_usage_stats.h
index 1dd3881892f..97e16ffe768 100644
--- a/searchlib/src/vespa/searchlib/common/lid_usage_stats.h
+++ b/searchlib/src/vespa/searchlib/common/lid_usage_stats.h
@@ -20,7 +20,7 @@ private:
uint32_t _highestUsedLid;
public:
- LidUsageStats()
+ LidUsageStats() noexcept
: _lidLimit(0),
_usedLids(0),
_lowestFreeLid(0),
@@ -30,7 +30,7 @@ public:
LidUsageStats(uint32_t lidLimit,
uint32_t usedLids,
uint32_t lowestFreeLid,
- uint32_t highestUsedLid)
+ uint32_t highestUsedLid) noexcept
: _lidLimit(lidLimit),
_usedLids(usedLids),
_lowestFreeLid(lowestFreeLid),
diff --git a/searchlib/src/vespa/searchlib/common/rankedhit.h b/searchlib/src/vespa/searchlib/common/rankedhit.h
index 635f6e350a5..8a0efb4ce3c 100644
--- a/searchlib/src/vespa/searchlib/common/rankedhit.h
+++ b/searchlib/src/vespa/searchlib/common/rankedhit.h
@@ -9,8 +9,8 @@
namespace search {
struct RankedHit {
- RankedHit() : _docId(0), _rankValue(zero_rank_value) { }
- RankedHit(unsigned int docId, HitRank rank = zero_rank_value) : _docId(docId), _rankValue(rank) { }
+ RankedHit() noexcept : _docId(0), _rankValue(zero_rank_value) { }
+ RankedHit(unsigned int docId, HitRank rank = zero_rank_value) noexcept : _docId(docId), _rankValue(rank) { }
unsigned int getDocId() const { return _docId & 0x7fffffff; }
bool hasMore() const { return _docId & 0x80000000; }
HitRank getRank() const { return _rankValue; }
@@ -21,13 +21,13 @@ struct RankedHit {
class RankedHitIterator {
public:
- RankedHitIterator(const RankedHit * h, size_t sz) : _h(h), _sz(sz), _pos(0) { }
- bool hasNext() const { return _pos < _sz; }
- uint32_t next() { return _h[_pos++].getDocId(); }
+ RankedHitIterator(const RankedHit * h, size_t sz) noexcept : _h(h), _sz(sz), _pos(0) { }
+ bool hasNext() const noexcept { return _pos < _sz; }
+ uint32_t next() noexcept { return _h[_pos++].getDocId(); }
private:
const RankedHit *_h;
- const size_t _sz;
- size_t _pos;
+ const size_t _sz;
+ size_t _pos;
};
} // namespace search
diff --git a/searchlib/src/vespa/searchlib/common/scheduletaskcallback.h b/searchlib/src/vespa/searchlib/common/scheduletaskcallback.h
index 27bbe751532..00f0d4b29f5 100644
--- a/searchlib/src/vespa/searchlib/common/scheduletaskcallback.h
+++ b/searchlib/src/vespa/searchlib/common/scheduletaskcallback.h
@@ -4,8 +4,7 @@
#include "idestructorcallback.h"
#include <vespa/vespalib/util/executor.h>
-namespace search
-{
+namespace search {
/**
* Class that schedules a task when instance is destroyed. Typically a
@@ -20,12 +19,11 @@ class ScheduleTaskCallback : public IDestructorCallback
vespalib::Executor::Task::UP _task;
public:
ScheduleTaskCallback(vespalib::Executor &executor,
- vespalib::Executor::Task::UP task)
+ vespalib::Executor::Task::UP task) noexcept
: _executor(executor),
_task(std::move(task))
- {
- }
- virtual ~ScheduleTaskCallback() {
+ {}
+ ~ScheduleTaskCallback() override {
_executor.execute(std::move(_task));
}
};
diff --git a/searchlib/src/vespa/searchlib/common/tunefileinfo.h b/searchlib/src/vespa/searchlib/common/tunefileinfo.h
index bcd6765845b..e27290d35de 100644
--- a/searchlib/src/vespa/searchlib/common/tunefileinfo.h
+++ b/searchlib/src/vespa/searchlib/common/tunefileinfo.h
@@ -19,7 +19,7 @@ private:
TuneControl _tuneControl;
public:
- TuneFileSeqRead() : _tuneControl(NORMAL) { }
+ TuneFileSeqRead() noexcept : _tuneControl(NORMAL) { }
void setWantDirectIO() { _tuneControl = DIRECTIO; }
bool getWantDirectIO() const { return _tuneControl == DIRECTIO; }
@@ -62,7 +62,7 @@ private:
TuneControl _tuneControl;
public:
- TuneFileSeqWrite() : _tuneControl(NORMAL) { }
+ TuneFileSeqWrite() noexcept : _tuneControl(NORMAL) { }
void setWantDirectIO() { _tuneControl = DIRECTIO; }
bool getWantDirectIO() const { return _tuneControl == DIRECTIO; }
bool getWantSyncWrites() const { return _tuneControl == OSYNC; }
@@ -99,7 +99,7 @@ private:
int _mmapFlags;
int _advise;
public:
- TuneFileRandRead()
+ TuneFileRandRead() noexcept
: _tuneControl(NORMAL),
_mmapFlags(0),
_advise(0)
@@ -139,9 +139,9 @@ public:
TuneFileSeqRead _read;
TuneFileSeqWrite _write;
- TuneFileIndexing() : _read(), _write() {}
+ TuneFileIndexing() noexcept : _read(), _write() {}
- TuneFileIndexing(const TuneFileSeqRead &r, const TuneFileSeqWrite &w) : _read(r), _write(w) { }
+ TuneFileIndexing(const TuneFileSeqRead &r, const TuneFileSeqWrite &w) noexcept : _read(r), _write(w) { }
bool operator==(const TuneFileIndexing &rhs) const {
return _read == rhs._read && _write == rhs._write;
@@ -161,8 +161,8 @@ class TuneFileSearch
public:
TuneFileRandRead _read;
- TuneFileSearch() : _read() { }
- TuneFileSearch(const TuneFileRandRead &r) : _read(r) { }
+ TuneFileSearch() noexcept : _read() { }
+ TuneFileSearch(const TuneFileRandRead &r) noexcept : _read(r) { }
bool operator==(const TuneFileSearch &rhs) const { return _read == rhs._read; }
bool operator!=(const TuneFileSearch &rhs) const { return _read != rhs._read; }
};
@@ -178,7 +178,7 @@ public:
TuneFileIndexing _indexing;
TuneFileSearch _search;
- TuneFileIndexManager() : _indexing(), _search() { }
+ TuneFileIndexManager() noexcept : _indexing(), _search() { }
bool operator==(const TuneFileIndexManager &rhs) const {
return _indexing == rhs._indexing && _search == rhs._search;
@@ -198,7 +198,7 @@ class TuneFileAttributes
public:
TuneFileSeqWrite _write;
- TuneFileAttributes() : _write() { }
+ TuneFileAttributes() noexcept : _write() { }
bool operator==(const TuneFileAttributes &rhs) const {
return _write == rhs._write;
@@ -220,7 +220,7 @@ public:
TuneFileSeqWrite _write;
TuneFileRandRead _randRead;
- TuneFileSummary() : _seqRead(), _write(), _randRead() { }
+ TuneFileSummary() noexcept : _seqRead(), _write(), _randRead() { }
bool operator==(const TuneFileSummary &rhs) const {
return _seqRead == rhs._seqRead &&
@@ -248,7 +248,7 @@ public:
TuneFileAttributes _attr;
TuneFileSummary _summary;
- TuneFileDocumentDB() : _index(), _attr(), _summary() { }
+ TuneFileDocumentDB() noexcept : _index(), _attr(), _summary() { }
bool operator==(const TuneFileDocumentDB &rhs) const {
return _index == rhs._index &&
diff --git a/searchlib/src/vespa/searchlib/diskindex/zc4_posting_writer_base.h b/searchlib/src/vespa/searchlib/diskindex/zc4_posting_writer_base.h
index e9b1efa5c7d..4e71a8356c0 100644
--- a/searchlib/src/vespa/searchlib/diskindex/zc4_posting_writer_base.h
+++ b/searchlib/src/vespa/searchlib/diskindex/zc4_posting_writer_base.h
@@ -24,7 +24,7 @@ public:
uint32_t _field_length;
uint32_t _num_occs;
uint32_t _features_size;
- DocIdAndFeatureSize(uint32_t doc_id, uint32_t field_length, uint32_t num_occs, uint32_t features_size)
+ DocIdAndFeatureSize(uint32_t doc_id, uint32_t field_length, uint32_t num_occs, uint32_t features_size) noexcept
: _doc_id(doc_id),
_field_length(field_length),
_num_occs(num_occs),
diff --git a/searchlib/src/vespa/searchlib/docstore/compacter.h b/searchlib/src/vespa/searchlib/docstore/compacter.h
index cf059b6cb04..52691d2c415 100644
--- a/searchlib/src/vespa/searchlib/docstore/compacter.h
+++ b/searchlib/src/vespa/searchlib/docstore/compacter.h
@@ -51,7 +51,7 @@ private:
uint64_t _writeCount;
vespalib::duration _maxBucketGuardDuration;
vespalib::steady_time _lastSample;
- vespalib::Lock _lock;
+ std::mutex _lock;
vespalib::MemoryDataStore _backingMemory;
std::vector<StoreByBucket> _tmpStore;
GenerationHandler::Guard _lidGuard;
diff --git a/searchlib/src/vespa/searchlib/docstore/filechunk.cpp b/searchlib/src/vespa/searchlib/docstore/filechunk.cpp
index b4ef45187ee..d66e178717c 100644
--- a/searchlib/src/vespa/searchlib/docstore/filechunk.cpp
+++ b/searchlib/src/vespa/searchlib/docstore/filechunk.cpp
@@ -320,7 +320,7 @@ appendChunks(FixedParams * args, Chunk::UP chunk)
for (const Chunk::Entry & e : ll) {
LidInfo lidInfo(args->fileId, chunk->getId(), e.netSize());
if (args->db.getLid(args->lidReadGuard, e.getLid()) == lidInfo) {
- vespalib::LockGuard guard(args->db.getLidGuard(e.getLid()));
+ auto guard(args->db.getLidGuard(e.getLid()));
if (args->db.getLid(args->lidReadGuard, e.getLid()) == lidInfo) {
// I am still in use so I need to taken care of.
vespalib::ConstBufferRef data(chunk->getLid(e.getLid()));
diff --git a/searchlib/src/vespa/searchlib/docstore/filechunk.h b/searchlib/src/vespa/searchlib/docstore/filechunk.h
index b68db801d60..3febb51ca69 100644
--- a/searchlib/src/vespa/searchlib/docstore/filechunk.h
+++ b/searchlib/src/vespa/searchlib/docstore/filechunk.h
@@ -9,7 +9,6 @@
#include <vespa/searchlib/common/tunefileinfo.h>
#include <vespa/vespalib/util/memoryusage.h>
#include <vespa/vespalib/util/ptrholder.h>
-#include <vespa/vespalib/util/sync.h>
#include <vespa/vespalib/stllike/hash_map.h>
#include <vespa/vespalib/util/generationhandler.h>
#include <vespa/vespalib/util/time.h>
@@ -30,9 +29,9 @@ class IWriteData
{
public:
typedef std::unique_ptr<IWriteData> UP;
- using LockGuard = vespalib::LockGuard;
+ using LockGuard = std::unique_lock<std::mutex>;
- virtual ~IWriteData() { }
+ virtual ~IWriteData() = default;
virtual void write(LockGuard guard, uint32_t chunkId, uint32_t lid, const void *buffer, size_t sz) = 0;
virtual void close() = 0;
@@ -41,7 +40,7 @@ public:
class IFileChunkVisitorProgress
{
public:
- virtual ~IFileChunkVisitorProgress() { }
+ virtual ~IFileChunkVisitorProgress() = default;
virtual void updateProgress() = 0;
};
@@ -73,10 +72,10 @@ private:
class FileChunk
{
public:
- using LockGuard = vespalib::LockGuard;
+ using LockGuard = std::unique_lock<std::mutex>;
class NameId {
public:
- explicit NameId(size_t id) : _id(id) { }
+ explicit NameId(size_t id) noexcept : _id(id) { }
uint64_t getId() const { return _id; }
vespalib::string createName(const vespalib::string &baseName) const;
bool operator == (const NameId & rhs) const { return _id == rhs._id; }
@@ -90,7 +89,7 @@ public:
};
class FileId {
public:
- explicit FileId(uint32_t id) : _id(id) { }
+ explicit FileId(uint32_t id) noexcept : _id(id) { }
uint32_t getId() const { return _id; }
bool operator != (const FileId & rhs) const { return _id != rhs._id; }
bool operator == (const FileId & rhs) const { return _id == rhs._id; }
diff --git a/searchlib/src/vespa/searchlib/docstore/lid_info.h b/searchlib/src/vespa/searchlib/docstore/lid_info.h
index 10ddd868c41..152246631a7 100644
--- a/searchlib/src/vespa/searchlib/docstore/lid_info.h
+++ b/searchlib/src/vespa/searchlib/docstore/lid_info.h
@@ -3,16 +3,16 @@
#pragma once
#include <vespa/vespalib/util/generationhandler.h>
-#include <vespa/vespalib/util/sync.h>
#include <limits>
#include <vector>
+#include <mutex>
namespace search {
class LidInfo {
public:
- LidInfo() : _value() { }
- LidInfo(uint64_t rep) { _value.r = rep; }
+ LidInfo() noexcept : _value() { }
+ LidInfo(uint64_t rep) noexcept { _value.r = rep; }
LidInfo(uint32_t fileId, uint32_t chunkId, uint32_t size);
uint32_t getFileId() const { return _value.v.fileId; }
uint32_t getChunkId() const { return _value.v.chunkId; }
@@ -57,7 +57,7 @@ private:
class LidInfoWithLid : public LidInfo {
public:
- LidInfoWithLid(LidInfo lidInfo, uint32_t lid) : LidInfo(lidInfo), _lid(lid) { }
+ LidInfoWithLid(LidInfo lidInfo, uint32_t lid) noexcept : LidInfo(lidInfo), _lid(lid) { }
uint32_t getLid() const { return _lid; }
private:
uint32_t _lid;
@@ -68,8 +68,8 @@ typedef std::vector<LidInfoWithLid> LidInfoWithLidV;
class ISetLid
{
public:
- using LockGuard = vespalib::LockGuard;
- virtual ~ISetLid() { }
+ using LockGuard = std::unique_lock<std::mutex>;
+ virtual ~ISetLid() = default;
virtual void setLid(const LockGuard & guard, uint32_t lid, const LidInfo & lm) = 0;
};
@@ -77,10 +77,11 @@ class IGetLid
{
public:
using Guard = vespalib::GenerationHandler::Guard;
- virtual ~IGetLid() { }
+ using LockGuard = std::unique_lock<std::mutex>;
+ virtual ~IGetLid() = default;
virtual LidInfo getLid(const Guard & guard, uint32_t lid) const = 0;
- virtual vespalib::LockGuard getLidGuard(uint32_t lid) const = 0;
+ virtual LockGuard getLidGuard(uint32_t lid) const = 0;
virtual Guard getLidReadGuard() const = 0;
};
diff --git a/searchlib/src/vespa/searchlib/docstore/logdatastore.cpp b/searchlib/src/vespa/searchlib/docstore/logdatastore.cpp
index 4adb3507eeb..37510afc572 100644
--- a/searchlib/src/vespa/searchlib/docstore/logdatastore.cpp
+++ b/searchlib/src/vespa/searchlib/docstore/logdatastore.cpp
@@ -464,8 +464,7 @@ bool LogDataStore::shouldCompactToActiveFile(size_t compactedSize) const {
void LogDataStore::setNewFileChunk(const LockGuard & guard, FileChunk::UP file)
{
- (void) guard;
- assert(guard.locks(_updateLock));
+ assert(hasUpdateLock(guard));
size_t fileId = file->getFileId().getId();
assert( ! _fileChunks[fileId]);
_fileChunks[fileId] = std::move(file);
@@ -854,7 +853,7 @@ LogDataStore::findIncompleteCompactedFiles(const NameIdSet & partList) {
LogDataStore::NameIdSet
LogDataStore::getAllActiveFiles() const {
NameIdSet files;
- vespalib::LockGuard guard(_updateLock);
+ LockGuard guard(_updateLock);
for (const auto & fc : _fileChunks) {
if (fc) {
files.insert(fc->getNameId());
@@ -1219,7 +1218,7 @@ LogDataStore::canShrinkLidSpace() const
}
bool
-LogDataStore::canShrinkLidSpace(const vespalib::LockGuard &) const
+LogDataStore::canShrinkLidSpace(const LockGuard &) const
{
return getDocIdLimit() < _lidInfo.size() &&
_compactLidSpaceGeneration < _genHandler.getFirstUsedGeneration();
diff --git a/searchlib/src/vespa/searchlib/docstore/logdatastore.h b/searchlib/src/vespa/searchlib/docstore/logdatastore.h
index c709c607f37..12073c49cde 100644
--- a/searchlib/src/vespa/searchlib/docstore/logdatastore.h
+++ b/searchlib/src/vespa/searchlib/docstore/logdatastore.h
@@ -33,7 +33,7 @@ private:
using FileId = FileChunk::FileId;
public:
using NameIdSet = std::set<NameId>;
- using LockGuard = vespalib::LockGuard;
+ using LockGuard = std::unique_lock<std::mutex>;
using CompressionConfig = vespalib::compression::CompressionConfig;
class Config {
public:
@@ -146,9 +146,9 @@ public:
}
// Implements IGetLid API
- LockGuard getLidGuard(uint32_t lid) const override {
+ IGetLid::LockGuard getLidGuard(uint32_t lid) const override {
(void) lid;
- return LockGuard(_updateLock);
+ return IGetLid::LockGuard(_updateLock);
}
// Implements IGetLid API
@@ -160,11 +160,14 @@ public:
return LidInfo();
}
}
- FileId getActiveFileId(const vespalib::LockGuard & guard) const {
- assert(guard.locks(_updateLock));
+ FileId getActiveFileId(const LockGuard & guard) const {
+ assert(hasUpdateLock(guard));
(void) guard;
return _active;
}
+ bool hasUpdateLock(const LockGuard & guard) const {
+ return (guard.mutex() == &_updateLock) && guard.owns_lock();
+ }
DataStoreStorageStats getStorageStats() const override;
vespalib::MemoryUsage getMemoryUsage() const override;
@@ -185,7 +188,7 @@ private:
class FileChunkHolder;
// Implements ISetLid API
- void setLid(const LockGuard & guard, uint32_t lid, const LidInfo & lm) override;
+ void setLid(const ISetLid::LockGuard & guard, uint32_t lid, const LidInfo & lm) override;
void compactWorst(double bloatLimit, double spreadLimit, bool prioritizeDiskBloat);
void compactFile(FileId chunkId);
@@ -211,25 +214,21 @@ private:
vespalib::string ls(const NameIdSet & partList);
WriteableFileChunk & getActive(const LockGuard & guard) {
- assert(guard.locks(_updateLock));
- (void) guard;
+ assert(hasUpdateLock(guard));
return static_cast<WriteableFileChunk &>(*_fileChunks[_active.getId()]);
}
const WriteableFileChunk & getActive(const LockGuard & guard) const {
- assert(guard.locks(_updateLock));
- (void) guard;
+ assert(hasUpdateLock(guard));
return static_cast<const WriteableFileChunk &>(*_fileChunks[_active.getId()]);
}
const FileChunk * getPrevActive(const LockGuard & guard) const {
- assert(guard.locks(_updateLock));
- (void) guard;
+ assert(hasUpdateLock(guard));
return ( !_prevActive.isActive() ) ? _fileChunks[_prevActive.getId()].get() : nullptr;
}
void setActive(const LockGuard & guard, FileId fileId) {
- assert(guard.locks(_updateLock));
- (void) guard;
+ assert(hasUpdateLock(guard));
_prevActive = _active;
_active = fileId;
}
@@ -270,7 +269,7 @@ private:
bool shouldCompactToActiveFile(size_t compactedSize) const;
std::pair<bool, FileId> findNextToCompact(double bloatLimit, double spreadLimit, bool prioritizeDiskBloat);
void incGeneration();
- bool canShrinkLidSpace(const vespalib::LockGuard &guard) const;
+ bool canShrinkLidSpace(const LockGuard &guard) const;
typedef std::vector<FileId> FileIdxVector;
Config _config;
@@ -282,7 +281,7 @@ private:
std::vector<uint32_t> _holdFileChunks;
FileId _active;
FileId _prevActive;
- vespalib::Lock _updateLock;
+ mutable std::mutex _updateLock;
bool _readOnly;
vespalib::ThreadExecutor &_executor;
SerialNum _initFlushSyncToken;
diff --git a/searchlib/src/vespa/searchlib/docstore/randreaders.cpp b/searchlib/src/vespa/searchlib/docstore/randreaders.cpp
index 2eb419cf8eb..cb670f513f7 100644
--- a/searchlib/src/vespa/searchlib/docstore/randreaders.cpp
+++ b/searchlib/src/vespa/searchlib/docstore/randreaders.cpp
@@ -107,7 +107,7 @@ MMapRandReadDynamic::MMapRandReadDynamic(const vespalib::string &fileName, int m
void
MMapRandReadDynamic::remap(size_t sz)
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
if ((sz > 0) && _holder.hasValue() && contains(*_holder.get(), sz)) {
return;
}
diff --git a/searchlib/src/vespa/searchlib/docstore/randreaders.h b/searchlib/src/vespa/searchlib/docstore/randreaders.h
index 4503c3600d4..00dc371bddf 100644
--- a/searchlib/src/vespa/searchlib/docstore/randreaders.h
+++ b/searchlib/src/vespa/searchlib/docstore/randreaders.h
@@ -47,7 +47,7 @@ private:
vespalib::PtrHolder<FastOS_FileInterface> _holder;
int _mmapFlags;
int _fadviseOptions;
- vespalib::Lock _lock;
+ std::mutex _lock;
};
class NormalRandRead : public FileRandRead
diff --git a/searchlib/src/vespa/searchlib/docstore/storebybucket.cpp b/searchlib/src/vespa/searchlib/docstore/storebybucket.cpp
index 5e595d0bb14..d7711b61d78 100644
--- a/searchlib/src/vespa/searchlib/docstore/storebybucket.cpp
+++ b/searchlib/src/vespa/searchlib/docstore/storebybucket.cpp
@@ -12,7 +12,7 @@ using document::BucketId;
using vespalib::makeTask;
using vespalib::makeClosure;
-StoreByBucket::StoreByBucket(MemoryDataStore & backingMemory, Executor & executor, const CompressionConfig & compression)
+StoreByBucket::StoreByBucket(MemoryDataStore & backingMemory, Executor & executor, const CompressionConfig & compression) noexcept
: _chunkSerial(0),
_current(),
_where(),
diff --git a/searchlib/src/vespa/searchlib/docstore/storebybucket.h b/searchlib/src/vespa/searchlib/docstore/storebybucket.h
index 8be0610b588..1365dcb4416 100644
--- a/searchlib/src/vespa/searchlib/docstore/storebybucket.h
+++ b/searchlib/src/vespa/searchlib/docstore/storebybucket.h
@@ -24,9 +24,12 @@ class StoreByBucket
using ConstBufferRef = vespalib::ConstBufferRef;
using CompressionConfig = vespalib::compression::CompressionConfig;
public:
- StoreByBucket(vespalib::MemoryDataStore & backingMemory, const CompressionConfig & compression);
- StoreByBucket(MemoryDataStore & backingMemory, Executor & executor, const CompressionConfig & compression);
- StoreByBucket(StoreByBucket &&) = default;
+ StoreByBucket(MemoryDataStore & backingMemory, Executor & executor, const CompressionConfig & compression) noexcept;
+ //TODO Putting the below move constructor into cpp file fails for some unknown reason. Needs to be resolved.
+ StoreByBucket(StoreByBucket &&) noexcept = default;
+ StoreByBucket(const StoreByBucket &) = delete;
+ StoreByBucket & operator=(StoreByBucket &&) noexcept = delete;
+ StoreByBucket & operator = (const StoreByBucket &) = delete;
~StoreByBucket();
class IWrite {
public:
@@ -52,10 +55,10 @@ private:
void closeChunk(Chunk::UP chunk);
struct Index {
using BucketId=document::BucketId;
- Index(BucketId bucketId, uint32_t id, uint32_t chunkId, uint32_t entry) :
+ Index(BucketId bucketId, uint32_t id, uint32_t chunkId, uint32_t entry) noexcept :
_bucketId(bucketId), _id(id), _chunkId(chunkId), _lid(entry)
{ }
- bool operator < (const Index & b) const {
+ bool operator < (const Index & b) const noexcept {
return BucketId::bucketIdToKey(_bucketId.getRawId()) < BucketId::bucketIdToKey(b._bucketId.getRawId());
}
BucketId _bucketId;
diff --git a/searchlib/src/vespa/searchlib/docstore/visitcache.cpp b/searchlib/src/vespa/searchlib/docstore/visitcache.cpp
index 6990a0a3ed7..1671b6cae69 100644
--- a/searchlib/src/vespa/searchlib/docstore/visitcache.cpp
+++ b/searchlib/src/vespa/searchlib/docstore/visitcache.cpp
@@ -11,7 +11,6 @@
namespace search::docstore {
using vespalib::ConstBufferRef;
-using vespalib::LockGuard;
using vespalib::DataBuffer;
using vespalib::alloc::Alloc;
using vespalib::alloc::MemoryAllocator;
@@ -167,7 +166,7 @@ VisitCache::reconfigure(size_t cacheSize, const CompressionConfig &compression)
VisitCache::Cache::IdSet
-VisitCache::Cache::findSetsContaining(const LockGuard &, const KeySet & keys) const {
+VisitCache::Cache::findSetsContaining(const UniqueLock &, const KeySet & keys) const {
IdSet found;
for (uint32_t subKey : keys.getKeys()) {
const auto foundLid = _lid2Id.find(subKey);
@@ -194,7 +193,7 @@ VisitCache::Cache::readSet(const KeySet & key)
}
void
-VisitCache::Cache::locateAndInvalidateOtherSubsets(const LockGuard & cacheGuard, const KeySet & keys)
+VisitCache::Cache::locateAndInvalidateOtherSubsets(const UniqueLock & cacheGuard, const KeySet & keys)
{
// Due to the implementation of insert where the global lock is released and the fact
// that 2 overlapping keysets kan have different keys and use different ValueLock
diff --git a/searchlib/src/vespa/searchlib/docstore/visitcache.h b/searchlib/src/vespa/searchlib/docstore/visitcache.h
index 8a06794ee35..430481acd4c 100644
--- a/searchlib/src/vespa/searchlib/docstore/visitcache.h
+++ b/searchlib/src/vespa/searchlib/docstore/visitcache.h
@@ -23,7 +23,7 @@ public:
KeySet() : _keys() { }
KeySet(uint32_t key);
explicit KeySet(const IDocumentStore::LidVector &keys);
- uint32_t hash() const { return _keys.empty() ? 0 : _keys[0]; }
+ uint32_t hash() const noexcept { return _keys.empty() ? 0 : _keys[0]; }
bool operator==(const KeySet &rhs) const { return _keys == rhs._keys; }
bool operator<(const KeySet &rhs) const { return _keys < rhs._keys; }
bool contains(const KeySet &rhs) const;
@@ -40,7 +40,7 @@ class BlobSet {
public:
class LidPosition {
public:
- LidPosition(uint32_t lid, uint32_t offset, uint32_t size) : _lid(lid), _offset(offset), _size(size) { }
+ LidPosition(uint32_t lid, uint32_t offset, uint32_t size) noexcept : _lid(lid), _offset(offset), _size(size) { }
uint32_t lid() const { return _lid; }
uint32_t offset() const { return _offset; }
uint32_t size() const { return _size; }
@@ -150,12 +150,12 @@ private:
CompressedBlobSet readSet(const KeySet & keys);
void removeKey(uint32_t key);
private:
- void locateAndInvalidateOtherSubsets(const vespalib::LockGuard & cacheGuard, const KeySet & keys);
+ void locateAndInvalidateOtherSubsets(const UniqueLock & cacheGuard, const KeySet & keys);
using IdSet = vespalib::hash_set<uint64_t>;
using Parent = vespalib::cache<CacheParams>;
using LidUniqueKeySetId = vespalib::hash_map<uint32_t, uint64_t>;
using IdKeySetMap = vespalib::hash_map<uint64_t, KeySet>;
- IdSet findSetsContaining(const vespalib::LockGuard &, const KeySet & keys) const;
+ IdSet findSetsContaining(const UniqueLock &, const KeySet & keys) const;
void onInsert(const K & key) override;
void onRemove(const K & key) override;
LidUniqueKeySetId _lid2Id;
diff --git a/searchlib/src/vespa/searchlib/docstore/writeablefilechunk.cpp b/searchlib/src/vespa/searchlib/docstore/writeablefilechunk.cpp
index 3517595d00a..cdf6220dfbc 100644
--- a/searchlib/src/vespa/searchlib/docstore/writeablefilechunk.cpp
+++ b/searchlib/src/vespa/searchlib/docstore/writeablefilechunk.cpp
@@ -204,7 +204,7 @@ seek_past(LidInfoWithLidV::const_iterator begin, LidInfoWithLidV::const_iterator
}
struct LidAndBuffer {
- LidAndBuffer(uint32_t lid, uint32_t sz, vespalib::alloc::Alloc buf) : _lid(lid), _size(sz), _buf(std::move(buf)) {}
+ LidAndBuffer(uint32_t lid, uint32_t sz, vespalib::alloc::Alloc buf) noexcept : _lid(lid), _size(sz), _buf(std::move(buf)) {}
uint32_t _lid;
uint32_t _size;
vespalib::alloc::Alloc _buf;
@@ -220,7 +220,7 @@ WriteableFileChunk::read(LidInfoWithLidV::const_iterator begin, size_t count, IB
vespalib::hash_map<uint32_t, ChunkInfo> chunksOnFile;
std::vector<LidAndBuffer> buffers;
{
- LockGuard guard(_lock);
+ vespalib::LockGuard guard(_lock);
for (size_t i(0); i < count; i++) {
const LidInfoWithLid & li = *(begin + i);
uint32_t chunk = li.getChunkId();
@@ -260,7 +260,7 @@ WriteableFileChunk::read(uint32_t lid, SubChunkId chunkId, vespalib::DataBuffer
{
ChunkInfo chunkInfo;
if (!frozen()) {
- LockGuard guard(_lock);
+ vespalib::LockGuard guard(_lock);
if ((chunkId >= _chunkInfo.size()) || !_chunkInfo[chunkId].valid()) {
auto found = _chunkMap.find(chunkId);
if (found != _chunkMap.end()) {
@@ -282,7 +282,7 @@ WriteableFileChunk::internalFlush(uint32_t chunkId, uint64_t serialNum)
{
Chunk * active(nullptr);
{
- LockGuard guard(_lock);
+ vespalib::LockGuard guard(_lock);
active = _chunkMap[chunkId].get();
}
@@ -298,7 +298,7 @@ WriteableFileChunk::internalFlush(uint32_t chunkId, uint64_t serialNum)
tmp->getBuf().moveFreeToData(padAfter);
}
{
- LockGuard innerGuard(_lock);
+ vespalib::LockGuard innerGuard(_lock);
setDiskFootprint(FileChunk::getDiskFootprint() + tmp->getBuf().getDataLen());
}
enque(std::move(tmp));
@@ -396,11 +396,11 @@ WriteableFileChunk::fetchNextChain(ProcessedChunkMap & orderedChunks, const uint
}
ChunkMeta
-WriteableFileChunk::computeChunkMeta(const LockGuard & guard,
+WriteableFileChunk::computeChunkMeta(const vespalib::LockGuard & guard,
const GenerationHandler::Guard & bucketizerGuard,
size_t offset, const ProcessedChunk & tmp, const Chunk & active)
{
- (void) guard;
+ assert(guard.locks(_lock));
size_t dataLen = tmp.getBuf().getDataLen();
const ChunkMeta cmeta(offset, tmp.getPayLoad(), active.getLastSerial(), active.count());
assert((size_t(tmp.getBuf().getData())%_alignment) == 0);
@@ -432,7 +432,7 @@ WriteableFileChunk::computeChunkMeta(ProcessedChunkQ & chunks, size_t startPos,
cmetaV.reserve(chunks.size());
uint64_t lastSerial(_lastPersistedSerialNum);
(void) lastSerial;
- LockGuard guard(_lock);
+ vespalib::LockGuard guard(_lock);
if (!_pendingChunks.empty()) {
const PendingChunk & pc = *_pendingChunks.back();
@@ -541,7 +541,7 @@ WriteableFileChunk::fileWriter(const uint32_t firstChunkId)
vespalib::system_time
WriteableFileChunk::getModificationTime() const
{
- LockGuard guard(_lock);
+ vespalib::LockGuard guard(_lock);
return _modificationTime;
}
@@ -595,7 +595,7 @@ size_t
WriteableFileChunk::getMemoryFootprint() const
{
size_t sz(0);
- LockGuard guard(_lock);
+ vespalib::LockGuard guard(_lock);
for (const auto & it : _chunkMap) {
sz += it.second->size();
}
@@ -613,7 +613,7 @@ WriteableFileChunk::getMemoryMetaFootprint() const
vespalib::MemoryUsage
WriteableFileChunk::getMemoryUsage() const
{
- LockGuard guard(_lock);
+ vespalib::LockGuard guard(_lock);
vespalib::MemoryUsage result;
for (const auto &chunk : _chunkMap) {
result.merge(chunk.second->getMemoryUsage());
@@ -843,7 +843,7 @@ WriteableFileChunk::updateCurrentDiskFootprint() {
*/
void
WriteableFileChunk::flushPendingChunks(uint64_t serialNum) {
- LockGuard flushGuard(_flushLock);
+ std::unique_lock flushGuard(_flushLock);
if (frozen())
return;
uint64_t datFileLen = _dataFile.getSize();
@@ -851,15 +851,14 @@ WriteableFileChunk::flushPendingChunks(uint64_t serialNum) {
if (needFlushPendingChunks(serialNum, datFileLen)) {
timeStamp = unconditionallyFlushPendingChunks(flushGuard, serialNum, datFileLen);
}
- LockGuard guard(_lock);
+ vespalib::LockGuard guard(_lock);
_modificationTime = std::max(timeStamp, _modificationTime);
}
vespalib::system_time
-WriteableFileChunk::unconditionallyFlushPendingChunks(const vespalib::LockGuard &flushGuard, uint64_t serialNum, uint64_t datFileLen)
+WriteableFileChunk::unconditionallyFlushPendingChunks(const LockGuard &flushGuard, uint64_t serialNum, uint64_t datFileLen)
{
- (void) flushGuard;
- assert(flushGuard.locks(_flushLock));
+ assert((flushGuard.mutex() == &_flushLock) && flushGuard.owns_lock());
if ( ! _dataFile.Sync()) {
throw SummaryException("Failed fsync of dat file", _dataFile, VESPA_STRLOC);
}
diff --git a/searchlib/src/vespa/searchlib/docstore/writeablefilechunk.h b/searchlib/src/vespa/searchlib/docstore/writeablefilechunk.h
index 65dd822ac1f..cdbbd51ec77 100644
--- a/searchlib/src/vespa/searchlib/docstore/writeablefilechunk.h
+++ b/searchlib/src/vespa/searchlib/docstore/writeablefilechunk.h
@@ -4,6 +4,7 @@
#include "filechunk.h"
#include <vespa/vespalib/util/executor.h>
+#include <vespa/vespalib/util/sync.h>
#include <vespa/searchlib/transactionlog/syncproxy.h>
#include <vespa/fastos/file.h>
#include <map>
@@ -90,7 +91,7 @@ private:
void writeDataHeader(const common::FileHeaderContext &fileHeaderContext);
bool needFlushPendingChunks(uint64_t serialNum, uint64_t datFileLen);
bool needFlushPendingChunks(const vespalib::MonitorGuard & guard, uint64_t serialNum, uint64_t datFileLen);
- vespalib::system_time unconditionallyFlushPendingChunks(const vespalib::LockGuard & flushGuard, uint64_t serialNum, uint64_t datFileLen);
+ vespalib::system_time unconditionallyFlushPendingChunks(const LockGuard & flushGuard, uint64_t serialNum, uint64_t datFileLen);
static void insertChunks(ProcessedChunkMap & orderedChunks, ProcessedChunkQ & newChunks, const uint32_t nextChunkId);
static ProcessedChunkQ fetchNextChain(ProcessedChunkMap & orderedChunks, const uint32_t firstChunkId);
ChunkMeta computeChunkMeta(const vespalib::LockGuard & guard,
@@ -108,8 +109,8 @@ private:
bool _frozen;
// Lock order is _writeLock, _flushLock, _lock
vespalib::Monitor _lock;
- vespalib::Lock _writeLock;
- vespalib::Lock _flushLock;
+ std::mutex _writeLock;
+ std::mutex _flushLock;
FastOS_File _dataFile;
using ChunkMap = std::map<uint32_t, Chunk::UP>;
ChunkMap _chunkMap;
diff --git a/searchlib/src/vespa/searchlib/engine/docsumreply.h b/searchlib/src/vespa/searchlib/engine/docsumreply.h
index 37431030253..0150b1eda3d 100644
--- a/searchlib/src/vespa/searchlib/engine/docsumreply.h
+++ b/searchlib/src/vespa/searchlib/engine/docsumreply.h
@@ -22,9 +22,9 @@ struct DocsumReply
document::GlobalId gid;
Blob data;
- Docsum() : docid(0), gid(), data(0) {}
- Docsum(document::GlobalId gid_) : docid(0), gid(gid_), data(0) { }
- Docsum(document::GlobalId gid_, const char *buf, uint32_t len) : docid(0), gid(gid_), data(len) {
+ Docsum() noexcept : docid(0), gid(), data(0) {}
+ Docsum(document::GlobalId gid_) noexcept : docid(0), gid(gid_), data(0) { }
+ Docsum(document::GlobalId gid_, const char *buf, uint32_t len) noexcept : docid(0), gid(gid_), data(len) {
memcpy(data.str(), buf, len);
}
Docsum & setData(const char *buf, uint32_t len) {
diff --git a/searchlib/src/vespa/searchlib/engine/docsumrequest.h b/searchlib/src/vespa/searchlib/engine/docsumrequest.h
index 8aa8d036b73..8fe5aa6f465 100644
--- a/searchlib/src/vespa/searchlib/engine/docsumrequest.h
+++ b/searchlib/src/vespa/searchlib/engine/docsumrequest.h
@@ -23,8 +23,8 @@ public:
class Hit {
public:
- Hit() : gid(), docid(0), path(0) {}
- Hit(const document::GlobalId & gid_) : gid(gid_), docid(0), path(0) {}
+ Hit() noexcept : gid(), docid(0), path(0) {}
+ Hit(const document::GlobalId & gid_) noexcept : gid(gid_), docid(0), path(0) {}
document::GlobalId gid;
mutable uint32_t docid; // converted in backend
diff --git a/searchlib/src/vespa/searchlib/engine/searchreply.h b/searchlib/src/vespa/searchlib/engine/searchreply.h
index d9468216a90..531f94d2b6f 100644
--- a/searchlib/src/vespa/searchlib/engine/searchreply.h
+++ b/searchlib/src/vespa/searchlib/engine/searchreply.h
@@ -18,7 +18,7 @@ public:
class Hit
{
public:
- Hit() : gid(), metric(0), path(0), _distributionKey(0) {}
+ Hit() noexcept : gid(), metric(0), path(0), _distributionKey(0) {}
void setDistributionKey(uint32_t key) { _distributionKey = key; }
uint32_t getDistributionKey() const { return _distributionKey; }
document::GlobalId gid;
@@ -30,9 +30,9 @@ public:
class Coverage {
public:
- Coverage() : Coverage(0) { }
- Coverage(uint64_t active) : Coverage(active, active) { }
- Coverage(uint64_t active, uint64_t covered)
+ Coverage() noexcept : Coverage(0) { }
+ Coverage(uint64_t active) noexcept : Coverage(active, active) { }
+ Coverage(uint64_t active, uint64_t covered) noexcept
: _covered(covered), _active(active), _soonActive(active),
_degradeReason(0), _nodesQueried(1), _nodesReplied(1)
{ }
diff --git a/searchlib/src/vespa/searchlib/features/array_parser.h b/searchlib/src/vespa/searchlib/features/array_parser.h
index 8bf6e9ca365..7de766efddc 100644
--- a/searchlib/src/vespa/searchlib/features/array_parser.h
+++ b/searchlib/src/vespa/searchlib/features/array_parser.h
@@ -29,7 +29,7 @@ public:
class ValueAndIndex {
public:
typedef T ValueType;
- ValueAndIndex(T value, uint32_t index) : _value(value), _index(index) { }
+ ValueAndIndex(T value, uint32_t index) noexcept : _value(value), _index(index) { }
T getValue() const { return _value; }
uint32_t getIndex() const { return _index; }
bool operator < (const ValueAndIndex & b) const { return _index < b._index; }
diff --git a/searchlib/src/vespa/searchlib/features/bm25_feature.h b/searchlib/src/vespa/searchlib/features/bm25_feature.h
index 0afd14e7ac8..72dcb7e2ef7 100644
--- a/searchlib/src/vespa/searchlib/features/bm25_feature.h
+++ b/searchlib/src/vespa/searchlib/features/bm25_feature.h
@@ -14,7 +14,7 @@ private:
fef::TermFieldHandle handle;
const fef::TermFieldMatchData* tfmd;
double idf_mul_k1_plus_one;
- QueryTerm(fef::TermFieldHandle handle_, double inverse_doc_freq, double k1_param)
+ QueryTerm(fef::TermFieldHandle handle_, double inverse_doc_freq, double k1_param) noexcept
: handle(handle_),
tfmd(nullptr),
idf_mul_k1_plus_one(inverse_doc_freq * (k1_param + 1))
diff --git a/searchlib/src/vespa/searchlib/features/fieldmatch/computer.h b/searchlib/src/vespa/searchlib/features/fieldmatch/computer.h
index e4dbde1248a..a4699b17457 100644
--- a/searchlib/src/vespa/searchlib/features/fieldmatch/computer.h
+++ b/searchlib/src/vespa/searchlib/features/fieldmatch/computer.h
@@ -289,7 +289,7 @@ private:
struct SegmentData {
SegmentData() : segment(), valid(false) {}
- SegmentData(SegmentStart::SP ss, bool v = false) : segment(std::move(ss)), valid(v) {}
+ SegmentData(SegmentStart::SP ss, bool v = false) noexcept : segment(std::move(ss)), valid(v) {}
SegmentStart::SP segment;
bool valid;
};
diff --git a/searchlib/src/vespa/searchlib/fef/rank_program.cpp b/searchlib/src/vespa/searchlib/fef/rank_program.cpp
index 0bc85a63ceb..dd1e774607f 100644
--- a/searchlib/src/vespa/searchlib/fef/rank_program.cpp
+++ b/searchlib/src/vespa/searchlib/fef/rank_program.cpp
@@ -23,7 +23,7 @@ struct Override
BlueprintResolver::FeatureRef ref;
feature_t value;
- Override(const BlueprintResolver::FeatureRef &r, feature_t v)
+ Override(const BlueprintResolver::FeatureRef &r, feature_t v) noexcept
: ref(r), value(v) {}
bool operator<(const Override &rhs) const {
diff --git a/searchlib/src/vespa/searchlib/fef/tablemanager.cpp b/searchlib/src/vespa/searchlib/fef/tablemanager.cpp
index 9503e34cbaa..1aa7d4a14e9 100644
--- a/searchlib/src/vespa/searchlib/fef/tablemanager.cpp
+++ b/searchlib/src/vespa/searchlib/fef/tablemanager.cpp
@@ -2,36 +2,29 @@
#include "tablemanager.h"
-namespace search {
-namespace fef {
+namespace search::fef {
-TableManager::TableManager() :
- _factories(),
- _cache(),
- _lock()
-{
-}
+TableManager::TableManager() = default;
-TableManager::~TableManager() {}
+TableManager::~TableManager() = default;
const Table *
TableManager::getTable(const vespalib::string & name) const
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
TableCache::const_iterator itr = _cache.find(name);
if (itr != _cache.end()) {
return itr->second.get();
}
for (size_t i = 0; i < _factories.size(); ++i) {
Table::SP table = _factories[i]->createTable(name);
- if (table.get() != NULL) {
+ if (table) {
_cache.insert(std::make_pair(name, table));
return table.get();
}
}
- _cache.insert(std::make_pair(name, Table::SP(NULL)));
- return NULL;
+ _cache.insert(std::make_pair(name, Table::SP()));
+ return nullptr;
}
-} // namespace fef
-} // namespace search
+}
diff --git a/searchlib/src/vespa/searchlib/fef/tablemanager.h b/searchlib/src/vespa/searchlib/fef/tablemanager.h
index 4efd8d4aeff..4b83cb7c7a0 100644
--- a/searchlib/src/vespa/searchlib/fef/tablemanager.h
+++ b/searchlib/src/vespa/searchlib/fef/tablemanager.h
@@ -4,12 +4,11 @@
#include "itablefactory.h"
#include "itablemanager.h"
-#include <vespa/vespalib/util/sync.h>
#include <map>
#include <vector>
+#include <mutex>
-namespace search {
-namespace fef {
+namespace search::fef {
/**
* This class manages a set of tables and contains an ordered list of table factories used to create tables,
@@ -24,11 +23,11 @@ private:
typedef std::map<vespalib::string, Table::SP> TableCache;
std::vector<ITableFactory::SP> _factories;
mutable TableCache _cache;
- vespalib::Lock _lock;
+ mutable std::mutex _lock;
public:
TableManager();
- ~TableManager();
+ ~TableManager() override;
/**
* Adds a table factory to this manager.
@@ -46,6 +45,4 @@ public:
const Table * getTable(const vespalib::string & name) const override;
};
-} // namespace fef
-} // namespace search
-
+}
diff --git a/searchlib/src/vespa/searchlib/fef/termmatchdatamerger.cpp b/searchlib/src/vespa/searchlib/fef/termmatchdatamerger.cpp
index 973e11fc0d2..11a5dd80b4c 100644
--- a/searchlib/src/vespa/searchlib/fef/termmatchdatamerger.cpp
+++ b/searchlib/src/vespa/searchlib/fef/termmatchdatamerger.cpp
@@ -24,7 +24,7 @@ TermMatchDataMerger::TermMatchDataMerger(const Inputs &allinputs,
}
}
-TermMatchDataMerger::~TermMatchDataMerger() {}
+TermMatchDataMerger::~TermMatchDataMerger() = default;
void
TermMatchDataMerger::merge(uint32_t docid)
diff --git a/searchlib/src/vespa/searchlib/fef/termmatchdatamerger.h b/searchlib/src/vespa/searchlib/fef/termmatchdatamerger.h
index e0addc374b2..fb129b792b8 100644
--- a/searchlib/src/vespa/searchlib/fef/termmatchdatamerger.h
+++ b/searchlib/src/vespa/searchlib/fef/termmatchdatamerger.h
@@ -6,8 +6,7 @@
#include "termfieldmatchdata.h"
#include <vector>
-namespace search {
-namespace fef {
+namespace search::fef {
class TermMatchDataMerger
{
@@ -16,8 +15,8 @@ public:
const TermFieldMatchData *matchData;
double exactness;
- Input() : matchData(NULL), exactness(0.0) {}
- Input(const TermFieldMatchData *arg_matchData, double arg_exactness)
+ Input() : matchData(nullptr), exactness(0.0) {}
+ Input(const TermFieldMatchData *arg_matchData, double arg_exactness) noexcept
: matchData(arg_matchData), exactness(arg_exactness)
{}
};
@@ -27,21 +26,16 @@ private:
const TermFieldMatchDataArray _output;
std::vector<TermFieldMatchDataPosition> _scratch;
- TermMatchDataMerger(const TermMatchDataMerger &);
- TermMatchDataMerger &operator=(const TermMatchDataMerger &);
-
- void merge(uint32_t docid,
- const Inputs &in,
- TermFieldMatchData &out);
+ void merge(uint32_t docid, const Inputs &in, TermFieldMatchData &out);
public:
+ TermMatchDataMerger(const TermMatchDataMerger &) = delete;
+ TermMatchDataMerger &operator=(const TermMatchDataMerger &) = delete;
- TermMatchDataMerger(const Inputs &allinputs,
- const TermFieldMatchDataArray &outputs);
+ TermMatchDataMerger(const Inputs &allinputs, const TermFieldMatchDataArray &outputs);
~TermMatchDataMerger();
void merge(uint32_t docid);
};
-} // namespace fef
-} // namespace search
+}
diff --git a/searchlib/src/vespa/searchlib/grouping/hyperloglog.h b/searchlib/src/vespa/searchlib/grouping/hyperloglog.h
index 931b832c76d..2206f4ccbe1 100644
--- a/searchlib/src/vespa/searchlib/grouping/hyperloglog.h
+++ b/searchlib/src/vespa/searchlib/grouping/hyperloglog.h
@@ -28,7 +28,7 @@ template <int BucketBits = 10, typename HashT = uint32_t>
class ExchangerSketch : public SparseSketch<BucketBits, HashT> {
typename Sketch<BucketBits, HashT>::UP &_sketch_ptr;
- virtual int aggregate(HashT hash) override {
+ int aggregate(HashT hash) override {
if (this->getSize() > SPARSE_SKETCH_LIMIT) {
NormalSketch<BucketBits, HashT> *normal_sketch =
new NormalSketch<BucketBits, HashT>;
diff --git a/searchlib/src/vespa/searchlib/grouping/sketch.h b/searchlib/src/vespa/searchlib/grouping/sketch.h
index 317c1bfef9d..c105b480a3d 100644
--- a/searchlib/src/vespa/searchlib/grouping/sketch.h
+++ b/searchlib/src/vespa/searchlib/grouping/sketch.h
@@ -70,21 +70,21 @@ struct SparseSketch : Sketch<BucketBits, HashT> {
enum { classId = IDENTIFIABLE_CLASSID_NS(search, SparseSketch) };
struct IdentityHash {
- size_t operator()(HashT hash) const { return hash; }
+ size_t operator()(HashT hash) const noexcept { return hash; }
};
std::unordered_set<HashT, IdentityHash> hash_set;
size_t getSize() const { return hash_set.size(); }
- virtual int aggregate(HashT hash) override {
+ int aggregate(HashT hash) override {
return hash_set.insert(hash).second ? 1 : 0;
}
- virtual uint32_t getClassId() const override { return classId; }
- virtual void serialize(vespalib::Serializer &os) const override;
- virtual void deserialize(vespalib::Deserializer &is) override;
+ uint32_t getClassId() const override { return classId; }
+ void serialize(vespalib::Serializer &os) const override;
+ void deserialize(vespalib::Deserializer &is) override;
- virtual bool operator==(const SketchType &other) const override {
+ bool operator==(const SketchType &other) const override {
const SparseSketch<BucketBits, HashT> *other_sparse =
dynamic_cast<const SparseSketch<BucketBits, HashT> *>(&other);
if (!other_sparse) {
@@ -101,7 +101,7 @@ struct SparseSketch : Sketch<BucketBits, HashT> {
return true;
}
- virtual void print(std::ostream &out) const override {
+ void print(std::ostream &out) const override {
out << " (" << hash_set.size() << " elements)";
for (auto hash : hash_set) {
out << " 0x" << std::hex;
diff --git a/searchlib/src/vespa/searchlib/index/docidandfeatures.h b/searchlib/src/vespa/searchlib/index/docidandfeatures.h
index 5372d5ef3aa..6ee80721038 100644
--- a/searchlib/src/vespa/searchlib/index/docidandfeatures.h
+++ b/searchlib/src/vespa/searchlib/index/docidandfeatures.h
@@ -26,14 +26,14 @@ private:
uint32_t _elementLen;
public:
- WordDocElementFeatures()
+ WordDocElementFeatures() noexcept
: _elementId(0u),
_numOccs(0u),
_weight(1),
_elementLen(SEARCHLIB_FEF_UNKNOWN_FIELD_LENGTH)
{}
- WordDocElementFeatures(uint32_t elementId)
+ WordDocElementFeatures(uint32_t elementId) noexcept
: _elementId(elementId),
_numOccs(0u),
_weight(1),
@@ -42,7 +42,7 @@ public:
WordDocElementFeatures(uint32_t elementId,
uint32_t weight,
- uint32_t elementLen)
+ uint32_t elementLen) noexcept
: _elementId(elementId),
_numOccs(0u),
_weight(weight),
@@ -71,11 +71,11 @@ private:
uint32_t _wordPos;
public:
- WordDocElementWordPosFeatures()
+ WordDocElementWordPosFeatures() noexcept
: _wordPos(0u)
{}
- WordDocElementWordPosFeatures(uint32_t wordPos)
+ WordDocElementWordPosFeatures(uint32_t wordPos) noexcept
: _wordPos(wordPos)
{}
@@ -101,17 +101,17 @@ protected:
std::vector<WordDocElementWordPosFeatures> _word_positions;
// Raw data (file format specific, packed)
- RawData _blob; // Feature data for (word, docid) pair
+ RawData _blob; // Feature data for (word, docid) pair
uint32_t _bit_offset; // Offset of feature start ([0..63])
uint32_t _bit_length; // Length of features
- bool _has_raw_data;
+ bool _has_raw_data;
public:
DocIdAndFeatures();
DocIdAndFeatures(const DocIdAndFeatures &);
DocIdAndFeatures & operator = (const DocIdAndFeatures &);
- DocIdAndFeatures(DocIdAndFeatures &&) = default;
- DocIdAndFeatures & operator = (DocIdAndFeatures &&) = default;
+ DocIdAndFeatures(DocIdAndFeatures &&) noexcept = default;
+ DocIdAndFeatures & operator = (DocIdAndFeatures &&) noexcept = default;
~DocIdAndFeatures();
void clear_features() {
diff --git a/searchlib/src/vespa/searchlib/index/schemautil.cpp b/searchlib/src/vespa/searchlib/index/schemautil.cpp
index 1fce4a1fe99..57a90892d4f 100644
--- a/searchlib/src/vespa/searchlib/index/schemautil.cpp
+++ b/searchlib/src/vespa/searchlib/index/schemautil.cpp
@@ -3,6 +3,7 @@
#include "schemautil.h"
#include <set>
#include <fstream>
+#include <cassert>
#include <vespa/log/log.h>
LOG_SETUP(".index.schemautil");
diff --git a/searchlib/src/vespa/searchlib/index/uri_field.cpp b/searchlib/src/vespa/searchlib/index/uri_field.cpp
index 30b78c24410..af0881dd6b4 100644
--- a/searchlib/src/vespa/searchlib/index/uri_field.cpp
+++ b/searchlib/src/vespa/searchlib/index/uri_field.cpp
@@ -1,6 +1,7 @@
// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "uri_field.h"
+#include <cassert>
namespace search::index {
diff --git a/searchlib/src/vespa/searchlib/memoryindex/field_index_remover.h b/searchlib/src/vespa/searchlib/memoryindex/field_index_remover.h
index 36d2286cfb1..717f21528bb 100644
--- a/searchlib/src/vespa/searchlib/memoryindex/field_index_remover.h
+++ b/searchlib/src/vespa/searchlib/memoryindex/field_index_remover.h
@@ -21,11 +21,11 @@ private:
struct WordFieldDocTuple {
vespalib::datastore::EntryRef _wordRef;
uint32_t _docId;
- WordFieldDocTuple() :
+ WordFieldDocTuple() noexcept :
_wordRef(0),
_docId(0)
{ }
- WordFieldDocTuple(vespalib::datastore::EntryRef wordRef, uint32_t docId) :
+ WordFieldDocTuple(vespalib::datastore::EntryRef wordRef, uint32_t docId) noexcept :
_wordRef(wordRef),
_docId(docId)
{ }
@@ -44,12 +44,12 @@ private:
CompactWordsStore _store;
CompactWordsStore::Builder::UP _builder;
- std::vector<WordFieldDocTuple> _wordFieldDocTuples;
+ std::vector<WordFieldDocTuple> _wordFieldDocTuples;
const WordStore &_wordStore;
public:
FieldIndexRemover(const WordStore &wordStore);
- ~FieldIndexRemover();
+ ~FieldIndexRemover() override;
void remove(uint32_t docId, IFieldIndexRemoveListener &inverter);
CompactWordsStore &getStore() { return _store; }
const CompactWordsStore &getStore() const { return _store; }
diff --git a/searchlib/src/vespa/searchlib/memoryindex/field_inverter.h b/searchlib/src/vespa/searchlib/memoryindex/field_inverter.h
index 78a1cf6c171..3a18d0c2f8c 100644
--- a/searchlib/src/vespa/searchlib/memoryindex/field_inverter.h
+++ b/searchlib/src/vespa/searchlib/memoryindex/field_inverter.h
@@ -39,7 +39,7 @@ public:
static constexpr uint32_t _elemRemoved =
std::numeric_limits<uint32_t>::max();
- PosInfo()
+ PosInfo() noexcept
: _wordNum(0),
_docId(0),
_elemId(0),
@@ -51,7 +51,7 @@ public:
PosInfo(uint32_t wordRef,
uint32_t docId,
uint32_t elemId,
- uint32_t wordPos, uint32_t elemRef)
+ uint32_t wordPos, uint32_t elemRef) noexcept
: _wordNum(wordRef),
_docId(docId),
_elemId(elemId),
@@ -60,8 +60,7 @@ public:
{
}
- PosInfo(uint32_t wordRef,
- uint32_t docId)
+ PosInfo(uint32_t wordRef, uint32_t docId) noexcept
: _wordNum(wordRef),
_docId(docId),
_elemId(_elemRemoved),
diff --git a/searchlib/src/vespa/searchlib/memoryindex/memory_index.cpp b/searchlib/src/vespa/searchlib/memoryindex/memory_index.cpp
index 34c5d65ab23..789b7fcf452 100644
--- a/searchlib/src/vespa/searchlib/memoryindex/memory_index.cpp
+++ b/searchlib/src/vespa/searchlib/memoryindex/memory_index.cpp
@@ -18,7 +18,6 @@ LOG_SETUP(".searchlib.memoryindex.memory_index");
using document::ArrayFieldValue;
using document::WeightedSetFieldValue;
-using vespalib::LockGuard;
namespace search {
@@ -215,7 +214,7 @@ MemoryIndex::getNumWords() const {
void
MemoryIndex::pruneRemovedFields(const Schema &schema)
{
- LockGuard lock(_lock);
+ std::lock_guard lock(_lock);
if (_prunedSchema.get() == nullptr) {
auto newSchema = Schema::intersect(_schema, schema);
if (_schema == *newSchema) {
@@ -241,7 +240,7 @@ MemoryIndex::pruneRemovedFields(const Schema &schema)
Schema::SP
MemoryIndex::getPrunedSchema() const
{
- LockGuard lock(_lock);
+ std::lock_guard lock(_lock);
return _prunedSchema;
}
diff --git a/searchlib/src/vespa/searchlib/memoryindex/memory_index.h b/searchlib/src/vespa/searchlib/memoryindex/memory_index.h
index a9f153f7dd8..56eb4ad7a66 100644
--- a/searchlib/src/vespa/searchlib/memoryindex/memory_index.h
+++ b/searchlib/src/vespa/searchlib/memoryindex/memory_index.h
@@ -48,14 +48,14 @@ private:
std::unique_ptr<DocumentInverter> _inverter0;
std::unique_ptr<DocumentInverter> _inverter1;
DocumentInverter *_inverter;
- bool _frozen;
- uint32_t _maxDocId;
- uint32_t _numDocs;
- vespalib::Lock _lock;
- std::vector<bool> _hiddenFields;
- index::Schema::SP _prunedSchema;
+ bool _frozen;
+ uint32_t _maxDocId;
+ uint32_t _numDocs;
+ mutable std::mutex _lock;
+ std::vector<bool> _hiddenFields;
+ index::Schema::SP _prunedSchema;
vespalib::hash_set<uint32_t> _indexedDocs; // documents in memory index
- const uint64_t _staticMemoryFootprint;
+ const uint64_t _staticMemoryFootprint;
MemoryIndex(const MemoryIndex &) = delete;
MemoryIndex(MemoryIndex &&) = delete;
diff --git a/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp b/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp
index 1820fb0e969..6039a86580c 100644
--- a/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp
+++ b/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp
@@ -225,7 +225,7 @@ SimpleQueryStackDumpIterator::next()
case ParseItem::ITEM_PREDICATE_QUERY:
try {
_curr_index_name = read_stringref(p);
- _predicate_query_term.reset(new PredicateQueryTerm);
+ _predicate_query_term = std::make_unique<PredicateQueryTerm>();
size_t count = readCompressedPositiveInt(p);
for (size_t i = 0; i < count; ++i) {
diff --git a/searchlib/src/vespa/searchlib/predicate/predicate_tree_analyzer.cpp b/searchlib/src/vespa/searchlib/predicate/predicate_tree_analyzer.cpp
index e8257d28c63..dba6ebfb117 100644
--- a/searchlib/src/vespa/searchlib/predicate/predicate_tree_analyzer.cpp
+++ b/searchlib/src/vespa/searchlib/predicate/predicate_tree_analyzer.cpp
@@ -4,6 +4,7 @@
#include <vespa/document/predicate/predicate.h>
#include <algorithm>
#include <cmath>
+#include <cassert>
using document::Predicate;
using std::map;
diff --git a/searchlib/src/vespa/searchlib/query/streaming/hit.h b/searchlib/src/vespa/searchlib/query/streaming/hit.h
index 64b71a70df9..fabaa3ad50c 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/hit.h
+++ b/searchlib/src/vespa/searchlib/query/streaming/hit.h
@@ -9,7 +9,7 @@ namespace search::streaming {
class Hit
{
public:
- Hit(uint32_t pos_, uint32_t context_, uint32_t elemId_, int32_t weight_)
+ Hit(uint32_t pos_, uint32_t context_, uint32_t elemId_, int32_t weight_) noexcept
: _position(pos_ | (context_<<24)),
_elemId(elemId_),
_weight(weight_)
diff --git a/searchlib/src/vespa/searchlib/query/tree/predicate_query_term.h b/searchlib/src/vespa/searchlib/query/tree/predicate_query_term.h
index 0a92546e414..8602eb1ac57 100644
--- a/searchlib/src/vespa/searchlib/query/tree/predicate_query_term.h
+++ b/searchlib/src/vespa/searchlib/query/tree/predicate_query_term.h
@@ -22,7 +22,7 @@ class PredicateQueryTerm {
public:
Entry(const vespalib::string &key, const ValueType &value,
- uint64_t sub_query_bitmap = ALL_SUB_QUERIES)
+ uint64_t sub_query_bitmap = ALL_SUB_QUERIES) noexcept
: _key(key), _value(value), _sub_query_bitmap(sub_query_bitmap) {}
vespalib::string getKey() const { return _key; }
@@ -41,13 +41,7 @@ class PredicateQueryTerm {
public:
typedef std::unique_ptr<PredicateQueryTerm> UP;
- PredicateQueryTerm() : _features(), _range_features() {}
-
- PredicateQueryTerm(const std::vector<Entry<vespalib::string>> &features,
- const std::vector<Entry<uint64_t>> &range_features)
- : _features(features),
- _range_features(range_features) {
- }
+ PredicateQueryTerm() noexcept : _features(), _range_features() {}
void addFeature(const vespalib::string &key, const vespalib::string &value,
uint64_t sub_query_bitmask = ALL_SUB_QUERIES) {
diff --git a/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h b/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h
index 9289df7cbe9..600249c3e1e 100644
--- a/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h
+++ b/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h
@@ -153,7 +153,7 @@ private:
void visit(PredicateQuery &node) override {
replicate(node, _builder.addPredicateQuery(
- PredicateQueryTerm::UP(new PredicateQueryTerm(*node.getTerm())),
+ std::make_unique<PredicateQueryTerm>(*node.getTerm()),
node.getView(), node.getId(), node.getWeight()));
}
diff --git a/searchlib/src/vespa/searchlib/queryeval/global_filter.h b/searchlib/src/vespa/searchlib/queryeval/global_filter.h
index b30162affa7..3e57ded4898 100644
--- a/searchlib/src/vespa/searchlib/queryeval/global_filter.h
+++ b/searchlib/src/vespa/searchlib/queryeval/global_filter.h
@@ -21,15 +21,15 @@ private:
struct ctor_tag {};
std::unique_ptr<search::BitVector> bit_vector;
+public:
GlobalFilter(const GlobalFilter &) = delete;
GlobalFilter(GlobalFilter &&) = delete;
-public:
- GlobalFilter(ctor_tag, std::unique_ptr<search::BitVector> bit_vector_in)
+ GlobalFilter(ctor_tag, std::unique_ptr<search::BitVector> bit_vector_in) noexcept
: bit_vector(std::move(bit_vector_in))
{}
- GlobalFilter(ctor_tag) : bit_vector() {}
+ GlobalFilter(ctor_tag) noexcept : bit_vector() {}
~GlobalFilter() {}
diff --git a/searchlib/src/vespa/searchlib/queryeval/sourceblendersearch.h b/searchlib/src/vespa/searchlib/queryeval/sourceblendersearch.h
index f209e0f7fd8..b9812036637 100644
--- a/searchlib/src/vespa/searchlib/queryeval/sourceblendersearch.h
+++ b/searchlib/src/vespa/searchlib/queryeval/sourceblendersearch.h
@@ -29,7 +29,7 @@ public:
SearchIterator *search;
uint32_t sourceId;
Child() : search(nullptr), sourceId(0) { }
- Child(SearchIterator *s, uint32_t id) : search(s), sourceId(id) {}
+ Child(SearchIterator *s, uint32_t id) noexcept : search(s), sourceId(id) {}
};
typedef std::vector<Child> Children;
diff --git a/searchlib/src/vespa/searchlib/queryeval/wand/wand_parts.h b/searchlib/src/vespa/searchlib/queryeval/wand/wand_parts.h
index 071d6d99470..937e7a089df 100644
--- a/searchlib/src/vespa/searchlib/queryeval/wand/wand_parts.h
+++ b/searchlib/src/vespa/searchlib/queryeval/wand/wand_parts.h
@@ -41,11 +41,12 @@ struct Term {
uint32_t estHits;
fef::TermFieldMatchData *matchData;
score_t maxScore = 0.0; // <- only used by rise wand test
- Term(SearchIterator *s, int32_t w, uint32_t e, fef::TermFieldMatchData *tfmd)
- : search(s), weight(w), estHits(e), matchData(tfmd) {}
- Term() : Term(nullptr, 0, 0, nullptr){}
- Term(SearchIterator *s, int32_t w, uint32_t e) : Term(s, w, e, nullptr) {}
- Term(SearchIterator::UP s, int32_t w, uint32_t e) : Term(s.release(), w, e, nullptr) {}
+ Term(SearchIterator *s, int32_t w, uint32_t e, fef::TermFieldMatchData *tfmd) noexcept
+ : search(s), weight(w), estHits(e), matchData(tfmd)
+ {}
+ Term() noexcept : Term(nullptr, 0, 0, nullptr){}
+ Term(SearchIterator *s, int32_t w, uint32_t e) noexcept : Term(s, w, e, nullptr) {}
+ Term(SearchIterator::UP s, int32_t w, uint32_t e) noexcept : Term(s.release(), w, e, nullptr) {}
};
//-----------------------------------------------------------------------------
diff --git a/searchlib/src/vespa/searchlib/queryeval/wand/weak_and_heap.cpp b/searchlib/src/vespa/searchlib/queryeval/wand/weak_and_heap.cpp
index dc84eb45b8a..28c229596b0 100644
--- a/searchlib/src/vespa/searchlib/queryeval/wand/weak_and_heap.cpp
+++ b/searchlib/src/vespa/searchlib/queryeval/wand/weak_and_heap.cpp
@@ -12,7 +12,7 @@ SharedWeakAndPriorityQueue::SharedWeakAndPriorityQueue(uint32_t scoresToTrack) :
_bestScores.reserve(scoresToTrack);
}
-SharedWeakAndPriorityQueue::~SharedWeakAndPriorityQueue() { }
+SharedWeakAndPriorityQueue::~SharedWeakAndPriorityQueue() = default;
void
SharedWeakAndPriorityQueue::adjust(score_t *begin, score_t *end)
@@ -20,7 +20,7 @@ SharedWeakAndPriorityQueue::adjust(score_t *begin, score_t *end)
if (getScoresToTrack() == 0) {
return;
}
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
for (score_t *itr = begin; itr != end; ++itr) {
score_t score = *itr;
if (!is_full()) {
diff --git a/searchlib/src/vespa/searchlib/queryeval/wand/weak_and_heap.h b/searchlib/src/vespa/searchlib/queryeval/wand/weak_and_heap.h
index d6105d7e6f2..28c317de3ee 100644
--- a/searchlib/src/vespa/searchlib/queryeval/wand/weak_and_heap.h
+++ b/searchlib/src/vespa/searchlib/queryeval/wand/weak_and_heap.h
@@ -3,7 +3,7 @@
#include "wand_parts.h"
#include <vespa/vespalib/util/priority_queue.h>
-#include <vespa/vespalib/util/sync.h>
+#include <mutex>
namespace search::queryeval {
@@ -51,7 +51,7 @@ class SharedWeakAndPriorityQueue : public WeakAndHeap
private:
typedef vespalib::PriorityQueue<score_t> Scores;
Scores _bestScores;
- vespalib::Lock _lock;
+ std::mutex _lock;
bool is_full() const { return (_bestScores.size() >= getScoresToTrack()); }
diff --git a/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp b/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp
index 9def5a7b0a8..6488b525b7c 100644
--- a/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp
+++ b/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp
@@ -40,7 +40,7 @@ struct PairDist {
uint32_t id_first;
uint32_t id_second;
double distance;
- PairDist(uint32_t i1, uint32_t i2, double d)
+ PairDist(uint32_t i1, uint32_t i2, double d) noexcept
: id_first(i1), id_second(i2), distance(d)
{}
};
diff --git a/searchlib/src/vespa/searchlib/tensor/hnsw_index_utils.h b/searchlib/src/vespa/searchlib/tensor/hnsw_index_utils.h
index 99266505780..d206b055071 100644
--- a/searchlib/src/vespa/searchlib/tensor/hnsw_index_utils.h
+++ b/searchlib/src/vespa/searchlib/tensor/hnsw_index_utils.h
@@ -16,9 +16,9 @@ struct HnswCandidate {
uint32_t docid;
HnswGraph::NodeRef node_ref;
double distance;
- HnswCandidate(uint32_t docid_in, double distance_in)
+ HnswCandidate(uint32_t docid_in, double distance_in) noexcept
: docid(docid_in), node_ref(), distance(distance_in) {}
- HnswCandidate(uint32_t docid_in, HnswGraph::NodeRef node_ref_in, double distance_in)
+ HnswCandidate(uint32_t docid_in, HnswGraph::NodeRef node_ref_in, double distance_in) noexcept
: docid(docid_in), node_ref(node_ref_in), distance(distance_in) {}
};
diff --git a/searchlib/src/vespa/searchlib/tensor/nearest_neighbor_index.h b/searchlib/src/vespa/searchlib/tensor/nearest_neighbor_index.h
index 74f14cea21b..c14da0d058f 100644
--- a/searchlib/src/vespa/searchlib/tensor/nearest_neighbor_index.h
+++ b/searchlib/src/vespa/searchlib/tensor/nearest_neighbor_index.h
@@ -29,12 +29,12 @@ public:
struct Neighbor {
uint32_t docid;
double distance;
- Neighbor(uint32_t id, double dist)
+ Neighbor(uint32_t id, double dist) noexcept
: docid(id), distance(dist)
{}
- Neighbor() : docid(0), distance(0.0) {}
+ Neighbor() noexcept : docid(0), distance(0.0) {}
};
- virtual ~NearestNeighborIndex() {}
+ virtual ~NearestNeighborIndex() = default;
virtual void add_document(uint32_t docid) = 0;
/**
diff --git a/searchlib/src/vespa/searchlib/test/imported_attribute_fixture.h b/searchlib/src/vespa/searchlib/test/imported_attribute_fixture.h
index e2fcbf444a2..0a04e1e79fd 100644
--- a/searchlib/src/vespa/searchlib/test/imported_attribute_fixture.h
+++ b/searchlib/src/vespa/searchlib/test/imported_attribute_fixture.h
@@ -23,7 +23,7 @@ namespace search {
struct MockDocumentMetaStoreContext : public IDocumentMetaStoreContext {
mutable size_t get_read_guard_cnt;
- MockDocumentMetaStoreContext() : get_read_guard_cnt(0) {}
+ MockDocumentMetaStoreContext() noexcept : get_read_guard_cnt(0) {}
IReadGuard::UP getReadGuard() const override;
};
diff --git a/searchlib/src/vespa/searchlib/transactionlog/client_session.cpp b/searchlib/src/vespa/searchlib/transactionlog/client_session.cpp
index 8678d88b43c..40db92cbe78 100644
--- a/searchlib/src/vespa/searchlib/transactionlog/client_session.cpp
+++ b/searchlib/src/vespa/searchlib/transactionlog/client_session.cpp
@@ -123,7 +123,7 @@ void
Session::clear()
{
if (_sessionId > 0) {
- LockGuard guard(_tlc._lock);
+ std::lock_guard guard(_tlc._lock);
_tlc._sessions.erase(SessionKey(_domain, _sessionId));
}
_sessionId = 0;
@@ -145,7 +145,7 @@ Session::init(FRT_RPCRequest *req)
_sessionId = retval;
SessionKey key(_domain, _sessionId);
{
- LockGuard guard(_tlc._lock);
+ std::lock_guard guard(_tlc._lock);
_tlc._sessions[key] = this;
}
retval = run();
diff --git a/searchlib/src/vespa/searchlib/transactionlog/domain.cpp b/searchlib/src/vespa/searchlib/transactionlog/domain.cpp
index 126a7afed4d..454293dfc84 100644
--- a/searchlib/src/vespa/searchlib/transactionlog/domain.cpp
+++ b/searchlib/src/vespa/searchlib/transactionlog/domain.cpp
@@ -19,7 +19,6 @@ LOG_SETUP(".transactionlog.domain");
using vespalib::string;
using vespalib::make_string_short::fmt;
-using vespalib::LockGuard;
using vespalib::makeTask;
using vespalib::makeClosure;
using vespalib::makeLambdaTask;
@@ -104,7 +103,7 @@ Domain::addPart(SerialNum partId, bool isLastPart) {
dp->erase(dp->range().to() + 1);
} else {
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_parts[partId] = dp;
}
if (! isLastPart) {
@@ -123,7 +122,7 @@ Domain::~Domain() {
DomainInfo
Domain::getDomainInfo() const
{
- LockGuard guard(_lock);
+ UniqueLock guard(_lock);
DomainInfo info(SerialNumRange(begin(guard), end(guard)), size(guard), byteSize(guard), _maxSessionRunTime);
for (const auto &entry: _parts) {
const DomainPart &part = *entry.second;
@@ -135,14 +134,18 @@ Domain::getDomainInfo() const
SerialNum
Domain::begin() const
{
- return begin(LockGuard(_lock));
+ return begin(UniqueLock(_lock));
}
+void
+Domain::verifyLock(const UniqueLock & guard) const {
+ assert(guard.mutex() == &_lock);
+ assert(guard.owns_lock());
+}
SerialNum
-Domain::begin(const LockGuard & guard) const
+Domain::begin(const UniqueLock & guard) const
{
- (void) guard;
- assert(guard.locks(_lock));
+ verifyLock(guard);
SerialNum s(0);
if ( ! _parts.empty() ) {
s = _parts.cbegin()->second->range().from();
@@ -153,14 +156,13 @@ Domain::begin(const LockGuard & guard) const
SerialNum
Domain::end() const
{
- return end(LockGuard(_lock));
+ return end(UniqueLock(_lock));
}
SerialNum
-Domain::end(const LockGuard & guard) const
+Domain::end(const UniqueLock & guard) const
{
- (void) guard;
- assert(guard.locks(_lock));
+ verifyLock(guard);
SerialNum s(0);
if ( ! _parts.empty() ) {
s = _parts.crbegin()->second->range().to();
@@ -171,14 +173,13 @@ Domain::end(const LockGuard & guard) const
size_t
Domain::byteSize() const
{
- return byteSize(LockGuard(_lock));
+ return byteSize(UniqueLock(_lock));
}
size_t
-Domain::byteSize(const LockGuard & guard) const
+Domain::byteSize(const UniqueLock & guard) const
{
- (void) guard;
- assert(guard.locks(_lock));
+ verifyLock(guard);
size_t size = 0;
for (const auto &entry : _parts) {
const DomainPart &part = *entry.second;
@@ -191,7 +192,7 @@ SerialNum
Domain::getSynced() const
{
SerialNum s(0);
- LockGuard guard(_lock);
+ UniqueLock guard(_lock);
if (_parts.empty()) {
return s;
}
@@ -228,7 +229,7 @@ Domain::triggerSyncNow()
DomainPart::SP
Domain::findPart(SerialNum s)
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
DomainPartList::iterator it(_parts.upper_bound(s));
if (!_parts.empty() && it != _parts.begin()) {
DomainPartList::iterator prev(it);
@@ -246,14 +247,13 @@ Domain::findPart(SerialNum s)
uint64_t
Domain::size() const
{
- return size(LockGuard(_lock));
+ return size(UniqueLock(_lock));
}
uint64_t
-Domain::size(const LockGuard & guard) const
+Domain::size(const UniqueLock & guard) const
{
- (void) guard;
- assert(guard.locks(_lock));
+ verifyLock(guard);
uint64_t sz(0);
for (const auto & part : _parts) {
sz += part.second->size();
@@ -265,7 +265,7 @@ SerialNum
Domain::findOldestActiveVisit() const
{
SerialNum oldestActive(std::numeric_limits<SerialNum>::max());
- LockGuard guard(_sessionLock);
+ std::lock_guard guard(_sessionLock);
for (const auto & pair : _sessions) {
Session * session(pair.second.get());
if (!session->inSync()) {
@@ -281,7 +281,7 @@ Domain::cleanSessions()
if ( _sessions.empty()) {
return;
}
- LockGuard guard(_sessionLock);
+ std::lock_guard guard(_sessionLock);
for (SessionList::iterator it(_sessions.begin()), mt(_sessions.end()); it != mt; ) {
Session * session(it->second.get());
if (session->inSync()) {
@@ -318,7 +318,7 @@ Domain::optionallyRotateFile(SerialNum serialNum) {
dp = std::make_shared<DomainPart>(_name, dir(), serialNum, _config.getEncoding(),
_config.getCompressionlevel(), _fileHeaderContext, false);
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_parts[serialNum] = dp;
assert(_parts.rbegin()->first == serialNum);
}
@@ -409,7 +409,7 @@ Domain::erase(SerialNum to)
for (DomainPartList::iterator it(_parts.begin()); (_parts.size() > 1) && (it->second.get()->range().to() < to); it = _parts.begin()) {
DomainPart::SP dp(it->second);
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_parts.erase(it);
}
retval = retval && dp->erase(to);
@@ -429,7 +429,7 @@ Domain::visit(const Domain::SP & domain, SerialNum from, SerialNum to, std::uniq
SerialNumRange range(from, to);
auto session = std::make_shared<Session>(_sessionId++, range, domain, std::move(dest));
int id = session->id();
- LockGuard guard(_sessionLock);
+ std::lock_guard guard(_sessionLock);
_sessions[id] = std::move(session);
return id;
}
@@ -438,7 +438,7 @@ int
Domain::startSession(int sessionId)
{
int retval(-1);
- LockGuard guard(_sessionLock);
+ std::lock_guard guard(_sessionLock);
SessionList::iterator found = _sessions.find(sessionId);
if (found != _sessions.end()) {
found->second->setStartTime(std::chrono::steady_clock::now());
@@ -458,7 +458,7 @@ Domain::closeSession(int sessionId)
int retval(-1);
DurationSeconds sessionRunTime(0);
{
- LockGuard guard(_sessionLock);
+ std::lock_guard guard(_sessionLock);
SessionList::iterator found = _sessions.find(sessionId);
if (found != _sessions.end()) {
sessionRunTime = (std::chrono::steady_clock::now() - found->second->getStartTime());
@@ -467,7 +467,7 @@ Domain::closeSession(int sessionId)
}
while (retval == 1) {
std::this_thread::sleep_for(10ms);
- LockGuard guard(_sessionLock);
+ std::lock_guard guard(_sessionLock);
SessionList::iterator found = _sessions.find(sessionId);
if (found != _sessions.end()) {
if ( ! found->second->isVisitRunning()) {
@@ -479,7 +479,7 @@ Domain::closeSession(int sessionId)
}
}
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
if (sessionRunTime > _maxSessionRunTime) {
_maxSessionRunTime = sessionRunTime;
}
diff --git a/searchlib/src/vespa/searchlib/transactionlog/domain.h b/searchlib/src/vespa/searchlib/transactionlog/domain.h
index e41ad930840..a883156f32c 100644
--- a/searchlib/src/vespa/searchlib/transactionlog/domain.h
+++ b/searchlib/src/vespa/searchlib/transactionlog/domain.h
@@ -56,16 +56,18 @@ public:
uint64_t size() const;
Domain & setConfig(const DomainConfig & cfg);
private:
+ using UniqueLock = std::unique_lock<std::mutex>;
+ void verifyLock(const UniqueLock & guard) const;
void commitIfFull(const vespalib::MonitorGuard & guard);
void commitAndTransferResponses(const vespalib::MonitorGuard & guard);
std::unique_ptr<CommitChunk> grabCurrentChunk(const vespalib::MonitorGuard & guard);
void commitChunk(std::unique_ptr<CommitChunk> chunk, const vespalib::MonitorGuard & chunkOrderGuard);
void doCommit(std::unique_ptr<CommitChunk> chunk);
- SerialNum begin(const vespalib::LockGuard & guard) const;
- SerialNum end(const vespalib::LockGuard & guard) const;
- size_t byteSize(const vespalib::LockGuard & guard) const;
- uint64_t size(const vespalib::LockGuard & guard) const;
+ SerialNum begin(const UniqueLock & guard) const;
+ SerialNum end(const UniqueLock & guard) const;
+ size_t byteSize(const UniqueLock & guard) const;
+ uint64_t size(const UniqueLock & guard) const;
void cleanSessions();
vespalib::string dir() const { return getDir(_baseDir, _name); }
void addPart(SerialNum partId, bool isLastPart);
@@ -89,9 +91,9 @@ private:
bool _pendingSync;
vespalib::string _name;
DomainPartList _parts;
- vespalib::Lock _lock;
+ mutable std::mutex _lock;
vespalib::Monitor _currentChunkMonitor;
- vespalib::Lock _sessionLock;
+ mutable std::mutex _sessionLock;
SessionList _sessions;
DurationSeconds _maxSessionRunTime;
vespalib::string _baseDir;
diff --git a/searchlib/src/vespa/searchlib/transactionlog/domainpart.cpp b/searchlib/src/vespa/searchlib/transactionlog/domainpart.cpp
index b7e02894e6b..830384ee538 100644
--- a/searchlib/src/vespa/searchlib/transactionlog/domainpart.cpp
+++ b/searchlib/src/vespa/searchlib/transactionlog/domainpart.cpp
@@ -5,6 +5,7 @@
#include <vespa/vespalib/data/fileheader.h>
#include <vespa/searchlib/common/fileheadercontext.h>
#include <vespa/fastlib/io/bufferedfile.h>
+#include <cassert>
#include <vespa/log/log.h>
LOG_SETUP(".transactionlog.domainpart");
@@ -14,7 +15,6 @@ using vespalib::FileHeader;
using vespalib::string;
using vespalib::getLastErrorString;
using vespalib::IllegalHeaderException;
-using vespalib::LockGuard;
using vespalib::nbostream;
using vespalib::nbostream_longlivedbuf;
using vespalib::alloc::Alloc;
@@ -238,7 +238,7 @@ DomainPart::buildPacketMapping(bool allowTruncate)
_range.to(packet.range().to());
_packets.insert(std::make_pair(firstSerial, std::move(packet)));
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_skipList.push_back(SkipInfo(firstSerial, firstPos));
}
} else {
@@ -329,7 +329,7 @@ DomainPart::close()
{
bool retval(false);
{
- LockGuard guard(_fileLock);
+ std::lock_guard guard(_fileLock);
/*
* Sync old domainpart before starting writing new, to avoid
* hole. XXX: Feed latency spike due to lack of delayed open
@@ -338,7 +338,7 @@ DomainPart::close()
handleSync(*_transLog);
_transLog->dropFromCache();
retval = _transLog->Close();
- LockGuard wguard(_writeLock);
+ std::lock_guard wguard(_writeLock);
_syncedSerial = _writtenSerial;
}
if ( ! retval ) {
@@ -346,7 +346,7 @@ DomainPart::close()
_transLog->GetFileName(), _transLog->GetSize()));
}
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_packets.clear();
}
return retval;
@@ -363,7 +363,7 @@ DomainPart::openAndFind(FastOS_FileInterface &file, const SerialNum &from)
bool retval(file.OpenReadOnly(_transLog->GetFileName()));
if (retval) {
int64_t pos(_headerLen);
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
for(SkipList::const_iterator it(_skipList.begin()), mt(_skipList.end());
(it < mt) && (it->id() <= from);
it++)
@@ -421,7 +421,7 @@ DomainPart::commit(SerialNum firstSerial, const Packet &packet)
}
bool merged(false);
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
if ( ! _packets.empty() ) {
Packet & lastPacket = _packets.rbegin()->second;
if (lastPacket.sizeBytes() < 0xf000) {
@@ -440,12 +440,12 @@ DomainPart::sync()
{
SerialNum syncSerial(0);
{
- LockGuard guard(_writeLock);
+ std::lock_guard guard(_writeLock);
syncSerial = _writtenSerial;
}
- LockGuard guard(_fileLock);
+ std::lock_guard guard(_fileLock);
handleSync(*_transLog);
- LockGuard wguard(_writeLock);
+ std::lock_guard wguard(_writeLock);
if (_syncedSerial < syncSerial) {
_syncedSerial = syncSerial;
}
@@ -455,7 +455,7 @@ bool
DomainPart::visit(SerialNumRange &r, Packet &packet)
{
bool retval(false);
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
LOG(spam, "Visit r(%" PRIu64 ", %" PRIu64 "] Checking %" PRIu64 " packets",
r.from(), r.to(), uint64_t(_packets.size()));
if ( ! isClosed() ) {
@@ -549,7 +549,7 @@ DomainPart::write(FastOS_FileInterface &file, const IChunk & chunk)
os << realEncoding.getRaw(); //Patching real encoding
os << uint32_t(end - (begin + sizeof(uint32_t) + sizeof(uint8_t))); // Patching actual size.
os.wp(end);
- LockGuard guard(_writeLock);
+ std::lock_guard guard(_writeLock);
if ( ! file.CheckedWrite(os.data(), os.size()) ) {
throw runtime_error(handleWriteError("Failed writing the entry.", file, byteSize(), chunk.range(), os.size()));
}
diff --git a/searchlib/src/vespa/searchlib/transactionlog/domainpart.h b/searchlib/src/vespa/searchlib/transactionlog/domainpart.h
index 31d6938b654..a956932be19 100644
--- a/searchlib/src/vespa/searchlib/transactionlog/domainpart.h
+++ b/searchlib/src/vespa/searchlib/transactionlog/domainpart.h
@@ -3,11 +3,11 @@
#include "common.h"
#include "ichunk.h"
-#include <vespa/vespalib/util/sync.h>
#include <vespa/vespalib/util/memory.h>
#include <map>
#include <vector>
#include <atomic>
+#include <mutex>
class FastOS_FileInterface;
@@ -34,7 +34,7 @@ public:
SerialNumRange range() const { return _range; }
SerialNum getSynced() const {
- vespalib::LockGuard guard(_writeLock);
+ std::lock_guard guard(_writeLock);
return _syncedSerial;
}
@@ -74,8 +74,8 @@ private:
typedef std::map<SerialNum, Packet> PacketList;
const Encoding _encoding;
const uint8_t _compressionLevel;
- vespalib::Lock _lock;
- vespalib::Lock _fileLock;
+ std::mutex _lock;
+ std::mutex _fileLock;
SerialNumRange _range;
size_t _sz;
std::atomic<uint64_t> _byteSize;
@@ -84,7 +84,7 @@ private:
std::unique_ptr<FastOS_FileInterface> _transLog;
SkipList _skipList;
uint32_t _headerLen;
- vespalib::Lock _writeLock;
+ mutable std::mutex _writeLock;
// Protected by _writeLock
SerialNum _writtenSerial;
SerialNum _syncedSerial;
diff --git a/searchlib/src/vespa/searchlib/transactionlog/session.cpp b/searchlib/src/vespa/searchlib/transactionlog/session.cpp
index c91b719be37..3aedeb11121 100644
--- a/searchlib/src/vespa/searchlib/transactionlog/session.cpp
+++ b/searchlib/src/vespa/searchlib/transactionlog/session.cpp
@@ -3,8 +3,9 @@
#include "domain.h"
#include "domainpart.h"
#include <vespa/fastlib/io/bufferedfile.h>
-#include <vespa/log/log.h>
+#include <cassert>
+#include <vespa/log/log.h>
LOG_SETUP(".transactionlog.session");
using vespalib::LockGuard;
diff --git a/searchlib/src/vespa/searchlib/transactionlog/session.h b/searchlib/src/vespa/searchlib/transactionlog/session.h
index ddbe218ed4e..ea78907da90 100644
--- a/searchlib/src/vespa/searchlib/transactionlog/session.h
+++ b/searchlib/src/vespa/searchlib/transactionlog/session.h
@@ -3,7 +3,6 @@
#include "common.h"
#include <vespa/vespalib/util/executor.h>
-#include <vespa/vespalib/util/sync.h>
#include <chrono>
#include <deque>
#include <atomic>
diff --git a/searchlib/src/vespa/searchlib/transactionlog/translogclient.h b/searchlib/src/vespa/searchlib/transactionlog/translogclient.h
index 289a0fcb8c0..c232dfdad69 100644
--- a/searchlib/src/vespa/searchlib/transactionlog/translogclient.h
+++ b/searchlib/src/vespa/searchlib/transactionlog/translogclient.h
@@ -3,10 +3,10 @@
#include "client_common.h"
#include "client_session.h"
-#include <vespa/vespalib/util/sync.h>
#include <vespa/fnet/frt/invokable.h>
#include <map>
#include <vector>
+#include <mutex>
class FNET_Transport;
class FRT_Supervisor;
@@ -58,7 +58,7 @@ private:
vespalib::string _rpcTarget;
SessionMap _sessions;
//Brute force lock for subscriptions. For multithread safety.
- vespalib::Lock _lock;
+ std::mutex _lock;
std::unique_ptr<FastOS_ThreadPool> _threadPool;
std::unique_ptr<FNET_Transport> _transport;
std::unique_ptr<FRT_Supervisor> _supervisor;
diff --git a/slobrok/src/tests/configure/configure.cpp b/slobrok/src/tests/configure/configure.cpp
index aa9826045ef..0e5b68053c8 100644
--- a/slobrok/src/tests/configure/configure.cpp
+++ b/slobrok/src/tests/configure/configure.cpp
@@ -5,11 +5,11 @@
#include <vespa/slobrok/sbregister.h>
#include <vespa/slobrok/server/slobrokserver.h>
#include <vespa/config/config.h>
+#include <vespa/config/common/configcontext.h>
#include <vespa/config-slobroks.h>
#include <vespa/fnet/transport.h>
#include <vespa/fnet/frt/supervisor.h>
#include <vespa/vespalib/util/host_name.h>
-#include <sstream>
#include <algorithm>
#include <iostream>
@@ -125,7 +125,7 @@ TEST("configure_test") {
set.addBuilder("client2", &cli2Builder);
set.addBuilder("client3", &cli3Builder);
- config::IConfigContext::SP cfgCtx(new config::ConfigContext(set));
+ auto cfgCtx = std::make_shared<config::ConfigContext>(set);
ConfigShim srvConfig1(18524, "server1", cfgCtx);
ConfigShim srvConfig2(18525, "server2", cfgCtx);
diff --git a/slobrok/src/tests/mirrorapi/mirrorapi.cpp b/slobrok/src/tests/mirrorapi/mirrorapi.cpp
index 53e194fad2d..4126f34716f 100644
--- a/slobrok/src/tests/mirrorapi/mirrorapi.cpp
+++ b/slobrok/src/tests/mirrorapi/mirrorapi.cpp
@@ -140,7 +140,7 @@ Test::Main()
FastOS_ThreadPool threadPool(0x10000);
FNET_Transport transport;
FRT_Supervisor supervisor(&transport);
- MirrorAPI mirror(supervisor, config::ConfigUri::createFromInstance(specBuilder));
+ MirrorAPI mirror(supervisor, slobrok::ConfiguratorFactory(config::ConfigUri::createFromInstance(specBuilder)));
EXPECT_TRUE(!mirror.ready());
transport.Start(&threadPool);
std::this_thread::sleep_for(1s);
diff --git a/slobrok/src/vespa/slobrok/cfg.h b/slobrok/src/vespa/slobrok/cfg.h
index 173f08c3227..db83790677a 100644
--- a/slobrok/src/vespa/slobrok/cfg.h
+++ b/slobrok/src/vespa/slobrok/cfg.h
@@ -31,9 +31,9 @@ class ConfiguratorFactory {
private:
config::ConfigUri _uri;
public:
- ConfiguratorFactory(const config::ConfigUri & uri);
+ explicit ConfiguratorFactory(const config::ConfigUri & uri);
// Convenience. Might belong somewhere else
- ConfiguratorFactory(const std::vector<std::string> & spec);
+ explicit ConfiguratorFactory(const std::vector<std::string> & spec);
Configurator::UP create(Configurable &target) const;
};
diff --git a/slobrok/src/vespa/slobrok/sblist.cpp b/slobrok/src/vespa/slobrok/sblist.cpp
index 9fc58aa2974..e7528fb6db2 100644
--- a/slobrok/src/vespa/slobrok/sblist.cpp
+++ b/slobrok/src/vespa/slobrok/sblist.cpp
@@ -5,7 +5,7 @@
#include <vespa/log/log.h>
LOG_SETUP(".slobrok.list");
-using vespalib::LockGuard;
+using LockGuard = std::lock_guard<std::mutex>;
namespace slobrok::api {
@@ -83,7 +83,7 @@ SlobrokList::setup(const std::vector<std::string> &specList)
_slobrokSpecs.push_back(specList[i]);
}
- vespalib::RandomGen randomizer(time(NULL));
+ vespalib::RandomGen randomizer(time(nullptr));
// randomize order
for (size_t i = 0; i + 1 < cfgSz; ++i) {
size_t lim = cfgSz - i;
diff --git a/slobrok/src/vespa/slobrok/sblist.h b/slobrok/src/vespa/slobrok/sblist.h
index e5f31c23e5b..08328b99d1a 100644
--- a/slobrok/src/vespa/slobrok/sblist.h
+++ b/slobrok/src/vespa/slobrok/sblist.h
@@ -2,7 +2,6 @@
#pragma once
#include "cfg.h"
-#include <vespa/vespalib/util/sync.h>
namespace slobrok::api {
@@ -42,7 +41,7 @@ public:
/** check if the list contains a given spec */
bool contains(const std::string &spec);
private:
- vespalib::Lock _lock;
+ std::mutex _lock;
std::vector<std::string> _slobrokSpecs;
size_t _nextSpec;
size_t _currSpec;
diff --git a/slobrok/src/vespa/slobrok/sbmirror.cpp b/slobrok/src/vespa/slobrok/sbmirror.cpp
index f0a810dad10..855ed4dd82d 100644
--- a/slobrok/src/vespa/slobrok/sbmirror.cpp
+++ b/slobrok/src/vespa/slobrok/sbmirror.cpp
@@ -55,7 +55,7 @@ MirrorAPI::SpecList
MirrorAPI::lookup(const std::string & pattern) const
{
SpecList ret;
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
SpecList::const_iterator end = _specs.end();
for (SpecList::const_iterator it = _specs.begin(); it != end; ++it) {
if (match(it->first.c_str(), pattern.c_str())) {
@@ -104,7 +104,7 @@ void
MirrorAPI::updateTo(SpecList& newSpecs, uint32_t newGen)
{
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
std::swap(newSpecs, _specs);
_updates.add();
}
@@ -117,7 +117,7 @@ MirrorAPI::updateTo(SpecList& newSpecs, uint32_t newGen)
bool
MirrorAPI::ready() const
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
return _updates.getAsInt() != 0;
}
diff --git a/slobrok/src/vespa/slobrok/sbmirror.h b/slobrok/src/vespa/slobrok/sbmirror.h
index 152886fc02e..437ef334af6 100644
--- a/slobrok/src/vespa/slobrok/sbmirror.h
+++ b/slobrok/src/vespa/slobrok/sbmirror.h
@@ -88,7 +88,7 @@ private:
void reSched(double seconds);
FRT_Supervisor &_orb;
- mutable vespalib::Lock _lock;
+ mutable std::mutex _lock;
bool _reqPending;
bool _scheduled;
bool _reqDone;
diff --git a/staging_vespalib/CMakeLists.txt b/staging_vespalib/CMakeLists.txt
index f2f8a41b68d..efb57618823 100644
--- a/staging_vespalib/CMakeLists.txt
+++ b/staging_vespalib/CMakeLists.txt
@@ -23,7 +23,6 @@ vespa_define_module(
src/tests/floatingpointtype
src/tests/growablebytebuffer
src/tests/json
- src/tests/librarypool
src/tests/memorydatastore
src/tests/metrics
src/tests/objectdump
diff --git a/staging_vespalib/src/tests/librarypool/.gitignore b/staging_vespalib/src/tests/librarypool/.gitignore
deleted file mode 100644
index 1a1aea2fda0..00000000000
--- a/staging_vespalib/src/tests/librarypool/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-staging_vespalib_librarypool_test_app
diff --git a/staging_vespalib/src/tests/librarypool/CMakeLists.txt b/staging_vespalib/src/tests/librarypool/CMakeLists.txt
deleted file mode 100644
index 83e1e92e680..00000000000
--- a/staging_vespalib/src/tests/librarypool/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_executable(staging_vespalib_librarypool_test_app TEST
- SOURCES
- librarypool_test.cpp
- DEPENDS
- staging_vespalib
-)
-vespa_add_test(NAME staging_vespalib_librarypool_test_app COMMAND staging_vespalib_librarypool_test_app)
diff --git a/staging_vespalib/src/tests/librarypool/librarypool_test.cpp b/staging_vespalib/src/tests/librarypool/librarypool_test.cpp
deleted file mode 100644
index adefdf3aa6b..00000000000
--- a/staging_vespalib/src/tests/librarypool/librarypool_test.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/vespalib/testkit/testapp.h>
-#include <vespa/vespalib/util/librarypool.h>
-#include <vespa/vespalib/util/exceptions.h>
-
-using namespace vespalib;
-
-class Test : public TestApp
-{
-public:
- int Main() override;
-};
-
-int
-Test::Main()
-{
- TEST_INIT("librarypool_test");
- LibraryPool p;
- ASSERT_TRUE(p.get("z") == NULL);
- p.loadLibrary("z");
- ASSERT_TRUE(p.get("z") != NULL);
- ASSERT_TRUE(p.get("z")->GetSymbol("some_symbol_that_is_not_there") == NULL);
- ASSERT_TRUE(p.get("z")->GetSymbol("compress") != NULL);
- try {
- p.loadLibrary("not_found");
- ASSERT_TRUE(false);
- } catch (const IllegalArgumentException & e) {
- ASSERT_TRUE(p.get("not_found") == NULL);
- }
- {
- const LibraryPool & c(p);
- ASSERT_TRUE(c.get("z") != NULL);
- ASSERT_TRUE(c.get("not_found") == NULL);
- }
- TEST_DONE();
-}
-
-TEST_APPHOOK(Test)
diff --git a/staging_vespalib/src/tests/metrics/mock_tick.h b/staging_vespalib/src/tests/metrics/mock_tick.h
index 3f244ea6c9f..d2e985b5ba3 100644
--- a/staging_vespalib/src/tests/metrics/mock_tick.h
+++ b/staging_vespalib/src/tests/metrics/mock_tick.h
@@ -15,8 +15,9 @@ class MockTick : public Tick {
private:
using Guard = std::unique_lock<std::mutex>;
struct Value {
- TimeStamp value{0.0};
- bool valid{false};
+ Value() noexcept : value(0.0), valid(false) {}
+ TimeStamp value;
+ bool valid;
};
TimeStamp _first_value;
@@ -55,7 +56,7 @@ private:
}
public:
- MockTick(TimeStamp first_value)
+ explicit MockTick(TimeStamp first_value) noexcept
: _first_value(first_value), _lock(), _cond(), _alive(true), _prev(), _next() {}
TimeStamp first() override { return _first_value; }
TimeStamp next(TimeStamp prev) override {
@@ -81,7 +82,7 @@ class TickProxy : public Tick {
private:
std::shared_ptr<Tick> _tick;
public:
- TickProxy(std::shared_ptr<Tick> tick) : _tick(std::move(tick)) {}
+ explicit TickProxy(std::shared_ptr<Tick> tick) noexcept : _tick(std::move(tick)) {}
TimeStamp first() override { return _tick->first(); }
TimeStamp next(TimeStamp prev) override { return _tick->next(prev); }
bool alive() const override { return _tick->alive(); }
diff --git a/staging_vespalib/src/tests/polymorphicarray/polymorphicarray_test.cpp b/staging_vespalib/src/tests/polymorphicarray/polymorphicarray_test.cpp
index e3ff7533d58..49bc52d6239 100644
--- a/staging_vespalib/src/tests/polymorphicarray/polymorphicarray_test.cpp
+++ b/staging_vespalib/src/tests/polymorphicarray/polymorphicarray_test.cpp
@@ -7,7 +7,7 @@ using namespace vespalib;
class A {
public:
- virtual ~A() { }
+ virtual ~A() = default;
virtual void assign(const A & rhs) { (void) rhs; assert(false); } // Required by the primitive array.
virtual A * clone() const { assert(false); return nullptr; } // Required for the complex array.
@@ -19,7 +19,7 @@ public:
class Primitive : public A
{
public:
- Primitive(size_t v=11) : _v(v) { }
+ Primitive(size_t v=11) noexcept : _v(v) { }
size_t value() const { return _v; }
bool operator == (const A & rhs) const override {
return dynamic_cast<const Primitive &>(rhs).value() == value();
@@ -38,7 +38,7 @@ private:
class Complex : public A
{
public:
- Complex(size_t v=11) : _v(v) { }
+ Complex(size_t v=11) noexcept : _v(v) { }
size_t value() const { return _v; }
bool operator == (const A & rhs) const override {
return dynamic_cast<const Complex &>(rhs).value() == value();
diff --git a/staging_vespalib/src/tests/sequencedtaskexecutor/adaptive_sequenced_executor_test.cpp b/staging_vespalib/src/tests/sequencedtaskexecutor/adaptive_sequenced_executor_test.cpp
index 2ca49105610..e75cdd09c8c 100644
--- a/staging_vespalib/src/tests/sequencedtaskexecutor/adaptive_sequenced_executor_test.cpp
+++ b/staging_vespalib/src/tests/sequencedtaskexecutor/adaptive_sequenced_executor_test.cpp
@@ -31,7 +31,7 @@ public:
int _fail;
int _val;
- TestObj()
+ TestObj() noexcept
: _m(),
_cv(),
_done(0),
diff --git a/staging_vespalib/src/tests/sequencedtaskexecutor/foregroundtaskexecutor_test.cpp b/staging_vespalib/src/tests/sequencedtaskexecutor/foregroundtaskexecutor_test.cpp
index a2671bb81a7..03ec64b771e 100644
--- a/staging_vespalib/src/tests/sequencedtaskexecutor/foregroundtaskexecutor_test.cpp
+++ b/staging_vespalib/src/tests/sequencedtaskexecutor/foregroundtaskexecutor_test.cpp
@@ -33,7 +33,7 @@ public:
int _fail;
int _val;
- TestObj()
+ TestObj() noexcept
: _m(),
_cv(),
_done(0),
diff --git a/staging_vespalib/src/tests/sequencedtaskexecutor/sequencedtaskexecutor_test.cpp b/staging_vespalib/src/tests/sequencedtaskexecutor/sequencedtaskexecutor_test.cpp
index df94e70f9d6..29b25cd0471 100644
--- a/staging_vespalib/src/tests/sequencedtaskexecutor/sequencedtaskexecutor_test.cpp
+++ b/staging_vespalib/src/tests/sequencedtaskexecutor/sequencedtaskexecutor_test.cpp
@@ -33,7 +33,7 @@ public:
int _fail;
int _val;
- TestObj()
+ TestObj() noexcept
: _m(),
_cv(),
_done(0),
diff --git a/staging_vespalib/src/vespa/vespalib/metrics/dummy_metrics_manager.cpp b/staging_vespalib/src/vespa/vespalib/metrics/dummy_metrics_manager.cpp
index cd7a3abb1eb..7909ec7486e 100644
--- a/staging_vespalib/src/vespa/vespalib/metrics/dummy_metrics_manager.cpp
+++ b/staging_vespalib/src/vespa/vespalib/metrics/dummy_metrics_manager.cpp
@@ -1,10 +1,9 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "dummy_metrics_manager.h"
-namespace vespalib {
-namespace metrics {
+namespace vespalib::metrics {
-DummyMetricsManager::~DummyMetricsManager() {}
+DummyMetricsManager::~DummyMetricsManager() = default;
Snapshot
DummyMetricsManager::snapshot()
@@ -20,5 +19,4 @@ DummyMetricsManager::totalSnapshot()
return snap;
}
-} // namespace vespalib::metrics
-} // namespace vespalib
+}
diff --git a/staging_vespalib/src/vespa/vespalib/metrics/dummy_metrics_manager.h b/staging_vespalib/src/vespa/vespalib/metrics/dummy_metrics_manager.h
index 6aeb1137732..1536888014a 100644
--- a/staging_vespalib/src/vespa/vespalib/metrics/dummy_metrics_manager.h
+++ b/staging_vespalib/src/vespa/vespalib/metrics/dummy_metrics_manager.h
@@ -10,8 +10,7 @@
#include "metrics_manager.h"
#include "clock.h"
-namespace vespalib {
-namespace metrics {
+namespace vespalib::metrics {
/**
* Dummy manager that discards everything, use
@@ -21,9 +20,9 @@ namespace metrics {
class DummyMetricsManager : public MetricsManager
{
protected:
- DummyMetricsManager() {}
+ DummyMetricsManager() noexcept {}
public:
- ~DummyMetricsManager();
+ ~DummyMetricsManager() override;
static std::shared_ptr<MetricsManager> create() {
return std::shared_ptr<MetricsManager>(new DummyMetricsManager());
@@ -58,5 +57,4 @@ public:
void sample(Gauge::Measurement) override {}
};
-} // namespace vespalib::metrics
-} // namespace vespalib
+}
diff --git a/staging_vespalib/src/vespa/vespalib/net/simple_component_config_producer.cpp b/staging_vespalib/src/vespa/vespalib/net/simple_component_config_producer.cpp
index d016b052dae..d4fe0ef43e1 100644
--- a/staging_vespalib/src/vespa/vespalib/net/simple_component_config_producer.cpp
+++ b/staging_vespalib/src/vespa/vespalib/net/simple_component_config_producer.cpp
@@ -10,27 +10,28 @@ SimpleComponentConfigProducer::SimpleComponentConfigProducer()
{
}
+SimpleComponentConfigProducer::~SimpleComponentConfigProducer() = default;
+
void
SimpleComponentConfigProducer::addConfig(const Config &config)
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_state.insert(std::make_pair(config.name, config)).first->second = config;
}
void
SimpleComponentConfigProducer::removeConfig(const vespalib::string &name)
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_state.erase(name);
}
void
SimpleComponentConfigProducer::getComponentConfig(Consumer &consumer)
{
- typedef std::map<vespalib::string, Config>::const_iterator ITR;
- LockGuard guard(_lock);
- for (ITR itr = _state.begin(); itr != _state.end(); ++itr) {
- consumer.add(itr->second);
+ std::lock_guard guard(_lock);
+ for (const auto & entry : _state) {
+ consumer.add(entry.second);
}
}
diff --git a/staging_vespalib/src/vespa/vespalib/net/simple_component_config_producer.h b/staging_vespalib/src/vespa/vespalib/net/simple_component_config_producer.h
index 5783139c9d5..70dd00a8792 100644
--- a/staging_vespalib/src/vespa/vespalib/net/simple_component_config_producer.h
+++ b/staging_vespalib/src/vespa/vespalib/net/simple_component_config_producer.h
@@ -3,19 +3,20 @@
#pragma once
#include "component_config_producer.h"
-#include <vespa/vespalib/util/sync.h>
#include <map>
+#include <mutex>
namespace vespalib {
class SimpleComponentConfigProducer : public ComponentConfigProducer
{
private:
- Lock _lock;
+ std::mutex _lock;
std::map<vespalib::string, Config> _state;
public:
SimpleComponentConfigProducer();
+ ~SimpleComponentConfigProducer() override;
void addConfig(const Config &config);
void removeConfig(const vespalib::string &name);
void getComponentConfig(Consumer &consumer) override;
diff --git a/staging_vespalib/src/vespa/vespalib/net/simple_health_producer.cpp b/staging_vespalib/src/vespa/vespalib/net/simple_health_producer.cpp
index 651dab97e68..a25888399c1 100644
--- a/staging_vespalib/src/vespa/vespalib/net/simple_health_producer.cpp
+++ b/staging_vespalib/src/vespa/vespalib/net/simple_health_producer.cpp
@@ -4,7 +4,6 @@
#include <vespa/defaults.h>
#include <fcntl.h>
#include <sys/stat.h>
-#include <sys/types.h>
#include <unistd.h>
namespace {
@@ -51,28 +50,26 @@ SimpleHealthProducer::SimpleHealthProducer()
setOk();
}
-SimpleHealthProducer::~SimpleHealthProducer()
-{
-}
+SimpleHealthProducer::~SimpleHealthProducer() = default;
void
SimpleHealthProducer::setOk()
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_health = Health(true, "All OK");
}
void
SimpleHealthProducer::setFailed(const vespalib::string &msg)
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_health = Health(false, msg);
}
HealthProducer::Health
SimpleHealthProducer::getHealth() const
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
if (_health.ok && diskFailed()) {
return Health(false, "disk ping failed");
}
diff --git a/staging_vespalib/src/vespa/vespalib/net/simple_health_producer.h b/staging_vespalib/src/vespa/vespalib/net/simple_health_producer.h
index 90fe2489b0a..fc89f5c7644 100644
--- a/staging_vespalib/src/vespa/vespalib/net/simple_health_producer.h
+++ b/staging_vespalib/src/vespa/vespalib/net/simple_health_producer.h
@@ -3,19 +3,19 @@
#pragma once
#include "health_producer.h"
-#include <vespa/vespalib/util/sync.h>
+#include <mutex>
namespace vespalib {
class SimpleHealthProducer : public HealthProducer
{
private:
- Lock _lock;
+ mutable std::mutex _lock;
HealthProducer::Health _health;
public:
SimpleHealthProducer();
- ~SimpleHealthProducer();
+ ~SimpleHealthProducer() override;
void setOk();
void setFailed(const vespalib::string &msg);
Health getHealth() const override;
diff --git a/staging_vespalib/src/vespa/vespalib/net/simple_metrics_producer.cpp b/staging_vespalib/src/vespa/vespalib/net/simple_metrics_producer.cpp
index 97be2a61235..b39bc96a5b6 100644
--- a/staging_vespalib/src/vespa/vespalib/net/simple_metrics_producer.cpp
+++ b/staging_vespalib/src/vespa/vespalib/net/simple_metrics_producer.cpp
@@ -11,35 +11,33 @@ SimpleMetricsProducer::SimpleMetricsProducer()
{
}
-SimpleMetricsProducer::~SimpleMetricsProducer()
-{
-}
+SimpleMetricsProducer::~SimpleMetricsProducer() = default;
void
SimpleMetricsProducer::setMetrics(const vespalib::string &metrics)
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_metrics = metrics;
}
vespalib::string
SimpleMetricsProducer::getMetrics(const vespalib::string &)
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
return _metrics;
}
void
SimpleMetricsProducer::setTotalMetrics(const vespalib::string &metrics)
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_totalMetrics = metrics;
}
vespalib::string
SimpleMetricsProducer::getTotalMetrics(const vespalib::string &)
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
return _totalMetrics;
}
diff --git a/staging_vespalib/src/vespa/vespalib/net/simple_metrics_producer.h b/staging_vespalib/src/vespa/vespalib/net/simple_metrics_producer.h
index 1dd1452c32f..fdcf1dce6b6 100644
--- a/staging_vespalib/src/vespa/vespalib/net/simple_metrics_producer.h
+++ b/staging_vespalib/src/vespa/vespalib/net/simple_metrics_producer.h
@@ -3,24 +3,24 @@
#pragma once
#include "metrics_producer.h"
-#include <vespa/vespalib/util/sync.h>
+#include <mutex>
namespace vespalib {
class SimpleMetricsProducer : public MetricsProducer
{
private:
- Lock _lock;
+ std::mutex _lock;
vespalib::string _metrics;
vespalib::string _totalMetrics;
public:
SimpleMetricsProducer();
- ~SimpleMetricsProducer();
+ ~SimpleMetricsProducer() override;
void setMetrics(const vespalib::string &metrics);
- virtual vespalib::string getMetrics(const vespalib::string &consumer) override;
+ vespalib::string getMetrics(const vespalib::string &consumer) override;
void setTotalMetrics(const vespalib::string &metrics);
- virtual vespalib::string getTotalMetrics(const vespalib::string &consumer) override;
+ vespalib::string getTotalMetrics(const vespalib::string &consumer) override;
};
} // namespace vespalib
diff --git a/staging_vespalib/src/vespa/vespalib/objects/identifiable.hpp b/staging_vespalib/src/vespa/vespalib/objects/identifiable.hpp
index 2c34ba306ab..b1c4a128feb 100644
--- a/staging_vespalib/src/vespa/vespalib/objects/identifiable.hpp
+++ b/staging_vespalib/src/vespa/vespalib/objects/identifiable.hpp
@@ -46,16 +46,16 @@ class IdentifiablePtr : public CloneablePtr<T>
{
public:
IdentifiablePtr(const T &t) : CloneablePtr<T>(t.clone()) {}
- IdentifiablePtr(IdentifiablePtr &&) = default;
- IdentifiablePtr & operator = (IdentifiablePtr &&) = default;
+ IdentifiablePtr(IdentifiablePtr &&) noexcept = default;
+ IdentifiablePtr & operator = (IdentifiablePtr &&) noexcept = default;
IdentifiablePtr(const IdentifiablePtr &) = default;
IdentifiablePtr & operator = (const IdentifiablePtr &) = default;
- IdentifiablePtr(T * p=NULL) : CloneablePtr<T>(p) { }
- IdentifiablePtr(std::unique_ptr<T> &&rhs)
+ IdentifiablePtr(T * p=NULL) noexcept : CloneablePtr<T>(p) { }
+ IdentifiablePtr(std::unique_ptr<T> &&rhs) noexcept
: CloneablePtr<T>(std::move(rhs))
{
}
- IdentifiablePtr &operator=(std::unique_ptr<T> &&rhs)
+ IdentifiablePtr &operator=(std::unique_ptr<T> &&rhs) noexcept
{
CloneablePtr<T>::operator=(std::move(rhs));
return *this;
diff --git a/staging_vespalib/src/vespa/vespalib/stllike/cache.h b/staging_vespalib/src/vespa/vespalib/stllike/cache.h
index 99b601f7c3c..798fdb70138 100644
--- a/staging_vespalib/src/vespa/vespalib/stllike/cache.h
+++ b/staging_vespalib/src/vespa/vespalib/stllike/cache.h
@@ -2,7 +2,6 @@
#pragma once
#include <vespa/vespalib/stllike/lrucache_map.h>
-#include <vespa/vespalib/util/sync.h>
#include <atomic>
namespace vespalib {
@@ -42,7 +41,7 @@ struct CacheParam : public P
template< typename P >
class cache : private lrucache_map<P>
{
- typedef lrucache_map<P> Lru;
+ using Lru = lrucache_map<P>;
protected:
typedef typename P::BackingStore BackingStore;
typedef typename P::Hash Hash;
@@ -120,11 +119,12 @@ public:
size_t getlookup() const { return _lookup; }
protected:
- vespalib::LockGuard getGuard();
- void invalidate(const vespalib::LockGuard & guard, const K & key);
- bool hasKey(const vespalib::LockGuard & guard, const K & key) const;
- bool hasLock() const;
+ using UniqueLock = std::unique_lock<std::mutex>;
+ UniqueLock getGuard();
+ void invalidate(const UniqueLock & guard, const K & key);
+ bool hasKey(const UniqueLock & guard, const K & key) const;
private:
+ void verifyHashLock(const UniqueLock & guard) const;
/**
* Called when an object is inserted, to see if the LRU should be removed.
* Default is to obey the maxsize given in constructor.
@@ -133,7 +133,7 @@ private:
*/
bool removeOldest(const value_type & v) override;
size_t calcSize(const K & k, const V & v) const { return sizeof(value_type) + _sizeK(k) + _sizeV(v); }
- vespalib::Lock & getLock(const K & k) {
+ std::mutex & getLock(const K & k) {
size_t h(_hasher(k));
return _addLocks[h%(sizeof(_addLocks)/sizeof(_addLocks[0]))];
}
@@ -153,9 +153,9 @@ private:
mutable size_t _invalidate;
mutable size_t _lookup;
BackingStore & _store;
- vespalib::Lock _hashLock;
+ mutable std::mutex _hashLock;
/// Striped locks that can be used for having a locked access to the backing store.
- vespalib::Lock _addLocks[113];
+ std::mutex _addLocks[113];
};
}
diff --git a/staging_vespalib/src/vespa/vespalib/stllike/cache.hpp b/staging_vespalib/src/vespa/vespalib/stllike/cache.hpp
index 906621d623c..719169ba747 100644
--- a/staging_vespalib/src/vespa/vespalib/stllike/cache.hpp
+++ b/staging_vespalib/src/vespa/vespalib/stllike/cache.hpp
@@ -30,25 +30,19 @@ cache<P>::setCapacityBytes(size_t sz) {
template< typename P >
void
cache<P>::invalidate(const K & key) {
- vespalib::LockGuard guard(_hashLock);
+ UniqueLock guard(_hashLock);
invalidate(guard, key);
}
template< typename P >
bool
cache<P>::hasKey(const K & key) const {
- vespalib::LockGuard guard(_hashLock);
+ UniqueLock guard(_hashLock);
return hasKey(guard, key);
}
template< typename P >
-bool
-cache<P>::hasLock() const {
- return TryLock(_hashLock).hasLock();
-}
-
-template< typename P >
-cache<P>::~cache() { }
+cache<P>::~cache() = default;
template< typename P >
cache<P>::cache(BackingStore & b, size_t maxBytes) :
@@ -79,9 +73,9 @@ cache<P>::removeOldest(const value_type & v) {
}
template< typename P >
-vespalib::LockGuard
+std::unique_lock<std::mutex>
cache<P>::getGuard() {
- return vespalib::LockGuard(_hashLock);
+ return UniqueLock(_hashLock);
}
template< typename P >
@@ -89,7 +83,7 @@ typename P::Value
cache<P>::read(const K & key)
{
{
- vespalib::LockGuard guard(_hashLock);
+ std::lock_guard guard(_hashLock);
if (Lru::hasKey(key)) {
_hit++;
return (*this)[key];
@@ -98,9 +92,9 @@ cache<P>::read(const K & key)
}
}
- vespalib::LockGuard storeGuard(getLock(key));
+ std::lock_guard storeGuard(getLock(key));
{
- vespalib::LockGuard guard(_hashLock);
+ std::lock_guard guard(_hashLock);
if (Lru::hasKey(key)) {
// Somebody else just fetched it ahead of me.
_race++;
@@ -109,7 +103,7 @@ cache<P>::read(const K & key)
}
V value;
if (_store.read(key, value)) {
- vespalib::LockGuard guard(_hashLock);
+ std::lock_guard guard(_hashLock);
Lru::insert(key, value);
_sizeBytes += calcSize(key, value);
_insert++;
@@ -124,9 +118,9 @@ void
cache<P>::write(const K & key, V value)
{
size_t newSize = calcSize(key, value);
- vespalib::LockGuard storeGuard(getLock(key));
+ std::lock_guard storeGuard(getLock(key));
{
- vespalib::LockGuard guard(_hashLock);
+ std::lock_guard guard(_hashLock);
if (Lru::hasKey(key)) {
_sizeBytes -= calcSize(key, (*this)[key]);
_update++;
@@ -135,7 +129,7 @@ cache<P>::write(const K & key, V value)
_store.write(key, value);
{
- vespalib::LockGuard guard(_hashLock);
+ std::lock_guard guard(_hashLock);
(*this)[key] = std::move(value);
_sizeBytes += newSize;
_write++;
@@ -146,17 +140,16 @@ template< typename P >
void
cache<P>::erase(const K & key)
{
- vespalib::LockGuard storeGuard(getLock(key));
+ std::lock_guard storeGuard(getLock(key));
invalidate(key);
_store.erase(key);
}
template< typename P >
void
-cache<P>::invalidate(const vespalib::LockGuard & guard, const K & key)
+cache<P>::invalidate(const UniqueLock & guard, const K & key)
{
- assert(guard.locks(_hashLock));
- (void) guard;
+ verifyHashLock(guard);
if (Lru::hasKey(key)) {
_sizeBytes -= calcSize(key, (*this)[key]);
_invalidate++;
@@ -166,13 +159,19 @@ cache<P>::invalidate(const vespalib::LockGuard & guard, const K & key)
template< typename P >
bool
-cache<P>::hasKey(const vespalib::LockGuard & guard, const K & key) const
+cache<P>::hasKey(const UniqueLock & guard, const K & key) const
{
- (void) guard;
- assert(guard.locks(_hashLock));
+ verifyHashLock(guard);
_lookup++;
return Lru::hasKey(key);
}
+template< typename P >
+void
+cache<P>::verifyHashLock(const UniqueLock & guard) const {
+ assert(guard.mutex() == & _hashLock);
+ assert(guard.owns_lock());
+}
+
}
diff --git a/staging_vespalib/src/vespa/vespalib/util/CMakeLists.txt b/staging_vespalib/src/vespa/vespalib/util/CMakeLists.txt
index 586e06396e7..70f17f76e4c 100644
--- a/staging_vespalib/src/vespa/vespalib/util/CMakeLists.txt
+++ b/staging_vespalib/src/vespa/vespalib/util/CMakeLists.txt
@@ -12,7 +12,6 @@ vespa_add_library(staging_vespalib_vespalib_util OBJECT
jsonexception.cpp
jsonstream.cpp
jsonwriter.cpp
- librarypool.cpp
process_memory_stats.cpp
programoptions.cpp
programoptions_testutils.cpp
diff --git a/staging_vespalib/src/vespa/vespalib/util/document_runnable.cpp b/staging_vespalib/src/vespa/vespalib/util/document_runnable.cpp
index c0a32197c07..0f7e6155276 100644
--- a/staging_vespalib/src/vespa/vespalib/util/document_runnable.cpp
+++ b/staging_vespalib/src/vespa/vespalib/util/document_runnable.cpp
@@ -2,6 +2,7 @@
#include "document_runnable.h"
#include <vespa/vespalib/util/exceptions.h>
+#include <cassert>
namespace document {
diff --git a/staging_vespalib/src/vespa/vespalib/util/librarypool.cpp b/staging_vespalib/src/vespa/vespalib/util/librarypool.cpp
deleted file mode 100644
index 2a3ca21c369..00000000000
--- a/staging_vespalib/src/vespa/vespalib/util/librarypool.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include <vespa/vespalib/util/librarypool.h>
-#include <vespa/vespalib/util/exceptions.h>
-#include <vespa/vespalib/util/stringfmt.h>
-
-namespace vespalib {
-
-LibraryPool::LibraryPool() :
- _libraries(),
- _lock()
-{
-}
-
-LibraryPool::~LibraryPool()
-{
- LockGuard guard(_lock);
- _libraries.clear();
-}
-
-void
-LibraryPool::loadLibrary(stringref libName)
-{
- LockGuard guard(_lock);
- if (_libraries.find(libName) == _libraries.end()) {
- DynamicLibrarySP lib(new FastOS_DynamicLibrary);
- string file(libName);
- if (!lib->Open(file.c_str())) {
- string error = lib->GetLastErrorString();
- throw IllegalArgumentException(make_string("Failed loading dynamic library '%s' due to '%s'.",
- file.c_str(), error.c_str()));
- } else {
- _libraries[libName] = lib;
- }
- }
-}
-
-FastOS_DynamicLibrary *
-LibraryPool::get(stringref name)
-{
- LockGuard guard(_lock);
- LibraryMap::const_iterator found(_libraries.find(name));
- return (found != _libraries.end())
- ? found->second.get()
- : NULL;
-}
-
-const FastOS_DynamicLibrary *
-LibraryPool::get(stringref name) const
-{
- LockGuard guard(_lock);
- LibraryMap::const_iterator found(_libraries.find(name));
- return (found != _libraries.end())
- ? found->second.get()
- : NULL;
-}
-
-}
diff --git a/staging_vespalib/src/vespa/vespalib/util/librarypool.h b/staging_vespalib/src/vespa/vespalib/util/librarypool.h
deleted file mode 100644
index f9149589338..00000000000
--- a/staging_vespalib/src/vespa/vespalib/util/librarypool.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#pragma once
-
-#include <vespa/vespalib/util/sync.h>
-#include <vespa/vespalib/stllike/string.h>
-#include <vespa/fastos/dynamiclibrary.h>
-#include <map>
-
-namespace vespalib {
-
-class LibraryPool
-{
-public:
- LibraryPool();
- ~LibraryPool();
- /**
- * This will load the library with the name given.
- * - It will verify linkage at load time.
- * - Symbols will be private.
- * @param name The name of the library to load. That is without the 'lib' prefix and the '.so' extension.
- * @throws IllegalArgumentException if there are any errors.
- */
- void loadLibrary(stringref name);
- /**
- * Will return the library requested. NULL if not found.
- * @param name The name of the library as given in the @ref loadLibrary call.
- * @return The library that has already been loaded. NULL if not found.
- */
- FastOS_DynamicLibrary *get(stringref name);
- const FastOS_DynamicLibrary *get(stringref name) const;
-private:
- typedef std::shared_ptr<FastOS_DynamicLibrary> DynamicLibrarySP;
- typedef std::map<vespalib::string, DynamicLibrarySP> LibraryMap;
- LibraryMap _libraries;
- Lock _lock;
-};
-
-}
-
diff --git a/staging_vespalib/src/vespa/vespalib/util/scheduledexecutor.cpp b/staging_vespalib/src/vespa/vespalib/util/scheduledexecutor.cpp
index d9b4feda293..3f5b3b79656 100644
--- a/staging_vespalib/src/vespa/vespalib/util/scheduledexecutor.cpp
+++ b/staging_vespalib/src/vespa/vespalib/util/scheduledexecutor.cpp
@@ -45,7 +45,7 @@ ScheduledExecutor::ScheduledExecutor()
ScheduledExecutor::~ScheduledExecutor()
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_transport->ShutDown(true);
_threadPool.Close();
_taskList.clear();
@@ -55,7 +55,7 @@ ScheduledExecutor::~ScheduledExecutor()
void
ScheduledExecutor::scheduleAtFixedRate(vespalib::Executor::Task::UP task, duration delay, duration interval)
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
TimerTaskPtr tTask(new TimerTask(_transport->GetScheduler(), std::move(task), interval));
_taskList.push_back(std::move(tTask));
_taskList.back()->Schedule(to_s(delay));
@@ -64,10 +64,10 @@ ScheduledExecutor::scheduleAtFixedRate(vespalib::Executor::Task::UP task, durati
void
ScheduledExecutor::reset()
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_transport->ShutDown(true);
_taskList.clear();
- _transport.reset(new FNET_Transport());
+ _transport = std::make_unique<FNET_Transport>();
_transport->Start(&_threadPool);
}
diff --git a/staging_vespalib/src/vespa/vespalib/util/scheduledexecutor.h b/staging_vespalib/src/vespa/vespalib/util/scheduledexecutor.h
index 0f052c762a7..0b98a236f74 100644
--- a/staging_vespalib/src/vespa/vespalib/util/scheduledexecutor.h
+++ b/staging_vespalib/src/vespa/vespalib/util/scheduledexecutor.h
@@ -2,7 +2,6 @@
#pragma once
#include <vespa/vespalib/util/executor.h>
-#include <vespa/vespalib/util/sync.h>
#include <vespa/vespalib/util/time.h>
#include <vespa/fastos/thread.h>
#include <vector>
@@ -25,8 +24,8 @@ private:
typedef std::vector<TimerTaskPtr> TaskList;
FastOS_ThreadPool _threadPool;
std::unique_ptr<FNET_Transport> _transport;
- vespalib::Lock _lock;
- TaskList _taskList;
+ std::mutex _lock;
+ TaskList _taskList;
public:
/**
diff --git a/staging_vespalib/src/vespa/vespalib/util/singleexecutor.cpp b/staging_vespalib/src/vespa/vespalib/util/singleexecutor.cpp
index 65857183879..795a7ef1ec3 100644
--- a/staging_vespalib/src/vespa/vespalib/util/singleexecutor.cpp
+++ b/staging_vespalib/src/vespa/vespalib/util/singleexecutor.cpp
@@ -1,7 +1,7 @@
// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "singleexecutor.h"
-#include <vespa/vespalib/util/time.h>
+#include <cassert>
namespace vespalib {
diff --git a/staging_vespalib/src/vespa/vespalib/util/varholder.h b/staging_vespalib/src/vespa/vespalib/util/varholder.h
index fdcc15d1fb4..5b68ffa5582 100644
--- a/staging_vespalib/src/vespa/vespalib/util/varholder.h
+++ b/staging_vespalib/src/vespa/vespalib/util/varholder.h
@@ -2,15 +2,15 @@
#pragma once
-#include <vespa/vespalib/util/sync.h>
+#include <mutex>
namespace vespalib {
template <typename T>
class VarHolder
{
- T _v;
- Lock _lock;
+ T _v;
+ mutable std::mutex _lock;
public:
VarHolder() : _v(), _lock() {}
explicit VarHolder(const T &v) : _v(v), _lock() {}
@@ -21,7 +21,7 @@ public:
void set(const T &v) {
T old;
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
old = _v;
_v = v;
}
@@ -30,7 +30,7 @@ public:
void clear() { set(T()); }
T get() const {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
return _v;
}
};
diff --git a/storage/src/tests/bucketdb/lockablemaptest.cpp b/storage/src/tests/bucketdb/lockablemaptest.cpp
index 709e158e531..527c0a927b4 100644
--- a/storage/src/tests/bucketdb/lockablemaptest.cpp
+++ b/storage/src/tests/bucketdb/lockablemaptest.cpp
@@ -148,7 +148,7 @@ namespace {
template <typename Map>
struct NonConstProcessor {
- typename Map::Decision operator()(int key, A& a) {
+ typename Map::Decision operator() (int key, A& a) const noexcept {
(void) key;
++a._val2;
return Map::UPDATE;
diff --git a/storage/src/tests/common/dummystoragelink.cpp b/storage/src/tests/common/dummystoragelink.cpp
index a747fbcf998..ab70bff3409 100644
--- a/storage/src/tests/common/dummystoragelink.cpp
+++ b/storage/src/tests/common/dummystoragelink.cpp
@@ -1,12 +1,12 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "dummystoragelink.h"
#include <vespa/storageframework/defaultimplementation/clock/realclock.h>
-#include <sys/time.h>
#include <vespa/vespalib/util/exceptions.h>
+#include <cassert>
namespace storage {
-DummyStorageLink* DummyStorageLink::_last(0);
+DummyStorageLink* DummyStorageLink::_last(nullptr);
DummyStorageLink::DummyStorageLink()
: StorageLink("Dummy storage link"),
@@ -37,7 +37,7 @@ DummyStorageLink::~DummyStorageLink()
bool
DummyStorageLink::handleInjectedReply()
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
if (!_injected.empty()) {
sendUp(*_injected.begin());
_injected.pop_front();
@@ -65,7 +65,7 @@ bool DummyStorageLink::onDown(const api::StorageMessage::SP& cmd)
if (isBottom()) {
vespalib::MonitorGuard lock(_waitMonitor);
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_commands.push_back(cmd);
}
lock.broadcast();
@@ -78,7 +78,7 @@ bool DummyStorageLink::onUp(const api::StorageMessage::SP& reply) {
if (isTop()) {
vespalib::MonitorGuard lock(_waitMonitor);
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_replies.push_back(reply);
}
lock.broadcast();
@@ -91,13 +91,13 @@ bool DummyStorageLink::onUp(const api::StorageMessage::SP& reply) {
void DummyStorageLink::injectReply(api::StorageReply* reply)
{
assert(reply);
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_injected.push_back(std::shared_ptr<api::StorageReply>(reply));
}
void DummyStorageLink::reset() {
vespalib::MonitorGuard lock(_waitMonitor);
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_commands.clear();
_replies.clear();
_injected.clear();
diff --git a/storage/src/tests/common/dummystoragelink.h b/storage/src/tests/common/dummystoragelink.h
index 174f8219560..46a1d4ea25f 100644
--- a/storage/src/tests/common/dummystoragelink.h
+++ b/storage/src/tests/common/dummystoragelink.h
@@ -18,7 +18,7 @@ namespace storage {
class DummyStorageLink : public StorageLink {
- mutable vespalib::Lock _lock; // to protect below containers:
+ mutable std::mutex _lock; // to protect below containers:
std::vector<api::StorageMessage::SP> _commands;
std::vector<api::StorageMessage::SP> _replies;
std::list<api::StorageMessage::SP> _injected;
@@ -31,7 +31,7 @@ class DummyStorageLink : public StorageLink {
public:
DummyStorageLink();
- ~DummyStorageLink();
+ ~DummyStorageLink() override;
bool onDown(const api::StorageMessage::SP&) override;
bool onUp(const api::StorageMessage::SP&) override;
@@ -63,21 +63,21 @@ public:
void waitForMessage(const api::MessageType&, int timeout = -1);
api::StorageMessage::SP getCommand(size_t i) const {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
api::StorageMessage::SP ret = _commands[i];
return ret;
}
api::StorageMessage::SP getReply(size_t i) const {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
api::StorageMessage::SP ret = _replies[i];
return ret;
}
size_t getNumCommands() const {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
return _commands.size();
}
size_t getNumReplies() const {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
return _replies.size();
}
@@ -90,7 +90,7 @@ public:
vespalib::MonitorGuard lock(_waitMonitor);
std::vector<api::StorageMessage::SP> retval;
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
retval.swap(_commands);
}
return retval;
@@ -100,7 +100,7 @@ public:
vespalib::MonitorGuard lock(_waitMonitor);
std::vector<api::StorageMessage::SP> retval;
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
retval.swap(_replies);
}
return retval;
diff --git a/storage/src/tests/common/teststorageapp.cpp b/storage/src/tests/common/teststorageapp.cpp
index 1847de0e84f..f2989f88765 100644
--- a/storage/src/tests/common/teststorageapp.cpp
+++ b/storage/src/tests/common/teststorageapp.cpp
@@ -57,9 +57,9 @@ TestStorageApp::TestStorageApp(StorageComponentRegisterImpl::UP compReg,
_compReg.setPriorityConfig(
*config::ConfigGetter<StorageComponent::PriorityConfig>
::getConfig(uri.getConfigId(), uri.getContext()));
- loadTypes.reset(new documentapi::LoadTypeSet(
+ loadTypes = std::make_shared<documentapi::LoadTypeSet>(
*config::ConfigGetter<vespa::config::content::LoadTypeConfig>
- ::getConfig(uri.getConfigId(), uri.getContext())));
+ ::getConfig(uri.getConfigId(), uri.getContext()));
} else {
if (index == 0xffff) index = 0;
loadTypes.reset(new documentapi::LoadTypeSet);
@@ -72,20 +72,18 @@ TestStorageApp::TestStorageApp(StorageComponentRegisterImpl::UP compReg,
_compReg.setDocumentTypeRepo(_docMan.getTypeRepoSP());
_compReg.setLoadTypes(loadTypes);
_compReg.setBucketIdFactory(document::BucketIdFactory());
- lib::Distribution::SP distr(new lib::Distribution(
- lib::Distribution::getDefaultDistributionConfig(
- redundancy, nodeCount)));
+ auto distr = std::make_shared<lib::Distribution>(
+ lib::Distribution::getDefaultDistributionConfig(redundancy, nodeCount));
_compReg.setDistribution(distr);
}
-TestStorageApp::~TestStorageApp() {}
+TestStorageApp::~TestStorageApp() = default;
void
TestStorageApp::setDistribution(Redundancy redundancy, NodeCount nodeCount)
{
- lib::Distribution::SP distr(new lib::Distribution(
- lib::Distribution::getDefaultDistributionConfig(
- redundancy, nodeCount)));
+ auto distr = std::make_shared<lib::Distribution>(
+ lib::Distribution::getDefaultDistributionConfig(redundancy, nodeCount));
_compReg.setDistribution(distr);
}
@@ -98,8 +96,7 @@ TestStorageApp::setTypeRepo(std::shared_ptr<const document::DocumentTypeRepo> re
void
TestStorageApp::setClusterState(const lib::ClusterState& c)
{
- _nodeStateUpdater.setClusterState(
- lib::ClusterState::CSP(new lib::ClusterState(c)));
+ _nodeStateUpdater.setClusterState(std::make_shared<lib::ClusterState>(c));
}
void
@@ -109,8 +106,7 @@ TestStorageApp::waitUntilInitialized(
// Always use real clock for wait timeouts. Component clock may be faked
// in tests
framework::defaultimplementation::RealClock clock;
- framework::MilliSecTime endTime(
- clock.getTimeInMillis() + timeout.getMillis());
+ framework::MilliSecTime endTime(clock.getTimeInMillis() + timeout.getMillis());
while (!isInitialized()) {
std::this_thread::sleep_for(1ms);
framework::MilliSecTime currentTime(clock.getTimeInMillis());
@@ -142,8 +138,7 @@ namespace {
TestServiceLayerApp::TestServiceLayerApp(vespalib::stringref configId)
: TestStorageApp(std::make_unique<ServiceLayerComponentRegisterImpl>(true), // TODO remove B-tree flag once default
lib::NodeType::STORAGE, getIndexFromConfig(configId), configId),
- _compReg(dynamic_cast<ServiceLayerComponentRegisterImpl&>(
- TestStorageApp::getComponentRegister())),
+ _compReg(dynamic_cast<ServiceLayerComponentRegisterImpl&>(TestStorageApp::getComponentRegister())),
_persistenceProvider(),
_partitions(1)
{
@@ -157,8 +152,7 @@ TestServiceLayerApp::TestServiceLayerApp(DiskCount dc, NodeIndex index,
vespalib::stringref configId)
: TestStorageApp(std::make_unique<ServiceLayerComponentRegisterImpl>(true), // TODO remove B-tree flag once default
lib::NodeType::STORAGE, index, configId),
- _compReg(dynamic_cast<ServiceLayerComponentRegisterImpl&>(
- TestStorageApp::getComponentRegister())),
+ _compReg(dynamic_cast<ServiceLayerComponentRegisterImpl&>(TestStorageApp::getComponentRegister())),
_persistenceProvider(),
_partitions(dc)
{
@@ -192,9 +186,7 @@ spi::PersistenceProvider&
TestServiceLayerApp::getPersistenceProvider()
{
if (_persistenceProvider.get() == 0) {
- throw vespalib::IllegalStateException(
- "Persistence provider requested but not initialized.",
- VESPA_STRLOC);
+ throw vespalib::IllegalStateException("Persistence provider requested but not initialized.", VESPA_STRLOC);
}
return *_persistenceProvider;
}
@@ -203,9 +195,7 @@ spi::PartitionStateList&
TestServiceLayerApp::getPartitions()
{
if (_persistenceProvider.get() == 0) {
- throw vespalib::IllegalStateException(
- "Partition list requested but not initialized.",
- VESPA_STRLOC);
+ throw vespalib::IllegalStateException("Partition list requested but not initialized.", VESPA_STRLOC);
}
return _partitions;
}
@@ -224,8 +214,7 @@ namespace {
template<typename T>
const T getConfig(vespalib::stringref configId) {
config::ConfigUri uri(configId);
- return *config::ConfigGetter<T>::getConfig(
- uri.getConfigId(), uri.getContext());
+ return *config::ConfigGetter<T>::getConfig(uri.getConfigId(), uri.getContext());
}
}
@@ -243,8 +232,7 @@ TestDistributorApp::TestDistributorApp(vespalib::stringref configId)
: TestStorageApp(
std::make_unique<DistributorComponentRegisterImpl>(),
lib::NodeType::DISTRIBUTOR, getIndexFromConfig(configId), configId),
- _compReg(dynamic_cast<DistributorComponentRegisterImpl&>(
- TestStorageApp::getComponentRegister())),
+ _compReg(dynamic_cast<DistributorComponentRegisterImpl&>(TestStorageApp::getComponentRegister())),
_lastUniqueTimestampRequested(0),
_uniqueTimestampCounter(0)
{
@@ -252,13 +240,11 @@ TestDistributorApp::TestDistributorApp(vespalib::stringref configId)
configure(configId);
}
-TestDistributorApp::TestDistributorApp(NodeIndex index,
- vespalib::stringref configId)
+TestDistributorApp::TestDistributorApp(NodeIndex index, vespalib::stringref configId)
: TestStorageApp(
std::make_unique<DistributorComponentRegisterImpl>(),
lib::NodeType::DISTRIBUTOR, index, configId),
- _compReg(dynamic_cast<DistributorComponentRegisterImpl&>(
- TestStorageApp::getComponentRegister())),
+ _compReg(dynamic_cast<DistributorComponentRegisterImpl&>(TestStorageApp::getComponentRegister())),
_lastUniqueTimestampRequested(0),
_uniqueTimestampCounter(0)
{
@@ -266,12 +252,12 @@ TestDistributorApp::TestDistributorApp(NodeIndex index,
configure(configId);
}
-TestDistributorApp::~TestDistributorApp() {}
+TestDistributorApp::~TestDistributorApp() = default;
api::Timestamp
TestDistributorApp::getUniqueTimestamp()
{
- vespalib::Lock lock(_accessLock);
+ std::lock_guard guard(_accessLock);
uint64_t timeNow(getClock().getTimeInSeconds().getTime());
if (timeNow == _lastUniqueTimestampRequested) {
++_uniqueTimestampCounter;
diff --git a/storage/src/tests/common/teststorageapp.h b/storage/src/tests/common/teststorageapp.h
index 218e7352f04..03936d37788 100644
--- a/storage/src/tests/common/teststorageapp.h
+++ b/storage/src/tests/common/teststorageapp.h
@@ -141,16 +141,16 @@ class TestDistributorApp : public TestStorageApp,
public UniqueTimeCalculator
{
DistributorComponentRegisterImpl& _compReg;
- vespalib::Lock _accessLock;
+ std::mutex _accessLock;
uint64_t _lastUniqueTimestampRequested;
uint32_t _uniqueTimestampCounter;
void configure(vespalib::stringref configId);
public:
- TestDistributorApp(vespalib::stringref configId = "");
- TestDistributorApp(NodeIndex index, vespalib::stringref configId = "");
- ~TestDistributorApp();
+ explicit TestDistributorApp(vespalib::stringref configId = "");
+ explicit TestDistributorApp(NodeIndex index, vespalib::stringref configId = "");
+ ~TestDistributorApp() override;
DistributorComponentRegisterImpl& getComponentRegister() {
return _compReg;
diff --git a/storage/src/tests/persistence/filestorage/filestormanagertest.cpp b/storage/src/tests/persistence/filestorage/filestormanagertest.cpp
index b7f2cb81956..e510076fe9b 100644
--- a/storage/src/tests/persistence/filestorage/filestormanagertest.cpp
+++ b/storage/src/tests/persistence/filestorage/filestormanagertest.cpp
@@ -2049,4 +2049,24 @@ TEST_F(FileStorManagerTest, get_command_size_is_added_to_metric) {
assert_request_size_set(c, std::move(cmd), thread_metrics_of(*c.manager)->get[defaultLoadType]);
}
+TEST_F(FileStorManagerTest, test_and_set_condition_mismatch_not_counted_as_failure) {
+ TestFileStorComponents c(*this);
+ auto doc = _node->getTestDocMan().createRandomDocument();
+ document::BucketId bucket(16, document::BucketIdFactory().getBucketId(doc->getId()).getRawId());
+ createBucket(bucket, 0);
+ auto cmd = std::make_shared<api::PutCommand>(makeDocumentBucket(bucket), std::move(doc), api::Timestamp(12345));
+ cmd->setCondition(TestAndSetCondition("not testdoctype1"));
+ cmd->setAddress(api::StorageMessageAddress("storage", lib::NodeType::STORAGE, 3));
+ c.top.sendDown(cmd);
+
+ api::PutReply* reply;
+ ASSERT_SINGLE_REPLY(api::PutReply, reply, c.top, _waitTime);
+ EXPECT_EQ(reply->getResult().getResult(), api::ReturnCode::TEST_AND_SET_CONDITION_FAILED);
+
+ auto& metrics = thread_metrics_of(*c.manager)->put[defaultLoadType];
+ EXPECT_EQ(metrics.failed.getValue(), 0);
+ EXPECT_EQ(metrics.test_and_set_failed.getValue(), 1);
+ EXPECT_EQ(thread_metrics_of(*c.manager)->failedOperations.getValue(), 0);
+}
+
} // storage
diff --git a/storage/src/tests/persistence/persistencetestutils.h b/storage/src/tests/persistence/persistencetestutils.h
index 3d25a205017..d4cbd896d11 100644
--- a/storage/src/tests/persistence/persistencetestutils.h
+++ b/storage/src/tests/persistence/persistencetestutils.h
@@ -42,7 +42,7 @@ public:
class NoBucketLock : public FileStorHandler::BucketLockInterface
{
public:
- NoBucketLock(document::Bucket bucket) : _bucket(bucket) { }
+ NoBucketLock(document::Bucket bucket) noexcept : _bucket(bucket) { }
const document::Bucket &getBucket() const override {
return _bucket;
}
diff --git a/storage/src/tests/storageserver/mergethrottlertest.cpp b/storage/src/tests/storageserver/mergethrottlertest.cpp
index 178862d8393..6ac0bfcb5d8 100644
--- a/storage/src/tests/storageserver/mergethrottlertest.cpp
+++ b/storage/src/tests/storageserver/mergethrottlertest.cpp
@@ -216,7 +216,7 @@ void waitUntilMergeQueueIs(MergeThrottler& throttler, std::size_t sz, int timeou
while (true) {
std::size_t count;
{
- vespalib::LockGuard lock(throttler.getStateLock());
+ std::lock_guard lock(throttler.getStateLock());
count = throttler.getMergeQueue().size();
}
if (count == sz) {
diff --git a/storage/src/tests/storageserver/rpc/storage_api_rpc_service_test.cpp b/storage/src/tests/storageserver/rpc/storage_api_rpc_service_test.cpp
index 8228ceb5e79..69d5a827272 100644
--- a/storage/src/tests/storageserver/rpc/storage_api_rpc_service_test.cpp
+++ b/storage/src/tests/storageserver/rpc/storage_api_rpc_service_test.cpp
@@ -265,7 +265,7 @@ struct StorageApiRpcServiceTest : Test {
return recv_as_put;
}
[[nodiscard]] std::shared_ptr<api::PutCommand> send_and_receive_put_command_at_node_1() {
- return send_and_receive_put_command_at_node_1([]([[maybe_unused]] auto& cmd){});
+ return send_and_receive_put_command_at_node_1([]([[maybe_unused]] auto& cmd) noexcept {});
}
[[nodiscard]] std::shared_ptr<api::PutReply> respond_and_receive_put_reply_at_node_0(
@@ -283,7 +283,7 @@ struct StorageApiRpcServiceTest : Test {
[[nodiscard]] std::shared_ptr<api::PutReply> respond_and_receive_put_reply_at_node_0(
const std::shared_ptr<api::PutCommand>& cmd) {
- return respond_and_receive_put_reply_at_node_0(cmd, []([[maybe_unused]] auto& reply){});
+ return respond_and_receive_put_reply_at_node_0(cmd, []([[maybe_unused]] auto& reply) noexcept {});
}
};
diff --git a/storage/src/tests/storageserver/testvisitormessagesession.h b/storage/src/tests/storageserver/testvisitormessagesession.h
index a9d83ca6c1a..1cea1c78d74 100644
--- a/storage/src/tests/storageserver/testvisitormessagesession.h
+++ b/storage/src/tests/storageserver/testvisitormessagesession.h
@@ -45,7 +45,7 @@ public:
struct TestVisitorMessageSessionFactory : public VisitorMessageSessionFactory
{
- vespalib::Lock _accessLock;
+ std::mutex _accessLock;
std::vector<TestVisitorMessageSession*> _visitorSessions;
mbus::Error _autoReplyError;
bool _createAutoReplyVisitorSessions;
@@ -56,11 +56,10 @@ struct TestVisitorMessageSessionFactory : public VisitorMessageSessionFactory
_priConverter(configId) {}
VisitorMessageSession::UP createSession(Visitor& v, VisitorThread& vt) override {
- vespalib::LockGuard lock(_accessLock);
- TestVisitorMessageSession::UP session(new TestVisitorMessageSession(vt, v, _autoReplyError,
- _createAutoReplyVisitorSessions));
+ std::lock_guard lock(_accessLock);
+ auto session = std::make_unique<TestVisitorMessageSession>(vt, v, _autoReplyError, _createAutoReplyVisitorSessions);
_visitorSessions.push_back(session.get());
- return VisitorMessageSession::UP(std::move(session));
+ return session;
}
documentapi::Priority::Value toDocumentPriority(uint8_t storagePriority) const override {
diff --git a/storage/src/tests/visiting/visitormanagertest.cpp b/storage/src/tests/visiting/visitormanagertest.cpp
index 20934d04eaa..0ce305fb8bb 100644
--- a/storage/src/tests/visiting/visitormanagertest.cpp
+++ b/storage/src/tests/visiting/visitormanagertest.cpp
@@ -223,7 +223,7 @@ VisitorManagerTest::getSession(uint32_t n)
framework::MilliSecTime endTime(clock.getTimeInMillis() + framework::MilliSecTime(30 * 1000));
while (true) {
{
- vespalib::LockGuard lock(_messageSessionFactory->_accessLock);
+ std::lock_guard lock(_messageSessionFactory->_accessLock);
if (sessions.size() > n) {
return *sessions[n];
}
diff --git a/storage/src/tests/visiting/visitortest.cpp b/storage/src/tests/visiting/visitortest.cpp
index 16b2fca77ae..ee6b8fa3d38 100644
--- a/storage/src/tests/visiting/visitortest.cpp
+++ b/storage/src/tests/visiting/visitortest.cpp
@@ -1,9 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/document/datatype/datatype.h>
#include <vespa/document/fieldvalue/intfieldvalue.h>
#include <vespa/document/fieldvalue/stringfieldvalue.h>
-#include <vespa/document/fieldvalue/rawfieldvalue.h>
#include <vespa/document/test/make_bucket_space.h>
#include <vespa/storageapi/message/datagram.h>
#include <vespa/storageapi/message/persistence.h>
@@ -259,7 +257,7 @@ VisitorTest::getSession(uint32_t n)
clock.getTimeInMillis() + framework::MilliSecTime(30 * 1000));
while (true) {
{
- vespalib::LockGuard lock(_messageSessionFactory->_accessLock);
+ std::lock_guard lock(_messageSessionFactory->_accessLock);
if (sessions.size() > n) {
return *sessions[n];
}
diff --git a/storage/src/vespa/storage/bucketdb/abstract_bucket_map.h b/storage/src/vespa/storage/bucketdb/abstract_bucket_map.h
index 9b738b26994..be83970e2b7 100644
--- a/storage/src/vespa/storage/bucketdb/abstract_bucket_map.h
+++ b/storage/src/vespa/storage/bucketdb/abstract_bucket_map.h
@@ -36,7 +36,7 @@ public:
key_type _key;
bool _locked;
- LockKeeper(AbstractBucketMap& map, key_type key)
+ LockKeeper(AbstractBucketMap& map, key_type key) noexcept
: _map(map), _key(key), _locked(true) {}
void unlock() { _map.unlock(_key); _locked = false; }
public:
@@ -44,7 +44,7 @@ public:
};
struct WrappedEntry {
- WrappedEntry()
+ WrappedEntry() noexcept
: _exists(false),
_preExisted(false),
_lockKeeper(),
@@ -103,16 +103,16 @@ public:
key_type _key;
const char* _owner;
- LockId() : _key(0), _owner("none - empty token") {}
- LockId(key_type key, const char* owner)
+ LockId() noexcept : _key(0), _owner("none - empty token") {}
+ LockId(key_type key, const char* owner) noexcept
: _key(key), _owner(owner)
{
assert(_owner);
}
- size_t hash() const { return _key; }
- size_t operator%(size_t val) const { return _key % val; }
- bool operator==(const LockId& id) const { return (_key == id._key); }
+ size_t hash() const noexcept { return _key; }
+ size_t operator%(size_t val) const noexcept { return _key % val; }
+ bool operator==(const LockId& id) const noexcept { return (_key == id._key); }
operator key_type() const { return _key; }
};
diff --git a/storage/src/vespa/storage/bucketdb/bucketcopy.h b/storage/src/vespa/storage/bucketdb/bucketcopy.h
index 09f86ef1324..94a1e63e53e 100644
--- a/storage/src/vespa/storage/bucketdb/bucketcopy.h
+++ b/storage/src/vespa/storage/bucketdb/bucketcopy.h
@@ -15,12 +15,12 @@ private:
public:
static const int TRUSTED = 1;
- BucketCopy()
+ BucketCopy() noexcept
: _timestamp(0), _flags(0), _node(0xffff) {}
BucketCopy(uint64_t timestamp,
uint16_t nodeIdx,
- const api::BucketInfo& info)
+ const api::BucketInfo& info) noexcept
: _timestamp(timestamp),
_info(info),
_flags(0),
diff --git a/storage/src/vespa/storage/bucketdb/lockablemap.hpp b/storage/src/vespa/storage/bucketdb/lockablemap.hpp
index d11d24c7acf..57183566964 100644
--- a/storage/src/vespa/storage/bucketdb/lockablemap.hpp
+++ b/storage/src/vespa/storage/bucketdb/lockablemap.hpp
@@ -354,7 +354,7 @@ LockableMap<Map>::print(std::ostream& out, bool verbose,
out << "LockableMap {\n" << indent << " ";
if (verbose) {
- for (const auto & entry : _map) {
+ for (const auto entry : _map) {
out << "Key: " << BucketId(BucketId::keyToBucketId(entry.first))
<< " Value: " << entry.second << "\n" << indent << " ";
}
diff --git a/storage/src/vespa/storage/common/distributorcomponent.h b/storage/src/vespa/storage/common/distributorcomponent.h
index e55e6f45cb1..27680b8c6ce 100644
--- a/storage/src/vespa/storage/common/distributorcomponent.h
+++ b/storage/src/vespa/storage/common/distributorcomponent.h
@@ -60,8 +60,7 @@ struct DistributorManagedComponent
struct DistributorComponentRegister : public virtual StorageComponentRegister
{
- virtual void registerDistributorComponent(
- DistributorManagedComponent&) = 0;
+ virtual void registerDistributorComponent(DistributorManagedComponent&) = 0;
};
class DistributorComponent : public StorageComponent,
@@ -86,10 +85,10 @@ public:
typedef std::unique_ptr<DistributorComponent> UP;
DistributorComponent(DistributorComponentRegister& compReg, vespalib::stringref name);
- ~DistributorComponent();
+ ~DistributorComponent() override;
api::Timestamp getUniqueTimestamp() const {
- assert(_timeCalculator); return _timeCalculator->getUniqueTimestamp();
+ return _timeCalculator->getUniqueTimestamp();
}
const DistributorConfig& getDistributorConfig() const {
return _distributorConfig;
diff --git a/storage/src/vespa/storage/common/servicelayercomponent.h b/storage/src/vespa/storage/common/servicelayercomponent.h
index 22a33aac14c..2308480411e 100644
--- a/storage/src/vespa/storage/common/servicelayercomponent.h
+++ b/storage/src/vespa/storage/common/servicelayercomponent.h
@@ -79,11 +79,9 @@ public:
const ContentBucketSpaceRepo &getBucketSpaceRepo() const;
StorBucketDatabase& getBucketDatabase(document::BucketSpace bucketSpace) const;
MinimumUsedBitsTracker& getMinUsedBitsTracker() {
- assert(_minUsedBitsTracker != 0);
return *_minUsedBitsTracker;
}
const MinimumUsedBitsTracker& getMinUsedBitsTracker() const {
- assert(_minUsedBitsTracker != 0);
return *_minUsedBitsTracker;
}
uint16_t getIdealPartition(const document::Bucket&) const;
diff --git a/storage/src/vespa/storage/common/storagelinkqueued.hpp b/storage/src/vespa/storage/common/storagelinkqueued.hpp
index 22c5e9ba5f2..ea6430f9e5c 100644
--- a/storage/src/vespa/storage/common/storagelinkqueued.hpp
+++ b/storage/src/vespa/storage/common/storagelinkqueued.hpp
@@ -8,6 +8,7 @@
#include <vespa/vespalib/util/stringfmt.h>
#include <sstream>
#include <chrono>
+#include <cassert>
namespace storage {
diff --git a/storage/src/vespa/storage/distributor/distributor.cpp b/storage/src/vespa/storage/distributor/distributor.cpp
index cfd8d7f1753..352da70d7e4 100644
--- a/storage/src/vespa/storage/distributor/distributor.cpp
+++ b/storage/src/vespa/storage/distributor/distributor.cpp
@@ -28,7 +28,7 @@ class Distributor::Status {
bool _done;
public:
- Status(const DelegatedStatusRequest& request)
+ Status(const DelegatedStatusRequest& request) noexcept
: _request(request),
_monitor(),
_done(false)
@@ -465,7 +465,7 @@ BucketSpacesStatsProvider::BucketSpacesStats Distributor::make_invalid_stats_per
}
void Distributor::invalidate_bucket_spaces_stats() {
- vespalib::LockGuard guard(_metricLock);
+ std::lock_guard guard(_metricLock);
_bucketSpacesStats = BucketSpacesStatsProvider::PerNodeBucketSpacesStats();
auto invalid_space_stats = make_invalid_stats_per_configured_space();
@@ -681,21 +681,21 @@ void Distributor::startExternalOperations() {
std::unordered_map<uint16_t, uint32_t>
Distributor::getMinReplica() const
{
- vespalib::LockGuard guard(_metricLock);
+ std::lock_guard guard(_metricLock);
return _bucketDbStats._minBucketReplica;
}
BucketSpacesStatsProvider::PerNodeBucketSpacesStats
Distributor::getBucketSpacesStats() const
{
- vespalib::LockGuard guard(_metricLock);
+ std::lock_guard guard(_metricLock);
return _bucketSpacesStats;
}
void
Distributor::propagateInternalScanMetricsToExternal()
{
- vespalib::LockGuard guard(_metricLock);
+ std::lock_guard guard(_metricLock);
// All shared values are written when _metricLock is held, so no races.
if (_bucketDBMetricUpdater.hasCompletedRound()) {
@@ -755,7 +755,7 @@ bool merge_no_longer_pending_edge(const PerNodeBucketSpacesStats& prev_stats,
void
Distributor::updateInternalMetricsForCompletedScan()
{
- vespalib::LockGuard guard(_metricLock);
+ std::lock_guard guard(_metricLock);
_bucketDBMetricUpdater.completeRound();
_bucketDbStats = _bucketDBMetricUpdater.getLastCompleteStats();
diff --git a/storage/src/vespa/storage/distributor/distributor.h b/storage/src/vespa/storage/distributor/distributor.h
index fcc08030764..d7dd1fda2e9 100644
--- a/storage/src/vespa/storage/distributor/distributor.h
+++ b/storage/src/vespa/storage/distributor/distributor.h
@@ -20,7 +20,6 @@
#include <vespa/storageapi/message/state.h>
#include <vespa/storageframework/generic/metric/metricupdatehook.h>
#include <vespa/storageframework/generic/thread/tickingthread.h>
-#include <vespa/vespalib/util/sync.h>
#include <queue>
#include <unordered_map>
@@ -301,7 +300,6 @@ private:
ClientRequestPriorityQueue _client_request_priority_queue;
MessageQueue _fetchedMessages;
framework::TickingThreadPool& _threadPool;
- vespalib::Monitor _statusMonitor;
mutable std::vector<std::shared_ptr<Status>> _statusToDo;
mutable std::vector<std::shared_ptr<Status>> _fetchedStatusRequests;
@@ -325,7 +323,7 @@ private:
BucketDBMetricUpdater _bucketDBMetricUpdater;
std::unique_ptr<BucketGcTimeCalculator::BucketIdHasher> _bucketIdHasher;
MetricUpdateHook _metricUpdateHook;
- vespalib::Lock _metricLock;
+ mutable std::mutex _metricLock;
/**
* Maintenance stats for last completed database scan iteration.
* Access must be protected by _metricLock as it is read by metric
diff --git a/storage/src/vespa/storage/distributor/distributorcomponent.h b/storage/src/vespa/storage/distributor/distributorcomponent.h
index df25efb3b00..283d0c20390 100644
--- a/storage/src/vespa/storage/distributor/distributorcomponent.h
+++ b/storage/src/vespa/storage/distributor/distributorcomponent.h
@@ -186,7 +186,6 @@ protected:
DistributorBucketSpaceRepo& _bucketSpaceRepo;
DistributorBucketSpaceRepo& _readOnlyBucketSpaceRepo;
- vespalib::Lock _sync;
};
}
diff --git a/storage/src/vespa/storage/distributor/messageguard.h b/storage/src/vespa/storage/distributor/messageguard.h
index 9c71758a24b..b2be0cc67ff 100644
--- a/storage/src/vespa/storage/distributor/messageguard.h
+++ b/storage/src/vespa/storage/distributor/messageguard.h
@@ -3,7 +3,6 @@
#include "pendingclusterstate.h"
#include <vespa/storage/common/messagesender.h>
-#include <vespa/vespalib/util/sync.h>
namespace storage {
@@ -11,12 +10,11 @@ class MessageGuard {
std::vector<std::shared_ptr<api::StorageMessage> > messagesUp;
std::vector<std::shared_ptr<api::StorageMessage> > messagesDown;
- vespalib::LockGuard _lock;
+ std::unique_lock<std::mutex> _lock;
ChainedMessageSender& _messageSender;
public:
- MessageGuard(const vespalib::Lock &lock,
- ChainedMessageSender& messageSender)
+ MessageGuard(std::mutex & lock, ChainedMessageSender& messageSender)
: _lock(lock),
_messageSender(messageSender) {}
diff --git a/storage/src/vespa/storage/distributor/messagetracker.h b/storage/src/vespa/storage/distributor/messagetracker.h
index 75ae287d98f..11d8c36082e 100644
--- a/storage/src/vespa/storage/distributor/messagetracker.h
+++ b/storage/src/vespa/storage/distributor/messagetracker.h
@@ -17,7 +17,7 @@ class MessageTracker {
public:
class ToSend {
public:
- ToSend(std::shared_ptr<api::BucketCommand> msg, uint16_t target) :
+ ToSend(std::shared_ptr<api::BucketCommand> msg, uint16_t target) noexcept :
_msg(std::move(msg)), _target(target) {};
std::shared_ptr<api::BucketCommand> _msg;
diff --git a/storage/src/vespa/storage/distributor/operation_sequencer.h b/storage/src/vespa/storage/distributor/operation_sequencer.h
index cf687e721a8..7a523b61e53 100644
--- a/storage/src/vespa/storage/distributor/operation_sequencer.h
+++ b/storage/src/vespa/storage/distributor/operation_sequencer.h
@@ -24,7 +24,7 @@ class SequencingHandle {
OperationSequencer* _sequencer;
document::GlobalId _gid;
public:
- SequencingHandle() : _sequencer(nullptr) {}
+ SequencingHandle() noexcept : _sequencer(nullptr) {}
SequencingHandle(OperationSequencer& sequencer, const document::GlobalId& gid)
: _sequencer(&sequencer),
_gid(gid)
diff --git a/storage/src/vespa/storage/distributor/operations/external/statbucketlistoperation.h b/storage/src/vespa/storage/distributor/operations/external/statbucketlistoperation.h
index c977ea78f67..aa38a0d2319 100644
--- a/storage/src/vespa/storage/distributor/operations/external/statbucketlistoperation.h
+++ b/storage/src/vespa/storage/distributor/operations/external/statbucketlistoperation.h
@@ -4,7 +4,6 @@
#include <vespa/vespalib/util/hdr_abort.h>
#include <vespa/storage/distributor/operations/operation.h>
#include <vespa/storage/bucketdb/bucketdatabase.h>
-#include <vespa/vespalib/util/sync.h>
namespace storage {
diff --git a/storage/src/vespa/storage/distributor/operations/external/updateoperation.h b/storage/src/vespa/storage/distributor/operations/external/updateoperation.h
index c66026f02f5..9d9bce9160b 100644
--- a/storage/src/vespa/storage/distributor/operations/external/updateoperation.h
+++ b/storage/src/vespa/storage/distributor/operations/external/updateoperation.h
@@ -55,7 +55,7 @@ private:
class PreviousDocumentVersion {
public:
- PreviousDocumentVersion(document::BucketId b, const api::BucketInfo& info, uint64_t o, uint16_t node) :
+ PreviousDocumentVersion(document::BucketId b, const api::BucketInfo& info, uint64_t o, uint16_t node) noexcept :
bucketId(b), bucketInfo(info), oldTs(o), nodeId(node) {}
document::BucketId bucketId;
diff --git a/storage/src/vespa/storage/distributor/operations/idealstate/mergemetadata.h b/storage/src/vespa/storage/distributor/operations/idealstate/mergemetadata.h
index fb84441b654..273603ca6ad 100644
--- a/storage/src/vespa/storage/distributor/operations/idealstate/mergemetadata.h
+++ b/storage/src/vespa/storage/distributor/operations/idealstate/mergemetadata.h
@@ -3,26 +3,22 @@
#pragma once
#include <vespa/storage/bucketdb/bucketcopy.h>
-#include <cassert>
-namespace storage {
-namespace distributor {
+namespace storage::distributor {
struct MergeMetaData {
uint16_t _nodeIndex;
bool _sourceOnly;
const BucketCopy* _copy;
- MergeMetaData() : _nodeIndex(0), _sourceOnly(false), _copy(0) {}
- MergeMetaData(uint16_t nodeIndex, const BucketCopy& copy)
+ MergeMetaData() noexcept : _nodeIndex(0), _sourceOnly(false), _copy(nullptr) {}
+ MergeMetaData(uint16_t nodeIndex, const BucketCopy& copy) noexcept
: _nodeIndex(nodeIndex), _sourceOnly(false), _copy(&copy) {}
bool trusted() const {
- assert(_copy != 0);
return _copy->trusted();
}
uint32_t checksum() const {
- assert(_copy != 0);
return _copy->getChecksum();
}
bool source_only() const noexcept { return _sourceOnly; }
@@ -30,6 +26,4 @@ struct MergeMetaData {
vespalib::asciistream& operator<<(vespalib::asciistream& out, const MergeMetaData& e);
-} // distributor
-} // storage
-
+}
diff --git a/storage/src/vespa/storage/distributor/sentmessagemap.h b/storage/src/vespa/storage/distributor/sentmessagemap.h
index 405e59f7b31..e84920b88d7 100644
--- a/storage/src/vespa/storage/distributor/sentmessagemap.h
+++ b/storage/src/vespa/storage/distributor/sentmessagemap.h
@@ -1,14 +1,10 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
-#include <vespa/vespalib/util/sync.h>
#include <map>
#include <vespa/storageapi/messageapi/storagemessage.h>
-namespace storage
-{
-
-namespace distributor {
+namespace storage::distributor {
class Operation;
@@ -32,6 +28,3 @@ private:
};
}
-
-}
-
diff --git a/storage/src/vespa/storage/frameworkimpl/component/distributorcomponentregisterimpl.cpp b/storage/src/vespa/storage/frameworkimpl/component/distributorcomponentregisterimpl.cpp
index 439bc9e078c..efd558a0b4b 100644
--- a/storage/src/vespa/storage/frameworkimpl/component/distributorcomponentregisterimpl.cpp
+++ b/storage/src/vespa/storage/frameworkimpl/component/distributorcomponentregisterimpl.cpp
@@ -1,6 +1,5 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "distributorcomponentregisterimpl.h"
-#include <vespa/vdslib/distribution/idealnodecalculatorimpl.h>
#include <vespa/vespalib/util/exceptions.h>
#include <vespa/vdslib/state/cluster_state_bundle.h>
@@ -11,8 +10,7 @@ DistributorComponentRegisterImpl::DistributorComponentRegisterImpl()
{
}
-DistributorComponentRegisterImpl::~DistributorComponentRegisterImpl() {
-}
+DistributorComponentRegisterImpl::~DistributorComponentRegisterImpl() = default;
void
DistributorComponentRegisterImpl::handleNewState()
@@ -24,7 +22,7 @@ DistributorComponentRegisterImpl::handleNewState()
void
DistributorComponentRegisterImpl::registerDistributorComponent(DistributorManagedComponent& smc)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
_components.push_back(&smc);
if (_timeCalculator != 0) {
smc.setTimeCalculator(*_timeCalculator);
@@ -36,7 +34,7 @@ DistributorComponentRegisterImpl::registerDistributorComponent(DistributorManage
void
DistributorComponentRegisterImpl::setTimeCalculator(UniqueTimeCalculator& utc)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
if (_timeCalculator != 0) {
throw vespalib::IllegalStateException(
"Time calculator already set. Cannot be updated live",
@@ -51,7 +49,7 @@ DistributorComponentRegisterImpl::setTimeCalculator(UniqueTimeCalculator& utc)
void
DistributorComponentRegisterImpl::setDistributorConfig(const DistributorConfig& c)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
_distributorConfig = c;
for (uint32_t i=0; i<_components.size(); ++i) {
_components[i]->setDistributorConfig(c);
@@ -61,7 +59,7 @@ DistributorComponentRegisterImpl::setDistributorConfig(const DistributorConfig&
void
DistributorComponentRegisterImpl::setVisitorConfig(const VisitorConfig& c)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
_visitorConfig = c;
for (uint32_t i=0; i<_components.size(); ++i) {
_components[i]->setVisitorConfig(c);
diff --git a/storage/src/vespa/storage/frameworkimpl/component/distributorcomponentregisterimpl.h b/storage/src/vespa/storage/frameworkimpl/component/distributorcomponentregisterimpl.h
index 61fba7f9921..a6c678630e0 100644
--- a/storage/src/vespa/storage/frameworkimpl/component/distributorcomponentregisterimpl.h
+++ b/storage/src/vespa/storage/frameworkimpl/component/distributorcomponentregisterimpl.h
@@ -21,7 +21,7 @@ class DistributorComponentRegisterImpl
public virtual StorageComponentRegisterImpl,
private StateListener
{
- vespalib::Lock _componentLock;
+ std::mutex _componentLock;
std::vector<DistributorManagedComponent*> _components;
UniqueTimeCalculator* _timeCalculator;
diff --git a/storage/src/vespa/storage/frameworkimpl/component/servicelayercomponentregisterimpl.cpp b/storage/src/vespa/storage/frameworkimpl/component/servicelayercomponentregisterimpl.cpp
index da45b61701e..17e65478411 100644
--- a/storage/src/vespa/storage/frameworkimpl/component/servicelayercomponentregisterimpl.cpp
+++ b/storage/src/vespa/storage/frameworkimpl/component/servicelayercomponentregisterimpl.cpp
@@ -18,7 +18,7 @@ void
ServiceLayerComponentRegisterImpl::registerServiceLayerComponent(
ServiceLayerManagedComponent& smc)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
_components.push_back(&smc);
smc.setDiskCount(_diskCount);
smc.setBucketSpaceRepo(_bucketSpaceRepo);
@@ -28,7 +28,7 @@ ServiceLayerComponentRegisterImpl::registerServiceLayerComponent(
void
ServiceLayerComponentRegisterImpl::setDiskCount(uint16_t count)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
if (_diskCount != 0) {
throw IllegalStateException("Disk count already set. Cannot be updated live", VESPA_STRLOC);
}
diff --git a/storage/src/vespa/storage/frameworkimpl/component/servicelayercomponentregisterimpl.h b/storage/src/vespa/storage/frameworkimpl/component/servicelayercomponentregisterimpl.h
index 9988b861422..e722110d770 100644
--- a/storage/src/vespa/storage/frameworkimpl/component/servicelayercomponentregisterimpl.h
+++ b/storage/src/vespa/storage/frameworkimpl/component/servicelayercomponentregisterimpl.h
@@ -18,7 +18,7 @@ class ServiceLayerComponentRegisterImpl
: public virtual ServiceLayerComponentRegister,
public virtual StorageComponentRegisterImpl
{
- vespalib::Lock _componentLock;
+ std::mutex _componentLock;
std::vector<ServiceLayerManagedComponent*> _components;
uint16_t _diskCount;
ContentBucketSpaceRepo _bucketSpaceRepo;
diff --git a/storage/src/vespa/storage/frameworkimpl/component/storagecomponentregisterimpl.cpp b/storage/src/vespa/storage/frameworkimpl/component/storagecomponentregisterimpl.cpp
index 654fcbd1380..9c421eb7f8f 100644
--- a/storage/src/vespa/storage/frameworkimpl/component/storagecomponentregisterimpl.cpp
+++ b/storage/src/vespa/storage/frameworkimpl/component/storagecomponentregisterimpl.cpp
@@ -2,9 +2,9 @@
#include "storagecomponentregisterimpl.h"
#include <vespa/vespalib/util/exceptions.h>
+#include <cassert>
#include <vespa/log/log.h>
-
LOG_SETUP(".storage.component.register");
namespace storage {
@@ -30,7 +30,7 @@ StorageComponentRegisterImpl::~StorageComponentRegisterImpl() = default;
void
StorageComponentRegisterImpl::registerStorageComponent(StorageComponent& smc)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
_components.push_back(&smc);
assert(_nodeType != nullptr);
smc.setNodeInfo(_clusterName, *_nodeType, _index);
@@ -49,7 +49,7 @@ StorageComponentRegisterImpl::setNodeInfo(vespalib::stringref clusterName,
const lib::NodeType& nodeType,
uint16_t index)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
if (_nodeType != nullptr) {
LOG(warning, "Node info already set. May be valid in tests, but is a "
"bug in production. Node info should not be updated live");
@@ -62,7 +62,7 @@ StorageComponentRegisterImpl::setNodeInfo(vespalib::stringref clusterName,
void
StorageComponentRegisterImpl::setNodeStateUpdater(NodeStateUpdater& updater)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
if (_nodeStateUpdater != 0) {
throw vespalib::IllegalStateException(
"Node state updater already set. Should never be altered live.",
@@ -77,7 +77,7 @@ StorageComponentRegisterImpl::setNodeStateUpdater(NodeStateUpdater& updater)
void
StorageComponentRegisterImpl::setDocumentTypeRepo(std::shared_ptr<const document::DocumentTypeRepo> repo)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
_docTypeRepo = repo;
for (auto& component : _components) {
component->setDocumentTypeRepo(repo);
@@ -87,7 +87,7 @@ StorageComponentRegisterImpl::setDocumentTypeRepo(std::shared_ptr<const document
void
StorageComponentRegisterImpl::setLoadTypes(documentapi::LoadTypeSet::SP loadTypes)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
_loadTypes = loadTypes;
for (auto& component : _components) {
component->setLoadTypes(loadTypes);
@@ -97,7 +97,7 @@ StorageComponentRegisterImpl::setLoadTypes(documentapi::LoadTypeSet::SP loadType
void
StorageComponentRegisterImpl::setPriorityConfig(const PriorityConfig& config)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
_priorityConfig = config;
for (auto& component : _components) {
component->setPriorityConfig(config);
@@ -107,7 +107,7 @@ StorageComponentRegisterImpl::setPriorityConfig(const PriorityConfig& config)
void
StorageComponentRegisterImpl::setBucketIdFactory(const document::BucketIdFactory& factory)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
_bucketIdFactory = factory;
for (auto& component : _components) {
component->setBucketIdFactory(factory);
@@ -117,7 +117,7 @@ StorageComponentRegisterImpl::setBucketIdFactory(const document::BucketIdFactory
void
StorageComponentRegisterImpl::setDistribution(lib::Distribution::SP distribution)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
_distribution = distribution;
for (auto& component : _components) {
component->setDistribution(distribution);
@@ -127,7 +127,7 @@ StorageComponentRegisterImpl::setDistribution(lib::Distribution::SP distribution
void
StorageComponentRegisterImpl::setBucketSpacesConfig(const BucketspacesConfig& config)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
_bucketSpacesConfig = config;
}
diff --git a/storage/src/vespa/storage/frameworkimpl/component/storagecomponentregisterimpl.h b/storage/src/vespa/storage/frameworkimpl/component/storagecomponentregisterimpl.h
index 2f8bfaab87b..b22ea93223b 100644
--- a/storage/src/vespa/storage/frameworkimpl/component/storagecomponentregisterimpl.h
+++ b/storage/src/vespa/storage/frameworkimpl/component/storagecomponentregisterimpl.h
@@ -24,7 +24,7 @@ class StorageComponentRegisterImpl
using PriorityConfig = StorageComponent::PriorityConfig;
using BucketspacesConfig = vespa::config::content::core::internal::InternalBucketspacesType;
- vespalib::Lock _componentLock;
+ std::mutex _componentLock;
std::vector<StorageComponent*> _components;
vespalib::string _clusterName;
const lib::NodeType* _nodeType;
@@ -41,24 +41,20 @@ public:
typedef std::unique_ptr<StorageComponentRegisterImpl> UP;
StorageComponentRegisterImpl();
- ~StorageComponentRegisterImpl();
+ ~StorageComponentRegisterImpl() override;
const vespalib::string& getClusterName() const { return _clusterName; }
- const lib::NodeType& getNodeType() const
- { assert(_nodeType != 0); return *_nodeType; }
+ const lib::NodeType& getNodeType() const { return *_nodeType; }
uint16_t getIndex() const { return _index; }
std::shared_ptr<const document::DocumentTypeRepo> getTypeRepo() { return _docTypeRepo; }
documentapi::LoadTypeSet::SP getLoadTypes() { return _loadTypes; }
const document::BucketIdFactory& getBucketIdFactory() { return _bucketIdFactory; }
lib::Distribution::SP getDistribution() { return _distribution; }
- NodeStateUpdater& getNodeStateUpdater()
- { assert(_nodeStateUpdater != 0); return *_nodeStateUpdater; }
+ NodeStateUpdater& getNodeStateUpdater() { return *_nodeStateUpdater; }
void registerStorageComponent(StorageComponent&) override;
- void setNodeInfo(vespalib::stringref clusterName,
- const lib::NodeType& nodeType,
- uint16_t index);
+ void setNodeInfo(vespalib::stringref clusterName, const lib::NodeType& nodeType, uint16_t index);
virtual void setNodeStateUpdater(NodeStateUpdater& updater);
virtual void setDocumentTypeRepo(std::shared_ptr<const document::DocumentTypeRepo>);
virtual void setLoadTypes(documentapi::LoadTypeSet::SP);
diff --git a/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.cpp b/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.cpp
index 4df2b5e591b..75348a25e76 100644
--- a/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.cpp
+++ b/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.cpp
@@ -75,8 +75,8 @@ FileStorHandlerImpl::~FileStorHandlerImpl() = default;
void
FileStorHandlerImpl::addMergeStatus(const document::Bucket& bucket, MergeStatus::SP status)
{
- vespalib::LockGuard mlock(_mergeStatesLock);
- if (_mergeStates.find(bucket) != _mergeStates.end()) {;
+ std::lock_guard mlock(_mergeStatesLock);
+ if (_mergeStates.find(bucket) != _mergeStates.end()) {
LOG(warning, "A merge status already existed for %s. Overwriting it.", bucket.toString().c_str());
}
_mergeStates[bucket] = status;
@@ -85,7 +85,7 @@ FileStorHandlerImpl::addMergeStatus(const document::Bucket& bucket, MergeStatus:
MergeStatus&
FileStorHandlerImpl::editMergeStatus(const document::Bucket& bucket)
{
- vespalib::LockGuard mlock(_mergeStatesLock);
+ std::lock_guard mlock(_mergeStatesLock);
MergeStatus::SP status = _mergeStates[bucket];
if (status.get() == 0) {
throw vespalib::IllegalStateException("No merge state exist for " + bucket.toString(), VESPA_STRLOC);
@@ -96,21 +96,21 @@ FileStorHandlerImpl::editMergeStatus(const document::Bucket& bucket)
bool
FileStorHandlerImpl::isMerging(const document::Bucket& bucket) const
{
- vespalib::LockGuard mlock(_mergeStatesLock);
+ std::lock_guard mlock(_mergeStatesLock);
return (_mergeStates.find(bucket) != _mergeStates.end());
}
uint32_t
FileStorHandlerImpl::getNumActiveMerges() const
{
- vespalib::LockGuard mlock(_mergeStatesLock);
+ std::lock_guard mlock(_mergeStatesLock);
return _mergeStates.size();
}
void
FileStorHandlerImpl::clearMergeStatus(const document::Bucket& bucket, const api::ReturnCode* code)
{
- vespalib::LockGuard mlock(_mergeStatesLock);
+ std::lock_guard mlock(_mergeStatesLock);
auto it = _mergeStates.find(bucket);
if (it == _mergeStates.end()) {
if (code != 0) {
@@ -301,7 +301,7 @@ void
FileStorHandlerImpl::updateMetrics(const MetricLockGuard &)
{
for (Disk & disk : _diskInfo) {
- vespalib::MonitorGuard lockGuard(_mergeStatesLock);
+ std::lock_guard lockGuard(_mergeStatesLock);
disk.metrics->pendingMerges.addValue(_mergeStates.size());
disk.metrics->queueSize.addValue(disk.getQueueSize());
@@ -802,7 +802,7 @@ FileStorHandlerImpl::Stripe::failOperations(const document::Bucket &bucket, cons
{
vespalib::MonitorGuard guard(_lock);
- BucketIdx& idx(bmi::get<2>(_queue));
+ BucketIdx& idx(bmi::get<2>(*_queue));
std::pair<BucketIdx::iterator, BucketIdx::iterator> range(idx.equal_range(bucket));
for (auto iter = range.first; iter != range.second;) {
@@ -869,9 +869,13 @@ FileStorHandlerImpl::MessageEntry::~MessageEntry() = default;
FileStorHandlerImpl::Disk::Disk(const FileStorHandlerImpl & owner, MessageSender & messageSender, uint32_t numStripes)
: metrics(0),
_nextStripeId(0),
- _stripes(numStripes, Stripe(owner, messageSender)),
+ _stripes(),
state(FileStorHandler::AVAILABLE)
{
+ _stripes.reserve(numStripes);
+ for (size_t i(0); i < numStripes; i++) {
+ _stripes.emplace_back(owner, messageSender);
+ }
assert(numStripes > 0);
}
@@ -884,6 +888,7 @@ FileStorHandlerImpl::Disk::Disk(Disk && rhs) noexcept
FileStorHandlerImpl::Disk::~Disk() = default;
FileStorHandlerImpl::Stripe::~Stripe() = default;
+FileStorHandlerImpl::Stripe::Stripe(Stripe &&) noexcept = default;
void
FileStorHandlerImpl::Disk::flush()
@@ -903,7 +908,7 @@ FileStorHandlerImpl::Disk::broadcast()
uint64_t FileStorHandlerImpl::Disk::dispersed_bucket_bits(const document::Bucket& bucket) noexcept {
const uint64_t raw_id = bucket.getBucketId().getId();
- return XXH64(&raw_id, sizeof(uint64_t), 0);
+ return XXH3_64bits(&raw_id, sizeof(uint64_t));
}
bool
@@ -921,6 +926,10 @@ FileStorHandlerImpl::Disk::schedule(const std::shared_ptr<api::StorageMessage>&
FileStorHandlerImpl::Stripe::Stripe(const FileStorHandlerImpl & owner, MessageSender & messageSender)
: _owner(owner),
_messageSender(messageSender),
+ _metrics(nullptr),
+ _lock(),
+ _queue(std::make_unique<PriorityQueue>()),
+ _lockedBuckets(),
_active_merges(0)
{}
@@ -933,7 +942,7 @@ FileStorHandlerImpl::Stripe::getNextMessage(uint32_t timeout, Disk & disk)
// second attempt. This is key to allowing the run loop to register
// ticks at regular intervals while not busy-waiting.
for (int attempt = 0; (attempt < 2) && ! disk.isClosed() && !_owner.isPaused(); ++attempt) {
- PriorityIdx& idx(bmi::get<1>(_queue));
+ PriorityIdx& idx(bmi::get<1>(*_queue));
PriorityIdx::iterator iter(idx.begin()), end(idx.end());
while (iter != end && operationIsInhibited(guard, iter->_bucket, *iter->_command)) {
@@ -1032,11 +1041,11 @@ void FileStorHandlerImpl::Stripe::abort(std::vector<std::shared_ptr<api::Storage
const AbortBucketOperationsCommand& cmd)
{
vespalib::MonitorGuard lockGuard(_lock);
- for (auto it(_queue.begin()); it != _queue.end();) {
+ for (auto it(_queue->begin()); it != _queue->end();) {
api::StorageMessage& msg(*it->_command);
if (messageMayBeAborted(msg) && cmd.shouldAbort(it->_bucket)) {
aborted.emplace_back(static_cast<api::StorageCommand&>(msg).makeReply());
- it = _queue.erase(it);
+ it = _queue->erase(it);
} else {
++it;
}
@@ -1046,7 +1055,7 @@ void FileStorHandlerImpl::Stripe::abort(std::vector<std::shared_ptr<api::Storage
bool FileStorHandlerImpl::Stripe::schedule(MessageEntry messageEntry)
{
vespalib::MonitorGuard lockGuard(_lock);
- _queue.emplace_back(std::move(messageEntry));
+ _queue->emplace_back(std::move(messageEntry));
lockGuard.broadcast();
return true;
}
@@ -1055,8 +1064,8 @@ void
FileStorHandlerImpl::Stripe::flush()
{
vespalib::MonitorGuard lockGuard(_lock);
- while (!(_queue.empty() && _lockedBuckets.empty())) {
- LOG(debug, "Still %ld in queue and %ld locked buckets", _queue.size(), _lockedBuckets.size());
+ while (!(_queue->empty() && _lockedBuckets.empty())) {
+ LOG(debug, "Still %ld in queue and %ld locked buckets", _queue->size(), _lockedBuckets.size());
lockGuard.wait(100);
}
}
@@ -1229,7 +1238,7 @@ FileStorHandlerImpl::Stripe::dumpQueueHtml(std::ostream & os) const
{
vespalib::MonitorGuard guard(_lock);
- const PriorityIdx& idx = bmi::get<1>(_queue);
+ const PriorityIdx& idx = bmi::get<1>(*_queue);
for (const auto & entry : idx) {
os << "<li>" << entry._command->toString() << " (priority: "
<< (int)entry._command->getPriority() << ")</li>\n";
@@ -1238,8 +1247,9 @@ FileStorHandlerImpl::Stripe::dumpQueueHtml(std::ostream & os) const
namespace {
-void dump_lock_entry(const document::BucketId& bucketId, const FileStorHandlerImpl::Stripe::LockEntry& entry,
- api::LockingRequirements lock_mode, FileStorHandlerImpl::Clock::time_point now_ts, std::ostream& os) {
+void
+dump_lock_entry(const document::BucketId& bucketId, const FileStorHandlerImpl::Stripe::LockEntry& entry,
+ api::LockingRequirements lock_mode, FileStorHandlerImpl::Clock::time_point now_ts, std::ostream& os) {
os << api::MessageType::get(entry.msgType).getName() << ":" << entry.msgId << " ("
<< bucketId << ", " << api::to_string(lock_mode)
<< " lock) Running for " << std::chrono::duration_cast<std::chrono::seconds>(now_ts - entry.timestamp).count() << " secs<br/>\n";
@@ -1269,7 +1279,7 @@ FileStorHandlerImpl::Stripe::dumpQueue(std::ostream & os) const
{
vespalib::MonitorGuard guard(_lock);
- const PriorityIdx& idx = bmi::get<1>(_queue);
+ const PriorityIdx& idx = bmi::get<1>(*_queue);
for (const auto & entry : idx) {
os << entry._bucket.getBucketId() << ": " << entry._command->toString() << " (priority: "
<< (int)entry._command->getPriority() << ")\n";
@@ -1300,7 +1310,7 @@ FileStorHandlerImpl::getStatus(std::ostream& out, const framework::HttpUrlPath&
out << "</ul>\n";
}
- vespalib::LockGuard mergeGuard(_mergeStatesLock);
+ std::lock_guard mergeGuard(_mergeStatesLock);
out << "<tr><td>Active merge operations</td><td>" << _mergeStates.size() << "</td></tr>\n";
if (verbose) {
out << "<h4>Active merges</h4>\n";
diff --git a/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.h b/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.h
index a609473afd5..02dcfea0654 100644
--- a/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.h
+++ b/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.h
@@ -84,9 +84,9 @@ public:
api::MessageType::Id msgType;
api::StorageMessage::Id msgId;
- LockEntry() : timestamp(), priority(0), msgType(), msgId(0) { }
+ LockEntry() noexcept : timestamp(), priority(0), msgType(), msgId(0) { }
- LockEntry(uint8_t priority_, api::MessageType::Id msgType_, api::StorageMessage::Id msgId_)
+ LockEntry(uint8_t priority_, api::MessageType::Id msgType_, api::StorageMessage::Id msgId_) noexcept
: timestamp(Clock::now()), priority(priority_), msgType(msgType_), msgId(msgId_)
{ }
};
@@ -98,6 +98,9 @@ public:
};
Stripe(const FileStorHandlerImpl & owner, MessageSender & messageSender);
+ Stripe(Stripe &&) noexcept;
+ Stripe(const Stripe &) = delete;
+ Stripe & operator =(const Stripe &) = delete;
~Stripe();
void flush();
bool schedule(MessageEntry messageEntry);
@@ -111,7 +114,7 @@ public:
}
size_t getQueueSize() const {
vespalib::MonitorGuard guard(_lock);
- return _queue.size();
+ return _queue->size();
}
void release(const document::Bucket & bucket, api::LockingRequirements reqOfReleasedLock,
api::StorageMessage::Id lockMsgId);
@@ -133,8 +136,8 @@ public:
void dumpActiveHtml(std::ostream & os) const;
void dumpQueueHtml(std::ostream & os) const;
vespalib::Monitor & exposeLock() { return _lock; }
- PriorityQueue & exposeQueue() { return _queue; }
- BucketIdx & exposeBucketIdx() { return bmi::get<2>(_queue); }
+ PriorityQueue & exposeQueue() { return *_queue; }
+ BucketIdx & exposeBucketIdx() { return bmi::get<2>(*_queue); }
void setMetrics(FileStorStripeMetrics * metrics) { _metrics = metrics; }
private:
bool hasActive(vespalib::MonitorGuard & monitor, const AbortBucketOperationsCommand& cmd) const;
@@ -143,13 +146,13 @@ public:
FileStorHandler::LockedMessage getMessage(vespalib::MonitorGuard & guard, PriorityIdx & idx,
PriorityIdx::iterator iter);
using LockedBuckets = vespalib::hash_map<document::Bucket, MultiLockEntry, document::Bucket::hash>;
- const FileStorHandlerImpl &_owner;
- MessageSender &_messageSender;
- FileStorStripeMetrics *_metrics;
- vespalib::Monitor _lock;
- PriorityQueue _queue;
- LockedBuckets _lockedBuckets;
- uint32_t _active_merges;
+ const FileStorHandlerImpl &_owner;
+ MessageSender &_messageSender;
+ FileStorStripeMetrics *_metrics;
+ vespalib::Monitor _lock;
+ std::unique_ptr<PriorityQueue> _queue;
+ LockedBuckets _lockedBuckets;
+ uint32_t _active_merges;
};
struct Disk {
FileStorDiskMetrics * metrics;
@@ -207,9 +210,9 @@ public:
}
std::vector<Stripe> & getStripes() { return _stripes; }
private:
- uint32_t _nextStripeId;
- std::vector<Stripe> _stripes;
- std::atomic<DiskState> state;
+ uint32_t _nextStripeId;
+ std::vector<Stripe> _stripes;
+ std::atomic<DiskState> state;
};
class BucketLock : public FileStorHandler::BucketLockInterface {
@@ -224,9 +227,9 @@ public:
api::LockingRequirements lockingRequirements() const noexcept override { return _lockReq; }
private:
- Stripe & _stripe;
- document::Bucket _bucket;
- api::StorageMessage::Id _uniqueMsgId;
+ Stripe & _stripe;
+ document::Bucket _bucket;
+ api::StorageMessage::Id _uniqueMsgId;
api::LockingRequirements _lockReq;
};
@@ -285,7 +288,7 @@ private:
std::vector<Disk> _diskInfo;
MessageSender& _messageSender;
const document::BucketIdFactory& _bucketIdFactory;
- vespalib::Lock _mergeStatesLock;
+ mutable std::mutex _mergeStatesLock;
std::map<document::Bucket, MergeStatus::SP> _mergeStates;
uint32_t _getNextMessageTimeout;
const uint32_t _max_active_merges_per_stripe; // Read concurrently by stripes.
diff --git a/storage/src/vespa/storage/persistence/filestorage/filestormanager.cpp b/storage/src/vespa/storage/persistence/filestorage/filestormanager.cpp
index 85604299e85..0341e34d39d 100644
--- a/storage/src/vespa/storage/persistence/filestorage/filestormanager.cpp
+++ b/storage/src/vespa/storage/persistence/filestorage/filestormanager.cpp
@@ -871,7 +871,7 @@ FileStorManager::reportHtmlStatus(std::ostream& out, const framework::HttpUrlPat
namespace {
struct Deactivator {
- StorBucketDatabase::Decision operator()(document::BucketId::Type, StorBucketDatabase::Entry& data)
+ StorBucketDatabase::Decision operator() (document::BucketId::Type, StorBucketDatabase::Entry& data) noexcept
{
data.info.setActive(false);
return StorBucketDatabase::Decision::UPDATE;
diff --git a/storage/src/vespa/storage/persistence/filestorage/filestormetrics.cpp b/storage/src/vespa/storage/persistence/filestorage/filestormetrics.cpp
index a80b17d4f19..8e09291a507 100644
--- a/storage/src/vespa/storage/persistence/filestorage/filestormetrics.cpp
+++ b/storage/src/vespa/storage/persistence/filestorage/filestormetrics.cpp
@@ -57,6 +57,34 @@ FileStorThreadMetrics::OpWithRequestSize<BaseOp>::clone(
->assignValues(*this));
}
+template <typename BaseOp>
+FileStorThreadMetrics::OpWithTestAndSetFailed<BaseOp>::OpWithTestAndSetFailed(const std::string& id, const std::string& name, MetricSet* owner)
+ : BaseOp(id, name, owner),
+ test_and_set_failed("test_and_set_failed", {{"yamasdefault"}},
+ "Number of times operations were failed due to a "
+ "test-and-set condition mismatch", this)
+{
+}
+
+template <typename BaseOp>
+FileStorThreadMetrics::OpWithTestAndSetFailed<BaseOp>::~OpWithTestAndSetFailed() = default;
+
+// FIXME this has very non-intuitive semantics, ending up with copy&paste patterns (yet again...)
+template <typename BaseOp>
+MetricSet*
+FileStorThreadMetrics::OpWithTestAndSetFailed<BaseOp>::clone(
+ std::vector<Metric::UP>& ownerList,
+ CopyType copyType,
+ MetricSet* owner,
+ bool includeUnused) const
+{
+ if (copyType == INACTIVE) {
+ return MetricSet::clone(ownerList, INACTIVE, owner, includeUnused);
+ }
+ return static_cast<OpWithTestAndSetFailed<BaseOp>*>((new OpWithTestAndSetFailed<BaseOp>(this->getName(), this->_name, owner))
+ ->assignValues(*this));
+}
+
FileStorThreadMetrics::OpWithNotFound::OpWithNotFound(const std::string& id, const std::string& name, MetricSet* owner)
: Op(id, name, owner),
notFound("not_found", {},
@@ -81,7 +109,7 @@ FileStorThreadMetrics::OpWithNotFound::clone(std::vector<Metric::UP>& ownerList,
}
FileStorThreadMetrics::Update::Update(MetricSet* owner)
- : OpWithRequestSize("update", "Update", owner),
+ : OpWithTestAndSetFailed("update", "Update", owner),
latencyRead("latency_read", {}, "Latency of the source read in the request.", this)
{ }
@@ -122,9 +150,9 @@ FileStorThreadMetrics::FileStorThreadMetrics(const std::string& name, const std:
: MetricSet(name, {{"filestor"},{"partofsum"}}, desc),
operations("operations", {}, "Number of operations processed.", this),
failedOperations("failedoperations", {}, "Number of operations throwing exceptions.", this),
- put(lt, OpWithRequestSize<Op>("put", "Put"), this),
- get(lt, OpWithRequestSize<OpWithNotFound>("get", "Get"), this),
- remove(lt, OpWithRequestSize<OpWithNotFound>("remove", "Remove"), this),
+ put(lt, PutMetricType("put", "Put"), this),
+ get(lt, GetMetricType("get", "Get"), this),
+ remove(lt, RemoveMetricType("remove", "Remove"), this),
removeLocation(lt, Op("remove_location", "Remove location"), this),
statBucket(lt, Op("stat_bucket", "Stat bucket"), this),
update(lt, Update(), this),
@@ -258,8 +286,9 @@ template class metrics::LoadMetric<storage::FileStorThreadMetrics::Op>;
template class metrics::LoadMetric<storage::FileStorThreadMetrics::OpWithNotFound>;
template class metrics::LoadMetric<storage::FileStorThreadMetrics::Update>;
template class metrics::LoadMetric<storage::FileStorThreadMetrics::Visitor>;
-template class metrics::LoadMetric<storage::FileStorThreadMetrics::OpWithRequestSize<storage::FileStorThreadMetrics::Op>>;
-template class metrics::LoadMetric<storage::FileStorThreadMetrics::OpWithRequestSize<storage::FileStorThreadMetrics::OpWithNotFound>>;
+template class metrics::LoadMetric<storage::FileStorThreadMetrics::PutMetricType>;
+template class metrics::LoadMetric<storage::FileStorThreadMetrics::GetMetricType>;
+template class metrics::LoadMetric<storage::FileStorThreadMetrics::RemoveMetricType>;
template class metrics::SumMetric<storage::FileStorThreadMetrics::Op>;
template class metrics::SumMetric<storage::FileStorThreadMetrics::OpWithNotFound>;
template class metrics::SumMetric<storage::FileStorThreadMetrics::Update>;
diff --git a/storage/src/vespa/storage/persistence/filestorage/filestormetrics.h b/storage/src/vespa/storage/persistence/filestorage/filestormetrics.h
index be1c5c48213..1ee47495502 100644
--- a/storage/src/vespa/storage/persistence/filestorage/filestormetrics.h
+++ b/storage/src/vespa/storage/persistence/filestorage/filestormetrics.h
@@ -44,6 +44,17 @@ struct FileStorThreadMetrics : public metrics::MetricSet
MetricSet* owner, bool includeUnused) const override;
};
+ template <typename BaseOp>
+ struct OpWithTestAndSetFailed : BaseOp {
+ metrics::LongCountMetric test_and_set_failed;
+
+ OpWithTestAndSetFailed(const std::string& id, const std::string& name, MetricSet* owner = nullptr);
+ ~OpWithTestAndSetFailed() override;
+
+ MetricSet * clone(std::vector<Metric::UP>& ownerList, CopyType copyType,
+ MetricSet* owner, bool includeUnused) const override;
+ };
+
struct OpWithNotFound : Op {
metrics::LongCountMetric notFound;
@@ -53,7 +64,7 @@ struct FileStorThreadMetrics : public metrics::MetricSet
MetricSet* owner, bool includeUnused) const override;
};
- struct Update : OpWithRequestSize<OpWithNotFound> {
+ struct Update : OpWithTestAndSetFailed<OpWithRequestSize<OpWithNotFound>> {
metrics::LongAverageMetric latencyRead;
explicit Update(MetricSet* owner = nullptr);
@@ -73,11 +84,16 @@ struct FileStorThreadMetrics : public metrics::MetricSet
MetricSet* owner, bool includeUnused) const override;
};
+ // FIXME this daisy-chaining approach to metric set variants is not the prettiest...
+ using PutMetricType = OpWithTestAndSetFailed<OpWithRequestSize<Op>>;
+ using GetMetricType = OpWithRequestSize<OpWithNotFound>;
+ using RemoveMetricType = OpWithTestAndSetFailed<OpWithRequestSize<OpWithNotFound>>;
+
metrics::LongCountMetric operations;
metrics::LongCountMetric failedOperations;
- metrics::LoadMetric<OpWithRequestSize<Op>> put;
- metrics::LoadMetric<OpWithRequestSize<OpWithNotFound>> get;
- metrics::LoadMetric<OpWithRequestSize<OpWithNotFound>> remove;
+ metrics::LoadMetric<PutMetricType> put;
+ metrics::LoadMetric<GetMetricType> get;
+ metrics::LoadMetric<RemoveMetricType> remove;
metrics::LoadMetric<Op> removeLocation;
metrics::LoadMetric<Op> statBucket;
metrics::LoadMetric<Update> update;
diff --git a/storage/src/vespa/storage/persistence/filestorage/modifiedbucketchecker.cpp b/storage/src/vespa/storage/persistence/filestorage/modifiedbucketchecker.cpp
index 3db3ec5dfcd..60b2c625d43 100644
--- a/storage/src/vespa/storage/persistence/filestorage/modifiedbucketchecker.cpp
+++ b/storage/src/vespa/storage/persistence/filestorage/modifiedbucketchecker.cpp
@@ -73,7 +73,7 @@ void
ModifiedBucketChecker::configure(
std::unique_ptr<vespa::config::content::core::StorServerConfig> newConfig)
{
- vespalib::LockGuard lock(_stateLock);
+ std::lock_guard lock(_stateLock);
if (newConfig->bucketRecheckingChunkSize < 1) {
throw config::InvalidConfigException(
"Cannot have bucket rechecking chunk size of less than 1");
@@ -135,7 +135,7 @@ ModifiedBucketChecker::onInternalReply(
const std::shared_ptr<api::InternalReply>& r)
{
if (r->getType() == RecheckBucketInfoReply::ID) {
- vespalib::LockGuard guard(_stateLock);
+ std::lock_guard guard(_stateLock);
assert(_pendingRequests > 0);
--_pendingRequests;
if (_pendingRequests == 0 && moreChunksRemaining()) {
@@ -158,7 +158,7 @@ ModifiedBucketChecker::requestModifiedBucketsFromProvider(document::BucketSpace
return false;
}
{
- vespalib::LockGuard guard(_stateLock);
+ std::lock_guard guard(_stateLock);
_rechecksNotStarted.reset(bucketSpace, result.getList());
}
return true;
@@ -202,7 +202,7 @@ ModifiedBucketChecker::tick()
// we want getModifiedBuckets() to called outside the lock.
bool shouldRequestFromProvider = false;
{
- vespalib::LockGuard guard(_stateLock);
+ std::lock_guard guard(_stateLock);
if (!currentChunkFinished()) {
return true;
}
@@ -216,7 +216,7 @@ ModifiedBucketChecker::tick()
std::vector<RecheckBucketInfoCommand::SP> commandsToSend;
{
- vespalib::LockGuard guard(_stateLock);
+ std::lock_guard guard(_stateLock);
if (moreChunksRemaining()) {
nextRecheckChunk(commandsToSend);
}
diff --git a/storage/src/vespa/storage/persistence/filestorage/modifiedbucketchecker.h b/storage/src/vespa/storage/persistence/filestorage/modifiedbucketchecker.h
index 05389cec3da..7114d1f676f 100644
--- a/storage/src/vespa/storage/persistence/filestorage/modifiedbucketchecker.h
+++ b/storage/src/vespa/storage/persistence/filestorage/modifiedbucketchecker.h
@@ -86,7 +86,7 @@ private:
framework::Thread::UP _thread;
config::ConfigFetcher _configFetcher;
vespalib::Monitor _monitor;
- vespalib::Lock _stateLock;
+ std::mutex _stateLock;
CyclicBucketSpaceIterator::UP _bucketSpaces;
BucketIdListResult _rechecksNotStarted;
size_t _pendingRequests;
diff --git a/storage/src/vespa/storage/persistence/persistencethread.cpp b/storage/src/vespa/storage/persistence/persistencethread.cpp
index a39abc7fa58..6cf0ec194e1 100644
--- a/storage/src/vespa/storage/persistence/persistencethread.cpp
+++ b/storage/src/vespa/storage/persistence/persistencethread.cpp
@@ -177,6 +177,9 @@ PersistenceThread::handlePut(api::PutCommand& cmd, MessageTracker::UP trackerUP)
metrics.request_size.addValue(cmd.getApproxByteSize());
if (tasConditionExists(cmd) && !tasConditionMatches(cmd, tracker, tracker.context())) {
+ // Will also count condition parse failures etc as TaS failures, but
+ // those results _will_ increase the error metrics as well.
+ metrics.test_and_set_failed.inc();
return trackerUP;
}
@@ -204,6 +207,7 @@ PersistenceThread::handleRemove(api::RemoveCommand& cmd, MessageTracker::UP trac
metrics.request_size.addValue(cmd.getApproxByteSize());
if (tasConditionExists(cmd) && !tasConditionMatches(cmd, tracker, tracker.context())) {
+ metrics.test_and_set_failed.inc();
return trackerUP;
}
@@ -243,6 +247,7 @@ PersistenceThread::handleUpdate(api::UpdateCommand& cmd, MessageTracker::UP trac
metrics.request_size.addValue(cmd.getApproxByteSize());
if (tasConditionExists(cmd) && !tasConditionMatches(cmd, tracker, tracker.context(), cmd.getUpdate()->getCreateIfNonExistent())) {
+ metrics.test_and_set_failed.inc();
return trackerUP;
}
diff --git a/storage/src/vespa/storage/persistence/persistenceutil.cpp b/storage/src/vespa/storage/persistence/persistenceutil.cpp
index 63ac5405fab..775e05488a9 100644
--- a/storage/src/vespa/storage/persistence/persistenceutil.cpp
+++ b/storage/src/vespa/storage/persistence/persistenceutil.cpp
@@ -68,12 +68,22 @@ MessageTracker::setMetric(FileStorThreadMetrics::Op& metric) {
MessageTracker::~MessageTracker() = default;
+bool MessageTracker::count_result_as_failure() const noexcept {
+ // Explicitly don't treat TaS failures as regular failures. These are tracked separately
+ // for operations that support TaS conditions.
+ if (hasReply() && getReply().getResult().failed()) {
+ return (getReply().getResult().getResult() != api::ReturnCode::TEST_AND_SET_CONDITION_FAILED);
+ }
+ return (getResult().failed()
+ && (getResult().getResult() != api::ReturnCode::TEST_AND_SET_CONDITION_FAILED));
+}
+
void
MessageTracker::sendReply() {
if ( ! _msg->getType().isReply()) {
generateReply(static_cast<api::StorageCommand &>(*_msg));
}
- if ((hasReply() && getReply().getResult().failed()) || getResult().failed()) {
+ if (count_result_as_failure()) {
_env._metrics.failedOperations.inc();
}
vespalib::duration duration = vespalib::from_s(_timer.getElapsedTimeAsDouble()/1000.0);
@@ -140,7 +150,11 @@ MessageTracker::generateReply(api::StorageCommand& cmd)
}
if (!_reply->getResult().success()) {
- _metric->failed.inc();
+ // TaS failures are tracked separately and explicitly in the put/update/remove paths,
+ // so don't double-count them here.
+ if (_reply->getResult().getResult() != api::ReturnCode::TEST_AND_SET_CONDITION_FAILED) {
+ _metric->failed.inc();
+ }
LOGBP(debug, "Failed to handle command %s: %s",
cmd.toString().c_str(),
_result.toString().c_str());
diff --git a/storage/src/vespa/storage/persistence/persistenceutil.h b/storage/src/vespa/storage/persistence/persistenceutil.h
index a57ef186b46..51eb2b4b590 100644
--- a/storage/src/vespa/storage/persistence/persistenceutil.h
+++ b/storage/src/vespa/storage/persistence/persistenceutil.h
@@ -78,6 +78,9 @@ public:
private:
MessageTracker(PersistenceUtil & env, MessageSender & replySender, bool updateBucketInfo,
FileStorHandler::BucketLockInterface::SP bucketLock, api::StorageMessage::SP msg);
+
+ [[nodiscard]] bool count_result_as_failure() const noexcept;
+
bool _sendReply;
bool _updateBucketInfo;
FileStorHandler::BucketLockInterface::SP _bucketLock;
diff --git a/storage/src/vespa/storage/storageserver/bouncer.cpp b/storage/src/vespa/storage/storageserver/bouncer.cpp
index bc9708f70a2..8a0cffedd05 100644
--- a/storage/src/vespa/storage/storageserver/bouncer.cpp
+++ b/storage/src/vespa/storage/storageserver/bouncer.cpp
@@ -72,7 +72,7 @@ Bouncer::configure(std::unique_ptr<vespa::config::content::core::StorBouncerConf
{
log_config_received(*config);
validateConfig(*config);
- vespalib::LockGuard lock(_lock);
+ std::lock_guard lock(_lock);
_config = std::move(config);
}
@@ -248,7 +248,7 @@ Bouncer::onDown(const std::shared_ptr<api::StorageMessage>& msg)
bool abortLoadWhenClusterDown;
int feedPriorityLowerBound;
{
- vespalib::LockGuard lock(_lock);
+ std::lock_guard lock(_lock);
state = &getDerivedNodeState(msg->getBucket().getBucketSpace()).getState();
maxClockSkewInSeconds = _config->maxClockSkewSeconds;
abortLoadWhenClusterDown = _config->stopExternalLoadWhenClusterDown;
@@ -325,7 +325,7 @@ deriveNodeState(const lib::NodeState &reportedNodeState,
void
Bouncer::handleNewState()
{
- vespalib::LockGuard lock(_lock);
+ std::lock_guard lock(_lock);
const auto reportedNodeState = *_component.getStateUpdater().getReportedNodeState();
const auto clusterStateBundle = _component.getStateUpdater().getClusterStateBundle();
const auto &clusterState = *clusterStateBundle->getBaselineClusterState();
diff --git a/storage/src/vespa/storage/storageserver/bouncer.h b/storage/src/vespa/storage/storageserver/bouncer.h
index 19c8e084c7d..ee51114fcbe 100644
--- a/storage/src/vespa/storage/storageserver/bouncer.h
+++ b/storage/src/vespa/storage/storageserver/bouncer.h
@@ -17,7 +17,6 @@
#include <vespa/storage/common/storagecomponent.h>
#include <vespa/storage/common/storagelink.h>
#include <vespa/storage/config/config-stor-bouncer.h>
-#include <vespa/vespalib/util/sync.h>
#include <unordered_map>
namespace config { class ConfigUri; }
@@ -32,8 +31,8 @@ class Bouncer : public StorageLink,
{
std::unique_ptr<vespa::config::content::core::StorBouncerConfig> _config;
StorageComponent _component;
- vespalib::Lock _lock;
- lib::NodeState _baselineNodeState;
+ std::mutex _lock;
+ lib::NodeState _baselineNodeState;
using BucketSpaceNodeStateMapping = std::unordered_map<document::BucketSpace, lib::NodeState, document::BucketSpace::hash>;
BucketSpaceNodeStateMapping _derivedNodeStates;
const lib::State* _clusterState;
diff --git a/storage/src/vespa/storage/storageserver/changedbucketownershiphandler.cpp b/storage/src/vespa/storage/storageserver/changedbucketownershiphandler.cpp
index 66e0209d4b7..aec0adf790c 100644
--- a/storage/src/vespa/storage/storageserver/changedbucketownershiphandler.cpp
+++ b/storage/src/vespa/storage/storageserver/changedbucketownershiphandler.cpp
@@ -57,7 +57,7 @@ ChangedBucketOwnershipHandler::configure(
void
ChangedBucketOwnershipHandler::reloadClusterState()
{
- vespalib::LockGuard guard(_stateLock);
+ std::lock_guard guard(_stateLock);
const auto clusterStateBundle = _component.getStateUpdater().getClusterStateBundle();
setCurrentOwnershipWithStateNoLock(*clusterStateBundle);
}
@@ -258,7 +258,7 @@ ChangedBucketOwnershipHandler::onSetSystemState(
// can get through in the off-case that the lower level storage links
// don't apply the state immediately for some reason.
{
- vespalib::LockGuard guard(_stateLock);
+ std::lock_guard guard(_stateLock);
oldOwnership = _currentOwnership;
setCurrentOwnershipWithStateNoLock(stateCmd->getClusterStateBundle());
newOwnership = _currentOwnership;
@@ -301,7 +301,7 @@ ChangedBucketOwnershipHandler::onSetSystemState(
void
ChangedBucketOwnershipHandler::storageDistributionChanged()
{
- vespalib::LockGuard guard(_stateLock);
+ std::lock_guard guard(_stateLock);
_currentOwnership = std::make_shared<OwnershipState>(
_component.getBucketSpaceRepo(), _currentState);
}
@@ -345,7 +345,7 @@ ChangedBucketOwnershipHandler::isMutatingExternalOperation(
ChangedBucketOwnershipHandler::OwnershipState::CSP
ChangedBucketOwnershipHandler::getCurrentOwnershipState() const
{
- vespalib::LockGuard guard(_stateLock);
+ std::lock_guard guard(_stateLock);
return _currentOwnership;
}
diff --git a/storage/src/vespa/storage/storageserver/changedbucketownershiphandler.h b/storage/src/vespa/storage/storageserver/changedbucketownershiphandler.h
index 1e524b6b2fc..0fc456b515c 100644
--- a/storage/src/vespa/storage/storageserver/changedbucketownershiphandler.h
+++ b/storage/src/vespa/storage/storageserver/changedbucketownershiphandler.h
@@ -4,7 +4,6 @@
#include <vespa/document/bucket/bucketid.h>
#include <vespa/storage/common/storagelink.h>
#include <vespa/vdslib/distribution/distribution.h>
-#include <vespa/vespalib/util/sync.h>
#include <vespa/metrics/metrics.h>
#include <vespa/config/config.h>
#include <vespa/config-persistence.h>
@@ -110,9 +109,9 @@ public:
private:
ServiceLayerComponent _component;
- Metrics _metrics;
+ Metrics _metrics;
config::ConfigFetcher _configFetcher;
- vespalib::Lock _stateLock;
+ mutable std::mutex _stateLock;
std::shared_ptr<const lib::ClusterStateBundle> _currentState;
OwnershipState::CSP _currentOwnership;
diff --git a/storage/src/vespa/storage/storageserver/communicationmanager.cpp b/storage/src/vespa/storage/storageserver/communicationmanager.cpp
index cfd74bacf16..8a7cc8ffc61 100644
--- a/storage/src/vespa/storage/storageserver/communicationmanager.cpp
+++ b/storage/src/vespa/storage/storageserver/communicationmanager.cpp
@@ -187,7 +187,7 @@ CommunicationManager::handleReply(std::unique_ptr<mbus::Reply> reply)
if (protocolName == documentapi::DocumentProtocol::NAME) {
std::shared_ptr<api::StorageCommand> originalCommand;
{
- vespalib::LockGuard lock(_messageBusSentLock);
+ std::lock_guard lock(_messageBusSentLock);
typedef std::map<api::StorageMessage::Id, api::StorageCommand::SP> MessageMap;
MessageMap::iterator iter(_messageBusSent.find(reply->getContext().value.UINT64));
if (iter != _messageBusSent.end()) {
@@ -601,7 +601,7 @@ CommunicationManager::sendCommand(
mbusMsg->setRetryEnabled(false);
{
- vespalib::LockGuard lock(_messageBusSentLock);
+ std::lock_guard lock(_messageBusSentLock);
_messageBusSent[msg->getMsgId()] = msg;
}
sendMessageBusMessage(msg, std::move(mbusMsg), address.getRoute());
diff --git a/storage/src/vespa/storage/storageserver/communicationmanager.h b/storage/src/vespa/storage/storageserver/communicationmanager.h
index 7ac9d575ee6..b10b12f404e 100644
--- a/storage/src/vespa/storage/storageserver/communicationmanager.h
+++ b/storage/src/vespa/storage/storageserver/communicationmanager.h
@@ -112,7 +112,7 @@ private:
std::unique_ptr<mbus::DestinationSession> _messageBusSession;
std::unique_ptr<mbus::SourceSession> _sourceSession;
- vespalib::Lock _messageBusSentLock;
+ std::mutex _messageBusSentLock;
std::map<api::StorageMessage::Id, std::shared_ptr<api::StorageCommand> > _messageBusSent;
config::ConfigUri _configUri;
@@ -137,7 +137,7 @@ public:
void dispatch_sync(std::shared_ptr<api::StorageMessage> msg) override;
void dispatch_async(std::shared_ptr<api::StorageMessage> msg) override;
- mbus::RPCMessageBus& getMessageBus() { assert(_mbus.get()); return *_mbus; }
+ mbus::RPCMessageBus& getMessageBus() { return *_mbus; }
const PriorityConverter& getPriorityConverter() const { return _docApiConverter.getPriorityConverter(); }
/**
diff --git a/storage/src/vespa/storage/storageserver/configurable_bucket_resolver.h b/storage/src/vespa/storage/storageserver/configurable_bucket_resolver.h
index 0800cc9612e..34e30aaea48 100644
--- a/storage/src/vespa/storage/storageserver/configurable_bucket_resolver.h
+++ b/storage/src/vespa/storage/storageserver/configurable_bucket_resolver.h
@@ -21,7 +21,7 @@ public:
using BucketSpaceMapping = std::unordered_map<vespalib::string, document::BucketSpace, vespalib::hash<vespalib::string>>;
const BucketSpaceMapping _type_to_space;
public:
- explicit ConfigurableBucketResolver(BucketSpaceMapping type_to_space)
+ explicit ConfigurableBucketResolver(BucketSpaceMapping type_to_space) noexcept
: _type_to_space(std::move(type_to_space))
{}
diff --git a/storage/src/vespa/storage/storageserver/mergethrottler.cpp b/storage/src/vespa/storage/storageserver/mergethrottler.cpp
index 83e31b78954..7999514ac00 100644
--- a/storage/src/vespa/storage/storageserver/mergethrottler.cpp
+++ b/storage/src/vespa/storage/storageserver/mergethrottler.cpp
@@ -9,6 +9,7 @@
#include <vespa/vespalib/stllike/asciistream.h>
#include <vespa/vespalib/util/stringfmt.h>
#include <algorithm>
+#include <cassert>
#include <vespa/log/log.h>
LOG_SETUP(".mergethrottler");
@@ -214,7 +215,7 @@ MergeThrottler::MergeThrottler(
void
MergeThrottler::configure(std::unique_ptr<vespa::config::content::core::StorServerConfig> newConfig)
{
- vespalib::LockGuard lock(_stateLock);
+ std::lock_guard lock(_stateLock);
if (newConfig->maxMergesPerNode < 1) {
throw config::InvalidConfigException("Cannot have a max merge count of less than 1");
@@ -277,7 +278,7 @@ MergeThrottler::onClose()
_closing = true;
}
if (LOG_WOULD_LOG(debug)) {
- vespalib::LockGuard lock(_stateLock);
+ std::lock_guard lock(_stateLock);
LOG(debug, "onClose; active: %zu, queued: %zu",
_merges.size(), _queue.size());
}
@@ -700,7 +701,7 @@ void MergeThrottler::backpressure_bounce_all_queued_merges(MessageGuard& guard)
}
bool MergeThrottler::backpressure_mode_active() const {
- vespalib::LockGuard lock(_stateLock);
+ std::lock_guard lock(_stateLock);
return backpressure_mode_active_no_lock();
}
@@ -1072,7 +1073,7 @@ MergeThrottler::onDown(const std::shared_ptr<api::StorageMessage>& msg)
lock.broadcast();
return true;
} else if (isDiffCommand(*msg)) {
- vespalib::LockGuard lock(_stateLock);
+ std::lock_guard lock(_stateLock);
auto& cmd = static_cast<api::StorageCommand&>(*msg);
if (bucketIsUnknownOrAborted(cmd.getBucket())) {
sendUp(makeAbortReply(cmd, "no state recorded for bucket in merge "
@@ -1264,7 +1265,7 @@ void
MergeThrottler::reportHtmlStatus(std::ostream& out,
const framework::HttpUrlPath&) const
{
- vespalib::LockGuard lock(_stateLock);
+ std::lock_guard lock(_stateLock);
{
out << "<p>Max pending: "
<< _throttlePolicy->getMaxPendingCount()
diff --git a/storage/src/vespa/storage/storageserver/mergethrottler.h b/storage/src/vespa/storage/storageserver/mergethrottler.h
index d62e9a042b2..b2087600105 100644
--- a/storage/src/vespa/storage/storageserver/mergethrottler.h
+++ b/storage/src/vespa/storage/storageserver/mergethrottler.h
@@ -155,7 +155,7 @@ private:
mbus::StaticThrottlePolicy::UP _throttlePolicy;
uint64_t _queueSequence; // TODO: move into a stable priority queue class
vespalib::Monitor _messageLock;
- vespalib::Lock _stateLock;
+ mutable std::mutex _stateLock;
config::ConfigFetcher _configFetcher;
// Messages pending to be processed by the worker thread
std::vector<api::StorageMessage::SP> _messagesDown;
@@ -205,7 +205,7 @@ public:
mbus::StaticThrottlePolicy& getThrottlePolicy() { return *_throttlePolicy; }
// For unit testing only
vespalib::Monitor& getMonitor() { return _messageLock; }
- vespalib::Lock& getStateLock() { return _stateLock; }
+ std::mutex & getStateLock() { return _stateLock; }
Metrics& getMetrics() { return *_metrics; }
std::size_t getMaxQueueSize() const { return _maxQueueSize; }
diff --git a/storage/src/vespa/storage/storageserver/opslogger.cpp b/storage/src/vespa/storage/storageserver/opslogger.cpp
index b6bceabf7a1..3e1fc34d470 100644
--- a/storage/src/vespa/storage/storageserver/opslogger.cpp
+++ b/storage/src/vespa/storage/storageserver/opslogger.cpp
@@ -42,7 +42,7 @@ OpsLogger::onClose()
void
OpsLogger::configure(std::unique_ptr<vespa::config::content::core::StorOpsloggerConfig> config)
{
- vespalib::LockGuard lock(_lock);
+ std::lock_guard lock(_lock);
// If no change in state, ignore
if (config->targetfile == _fileName) return;
// If a change we need to close old handle if open
@@ -79,7 +79,7 @@ OpsLogger::onPutReply(const std::shared_ptr<api::PutReply>& msg)
<< "\tPUT\t" << msg->getDocumentId() << "\t"
<< msg->getResult() << "\n";
{
- vespalib::LockGuard lock(_lock);
+ std::lock_guard lock(_lock);
if (_targetFile == nullptr) return false;
fwrite(ost.str().c_str(), ost.str().length(), 1, _targetFile);
fflush(_targetFile);
@@ -96,7 +96,7 @@ OpsLogger::onUpdateReply(const std::shared_ptr<api::UpdateReply>& msg)
<< "\tUPDATE\t" << msg->getDocumentId() << "\t"
<< msg->getResult() << "\n";
{
- vespalib::LockGuard lock(_lock);
+ std::lock_guard lock(_lock);
if (_targetFile == nullptr) return false;
fwrite(ost.str().c_str(), ost.str().length(), 1, _targetFile);
fflush(_targetFile);
@@ -113,7 +113,7 @@ OpsLogger::onRemoveReply(const std::shared_ptr<api::RemoveReply>& msg)
<< "\tREMOVE\t" << msg->getDocumentId() << "\t"
<< msg->getResult() << "\n";
{
- vespalib::LockGuard lock(_lock);
+ std::lock_guard lock(_lock);
if (_targetFile == nullptr) return false;
fwrite(ost.str().c_str(), ost.str().length(), 1, _targetFile);
fflush(_targetFile);
@@ -130,7 +130,7 @@ OpsLogger::onGetReply(const std::shared_ptr<api::GetReply>& msg)
<< "\tGET\t" << msg->getDocumentId() << "\t"
<< msg->getResult() << "\n";
{
- vespalib::LockGuard lock(_lock);
+ std::lock_guard lock(_lock);
if (_targetFile == nullptr) return false;
fwrite(ost.str().c_str(), ost.str().length(), 1, _targetFile);
fflush(_targetFile);
diff --git a/storage/src/vespa/storage/storageserver/opslogger.h b/storage/src/vespa/storage/storageserver/opslogger.h
index 1e903bb1ef3..cecadf9ed1d 100644
--- a/storage/src/vespa/storage/storageserver/opslogger.h
+++ b/storage/src/vespa/storage/storageserver/opslogger.h
@@ -13,7 +13,6 @@
#include <vespa/storageapi/messageapi/storagemessage.h>
#include <vespa/storageapi/message/state.h>
#include <vespa/storage/config/config-stor-opslogger.h>
-#include <vespa/vespalib/util/sync.h>
#include <vespa/config/config.h>
namespace storage {
@@ -23,7 +22,7 @@ class OpsLogger : public StorageLink,
public:
explicit OpsLogger(StorageComponentRegister&,
const config::ConfigUri & configUri);
- ~OpsLogger();
+ ~OpsLogger() override;
void onClose() override;
void print(std::ostream& out, bool verbose, const std::string& indent) const override;
@@ -36,9 +35,9 @@ public:
bool onDown(const std::shared_ptr<api::StorageMessage>&) override { return false; };
void configure(std::unique_ptr<vespa::config::content::core::StorOpsloggerConfig> config) override;
private:
- vespalib::Lock _lock;
- std::string _fileName;
- FILE* _targetFile;
+ std::mutex _lock;
+ std::string _fileName;
+ FILE * _targetFile;
framework::Component _component;
config::ConfigFetcher _configFetcher;
diff --git a/storage/src/vespa/storage/storageserver/priorityconverter.cpp b/storage/src/vespa/storage/storageserver/priorityconverter.cpp
index 8d0f18b4157..41bea1b44df 100644
--- a/storage/src/vespa/storage/storageserver/priorityconverter.cpp
+++ b/storage/src/vespa/storage/storageserver/priorityconverter.cpp
@@ -31,7 +31,7 @@ PriorityConverter::toStoragePriority(documentapi::Priority::Value documentApiPri
documentapi::Priority::Value
PriorityConverter::toDocumentPriority(uint8_t storagePriority) const
{
- vespalib::LockGuard guard(_mutex);
+ std::lock_guard guard(_mutex);
std::map<uint8_t, documentapi::Priority::Value>::const_iterator iter =
_reverseMapping.lower_bound(storagePriority);
@@ -63,7 +63,7 @@ PriorityConverter::configure(std::unique_ptr<vespa::config::content::core::StorP
_mapping[documentapi::Priority::PRI_VERY_LOW] = config->veryLow;
_mapping[documentapi::Priority::PRI_LOWEST] = config->lowest;
- vespalib::LockGuard guard(_mutex);
+ std::lock_guard guard(_mutex);
_reverseMapping.clear();
_reverseMapping[config->highest] = documentapi::Priority::PRI_HIGHEST;
_reverseMapping[config->veryHigh] = documentapi::Priority::PRI_VERY_HIGH;
diff --git a/storage/src/vespa/storage/storageserver/priorityconverter.h b/storage/src/vespa/storage/storageserver/priorityconverter.h
index f4cfb7488e2..08669c672d5 100644
--- a/storage/src/vespa/storage/storageserver/priorityconverter.h
+++ b/storage/src/vespa/storage/storageserver/priorityconverter.h
@@ -5,9 +5,9 @@
#include <vespa/storage/config/config-stor-prioritymapping.h>
#include <vespa/config/helper/configfetcher.h>
#include <vespa/documentapi/messagebus/priority.h>
-#include <vespa/vespalib/util/sync.h>
#include <atomic>
#include <array>
+#include <mutex>
namespace config {class ConfigUri; }
@@ -20,8 +20,8 @@ class PriorityConverter
public:
typedef vespa::config::content::core::StorPrioritymappingConfig Config;
- PriorityConverter(const config::ConfigUri& configUri);
- ~PriorityConverter();
+ explicit PriorityConverter(const config::ConfigUri& configUri);
+ ~PriorityConverter() override;
/** Converts the given priority into a storage api priority number. */
uint8_t toStoragePriority(documentapi::Priority::Value) const;
@@ -40,7 +40,7 @@ private:
std::array<std::atomic<uint8_t>, PRI_ENUM_SIZE> _mapping;
std::map<uint8_t, documentapi::Priority::Value> _reverseMapping;
- vespalib::Lock _mutex;
+ mutable std::mutex _mutex;
config::ConfigFetcher _configFetcher;
};
diff --git a/storage/src/vespa/storage/storageserver/rpc/shared_rpc_resources.cpp b/storage/src/vespa/storage/storageserver/rpc/shared_rpc_resources.cpp
index 8896df7a155..553132507ab 100644
--- a/storage/src/vespa/storage/storageserver/rpc/shared_rpc_resources.cpp
+++ b/storage/src/vespa/storage/storageserver/rpc/shared_rpc_resources.cpp
@@ -66,8 +66,8 @@ SharedRpcResources::SharedRpcResources(const config::ConfigUri& config_uri,
: _thread_pool(std::make_unique<FastOS_ThreadPool>(1024*60)),
_transport(std::make_unique<FNET_Transport>(rpc_thread_pool_size)),
_orb(std::make_unique<FRT_Supervisor>(_transport.get())),
- _slobrok_register(std::make_unique<slobrok::api::RegisterAPI>(*_orb, config_uri)),
- _slobrok_mirror(std::make_unique<slobrok::api::MirrorAPI>(*_orb, config_uri)),
+ _slobrok_register(std::make_unique<slobrok::api::RegisterAPI>(*_orb, slobrok::ConfiguratorFactory(config_uri))),
+ _slobrok_mirror(std::make_unique<slobrok::api::MirrorAPI>(*_orb, slobrok::ConfiguratorFactory(config_uri))),
_target_factory(std::make_unique<RpcTargetFactoryImpl>(*_orb)),
_hostname(vespalib::HostName::get()),
_rpc_server_port(rpc_server_port),
diff --git a/storage/src/vespa/storage/storageserver/service_layer_error_listener.h b/storage/src/vespa/storage/storageserver/service_layer_error_listener.h
index 6995459e333..5dd01329ff4 100644
--- a/storage/src/vespa/storage/storageserver/service_layer_error_listener.h
+++ b/storage/src/vespa/storage/storageserver/service_layer_error_listener.h
@@ -23,7 +23,7 @@ class ServiceLayerErrorListener : public ProviderErrorListener {
std::atomic<bool> _shutdown_initiated;
public:
ServiceLayerErrorListener(StorageComponent& component,
- MergeThrottler& merge_throttler)
+ MergeThrottler& merge_throttler) noexcept
: _component(component),
_merge_throttler(merge_throttler),
_shutdown_initiated(false)
diff --git a/storage/src/vespa/storage/storageserver/servicelayernode.cpp b/storage/src/vespa/storage/storageserver/servicelayernode.cpp
index 4f1db0e1b30..1edfcde393b 100644
--- a/storage/src/vespa/storage/storageserver/servicelayernode.cpp
+++ b/storage/src/vespa/storage/storageserver/servicelayernode.cpp
@@ -91,7 +91,7 @@ ServiceLayerNode::subscribeToConfigs()
StorageNode::subscribeToConfigs();
_configFetcher.reset(new config::ConfigFetcher(_configUri.getContext()));
- vespalib::LockGuard configLockGuard(_configLock);
+ std::lock_guard configLockGuard(_configLock);
// Verify and set disk count
if (_serverConfig->diskCount != 0
&& _serverConfig->diskCount != _partitions.size())
diff --git a/storage/src/vespa/storage/storageserver/statemanager.cpp b/storage/src/vespa/storage/storageserver/statemanager.cpp
index da221e312e2..db4dfd0323e 100644
--- a/storage/src/vespa/storage/storageserver/statemanager.cpp
+++ b/storage/src/vespa/storage/storageserver/statemanager.cpp
@@ -204,14 +204,14 @@ StateManager::getClusterStateBundle() const
void
StateManager::addStateListener(StateListener& listener)
{
- vespalib::LockGuard lock(_listenerLock);
+ std::lock_guard lock(_listenerLock);
_stateListeners.push_back(&listener);
}
void
StateManager::removeStateListener(StateListener& listener)
{
- vespalib::LockGuard lock(_listenerLock);
+ std::lock_guard lock(_listenerLock);
for (auto it = _stateListeners.begin(); it != _stateListeners.end();) {
if (*it == &listener) {
it = _stateListeners.erase(it);
@@ -224,7 +224,7 @@ StateManager::removeStateListener(StateListener& listener)
struct StateManager::ExternalStateLock : public NodeStateUpdater::Lock {
StateManager& _manager;
- explicit ExternalStateLock(StateManager& manager) : _manager(manager) {}
+ explicit ExternalStateLock(StateManager& manager) noexcept : _manager(manager) {}
~ExternalStateLock() override {
{
vespalib::MonitorGuard lock(_manager._stateLock);
@@ -282,7 +282,7 @@ StateManager::notifyStateListeners()
if (_notifyingListeners) {
return;
}
- vespalib::LockGuard listenerLock(_listenerLock);
+ std::lock_guard listenerLock(_listenerLock);
_notifyingListeners = true;
lib::NodeState::SP newState;
while (true) {
diff --git a/storage/src/vespa/storage/storageserver/statemanager.h b/storage/src/vespa/storage/storageserver/statemanager.h
index 3d231c070ef..b6f43eb270e 100644
--- a/storage/src/vespa/storage/storageserver/statemanager.h
+++ b/storage/src/vespa/storage/storageserver/statemanager.h
@@ -45,7 +45,7 @@ class StateManager : public NodeStateUpdater,
StorageComponent _component;
metrics::MetricManager& _metricManager;
vespalib::Monitor _stateLock;
- vespalib::Lock _listenerLock;
+ std::mutex _listenerLock;
std::shared_ptr<lib::NodeState> _nodeState;
std::shared_ptr<lib::NodeState> _nextNodeState;
using ClusterStateBundle = lib::ClusterStateBundle;
diff --git a/storage/src/vespa/storage/storageserver/storagenode.cpp b/storage/src/vespa/storage/storageserver/storagenode.cpp
index aa50391c037..c1cfc97bab6 100644
--- a/storage/src/vespa/storage/storageserver/storagenode.cpp
+++ b/storage/src/vespa/storage/storageserver/storagenode.cpp
@@ -129,7 +129,7 @@ StorageNode::subscribeToConfigs()
_configFetcher->start();
- vespalib::LockGuard configLockGuard(_configLock);
+ std::lock_guard configLockGuard(_configLock);
_serverConfig = std::move(_newServerConfig);
_clusterConfig = std::move(_newClusterConfig);
_distributionConfig = std::move(_newDistributionConfig);
@@ -252,7 +252,7 @@ StorageNode::initializeStatusWebServer()
void
StorageNode::setNewDocumentRepo(const std::shared_ptr<const document::DocumentTypeRepo>& repo)
{
- vespalib::LockGuard configLockGuard(_configLock);
+ std::lock_guard configLockGuard(_configLock);
_context.getComponentRegister().setDocumentTypeRepo(repo);
if (_communicationManager != nullptr) {
_communicationManager->updateMessagebusProtocol(repo);
@@ -280,7 +280,7 @@ StorageNode::handleLiveConfigUpdate(const InitialGuard & initGuard)
{
// Make sure we don't conflict with initialize or shutdown threads.
(void) initGuard;
- vespalib::LockGuard configLockGuard(_configLock);
+ std::lock_guard configLockGuard(_configLock);
assert(_chain);
// If we get here, initialize is done running. We have to handle changes
@@ -476,7 +476,7 @@ void StorageNode::configure(std::unique_ptr<StorServerConfig> config) {
// to a variable where we can find it later when processing config
// updates
{
- vespalib::LockGuard configLockGuard(_configLock);
+ std::lock_guard configLockGuard(_configLock);
_newServerConfig = std::move(config);
}
if (_serverConfig) {
@@ -488,7 +488,7 @@ void StorageNode::configure(std::unique_ptr<StorServerConfig> config) {
void StorageNode::configure(std::unique_ptr<UpgradingConfig> config) {
log_config_received(*config);
{
- vespalib::LockGuard configLockGuard(_configLock);
+ std::lock_guard configLockGuard(_configLock);
_newClusterConfig = std::move(config);
}
if (_clusterConfig) {
@@ -500,7 +500,7 @@ void StorageNode::configure(std::unique_ptr<UpgradingConfig> config) {
void StorageNode::configure(std::unique_ptr<StorDistributionConfig> config) {
log_config_received(*config);
{
- vespalib::LockGuard configLockGuard(_configLock);
+ std::lock_guard configLockGuard(_configLock);
_newDistributionConfig = std::move(config);
}
if (_distributionConfig) {
@@ -512,7 +512,7 @@ void StorageNode::configure(std::unique_ptr<StorDistributionConfig> config) {
void StorageNode::configure(std::unique_ptr<StorPrioritymappingConfig> config) {
log_config_received(*config);
{
- vespalib::LockGuard configLockGuard(_configLock);
+ std::lock_guard configLockGuard(_configLock);
_newPriorityConfig = std::move(config);
}
if (_priorityConfig) {
@@ -530,7 +530,7 @@ StorageNode::configure(std::unique_ptr<document::DocumenttypesConfig> config,
if (!hasChanged)
return;
{
- vespalib::LockGuard configLockGuard(_configLock);
+ std::lock_guard configLockGuard(_configLock);
_newDoctypesConfig = std::move(config);
}
if (_doctypesConfig) {
@@ -542,7 +542,7 @@ StorageNode::configure(std::unique_ptr<document::DocumenttypesConfig> config,
void StorageNode::configure(std::unique_ptr<BucketspacesConfig> config) {
log_config_received(*config);
{
- vespalib::LockGuard configLockGuard(_configLock);
+ std::lock_guard configLockGuard(_configLock);
_newBucketSpacesConfig = std::move(config);
}
if (_bucketSpacesConfig) {
diff --git a/storage/src/vespa/storage/storageserver/storagenode.h b/storage/src/vespa/storage/storageserver/storagenode.h
index 91a2bae3190..adc55266588 100644
--- a/storage/src/vespa/storage/storageserver/storagenode.h
+++ b/storage/src/vespa/storage/storageserver/storagenode.h
@@ -144,7 +144,7 @@ private:
protected:
// Lock taken while doing configuration of the server.
- vespalib::Lock _configLock;
+ std::mutex _configLock;
std::mutex _initial_config_mutex;
using InitialGuard = std::lock_guard<std::mutex>;
// Current running config. Kept, such that we can see what has been
diff --git a/storage/src/vespa/storage/visiting/recoveryvisitor.cpp b/storage/src/vespa/storage/visiting/recoveryvisitor.cpp
index 80e74e890a1..1ac0248961a 100644
--- a/storage/src/vespa/storage/visiting/recoveryvisitor.cpp
+++ b/storage/src/vespa/storage/visiting/recoveryvisitor.cpp
@@ -34,7 +34,7 @@ RecoveryVisitor::handleDocuments(const document::BucketId& bid,
std::vector<spi::DocEntry::UP>& entries,
HitCounter& hitCounter)
{
- vespalib::LockGuard guard(_mutex);
+ std::lock_guard guard(_mutex);
LOG(debug, "Visitor %s handling block of %zu documents.", _id.c_str(), entries.size());
@@ -87,7 +87,7 @@ void RecoveryVisitor::completedBucket(const document::BucketId& bid, HitCounter&
LOG(debug, "Finished bucket %s", bid.toString().c_str());
{
- vespalib::LockGuard guard(_mutex);
+ std::lock_guard guard(_mutex);
CommandMap::iterator iter = _activeCommands.find(bid);
diff --git a/storage/src/vespa/storage/visiting/recoveryvisitor.h b/storage/src/vespa/storage/visiting/recoveryvisitor.h
index 1da2acfed9c..fd296c30361 100644
--- a/storage/src/vespa/storage/visiting/recoveryvisitor.h
+++ b/storage/src/vespa/storage/visiting/recoveryvisitor.h
@@ -33,7 +33,7 @@ private:
using CommandMap = std::map<document::BucketId, CommandPtr>;
CommandMap _activeCommands;
- vespalib::Lock _mutex;
+ std::mutex _mutex;
};
struct RecoveryVisitorFactory : public VisitorFactory {
diff --git a/storage/src/vespa/storage/visiting/visitor.cpp b/storage/src/vespa/storage/visiting/visitor.cpp
index dcd8cc4ba39..982bcd78f6f 100644
--- a/storage/src/vespa/storage/visiting/visitor.cpp
+++ b/storage/src/vespa/storage/visiting/visitor.cpp
@@ -13,6 +13,7 @@
#include <vespa/vespalib/util/stringfmt.h>
#include <unordered_map>
#include <sstream>
+#include <cassert>
#include <vespa/log/log.h>
LOG_SETUP(".visitor.instance.visitor");
diff --git a/storage/src/vespa/storage/visiting/visitormanager.cpp b/storage/src/vespa/storage/visiting/visitormanager.cpp
index 1a1f1498578..7a450508375 100644
--- a/storage/src/vespa/storage/visiting/visitormanager.cpp
+++ b/storage/src/vespa/storage/visiting/visitormanager.cpp
@@ -10,6 +10,7 @@
#include <vespa/config/common/exceptions.h>
#include <vespa/documentapi/loadtypes/loadtypeset.h>
#include <vespa/vespalib/util/stringfmt.h>
+#include <cassert>
#include <vespa/log/log.h>
LOG_SETUP(".visitor.manager");
@@ -660,7 +661,7 @@ VisitorManager::reportHtmlStatus(std::ostream& out,
}
// Only one can access status at a time as _statusRequest only holds
// answers from one request at a time
- vespalib::LockGuard sync(_statusLock);
+ std::lock_guard sync(_statusLock);
vespalib::MonitorGuard waiter(_statusMonitor);
// Send all subrequests
uint32_t parts = _visitorThread.size();
diff --git a/storage/src/vespa/storage/visiting/visitormanager.h b/storage/src/vespa/storage/visiting/visitormanager.h
index 3675a824e1d..70ba95396fc 100644
--- a/storage/src/vespa/storage/visiting/visitormanager.h
+++ b/storage/src/vespa/storage/visiting/visitormanager.h
@@ -75,10 +75,9 @@ private:
framework::MicroSecTime> > _recentlyDeletedVisitors;
framework::MicroSecTime _recentlyDeletedMaxTime;
- mutable vespalib::Lock _statusLock; // Only one can get status at a time
+ mutable std::mutex _statusLock; // Only one can get status at a time
mutable vespalib::Monitor _statusMonitor; // Notify when done
- mutable std::vector<std::shared_ptr<RequestStatusPageReply> >
- _statusRequest;
+ mutable std::vector<std::shared_ptr<RequestStatusPageReply> > _statusRequest;
bool _enforceQueueUse;
VisitorFactory::Map _visitorFactories;
diff --git a/storageapi/src/vespa/storageapi/buckets/bucketinfo.cpp b/storageapi/src/vespa/storageapi/buckets/bucketinfo.cpp
index c3980784106..7466d5c603e 100644
--- a/storageapi/src/vespa/storageapi/buckets/bucketinfo.cpp
+++ b/storageapi/src/vespa/storageapi/buckets/bucketinfo.cpp
@@ -5,7 +5,7 @@
namespace storage::api {
-BucketInfo::BucketInfo()
+BucketInfo::BucketInfo() noexcept
: _lastModified(0),
_checksum(0),
_docCount(0),
@@ -17,7 +17,7 @@ BucketInfo::BucketInfo()
{}
BucketInfo::BucketInfo(uint32_t checksum, uint32_t docCount,
- uint32_t totDocSize)
+ uint32_t totDocSize) noexcept
: _lastModified(0),
_checksum(checksum),
_docCount(docCount),
@@ -30,7 +30,7 @@ BucketInfo::BucketInfo(uint32_t checksum, uint32_t docCount,
BucketInfo::BucketInfo(uint32_t checksum, uint32_t docCount,
uint32_t totDocSize, uint32_t metaCount,
- uint32_t usedFileSize)
+ uint32_t usedFileSize) noexcept
: _lastModified(0),
_checksum(checksum),
_docCount(docCount),
@@ -44,7 +44,7 @@ BucketInfo::BucketInfo(uint32_t checksum, uint32_t docCount,
BucketInfo::BucketInfo(uint32_t checksum, uint32_t docCount,
uint32_t totDocSize, uint32_t metaCount,
uint32_t usedFileSize,
- bool ready, bool active)
+ bool ready, bool active) noexcept
: _lastModified(0),
_checksum(checksum),
_docCount(docCount),
@@ -58,7 +58,7 @@ BucketInfo::BucketInfo(uint32_t checksum, uint32_t docCount,
BucketInfo::BucketInfo(uint32_t checksum, uint32_t docCount,
uint32_t totDocSize, uint32_t metaCount,
uint32_t usedFileSize,
- bool ready, bool active, Timestamp lastModified)
+ bool ready, bool active, Timestamp lastModified) noexcept
: _lastModified(lastModified),
_checksum(checksum),
_docCount(docCount),
@@ -69,9 +69,9 @@ BucketInfo::BucketInfo(uint32_t checksum, uint32_t docCount,
_active(active)
{}
-BucketInfo::BucketInfo(const BucketInfo &) = default;
-BucketInfo & BucketInfo::operator = (const BucketInfo &) = default;
-BucketInfo::~BucketInfo() {}
+BucketInfo::BucketInfo(const BucketInfo &) noexcept = default;
+BucketInfo & BucketInfo::operator = (const BucketInfo &) noexcept = default;
+BucketInfo::~BucketInfo() = default;
bool
BucketInfo::operator==(const BucketInfo& info) const
diff --git a/storageapi/src/vespa/storageapi/buckets/bucketinfo.h b/storageapi/src/vespa/storageapi/buckets/bucketinfo.h
index a80595527e2..f15d99588ca 100644
--- a/storageapi/src/vespa/storageapi/buckets/bucketinfo.h
+++ b/storageapi/src/vespa/storageapi/buckets/bucketinfo.h
@@ -31,18 +31,18 @@ class BucketInfo : public vespalib::AsciiPrintable
bool _active;
public:
- BucketInfo();
- BucketInfo(uint32_t checksum, uint32_t docCount, uint32_t totDocSize);
+ BucketInfo() noexcept;
+ BucketInfo(uint32_t checksum, uint32_t docCount, uint32_t totDocSize) noexcept;
BucketInfo(uint32_t checksum, uint32_t docCount, uint32_t totDocSize,
- uint32_t metaCount, uint32_t usedFileSize);
+ uint32_t metaCount, uint32_t usedFileSize) noexcept;
BucketInfo(uint32_t checksum, uint32_t docCount, uint32_t totDocSize,
uint32_t metaCount, uint32_t usedFileSize,
- bool ready, bool active);
+ bool ready, bool active) noexcept;
BucketInfo(uint32_t checksum, uint32_t docCount, uint32_t totDocSize,
uint32_t metaCount, uint32_t usedFileSize,
- bool ready, bool active, Timestamp lastModified);
- BucketInfo(const BucketInfo &);
- BucketInfo & operator = (const BucketInfo &);
+ bool ready, bool active, Timestamp lastModified) noexcept;
+ BucketInfo(const BucketInfo &) noexcept;
+ BucketInfo & operator = (const BucketInfo &) noexcept;
~BucketInfo();
Timestamp getLastModified() const { return _lastModified; }
diff --git a/storageapi/src/vespa/storageapi/defs.h b/storageapi/src/vespa/storageapi/defs.h
index e5445f22870..531a1b13120 100644
--- a/storageapi/src/vespa/storageapi/defs.h
+++ b/storageapi/src/vespa/storageapi/defs.h
@@ -8,8 +8,7 @@
#include <cstdint>
-namespace storage {
-namespace api {
+namespace storage:: api {
typedef uint64_t Timestamp;
typedef uint32_t VisitorId;
@@ -17,4 +16,3 @@ typedef uint32_t VisitorId;
const Timestamp MAX_TIMESTAMP = (Timestamp)-1ll;
}
-}
diff --git a/storageapi/src/vespa/storageapi/message/bucket.h b/storageapi/src/vespa/storageapi/message/bucket.h
index 45af2296e8a..2b09967d95b 100644
--- a/storageapi/src/vespa/storageapi/message/bucket.h
+++ b/storageapi/src/vespa/storageapi/message/bucket.h
@@ -104,10 +104,10 @@ public:
uint16_t index;
bool sourceOnly;
- Node(uint16_t index_, bool sourceOnly_ = false)
+ Node(uint16_t index_, bool sourceOnly_ = false) noexcept
: index(index_), sourceOnly(sourceOnly_) {}
- bool operator==(const Node& n) const
+ bool operator==(const Node& n) const noexcept
{ return (index == n.index && sourceOnly == n.sourceOnly); }
};
@@ -123,7 +123,7 @@ public:
Timestamp maxTimestamp,
uint32_t clusterStateVersion = 0,
const std::vector<uint16_t>& chain = std::vector<uint16_t>());
- ~MergeBucketCommand();
+ ~MergeBucketCommand() override;
const std::vector<Node>& getNodes() const { return _nodes; }
Timestamp getMaxTimestamp() const { return _maxTimestamp; }
diff --git a/storageapi/src/vespa/storageapi/message/visitor.h b/storageapi/src/vespa/storageapi/message/visitor.h
index 7189cc67195..67c41a0cc4d 100644
--- a/storageapi/src/vespa/storageapi/message/visitor.h
+++ b/storageapi/src/vespa/storageapi/message/visitor.h
@@ -186,12 +186,12 @@ public:
document::BucketId bucketId;
Timestamp timestamp;
- BucketTimestampPair() : bucketId(), timestamp(0) {}
- BucketTimestampPair(const document::BucketId& bucket,
- const Timestamp& ts)
- : bucketId(bucket), timestamp(ts) {}
+ BucketTimestampPair() noexcept : bucketId(), timestamp(0) {}
+ BucketTimestampPair(const document::BucketId& bucket, const Timestamp& ts) noexcept
+ : bucketId(bucket), timestamp(ts)
+ {}
- bool operator==(const BucketTimestampPair& other) const {
+ bool operator==(const BucketTimestampPair& other) const noexcept {
return (bucketId == other.bucketId && timestamp && other.timestamp);
}
};
@@ -203,7 +203,7 @@ private:
public:
VisitorInfoCommand();
- ~VisitorInfoCommand();
+ ~VisitorInfoCommand() override;
void setErrorCode(const ReturnCode& code) { _error = code; }
void setCompleted() { _completed = true; }
diff --git a/storageapi/src/vespa/storageapi/messageapi/storagemessage.cpp b/storageapi/src/vespa/storageapi/messageapi/storagemessage.cpp
index 1f1a2c602de..0f5546a5510 100644
--- a/storageapi/src/vespa/storageapi/messageapi/storagemessage.cpp
+++ b/storageapi/src/vespa/storageapi/messageapi/storagemessage.cpp
@@ -4,7 +4,6 @@
#include <vespa/messagebus/routing/verbatimdirective.h>
#include <vespa/vespalib/util/exceptions.h>
-#include <vespa/vespalib/util/sync.h>
#include <vespa/vespalib/stllike/asciistream.h>
#include <vespa/vespalib/stllike/hash_fun.h>
#include <sstream>
diff --git a/storageframework/src/vespa/storageframework/defaultimplementation/clock/fakeclock.h b/storageframework/src/vespa/storageframework/defaultimplementation/clock/fakeclock.h
index bf810d754d6..24132f710fd 100644
--- a/storageframework/src/vespa/storageframework/defaultimplementation/clock/fakeclock.h
+++ b/storageframework/src/vespa/storageframework/defaultimplementation/clock/fakeclock.h
@@ -8,11 +8,9 @@
#pragma once
#include <vespa/storageframework/generic/clock/clock.h>
-#include <vespa/vespalib/util/sync.h>
+#include <mutex>
-namespace storage {
-namespace framework {
-namespace defaultimplementation {
+namespace storage::framework::defaultimplementation {
struct FakeClock : public framework::Clock {
enum Mode {
@@ -25,45 +23,45 @@ struct FakeClock : public framework::Clock {
private:
Mode _mode;
framework::MicroSecTime _absoluteTime;
- mutable time_t _cycleCount;
- vespalib::Lock _lock;
+ mutable time_t _cycleCount;
+ mutable std::mutex _lock;
public:
FakeClock(Mode m = FAKE_ABSOLUTE,
framework::MicroSecTime startTime = framework::MicroSecTime(1));
void setMode(Mode m) {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_mode = m;
}
virtual void setFakeCycleMode() { setMode(FAKE_ABSOLUTE_CYCLE); }
virtual void setAbsoluteTimeInSeconds(uint32_t seconds) {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_absoluteTime = framework::MicroSecTime(seconds * uint64_t(1000000));
_cycleCount = 0;
_mode = FAKE_ABSOLUTE;
}
virtual void setAbsoluteTimeInMicroSeconds(uint64_t usecs) {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_absoluteTime = framework::MicroSecTime(usecs);
_cycleCount = 0;
_mode = FAKE_ABSOLUTE;
}
virtual void addMilliSecondsToTime(uint64_t ms) {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_absoluteTime += framework::MicroSecTime(ms * 1000);
}
virtual void addSecondsToTime(uint32_t nr) {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_absoluteTime += framework::MicroSecTime(nr * uint64_t(1000000));
}
framework::MicroSecTime getTimeInMicros() const override {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
if (_mode == FAKE_ABSOLUTE) return _absoluteTime;
return _absoluteTime + framework::MicroSecTime(1000000 * _cycleCount++);
}
@@ -80,7 +78,5 @@ public:
}
};
-} // defaultimplementation
-} // framework
-} // storage
+}
diff --git a/storageframework/src/vespa/storageframework/defaultimplementation/component/componentregisterimpl.cpp b/storageframework/src/vespa/storageframework/defaultimplementation/component/componentregisterimpl.cpp
index 2595514e6f4..e4560370a01 100644
--- a/storageframework/src/vespa/storageframework/defaultimplementation/component/componentregisterimpl.cpp
+++ b/storageframework/src/vespa/storageframework/defaultimplementation/component/componentregisterimpl.cpp
@@ -4,6 +4,7 @@
#include <vespa/storageframework/storageframework.h>
#include <vespa/metrics/metricmanager.h>
#include <vespa/vespalib/util/exceptions.h>
+#include <cassert>
namespace storage::framework::defaultimplementation {
@@ -24,7 +25,7 @@ ComponentRegisterImpl::~ComponentRegisterImpl() = default;
void
ComponentRegisterImpl::registerComponent(ManagedComponent& mc)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
_components.push_back(&mc);
if (_clock) {
mc.setClock(*_clock);
@@ -41,7 +42,7 @@ ComponentRegisterImpl::registerComponent(ManagedComponent& mc)
void
ComponentRegisterImpl::requestShutdown(vespalib::stringref reason)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
if (_shutdownListener) {
_shutdownListener->requestShutdown(reason);
}
@@ -52,7 +53,7 @@ ComponentRegisterImpl::setMetricManager(metrics::MetricManager& mm)
{
std::vector<ManagedComponent*> components;
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
assert(_metricManager == nullptr);
components = _components;
_metricManager = &mm;
@@ -69,7 +70,7 @@ ComponentRegisterImpl::setMetricManager(metrics::MetricManager& mm)
void
ComponentRegisterImpl::setClock(Clock& c)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
assert(_clock == nullptr);
_clock = &c;
for (auto* component : _components) {
@@ -80,7 +81,7 @@ ComponentRegisterImpl::setClock(Clock& c)
void
ComponentRegisterImpl::setThreadPool(ThreadPool& tp)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
assert(_threadPool == nullptr);
_threadPool = &tp;
for (auto* component : _components) {
@@ -91,7 +92,7 @@ ComponentRegisterImpl::setThreadPool(ThreadPool& tp)
void
ComponentRegisterImpl::setUpgradeFlag(UpgradeFlags flag)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
_upgradeFlag = flag;
for (auto* component : _components) {
component->setUpgradeFlag(_upgradeFlag);
@@ -101,7 +102,7 @@ ComponentRegisterImpl::setUpgradeFlag(UpgradeFlags flag)
const StatusReporter*
ComponentRegisterImpl::getStatusReporter(vespalib::stringref id)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
for (auto* component : _components) {
if ((component->getStatusReporter() != nullptr)
&& (component->getStatusReporter()->getId() == id))
@@ -116,7 +117,7 @@ std::vector<const StatusReporter*>
ComponentRegisterImpl::getStatusReporters()
{
std::vector<const StatusReporter*> reporters;
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
for (auto* component : _components) {
if (component->getStatusReporter() != nullptr) {
reporters.emplace_back(component->getStatusReporter());
@@ -152,7 +153,7 @@ ComponentRegisterImpl::registerUpdateHook(vespalib::stringref name,
MetricUpdateHook& hook,
SecondTime period)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
auto hookPtr = std::make_unique<MetricHookWrapper>(name, hook);
_metricManager->addMetricUpdateHook(*hookPtr, period.getTime());
_hooks.emplace_back(std::move(hookPtr));
@@ -167,7 +168,7 @@ ComponentRegisterImpl::getMetricManagerLock()
void
ComponentRegisterImpl::registerShutdownListener(ShutdownListener& listener)
{
- vespalib::LockGuard lock(_componentLock);
+ std::lock_guard lock(_componentLock);
assert(_shutdownListener == nullptr);
_shutdownListener = &listener;
}
diff --git a/storageframework/src/vespa/storageframework/defaultimplementation/component/componentregisterimpl.h b/storageframework/src/vespa/storageframework/defaultimplementation/component/componentregisterimpl.h
index b5f79313dfb..3adef5f4838 100644
--- a/storageframework/src/vespa/storageframework/defaultimplementation/component/componentregisterimpl.h
+++ b/storageframework/src/vespa/storageframework/defaultimplementation/component/componentregisterimpl.h
@@ -21,7 +21,6 @@
#include <vespa/storageframework/generic/component/managedcomponent.h>
#include <vespa/storageframework/generic/metric/metricregistrator.h>
#include <vespa/storageframework/generic/status/statusreportermap.h>
-#include <vespa/vespalib/util/sync.h>
#include <vespa/metrics/metricset.h>
namespace metrics {
@@ -43,7 +42,7 @@ class ComponentRegisterImpl : public virtual ComponentRegister,
public StatusReporterMap,
public MetricRegistrator
{
- vespalib::Lock _componentLock;
+ std::mutex _componentLock;
std::vector<ManagedComponent*> _components;
metrics::MetricSet _topMetricSet;
diff --git a/storageframework/src/vespa/storageframework/defaultimplementation/component/testcomponentregister.cpp b/storageframework/src/vespa/storageframework/defaultimplementation/component/testcomponentregister.cpp
index 2e90e1ae3ee..5c8e70f2773 100644
--- a/storageframework/src/vespa/storageframework/defaultimplementation/component/testcomponentregister.cpp
+++ b/storageframework/src/vespa/storageframework/defaultimplementation/component/testcomponentregister.cpp
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "testcomponentregister.h"
+#include <cassert>
namespace storage::framework::defaultimplementation {
diff --git a/storageframework/src/vespa/storageframework/defaultimplementation/thread/threadpoolimpl.cpp b/storageframework/src/vespa/storageframework/defaultimplementation/thread/threadpoolimpl.cpp
index affeae44c04..e4a1188030c 100644
--- a/storageframework/src/vespa/storageframework/defaultimplementation/thread/threadpoolimpl.cpp
+++ b/storageframework/src/vespa/storageframework/defaultimplementation/thread/threadpoolimpl.cpp
@@ -21,7 +21,7 @@ ThreadPoolImpl::ThreadPoolImpl(Clock& clock)
ThreadPoolImpl::~ThreadPoolImpl()
{
{
- vespalib::LockGuard lock(_threadVectorLock);
+ std::lock_guard lock(_threadVectorLock);
_stopping = true;
for (ThreadImpl * thread : _threads) {
thread->interrupt();
@@ -32,7 +32,7 @@ ThreadPoolImpl::~ThreadPoolImpl()
}
for (uint32_t i=0; true; i+=10) {
{
- vespalib::LockGuard lock(_threadVectorLock);
+ std::lock_guard lock(_threadVectorLock);
if (_threads.empty()) break;
}
if (i > 1000) {
@@ -49,7 +49,7 @@ Thread::UP
ThreadPoolImpl::startThread(Runnable& runnable, vespalib::stringref id, uint64_t waitTimeMs,
uint64_t maxProcessTime, int ticksBeforeWait)
{
- vespalib::LockGuard lock(_threadVectorLock);
+ std::lock_guard lock(_threadVectorLock);
if (_stopping) {
throw IllegalStateException("Threadpool is stopping", VESPA_STRLOC);
}
@@ -62,7 +62,7 @@ ThreadPoolImpl::startThread(Runnable& runnable, vespalib::stringref id, uint64_t
void
ThreadPoolImpl::visitThreads(ThreadVisitor& visitor) const
{
- vespalib::LockGuard lock(_threadVectorLock);
+ std::lock_guard lock(_threadVectorLock);
for (const ThreadImpl * thread : _threads) {
visitor.visitThread(thread->getId(), thread->getProperties(), thread->getTickData());
}
@@ -71,7 +71,7 @@ ThreadPoolImpl::visitThreads(ThreadVisitor& visitor) const
void
ThreadPoolImpl::unregisterThread(ThreadImpl& t)
{
- vespalib::LockGuard lock(_threadVectorLock);
+ std::lock_guard lock(_threadVectorLock);
std::vector<ThreadImpl*> threads;
threads.reserve(_threads.size());
for (ThreadImpl * thread : _threads) {
diff --git a/storageframework/src/vespa/storageframework/defaultimplementation/thread/threadpoolimpl.h b/storageframework/src/vespa/storageframework/defaultimplementation/thread/threadpoolimpl.h
index 4e973c2ad20..5f0ee523eff 100644
--- a/storageframework/src/vespa/storageframework/defaultimplementation/thread/threadpoolimpl.h
+++ b/storageframework/src/vespa/storageframework/defaultimplementation/thread/threadpoolimpl.h
@@ -4,7 +4,6 @@
#include <vespa/storageframework/generic/thread/threadpool.h>
#include <vespa/fastos/thread.h>
-#include <vespa/vespalib/util/sync.h>
namespace storage::framework::defaultimplementation {
@@ -14,13 +13,13 @@ struct ThreadPoolImpl : public ThreadPool
{
FastOS_ThreadPool _backendThreadPool;
std::vector<ThreadImpl*> _threads;
- vespalib::Lock _threadVectorLock;
+ mutable std::mutex _threadVectorLock;
Clock & _clock;
bool _stopping;
public:
ThreadPoolImpl(Clock&);
- ~ThreadPoolImpl();
+ ~ThreadPoolImpl() override;
Thread::UP startThread(Runnable&, vespalib::stringref id, uint64_t waitTimeMs,
uint64_t maxProcessTime, int ticksBeforeWait) override;
diff --git a/storageframework/src/vespa/storageframework/generic/component/component.cpp b/storageframework/src/vespa/storageframework/generic/component/component.cpp
index b0569bdee41..3818a2865d9 100644
--- a/storageframework/src/vespa/storageframework/generic/component/component.cpp
+++ b/storageframework/src/vespa/storageframework/generic/component/component.cpp
@@ -4,6 +4,7 @@
#include "componentregister.h"
#include <vespa/storageframework/generic/metric/metricregistrator.h>
#include <vespa/storageframework/generic/thread/threadpool.h>
+#include <cassert>
namespace storage::framework {
diff --git a/storageframework/src/vespa/storageframework/generic/component/component.h b/storageframework/src/vespa/storageframework/generic/component/component.h
index 165d9c47d6e..c91d7feb532 100644
--- a/storageframework/src/vespa/storageframework/generic/component/component.h
+++ b/storageframework/src/vespa/storageframework/generic/component/component.h
@@ -110,7 +110,6 @@ class Component : private ManagedComponent
void setClock(Clock& c) override { _clock = &c; }
void setThreadPool(ThreadPool& tp) override { _threadPool = &tp; }
void setUpgradeFlag(UpgradeFlags flag) override {
- assert(_upgradeFlag.is_lock_free());
_upgradeFlag.store(flag, std::memory_order_relaxed);
}
void open() override;
diff --git a/storageframework/src/vespa/storageframework/generic/thread/tickingthread.cpp b/storageframework/src/vespa/storageframework/generic/thread/tickingthread.cpp
index dc4f8bbc1f1..3178220654e 100644
--- a/storageframework/src/vespa/storageframework/generic/thread/tickingthread.cpp
+++ b/storageframework/src/vespa/storageframework/generic/thread/tickingthread.cpp
@@ -1,8 +1,9 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "tickingthread.h"
#include "threadpool.h"
-#include <vespa/vespalib/util/exceptions.h>
#include <vespa/vespalib/stllike/asciistream.h>
+#include <vespa/vespalib/util/sync.h>
+#include <cassert>
namespace storage::framework {
diff --git a/storageframework/src/vespa/storageframework/generic/thread/tickingthread.h b/storageframework/src/vespa/storageframework/generic/thread/tickingthread.h
index 477c17b1cc3..1ed02d0f6fd 100644
--- a/storageframework/src/vespa/storageframework/generic/thread/tickingthread.h
+++ b/storageframework/src/vespa/storageframework/generic/thread/tickingthread.h
@@ -21,7 +21,6 @@
#include <memory>
#include <vespa/storageframework/generic/clock/time.h>
#include <vespa/vespalib/stllike/string.h>
-#include <vespa/vespalib/util/sync.h>
namespace storage::framework {
diff --git a/streamingvisitors/src/vespa/searchvisitor/matching_elements_filler.cpp b/streamingvisitors/src/vespa/searchvisitor/matching_elements_filler.cpp
index d51bd57e942..13b396f5284 100644
--- a/streamingvisitors/src/vespa/searchvisitor/matching_elements_filler.cpp
+++ b/streamingvisitors/src/vespa/searchvisitor/matching_elements_filler.cpp
@@ -30,7 +30,7 @@ struct SubFieldTerm
vespalib::string _field_name;
const QueryTerm* _term;
public:
- SubFieldTerm(vespalib::string field_name, const QueryTerm* term)
+ SubFieldTerm(vespalib::string field_name, const QueryTerm* term) noexcept
: _field_name(std::move(field_name)),
_term(term)
{
diff --git a/streamingvisitors/src/vespa/searchvisitor/searchenvironment.cpp b/streamingvisitors/src/vespa/searchvisitor/searchenvironment.cpp
index 107a1b44208..614d11aabfa 100644
--- a/streamingvisitors/src/vespa/searchvisitor/searchenvironment.cpp
+++ b/streamingvisitors/src/vespa/searchvisitor/searchenvironment.cpp
@@ -57,7 +57,7 @@ SearchEnvironment::SearchEnvironment(const config::ConfigUri & configUri) :
SearchEnvironment::~SearchEnvironment()
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_threadLocals.clear();
}
@@ -68,12 +68,12 @@ SearchEnvironment::getEnv(const vespalib::string & searchCluster)
if (_localEnvMap == nullptr) {
EnvMapUP envMap = std::make_unique<EnvMap>();
_localEnvMap = envMap.get();
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_threadLocals.emplace_back(std::move(envMap));
}
EnvMap::iterator localFound = _localEnvMap->find(searchCluster);
if (localFound == _localEnvMap->end()) {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
EnvMap::iterator found = _envMap.find(searchCluster);
if (found == _envMap.end()) {
LOG(debug, "Init VSMAdapter with config id = '%s'", searchCluster.c_str());
diff --git a/streamingvisitors/src/vespa/searchvisitor/searchenvironment.h b/streamingvisitors/src/vespa/searchvisitor/searchenvironment.h
index 126b8370105..3dce03e9402 100644
--- a/streamingvisitors/src/vespa/searchvisitor/searchenvironment.h
+++ b/streamingvisitors/src/vespa/searchvisitor/searchenvironment.h
@@ -19,7 +19,7 @@ private:
public:
typedef std::shared_ptr<Env> SP;
Env(const vespalib::string & muffens, const config::ConfigUri & configUri, Fast_NormalizeWordFolder & wf);
- ~Env();
+ ~Env() override;
const vsm::VSMAdapter * getVSMAdapter() const { return _vsmAdapter.get(); }
const RankManager * getRankManager() const { return _rankManager.get(); }
void configure(const config::ConfigSnapshot & snapshot) override;
@@ -38,7 +38,7 @@ private:
static __thread EnvMap * _localEnvMap;
EnvMap _envMap;
ThreadLocals _threadLocals;
- vespalib::Lock _lock;
+ std::mutex _lock;
Fast_NormalizeWordFolder _wordFolder;
config::ConfigUri _configUri;
diff --git a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.h b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.h
index 9f1887c3b53..eb3879863a5 100644
--- a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.h
+++ b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.h
@@ -57,7 +57,7 @@ private:
* @param fid the field id of the attribute field.
* @param attr a guard to the attribute vector.
**/
- AttrInfo(vsm::FieldIdT fid, search::AttributeGuard::UP attr) :
+ AttrInfo(vsm::FieldIdT fid, search::AttributeGuard::UP attr) noexcept :
_field(fid),
_ascending(true),
_converter(nullptr),
@@ -71,7 +71,7 @@ private:
* @param ascending whether this attribute should be sorted ascending or not.
* @param converter is a converter to apply to the attribute before sorting.
**/
- AttrInfo(vsm::FieldIdT fid, search::AttributeGuard::UP attr, bool ascending, const search::common::BlobConverter * converter) :
+ AttrInfo(vsm::FieldIdT fid, search::AttributeGuard::UP attr, bool ascending, const search::common::BlobConverter * converter) noexcept :
_field(fid),
_ascending(ascending),
_converter(converter),
diff --git a/vbench/src/apps/vbench/vbench.cpp b/vbench/src/apps/vbench/vbench.cpp
index 61206c772e7..ab695f0b728 100644
--- a/vbench/src/apps/vbench/vbench.cpp
+++ b/vbench/src/apps/vbench/vbench.cpp
@@ -1,7 +1,6 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/vespalib/util/signalhandler.h>
#include <vespa/vespalib/util/programoptions.h>
-#include <vespa/vespalib/util/sync.h>
#include <vespa/vespalib/util/thread.h>
#include <vespa/vespalib/util/runnable_pair.h>
#include <vbench/vbench/vbench.h>
diff --git a/vbench/src/tests/http_connection_pool/http_connection_pool_test.cpp b/vbench/src/tests/http_connection_pool/http_connection_pool_test.cpp
index c0c5982d22b..08d44057dfc 100644
--- a/vbench/src/tests/http_connection_pool/http_connection_pool_test.cpp
+++ b/vbench/src/tests/http_connection_pool/http_connection_pool_test.cpp
@@ -1,7 +1,6 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/vespalib/testkit/testapp.h>
#include <vbench/test/all.h>
-#include <vespa/vespalib/util/sync.h>
#include <vespa/vespalib/net/crypto_engine.h>
using namespace vbench;
diff --git a/vbench/src/tests/time_queue/time_queue_test.cpp b/vbench/src/tests/time_queue/time_queue_test.cpp
index 8b683f99127..5ce4feab747 100644
--- a/vbench/src/tests/time_queue/time_queue_test.cpp
+++ b/vbench/src/tests/time_queue/time_queue_test.cpp
@@ -1,7 +1,6 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/vespalib/testkit/testapp.h>
#include <vbench/test/all.h>
-#include <vespa/vespalib/util/sync.h>
using namespace vbench;
diff --git a/vbench/src/vbench/core/dispatcher.h b/vbench/src/vbench/core/dispatcher.h
index 212cf04a06e..21db6c931a4 100644
--- a/vbench/src/vbench/core/dispatcher.h
+++ b/vbench/src/vbench/core/dispatcher.h
@@ -5,7 +5,6 @@
#include "handler.h"
#include "provider.h"
#include "closeable.h"
-#include <vespa/vespalib/util/sync.h>
#include <vespa/vespalib/util/gate.h>
#include <vector>
@@ -31,13 +30,13 @@ private:
};
Handler<T> &_fallback;
- vespalib::Lock _lock;
+ mutable std::mutex _lock;
std::vector<ThreadState*> _threads;
bool _closed;
public:
- Dispatcher(Handler<T> &fallback);
- ~Dispatcher();
+ explicit Dispatcher(Handler<T> &fallback);
+ ~Dispatcher() override;
bool waitForThreads(size_t threads, size_t pollCnt) const;
void close() override;
void handle(std::unique_ptr<T> obj) override;
diff --git a/vbench/src/vbench/core/dispatcher.hpp b/vbench/src/vbench/core/dispatcher.hpp
index 9fd5c5dd527..9a985797967 100644
--- a/vbench/src/vbench/core/dispatcher.hpp
+++ b/vbench/src/vbench/core/dispatcher.hpp
@@ -14,7 +14,7 @@ Dispatcher<T>::Dispatcher(Handler<T> &fallback)
}
template <typename T>
-Dispatcher<T>::~Dispatcher() {}
+Dispatcher<T>::~Dispatcher() = default;
template <typename T>
bool
@@ -25,7 +25,7 @@ Dispatcher<T>::waitForThreads(size_t threads, size_t pollCnt) const
vespalib::Thread::sleep(20);
}
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
if (_threads.size() >= threads) {
return true;
}
@@ -40,7 +40,7 @@ Dispatcher<T>::close()
{
std::vector<ThreadState*> threads;
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
std::swap(_threads, threads);
_closed = true;
}
@@ -53,7 +53,7 @@ template <typename T>
void
Dispatcher<T>::handle(std::unique_ptr<T> obj)
{
- vespalib::LockGuard guard(_lock);
+ std::unique_lock guard(_lock);
if (!_threads.empty()) {
ThreadState *state = _threads.back();
_threads.pop_back();
@@ -75,7 +75,7 @@ Dispatcher<T>::provide()
{
ThreadState state;
{
- vespalib::LockGuard guard(_lock);
+ std::unique_lock guard(_lock);
if (!_closed) {
_threads.push_back(&state);
guard.unlock();
diff --git a/vbench/src/vbench/core/time_queue.h b/vbench/src/vbench/core/time_queue.h
index 2af6f3edbcd..5237a6bc0fb 100644
--- a/vbench/src/vbench/core/time_queue.h
+++ b/vbench/src/vbench/core/time_queue.h
@@ -21,14 +21,14 @@ private:
struct Entry {
std::unique_ptr<T> object;
double time;
- Entry(std::unique_ptr<T> obj, double t) : object(std::move(obj)), time(t) {}
- Entry(Entry &&rhs) : object(std::move(rhs.object)), time(rhs.time) {}
- Entry &operator=(Entry &&rhs) {
+ Entry(std::unique_ptr<T> obj, double t) noexcept : object(std::move(obj)), time(t) {}
+ Entry(Entry &&rhs) noexcept : object(std::move(rhs.object)), time(rhs.time) {}
+ Entry &operator=(Entry &&rhs) noexcept {
object = std::move(rhs.object);
time = rhs.time;
return *this;
}
- bool operator<(const Entry &rhs) const {
+ bool operator<(const Entry &rhs) const noexcept {
return (time < rhs.time);
}
};
@@ -42,6 +42,7 @@ private:
public:
TimeQueue(double window, double tick);
+ ~TimeQueue();
void close() override;
void discard();
void insert(std::unique_ptr<T> obj, double time);
diff --git a/vbench/src/vbench/core/time_queue.hpp b/vbench/src/vbench/core/time_queue.hpp
index 4a70e258935..0a1a74d72db 100644
--- a/vbench/src/vbench/core/time_queue.hpp
+++ b/vbench/src/vbench/core/time_queue.hpp
@@ -13,6 +13,9 @@ TimeQueue<T>::TimeQueue(double window, double tick)
{
}
+template<typename T>
+TimeQueue<T>::~TimeQueue() = default;
+
template <typename T>
void
TimeQueue<T>::close()
diff --git a/vbench/src/vbench/http/http_connection_pool.cpp b/vbench/src/vbench/http/http_connection_pool.cpp
index ffe6518e374..b949279b7d3 100644
--- a/vbench/src/vbench/http/http_connection_pool.cpp
+++ b/vbench/src/vbench/http/http_connection_pool.cpp
@@ -19,7 +19,7 @@ HttpConnection::UP
HttpConnectionPool::getConnection(const ServerSpec &server)
{
double now = _timer.sample();
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
auto res = _map.insert(std::make_pair(server, _store.size()));
if (res.second) {
_store.emplace_back();
@@ -40,7 +40,7 @@ void
HttpConnectionPool::putConnection(HttpConnection::UP conn)
{
double now = _timer.sample();
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
conn->touch(now);
size_t idx = _map[conn->server()];
assert(idx < _store.size());
diff --git a/vbench/src/vbench/http/http_connection_pool.h b/vbench/src/vbench/http/http_connection_pool.h
index 5dd9eb6361c..f5c279e7efe 100644
--- a/vbench/src/vbench/http/http_connection_pool.h
+++ b/vbench/src/vbench/http/http_connection_pool.h
@@ -5,7 +5,6 @@
#include "http_connection.h"
#include <vbench/core/timer.h>
#include <vespa/vespalib/util/arrayqueue.hpp>
-#include <vespa/vespalib/util/sync.h>
#include <map>
namespace vbench {
@@ -22,7 +21,7 @@ private:
typedef std::map<ServerSpec, size_t> Map;
using CryptoEngine = vespalib::CryptoEngine;
- vespalib::Lock _lock;
+ std::mutex _lock;
Map _map;
std::vector<Queue> _store;
CryptoEngine::SP _crypto;
diff --git a/vbench/src/vbench/vbench/request_scheduler.h b/vbench/src/vbench/vbench/request_scheduler.h
index 2f9e9177c53..69be0bba6ca 100644
--- a/vbench/src/vbench/vbench/request_scheduler.h
+++ b/vbench/src/vbench/vbench/request_scheduler.h
@@ -7,7 +7,6 @@
#include <vbench/core/time_queue.h>
#include <vbench/core/dispatcher.h>
#include <vbench/core/handler_thread.h>
-#include <vespa/vespalib/util/sync.h>
#include <vespa/vespalib/util/active.h>
namespace vbench {
diff --git a/vdslib/CMakeLists.txt b/vdslib/CMakeLists.txt
index b997bf5f983..3c1ee756e56 100644
--- a/vdslib/CMakeLists.txt
+++ b/vdslib/CMakeLists.txt
@@ -21,7 +21,6 @@ vespa_define_module(
TESTS
src/tests
- src/tests/bucketdistribution
src/tests/container
src/tests/distribution
src/tests/state
diff --git a/vdslib/src/tests/CMakeLists.txt b/vdslib/src/tests/CMakeLists.txt
index bc230a7157b..6cf1ba5e33f 100644
--- a/vdslib/src/tests/CMakeLists.txt
+++ b/vdslib/src/tests/CMakeLists.txt
@@ -6,7 +6,6 @@ vespa_add_executable(vdslib_gtest_runner_app TEST
SOURCES
gtest_runner.cpp
DEPENDS
- vdslib_bucketdistributiontest
vdslib_containertest
vdslib_testdistribution
vdslib_teststate
diff --git a/vdslib/src/tests/bucketdistribution/.gitignore b/vdslib/src/tests/bucketdistribution/.gitignore
deleted file mode 100644
index 583460ae288..00000000000
--- a/vdslib/src/tests/bucketdistribution/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-*.So
-.depend
-Makefile
diff --git a/vdslib/src/tests/bucketdistribution/CMakeLists.txt b/vdslib/src/tests/bucketdistribution/CMakeLists.txt
deleted file mode 100644
index 79ca63b72f2..00000000000
--- a/vdslib/src/tests/bucketdistribution/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_library(vdslib_bucketdistributiontest
- SOURCES
- bucketdistributiontest.cpp
- DEPENDS
- vdslib
- GTest::GTest
-)
diff --git a/vdslib/src/tests/bucketdistribution/bucketdistributiontest.cpp b/vdslib/src/tests/bucketdistribution/bucketdistributiontest.cpp
deleted file mode 100644
index 7f2b012680c..00000000000
--- a/vdslib/src/tests/bucketdistribution/bucketdistributiontest.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include <vespa/vdslib/bucketdistribution.h>
-#include <gtest/gtest.h>
-
-using namespace vdslib;
-
-void
-assertDistribution(uint32_t numColumns, uint32_t numBucketBits, const uint32_t expected[])
-{
- BucketDistribution bd(numColumns, numBucketBits);
- EXPECT_EQ(numColumns, bd.getNumColumns());
- EXPECT_EQ((uint32_t)(1 << numBucketBits), bd.getNumBuckets());
- for (uint32_t i = 0; i < bd.getNumBuckets(); ++i) {
- EXPECT_EQ(expected[i], bd.getColumn(document::BucketId(16, i)));
- }
-}
-
-TEST(BucketDistributionTest, testDistribution)
-{
- const uint32_t expected4[] = {
- 10, 11, 9, 6, 4, 8, 14, 1, 13, 2, 12, 3, 5, 7, 15, 0 };
- assertDistribution(16, 4, expected4);
-
- const uint32_t expected5[] = {
- 11, 12, 11, 13, 8, 13, 8, 9, 4, 5, 6, 12, 10, 15, 1, 1, 7, 9, 14, 2, 2, 14, 3, 3, 4, 5, 6, 7, 10, 15, 0, 0 };
- assertDistribution(16, 5, expected5);
-
- const uint32_t expected6[] = {
- 13, 13, 13, 13, 9, 11, 8, 9, 11, 14, 9, 11, 14, 14, 8, 10, 11, 14, 4, 5, 5, 6, 6, 7, 8, 10, 12, 15, 1, 1, 1, 1,
- 6, 7, 8, 10, 12, 15, 2, 2, 2, 2, 12, 15, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6, 7, 7, 9, 10, 12, 15, 0, 0, 0, 0 };
- assertDistribution(16, 6, expected6);
-
- const uint32_t expected7[] = {
- 14, 14, 14, 13, 11, 14, 14, 10, 13, 14, 10, 12, 8, 8, 9, 10, 9, 10, 11, 12, 13, 15, 11, 12, 13, 13, 15, 8, 8, 9, 10, 11,
- 11, 12, 13, 15, 4, 4, 5, 5, 5, 5, 15, 6, 6, 7, 7, 7, 8, 9, 9, 10, 11, 12, 14, 15, 1, 1, 1, 1, 1, 1, 1, 1,
- 6, 6, 6, 7, 7, 8, 8, 9, 10, 11, 12, 13, 15, 2, 2, 2, 2, 2, 2, 2, 2, 12, 13, 15, 3, 3, 3, 3, 3, 3, 3, 3,
- 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 9, 9, 10, 11, 12, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0 };
- assertDistribution(16, 7, expected7);
-
- const uint32_t expected8[] = {
- 15, 14, 15, 15, 12, 14, 15, 12, 12, 11, 12, 13, 14, 13, 13, 13, 14, 15, 15, 9, 14, 9, 15, 10, 11, 11, 12, 8, 8, 8, 8, 9,
- 9, 10, 10, 10, 11, 11, 12, 13, 13, 14, 10, 11, 11, 12, 13, 13, 14, 13, 13, 14, 15, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11,
- 10, 10, 11, 11, 12, 13, 13, 14, 15, 4, 4, 4, 4, 15, 5, 5, 5, 5, 5, 5, 5, 15, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7,
- 8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 14, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 14, 15, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 12, 13, 14, 14, 15, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7,
- 8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- assertDistribution(16, 8, expected8);
-
- const uint32_t expected9[] = {
- 15, 15, 15, 15, 14, 14, 15, 13, 13, 13, 13, 13, 14, 14, 15, 12, 14, 15, 15, 11, 11, 12, 13, 13, 13, 14, 14, 15, 15, 10, 12, 12,
- 12, 13, 13, 13, 14, 14, 15, 15, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 15, 15, 8, 8, 8, 8, 9, 9, 9,
- 9, 9, 9, 10, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 14, 14, 10, 10, 10, 11, 11, 11, 12, 12, 12, 12,
- 13, 13, 14, 14, 14, 15, 15, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11,
- 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 4, 4, 4, 4, 4, 4, 4, 15, 15, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 14, 14, 14, 15, 15, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,
- 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- assertDistribution(16, 9, expected9);
-}
-
-TEST(BucketDistributionTest, testNumBucketBits)
-{
- BucketDistribution bd(1, 4);
- for (uint32_t i = 0; i <= 0xf; ++i) {
- EXPECT_EQ(0u, bd.getColumn(document::BucketId(32, (rand() << 4) & i)));
- }
-
- bd.reset();
- bd.setNumColumns(1);
- bd.setNumBucketBits(8);
- for (uint32_t i = 0; i <= 0xff; ++i) {
- EXPECT_EQ(0u, bd.getColumn(document::BucketId(32, (rand() << 8) & i)));
- }
-
- bd.reset();
- bd.setNumColumns(1);
- bd.setNumBucketBits(16);
- for (uint32_t i = 0; i <= 0xffff; ++i) {
- EXPECT_EQ(0u, bd.getColumn(document::BucketId(32, (rand() << 16) & i)));
- }
-}
diff --git a/vdslib/src/tests/thread/taskschedulertest.cpp b/vdslib/src/tests/thread/taskschedulertest.cpp
index 1925625172c..54877fae62b 100644
--- a/vdslib/src/tests/thread/taskschedulertest.cpp
+++ b/vdslib/src/tests/thread/taskschedulertest.cpp
@@ -2,7 +2,6 @@
#include <vespa/vdslib/thread/taskscheduler.h>
#include <vespa/vespalib/gtest/gtest.h>
-#include <vespa/vespalib/util/time.h>
#include <thread>
namespace vdslib {
@@ -10,24 +9,24 @@ namespace vdslib {
namespace {
struct TestWatch : public TaskScheduler::Watch {
- vespalib::Lock _lock;
+ mutable std::mutex _lock;
uint64_t _time;
TestWatch(uint64_t startTime = 0) : _time(startTime) {}
- ~TestWatch() {}
+ ~TestWatch() = default;
TaskScheduler::Time getTime() const override {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
return _time;
}
void increment(uint64_t ms) {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_time += ms;
}
void set(uint64_t ms) {
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_time = ms;
}
};
diff --git a/vdslib/src/vespa/vdslib/CMakeLists.txt b/vdslib/src/vespa/vdslib/CMakeLists.txt
index ace44439a23..cf5053a5ceb 100644
--- a/vdslib/src/vespa/vdslib/CMakeLists.txt
+++ b/vdslib/src/vespa/vdslib/CMakeLists.txt
@@ -1,7 +1,6 @@
# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
vespa_add_library(vdslib
SOURCES
- bucketdistribution.cpp
$<TARGET_OBJECTS:vdslib_container>
$<TARGET_OBJECTS:vdslib_state>
$<TARGET_OBJECTS:vdslib_distribution>
diff --git a/vdslib/src/vespa/vdslib/bucketdistribution.cpp b/vdslib/src/vespa/vdslib/bucketdistribution.cpp
deleted file mode 100644
index a8c39ad6577..00000000000
--- a/vdslib/src/vespa/vdslib/bucketdistribution.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include "bucketdistribution.h"
-
-#include <vespa/log/log.h>
-LOG_SETUP(".bucketdistribution");
-
-namespace vdslib {
-
-BucketDistribution::BucketDistribution(uint32_t numColumns, uint32_t numBucketBits) :
- _numColumns(0),
- _numBucketBits(numBucketBits),
- _bucketToColumn(),
- _lock()
-{
- _bucketToColumn.resize(getNumBuckets());
- reset();
- setNumColumns(numColumns);
-}
-
-BucketDistribution::BucketDistribution(const BucketDistribution &) = default;
-BucketDistribution & BucketDistribution::operator = (const BucketDistribution &) = default;
-
-BucketDistribution::~BucketDistribution() {}
-
-void
-BucketDistribution::getBucketCount(uint32_t numColumns, uint32_t numBucketBits, std::vector<uint32_t> &ret)
-{
- ret.resize(numColumns);
- uint32_t cnt = getNumBuckets(numBucketBits) / numColumns;
- uint32_t rst = getNumBuckets(numBucketBits) % numColumns;
- for (uint32_t i = 0; i < numColumns; ++i) {
- ret[i] = cnt + (i < rst ? 1 : 0);
- }
-}
-
-void
-BucketDistribution::getBucketMigrateCount(uint32_t numColumns, uint32_t numBucketBits, std::vector<uint32_t> &ret)
-{
- getBucketCount(numColumns++, numBucketBits, ret);
- uint32_t cnt = getNumBuckets(numBucketBits) / numColumns;
- uint32_t rst = getNumBuckets(numBucketBits) % numColumns;
- for (uint32_t i = 0; i < numColumns - 1; ++i) {
- ret[i] -= cnt + (i < rst ? 1 : 0);
- }
-}
-
-void
-BucketDistribution::reset()
-{
- for (std::vector<uint32_t>::iterator it = _bucketToColumn.begin();
- it != _bucketToColumn.end(); ++it) {
- *it = 0;
- }
- _numColumns = 1;
-}
-
-void
-BucketDistribution::addColumn()
-{
- uint32_t newColumns = _numColumns + 1;
- std::vector<uint32_t> migrate;
- getBucketMigrateCount(_numColumns, _numBucketBits, migrate);
- uint32_t numBuckets = getNumBuckets(_numBucketBits);
- for (uint32_t i = 0; i < numBuckets; ++i) {
- uint32_t old = _bucketToColumn[i];
- if (migrate[old] > 0) {
- _bucketToColumn[i] = _numColumns; // move this bucket to the new column
- migrate[old]--;
- }
- }
- _numColumns = newColumns;
-}
-
-void
-BucketDistribution::setNumColumns(uint32_t numColumns)
-{
- vespalib::LockGuard guard(_lock);
- if (numColumns < _numColumns) {
- reset();
- }
- if (numColumns == _numColumns) {
- return;
- }
- for (int i = numColumns - _numColumns; --i >= 0; ) {
- addColumn();
- }
-}
-
-void
-BucketDistribution::setNumBucketBits(uint32_t numBucketBits)
-{
- uint32_t numColumns;
- {
- vespalib::LockGuard guard(_lock);
- if (numBucketBits == _numBucketBits) {
- return;
- }
- _numBucketBits = numBucketBits;
- _bucketToColumn.resize(getNumBuckets(numBucketBits));
- numColumns = _numColumns;
- reset();
- }
- setNumColumns(numColumns);
-}
-
-uint32_t
-BucketDistribution::getColumn(const document::BucketId &bucketId) const
-{
- uint32_t ret = (uint32_t)(bucketId.getId() & (getNumBuckets(_numBucketBits) - 1));
- if (ret >= _bucketToColumn.size()) {
- LOG(error,
- "The bucket distribution map is not in sync with the number of bucket bits. "
- "This should never happen! Distribution is broken!!");
- return 0;
- }
- return _bucketToColumn[ret];
-}
-
-}
diff --git a/vdslib/src/vespa/vdslib/bucketdistribution.h b/vdslib/src/vespa/vdslib/bucketdistribution.h
deleted file mode 100644
index c9e584af7ef..00000000000
--- a/vdslib/src/vespa/vdslib/bucketdistribution.h
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#pragma once
-
-#include <vespa/document/bucket/bucketid.h>
-#include <vespa/vespalib/util/sync.h>
-#include <vector>
-
-namespace vdslib {
-
-/**
- * Stable algorithmic hash distribution; this class assigns hash buckets to targets. The number of hash buckets should
- * be large compared to the number of targets. The mapping from hash value to hash bucket is performed outside this
- * class.
- */
-class BucketDistribution {
-public:
- /**
- * Constructs a new bucket distribution object with a given number of columns and buckets.
- *
- * @param numColumns The number of columns to distribute to.
- * @param numBucketBits The number of bits to use for bucket id.
- */
- BucketDistribution(uint32_t numColumns, uint32_t numBucketBits);
- BucketDistribution(const BucketDistribution &);
- BucketDistribution & operator = (const BucketDistribution &);
- BucketDistribution(BucketDistribution &&) = default;
- BucketDistribution & operator = (BucketDistribution &&) = default;
- ~BucketDistribution();
-
- /**
- * Returns the number of buckets that the given number of bucket bits will allow.
- *
- * @param numBucketBits The number of bits to use for bucket id.
- * @return The number of buckets allowed.
- */
- static uint32_t getNumBuckets(uint32_t numBucketBits) { return 1 << numBucketBits; }
-
- /**
- * This method returns a list that contains the distributions of the given number of buckets over the given number
- * of columns.
- *
- * @param numColumns The number of columns to distribute to.
- * @param numBucketBits The number of bits to use for bucket id.
- * @param ret List to fill with the bucket distribution.
- */
- static void getBucketCount(uint32_t numColumns, uint32_t numBucketBits, std::vector<uint32_t> &ret);
-
- /**
- * This method returns a list similar to {@link this#getBucketCount(int,int)}, except that the returned list
- * contains the number of buckets that will have to be migrated from each column if an additional column was added.
- *
- * @param numColumns The original number of columns.
- * @param numBucketBits The number of bits to use for bucket id.
- * @param ret List to fill with the number of buckets to migrate, one value per column.
- */
- static void getBucketMigrateCount(uint32_t numColumns, uint32_t numBucketBits, std::vector<uint32_t> &ret);
-
- /**
- * Sets the number of columns to distribute to to 1, and resets the content of the internal bucket-to-column map so
- * that it all buckets point to that single column.
- */
- void reset();
-
- /**
- * Sets the number of columns to use for this document distribution object. This will reset and setup this object
- * from scratch. The original number of buckets is maintained.
- *
- * @param numColumns The new number of columns to distribute to.
- */
- void setNumColumns(uint32_t numColumns);
-
- /**
- * Returns the number of columns to distribute to.
- *
- * @return The number of columns.
- */
- uint32_t getNumColumns() const { return _numColumns; }
-
- /**
- * Sets the number of buckets to use for this document distribution object. This will reset and setup this object
- * from scratch. The original number of columns is maintained.
- *
- * @param numBucketBits The new number of bits to use for bucket id.
- */
- void setNumBucketBits(uint32_t numBucketBits);
-
- /**
- * Returns the number of bits used for bucket identifiers.
- *
- * @return The number of bits.
- */
- uint32_t getNumBucketBits() const { return _numBucketBits; }
-
- /**
- * Returns the number of buckets available using the configured number of bucket bits.
- *
- * @return The number of buckets.
- */
- uint32_t getNumBuckets() const { return getNumBuckets(_numBucketBits); }
-
- /**
- * This method maps the given bucket id to its corresponding column.
- *
- * @param bucketId The bucket whose column to lookup.
- * @return The column to distribute the bucket to.
- */
- uint32_t getColumn(const document::BucketId &bucketId) const;
-
-private:
- /**
- * Adds a single column to this bucket distribution object. This will modify the internal bucket-to-column map so
- * that it takes into account the new column.
- */
- void addColumn();
-
-private:
- uint32_t _numColumns; // The number of columns to distribute to.
- uint32_t _numBucketBits; // The number of bits to use for bucket identification.
- std::vector<uint32_t> _bucketToColumn; // A map from bucket id to column index.
- vespalib::Lock _lock;
-};
-
-}
diff --git a/vdslib/src/vespa/vdslib/distribution/distribution.cpp b/vdslib/src/vespa/vdslib/distribution/distribution.cpp
index 0a154f3dec1..474ed63e8c3 100644
--- a/vdslib/src/vespa/vdslib/distribution/distribution.cpp
+++ b/vdslib/src/vespa/vdslib/distribution/distribution.cpp
@@ -14,6 +14,7 @@
#include <list>
#include <algorithm>
#include <cmath>
+#include <cassert>
#include <vespa/log/bufferedlogger.h>
LOG_SETUP(".vdslib.distribution");
diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/DocumentOperationExecutorImpl.java b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/DocumentOperationExecutorImpl.java
index 7074d363316..309bed38c0b 100644
--- a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/DocumentOperationExecutorImpl.java
+++ b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/DocumentOperationExecutorImpl.java
@@ -40,6 +40,7 @@ import java.util.StringJoiner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@@ -85,6 +86,7 @@ public class DocumentOperationExecutorImpl implements DocumentOperationExecutor
private final DelayQueue throttled;
private final DelayQueue timeouts;
private final Map<VisitorControlHandler, VisitorSession> visits = new ConcurrentHashMap<>();
+ private final ExecutorService visitSessionShutdownExecutor = Executors.newSingleThreadExecutor(new DaemonThreadFactory("visit-session-shutdown-"));
public DocumentOperationExecutorImpl(ClusterListConfig clustersConfig, AllClustersBucketSpacesConfig bucketsConfig,
DocumentOperationExecutorConfig executorConfig, DocumentAccess access, Clock clock) {
@@ -105,7 +107,7 @@ public class DocumentOperationExecutorImpl implements DocumentOperationExecutor
this.asyncSession = access.createAsyncSession(new AsyncParameters());
this.clock = requireNonNull(clock);
this.clusters = Map.copyOf(clusters);
- this.throttled = new DelayQueue(maxThrottled, this::send, resendDelay, clock, "throttle");
+ this.throttled = new DelayQueue(maxThrottled, this::send, Duration.ZERO, clock, "throttle");
this.timeouts = new DelayQueue(Long.MAX_VALUE, (__, context) -> {
context.error(TIMEOUT, "Timed out after " + defaultTimeout);
return true;
@@ -150,14 +152,16 @@ public class DocumentOperationExecutorImpl implements DocumentOperationExecutor
@Override
public void shutdown() {
long shutdownMillis = clock.instant().plusSeconds(20).toEpochMilli();
+ visitSessionShutdownExecutor.shutdown();
visits.values().forEach(VisitorSession::destroy);
Future<?> throttleShutdown = throttled.shutdown(Duration.ofSeconds(10),
context -> context.error(OVERLOAD, "Retry on overload failed due to shutdown"));
Future<?> timeoutShutdown = timeouts.shutdown(Duration.ofSeconds(15),
context -> context.error(TIMEOUT, "Timed out due to shutdown"));
try {
- throttleShutdown.get(Math.max(0, shutdownMillis - clock.millis()), TimeUnit.MILLISECONDS);
- timeoutShutdown.get(Math.max(0, shutdownMillis - clock.millis()), TimeUnit.MILLISECONDS);
+ throttleShutdown.get(Math.max(1, shutdownMillis - clock.millis()), TimeUnit.MILLISECONDS);
+ timeoutShutdown.get(Math.max(1, shutdownMillis - clock.millis()), TimeUnit.MILLISECONDS);
+ visitSessionShutdownExecutor.awaitTermination(Math.max(1, shutdownMillis - clock.millis()), TimeUnit.MILLISECONDS);
}
catch (InterruptedException | ExecutionException | TimeoutException e) {
throttleShutdown.cancel(true);
@@ -212,12 +216,18 @@ public class DocumentOperationExecutorImpl implements DocumentOperationExecutor
context.error(ERROR, message != null ? message : "Visiting failed");
}
done.set(true); // This may be reached before dispatching thread is done putting us in the map.
- visits.computeIfPresent(this, (__, session) -> { session.destroy(); return null; });
+ visits.computeIfPresent(this, (__, session) -> {
+ visitSessionShutdownExecutor.execute(() -> session.destroy());
+ return null;
+ });
}
});
visits.put(parameters.getControlHandler(), access.createVisitorSession(parameters));
if (done.get())
- visits.computeIfPresent(parameters.getControlHandler(), (__, session) -> { session.destroy(); return null; });
+ visits.computeIfPresent(parameters.getControlHandler(), (__, session) -> {
+ visitSessionShutdownExecutor.execute(() -> session.destroy());
+ return null;
+ });
}
catch (IllegalArgumentException | ParseException e) {
context.error(BAD_REQUEST, Exceptions.toMessageString(e));
@@ -386,7 +396,7 @@ public class DocumentOperationExecutorImpl implements DocumentOperationExecutor
synchronized (this) {
do {
notify();
- wait(Math.max(0, waitUntilMillis - clock.millis()));
+ wait(Math.max(1, waitUntilMillis - clock.millis()));
}
while (clock.millis() < waitUntilMillis);
}
diff --git a/vespaclient-container-plugin/src/main/resources/configdefinitions/document-operation-executor.def b/vespaclient-container-plugin/src/main/resources/configdefinitions/document-operation-executor.def
index 19f4f50648b..770189f90f5 100644
--- a/vespaclient-container-plugin/src/main/resources/configdefinitions/document-operation-executor.def
+++ b/vespaclient-container-plugin/src/main/resources/configdefinitions/document-operation-executor.def
@@ -11,5 +11,5 @@ defaultTimeoutSeconds int default=180
visitTimeoutSeconds int default=120
# Bound on number of document operations to keep in retry queue — further operations are rejected
-maxThrottled int default=200
+maxThrottled int default=1000
diff --git a/vespaclient/src/vespa/vespaclient/vdsstates/statesapp.cpp b/vespaclient/src/vespa/vespaclient/vdsstates/statesapp.cpp
index 082aa83c3da..9393562bf28 100644
--- a/vespaclient/src/vespa/vespaclient/vdsstates/statesapp.cpp
+++ b/vespaclient/src/vespa/vespaclient/vdsstates/statesapp.cpp
@@ -254,11 +254,11 @@ struct StateApp : public FastOS_Application {
std::unique_ptr<slobrok::api::MirrorAPI> slobrok;
if (_options._slobrokConnectionSpec == "") {
config::ConfigUri config(_options._slobrokConfigId);
- slobrok.reset(new slobrok::api::MirrorAPI(supervisor.supervisor(), config));
+ slobrok = std::make_unique<slobrok::api::MirrorAPI>(supervisor.supervisor(), slobrok::ConfiguratorFactory(config));
} else {
std::vector<std::string> specList;
specList.push_back(_options._slobrokConnectionSpec);
- slobrok.reset(new slobrok::api::MirrorAPI(supervisor.supervisor(), specList));
+ slobrok = std::make_unique<slobrok::api::MirrorAPI>(supervisor.supervisor(), slobrok::ConfiguratorFactory(specList));
}
LOG(debug, "Waiting for slobrok data to be available.");
uint64_t startTime = getTimeInMillis();
diff --git a/vespalib/CMakeLists.txt b/vespalib/CMakeLists.txt
index ec003329999..278d32c118d 100644
--- a/vespalib/CMakeLists.txt
+++ b/vespalib/CMakeLists.txt
@@ -46,7 +46,6 @@ vespa_define_module(
src/tests/datastore/unique_store
src/tests/datastore/unique_store_dictionary
src/tests/datastore/unique_store_string_allocator
- src/tests/delegatelist
src/tests/detect_type_benchmark
src/tests/dotproduct
src/tests/drop-file-from-cache
@@ -94,7 +93,6 @@ vespa_define_module(
src/tests/regex
src/tests/rendezvous
src/tests/runnable_pair
- src/tests/rwlock
src/tests/sha1
src/tests/sharedptr
src/tests/signalhandler
diff --git a/vespalib/src/tests/datastore/unique_store_dictionary/unique_store_dictionary_test.cpp b/vespalib/src/tests/datastore/unique_store_dictionary/unique_store_dictionary_test.cpp
index 37a22108dc5..6a9215c3eb9 100644
--- a/vespalib/src/tests/datastore/unique_store_dictionary/unique_store_dictionary_test.cpp
+++ b/vespalib/src/tests/datastore/unique_store_dictionary/unique_store_dictionary_test.cpp
@@ -40,7 +40,7 @@ struct DictionaryReadTest : public ::testing::Test {
{
}
DictionaryReadTest& add(uint32_t value) {
- auto result = dict.add(Comparator(value), [=]() { return EntryRef(value); });
+ auto result = dict.add(Comparator(value), [=]() noexcept { return EntryRef(value); });
assert(result.inserted());
return *this;
}
diff --git a/vespalib/src/tests/delegatelist/.cvsignore b/vespalib/src/tests/delegatelist/.cvsignore
deleted file mode 100644
index 0e8f4d0be0b..00000000000
--- a/vespalib/src/tests/delegatelist/.cvsignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.depend
-Makefile
-delegatelist_test
diff --git a/vespalib/src/tests/delegatelist/.gitignore b/vespalib/src/tests/delegatelist/.gitignore
deleted file mode 100644
index 42ac4beb0c3..00000000000
--- a/vespalib/src/tests/delegatelist/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.depend
-Makefile
-delegatelist_test
-vespalib_delegatelist_test_app
diff --git a/vespalib/src/tests/delegatelist/CMakeLists.txt b/vespalib/src/tests/delegatelist/CMakeLists.txt
deleted file mode 100644
index 71551474445..00000000000
--- a/vespalib/src/tests/delegatelist/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_executable(vespalib_delegatelist_test_app TEST
- SOURCES
- delegatelist.cpp
- DEPENDS
- vespalib
-)
-vespa_add_test(NAME vespalib_delegatelist_test_app COMMAND vespalib_delegatelist_test_app)
diff --git a/vespalib/src/tests/delegatelist/delegatelist.cpp b/vespalib/src/tests/delegatelist/delegatelist.cpp
deleted file mode 100644
index 070864dd85a..00000000000
--- a/vespalib/src/tests/delegatelist/delegatelist.cpp
+++ /dev/null
@@ -1,824 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include <vespa/vespalib/testkit/testapp.h>
-#include <vespa/vespalib/util/delegatelist.hpp>
-#include <vespa/vespalib/util/guard.h>
-#include <vespa/fastos/thread.h>
-#include <queue>
-
-#include <vespa/log/log.h>
-LOG_SETUP("delegatelist_test");
-
-using namespace vespalib;
-
-//-----------------------------------------------------------------------------
-
-class Test : public TestApp
-{
-public:
- void testEmpty();
- void testAdd();
- void testRemove();
- void testOneShot();
- void testMultiSnapshot();
- void testActors();
- void testWaitSnapshots();
- void stressTest();
- int Main() override;
-};
-
-//-----------------------------------------------------------------------------
-
-namespace {
-
-class Handler
-{
-private:
- int _num;
-public:
- Handler() : _num(0) {}
- void add() { _num++; }
- int getNum() { return _num; }
-};
-
-typedef DelegateList<Handler> DL;
-
-void multicast(DL &dl) {
- for (DL::Snapshot snap(dl) ; snap.valid(); snap.next()) {
- snap.get()->add();
- }
-}
-
-void multicast_clear(DL &dl) {
- DL::Snapshot snap(dl);
- dl.clear();
- for (; snap.valid(); snap.next()) {
- snap.get()->add();
- }
-}
-
-//-----------------------------------------------------------------------------
-
-enum {
- CMD_MULTICAST,
- CMD_MULTICAST_CLEAR,
- CMD_ADD,
- CMD_REMOVE,
- CMD_CLEAR,
- CMD_WAIT_SNAP,
- CMD_DO,
- CMD_DONE,
- CMD_EXIT
-};
-
-struct Command
-{
- DL *dl;
- int cmd;
- int cnt;
- Handler *handler;
- Command(DL *dl_, int cmd_, int cnt_, Handler *handler_)
- : dl(dl_), cmd(cmd_), cnt(cnt_), handler(handler_) {}
- Command(const Command &rhs)
- : dl(rhs.dl), cmd(rhs.cmd), cnt(rhs.cnt), handler(rhs.handler) {}
- Command &operator=(const Command &rhs) {
- memcpy(this, &rhs, sizeof(Command));
- return *this;
- }
- bool operator==(const Command &rhs) {
- return memcmp(this, &rhs, sizeof(Command)) == 0;
- }
-};
-
-Command
-cmd_multicast(DL *dl) {
- return Command(dl, CMD_MULTICAST, 0, 0);
-}
-
-Command
-cmd_multicast_clear(DL *dl) {
- return Command(dl, CMD_MULTICAST_CLEAR, 0, 0);
-}
-
-Command
-cmd_add(DL *dl, Handler *handler) {
- return Command(dl, CMD_ADD, 0, handler);
-}
-
-Command
-cmd_remove(DL *dl, Handler *handler) {
- return Command(dl, CMD_REMOVE, 0, handler);
-}
-
-Command
-cmd_clear(DL *dl) {
- return Command(dl, CMD_CLEAR, 0, 0);
-}
-
-Command
-cmd_wait_snap(DL *dl) {
- return Command(dl, CMD_WAIT_SNAP, 0, 0);
-}
-
-Command
-cmd_do(int cnt) {
- return Command(0, CMD_DO, cnt, 0);
-}
-
-Command
-cmd_done() {
- return Command(0, CMD_DONE, 0, 0);
-}
-
-Command
-cmd_exit() {
- return Command(0, CMD_EXIT, 0, 0);
-}
-
-typedef std::vector<Command> CmdList;
-typedef std::pair<Command, int> HistEntry;
-typedef std::vector<HistEntry> HistList;
-
-//-----------------------------------------------------------------------------
-
-struct History {
- Lock lock;
- HistList list;
- History() : lock(), list() {}
- void add(const HistEntry &entry) {
- LockGuard guard(lock);
- list.push_back(entry);
- }
-};
-
-//-----------------------------------------------------------------------------
-
-template <typename T>
-class Queue {
-private:
- std::queue<T> _q;
- Monitor _cond;
- int _waitCnt;
- Queue(const Queue &);
- Queue &operator=(const Queue &);
-public:
- Queue() : _q(), _cond(), _waitCnt(0) {}
- void enqueue(const T &entry) {
- MonitorGuard guard(_cond);
- _q.push(entry);
- if (_waitCnt > 0) {
- guard.signal();
- }
- }
- T dequeue() {
- MonitorGuard guard(_cond);
- CounterGuard cntGuard(_waitCnt);
- while (_q.empty()) {
- guard.wait();
- }
- T tmp = _q.front();
- _q.pop();
- return tmp;
- }
- size_t size() const { return _q.size(); }
-};
-
-typedef Queue<CmdList> CmdListQueue;
-
-//-----------------------------------------------------------------------------
-
-class Actor : public FastOS_Runnable
-{
-public:
- enum {
- STATE_INIT,
- STATE_IDLE,
- STATE_BUSY,
- STATE_DONE
- };
-private:
- int _id;
- History *_hist;
- CmdListQueue _queue;
- Monitor _cond;
- int _state;
- int _waitCnt;
- int _opCnt;
- bool _exit;
- Actor(const Actor &);
- Actor &operator=(const Actor &);
- void setState(int state, MonitorGuard &guard);
- void doneOp(const Command &cmd);
- int perform(int cnt, int start, const CmdList &cmdList);
-public:
- Actor(int id, History *hist);
- ~Actor();
- int getOpCnt() const { return _opCnt; }
- int getState() const { return _state; }
- void doIt(const CmdList &cmdList);
- void doIt(const Command &cmd);
- void waitState(int state);
- void Run(FastOS_ThreadInterface *, void *) override;
-};
-
-Actor::Actor(int id, History *hist)
- : _id(id), _hist(hist), _queue(), _cond(), _state(STATE_INIT),
- _waitCnt(0), _opCnt(0), _exit(false)
-{}
-Actor::~Actor() {}
-
-void
-Actor::setState(int state, MonitorGuard &guard) {
- _state = state;
- if (_waitCnt > 0) {
- guard.broadcast();
- }
-}
-
-
-void
-Actor::doneOp(const Command &cmd)
-{
- ++_opCnt;
- if (_hist != 0) {
- _hist->add(HistEntry(cmd, _id));
- }
-}
-
-
-int
-Actor::perform(int cnt, int start, const CmdList &cmdList)
-{
- int doneIdx = cmdList.size();
- for (int i = 0; i < cnt; ++i) {
- for (uint32_t idx = start; idx < cmdList.size(); ++idx) {
- Command cmd = cmdList[idx];
- switch (cmd.cmd) {
- case CMD_MULTICAST:
- multicast(*cmd.dl);
- doneOp(cmd);
- break;
- case CMD_MULTICAST_CLEAR:
- multicast_clear(*cmd.dl);
- doneOp(cmd);
- break;
- case CMD_ADD:
- cmd.dl->add(cmd.handler);
- doneOp(cmd);
- break;
- case CMD_REMOVE:
- cmd.dl->remove(cmd.handler);
- doneOp(cmd);
- break;
- case CMD_CLEAR:
- cmd.dl->clear();
- doneOp(cmd);
- break;
- case CMD_WAIT_SNAP:
- cmd.dl->waitSnapshots();
- doneOp(cmd);
- break;
- case CMD_DO:
- idx = perform(cmd.cnt, idx + 1, cmdList);
- break;
- case CMD_DONE:
- doneIdx = idx;
- idx = cmdList.size();
- break;
- case CMD_EXIT:
- _exit = true;
- return cmdList.size();
- break;
- default:
- LOG_ABORT("should not be reached"); // that does not seem to work
- }
- }
- }
- return doneIdx;
-}
-
-
-void
-Actor::doIt(const CmdList &cmdList)
-{
- MonitorGuard guard(_cond);
- setState(STATE_BUSY, guard);
- _queue.enqueue(cmdList);
-}
-
-
-void
-Actor::doIt(const Command &cmd)
-{
- CmdList cmdList;
- cmdList.push_back(cmd);
- doIt(cmdList);
-}
-
-
-void
-Actor::waitState(int state) {
- MonitorGuard guard(_cond);
- CounterGuard cntGuard(_waitCnt);
- while (_state != state) {
- guard.wait();
- }
-}
-
-
-void
-Actor::Run(FastOS_ThreadInterface *, void *)
-{
- while (!_exit) {
- {
- MonitorGuard guard(_cond);
- if (_queue.size() == 0) {
- setState(STATE_IDLE, guard);
- }
- }
- CmdList cmdList = _queue.dequeue();
- perform(1, 0, cmdList);
- }
- {
- MonitorGuard guard(_cond);
- setState(STATE_DONE, guard);
- }
-}
-
-} // namespace <unnamed>
-
-//-----------------------------------------------------------------------------
-
-void
-Test::testEmpty()
-{
- DL multicaster;
- multicast(multicaster);
- multicast_clear(multicaster);
- DL::Snapshot empty_snap(multicaster);
- EXPECT_TRUE(!empty_snap.valid());
-}
-
-
-void
-Test::testAdd()
-{
- DL multicaster;
- Handler h1;
- Handler h2;
- Handler h3;
- Handler h4;
- Handler h5;
-
- // ensure correct initial state
- EXPECT_TRUE(h1.getNum() == 0);
- EXPECT_TRUE(h2.getNum() == 0);
- EXPECT_TRUE(h3.getNum() == 0);
- EXPECT_TRUE(h4.getNum() == 0);
- EXPECT_TRUE(h5.getNum() == 0);
-
- // test basic adding
- multicaster.add(&h1);
- multicast(multicaster);
- multicaster.add(&h2);
- multicast(multicaster);
- multicaster.add(&h3);
- multicast(multicaster);
- multicaster.add(&h4);
- multicast(multicaster);
- multicaster.add(&h5);
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 5);
- EXPECT_TRUE(h2.getNum() == 4);
- EXPECT_TRUE(h3.getNum() == 3);
- EXPECT_TRUE(h4.getNum() == 2);
- EXPECT_TRUE(h5.getNum() == 1);
-
- // duplicate adds
- multicaster.add(&h1);
- multicaster.add(&h1);
- multicaster.add(&h1);
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 6);
- EXPECT_TRUE(h2.getNum() == 5);
- EXPECT_TRUE(h3.getNum() == 4);
- EXPECT_TRUE(h4.getNum() == 3);
- EXPECT_TRUE(h5.getNum() == 2);
-}
-
-
-void
-Test::testRemove()
-{
- DL multicaster;
- Handler h1;
- Handler h2;
- Handler h3;
- Handler h4;
- Handler h5;
-
- multicaster.add(&h1).add(&h2).add(&h3).add(&h4).add(&h5);
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 1);
- EXPECT_TRUE(h2.getNum() == 1);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 1);
- EXPECT_TRUE(h5.getNum() == 1);
-
- // remove middle
- multicaster.remove(&h3);
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 2);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 2);
- EXPECT_TRUE(h5.getNum() == 2);
-
- // remove head
- multicaster.remove(&h1);
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 3);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 3);
- EXPECT_TRUE(h5.getNum() == 3);
-
- // remove tail
- multicaster.remove(&h5);
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 4);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 4);
- EXPECT_TRUE(h5.getNum() == 3);
-
- // duplicate removes
- multicaster.remove(&h1).remove(&h3).remove(&h5);
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 5);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 5);
- EXPECT_TRUE(h5.getNum() == 3);
-
- // remove all
- multicaster.clear();
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 5);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 5);
- EXPECT_TRUE(h5.getNum() == 3);
-}
-
-
-void
-Test::testOneShot()
-{
- DL multicaster;
- Handler h1;
- Handler h2;
- Handler h3;
- Handler h4;
- Handler h5;
-
- // oneshot multicast removes handlers
- multicaster.add(&h1).add(&h2).add(&h3).add(&h4).add(&h5);
- multicast_clear(multicaster);
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 1);
- EXPECT_TRUE(h2.getNum() == 1);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 1);
- EXPECT_TRUE(h5.getNum() == 1);
-}
-
-
-void
-Test::testMultiSnapshot()
-{
- DL multicaster;
- Handler h1;
- Handler h2;
- Handler h3;
- Handler h4;
- Handler h5;
-
- DL::Snapshot empty_snap(multicaster);
- multicaster.add(&h1).add(&h2).add(&h3).add(&h4).add(&h5);
- DL::Snapshot snap1(multicaster);
- multicaster.remove(&h3);
- DL::Snapshot snap2(multicaster);
- multicaster.remove(&h1);
- DL::Snapshot snap3(multicaster);
- multicaster.remove(&h5);
- DL::Snapshot snap4(multicaster);
-
- EXPECT_TRUE(!empty_snap.valid());
- for (; snap1.valid(); snap1.next()) {
- snap1.get()->add();
- }
- EXPECT_TRUE(h1.getNum() == 1);
- EXPECT_TRUE(h2.getNum() == 1);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 1);
- EXPECT_TRUE(h5.getNum() == 1);
- for (; snap2.valid(); snap2.next()) {
- snap2.get()->add();
- }
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 2);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 2);
- EXPECT_TRUE(h5.getNum() == 2);
- for (; snap3.valid(); snap3.next()) {
- snap3.get()->add();
- }
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 3);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 3);
- EXPECT_TRUE(h5.getNum() == 3);
- for (; snap4.valid(); snap4.next()) {
- snap4.get()->add();
- }
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 4);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 4);
- EXPECT_TRUE(h5.getNum() == 3);
-}
-
-
-void
-Test::testActors()
-{
- FastOS_ThreadPool pool(65000);
- History hist;
- Actor a1(1, &hist);
- Actor a2(2, &hist);
- DL dl;
- Handler h1;
- Handler h2;
-
- ASSERT_TRUE(pool.NewThread(&a1, 0) != 0);
- ASSERT_TRUE(pool.NewThread(&a2, 0) != 0);
-
- {
- CmdList prog;
- prog.push_back(cmd_add(&dl, &h1));
- prog.push_back(cmd_multicast(&dl));
- prog.push_back(cmd_add(&dl, &h2));
- prog.push_back(cmd_multicast(&dl));
- a1.doIt(prog);
- a1.waitState(Actor::STATE_IDLE);
- }
-
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 1);
-
- {
- CmdList prog;
- prog.push_back(cmd_remove(&dl, &h1));
- prog.push_back(cmd_multicast(&dl));
- prog.push_back(cmd_clear(&dl));
- prog.push_back(cmd_multicast(&dl));
- a2.doIt(prog);
- a2.waitState(Actor::STATE_IDLE);
- }
-
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 2);
-
- {
- CmdList prog;
- prog.push_back(cmd_add(&dl, &h1));
- prog.push_back(cmd_add(&dl, &h2));
- prog.push_back(cmd_multicast_clear(&dl));
- prog.push_back(cmd_multicast(&dl));
- a1.doIt(prog);
- a1.waitState(Actor::STATE_IDLE);
- }
-
- EXPECT_TRUE(h1.getNum() == 3);
- EXPECT_TRUE(h2.getNum() == 3);
-
- {
- CmdList prog;
- prog.push_back(cmd_add(&dl, &h1));
- prog.push_back(cmd_add(&dl, &h2));
- prog.push_back(cmd_do(10));
- prog.push_back(cmd_do(10));
- prog.push_back(cmd_multicast(&dl));
- prog.push_back(cmd_done());
- prog.push_back(cmd_done());
- prog.push_back(cmd_exit());
- a2.doIt(prog);
- a2.waitState(Actor::STATE_DONE);
- }
-
- EXPECT_TRUE(h1.getNum() == 103);
- EXPECT_TRUE(h2.getNum() == 103);
-
- EXPECT_TRUE(hist.list.size() == 114);
-
- EXPECT_TRUE(hist.list[0].first == cmd_add(&dl, &h1));
- EXPECT_TRUE(hist.list[1].first == cmd_multicast(&dl));
- EXPECT_TRUE(hist.list[2].first == cmd_add(&dl, &h2));
- EXPECT_TRUE(hist.list[3].first == cmd_multicast(&dl));
- for (int i = 0; i < 4; i++) {
- EXPECT_TRUE(hist.list[i].second == 1);
- }
-
- EXPECT_TRUE(hist.list[4].first == cmd_remove(&dl, &h1));
- EXPECT_TRUE(hist.list[5].first == cmd_multicast(&dl));
- EXPECT_TRUE(hist.list[6].first == cmd_clear(&dl));
- EXPECT_TRUE(hist.list[7].first == cmd_multicast(&dl));
- for (int i = 4; i < 8; i++) {
- EXPECT_TRUE(hist.list[i].second == 2);
- }
-
- EXPECT_TRUE(hist.list[8].first == cmd_add(&dl, &h1));
- EXPECT_TRUE(hist.list[9].first == cmd_add(&dl, &h2));
- EXPECT_TRUE(hist.list[10].first == cmd_multicast_clear(&dl));
- EXPECT_TRUE(hist.list[11].first == cmd_multicast(&dl));
- for (int i = 8; i < 12; i++) {
- EXPECT_TRUE(hist.list[i].second == 1);
- }
-
- EXPECT_TRUE(hist.list[12].first == cmd_add(&dl, &h1));
- EXPECT_TRUE(hist.list[13].first == cmd_add(&dl, &h2));
- EXPECT_TRUE(hist.list[12].second == 2);
- EXPECT_TRUE(hist.list[13].second == 2);
-
- for (int i = 14; i < 114; i++) {
- EXPECT_TRUE(hist.list[i].first == cmd_multicast(&dl));
- EXPECT_TRUE(hist.list[i].second == 2);
- }
-
- a1.doIt(cmd_exit());
- a1.waitState(Actor::STATE_DONE);
-
- EXPECT_TRUE(a1.getOpCnt() == 8);
- EXPECT_TRUE(a2.getOpCnt() == 106);
-}
-
-
-void
-Test::stressTest()
-{
- FastOS_ThreadPool pool(65000);
- Actor a1(1, 0);
- Actor a2(2, 0);
- Actor a3(3, 0);
- Actor a4(4, 0);
- Actor a5(5, 0);
- Actor a6(6, 0);
- DL dl;
- Handler h1;
- Handler h2;
- Handler h3;
- Handler h4;
- Handler h5;
- int scale = 10000;
-
- ASSERT_TRUE(pool.NewThread(&a1, 0) != 0);
- ASSERT_TRUE(pool.NewThread(&a2, 0) != 0);
- ASSERT_TRUE(pool.NewThread(&a3, 0) != 0);
- ASSERT_TRUE(pool.NewThread(&a4, 0) != 0);
- ASSERT_TRUE(pool.NewThread(&a5, 0) != 0);
- ASSERT_TRUE(pool.NewThread(&a6, 0) != 0);
-
- CmdList prog_multicast;
- prog_multicast.push_back(cmd_do(10 * scale));
- prog_multicast.push_back(cmd_multicast(&dl));
- prog_multicast.push_back(cmd_done());
- prog_multicast.push_back(cmd_exit());
-
- CmdList prog_wait_snap;
- prog_wait_snap.push_back(cmd_do(10 * scale));
- prog_wait_snap.push_back(cmd_wait_snap(&dl));
- prog_wait_snap.push_back(cmd_done());
- prog_wait_snap.push_back(cmd_exit());
-
- CmdList prog_add_remove_1;
- prog_add_remove_1.push_back(cmd_do(scale));
- prog_add_remove_1.push_back(cmd_add(&dl, &h1));
- prog_add_remove_1.push_back(cmd_add(&dl, &h3));
- prog_add_remove_1.push_back(cmd_remove(&dl, &h2));
- prog_add_remove_1.push_back(cmd_remove(&dl, &h4));
- prog_add_remove_1.push_back(cmd_add(&dl, &h4));
- prog_add_remove_1.push_back(cmd_add(&dl, &h2));
- prog_add_remove_1.push_back(cmd_remove(&dl, &h5));
- prog_add_remove_1.push_back(cmd_remove(&dl, &h3));
- prog_add_remove_1.push_back(cmd_add(&dl, &h5));
- prog_add_remove_1.push_back(cmd_remove(&dl, &h1));
- prog_add_remove_1.push_back(cmd_done());
- prog_add_remove_1.push_back(cmd_exit());
-
- CmdList prog_add_remove_2;
- prog_add_remove_2.push_back(cmd_do(scale));
- prog_add_remove_2.push_back(cmd_add(&dl, &h5));
- prog_add_remove_2.push_back(cmd_add(&dl, &h4));
- prog_add_remove_2.push_back(cmd_remove(&dl, &h1));
- prog_add_remove_2.push_back(cmd_remove(&dl, &h3));
- prog_add_remove_2.push_back(cmd_add(&dl, &h1));
- prog_add_remove_2.push_back(cmd_remove(&dl, &h2));
- prog_add_remove_2.push_back(cmd_add(&dl, &h2));
- prog_add_remove_2.push_back(cmd_add(&dl, &h3));
- prog_add_remove_2.push_back(cmd_remove(&dl, &h5));
- prog_add_remove_2.push_back(cmd_remove(&dl, &h4));
- prog_add_remove_2.push_back(cmd_done());
- prog_add_remove_2.push_back(cmd_exit());
-
- CmdList prog_add_remove_3;
- prog_add_remove_3.push_back(cmd_do(scale));
- prog_add_remove_3.push_back(cmd_add(&dl, &h3));
- prog_add_remove_3.push_back(cmd_remove(&dl, &h4));
- prog_add_remove_3.push_back(cmd_remove(&dl, &h3));
- prog_add_remove_3.push_back(cmd_add(&dl, &h5));
- prog_add_remove_3.push_back(cmd_add(&dl, &h2));
- prog_add_remove_3.push_back(cmd_remove(&dl, &h2));
- prog_add_remove_3.push_back(cmd_add(&dl, &h1));
- prog_add_remove_3.push_back(cmd_add(&dl, &h4));
- prog_add_remove_3.push_back(cmd_remove(&dl, &h1));
- prog_add_remove_3.push_back(cmd_remove(&dl, &h5));
- prog_add_remove_3.push_back(cmd_done());
- prog_add_remove_3.push_back(cmd_exit());
-
- a1.doIt(prog_multicast);
- a2.doIt(prog_multicast);
- a3.doIt(prog_wait_snap);
- a4.doIt(prog_add_remove_1);
- a5.doIt(prog_add_remove_2);
- a6.doIt(prog_add_remove_3);
-
- a1.waitState(Actor::STATE_DONE);
- a2.waitState(Actor::STATE_DONE);
- a3.waitState(Actor::STATE_DONE);
- a4.waitState(Actor::STATE_DONE);
- a5.waitState(Actor::STATE_DONE);
- a6.waitState(Actor::STATE_DONE);
-
- EXPECT_TRUE(a1.getOpCnt() == 10 * scale);
- EXPECT_TRUE(a2.getOpCnt() == 10 * scale);
- EXPECT_TRUE(a3.getOpCnt() == 10 * scale);
- EXPECT_TRUE(a4.getOpCnt() == 10 * scale);
- EXPECT_TRUE(a5.getOpCnt() == 10 * scale);
- EXPECT_TRUE(a6.getOpCnt() == 10 * scale);
-}
-
-
-void
-Test::testWaitSnapshots()
-{
- FastOS_ThreadPool pool(65000);
- Actor a1(1, 0);
- DL dl;
- std::unique_ptr<DL::Snapshot> s1;
- std::unique_ptr<DL::Snapshot> s2;
- ASSERT_TRUE(pool.NewThread(&a1, 0) != 0);
- s1.reset(new DL::Snapshot(dl)); // create snap 1
- a1.doIt(cmd_wait_snap(&dl)); // wait for snaps
- std::this_thread::sleep_for(1s);
- EXPECT_TRUE(a1.getState() == Actor::STATE_BUSY); // still waiting...
- s2.reset(new DL::Snapshot(dl)); // create snap 2
- s1.reset(); // destroy snap 1
- std::this_thread::sleep_for(1s);
- EXPECT_TRUE(a1.getState() == Actor::STATE_IDLE); // wait done!
- a1.doIt(cmd_exit());
- a1.waitState(Actor::STATE_DONE);
- s2.reset(); // destroy snap 2
- EXPECT_TRUE(a1.getOpCnt() == 1);
-}
-
-//-----------------------------------------------------------------------------
-
-struct Foo { void completeBarrier() {} };
-
-int
-Test::Main()
-{
- TEST_INIT("delegatelist_test");
- LOG(info, "Lock size: %4zu bytes", sizeof(Lock));
- LOG(info, "ArrayQueue size: %4zu bytes", sizeof(ArrayQueue<Foo>));
- LOG(info, "std::vector size: %4zu bytes", sizeof(std::vector<Foo>));
- LOG(info, "EventBarrier size: %4zu bytes", sizeof(EventBarrier<Foo>));
- LOG(info, "DelegateList size: %4zu bytes", sizeof(DelegateList<Foo>));
-
- testEmpty();
- testAdd();
- testRemove();
- testOneShot();
- testMultiSnapshot();
-
- TEST_FLUSH();
- testActors();
- testWaitSnapshots();
-
- TEST_FLUSH();
- stressTest();
- TEST_DONE();
-}
-
-TEST_APPHOOK(Test);
diff --git a/vespalib/src/tests/detect_type_benchmark/detect_type_benchmark.cpp b/vespalib/src/tests/detect_type_benchmark/detect_type_benchmark.cpp
index 6d178093069..71c4a7856c8 100644
--- a/vespalib/src/tests/detect_type_benchmark/detect_type_benchmark.cpp
+++ b/vespalib/src/tests/detect_type_benchmark/detect_type_benchmark.cpp
@@ -57,7 +57,7 @@ struct CheckType {
};
struct Nop {
- void operator()() const {}
+ void operator()() const noexcept {}
};
//-----------------------------------------------------------------------------
diff --git a/vespalib/src/tests/executor/blocking_executor_stress.cpp b/vespalib/src/tests/executor/blocking_executor_stress.cpp
index b753dc69373..27367f6677c 100644
--- a/vespalib/src/tests/executor/blocking_executor_stress.cpp
+++ b/vespalib/src/tests/executor/blocking_executor_stress.cpp
@@ -2,7 +2,6 @@
#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/vespalib/util/blockingthreadstackexecutor.h>
#include <vespa/vespalib/util/executor.h>
-#include <vespa/vespalib/util/sync.h>
#include <atomic>
using namespace vespalib;
@@ -26,7 +25,7 @@ struct MyTask : Executor::Task {
size_t size;
size_t data;
MyTask(size_t size_in) : size(size_in), data(0) {}
- virtual void run() override {
+ void run() override {
data += do_stuff(size);
++tasks_run;
data += do_stuff(size);
diff --git a/vespalib/src/tests/executor/blockingthreadstackexecutor_test.cpp b/vespalib/src/tests/executor/blockingthreadstackexecutor_test.cpp
index c2a3e66c671..46db619516a 100644
--- a/vespalib/src/tests/executor/blockingthreadstackexecutor_test.cpp
+++ b/vespalib/src/tests/executor/blockingthreadstackexecutor_test.cpp
@@ -3,7 +3,6 @@
#include <vespa/vespalib/util/blockingthreadstackexecutor.h>
#include <vespa/vespalib/util/executor.h>
-#include <vespa/vespalib/util/sync.h>
#include <vespa/vespalib/util/backtrace.h>
#include <thread>
diff --git a/vespalib/src/tests/executor/threadstackexecutor_test.cpp b/vespalib/src/tests/executor/threadstackexecutor_test.cpp
index 9d69adcd96a..b43a75f8244 100644
--- a/vespalib/src/tests/executor/threadstackexecutor_test.cpp
+++ b/vespalib/src/tests/executor/threadstackexecutor_test.cpp
@@ -2,7 +2,6 @@
#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/vespalib/util/threadstackexecutor.h>
-#include <vespa/vespalib/util/sync.h>
#include <vespa/vespalib/util/backtrace.h>
#include <atomic>
diff --git a/vespalib/src/tests/explore_modern_cpp/explore_modern_cpp_test.cpp b/vespalib/src/tests/explore_modern_cpp/explore_modern_cpp_test.cpp
index 1ba368b39a3..29a82138d29 100644
--- a/vespalib/src/tests/explore_modern_cpp/explore_modern_cpp_test.cpp
+++ b/vespalib/src/tests/explore_modern_cpp/explore_modern_cpp_test.cpp
@@ -5,7 +5,7 @@
TEST("verify how std::function copies lambda closures") {
size_t count = 0;
size_t value = 0;
- auto closure = [count,&value]()mutable{ ++count; value += count; };
+ auto closure = [count,&value]() mutable noexcept { ++count; value += count; };
closure();
EXPECT_EQUAL(0u, count);
EXPECT_EQUAL(1u, value); // +1
diff --git a/vespalib/src/tests/net/async_resolver/async_resolver_test.cpp b/vespalib/src/tests/net/async_resolver/async_resolver_test.cpp
index 434cb8d6a69..f04fe549c09 100644
--- a/vespalib/src/tests/net/async_resolver/async_resolver_test.cpp
+++ b/vespalib/src/tests/net/async_resolver/async_resolver_test.cpp
@@ -3,7 +3,6 @@
#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/vespalib/net/async_resolver.h>
#include <vespa/vespalib/net/socket_spec.h>
-#include <vespa/vespalib/util/sync.h>
#include <atomic>
using namespace vespalib;
@@ -11,7 +10,7 @@ using namespace vespalib;
struct ResultSetter : public AsyncResolver::ResultHandler {
SocketAddress &addr;
std::atomic<bool> done;
- ResultSetter(SocketAddress &addr_out) : addr(addr_out), done(false) {}
+ ResultSetter(SocketAddress &addr_out) noexcept : addr(addr_out), done(false) {}
void handle_result(SocketAddress result) override {
addr = result;
done = true;
@@ -31,7 +30,7 @@ struct MyClock : public AsyncResolver::Clock {
struct BlockingHostResolver : public AsyncResolver::HostResolver {
CountDownLatch callers;
Gate barrier;
- BlockingHostResolver(size_t num_callers)
+ BlockingHostResolver(size_t num_callers) noexcept
: callers(num_callers), barrier() {}
vespalib::string ip_address(const vespalib::string &) override {
callers.countDown();
diff --git a/vespalib/src/tests/portal/portal_test.cpp b/vespalib/src/tests/portal/portal_test.cpp
index 0bd029c0c3a..07d3b9e1bfb 100644
--- a/vespalib/src/tests/portal/portal_test.cpp
+++ b/vespalib/src/tests/portal/portal_test.cpp
@@ -202,7 +202,7 @@ TEST("require that get requests dropped on the floor returns HTTP error") {
vespalib::string path = "/test";
auto portal = Portal::create(null_crypto(), 0);
auto expect = make_expected_error(500, "Internal Server Error");
- MyGetHandler handler([](Portal::GetRequest){});
+ MyGetHandler handler([](Portal::GetRequest) noexcept {});
auto bound = portal->bind(path, handler);
auto result = fetch(portal->listen_port(), null_crypto(), path);
EXPECT_EQUAL(result, expect);
diff --git a/vespalib/src/tests/priority_queue/priority_queue_test.cpp b/vespalib/src/tests/priority_queue/priority_queue_test.cpp
index 3457c2bde6b..af8dd853c6c 100644
--- a/vespalib/src/tests/priority_queue/priority_queue_test.cpp
+++ b/vespalib/src/tests/priority_queue/priority_queue_test.cpp
@@ -154,11 +154,11 @@ TEST("require that priority queue works with move-only objects") {
struct MyItem {
int value;
int *ref;
- MyItem(int v, int &r) : value(v), ref(&r) {}
- MyItem(const MyItem &) = delete;
- MyItem &operator=(const MyItem &) = delete;
- MyItem(MyItem &&rhs) : value(rhs.value), ref(rhs.ref) { rhs.ref = 0; }
- MyItem &operator=(MyItem &&rhs) {
+ MyItem(int v, int &r) noexcept : value(v), ref(&r) {}
+ MyItem(const MyItem &) noexcept = delete;
+ MyItem &operator=(const MyItem &) noexcept = delete;
+ MyItem(MyItem &&rhs) noexcept : value(rhs.value), ref(rhs.ref) { rhs.ref = 0; }
+ MyItem &operator=(MyItem &&rhs) noexcept {
value = rhs.value;
ref = rhs.ref;
rhs.ref = 0;
diff --git a/vespalib/src/tests/rwlock/.gitignore b/vespalib/src/tests/rwlock/.gitignore
deleted file mode 100644
index 3ba74c11b14..00000000000
--- a/vespalib/src/tests/rwlock/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.depend
-Makefile
-rwlock_test
-vespalib_rwlock_test_app
diff --git a/vespalib/src/tests/rwlock/CMakeLists.txt b/vespalib/src/tests/rwlock/CMakeLists.txt
deleted file mode 100644
index 2eda95a200c..00000000000
--- a/vespalib/src/tests/rwlock/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_executable(vespalib_rwlock_test_app TEST
- SOURCES
- rwlock_test.cpp
- DEPENDS
- vespalib
-)
-vespa_add_test(NAME vespalib_rwlock_test_app COMMAND vespalib_rwlock_test_app)
diff --git a/vespalib/src/tests/rwlock/rwlock_test.cpp b/vespalib/src/tests/rwlock/rwlock_test.cpp
deleted file mode 100644
index 66e73c3a5d9..00000000000
--- a/vespalib/src/tests/rwlock/rwlock_test.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include <vespa/vespalib/testkit/testapp.h>
-#include <vespa/vespalib/util/rwlock.h>
-
-using namespace vespalib;
-
-class RWLockTest : public TestApp
-{
-public:
- int Main() override;
- static RWLockReader rbvReader(RWLock & lock) { RWLockReader r(lock); return r; }
- static RWLockWriter rbvWriter(RWLock & lock) { RWLockWriter r(lock); return r; }
-};
-
-
-int
-RWLockTest::Main()
-{
- TEST_INIT("rwlock_test");
-
- RWLock lock;
- EXPECT_TRUE(lock._givenLocks == 0);
- {
- EXPECT_TRUE(lock._givenLocks == 0);
- RWLockReader r1(lock);
- EXPECT_TRUE(lock._givenLocks == 1);
- RWLockReader r2(lock);
- EXPECT_TRUE(lock._givenLocks == 2);
- RWLockReader r3(lock);
- EXPECT_TRUE(lock._givenLocks == 3);
- }
- EXPECT_TRUE(lock._givenLocks == 0);
- {
- EXPECT_TRUE(lock._givenLocks == 0);
- RWLockWriter w(lock);
- EXPECT_TRUE(lock._givenLocks == -1);
- }
- EXPECT_TRUE(lock._givenLocks == 0);
- {
- RWLockReader rbv(rbvReader(lock));
- EXPECT_TRUE(lock._givenLocks == 1);
- RWLockReader copy(rbv);
- EXPECT_TRUE(lock._givenLocks == 1);
- RWLockReader copy2(copy);
- EXPECT_TRUE(lock._givenLocks == 1);
- }
- EXPECT_TRUE(lock._givenLocks == 0);
- {
- RWLock lock2;
- RWLockReader copy(rbvReader(lock));
- EXPECT_TRUE(lock._givenLocks == 1);
- RWLockReader copy2(rbvReader(lock2));
- EXPECT_TRUE(lock._givenLocks == 1);
- EXPECT_TRUE(lock2._givenLocks == 1);
- RWLockReader rbv(rbvReader(lock));
- EXPECT_TRUE(lock._givenLocks == 2);
- copy=rbv;
- EXPECT_TRUE(lock._givenLocks == 1);
- copy2=copy;
- EXPECT_TRUE(lock2._givenLocks == 0);
- EXPECT_TRUE(lock._givenLocks == 1);
- }
- EXPECT_TRUE(lock._givenLocks == 0);
- {
- RWLockWriter rbv(rbvWriter(lock));
- EXPECT_TRUE(lock._givenLocks == -1);
- RWLockWriter copy(rbv);
- EXPECT_TRUE(lock._givenLocks == -1);
- RWLockWriter copy2(copy);
- EXPECT_TRUE(lock._givenLocks == -1);
- }
- EXPECT_TRUE(lock._givenLocks == 0);
-
- TEST_DONE();
-}
-
-TEST_APPHOOK(RWLockTest)
diff --git a/vespalib/src/tests/simple_thread_bundle/simple_thread_bundle_test.cpp b/vespalib/src/tests/simple_thread_bundle/simple_thread_bundle_test.cpp
index 5641d751f34..d3c562c583c 100644
--- a/vespalib/src/tests/simple_thread_bundle/simple_thread_bundle_test.cpp
+++ b/vespalib/src/tests/simple_thread_bundle/simple_thread_bundle_test.cpp
@@ -3,7 +3,6 @@
#include <vespa/vespalib/util/simple_thread_bundle.h>
#include <vespa/vespalib/util/exceptions.h>
#include <vespa/vespalib/util/box.h>
-#include <vespa/vespalib/util/sync.h>
using namespace vespalib;
using namespace vespalib::fixed_thread_bundle;
diff --git a/vespalib/src/tests/stllike/hash_test.cpp b/vespalib/src/tests/stllike/hash_test.cpp
index e86a9ad020a..2b190b6b2dc 100644
--- a/vespalib/src/tests/stllike/hash_test.cpp
+++ b/vespalib/src/tests/stllike/hash_test.cpp
@@ -15,14 +15,14 @@ namespace {
struct Foo {
int i;
- Foo() : i(0) {}
- Foo(int i_) : i(i_) {}
+ Foo() noexcept : i(0) {}
+ Foo(int i_) noexcept : i(i_) {}
- bool operator==(const Foo& f) const
+ bool operator==(const Foo& f) const noexcept
{ return (i == f.i); }
struct hash {
- size_t operator() (const Foo& f) const {
+ size_t operator() (const Foo& f) const noexcept {
return (f.i % 16);
}
};
@@ -33,7 +33,7 @@ namespace {
TEST("test that hashValue gives expected response")
{
const char * s("abcdefghi");
- EXPECT_EQUAL(2878261200250560019ul, vespalib::hashValue(s));
+ EXPECT_EQUAL(16203358805722239136ul, vespalib::hashValue(s));
EXPECT_EQUAL(vespalib::hashValue(s), vespalib::hashValue(s, strlen(s)));
EXPECT_NOT_EQUAL(vespalib::hashValue(s), vespalib::hashValue(s, strlen(s)-1));
}
@@ -332,10 +332,10 @@ TEST("test hash map with simple key and value type")
class S {
public:
- explicit S(uint64_t l=0) : _a(l&0xfffffffful), _b(l>>32) { }
+ explicit S(uint64_t l=0) noexcept : _a(l&0xfffffffful), _b(l>>32) { }
uint32_t hash() const { return _a; }
uint32_t a() const { return _a; }
- friend bool operator == (const S & a, const S & b) { return a._a == b._a && a._b == b._b; }
+ friend bool operator == (const S & a, const S & b) noexcept { return a._a == b._a && a._b == b._b; }
private:
uint32_t _a, _b;
};
diff --git a/vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp b/vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp
index 72a0c93c719..faee7680426 100644
--- a/vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp
+++ b/vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp
@@ -71,13 +71,13 @@ class Gid
{
public:
struct hash {
- size_t operator () (const Gid & g) const { return g.getGid()[0]; }
+ size_t operator () (const Gid & g) const noexcept { return g.getGid()[0]; }
};
- Gid(unsigned int v=0) : _gid() { _gid[0] = _gid[1] = _gid[2] = v; }
+ Gid(unsigned int v=0) noexcept : _gid() { _gid[0] = _gid[1] = _gid[2] = v; }
const unsigned int * getGid() const { return _gid; }
- int cmp(const Gid & b) const { return memcmp(_gid, b._gid, sizeof(_gid)); }
- bool operator < (const Gid & b) const { return cmp(b) < 0; }
- bool operator == (const Gid & b) const { return cmp(b) == 0; }
+ int cmp(const Gid & b) const noexcept { return memcmp(_gid, b._gid, sizeof(_gid)); }
+ bool operator < (const Gid & b) const noexcept { return cmp(b) < 0; }
+ bool operator == (const Gid & b) const noexcept { return cmp(b) == 0; }
private:
unsigned int _gid[3];
};
@@ -85,15 +85,15 @@ private:
class Slot
{
public:
- Slot(unsigned int v=0) : _gid(v) { }
+ Slot(unsigned int v=0) noexcept : _gid(v) { }
const Gid & getGid() const { return _gid; }
- int cmp(const Slot & b) const { return _gid.cmp(b.getGid()); }
+ int cmp(const Slot & b) const noexcept { return _gid.cmp(b.getGid()); }
private:
Gid _gid;
};
struct IndirectCmp : public std::binary_function<Slot*, Slot*, bool> {
- bool operator()(const Slot* s1, const Slot* s2) {
+ bool operator() (const Slot* s1, const Slot* s2) noexcept {
return s1->cmp(*s2) < 0;
}
};
diff --git a/vespalib/src/tests/sync/sync_test.cpp b/vespalib/src/tests/sync/sync_test.cpp
index a17f9089877..3a2cf0ea7a0 100644
--- a/vespalib/src/tests/sync/sync_test.cpp
+++ b/vespalib/src/tests/sync/sync_test.cpp
@@ -3,6 +3,41 @@
#include <vespa/vespalib/testkit/testapp.h>
#include <vespa/vespalib/util/sync.h>
+namespace vespalib {
+class TryLock
+{
+private:
+ friend class LockGuard;
+ friend class MonitorGuard;
+
+ std::unique_lock<std::mutex> _guard;
+ std::condition_variable *_cond;
+
+public:
+ TryLock(const Monitor &mon)
+ : _guard(*mon._mutex, std::try_to_lock),
+ _cond(_guard ? mon._cond.get() : nullptr)
+ {}
+ ~TryLock() = default;
+
+ TryLock(const TryLock &) = delete;
+ TryLock &operator=(const TryLock &) = delete;
+
+ /**
+ * @brief Check whether this object holds a lock
+ *
+ * @return true if this object holds a lock
+ **/
+ bool hasLock() const { return static_cast<bool>(_guard); }
+ void unlock() {
+ if (_guard) {
+ _guard.unlock();
+ _cond = nullptr;
+ }
+ }
+};
+
+}
using namespace vespalib;
#define CHECK_LOCKED(m) { TryLock tl(m); EXPECT_TRUE(!tl.hasLock()); }
@@ -11,19 +46,18 @@ using namespace vespalib;
class Test : public TestApp
{
private:
- Lock _lock;
Monitor _monitor;
- LockGuard lockLock() { return LockGuard(_lock); }
LockGuard lockMonitor() { return LockGuard(_monitor); }
MonitorGuard obtainMonitor() { return MonitorGuard(_monitor); }
public:
- ~Test();
+ ~Test() override;
void testCountDownLatch();
int Main() override;
};
-Test::~Test() {}
+Test::~Test() = default;
+
void
Test::testCountDownLatch() {
{
@@ -70,21 +104,6 @@ int
Test::Main()
{
TEST_INIT("sync_test");
- {
- Lock lock;
- {
- CHECK_UNLOCKED(lock);
- LockGuard guard(lock);
- CHECK_LOCKED(lock);
- }
- CHECK_UNLOCKED(lock);
- {
- LockGuard guard(lock);
- CHECK_LOCKED(lock);
- guard.unlock();
- CHECK_UNLOCKED(lock);
- }
- }
// you can use a LockGuard to lock a Monitor
{
Monitor monitor;
@@ -119,24 +138,9 @@ Test::Main()
CHECK_UNLOCKED(monitor);
}
}
- // copy/assign is nop, but legal
- {
- Lock a;
- Lock b(a);
- b = a;
- }
- {
- Monitor a;
- Monitor b(a);
- b = a;
- }
+
// you can lock const objects
- {
- const Lock lock;
- CHECK_UNLOCKED(lock);
- LockGuard guard(lock);
- CHECK_LOCKED(lock);
- }
+
{
const Monitor lock;
CHECK_UNLOCKED(lock);
@@ -149,100 +153,9 @@ Test::Main()
MonitorGuard guard(monitor);
CHECK_LOCKED(monitor);
}
- // TryLock hands the lock over to a LockGuard/MonitorGuard
- {
- Lock lock;
- CHECK_UNLOCKED(lock);
- TryLock a(lock);
- CHECK_LOCKED(lock);
- if (a.hasLock()) {
- LockGuard guard(std::move(a));
- CHECK_LOCKED(lock);
- }
- CHECK_UNLOCKED(lock);
- }
- {
- Monitor mon;
- CHECK_UNLOCKED(mon);
- TryLock a(mon);
- CHECK_LOCKED(mon);
- if (a.hasLock()) {
- LockGuard guard(std::move(a));
- CHECK_LOCKED(mon);
- }
- CHECK_UNLOCKED(mon);
- }
- {
- Monitor mon;
- CHECK_UNLOCKED(mon);
- TryLock a(mon);
- CHECK_LOCKED(mon);
- if (a.hasLock()) {
- MonitorGuard guard(std::move(a));
- CHECK_LOCKED(mon);
- }
- CHECK_UNLOCKED(mon);
- }
- {
- Lock lock;
-
- CHECK_UNLOCKED(lock);
- TryLock a(lock);
- CHECK_LOCKED(lock);
- TryLock b(lock);
- CHECK_LOCKED(lock);
-
- EXPECT_TRUE(a.hasLock());
- EXPECT_TRUE(!b.hasLock());
- {
- CHECK_LOCKED(lock);
- EXPECT_TRUE(a.hasLock());
- LockGuard guard(std::move(a));
- EXPECT_TRUE(!a.hasLock());
- CHECK_LOCKED(lock);
- }
- CHECK_UNLOCKED(lock);
- }
- // TryLock will unlock when exiting scope if lock was not passed on
- {
- Lock lock;
- Monitor mon;
- CHECK_UNLOCKED(lock);
- CHECK_UNLOCKED(mon);
- {
- TryLock a(lock);
- EXPECT_TRUE(a.hasLock());
- TryLock b(mon);
- EXPECT_TRUE(b.hasLock());
- CHECK_LOCKED(lock);
- CHECK_LOCKED(mon);
- }
- CHECK_UNLOCKED(lock);
- CHECK_UNLOCKED(mon);
- }
- // TryLock explicitt unlock of lock
- {
- Lock lock;
- TryLock tl(lock);
- EXPECT_TRUE(tl.hasLock());
- tl.unlock();
- EXPECT_FALSE(tl.hasLock());
- tl.unlock();
- EXPECT_FALSE(tl.hasLock());
- }
- // TryLock explicitt unlock of monitor
- {
- Monitor lock;
- TryLock tl(lock);
- EXPECT_TRUE(tl.hasLock());
- tl.unlock();
- EXPECT_FALSE(tl.hasLock());
- tl.unlock();
- EXPECT_FALSE(tl.hasLock());
- }
// LockGuard/MonitorGuard have destructive move
{
- Lock lock;
+ Monitor lock;
CHECK_UNLOCKED(lock);
LockGuard a(lock);
CHECK_LOCKED(lock);
@@ -267,19 +180,13 @@ Test::Main()
}
// Destructive copy also works for return value handover
{
- CHECK_UNLOCKED(_lock);
CHECK_UNLOCKED(_monitor);
{
- CHECK_UNLOCKED(_lock);
CHECK_UNLOCKED(_monitor);
- LockGuard a(lockLock());
- CHECK_LOCKED(_lock);
CHECK_UNLOCKED(_monitor);
LockGuard b = lockMonitor(); // copy, not assign
- CHECK_LOCKED(_lock);
CHECK_LOCKED(_monitor);
}
- CHECK_UNLOCKED(_lock);
CHECK_UNLOCKED(_monitor);
}
{
@@ -293,8 +200,8 @@ Test::Main()
}
// Test that guards can be matched to locks/monitors
{
- Lock lock1;
- Lock lock2;
+ Monitor lock1;
+ Monitor lock2;
LockGuard lockGuard1(lock1);
LockGuard lockGuard2(lock2);
EXPECT_TRUE(lockGuard1.locks(lock1));
diff --git a/vespalib/src/tests/time_tracer/time_tracer_test.cpp b/vespalib/src/tests/time_tracer/time_tracer_test.cpp
index d7e2e0d579a..6d55e867ba5 100644
--- a/vespalib/src/tests/time_tracer/time_tracer_test.cpp
+++ b/vespalib/src/tests/time_tracer/time_tracer_test.cpp
@@ -67,8 +67,8 @@ TEST("require that records are extracted inversely ordered by end time per threa
}
TEST("benchmark time sampling") {
- double min_stamp_us = 1000000.0 * BenchmarkTimer::benchmark([](){ (void) TimeTracer::now(); }, 1.0);
- double min_sample_us = 1000000.0 * BenchmarkTimer::benchmark([](){ TT_Sample my_sample(my_tag); }, 1.0);
+ double min_stamp_us = 1000000.0 * BenchmarkTimer::benchmark([]() noexcept { (void) TimeTracer::now(); }, 1.0);
+ double min_sample_us = 1000000.0 * BenchmarkTimer::benchmark([]() noexcept { TT_Sample my_sample(my_tag); }, 1.0);
fprintf(stderr, "min timestamp time: %g us\n", min_stamp_us);
fprintf(stderr, "min sample time: %g us\n", min_sample_us);
fprintf(stderr, "estimated non-clock overhead: %g us\n", (min_sample_us - (min_stamp_us * 2.0)));
diff --git a/vespalib/src/tests/util/generationhandler_stress/generation_handler_stress_test.cpp b/vespalib/src/tests/util/generationhandler_stress/generation_handler_stress_test.cpp
index a61f9fb5bca..2c1463e506a 100644
--- a/vespalib/src/tests/util/generationhandler_stress/generation_handler_stress_test.cpp
+++ b/vespalib/src/tests/util/generationhandler_stress/generation_handler_stress_test.cpp
@@ -15,7 +15,7 @@ struct WorkContext
{
uint64_t _generation;
- WorkContext()
+ WorkContext() noexcept
: _generation(0)
{
}
diff --git a/vespalib/src/vespa/vespalib/btree/btree_key_data.h b/vespalib/src/vespa/vespalib/btree/btree_key_data.h
index dc44faf00a9..5d4929694d5 100644
--- a/vespalib/src/vespa/vespalib/btree/btree_key_data.h
+++ b/vespalib/src/vespa/vespalib/btree/btree_key_data.h
@@ -28,12 +28,12 @@ public:
KeyT _key;
DataT _data;
- BTreeKeyData()
+ BTreeKeyData() noexcept
: _key(),
_data()
{}
- BTreeKeyData(const KeyT &key, const DataT &data)
+ BTreeKeyData(const KeyT &key, const DataT &data) noexcept
: _key(key),
_data(data)
{}
@@ -60,9 +60,9 @@ public:
KeyT _key;
- BTreeKeyData() : _key() {}
+ BTreeKeyData() noexcept : _key() {}
- BTreeKeyData(const KeyT &key, const BTreeNoLeafData &)
+ BTreeKeyData(const KeyT &key, const BTreeNoLeafData &) noexcept
: _key(key)
{
}
diff --git a/vespalib/src/vespa/vespalib/data/databuffer.cpp b/vespalib/src/vespa/vespalib/data/databuffer.cpp
index 04c4b1e225b..6b98226e50e 100644
--- a/vespalib/src/vespa/vespalib/data/databuffer.cpp
+++ b/vespalib/src/vespa/vespalib/data/databuffer.cpp
@@ -11,7 +11,7 @@ size_t padbefore(size_t alignment, const char *buf) {
}
}
-DataBuffer::DataBuffer(size_t len, size_t alignment, const Alloc & initial)
+DataBuffer::DataBuffer(size_t len, size_t alignment, const Alloc & initial) noexcept
: _alignment(alignment),
_externalBuf(nullptr),
_bufstart(nullptr),
diff --git a/vespalib/src/vespa/vespalib/data/databuffer.h b/vespalib/src/vespa/vespalib/data/databuffer.h
index 7c4cd63a7b1..93da2b92379 100644
--- a/vespalib/src/vespa/vespalib/data/databuffer.h
+++ b/vespalib/src/vespa/vespalib/data/databuffer.h
@@ -44,8 +44,8 @@ public:
typedef std::unique_ptr<DataBuffer> UP;
DataBuffer(const DataBuffer &) = delete;
DataBuffer &operator=(const DataBuffer &) = delete;
- DataBuffer(DataBuffer &&) = default;
- DataBuffer &operator=(DataBuffer &&) = default;
+ DataBuffer(DataBuffer &&) noexcept = default;
+ DataBuffer &operator=(DataBuffer &&) noexcept = default;
/**
* Construct a databuffer.
@@ -53,7 +53,7 @@ public:
* @param len the initial size of the buffer.
* @param alignment required memory alignment for data start
**/
- DataBuffer(size_t len = 1024, size_t alignment = 1, const Alloc & initial = Alloc::alloc(0));
+ DataBuffer(size_t len = 1024, size_t alignment = 1, const Alloc & initial = Alloc::alloc(0)) noexcept;
/**
* Construct a databuffer using externally allocated memory. Note
@@ -63,7 +63,7 @@ public:
* @param buf pointer to preallocated memory
* @param len length of preallocated memory
**/
- DataBuffer(void *buf, size_t len) :
+ DataBuffer(void *buf, size_t len) noexcept :
_alignment(1),
_externalBuf(static_cast<char *>(buf)),
_bufstart(_externalBuf),
@@ -73,7 +73,7 @@ public:
_buffer(Alloc::alloc(0))
{ }
- DataBuffer(const void *buf, size_t len) :
+ DataBuffer(const void *buf, size_t len) noexcept :
_alignment(1),
_externalBuf(static_cast<char *>(const_cast<void *>(buf))),
_bufstart(_externalBuf),
diff --git a/vespalib/src/vespa/vespalib/data/memorydatastore.cpp b/vespalib/src/vespa/vespalib/data/memorydatastore.cpp
index df1b68cff12..1f8c72a5a64 100644
--- a/vespalib/src/vespa/vespalib/data/memorydatastore.cpp
+++ b/vespalib/src/vespa/vespalib/data/memorydatastore.cpp
@@ -5,8 +5,9 @@
namespace vespalib {
using alloc::Alloc;
+using LockGuard = std::lock_guard<std::mutex>;
-MemoryDataStore::MemoryDataStore(Alloc && initialAlloc, Lock * lock) :
+MemoryDataStore::MemoryDataStore(Alloc && initialAlloc, std::mutex * lock) :
_buffers(),
_writePos(0),
_lock(lock)
diff --git a/vespalib/src/vespa/vespalib/data/memorydatastore.h b/vespalib/src/vespa/vespalib/data/memorydatastore.h
index 2d02bfb107c..fa6113279da 100644
--- a/vespalib/src/vespa/vespalib/data/memorydatastore.h
+++ b/vespalib/src/vespa/vespalib/data/memorydatastore.h
@@ -3,8 +3,8 @@
#include <vespa/vespalib/util/alloc.h>
#include <vespa/vespalib/util/array.h>
-#include <vespa/vespalib/util/sync.h>
#include <vector>
+#include <mutex>
namespace vespalib {
@@ -24,7 +24,7 @@ public:
private:
void * _data;
};
- MemoryDataStore(alloc::Alloc && initialAlloc=alloc::Alloc::alloc(256), Lock * lock=nullptr);
+ MemoryDataStore(alloc::Alloc && initialAlloc=alloc::Alloc::alloc(256), std::mutex * lock=nullptr);
MemoryDataStore(const MemoryDataStore &) = delete;
MemoryDataStore & operator = (const MemoryDataStore &) = delete;
~MemoryDataStore();
@@ -41,7 +41,7 @@ public:
private:
std::vector<alloc::Alloc> _buffers;
size_t _writePos;
- Lock * _lock;
+ std::mutex * _lock;
};
class VariableSizeVector
diff --git a/vespalib/src/vespa/vespalib/data/slime/json_format.cpp b/vespalib/src/vespa/vespalib/data/slime/json_format.cpp
index d2f953b38c8..080e3b8da48 100644
--- a/vespalib/src/vespa/vespalib/data/slime/json_format.cpp
+++ b/vespalib/src/vespa/vespalib/data/slime/json_format.cpp
@@ -8,6 +8,7 @@
#include <vespa/vespalib/locale/c.h>
#include <cmath>
#include <sstream>
+#include <cassert>
#include <vespa/log/log.h>
LOG_SETUP(".vespalib.data.slime.json_format");
diff --git a/vespalib/src/vespa/vespalib/data/slime/slime.h b/vespalib/src/vespa/vespalib/data/slime/slime.h
index 6523cd1dac0..3ee608799a6 100644
--- a/vespalib/src/vespa/vespalib/data/slime/slime.h
+++ b/vespalib/src/vespa/vespalib/data/slime/slime.h
@@ -86,7 +86,7 @@ public:
~Slime();
- Slime(Slime &&rhs) :
+ Slime(Slime &&rhs) noexcept :
_names(std::move(rhs._names)),
_stash(std::move(rhs._stash)),
_root(std::move(rhs._root))
diff --git a/vespalib/src/vespa/vespalib/datastore/entryref.h b/vespalib/src/vespa/vespalib/datastore/entryref.h
index 51a4e0699fc..4a5123ee1b3 100644
--- a/vespalib/src/vespa/vespalib/datastore/entryref.h
+++ b/vespalib/src/vespa/vespalib/datastore/entryref.h
@@ -13,13 +13,13 @@ class EntryRef {
protected:
uint32_t _ref;
public:
- EntryRef() : _ref(0u) { }
- explicit EntryRef(uint32_t ref_) : _ref(ref_) { }
- uint32_t ref() const { return _ref; }
- bool valid() const { return _ref != 0u; }
- bool operator==(const EntryRef &rhs) const { return _ref == rhs._ref; }
- bool operator!=(const EntryRef &rhs) const { return _ref != rhs._ref; }
- bool operator <(const EntryRef &rhs) const { return _ref < rhs._ref; }
+ EntryRef() noexcept : _ref(0u) { }
+ explicit EntryRef(uint32_t ref_) noexcept : _ref(ref_) { }
+ uint32_t ref() const noexcept { return _ref; }
+ bool valid() const noexcept { return _ref != 0u; }
+ bool operator==(const EntryRef &rhs) const noexcept { return _ref == rhs._ref; }
+ bool operator!=(const EntryRef &rhs) const noexcept { return _ref != rhs._ref; }
+ bool operator <(const EntryRef &rhs) const noexcept { return _ref < rhs._ref; }
};
/**
@@ -29,9 +29,9 @@ public:
template <uint32_t OffsetBits, uint32_t BufferBits = 32u - OffsetBits>
class EntryRefT : public EntryRef {
public:
- EntryRefT() : EntryRef() {}
- EntryRefT(size_t offset_, uint32_t bufferId_);
- EntryRefT(const EntryRef & ref_) : EntryRef(ref_.ref()) {}
+ EntryRefT() noexcept : EntryRef() {}
+ EntryRefT(size_t offset_, uint32_t bufferId_) noexcept;
+ EntryRefT(const EntryRef & ref_) noexcept : EntryRef(ref_.ref()) {}
size_t offset() const { return _ref & (offsetSize() - 1); }
uint32_t bufferId() const { return _ref >> OffsetBits; }
static size_t offsetSize() { return 1ul << OffsetBits; }
@@ -55,10 +55,10 @@ private:
typedef EntryRefT<OffsetBits> ParentType;
static const uint32_t PadConstant = ((1 << OffsetAlign) - 1);
public:
- AlignedEntryRefT() : ParentType() {}
- AlignedEntryRefT(size_t offset_, uint32_t bufferId_) :
+ AlignedEntryRefT() noexcept : ParentType() {}
+ AlignedEntryRefT(size_t offset_, uint32_t bufferId_) noexcept :
ParentType(align(offset_) >> OffsetAlign, bufferId_) {}
- AlignedEntryRefT(const EntryRef & ref_) : ParentType(ref_) {}
+ AlignedEntryRefT(const EntryRef & ref_) noexcept : ParentType(ref_) {}
size_t offset() const { return ParentType::offset() << OffsetAlign; }
static size_t offsetSize() { return ParentType::offsetSize() << OffsetAlign; }
static size_t align(size_t val) { return val + pad(val); }
diff --git a/vespalib/src/vespa/vespalib/datastore/entryref.hpp b/vespalib/src/vespa/vespalib/datastore/entryref.hpp
index 56ebe62dfab..34b8d5355e3 100644
--- a/vespalib/src/vespa/vespalib/datastore/entryref.hpp
+++ b/vespalib/src/vespa/vespalib/datastore/entryref.hpp
@@ -8,7 +8,7 @@
namespace vespalib::datastore {
template <uint32_t OffsetBits, uint32_t BufferBits>
-EntryRefT<OffsetBits, BufferBits>::EntryRefT(size_t offset_, uint32_t bufferId_) :
+EntryRefT<OffsetBits, BufferBits>::EntryRefT(size_t offset_, uint32_t bufferId_) noexcept :
EntryRef((bufferId_ << OffsetBits) + offset_)
{
ASSERT_ONCE_OR_LOG(offset_ < offsetSize(), "EntryRefT.offset_overflow", 10000);
diff --git a/vespalib/src/vespa/vespalib/net/socket_address.h b/vespalib/src/vespa/vespalib/net/socket_address.h
index 2b75eae8948..543af44a56e 100644
--- a/vespalib/src/vespa/vespalib/net/socket_address.h
+++ b/vespalib/src/vespa/vespalib/net/socket_address.h
@@ -48,7 +48,7 @@ public:
vespalib::string name() const;
vespalib::string spec() const;
SocketHandle connect(const std::function<bool(SocketHandle&)> &tweak) const;
- SocketHandle connect() const { return connect([](SocketHandle&){ return true; }); }
+ SocketHandle connect() const { return connect([](SocketHandle&) noexcept { return true; }); }
SocketHandle connect_async() const {
return connect([](SocketHandle &handle){ return handle.set_blocking(false); });
}
diff --git a/vespalib/src/vespa/vespalib/portal/portal.h b/vespalib/src/vespa/vespalib/portal/portal.h
index 1c5b9f88a5f..5ac2d85a6e3 100644
--- a/vespalib/src/vespa/vespalib/portal/portal.h
+++ b/vespalib/src/vespa/vespalib/portal/portal.h
@@ -53,7 +53,7 @@ public:
GetRequest(const GetRequest &rhs) = delete;
GetRequest &operator=(const GetRequest &rhs) = delete;
GetRequest &operator=(GetRequest &&rhs) = delete;
- GetRequest(GetRequest &&rhs) : _conn(rhs._conn) {
+ GetRequest(GetRequest &&rhs) noexcept : _conn(rhs._conn) {
rhs._conn = nullptr;
}
bool active() const { return (_conn != nullptr); }
diff --git a/vespalib/src/vespa/vespalib/portal/reactor.h b/vespalib/src/vespa/vespalib/portal/reactor.h
index a7961c3c943..408f358d31b 100644
--- a/vespalib/src/vespa/vespalib/portal/reactor.h
+++ b/vespalib/src/vespa/vespalib/portal/reactor.h
@@ -60,7 +60,7 @@ private:
public:
Reactor(std::function<int()> tick);
- Reactor() : Reactor([](){ return -1; }) {}
+ Reactor() : Reactor([]() noexcept { return -1; }) {}
~Reactor();
Token::UP attach(EventHandler &handler, int fd, bool read, bool write);
};
diff --git a/vespalib/src/vespa/vespalib/stllike/hash_fun.cpp b/vespalib/src/vespa/vespalib/stllike/hash_fun.cpp
index 5f4fee06c4a..84882d763d6 100644
--- a/vespalib/src/vespa/vespalib/stllike/hash_fun.cpp
+++ b/vespalib/src/vespa/vespalib/stllike/hash_fun.cpp
@@ -6,7 +6,7 @@
namespace vespalib {
size_t
-hashValue(const char *str)
+hashValue(const char *str) noexcept
{
return hashValue(str, strlen(str));
}
@@ -14,15 +14,15 @@ hashValue(const char *str)
/**
* @brief Calculate hash value.
*
- * The hash function XXH64 from xxhash library.
+ * The hash function XXH3_64bits from xxhash library.
* @param buf input buffer
* @param sz input buffer size
* @return hash value of input
**/
size_t
-hashValue(const void * buf, size_t sz)
+hashValue(const void * buf, size_t sz) noexcept
{
- return XXH64(buf, sz, 0);
+ return XXH3_64bits(buf, sz);
}
}
diff --git a/vespalib/src/vespa/vespalib/stllike/hash_fun.h b/vespalib/src/vespa/vespalib/stllike/hash_fun.h
index c5f239f2b4e..089e8b14039 100644
--- a/vespalib/src/vespa/vespalib/stllike/hash_fun.h
+++ b/vespalib/src/vespa/vespalib/stllike/hash_fun.h
@@ -8,71 +8,71 @@ namespace vespalib {
template<typename K> struct hash {
// specializations operate as functor for known key types
- size_t operator() (const K & v) const {
+ size_t operator() (const K & v) const noexcept(noexcept(v.hash())) {
return v.hash();
}
};
template<> struct hash<char> {
- size_t operator() (char arg) const { return arg; }
+ size_t operator() (char arg) const noexcept { return arg; }
};
template<> struct hash<signed char> {
- size_t operator() (signed char arg) const { return arg; }
+ size_t operator() (signed char arg) const noexcept { return arg; }
};
template<> struct hash<short> {
- size_t operator() (short arg) const { return arg; }
+ size_t operator() (short arg) const noexcept { return arg; }
};
template<> struct hash<int> {
- size_t operator() (int arg) const { return arg; }
+ size_t operator() (int arg) const noexcept { return arg; }
};
template<> struct hash<long> {
- size_t operator() (long arg) const { return arg; }
+ size_t operator() (long arg) const noexcept { return arg; }
};
template<> struct hash<long long> {
- size_t operator() (long long arg) const { return arg; }
+ size_t operator() (long long arg) const noexcept { return arg; }
};
template<> struct hash<unsigned char> {
- size_t operator() (unsigned char arg) const { return arg; }
+ size_t operator() (unsigned char arg) const noexcept { return arg; }
};
template<> struct hash<unsigned short> {
- size_t operator() (unsigned short arg) const { return arg; }
+ size_t operator() (unsigned short arg) const noexcept { return arg; }
};
template<> struct hash<unsigned int> {
- size_t operator() (unsigned int arg) const { return arg; }
+ size_t operator() (unsigned int arg) const noexcept { return arg; }
};
template<> struct hash<unsigned long> {
- size_t operator() (unsigned long arg) const { return arg; }
+ size_t operator() (unsigned long arg) const noexcept { return arg; }
};
template<> struct hash<unsigned long long> {
- size_t operator() (unsigned long long arg) const { return arg; }
+ size_t operator() (unsigned long long arg) const noexcept { return arg; }
};
template<> struct hash<float> {
union U { float f; uint32_t i; };
- size_t operator() (float arg) const { U t; t.f = arg; return t.i; }
+ size_t operator() (float arg) const noexcept { U t; t.f = arg; return t.i; }
};
template<> struct hash<double> {
union U { double f; uint64_t i; };
- size_t operator() (double arg) const { U t; t.f = arg; return t.i; }
+ size_t operator() (double arg) const noexcept { U t; t.f = arg; return t.i; }
};
template<typename T> struct hash<T *> {
- size_t operator() (const T * arg) const { return size_t(arg); }
+ size_t operator() (const T * arg) const noexcept { return size_t(arg); }
};
template<typename T> struct hash<const T *> {
- size_t operator() (const T * arg) const { return size_t(arg); }
+ size_t operator() (const T * arg) const noexcept { return size_t(arg); }
};
// reuse old string hash function
-size_t hashValue(const char *str);
-size_t hashValue(const void *str, size_t sz);
+size_t hashValue(const char *str) noexcept;
+size_t hashValue(const void *str, size_t sz) noexcept;
struct hash_strings {
- size_t operator() (const vespalib::string & arg) const { return hashValue(arg.c_str()); }
- size_t operator() (vespalib::stringref arg) const { return hashValue(arg.data(), arg.size()); }
- size_t operator() (const char * arg) const { return hashValue(arg); }
- size_t operator() (const std::string& arg) const { return hashValue(arg.c_str()); }
+ size_t operator() (const vespalib::string & arg) const noexcept { return hashValue(arg.c_str()); }
+ size_t operator() (vespalib::stringref arg) const noexcept { return hashValue(arg.data(), arg.size()); }
+ size_t operator() (const char * arg) const noexcept { return hashValue(arg); }
+ size_t operator() (const std::string& arg) const noexcept { return hashValue(arg.c_str()); }
};
template<> struct hash<const char *> : hash_strings { };
@@ -81,11 +81,11 @@ template<> struct hash<vespalib::string> : hash_strings {};
template<> struct hash<std::string> : hash_strings {};
template<typename V> struct size {
- size_t operator() (const V & arg) const { return arg.size(); }
+ size_t operator() (const V & arg) const noexcept { return arg.size(); }
};
template<typename V> struct zero {
- size_t operator() (const V & ) const { return 0; }
+ size_t operator() (const V & ) const noexcept { return 0; }
};
} // namespace vespalib
diff --git a/vespalib/src/vespa/vespalib/stllike/string.h b/vespalib/src/vespa/vespalib/stllike/string.h
index 7d4ed06c411..f1207c1d9b8 100644
--- a/vespalib/src/vespa/vespalib/stllike/string.h
+++ b/vespalib/src/vespa/vespalib/stllike/string.h
@@ -180,7 +180,7 @@ public:
small_string(const char * s) noexcept : _buf(_stack), _sz(s ? strlen(s) : 0) { init(s); }
small_string(const void * s, size_type sz) noexcept : _buf(_stack), _sz(sz) { init(s); }
small_string(stringref s) noexcept : _buf(_stack), _sz(s.size()) { init(s.data()); }
- small_string(const std::string & s) : _buf(_stack), _sz(s.size()) { init(s.data()); }
+ small_string(const std::string & s) noexcept : _buf(_stack), _sz(s.size()) { init(s.data()); }
small_string(small_string && rhs) noexcept
: _sz(rhs.size()), _bufferSize(rhs._bufferSize)
{
diff --git a/vespalib/src/vespa/vespalib/testkit/test_hook.h b/vespalib/src/vespa/vespalib/testkit/test_hook.h
index 28419c0b31b..706a1c9f741 100644
--- a/vespalib/src/vespa/vespalib/testkit/test_hook.h
+++ b/vespalib/src/vespa/vespalib/testkit/test_hook.h
@@ -6,6 +6,7 @@
#include <vespa/vespalib/util/barrier.h>
#include <string>
#include <vector>
+#include <cassert>
#include "test_master.h"
namespace vespalib {
diff --git a/vespalib/src/vespa/vespalib/testkit/test_master.cpp b/vespalib/src/vespa/vespalib/testkit/test_master.cpp
index 789d40d478d..60e51ac3a91 100644
--- a/vespalib/src/vespa/vespalib/testkit/test_master.cpp
+++ b/vespalib/src/vespa/vespalib/testkit/test_master.cpp
@@ -3,6 +3,7 @@
#include "test_master.h"
#include <vespa/vespalib/util/barrier.h>
#include <cstring>
+#include <cassert>
#include <vespa/log/log.h>
LOG_SETUP(".vespalib.testkit.test_master");
@@ -33,10 +34,10 @@ __thread TestMaster::ThreadState *TestMaster::_threadState = 0;
//-----------------------------------------------------------------------------
-TestMaster::TraceItem::~TraceItem() { }
+TestMaster::TraceItem::~TraceItem() = default;
TestMaster::ThreadState &
-TestMaster::threadState(const vespalib::LockGuard &)
+TestMaster::threadState(const lock_guard &)
{
if (_threadState == 0) {
std::ostringstream threadName;
@@ -54,7 +55,7 @@ TestMaster::threadState()
return *_threadState;
}
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
return threadState(guard);
}
}
@@ -62,7 +63,7 @@ TestMaster::threadState()
//-----------------------------------------------------------------------------
void
-TestMaster::checkFailed(const vespalib::LockGuard &guard,
+TestMaster::checkFailed(const lock_guard &guard,
const char *file, uint32_t line, const char *str)
{
ThreadState &thread = threadState(guard);
@@ -80,7 +81,7 @@ TestMaster::checkFailed(const vespalib::LockGuard &guard,
}
void
-TestMaster::printDiff(const vespalib::LockGuard &guard,
+TestMaster::printDiff(const lock_guard &guard,
const std::string &text, const std::string &file, uint32_t line,
const std::string &lhs, const std::string &rhs)
{
@@ -105,7 +106,7 @@ TestMaster::printDiff(const vespalib::LockGuard &guard,
}
void
-TestMaster::handleFailure(const vespalib::LockGuard &guard, bool fatal)
+TestMaster::handleFailure(const lock_guard &guard, bool fatal)
{
ThreadState &thread = threadState(guard);
if (fatal) {
@@ -119,7 +120,7 @@ TestMaster::handleFailure(const vespalib::LockGuard &guard, bool fatal)
}
void
-TestMaster::closeDebugFiles(const vespalib::LockGuard &)
+TestMaster::closeDebugFiles(const lock_guard &)
{
if (_state.lhsFile != NULL) {
fclose(_state.lhsFile);
@@ -132,7 +133,7 @@ TestMaster::closeDebugFiles(const vespalib::LockGuard &)
}
void
-TestMaster::importThreads(const vespalib::LockGuard &)
+TestMaster::importThreads(const lock_guard &)
{
size_t importCnt = 0;
for (size_t i = 0; i < _threadStorage.size(); ++i) {
@@ -148,7 +149,7 @@ TestMaster::importThreads(const vespalib::LockGuard &)
}
bool
-TestMaster::reportConclusion(const vespalib::LockGuard &)
+TestMaster::reportConclusion(const lock_guard &)
{
bool ok = (_state.failCnt == 0);
fprintf(stderr, "%s: info: summary --- %zu check(s) passed --- %zu check(s) failed\n",
@@ -174,7 +175,7 @@ TestMaster::TestMaster()
void
TestMaster::init(const char *name)
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
_name = skip_path(name);
fprintf(stderr, "%s: info: running test suite '%s'\n", _name.c_str(), _name.c_str());
}
@@ -182,7 +183,7 @@ TestMaster::init(const char *name)
std::string
TestMaster::getName()
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
return _name;
}
@@ -225,7 +226,7 @@ TestMaster::setThreadIgnore(bool ignore)
size_t revertCnt = (thread.failCnt - thread.preIgnoreFailCnt);
thread.failCnt = thread.preIgnoreFailCnt;
if (revertCnt > 0) {
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
assert(_state.failCnt >= revertCnt);
_state.failCnt -= revertCnt;
}
@@ -271,7 +272,7 @@ TestMaster::getThreadFailCnt()
TestMaster::Progress
TestMaster::getProgress()
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
return Progress(_state.passCnt, _state.failCnt);
}
@@ -279,7 +280,7 @@ void
TestMaster::openDebugFiles(const std::string &lhsFile,
const std::string &rhsFile)
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
closeDebugFiles(guard);
_state.lhsFile = fopen(lhsFile.c_str(), "w");
_state.rhsFile = fopen(rhsFile.c_str(), "w");
@@ -317,7 +318,7 @@ TestMaster::check(bool rc, const char *file, uint32_t line,
return true;
}
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
checkFailed(guard, file, line, str);
handleFailure(guard, fatal);
}
@@ -329,7 +330,7 @@ TestMaster::flush(const char *file, uint32_t line)
{
ThreadState &thread = threadState();
if (thread.passCnt > 0) {
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
_state.passCnt += thread.passCnt;
fprintf(stderr, "%s: info: flushed %zu passed check(s) from thread '%s' (%s:%d)\n",
_name.c_str(), thread.passCnt, thread.name.c_str(), skip_path(file), line);
@@ -348,7 +349,7 @@ TestMaster::trace(const char *file, uint32_t line)
bool
TestMaster::discardFailedChecks(size_t failCnt)
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
ThreadState &thread = threadState(guard);
if (failCnt == _state.failCnt) {
fprintf(stderr, "%s: info: discarding %zu failed check(s)\n", _name.c_str(), _state.failCnt);
@@ -366,7 +367,7 @@ TestMaster::discardFailedChecks(size_t failCnt)
bool
TestMaster::fini()
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
closeDebugFiles(guard);
importThreads(guard);
return reportConclusion(guard);
diff --git a/vespalib/src/vespa/vespalib/testkit/test_master.h b/vespalib/src/vespa/vespalib/testkit/test_master.h
index a9dc5ebb3a2..c20982b994d 100644
--- a/vespalib/src/vespa/vespalib/testkit/test_master.h
+++ b/vespalib/src/vespa/vespalib/testkit/test_master.h
@@ -2,10 +2,10 @@
#pragma once
-#include <vespa/vespalib/util/sync.h>
#include <string>
#include <vector>
#include <memory>
+#include <mutex>
namespace vespalib {
@@ -69,24 +69,25 @@ private:
};
private:
- vespalib::Lock _lock;
+ std::mutex _lock;
std::string _name;
std::string _path_prefix;
SharedState _state;
std::vector<std::unique_ptr<ThreadState> > _threadStorage;
+ using lock_guard = std::lock_guard<std::mutex>;
private:
- ThreadState &threadState(const vespalib::LockGuard &);
+ ThreadState &threadState(const lock_guard &);
ThreadState &threadState();
- void checkFailed(const vespalib::LockGuard &,
+ void checkFailed(const lock_guard &,
const char *file, uint32_t line, const char *str);
- void printDiff(const vespalib::LockGuard &,
+ void printDiff(const lock_guard &,
const std::string &text, const std::string &file, uint32_t line,
const std::string &lhs, const std::string &rhs);
- void handleFailure(const vespalib::LockGuard &, bool do_abort);
- void closeDebugFiles(const vespalib::LockGuard &);
- void importThreads(const vespalib::LockGuard &);
- bool reportConclusion(const vespalib::LockGuard &);
+ void handleFailure(const lock_guard &, bool do_abort);
+ void closeDebugFiles(const lock_guard &);
+ void importThreads(const lock_guard &);
+ bool reportConclusion(const lock_guard &);
private:
TestMaster();
diff --git a/vespalib/src/vespa/vespalib/testkit/test_master.hpp b/vespalib/src/vespa/vespalib/testkit/test_master.hpp
index f165458c9aa..245c128b788 100644
--- a/vespalib/src/vespa/vespalib/testkit/test_master.hpp
+++ b/vespalib/src/vespa/vespalib/testkit/test_master.hpp
@@ -33,7 +33,7 @@ TestMaster::compare(const char *file, uint32_t line,
lhs << a;
rhs << b;
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
checkFailed(guard, file, line, str.c_str());
printDiff(guard, str, file, line, lhs.str(), rhs.str());
handleFailure(guard, fatal);
diff --git a/vespalib/src/vespa/vespalib/util/CMakeLists.txt b/vespalib/src/vespa/vespalib/util/CMakeLists.txt
index 0973653861f..ea2189fc3a8 100644
--- a/vespalib/src/vespa/vespalib/util/CMakeLists.txt
+++ b/vespalib/src/vespa/vespalib/util/CMakeLists.txt
@@ -40,7 +40,6 @@ vespa_add_library(vespalib_vespalib_util OBJECT
reusable_set_pool.cpp
runnable.cpp
runnable_pair.cpp
- rwlock.cpp
sequence.cpp
sha1.cpp
sig_catch.cpp
@@ -50,6 +49,7 @@ vespa_add_library(vespalib_vespalib_util OBJECT
stash.cpp
string_hash.cpp
stringfmt.cpp
+ sync.cpp
thread.cpp
thread_bundle.cpp
threadstackexecutor.cpp
diff --git a/vespalib/src/vespa/vespalib/util/alloc.cpp b/vespalib/src/vespa/vespalib/util/alloc.cpp
index 29285932f63..745fb50db03 100644
--- a/vespalib/src/vespa/vespalib/util/alloc.cpp
+++ b/vespalib/src/vespa/vespalib/util/alloc.cpp
@@ -4,10 +4,11 @@
#include <vespa/vespalib/util/stringfmt.h>
#include <vespa/vespalib/util/exceptions.h>
#include <vespa/vespalib/util/backtrace.h>
-#include <vespa/vespalib/util/sync.h>
#include <map>
#include <atomic>
#include <unordered_map>
+#include <cassert>
+#include <mutex>
#include <vespa/fastos/file.h>
#include <unistd.h>
@@ -24,7 +25,7 @@ int _G_HugeFlags = 0;
const size_t _G_pageSize = getpagesize();
size_t _G_MMapLogLimit = std::numeric_limits<size_t>::max();
size_t _G_MMapNoCoreLimit = std::numeric_limits<size_t>::max();
-Lock _G_lock;
+std::mutex _G_lock;
std::atomic<size_t> _G_mmapCount(0);
size_t
@@ -361,7 +362,7 @@ MMapAllocator::salloc(size_t sz, void * wantedAddress)
}
#endif
if (sz >= _G_MMapLogLimit) {
- LockGuard guard(_G_lock);
+ std::lock_guard guard(_G_lock);
_G_HugeMappings[buf] = MMapInfo(mmapId, sz, stackTrace);
LOG(info, "%ld mappings of accumulated size %ld", _G_HugeMappings.size(), sum(_G_HugeMappings));
}
@@ -411,7 +412,7 @@ void MMapAllocator::sfree(PtrAndSize alloc)
retval = munmap(alloc.first, alloc.second);
assert(retval == 0);
if (alloc.second >= _G_MMapLogLimit) {
- LockGuard guard(_G_lock);
+ std::lock_guard guard(_G_lock);
MMapInfo info = _G_HugeMappings[alloc.first];
assert(alloc.second == info._sz);
_G_HugeMappings.erase(alloc.first);
@@ -510,13 +511,13 @@ Alloc::allocMMap(size_t sz)
}
Alloc
-Alloc::alloc()
+Alloc::alloc() noexcept
{
return Alloc(&AutoAllocator::getDefault());
}
Alloc
-Alloc::alloc(size_t sz, size_t mmapLimit, size_t alignment)
+Alloc::alloc(size_t sz, size_t mmapLimit, size_t alignment) noexcept
{
return Alloc(&AutoAllocator::getAllocator(mmapLimit, alignment), sz);
}
diff --git a/vespalib/src/vespa/vespalib/util/alloc.h b/vespalib/src/vespa/vespalib/util/alloc.h
index 449cdde5fc7..cf7135736e5 100644
--- a/vespalib/src/vespa/vespalib/util/alloc.h
+++ b/vespalib/src/vespa/vespalib/util/alloc.h
@@ -81,18 +81,18 @@ public:
}
return *this;
}
- Alloc() : _alloc(nullptr, 0), _allocator(nullptr) { }
+ Alloc() noexcept : _alloc(nullptr, 0), _allocator(nullptr) { }
~Alloc() {
if (_alloc.first != nullptr) {
_allocator->free(_alloc);
_alloc.first = nullptr;
}
}
- void swap(Alloc & rhs) {
+ void swap(Alloc & rhs) noexcept {
std::swap(_alloc, rhs._alloc);
std::swap(_allocator, rhs._allocator);
}
- Alloc create(size_t sz) const {
+ Alloc create(size_t sz) const noexcept {
return (sz == 0) ? Alloc(_allocator) : Alloc(_allocator, sz);
}
@@ -103,11 +103,11 @@ public:
* Optional alignment is assumed to be <= system page size, since mmap
* is always used when size is above limit.
*/
- static Alloc alloc(size_t sz, size_t mmapLimit = MemoryAllocator::HUGEPAGE_SIZE, size_t alignment=0);
- static Alloc alloc();
+ static Alloc alloc(size_t sz, size_t mmapLimit = MemoryAllocator::HUGEPAGE_SIZE, size_t alignment=0) noexcept;
+ static Alloc alloc() noexcept;
private:
- Alloc(const MemoryAllocator * allocator, size_t sz) : _alloc(allocator->alloc(sz)), _allocator(allocator) { }
- Alloc(const MemoryAllocator * allocator) : _alloc(nullptr, 0), _allocator(allocator) { }
+ Alloc(const MemoryAllocator * allocator, size_t sz) noexcept : _alloc(allocator->alloc(sz)), _allocator(allocator) { }
+ Alloc(const MemoryAllocator * allocator) noexcept : _alloc(nullptr, 0), _allocator(allocator) { }
void clear() {
_alloc.first = nullptr;
_alloc.second = 0;
diff --git a/vespalib/src/vespa/vespalib/util/arrayqueue.hpp b/vespalib/src/vespa/vespalib/util/arrayqueue.hpp
index 17a8c02dbf5..9af446e7a0f 100644
--- a/vespalib/src/vespa/vespalib/util/arrayqueue.hpp
+++ b/vespalib/src/vespa/vespalib/util/arrayqueue.hpp
@@ -101,15 +101,16 @@ public:
/**
* Create an empty queue with an initial capacity of 0.
**/
- ArrayQueue() : _data(0), _capacity(0), _used(0), _skew(0) {}
+ ArrayQueue() noexcept : _data(0), _capacity(0), _used(0), _skew(0) {}
/**
* Create an empty queue with the given initial capacity.
*
* @param cap initial capacity
**/
- explicit ArrayQueue(uint32_t cap) : _data((T*)malloc(sizeof(T) * cap)),
- _capacity(cap), _used(0), _skew(0) {}
+ explicit ArrayQueue(uint32_t cap) noexcept
+ : _data((T*)malloc(sizeof(T) * cap)), _capacity(cap), _used(0), _skew(0)
+ {}
/**
* Create a queue that is a copy of another queue. Now with funky
@@ -119,8 +120,8 @@ public:
* @param q the queue that should be copied
**/
ArrayQueue(typename std::conditional<is_copyable<T>::value, void_tag, const ArrayQueue &>::type q) = delete;
- ArrayQueue(typename std::conditional<is_copyable<T>::value, const ArrayQueue &, void_tag>::type q) : _data((T*)malloc(sizeof(T) * q._capacity)),
- _capacity(q._capacity), _used(0), _skew(0)
+ ArrayQueue(typename std::conditional<is_copyable<T>::value, const ArrayQueue &, void_tag>::type q)
+ : _data((T*)malloc(sizeof(T) * q._capacity)), _capacity(q._capacity), _used(0), _skew(0)
{
try {
q.copyInto(*this);
@@ -136,7 +137,7 @@ public:
*
* @param q the queue that should be moved
**/
- ArrayQueue(ArrayQueue &&q) : _data(0), _capacity(0), _used(0), _skew(0)
+ ArrayQueue(ArrayQueue &&q) noexcept : _data(0), _capacity(0), _used(0), _skew(0)
{
swap(q);
}
@@ -358,7 +359,7 @@ public:
*
* @param q the queue we want to swap state with
**/
- void swap(ArrayQueue<T> &q) {
+ void swap(ArrayQueue<T> &q) noexcept {
std::swap(_data, q._data);
std::swap(_capacity, q._capacity);
std::swap(_used, q._used);
diff --git a/vespalib/src/vespa/vespalib/util/child_process.cpp b/vespalib/src/vespa/vespalib/util/child_process.cpp
index ce0c2eb1779..b804d4ca87c 100644
--- a/vespalib/src/vespa/vespalib/util/child_process.cpp
+++ b/vespalib/src/vespa/vespalib/util/child_process.cpp
@@ -56,9 +56,6 @@ public:
} // namespace child_process
-using child_process::Timer;
-
-//-----------------------------------------------------------------------------
void
ChildProcess::Reader::OnReceiveData(const void *data, size_t length)
@@ -88,7 +85,7 @@ ChildProcess::Reader::hasData()
bool
-ChildProcess::Reader::waitForData(Timer &timer, MonitorGuard &lock)
+ChildProcess::Reader::waitForData(child_process::Timer &timer, MonitorGuard &lock)
{
// NB: caller has lock on _cond
CounterGuard count(_waitCnt);
@@ -131,7 +128,7 @@ ChildProcess::Reader::read(char *buf, uint32_t len, int msTimeout)
if (eof()) {
return 0;
}
- Timer timer(msTimeout);
+ child_process::Timer timer(msTimeout);
MonitorGuard lock(_cond);
waitForData(timer, lock);
uint32_t bytes = 0;
@@ -162,7 +159,7 @@ ChildProcess::Reader::readLine(std::string &line, int msTimeout)
if (eof()) {
return false;
}
- Timer timer(msTimeout);
+ child_process::Timer timer(msTimeout);
MonitorGuard lock(_cond);
while (waitForData(timer, lock)) {
while (hasData()) {
@@ -299,7 +296,7 @@ ChildProcess::run(const std::string &input, const char *cmd,
std::string &output, int msTimeout)
{
ChildProcess proc(cmd);
- Timer timer(msTimeout);
+ child_process::Timer timer(msTimeout);
char buf[4096];
proc.write(input.data(), input.length());
proc.close(); // close stdin
diff --git a/vespalib/src/vespa/vespalib/util/compressionconfig.h b/vespalib/src/vespa/vespalib/util/compressionconfig.h
index c0010e8e05c..88563c181a1 100644
--- a/vespalib/src/vespa/vespalib/util/compressionconfig.h
+++ b/vespalib/src/vespa/vespalib/util/compressionconfig.h
@@ -20,15 +20,15 @@ struct CompressionConfig {
ZSTD = 7
};
- CompressionConfig()
+ CompressionConfig() noexcept
: type(NONE), compressionLevel(0), threshold(90), minSize(0) {}
- CompressionConfig(Type t)
+ CompressionConfig(Type t) noexcept
: type(t), compressionLevel(9), threshold(90), minSize(0) {}
- CompressionConfig(Type t, uint8_t level, uint8_t minRes)
+ CompressionConfig(Type t, uint8_t level, uint8_t minRes) noexcept
: type(t), compressionLevel(level), threshold(minRes), minSize(0) {}
- CompressionConfig(Type t, uint8_t lvl, uint8_t minRes, size_t minSz)
+ CompressionConfig(Type t, uint8_t lvl, uint8_t minRes, size_t minSz) noexcept
: type(t), compressionLevel(lvl), threshold(minRes), minSize(minSz) {}
bool operator==(const CompressionConfig& o) const {
diff --git a/vespalib/src/vespa/vespalib/util/count_down_latch.h b/vespalib/src/vespa/vespalib/util/count_down_latch.h
index 66ef1e44cee..420be8f7ab2 100644
--- a/vespalib/src/vespa/vespalib/util/count_down_latch.h
+++ b/vespalib/src/vespa/vespalib/util/count_down_latch.h
@@ -37,7 +37,7 @@ public:
*
* @param cnt initial count
**/
- CountDownLatch(uint32_t cnt) : _lock(), _cond(), _count(cnt) {}
+ CountDownLatch(uint32_t cnt) noexcept : _lock(), _cond(), _count(cnt) {}
/**
* Count down this latch. When the count reaches 0, all threads
diff --git a/vespalib/src/vespa/vespalib/util/delegatelist.hpp b/vespalib/src/vespa/vespalib/util/delegatelist.hpp
deleted file mode 100644
index 716474f66f7..00000000000
--- a/vespalib/src/vespa/vespalib/util/delegatelist.hpp
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#pragma once
-
-#include "eventbarrier.hpp"
-#include "sync.h"
-
-namespace vespalib {
-
-/**
- * Data structure for robust event multi-casting in a multi-threaded
- * environment. The state tracked by this class can be modeled as a
- * set of bald object pointers; the delegates. All interaction with
- * the delegates is done through a snapshot of the delegate list. The
- * list may be modified at any time. Modifications will not be visible
- * to already existing snapshots. A separate method may be used to
- * wait for the destruction of all currently active snapshots. This
- * synchronization will ensure visibility of any previous
- * modifications to the delegate list. State snapshotting is
- * implemented with reference counted immutable lists. Snapshot
- * waiting is implemented using event barriers.
- **/
-template <typename T>
-class DelegateList
-{
-private:
- /**
- * Simple class used to synchronize with the completion of an
- * event barrier by coupling barrier completion to a gate.
- **/
- struct Sync
- {
- Gate gate;
- Sync() : gate() {}
- void completeBarrier() { gate.countDown(); }
- };
-
- /**
- * Inner structure used when keeping track of a set of delegates.
- **/
- struct Node {
- uint32_t refcnt; // the number of incoming pointers to this node.
- T *delegate; // the delegate tracked by this node.
- Node *next; // the next node in this list.
- };
-
- Lock _lock; // lock protecting access to this object
- Node *_head; // head of current list of delegates
- EventBarrier<Sync> _barrier; // object used to resolve event barriers
- Node *_freeNodes; // a list of recyclable internal nodes
- int _activeNodes; // number of internal nodes currently in use
- ArrayQueue<T*> _stack; // explicit stack for cheap 'recursion'
-
- /**
- * Allocate a new node and initialize it with the given data
- * members. Nodes are recycled internally by this object to reduce
- * overhead.
- *
- * @return the new node
- * @param delegate the delegate for the new node
- * @param next the next pointer for the new node
- **/
- Node *allocNode(T *delegate, Node *next) {
- Node *node = _freeNodes;
- if (node != 0) {
- _freeNodes = node->next;
- } else {
- node = new Node();
- }
- node->refcnt = 1;
- node->delegate = delegate;
- node->next = next;
- ++_activeNodes;
- return node;
- }
-
- /**
- * Copy a list of nodes. This will increase the reference count of
- * the list.
- *
- * @return the copy of the list
- * @param list the list to copy
- **/
- Node *copyList(Node *list) {
- if (list != 0) {
- ++list->refcnt;
- }
- return list;
- }
-
- /**
- * Free a list of nodes. This will decrease the reference count of
- * the list. Any nodes no longer in use will be put back on the
- * internal free list.
- *
- * @return 0
- * @param list the list to free
- **/
- Node *freeList(Node *list) {
- while (list != 0 && --list->refcnt == 0) {
- Node *node = list;
- list = node->next;
- node->next = _freeNodes;
- _freeNodes = node;
- --_activeNodes;
- }
- return 0;
- }
-
- DelegateList(const DelegateList &);
- DelegateList &operator=(const DelegateList &);
-
-public:
- /**
- * A snapshot of a delegate list. The only way to access the
- * delegates kept by a delegate list is to create a snapshot of
- * it. The snapshot lets the user traverse the list of delegates,
- * accessing each of them in turn. The existence of a snapshot is
- * used by the delegate list to identify that someone is observing
- * the delegate list in a specific state. Snapshots should be
- * created on the stack in a scope as close as possible to the
- * code actually accessing the delegates. The delegate list itself
- * may not be destructed until all snapshots of that list have
- * been destructed.
- **/
- class Snapshot
- {
- private:
- DelegateList &_list; // the parent object
- Node *_head; // head of the snapshotted list
- Node *_node; // current position within snapshot
- uint32_t _token; // token used for barrier resolving
-
- Snapshot(const Snapshot &);
- Snapshot &operator=(const Snapshot &);
- public:
- /**
- * Create a snapshot of the given delegate list. The snapshots
- * current position will be set to the first delegate part of
- * the snapshot.
- *
- * @param list the delegate list we are snapshotting
- **/
- explicit Snapshot(DelegateList &list) : _list(list) {
- LockGuard guard(list._lock);
- _head = list.copyList(list._head);
- _node = _head;
- _token = list._barrier.startEvent();
- }
-
- /**
- * Destructing a snapshot will tell the delegate list that we
- * are no longer accessing the list in the state observed by
- * the snapshot.
- **/
- ~Snapshot() {
- LockGuard guard(_list._lock);
- _list.freeList(_head);
- _list._barrier.completeEvent(_token);
- }
-
- /**
- * Check whether the current delegate is valid. A snapshot
- * becomes invalid after the user has stepped through all
- * delegates part of the snapshot using the 'next' method.
- *
- * @return true if the current delegate is valid
- **/
- bool valid() const {
- return (_node != 0);
- }
-
- /**
- * Step to the next delegate. This method may only be called
- * if the 'valid' method returns true.
- **/
- void next() {
- _node = _node->next;
- }
-
- /**
- * Get the current delegate. This method may only be called if
- * the 'valid' method returns true.
- *
- * @return current delegate
- **/
- T *get() const {
- return _node->delegate;
- }
- };
-
- /**
- * Create an initially empty delegate list.
- **/
- DelegateList()
- : _lock(),
- _head(0),
- _barrier(),
- _freeNodes(0),
- _activeNodes(0),
- _stack()
- {
- }
-
- /**
- * The destructor will clean up internal memory usage. The
- * delegate list itself does not need to be empty when it is
- * deleted. However, there may be no active snapshots of it and
- * no-one may be waiting for snapshot destruction.
- **/
- ~DelegateList() {
- freeList(_head);
- assert(_barrier.countBarriers() == 0);
- assert(_barrier.countEvents() == 0);
- assert(_activeNodes == 0);
- while (_freeNodes != 0) {
- Node *node = _freeNodes;
- _freeNodes = node->next;
- delete node;
- }
- }
-
- /**
- * Add a delegate to this list. Adding a delegate that is already
- * in the list will have no effect.
- *
- * @return this object, for chaining
- * @param delegate the delegate to add
- **/
- DelegateList &add(T *delegate) {
- LockGuard guard(_lock);
- Node *node = _head;
- while (node != 0 && node->delegate != delegate) {
- node = node->next;
- }
- if (node == 0) {
- _head = allocNode(delegate, _head);
- }
- return *this;
- }
-
- /**
- * Remove a delegate from this list.
- *
- * @return this object, for chaining
- * @param delegate the delegate to remove
- **/
- DelegateList &remove(T *delegate) {
- LockGuard guard(_lock);
- _stack.clear();
- Node *node = _head;
- while (node != 0 && node->delegate != delegate) {
- _stack.push(node->delegate);
- node = node->next;
- }
- if (node != 0) { // delegate found in list
- node = copyList(node->next);
- while (!_stack.empty()) {
- try {
- node = allocNode(_stack.back(), node);
- } catch (...) {
- freeList(node);
- throw;
- }
- _stack.popBack();
- }
- freeList(_head);
- _head = node;
- }
- return *this;
- }
-
- /**
- * Remove all delegates currently in this list.
- *
- * @return this object, for chaining
- **/
- DelegateList &clear() {
- LockGuard guard(_lock);
- _head = freeList(_head);
- return *this;
- }
-
- /**
- * Wait for the destruction of all currently active snapshots of
- * this list. This method will block until all relevant snapshots
- * are destructed. The creation of new snapshots will not
- * interfere with the completion of this method. This method is
- * used to enforce visibility between threads; after this method
- * returns, any modifications performed on the list before this
- * method was invoked will be visible to all threads.
- *
- * @return this object, for chaining
- **/
- DelegateList &waitSnapshots() {
- Sync sync;
- {
- LockGuard guard(_lock);
- if (!_barrier.startBarrier(sync)) {
- return *this;
- }
- }
- sync.gate.await();
- return *this;
- }
-};
-
-} // namespace vespalib
-
diff --git a/vespalib/src/vespa/vespalib/util/gate.h b/vespalib/src/vespa/vespalib/util/gate.h
index 7d913a7a039..5505a3676df 100644
--- a/vespalib/src/vespa/vespalib/util/gate.h
+++ b/vespalib/src/vespa/vespalib/util/gate.h
@@ -16,7 +16,7 @@ public:
/**
* Sets the initial count to 1.
**/
- Gate() : CountDownLatch(1) {}
+ Gate() noexcept : CountDownLatch(1) {}
};
} // namespace vespalib
diff --git a/vespalib/src/vespa/vespalib/util/memory.h b/vespalib/src/vespa/vespalib/util/memory.h
index f1c7c7820f1..2e0d631725a 100644
--- a/vespalib/src/vespa/vespalib/util/memory.h
+++ b/vespalib/src/vespa/vespalib/util/memory.h
@@ -200,7 +200,7 @@ public:
* with default sz=0 you get an empty container
* @param sz the number of bytes to allocate
**/
- MallocPtr(const size_t sz=0) : _sz(sz), _p(_sz ? malloc(sz) : nullptr) {
+ MallocPtr(const size_t sz=0) noexcept : _sz(sz), _p(_sz ? malloc(sz) : nullptr) {
if (_p == nullptr) {
_sz = 0;
}
@@ -208,7 +208,7 @@ public:
/** @brief destructor doing free() if needed */
~MallocPtr() { cleanup(); }
- MallocPtr(MallocPtr && rhs) :
+ MallocPtr(MallocPtr && rhs) noexcept :
_sz(rhs.size()), _p(rhs._p)
{
rhs._sz = 0;
@@ -221,7 +221,7 @@ public:
* Does deep copy of contents (using memcpy).
* @param rhs container to copy
**/
- MallocPtr(const MallocPtr & rhs)
+ MallocPtr(const MallocPtr & rhs) noexcept
: _sz(rhs.size()), _p(_sz ? malloc(_sz) : nullptr)
{
if (_p == nullptr) {
@@ -238,14 +238,14 @@ public:
* works like destruct + copy construct.
* @param rhs container to copy
**/
- MallocPtr & operator = (const MallocPtr & rhs) {
+ MallocPtr & operator = (const MallocPtr & rhs) noexcept {
if (this != &rhs) {
MallocPtr tmp(rhs);
swap(tmp);
}
return *this;
}
- MallocPtr & operator = (MallocPtr && rhs) {
+ MallocPtr & operator = (MallocPtr && rhs) noexcept {
if (this != &rhs) {
cleanup();
_sz = rhs._sz;
@@ -261,7 +261,7 @@ public:
*
* does not copy anything, just swaps pointers.
**/
- void swap(MallocPtr & rhs) {
+ void swap(MallocPtr & rhs) noexcept {
std::swap(_sz, rhs._sz); std::swap(_p, rhs._p);
}
@@ -307,7 +307,7 @@ public:
}
}
private:
- void cleanup() {
+ void cleanup() noexcept {
if (_p) {
free(_p);
_p = nullptr;
@@ -350,7 +350,7 @@ public:
}
/** @brief move constructor, takes over ownership */
- CloneablePtr(std::unique_ptr<T> &&rhs)
+ CloneablePtr(std::unique_ptr<T> &&rhs) noexcept
: _p(rhs.release())
{
}
@@ -373,7 +373,7 @@ public:
}
/** @brief swap contents */
- void swap(CloneablePtr & rhs) { std::swap(_p, rhs._p); }
+ void swap(CloneablePtr & rhs) noexcept { std::swap(_p, rhs._p); }
/** @brief value access */
const T * get() const { return _p; }
diff --git a/vespalib/src/vespa/vespalib/util/ptrholder.h b/vespalib/src/vespa/vespalib/util/ptrholder.h
index 1c06e5c53e6..be528ba25db 100644
--- a/vespalib/src/vespa/vespalib/util/ptrholder.h
+++ b/vespalib/src/vespa/vespalib/util/ptrholder.h
@@ -4,7 +4,7 @@
#include <algorithm>
#include <memory>
-#include <vespa/vespalib/util/sync.h>
+#include <mutex>
namespace vespalib {
@@ -29,11 +29,11 @@ class PtrHolder
private:
std::shared_ptr<T> _current;
std::shared_ptr<T> _next;
- mutable Lock _lock;
-
- PtrHolder(const PtrHolder &);
- PtrHolder &operator=(const PtrHolder &);
+ mutable std::mutex _lock;
+ using LockGuard = std::lock_guard<std::mutex>;
public:
+ PtrHolder(const PtrHolder &) = delete;
+ PtrHolder &operator=(const PtrHolder &) = delete;
/**
* @brief Create an empty PtrHolder with both current and new
* pointers set to 0
@@ -53,14 +53,14 @@ public:
*
* @return true if the current value is set (not 0)
**/
- bool hasValue() const { return (_current.get() != nullptr); }
+ bool hasValue() const { return bool(_current); }
/**
* @brief Check if the new value is set (not 0)
*
* @return true if the new value is set (not 0)
**/
- bool hasNewValue() const { return (_next.get() != nullptr); }
+ bool hasNewValue() const { return bool(_next); }
/**
* @brief Set a new value
diff --git a/vespalib/src/vespa/vespalib/util/rwlock.cpp b/vespalib/src/vespa/vespalib/util/rwlock.cpp
deleted file mode 100644
index d1e155851cf..00000000000
--- a/vespalib/src/vespa/vespalib/util/rwlock.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include <vespa/vespalib/util/rwlock.h>
-
-namespace vespalib {
-
-void RWLock::lockRead() {
- MonitorGuard guard(_monitor);
- CounterGuard waitCnt(_waitingReaders);
- while (_givenLocks == -1 || _waitingWriters > 0) {
- guard.wait();
- }
- ++_givenLocks;
-}
-
-void RWLock::unlockRead() {
- MonitorGuard guard(_monitor);
- assert(_givenLocks > 0);
- if (--_givenLocks == 0 && _waitingWriters > 0) {
- guard.broadcast();
- }
-}
-
-void RWLock::lockWrite() {
- MonitorGuard guard(_monitor);
- CounterGuard waitCnt(_waitingWriters);
- while (_givenLocks != 0) {
- guard.wait();
- }
- _givenLocks = -1;
-}
-
-void RWLock::unlockWrite() {
- MonitorGuard guard(_monitor);
- assert(_givenLocks == -1);
- _givenLocks = 0;
- if (_waitingReaders > 0 || _waitingWriters > 0) {
- guard.broadcast();
- }
-}
-
-} // namespace vespalib
diff --git a/vespalib/src/vespa/vespalib/util/rwlock.h b/vespalib/src/vespa/vespalib/util/rwlock.h
deleted file mode 100644
index 9b1f9b93289..00000000000
--- a/vespalib/src/vespa/vespalib/util/rwlock.h
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#pragma once
-
-#include <vespa/vespalib/util/sync.h>
-#include <vespa/vespalib/util/guard.h>
-
-class RWLockTest;
-
-namespace vespalib {
-
-/**
- * @brief An RWLock is a reader/writer lock. It can either be held by
- * any number of readers or a single writer at any time.
- *
- * The RWLockReader and RWLockWriter classes are used to acquire and
- * release reader and writer locks respectively.
- *
- * Writer locks have priority above reader locks to prevent
- * starvation.
- **/
-class RWLock
-{
-private:
- friend class ::RWLockTest;
- friend class RWLockReader;
- friend class RWLockWriter;
-
- int _givenLocks;
- int _waitingReaders;
- int _waitingWriters;
- Monitor _monitor;
-
- void lockRead();
- void unlockRead();
- void lockWrite();
- void unlockWrite();
-public:
- /**
- * @brief Create a new RWLock
- **/
- RWLock()
- : _givenLocks(0),
- _waitingReaders(0),
- _waitingWriters(0),
- _monitor() {}
- /**
- * @brief Create a new RWLock, ignoring the right hand side.
- *
- * It makes no sense to copy the state of an RWLock, but we want
- * to allow copying objects that contain RWLock objects.
- *
- * @param rhs ignore this
- **/
- RWLock(const RWLock &rhs)
- : _givenLocks(0),
- _waitingReaders(0),
- _waitingWriters(0),
- _monitor() { (void) rhs;}
- /**
- * @brief Assignment operator ignoring the right hand side.
- *
- * It makes no sense to assign the state of one RWLock to another,
- * but we want to allow assigning objects that contain RWLock
- * objects.
- *
- * @param rhs ignore this
- **/
- RWLock &operator=(const RWLock &rhs) {
- (void) rhs;
- return *this;
- }
-
- /**
- * To get an instance of RWLockReader or RWLockWriter that isn't
- * associated with a specific RWLock at initialization, you may
- * construct them from this tag type.
- **/
- struct InitiallyUnlockedGuard {};
-};
-
-#ifndef IAM_DOXYGEN
-class RWLockReaderHandover
-{
-private:
- friend class RWLockReader;
- RWLock *_lock;
- RWLockReaderHandover(const RWLockReaderHandover &);
- RWLockReaderHandover &operator=(const RWLockReaderHandover &);
- RWLockReaderHandover(RWLock *m) : _lock(m) {}
-public:
-};
-
-class RWLockWriterHandover
-{
-private:
- friend class RWLockWriter;
- RWLock *_lock;
- RWLockWriterHandover(const RWLockWriterHandover &);
- RWLockWriterHandover &operator=(const RWLockWriterHandover &);
- RWLockWriterHandover(RWLock *m) : _lock(m) {}
-public:
-};
-#endif
-
-
-/**
- * @brief An RWLockReader holds a reader lock on an RWLock.
- *
- * The lock is acquired in the constructor and released in the
- * destructor.
- *
- * RWLockReader has destructive copy (like unique_ptr). Assigning from
- * or copying a RWLockReader has the semantic of transferring the lock
- * from one object to the other. Note that assigning from or copying
- * a RWLockReader that does not have a lock will result in an assert.
- **/
-class RWLockReader
-{
-private:
- RWLock * _lock;
- RWLock * stealLock() {
- RWLock * ret(_lock);
- assert(ret != NULL);
- _lock = NULL;
- return ret;
- }
- void cleanup() { if (_lock != NULL) { _lock->unlockRead(); } }
-public:
-
- /**
- * @brief Obtain reader lock.
- *
- * This will block until a reader lock can be acquired.
- *
- * @param lock the underlying RWLock object
- **/
- RWLockReader(RWLock &lock) : _lock(&lock) { _lock->lockRead(); }
-
- /**
- * @brief Construct initially unlocked guard.
- * @param tag (unused) marker argument
- **/
- RWLockReader(const RWLock::InitiallyUnlockedGuard &tag) : _lock(NULL) { (void)tag; }
-
- /**
- * @brief Steal the lock from the given RWLockReader
- *
- * @param rhs steal the lock from this one
- **/
- RWLockReader(RWLockReader &rhs) : _lock(rhs.stealLock()) {}
-
- /**
- * @brief Steal the lock from the given RWLockReader
- *
- * @param rhs steal the lock from this one
- **/
- RWLockReader &operator=(RWLockReader & rhs) {
- if (this != & rhs) {
- cleanup();
- _lock = rhs.stealLock();
- }
- return *this;
- }
-
- /**
- * @brief Release the lock obtained in the constructor
- **/
- ~RWLockReader() { cleanup(); }
-
-#ifndef IAM_DOXYGEN
- RWLockReader(const RWLockReaderHandover &rhs) : _lock(rhs._lock) {}
- operator RWLockReaderHandover() { return RWLockReaderHandover(stealLock()); }
-#endif
-};
-
-
-/**
- * @brief An RWLockWriter holds a writer lock on an RWLock.
- *
- * The lock is acquired in the constructor and released in the
- * destructor.
- *
- * RWLockWriter has destructive copy (like unique_ptr). Assigning from
- * or copying a RWLockWriter has the semantic of transferring the lock
- * from one object to the other, and assignment is similar. Note that
- * assigning from or copying a RWLockWriter that does not have a lock
- * will result in an assert.
- **/
-class RWLockWriter
-{
-private:
- RWLock * _lock;
- RWLock * stealLock() {
- RWLock * ret(_lock);
- assert(ret != NULL);
- _lock = NULL;
- return ret;
- }
- void cleanup() { if (_lock != NULL) { _lock->unlockWrite(); } }
-public:
-
- /**
- * @brief Obtain writer lock.
- *
- * This will block until a writer lock can be acquired.
- *
- * @param lock the underlying RWLock object
- **/
- RWLockWriter(RWLock &lock) : _lock(&lock) { _lock->lockWrite(); }
-
- /**
- * @brief Construct initially unlocked guard.
- * @param tag (unused) marker argument
- **/
- RWLockWriter(const RWLock::InitiallyUnlockedGuard &tag) : _lock(NULL) { (void)tag; }
-
- /**
- * @brief Steal the lock from the given RWLockWriter
- *
- * @param rhs steal the lock from this one
- **/
- RWLockWriter(RWLockWriter &rhs) : _lock(rhs.stealLock()) {}
-
- /**
- * @brief Steal the lock from the given RWLockWriter
- *
- * @param rhs steal the lock from this one
- **/
- RWLockWriter &operator=(RWLockWriter & rhs) {
- if (this != & rhs) {
- cleanup();
- _lock = rhs.stealLock();
- }
- return *this;
- }
-
- /**
- * @brief Release the lock obtained in the constructor
- **/
- ~RWLockWriter() { cleanup(); }
-
-#ifndef IAM_DOXYGEN
- RWLockWriter(const RWLockWriterHandover &rhs) : _lock(rhs._lock) {}
- operator RWLockWriterHandover() { return RWLockWriterHandover(stealLock()); }
-#endif
-};
-
-} // namespace vespalib
-
diff --git a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp
index 01979c25164..e0d78c5d1b7 100644
--- a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp
+++ b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp
@@ -2,6 +2,7 @@
#include "simple_thread_bundle.h"
#include "exceptions.h"
+#include <cassert>
using namespace vespalib::fixed_thread_bundle;
@@ -68,20 +69,20 @@ SimpleThreadBundle::UP
SimpleThreadBundle::Pool::obtain()
{
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
if (!_bundles.empty()) {
SimpleThreadBundle::UP ret(_bundles.back());
_bundles.pop_back();
return ret;
}
}
- return SimpleThreadBundle::UP(new SimpleThreadBundle(_bundleSize));
+ return std::make_unique<SimpleThreadBundle>(_bundleSize);
}
void
SimpleThreadBundle::Pool::release(SimpleThreadBundle::UP bundle)
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_bundles.push_back(bundle.get());
bundle.release();
}
diff --git a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h
index 4fa73c1112f..135fc2d7562 100644
--- a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h
+++ b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h
@@ -2,7 +2,6 @@
#pragma once
-#include "sync.h"
#include "count_down_latch.h"
#include "thread.h"
#include "runnable.h"
@@ -48,7 +47,7 @@ struct Signal {
bool valid;
size_t generation;
Monitor monitor;
- Signal() : valid(true), generation(0), monitor() {}
+ Signal() noexcept : valid(true), generation(0), monitor() {}
size_t wait(size_t &localGen) {
MonitorGuard guard(monitor);
while (localGen == generation) {
@@ -94,8 +93,8 @@ public:
class Pool
{
private:
- Lock _lock;
- size_t _bundleSize;
+ std::mutex _lock;
+ size_t _bundleSize;
std::vector<SimpleThreadBundle*> _bundles;
public:
diff --git a/vespalib/src/vespa/vespalib/util/sync.cpp b/vespalib/src/vespa/vespalib/util/sync.cpp
new file mode 100644
index 00000000000..1f7a5215c46
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/util/sync.cpp
@@ -0,0 +1,99 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "sync.h"
+#include <cassert>
+
+namespace vespalib {
+
+Monitor::Monitor() noexcept
+ : _mutex(std::make_unique<std::mutex>()),
+ _cond(std::make_unique<std::condition_variable>())
+{}
+Monitor::Monitor(Monitor &&rhs) noexcept = default;
+Monitor::~Monitor() = default;
+
+LockGuard::LockGuard() : _guard() {}
+
+LockGuard::LockGuard(LockGuard &&rhs) noexcept : _guard(std::move(rhs._guard)) { }
+LockGuard::LockGuard(const Monitor &lock) : _guard(*lock._mutex) { }
+
+LockGuard &
+LockGuard::operator=(LockGuard &&rhs) noexcept{
+ if (this != &rhs) {
+ _guard = std::move(rhs._guard);
+ }
+ return *this;
+}
+
+void
+LockGuard::unlock() {
+ if (_guard) {
+ _guard.unlock();
+ }
+}
+LockGuard::~LockGuard() = default;
+
+bool
+LockGuard::locks(const Monitor & lock) const {
+ return (_guard && _guard.mutex() == lock._mutex.get());
+}
+
+MonitorGuard::MonitorGuard() : _guard(), _cond(nullptr) {}
+MonitorGuard::MonitorGuard(MonitorGuard &&rhs) noexcept
+ : _guard(std::move(rhs._guard)),
+ _cond(rhs._cond)
+{
+ rhs._cond = nullptr;
+}
+MonitorGuard::MonitorGuard(const Monitor &monitor)
+ : _guard(*monitor._mutex),
+ _cond(monitor._cond.get())
+{ }
+
+MonitorGuard &
+MonitorGuard::operator=(MonitorGuard &&rhs) noexcept {
+ if (this != &rhs) {
+ _guard = std::move(rhs._guard);
+ _cond = rhs._cond;
+ rhs._cond = nullptr;
+ }
+ return *this;
+}
+
+void
+MonitorGuard::unlock() {
+ assert(_guard);
+ _guard.unlock();
+ _cond = nullptr;
+}
+void
+MonitorGuard::wait() {
+ _cond->wait(_guard);
+}
+bool
+MonitorGuard::wait(int msTimeout) {
+ return wait(std::chrono::milliseconds(msTimeout));
+}
+bool
+MonitorGuard::wait(std::chrono::nanoseconds timeout) {
+ return _cond->wait_for(_guard, timeout) == std::cv_status::no_timeout;
+}
+void
+MonitorGuard::signal() {
+ _cond->notify_one();
+}
+void
+MonitorGuard::broadcast() {
+ _cond->notify_all();
+}
+void
+MonitorGuard::unsafeSignalUnlock() {
+ _guard.unlock();
+ _cond->notify_one();
+ _cond = nullptr;
+}
+
+MonitorGuard::~MonitorGuard() = default;
+
+} // namespace vespalib
+
diff --git a/vespalib/src/vespa/vespalib/util/sync.h b/vespalib/src/vespa/vespalib/util/sync.h
index 8458bc19629..d66a53cf539 100644
--- a/vespalib/src/vespa/vespalib/util/sync.h
+++ b/vespalib/src/vespa/vespalib/util/sync.h
@@ -2,45 +2,13 @@
#pragma once
-#include <cassert>
+#include "time.h"
#include <mutex>
#include <condition_variable>
-#include <chrono>
namespace vespalib {
/**
- * @brief A Lock is a synchronization primitive used to ensure mutual
- * exclusion.
- *
- * Use a LockGuard to hold a lock inside a scope.
- *
- * It is possible to obtain a lock on a const Lock object.
- *
- * @see TryLock
- **/
-class Lock
-{
-protected:
- friend class LockGuard;
- friend class TryLock;
-
- mutable std::mutex _mutex;
-public:
- /**
- * @brief Create a new Lock.
- *
- * Creates a Lock that has mutex instrumentation disabled.
- **/
- Lock() : _mutex() {}
- Lock(const Lock &) : Lock() { }
- Lock(Lock &&) : Lock() { }
- Lock &operator=(const Lock &) { return *this; }
- Lock &operator=(Lock &&) { return *this; }
-};
-
-
-/**
* @brief A Monitor is a synchronization primitive used to protect
* data access and also facilitate signaling and waiting between
* threads.
@@ -52,133 +20,24 @@ public:
*
* @see TryLock
**/
-class Monitor : public Lock
+class Monitor
{
private:
friend class LockGuard;
friend class MonitorGuard;
friend class TryLock;
- mutable std::condition_variable _cond;
+ std::unique_ptr<std::mutex> _mutex;
+ std::unique_ptr<std::condition_variable> _cond;
public:
/**
* @brief Create a new Monitor.
*
* Creates a Monitor that has mutex instrumentation disabled.
**/
- Monitor() : Lock(), _cond() {}
- Monitor(const Monitor &) : Monitor() { }
- Monitor(Monitor &&) : Monitor() { }
- Monitor &operator=(const Monitor &) { return *this; }
- Monitor &operator=(Monitor &&) { return *this; }
-};
-
-
-/**
- * @brief A TryLock object is used to try to obtain the lock on a Lock
- * or a Monitor without blocking.
- *
- * A TryLock will typically fail to obatin the lock if someone else
- * already has it. In that case, the TryLock object has no further
- * use.
- *
- * If the TryLock managed to acquire the lock, it can be passed over
- * to a LockGuard or MonitorGuard object. If the lock is not passed
- * on, the TryLock object will release it when it goes out of scope.
- *
- * Note that passing the lock obtained from a Lock to a MonitorGuard
- * is illegal. Also note that if the TryLock fails to aquire the lock,
- * it cannot be passed on. Trying to do so will result in an assert.
- *
- * copy/assignment of a TryLock is illegal.
- *
- * <pre>
- * Example:
- *
- * Lock lock;
- * TryLock tl(lock);
- * if (tl.hasLock()) {
- * LockGuard guard(tl)
- * ... do stuff
- * } // the lock is released as 'guard' goes out of scope
- * </pre>
- **/
-class TryLock
-{
-private:
- friend class LockGuard;
- friend class MonitorGuard;
-
- std::unique_lock<std::mutex> _guard;
- std::condition_variable *_cond;
-
- TryLock(const TryLock &) = delete;
- TryLock &operator=(const TryLock &) = delete;
-
-public:
- /**
- * @brief Try to obtain the lock represented by the given Lock object
- *
- * @param lock the lock to obtain
- **/
- TryLock(const Lock &lock)
- : _guard(lock._mutex, std::try_to_lock),
- _cond(nullptr)
- {
- }
-
- /**
- * @brief Try to lock the given Monitor
- *
- * @param mon the monitor to lock
- **/
- TryLock(const Monitor &mon)
- : _guard(mon._mutex, std::try_to_lock),
- _cond(_guard ? &mon._cond : nullptr)
- {
- }
-
- TryLock(TryLock &&rhs)
- : _guard(std::move(rhs._guard)),
- _cond(rhs._cond)
- {
- rhs._cond = nullptr;
- }
-
- /**
- * @brief Release the lock held by this object, if any
- **/
- ~TryLock() = default;
-
- TryLock &operator=(TryLock &&rhs) {
- if (this != &rhs) {
- _guard = std::move(rhs._guard);
- _cond = rhs._cond;
- rhs._cond = nullptr;
- }
- return *this;
- }
-
- /**
- * @brief Check whether this object holds a lock
- *
- * @return true if this object holds a lock
- **/
- bool hasLock() { return static_cast<bool>(_guard); }
- /**
- * @brief Release the lock held by this object.
- *
- * No methods may be invoked after invoking unlock (except the
- * destructor). Note that this method should only be used if you
- * need to release the lock before the object is destructed, as
- * the destructor will release the lock.
- **/
- void unlock() {
- if (_guard) {
- _guard.unlock();
- _cond = nullptr;
- }
- }
+ Monitor() noexcept;
+ Monitor(Monitor && rhs) noexcept;
+ ~Monitor();
};
@@ -198,19 +57,20 @@ class LockGuard
{
private:
std::unique_lock<std::mutex> _guard;
- LockGuard &operator=(const LockGuard &) = delete;
public:
/**
* @brief A noop guard without any mutex.
**/
- LockGuard() : _guard() {}
+ LockGuard();
LockGuard(const LockGuard &rhs) = delete;
+ LockGuard &operator=(const LockGuard &) = delete;
+
/**
* @brief Steal the lock from the given LockGuard
*
* @param rhs steal the lock from this one
**/
- LockGuard(LockGuard &&rhs) : _guard(std::move(rhs._guard)) { }
+ LockGuard(LockGuard &&rhs) noexcept;
/**
* @brief Obtain the lock represented by the given Lock object.
*
@@ -218,28 +78,9 @@ public:
*
* @param lock take it
**/
- LockGuard(const Lock &lock) : _guard(lock._mutex) { }
-
- /**
- * @brief Create a LockGuard from a TryLock.
- *
- * The TryLock may have been created from either a Lock or a
- * Monitor, but it must have managed to acquire the lock. The lock
- * will be handed over from the TryLock to the new object.
- *
- * @param tlock take the lock from this one
- **/
- LockGuard(TryLock &&tlock) : _guard(std::move(tlock._guard))
- {
- tlock._cond = nullptr;
- }
+ LockGuard(const Monitor &lock);
- LockGuard &operator=(LockGuard &&rhs) {
- if (this != &rhs) {
- _guard = std::move(rhs._guard);
- }
- return *this;
- }
+ LockGuard &operator=(LockGuard &&rhs) noexcept;
/**
* @brief Release the lock held by this object.
@@ -249,24 +90,18 @@ public:
* need to release the lock before the object is destructed, as
* the destructor will release the lock.
**/
- void unlock() {
- if (_guard) {
- _guard.unlock();
- }
- }
+ void unlock();
/**
* @brief Release the lock held by this object if unlock has not
* been called.
**/
- ~LockGuard() = default;
+ ~LockGuard();
/**
* Allow code to match guard with lock. This allows functions to take a
* guard ref as input, ensuring that the caller have grabbed a lock.
*/
- bool locks(const Lock& lock) const {
- return (_guard && _guard.mutex() == &lock._mutex);
- }
+ bool locks(const Monitor& lock) const;
};
@@ -294,19 +129,14 @@ public:
/**
* @brief A noop guard without any condition.
**/
- MonitorGuard() : _guard(), _cond(nullptr) {}
+ MonitorGuard();
MonitorGuard(const MonitorGuard &rhs) = delete;
/**
* @brief Steal the lock from the given MonitorGuard
*
* @param rhs steal the lock from this one
**/
- MonitorGuard(MonitorGuard &&rhs)
- : _guard(std::move(rhs._guard)),
- _cond(rhs._cond)
- {
- rhs._cond = nullptr;
- }
+ MonitorGuard(MonitorGuard &&rhs) noexcept;
/**
* @brief Obtain the lock on the given Monitor object.
*
@@ -314,39 +144,9 @@ public:
*
* @param monitor take the lock on it
**/
- MonitorGuard(const Monitor &monitor)
- : _guard(monitor._mutex),
- _cond(&monitor._cond)
- {
- }
- /**
- * @brief Create a MonitorGuard from a TryLock.
- *
- * The TryLock must have been created from a Monitor, and it must
- * have managed to acquire the lock. The lock will be handed over
- * from the TryLock to the new object.
- *
- * @param tlock take the lock from this one
- **/
- MonitorGuard(TryLock &&tlock)
- : _guard(),
- _cond(nullptr)
- {
- if (tlock._guard && tlock._cond != nullptr) {
- _guard = std::move(tlock._guard);
- _cond = tlock._cond;
- tlock._cond = nullptr;
- }
- }
+ MonitorGuard(const Monitor &monitor);
- MonitorGuard &operator=(MonitorGuard &&rhs) {
- if (this != &rhs) {
- _guard = std::move(rhs._guard);
- _cond = rhs._cond;
- rhs._cond = nullptr;
- }
- return *this;
- }
+ MonitorGuard &operator=(MonitorGuard &&rhs) noexcept;
/**
@@ -357,17 +157,11 @@ public:
* need to release the lock before this object is destructed, as
* the destructor will release the lock.
**/
- void unlock() {
- assert(_guard);
- _guard.unlock();
- _cond = nullptr;
- }
+ void unlock();
/**
* @brief Wait for a signal on the underlying Monitor.
**/
- void wait() {
- _cond->wait(_guard);
- }
+ void wait();
/**
* @brief Wait for a signal on the underlying Monitor with the
* given timeout.
@@ -375,25 +169,17 @@ public:
* @param msTimeout timeout in milliseconds
* @return true if a signal was received, false if the wait timed out.
**/
- bool wait(int msTimeout) {
- return wait(std::chrono::milliseconds(msTimeout));
- }
- bool wait(std::chrono::nanoseconds timeout) {
- return _cond->wait_for(_guard, timeout) == std::cv_status::no_timeout;
- }
+ bool wait(int msTimeout);
+ bool wait(duration timeout);
/**
* @brief Send a signal to a single waiter on the underlying
* Monitor.
**/
- void signal() {
- _cond->notify_one();
- }
+ void signal();
/**
* @brief Send a signal to all waiters on the underlying Monitor.
**/
- void broadcast() {
- _cond->notify_all();
- }
+ void broadcast();
/**
* @brief Send a signal to a single waiter on the underlying
* Monitor, but unlock the monitor right before doing so.
@@ -402,24 +188,20 @@ public:
* synchronization to ensure that the underlying Monitor object
* will live long enough to be signaled.
**/
- void unsafeSignalUnlock() {
- _guard.unlock();
- _cond->notify_one();
- _cond = nullptr;
- }
+ void unsafeSignalUnlock();
/**
* @brief Release the lock held by this object if unlock has not
* been called.
**/
- ~MonitorGuard() = default;
+ ~MonitorGuard();
/**
* Allow code to match guard with lock. This allows functions to take a
* guard ref as input, ensuring that the caller have grabbed a lock.
*/
bool monitors(const Monitor& m) const {
- return (_cond != nullptr && _cond == &m._cond);
+ return (_cond != nullptr && _cond == m._cond.get());
}
};
diff --git a/vespalib/src/vespa/vespalib/util/thread.cpp b/vespalib/src/vespa/vespalib/util/thread.cpp
index 4eb436458a2..c595a76b8fe 100644
--- a/vespalib/src/vespa/vespalib/util/thread.cpp
+++ b/vespalib/src/vespa/vespalib/util/thread.cpp
@@ -2,6 +2,7 @@
#include "thread.h"
#include <thread>
+#include <cassert>
namespace vespalib {
diff --git a/vespalib/src/vespa/vespalib/util/zstdcompressor.cpp b/vespalib/src/vespa/vespalib/util/zstdcompressor.cpp
index 2f09abf4846..931f727ad6c 100644
--- a/vespalib/src/vespa/vespalib/util/zstdcompressor.cpp
+++ b/vespalib/src/vespa/vespalib/util/zstdcompressor.cpp
@@ -2,9 +2,7 @@
#include "zstdcompressor.h"
#include <vespa/vespalib/util/alloc.h>
-#include <vespa/vespalib/util/sync.h>
#include <zstd.h>
-#include <vector>
#include <cassert>
using vespalib::alloc::Alloc;
diff --git a/vsm/src/vespa/vsm/vsm/vsm-adapter.cpp b/vsm/src/vespa/vsm/vsm/vsm-adapter.cpp
index 8307954faae..db238279fa3 100644
--- a/vsm/src/vespa/vsm/vsm/vsm-adapter.cpp
+++ b/vsm/src/vespa/vsm/vsm/vsm-adapter.cpp
@@ -116,7 +116,7 @@ DocsumTools::obtainFieldNames(const FastS_VsmsummaryHandle &cfg)
void
VSMAdapter::configure(const VSMConfigSnapshot & snapshot)
{
- vespalib::LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
LOG(debug, "(re-)configure VSM (docsum tools)");
std::shared_ptr<SummaryConfig> summary(snapshot.getConfig<SummaryConfig>().release());
@@ -141,7 +141,7 @@ VSMAdapter::configure(const VSMConfigSnapshot & snapshot)
}
// init keyword extractor
- std::unique_ptr<KeywordExtractor> kwExtractor(new KeywordExtractor(NULL));
+ auto kwExtractor = std::make_unique<KeywordExtractor>(nullptr);
kwExtractor->AddLegalIndexSpec(_highlightindexes.c_str());
vespalib::string spec = kwExtractor->GetLegalIndexSpec();
LOG(debug, "index highlight spec: '%s'", spec.c_str());
diff --git a/vsm/src/vespa/vsm/vsm/vsm-adapter.h b/vsm/src/vespa/vsm/vsm/vsm-adapter.h
index 31e472713de..f6895dd71a6 100644
--- a/vsm/src/vespa/vsm/vsm/vsm-adapter.h
+++ b/vsm/src/vespa/vsm/vsm/vsm-adapter.h
@@ -127,7 +127,7 @@ private:
vespalib::PtrHolder<DocsumTools> _docsumTools;
std::unique_ptr<JuniperProperties> _juniperProps;
- vespalib::Lock _lock;
+ std::mutex _lock;
VSMAdapter(const VSMAdapter &);
VSMAdapter &operator=(const VSMAdapter &);
diff --git a/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/LockAttempt.java b/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/LockAttempt.java
index 1478b36d331..9cf490bf8c6 100644
--- a/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/LockAttempt.java
+++ b/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/LockAttempt.java
@@ -21,19 +21,21 @@ public class LockAttempt {
private final String lockPath;
private final Instant callAcquireInstant;
private final Duration timeout;
+ private final boolean reentry;
private final LockMetrics lockMetrics;
private final List<LockAttempt> nestedLockAttempts = new ArrayList<>();
private final LatencyStats.ActiveInterval activeAcquireInterval;
// Only accessed by mutating thread:
- private LatencyStats.ActiveInterval activeLockedInterval = null;
+ private Optional<LatencyStats.ActiveInterval> activeLockedInterval = Optional.empty();
private volatile Optional<Instant> lockAcquiredInstant = Optional.empty();
private volatile Optional<Instant> terminalStateInstant = Optional.empty();
private volatile Optional<String> stackTrace = Optional.empty();
public static LockAttempt invokingAcquire(ThreadLockStats threadLockStats, String lockPath,
- Duration timeout, LockMetrics lockMetrics) {
- return new LockAttempt(threadLockStats, lockPath, timeout, Instant.now(), lockMetrics);
+ Duration timeout, LockMetrics lockMetrics,
+ boolean reentry) {
+ return new LockAttempt(threadLockStats, lockPath, timeout, Instant.now(), lockMetrics, reentry);
}
public enum LockState {
@@ -50,13 +52,14 @@ public class LockAttempt {
private volatile LockState lockState = LockState.ACQUIRING;
private LockAttempt(ThreadLockStats threadLockStats, String lockPath, Duration timeout,
- Instant callAcquireInstant, LockMetrics lockMetrics) {
+ Instant callAcquireInstant, LockMetrics lockMetrics, boolean reentry) {
this.threadLockStats = threadLockStats;
this.lockPath = lockPath;
this.callAcquireInstant = callAcquireInstant;
this.timeout = timeout;
this.lockMetrics = lockMetrics;
- this.activeAcquireInterval = lockMetrics.acquireInvoked();
+ this.reentry = reentry;
+ this.activeAcquireInterval = lockMetrics.acquireInvoked(reentry);
}
public String getThreadName() { return threadLockStats.getThreadName(); }
@@ -101,22 +104,22 @@ public class LockAttempt {
void acquireFailed() {
setTerminalState(LockState.ACQUIRE_FAILED);
- lockMetrics.acquireFailed(activeAcquireInterval);
+ lockMetrics.acquireFailed(reentry, activeAcquireInterval);
}
void timedOut() {
setTerminalState(LockState.TIMED_OUT);
- lockMetrics.acquireTimedOut(activeAcquireInterval);
+ lockMetrics.acquireTimedOut(reentry, activeAcquireInterval);
}
void lockAcquired() {
lockState = LockState.ACQUIRED;
lockAcquiredInstant = Optional.of(Instant.now());
- activeLockedInterval = lockMetrics.lockAcquired(activeAcquireInterval);
+ activeLockedInterval = Optional.of(lockMetrics.lockAcquired(reentry, activeAcquireInterval));
}
void preRelease() {
- lockMetrics.preRelease(activeLockedInterval);
+ lockMetrics.preRelease(reentry, activeLockedInterval.orElseThrow());
}
void postRelease() {
@@ -125,7 +128,7 @@ public class LockAttempt {
void releaseFailed() {
setTerminalState(LockState.RELEASED_WITH_ERROR);
- lockMetrics.releaseFailed();
+ lockMetrics.releaseFailed(reentry);
}
void setTerminalState(LockState terminalState) { setTerminalState(terminalState, Instant.now()); }
diff --git a/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/LockMetrics.java b/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/LockMetrics.java
index 18ab70d42da..36758354171 100644
--- a/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/LockMetrics.java
+++ b/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/LockMetrics.java
@@ -17,6 +17,7 @@ public class LockMetrics {
private final AtomicInteger acquireSucceededCount = new AtomicInteger(0);
private final AtomicInteger releaseCount = new AtomicInteger(0);
private final AtomicInteger releaseFailedCount = new AtomicInteger(0);
+ private final AtomicInteger reentryCount = new AtomicInteger(0);
private final AtomicInteger cumulativeAcquireCount = new AtomicInteger(0);
private final AtomicInteger cumulativeAcquireFailedCount = new AtomicInteger(0);
@@ -24,43 +25,55 @@ public class LockMetrics {
private final AtomicInteger cumulativeAcquireSucceededCount = new AtomicInteger(0);
private final AtomicInteger cumulativeReleaseCount = new AtomicInteger(0);
private final AtomicInteger cumulativeReleaseFailedCount = new AtomicInteger(0);
+ private final AtomicInteger cumulativeReentryCount = new AtomicInteger(0);
private final LatencyStats acquireStats = new LatencyStats();
private final LatencyStats lockedStats = new LatencyStats();
/** Returns a Runnable that must be invoked when the acquire() finishes. */
- ActiveInterval acquireInvoked() {
+ ActiveInterval acquireInvoked(boolean reentry) {
+ if (reentry) {
+ reentryCount.incrementAndGet();
+ cumulativeReentryCount.incrementAndGet();
+ return () -> { };
+ }
+
acquireCount.incrementAndGet();
cumulativeAcquireCount.incrementAndGet();
return acquireStats.startNewInterval();
}
- void acquireFailed(ActiveInterval acquireInterval) {
+ void acquireFailed(boolean reentry, ActiveInterval acquireInterval) {
acquireInterval.close();
+ if (reentry) return;
acquireFailedCount.incrementAndGet();
cumulativeAcquireFailedCount.incrementAndGet();
}
- void acquireTimedOut(ActiveInterval acquireInterval) {
+ void acquireTimedOut(boolean reentry, ActiveInterval acquireInterval) {
acquireInterval.close();
+ if (reentry) return;
acquireTimedOutCount.incrementAndGet();
cumulativeAcquireTimedOutCount.incrementAndGet();
}
- ActiveInterval lockAcquired(ActiveInterval acquireInterval) {
+ ActiveInterval lockAcquired(boolean reentry, ActiveInterval acquireInterval) {
acquireInterval.close();
+ if (reentry) return () -> {};
acquireSucceededCount.incrementAndGet();
cumulativeAcquireSucceededCount.incrementAndGet();
return lockedStats.startNewInterval();
}
- void preRelease(ActiveInterval lockedInterval) {
+ void preRelease(boolean reentry, ActiveInterval lockedInterval) {
lockedInterval.close();
+ if (reentry) return;
releaseCount.incrementAndGet();
cumulativeReleaseCount.incrementAndGet();
}
- void releaseFailed() {
+ void releaseFailed(boolean reentry) {
+ if (reentry) return;
releaseFailedCount.incrementAndGet();
cumulativeReleaseFailedCount.incrementAndGet();
}
@@ -71,6 +84,7 @@ public class LockMetrics {
public int getAndResetAcquireSucceededCount() { return acquireSucceededCount.getAndSet(0); }
public int getAndResetReleaseCount() { return releaseCount.getAndSet(0); }
public int getAndResetReleaseFailedCount() { return releaseFailedCount.getAndSet(0); }
+ public int getAndResetReentryCount() { return reentryCount.getAndSet(0); }
public int getCumulativeAcquireCount() { return cumulativeAcquireCount.get(); }
public int getCumulativeAcquireFailedCount() { return cumulativeAcquireFailedCount.get(); }
@@ -78,6 +92,7 @@ public class LockMetrics {
public int getCumulativeAcquireSucceededCount() { return cumulativeAcquireSucceededCount.get(); }
public int getCumulativeReleaseCount() { return cumulativeReleaseCount.get(); }
public int getCumulativeReleaseFailedCount() { return cumulativeReleaseFailedCount.get(); }
+ public int getCumulativeReentryCount() { return cumulativeReentryCount.get(); }
public LatencyMetrics getAcquireLatencyMetrics() { return acquireStats.getLatencyMetrics(); }
public LatencyMetrics getLockedLatencyMetrics() { return lockedStats.getLatencyMetrics(); }
@@ -86,20 +101,22 @@ public class LockMetrics {
public LatencyMetrics getAndResetLockedLatencyMetrics() { return lockedStats.getLatencyMetricsAndStartNewPeriod(); }
// For tests
- void setAcquireCount(int count) { acquireCount.set(count); }
- void setAcquireFailedCount(int count) { acquireFailedCount.set(count); }
- void setAcquireTimedOutCount(int count) { acquireTimedOutCount.set(count); }
- void setAcquireSucceededCount(int count) { acquireSucceededCount.set(count); }
- void setReleaseCount(int count) { releaseCount.set(count); }
- void setReleaseFailedCount(int count) { releaseFailedCount.set(count); }
+ LockMetrics setAcquireCount(int count) { acquireCount.set(count); return this; }
+ LockMetrics setAcquireFailedCount(int count) { acquireFailedCount.set(count); return this; }
+ LockMetrics setAcquireTimedOutCount(int count) { acquireTimedOutCount.set(count); return this; }
+ LockMetrics setAcquireSucceededCount(int count) { acquireSucceededCount.set(count); return this; }
+ LockMetrics setReleaseCount(int count) { releaseCount.set(count); return this; }
+ LockMetrics setReleaseFailedCount(int count) { releaseFailedCount.set(count); return this; }
+ LockMetrics setReentryCount(int count) { reentryCount.set(count); return this; }
// For tests
- void setCumulativeAcquireCount(int count) { cumulativeAcquireCount.set(count); }
- void setCumulativeAcquireFailedCount(int count) { cumulativeAcquireFailedCount.set(count); }
- void setCumulativeAcquireTimedOutCount(int count) { cumulativeAcquireTimedOutCount.set(count); }
- void setCumulativeAcquireSucceededCount(int count) { cumulativeAcquireSucceededCount.set(count); }
- void setCumulativeReleaseCount(int count) { cumulativeReleaseCount.set(count); }
- void setCumulativeReleaseFailedCount(int count) { cumulativeReleaseFailedCount.set(count); }
+ LockMetrics setCumulativeAcquireCount(int count) { cumulativeAcquireCount.set(count); return this; }
+ LockMetrics setCumulativeAcquireFailedCount(int count) { cumulativeAcquireFailedCount.set(count); return this; }
+ LockMetrics setCumulativeAcquireTimedOutCount(int count) { cumulativeAcquireTimedOutCount.set(count); return this; }
+ LockMetrics setCumulativeAcquireSucceededCount(int count) { cumulativeAcquireSucceededCount.set(count); return this; }
+ LockMetrics setCumulativeReleaseCount(int count) { cumulativeReleaseCount.set(count); return this; }
+ LockMetrics setCumulativeReleaseFailedCount(int count) { cumulativeReleaseFailedCount.set(count); return this; }
+ LockMetrics setCumulativeReentryCount(int count) { cumulativeReentryCount.set(count); return this; }
@Override
public String toString() {
@@ -110,12 +127,14 @@ public class LockMetrics {
", acquireSucceededCount=" + acquireSucceededCount +
", releaseCount=" + releaseCount +
", releaseFailedCount=" + releaseFailedCount +
+ ", reentryCount=" + reentryCount +
", cumulativeAcquireCount=" + cumulativeAcquireCount +
", cumulativeAcquireFailedCount=" + cumulativeAcquireFailedCount +
", cumulativeAcquireTimedOutCount=" + cumulativeAcquireTimedOutCount +
", cumulativeAcquireSucceededCount=" + cumulativeAcquireSucceededCount +
", cumulativeReleaseCount=" + cumulativeReleaseCount +
", cumulativeReleaseFailedCount=" + cumulativeReleaseFailedCount +
+ ", cumulativeReentryCount=" + cumulativeReentryCount +
", acquireStats=" + acquireStats +
", lockedStats=" + lockedStats +
'}';
diff --git a/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockStats.java b/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockStats.java
index 964aa83c52f..393fac5e3db 100644
--- a/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockStats.java
+++ b/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockStats.java
@@ -64,7 +64,10 @@ public class ThreadLockStats {
/** Mutable method (see class doc) */
public void invokingAcquire(String lockPath, Duration timeout) {
- LockAttempt lockAttempt = LockAttempt.invokingAcquire(this, lockPath, timeout, getGlobalLockMetrics(lockPath));
+ boolean reentry = lockAttemptsStack.stream().anyMatch(lockAttempt -> lockAttempt.getLockPath().equals(lockPath));
+
+ LockAttempt lockAttempt = LockAttempt.invokingAcquire(this, lockPath, timeout,
+ getGlobalLockMetrics(lockPath), reentry);
LockAttempt lastLockAttempt = lockAttemptsStack.peekLast();
if (lastLockAttempt == null) {
diff --git a/zkfacade/src/test/java/com/yahoo/vespa/curator/stats/LockAttemptSamplesTest.java b/zkfacade/src/test/java/com/yahoo/vespa/curator/stats/LockAttemptSamplesTest.java
index 252a90f8bb4..e54e340deb5 100644
--- a/zkfacade/src/test/java/com/yahoo/vespa/curator/stats/LockAttemptSamplesTest.java
+++ b/zkfacade/src/test/java/com/yahoo/vespa/curator/stats/LockAttemptSamplesTest.java
@@ -54,7 +54,7 @@ public class LockAttemptSamplesTest {
private boolean maybeSample(String lockPath, int secondsDuration) {
LockAttempt lockAttempt = LockAttempt.invokingAcquire(threadLockStats, lockPath,
- Duration.ofSeconds(1), new LockMetrics());
+ Duration.ofSeconds(1), new LockMetrics(), false);
Instant instant = lockAttempt.getTimeAcquiredWasInvoked().plus(Duration.ofSeconds(secondsDuration));
lockAttempt.setTerminalState(LockAttempt.LockState.RELEASED, instant);
return samples.maybeSample(lockAttempt);
diff --git a/zkfacade/src/test/java/com/yahoo/vespa/curator/stats/LockTest.java b/zkfacade/src/test/java/com/yahoo/vespa/curator/stats/LockTest.java
index d673655c798..f440c2cfad8 100644
--- a/zkfacade/src/test/java/com/yahoo/vespa/curator/stats/LockTest.java
+++ b/zkfacade/src/test/java/com/yahoo/vespa/curator/stats/LockTest.java
@@ -26,8 +26,10 @@ import static org.mockito.Mockito.when;
public class LockTest {
private final InterProcessLock mutex = mock(InterProcessLock.class);
private final String lockPath = "/lock/path";
+ private final String lock2Path = "/lock2/path";
private final Duration acquireTimeout = Duration.ofSeconds(10);
private final Lock lock = new Lock(lockPath, mutex);
+ private final Lock lock2 = new Lock(lock2Path, mutex);
@Before
public void setUp() {
@@ -51,7 +53,7 @@ public class LockTest {
expectedMetrics.setCumulativeAcquireCount(1);
expectedMetrics.setAcquireFailedCount(1);
expectedMetrics.setCumulativeAcquireFailedCount(1);
- assertLockMetrics(expectedMetrics);
+ assertLockMetricsIs(expectedMetrics);
List<LockAttempt> slowLockAttempts = LockStats.getGlobal().getLockAttemptSamples();
assertEquals(1, slowLockAttempts.size());
@@ -69,8 +71,15 @@ public class LockTest {
assertEquals(0, threadLockStats.getOngoingLockAttempts().size());
}
- private void assertLockMetrics(LockMetrics expected) {
- LockMetrics actual = LockStats.getGlobal().getLockMetricsByPath().get(lockPath);
+ private void assertLock2MetricsIs(LockMetrics expected) {
+ assertLockMetrics(expected, LockStats.getGlobal().getLockMetricsByPath().get(lock2Path));
+ }
+
+ private void assertLockMetricsIs(LockMetrics expected) {
+ assertLockMetrics(expected, LockStats.getGlobal().getLockMetricsByPath().get(lockPath));
+ }
+
+ private void assertLockMetrics(LockMetrics expected, LockMetrics actual) {
assertNotNull(actual);
assertEquals(expected.getCumulativeAcquireCount(), actual.getCumulativeAcquireCount());
@@ -79,6 +88,7 @@ public class LockTest {
assertEquals(expected.getCumulativeAcquireSucceededCount(), actual.getCumulativeAcquireSucceededCount());
assertEquals(expected.getCumulativeReleaseCount(), actual.getCumulativeReleaseCount());
assertEquals(expected.getCumulativeReleaseFailedCount(), actual.getCumulativeReleaseFailedCount());
+ assertEquals(expected.getCumulativeReentryCount(), actual.getCumulativeReentryCount());
assertEquals(expected.getAndResetAcquireCount(), actual.getAndResetAcquireCount());
assertEquals(expected.getAndResetAcquireFailedCount(), actual.getAndResetAcquireFailedCount());
@@ -86,6 +96,7 @@ public class LockTest {
assertEquals(expected.getAndResetAcquireSucceededCount(), actual.getAndResetAcquireSucceededCount());
assertEquals(expected.getAndResetReleaseCount(), actual.getAndResetReleaseCount());
assertEquals(expected.getAndResetReleaseFailedCount(), actual.getAndResetReleaseFailedCount());
+ assertEquals(expected.getAndResetReentryCount(), actual.getAndResetReentryCount());
}
@Test
@@ -104,7 +115,7 @@ public class LockTest {
expectedMetrics.setCumulativeAcquireCount(1);
expectedMetrics.setAcquireTimedOutCount(1);
expectedMetrics.setCumulativeAcquireTimedOutCount(1);
- assertLockMetrics(expectedMetrics);
+ assertLockMetricsIs(expectedMetrics);
}
@Test
@@ -112,36 +123,53 @@ public class LockTest {
when(mutex.acquire(anyLong(), any())).thenReturn(true);
lock.acquire(acquireTimeout);
+ assertLockMetricsIs(new LockMetrics()
+ .setAcquireCount(1)
+ .setCumulativeAcquireCount(1)
+ .setAcquireSucceededCount(1)
+ .setCumulativeAcquireSucceededCount(1));
+
+ // reenter lock
+ {
+ // NB: non-cumulative counters are reset on fetch
+ lock.acquire(acquireTimeout);
+ assertLockMetricsIs(new LockMetrics()
+ .setReentryCount(1)
+ .setCumulativeAcquireCount(1)
+ .setCumulativeAcquireSucceededCount(1)
+ .setCumulativeReentryCount(1));
+
+ lock.close();
+ assertLockMetricsIs(new LockMetrics()
+ .setCumulativeAcquireCount(1)
+ .setCumulativeAcquireSucceededCount(1)
+ .setCumulativeReentryCount(1));
+ }
- var expectedMetrics = new LockMetrics();
- expectedMetrics.setAcquireCount(1);
- expectedMetrics.setCumulativeAcquireCount(1);
- expectedMetrics.setAcquireSucceededCount(1);
- expectedMetrics.setCumulativeAcquireSucceededCount(1);
- assertLockMetrics(expectedMetrics);
-
- // reenter
- // NB: non-cumulative counters are reset on fetch
- lock.acquire(acquireTimeout);
- expectedMetrics.setAcquireCount(1); // reset to 0 above, + 1
- expectedMetrics.setCumulativeAcquireCount(2);
- expectedMetrics.setAcquireSucceededCount(1); // reset to 0 above, +1
- expectedMetrics.setCumulativeAcquireSucceededCount(2);
- assertLockMetrics(expectedMetrics);
-
- // inner-most closes
- lock.close();
- expectedMetrics.setAcquireCount(0); // reset to 0 above
- expectedMetrics.setAcquireSucceededCount(0); // reset to 0 above
- expectedMetrics.setReleaseCount(1);
- expectedMetrics.setCumulativeReleaseCount(1);
- assertLockMetrics(expectedMetrics);
+ // nested lock2
+ {
+ lock2.acquire(acquireTimeout);
+ assertLock2MetricsIs(new LockMetrics()
+ .setAcquireCount(1)
+ .setCumulativeAcquireCount(1)
+ .setAcquireSucceededCount(1)
+ .setCumulativeAcquireSucceededCount(1));
+
+ lock2.close();
+ assertLock2MetricsIs(new LockMetrics()
+ .setReleaseCount(1)
+ .setCumulativeAcquireCount(1)
+ .setCumulativeAcquireSucceededCount(1)
+ .setCumulativeReleaseCount(1));
+ }
- // outer-most closes
lock.close();
- expectedMetrics.setReleaseCount(1); // reset to 0 above, +1
- expectedMetrics.setCumulativeReleaseCount(2);
- assertLockMetrics(expectedMetrics);
+ assertLockMetricsIs(new LockMetrics()
+ .setReleaseCount(1)
+ .setCumulativeAcquireCount(1)
+ .setCumulativeAcquireSucceededCount(1)
+ .setCumulativeReentryCount(1)
+ .setCumulativeReleaseCount(1));
}
@Test