diff options
author | Jon Marius Venstad <jonmv@users.noreply.github.com> | 2022-04-17 13:40:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-17 13:40:48 +0200 |
commit | ecc1d05760fedf9c49a24a949160aa7930838dcc (patch) | |
tree | 846847b018d480cbfd399921d447a9656b817629 | |
parent | e593f6bf57a63b71e0e078466104fc110a60d267 (diff) | |
parent | 5dd851d5c5fce2e95b236cd1f5385270077f0450 (diff) |
Merge branch 'master' into jonmv/no-more-serviceview/v1
24 files changed, 271 insertions, 149 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java index e98a5254e09..360968bacd5 100644 --- a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java +++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java @@ -107,7 +107,7 @@ public interface ModelContext { @ModelFeatureFlag(owners = {"hmusum"}) default boolean failDeploymentWithInvalidJvmOptions() { return false; } @ModelFeatureFlag(owners = {"arnej", "andreer"}) default List<String> ignoredHttpUserAgents() { return List.of(); } @ModelFeatureFlag(owners = {"bjorncs"}) default boolean enableServerOcspStapling() { return false; } - @ModelFeatureFlag(owners = {"vekterli"}) default String persistenceAsyncThrottling() { throw new UnsupportedOperationException("TODO specify default value"); } + @ModelFeatureFlag(owners = {"vekterli"}) default String persistenceAsyncThrottling() { return "DYNAMIC"; } @ModelFeatureFlag(owners = {"vekterli"}) default String mergeThrottlingPolicy() { throw new UnsupportedOperationException("TODO specify default value"); } @ModelFeatureFlag(owners = {"vekterli"}) default double persistenceThrottlingWsDecrementFactor() { throw new UnsupportedOperationException("TODO specify default value"); } @ModelFeatureFlag(owners = {"vekterli"}) default double persistenceThrottlingWsBackoff() { throw new UnsupportedOperationException("TODO specify default value"); } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java index cc0baf09c6b..97128d4c980 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java @@ -55,6 +55,9 @@ public interface ConfigServer { /** Returns a proxied response from a given path running on a given service and node */ ProxyResponse getServiceNodePage(DeploymentId deployment, String serviceName, DomainName node, Path subPath, Query query); + /** Returns health status for the services of an application */ + ProxyResponse getServiceNodes(DeploymentId deployment); + /** * Gets the Vespa logs of the given deployment. * diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java index b7874734e11..b5f03756777 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java @@ -115,6 +115,7 @@ enum PathGroup { "/application/v4/tenant/{tenant}/application/{application}/instance/{ignored}/environment/{environment}/region/{region}/clusters", "/application/v4/tenant/{tenant}/application/{application}/instance/{ignored}/environment/{environment}/region/{region}/content/{*}", "/application/v4/tenant/{tenant}/application/{application}/instance/{ignored}/environment/{environment}/region/{region}/logs", + "/application/v4/tenant/{tenant}/application/{application}/instance/{ignored}/environment/{environment}/region/{region}/orchestrator", "/application/v4/tenant/{tenant}/application/{application}/instance/{ignored}/environment/{environment}/region/{region}/suspended", "/application/v4/tenant/{tenant}/application/{application}/instance/{ignored}/environment/{environment}/region/{region}/service/{*}", "/application/v4/tenant/{tenant}/application/{application}/instance/{ignored}/environment/{environment}/region/{region}/access/support", diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/InstanceList.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/InstanceList.java index 030f7678b8c..6178bfbb89e 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/InstanceList.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/InstanceList.java @@ -72,8 +72,9 @@ public class InstanceList extends AbstractFilteringList<ApplicationId, InstanceL /** Returns the subset of instances which contain declared jobs */ public InstanceList withDeclaredJobs() { - return matching(id -> instances.get(id).jobSteps().values().stream() - .anyMatch(job -> job.isDeclared() && job.job().get().application().equals(id))); + return matching(id -> instances.get(id).application().revisions().last().isPresent() + && instances.get(id).jobSteps().values().stream() + .anyMatch(job -> job.isDeclared() && job.job().get().application().equals(id))); } /** Returns the subset of instances which have at least one deployment on a lower version than the given one, or which have no production deployments */ diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java index a2c5b8f4a9b..814e33f616b 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java @@ -182,6 +182,8 @@ public class DeploymentStatus { } private Map<JobId, List<Job>> jobsToRun(Map<InstanceName, Change> changes, boolean eagerTests) { + if (application.revisions().last().isEmpty()) return Map.of(); + Map<JobId, List<Job>> productionJobs = new LinkedHashMap<>(); changes.forEach((instance, change) -> productionJobs.putAll(productionJobs(instance, change, eagerTests))); Map<JobId, List<Job>> testJobs = testJobs(productionJobs); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java index 57c817e6cd5..d1c19476929 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java @@ -478,7 +478,7 @@ public class JobController { controller.clock().instant(), applicationPackage.metaDataZip()); - application = application.withProjectId(OptionalLong.of(projectId)); + application = application.withProjectId(projectId == -1 ? OptionalLong.empty() : OptionalLong.of(projectId)); application = application.withRevisions(revisions -> revisions.with(version.get())); application = withPrunedPackages(application); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/Upgrader.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/Upgrader.java index e412a5cc9f7..fa5afa3a216 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/Upgrader.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/Upgrader.java @@ -66,7 +66,9 @@ public class Upgrader extends ControllerMaintainer { /** Returns a list of all production application instances, except those which are pinned, which we should not manipulate here. */ private InstanceList instances(Version systemVersion) { - return InstanceList.from(controller().jobController().deploymentStatuses(ApplicationList.from(controller().applications().readable()), systemVersion)) + return InstanceList.from(controller().jobController().deploymentStatuses(ApplicationList.from(controller().applications().readable()) + .withProjectId(), + systemVersion)) .withDeclaredJobs() .shuffle(random) .byIncreasingDeployedVersion() diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java index a9d1386c032..f57bf75de40 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java @@ -269,6 +269,7 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler { if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/suspended")) return suspended(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), request); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/service/{service}/{host}/status/{*}")) return status(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), path.get("service"), path.get("host"), path.getRest(), request); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/service/{service}/{host}/state/v1/{*}")) return stateV1(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), path.get("service"), path.get("host"), path.getRest(), request); + if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/orchestrator")) return orchestrator(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region")); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/nodes")) return nodes(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region")); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/clusters")) return clusters(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region")); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/content/{*}")) return content(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), path.getRest(), request); @@ -796,9 +797,6 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler { } private HttpResponse devApplicationPackage(ApplicationId id, JobType type) { - if ( ! type.environment().isManuallyDeployed()) - throw new IllegalArgumentException("Only manually deployed zones have dev packages"); - ZoneId zone = type.zone(controller.system()); RevisionId revision = controller.jobController().last(id, type).get().versions().targetRevision(); byte[] applicationPackage = controller.applications().applicationStore().get(new DeploymentId(id, zone), revision); @@ -1786,6 +1784,11 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler { Query.empty().add(request.getJDiscRequest().parameters())); } + private HttpResponse orchestrator(String tenantName, String applicationName, String instanceName, String environment, String region) { + DeploymentId deploymentId = new DeploymentId(ApplicationId.from(tenantName, applicationName, instanceName), requireZone(environment, region)); + return controller.serviceRegistry().configServer().getServiceNodes(deploymentId); + } + private HttpResponse stateV1(String tenantName, String applicationName, String instanceName, String environment, String region, String serviceName, String host, HttpURL.Path rest, HttpRequest request) { DeploymentId deploymentId = new DeploymentId(ApplicationId.from(tenantName, applicationName, instanceName), requireZone(environment, region)); Query query = Query.empty().add(request.getJDiscRequest().parameters()); @@ -2697,7 +2700,8 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler { private HttpResponse submit(String tenant, String application, HttpRequest request) { Map<String, byte[]> dataParts = parseDataParts(request); Inspector submitOptions = SlimeUtils.jsonToSlime(dataParts.get(EnvironmentResource.SUBMIT_OPTIONS)).get(); - long projectId = Math.max(1, submitOptions.field("projectId").asLong()); // Absence of this means it's not a prod app :/ + long projectId = submitOptions.field("projectId").asLong(); // Absence of this means it's not a prod app :/ + projectId = projectId == 0 ? 1 : projectId; Optional<String> repository = optional("repository", submitOptions); Optional<String> branch = optional("branch", submitOptions); Optional<String> commit = optional("commit", submitOptions); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java index 6eb87a47779..644d60fbe72 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java @@ -71,6 +71,7 @@ import java.util.stream.Collectors; import static com.yahoo.config.provision.NodeResources.DiskSpeed.slow; import static com.yahoo.config.provision.NodeResources.StorageType.remote; +import static java.nio.charset.StandardCharsets.UTF_8; /** * @author mortent @@ -495,7 +496,12 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer @Override public ProxyResponse getServiceNodePage(DeploymentId deployment, String serviceName, DomainName node, Path subPath, Query query) { - return new ProxyResponse((subPath + " and " + query).getBytes(StandardCharsets.UTF_8), "text/html", 200); + return new ProxyResponse((subPath + " and " + query).getBytes(UTF_8), "text/html", 200); + } + + @Override + public ProxyResponse getServiceNodes(DeploymentId deployment) { + return new ProxyResponse("{\"json\":\"thank you very much\"}".getBytes(UTF_8), "application.json", 200); } @Override @@ -525,12 +531,12 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer @Override public InputStream getLogs(DeploymentId deployment, Map<String, String> queryParameters) { - return new ByteArrayInputStream(log.get().getBytes(StandardCharsets.UTF_8)); + return new ByteArrayInputStream(log.get().getBytes(UTF_8)); } @Override public ProxyResponse getApplicationPackageContent(DeploymentId deployment, Path path, URI requestUri) { - return new ProxyResponse(("{\"path\":\"/" + String.join("/", path.segments()) + "\"}").getBytes(StandardCharsets.UTF_8), "application/json", 200); + return new ProxyResponse(("{\"path\":\"/" + String.join("/", path.segments()) + "\"}").getBytes(UTF_8), "application/json", 200); } public void setLogStream(Supplier<String> log) { diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java index 483f9f26b19..992ef59d9a5 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java @@ -694,6 +694,17 @@ public class ApplicationApiTest extends ControllerContainerTest { .userIdentity(USER_ID), new File("suspended.json")); + + // GET service/state/v1 + tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/service/storagenode/host.com/state/v1/?foo=bar", GET) + .userIdentity(USER_ID), + new File("service")); + + // GET orchestrator + tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/orchestrator", GET) + .userIdentity(USER_ID), + "{\"json\":\"thank you very much\"}"); + // DELETE application with active deployments fails tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", DELETE) .userIdentity(USER_ID) diff --git a/dist/vespa.spec b/dist/vespa.spec index 71d976f64a3..104e78e9303 100644 --- a/dist/vespa.spec +++ b/dist/vespa.spec @@ -595,7 +595,7 @@ mvn --batch-mode -e -N io.takari:maven:wrapper -Dmaven=3.6.3 . make %{_smp_mflags} -VERSION=%{version} make -C client/go install-all +VERSION=%{version} CI=true make -C client/go install-all %endif %install diff --git a/searchcommon/src/vespa/searchcommon/attribute/i_multi_value_attribute.h b/searchcommon/src/vespa/searchcommon/attribute/i_multi_value_attribute.h index cf72b3cf643..3ed86a076b3 100644 --- a/searchcommon/src/vespa/searchcommon/attribute/i_multi_value_attribute.h +++ b/searchcommon/src/vespa/searchcommon/attribute/i_multi_value_attribute.h @@ -4,6 +4,8 @@ #include "i_multi_value_read_view.h" +namespace vespalib { class Stash; } + namespace search::attribute { /** @@ -11,6 +13,7 @@ namespace search::attribute { * * The type-safe down-cast functions only return a valid pointer when that particular type is supported. * Otherwise a nullptr is returned. + * The returned read view is owned by the supplied stash. */ class IMultiValueAttribute { public: @@ -29,22 +32,22 @@ public: virtual ~IMultiValueAttribute() {} - virtual const IArrayReadView<int8_t>* as_read_view(ArrayTag<int8_t>) const { return nullptr; } - virtual const IArrayReadView<int16_t>* as_read_view(ArrayTag<int16_t>) const { return nullptr; } - virtual const IArrayReadView<int32_t>* as_read_view(ArrayTag<int32_t>) const { return nullptr; } - virtual const IArrayReadView<int64_t>* as_read_view(ArrayTag<int64_t>) const { return nullptr; } - virtual const IArrayReadView<float>* as_read_view(ArrayTag<float>) const { return nullptr; } - virtual const IArrayReadView<double>* as_read_view(ArrayTag<double>) const { return nullptr; } - - virtual const IWeightedSetReadView<int8_t>* as_read_view(WeightedSetTag<int8_t>) const { return nullptr; } - virtual const IWeightedSetReadView<int16_t>* as_read_view(WeightedSetTag<int16_t>) const { return nullptr; } - virtual const IWeightedSetReadView<int32_t>* as_read_view(WeightedSetTag<int32_t>) const { return nullptr; } - virtual const IWeightedSetReadView<int64_t>* as_read_view(WeightedSetTag<int64_t>) const { return nullptr; } - virtual const IWeightedSetReadView<float>* as_read_view(WeightedSetTag<float>) const { return nullptr; } - virtual const IWeightedSetReadView<double>* as_read_view(WeightedSetTag<double>) const { return nullptr; } - - virtual const IArrayEnumReadView* as_read_view(ArrayEnumTag) const { return nullptr; } - virtual const IWeightedSetEnumReadView* as_read_view(WeightedSetEnumTag) const { return nullptr; } + virtual const IArrayReadView<int8_t>* make_read_view(ArrayTag<int8_t>, vespalib::Stash&) const { return nullptr; } + virtual const IArrayReadView<int16_t>* make_read_view(ArrayTag<int16_t>, vespalib::Stash&) const { return nullptr; } + virtual const IArrayReadView<int32_t>* make_read_view(ArrayTag<int32_t>, vespalib::Stash&) const { return nullptr; } + virtual const IArrayReadView<int64_t>* make_read_view(ArrayTag<int64_t>, vespalib::Stash&) const { return nullptr; } + virtual const IArrayReadView<float>* make_read_view(ArrayTag<float>, vespalib::Stash&) const { return nullptr; } + virtual const IArrayReadView<double>* make_read_view(ArrayTag<double>, vespalib::Stash&) const { return nullptr; } + + virtual const IWeightedSetReadView<int8_t>* make_read_view(WeightedSetTag<int8_t>, vespalib::Stash&) const { return nullptr; } + virtual const IWeightedSetReadView<int16_t>* make_read_view(WeightedSetTag<int16_t>, vespalib::Stash&) const { return nullptr; } + virtual const IWeightedSetReadView<int32_t>* make_read_view(WeightedSetTag<int32_t>, vespalib::Stash&) const { return nullptr; } + virtual const IWeightedSetReadView<int64_t>* make_read_view(WeightedSetTag<int64_t>, vespalib::Stash&) const { return nullptr; } + virtual const IWeightedSetReadView<float>* make_read_view(WeightedSetTag<float>, vespalib::Stash&) const { return nullptr; } + virtual const IWeightedSetReadView<double>* make_read_view(WeightedSetTag<double>, vespalib::Stash&) const { return nullptr; } + + virtual const IArrayEnumReadView* make_read_view(ArrayEnumTag, vespalib::Stash&) const { return nullptr; } + virtual const IWeightedSetEnumReadView* make_read_view(WeightedSetEnumTag, vespalib::Stash&) const { return nullptr; } }; } diff --git a/searchcommon/src/vespa/searchcommon/attribute/i_multi_value_read_view.h b/searchcommon/src/vespa/searchcommon/attribute/i_multi_value_read_view.h index b62efb2098f..8e5005eae8d 100644 --- a/searchcommon/src/vespa/searchcommon/attribute/i_multi_value_read_view.h +++ b/searchcommon/src/vespa/searchcommon/attribute/i_multi_value_read_view.h @@ -9,14 +9,14 @@ namespace search::attribute { /** - * Read view for the raw data stored in a multi-value attribute. - * @tparam MultiValueType The multi-value type of the raw data to access. + * Read view for the data stored in a multi-value attribute. + * @tparam MultiValueType The multi-value type of the data to access. */ template <typename MultiValueType> class IMultiValueReadView { public: virtual ~IMultiValueReadView() {} - virtual vespalib::ConstArrayRef<MultiValueType> get_raw_values(uint32_t docid) const = 0; + virtual vespalib::ConstArrayRef<MultiValueType> get_values(uint32_t docid) const = 0; }; /** diff --git a/searchlib/src/tests/attribute/extendattributes/CMakeLists.txt b/searchlib/src/tests/attribute/extendattributes/CMakeLists.txt index e989d317b9c..f733f3d0091 100644 --- a/searchlib/src/tests/attribute/extendattributes/CMakeLists.txt +++ b/searchlib/src/tests/attribute/extendattributes/CMakeLists.txt @@ -4,6 +4,6 @@ vespa_add_executable(searchlib_extendattribute_test_app TEST extendattribute.cpp DEPENDS searchlib + GTest::GTest ) -vespa_add_test(NAME searchlib_extendattribute_test_app COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/extendattribute_test.sh - DEPENDS searchlib_extendattribute_test_app) +vespa_add_test(NAME searchlib_extendattribute_test_app COMMAND searchlib_extendattribute_test_app) diff --git a/searchlib/src/tests/attribute/extendattributes/extendattribute.cpp b/searchlib/src/tests/attribute/extendattributes/extendattribute.cpp index 6707a7c6edf..35dd0351f34 100644 --- a/searchlib/src/tests/attribute/extendattributes/extendattribute.cpp +++ b/searchlib/src/tests/attribute/extendattributes/extendattribute.cpp @@ -1,58 +1,55 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/log/log.h> -LOG_SETUP("extendattribute_test"); -#include <vespa/vespalib/testkit/testapp.h> +#include <vespa/vespalib/gtest/gtest.h> #include <vespa/searchlib/attribute/extendableattributes.h> namespace search { -class ExtendAttributeTest : public vespalib::TestApp +class ExtendAttributeTest : public ::testing::Test { -private: +protected: + ExtendAttributeTest() = default; + ~ExtendAttributeTest() override = default; template <typename Attribute> void testExtendInteger(Attribute & attr); template <typename Attribute> void testExtendFloat(Attribute & attr); template <typename Attribute> void testExtendString(Attribute & attr); - -public: - int Main() override; }; template <typename Attribute> void ExtendAttributeTest::testExtendInteger(Attribute & attr) { uint32_t docId(0); - EXPECT_EQUAL(attr.getNumDocs(), 0u); + EXPECT_EQ(attr.getNumDocs(), 0u); attr.addDoc(docId); - EXPECT_EQUAL(docId, 0u); - EXPECT_EQUAL(attr.getNumDocs(), 1u); + EXPECT_EQ(docId, 0u); + EXPECT_EQ(attr.getNumDocs(), 1u); attr.add(1, 10); - EXPECT_EQUAL(attr.getInt(0), 1); + EXPECT_EQ(attr.getInt(0), 1); attr.add(2, 20); - EXPECT_EQUAL(attr.getInt(0), attr.hasMultiValue() ? 1 : 2); + EXPECT_EQ(attr.getInt(0), attr.hasMultiValue() ? 1 : 2); if (attr.hasMultiValue()) { AttributeVector::WeightedInt v[2]; - EXPECT_EQUAL((static_cast<AttributeVector &>(attr)).get(0, v, 2), 2u); - EXPECT_EQUAL(v[0].getValue(), 1); - EXPECT_EQUAL(v[1].getValue(), 2); + EXPECT_EQ((static_cast<AttributeVector &>(attr)).get(0, v, 2), 2u); + EXPECT_EQ(v[0].getValue(), 1); + EXPECT_EQ(v[1].getValue(), 2); if (attr.hasWeightedSetType()) { - EXPECT_EQUAL(v[0].getWeight(), 10); - EXPECT_EQUAL(v[1].getWeight(), 20); + EXPECT_EQ(v[0].getWeight(), 10); + EXPECT_EQ(v[1].getWeight(), 20); } } attr.addDoc(docId); - EXPECT_EQUAL(docId, 1u); - EXPECT_EQUAL(attr.getNumDocs(), 2u); + EXPECT_EQ(docId, 1u); + EXPECT_EQ(attr.getNumDocs(), 2u); attr.add(3, 30); - EXPECT_EQUAL(attr.getInt(1), 3); + EXPECT_EQ(attr.getInt(1), 3); if (attr.hasMultiValue()) { AttributeVector::WeightedInt v[1]; - EXPECT_EQUAL((static_cast<AttributeVector &>(attr)).get(1, v, 1), 1u); - EXPECT_EQUAL(v[0].getValue(), 3); + EXPECT_EQ((static_cast<AttributeVector &>(attr)).get(1, v, 1), 1u); + EXPECT_EQ(v[0].getValue(), 3); if (attr.hasWeightedSetType()) { - EXPECT_EQUAL(v[0].getWeight(), 30); + EXPECT_EQ(v[0].getWeight(), 30); } } } @@ -61,36 +58,36 @@ template <typename Attribute> void ExtendAttributeTest::testExtendFloat(Attribute & attr) { uint32_t docId(0); - EXPECT_EQUAL(attr.getNumDocs(), 0u); + EXPECT_EQ(attr.getNumDocs(), 0u); attr.addDoc(docId); - EXPECT_EQUAL(docId, 0u); - EXPECT_EQUAL(attr.getNumDocs(), 1u); + EXPECT_EQ(docId, 0u); + EXPECT_EQ(attr.getNumDocs(), 1u); attr.add(1.7, 10); - EXPECT_EQUAL(attr.getInt(0), 1); - EXPECT_EQUAL(attr.getFloat(0), 1.7); + EXPECT_EQ(attr.getInt(0), 1); + EXPECT_EQ(attr.getFloat(0), 1.7); attr.add(2.3, 20); - EXPECT_EQUAL(attr.getFloat(0), attr.hasMultiValue() ? 1.7 : 2.3); + EXPECT_EQ(attr.getFloat(0), attr.hasMultiValue() ? 1.7 : 2.3); if (attr.hasMultiValue()) { AttributeVector::WeightedFloat v[2]; - EXPECT_EQUAL((static_cast<AttributeVector &>(attr)).get(0, v, 2), 2u); - EXPECT_EQUAL(v[0].getValue(), 1.7); - EXPECT_EQUAL(v[1].getValue(), 2.3); + EXPECT_EQ((static_cast<AttributeVector &>(attr)).get(0, v, 2), 2u); + EXPECT_EQ(v[0].getValue(), 1.7); + EXPECT_EQ(v[1].getValue(), 2.3); if (attr.hasWeightedSetType()) { - EXPECT_EQUAL(v[0].getWeight(), 10); - EXPECT_EQUAL(v[1].getWeight(), 20); + EXPECT_EQ(v[0].getWeight(), 10); + EXPECT_EQ(v[1].getWeight(), 20); } } attr.addDoc(docId); - EXPECT_EQUAL(docId, 1u); - EXPECT_EQUAL(attr.getNumDocs(), 2u); + EXPECT_EQ(docId, 1u); + EXPECT_EQ(attr.getNumDocs(), 2u); attr.add(3.6, 30); - EXPECT_EQUAL(attr.getFloat(1), 3.6); + EXPECT_EQ(attr.getFloat(1), 3.6); if (attr.hasMultiValue()) { AttributeVector::WeightedFloat v[1]; - EXPECT_EQUAL((static_cast<AttributeVector &>(attr)).get(1, v, 1), 1u); - EXPECT_EQUAL(v[0].getValue(), 3.6); + EXPECT_EQ((static_cast<AttributeVector &>(attr)).get(1, v, 1), 1u); + EXPECT_EQ(v[0].getValue(), 3.6); if (attr.hasWeightedSetType()) { - EXPECT_EQUAL(v[0].getWeight(), 30); + EXPECT_EQ(v[0].getWeight(), 30); } } } @@ -99,77 +96,103 @@ template <typename Attribute> void ExtendAttributeTest::testExtendString(Attribute & attr) { uint32_t docId(0); - EXPECT_EQUAL(attr.getNumDocs(), 0u); + EXPECT_EQ(attr.getNumDocs(), 0u); attr.addDoc(docId); - EXPECT_EQUAL(docId, 0u); - EXPECT_EQUAL(attr.getNumDocs(), 1u); + EXPECT_EQ(docId, 0u); + EXPECT_EQ(attr.getNumDocs(), 1u); attr.add("1.7", 10); - EXPECT_EQUAL(std::string(attr.getString(0, NULL, 0)), "1.7"); + EXPECT_EQ(std::string(attr.getString(0, NULL, 0)), "1.7"); attr.add("2.3", 20); - EXPECT_EQUAL(std::string(attr.getString(0, NULL, 0)), attr.hasMultiValue() ? "1.7" : "2.3"); + EXPECT_EQ(std::string(attr.getString(0, NULL, 0)), attr.hasMultiValue() ? "1.7" : "2.3"); if (attr.hasMultiValue()) { AttributeVector::WeightedString v[2]; - EXPECT_EQUAL((static_cast<AttributeVector &>(attr)).get(0, v, 2), 2u); - EXPECT_EQUAL(v[0].getValue(), "1.7"); - EXPECT_EQUAL(v[1].getValue(), "2.3"); + EXPECT_EQ((static_cast<AttributeVector &>(attr)).get(0, v, 2), 2u); + EXPECT_EQ(v[0].getValue(), "1.7"); + EXPECT_EQ(v[1].getValue(), "2.3"); if (attr.hasWeightedSetType()) { - EXPECT_EQUAL(v[0].getWeight(), 10); - EXPECT_EQUAL(v[1].getWeight(), 20); + EXPECT_EQ(v[0].getWeight(), 10); + EXPECT_EQ(v[1].getWeight(), 20); } } attr.addDoc(docId); - EXPECT_EQUAL(docId, 1u); - EXPECT_EQUAL(attr.getNumDocs(), 2u); + EXPECT_EQ(docId, 1u); + EXPECT_EQ(attr.getNumDocs(), 2u); attr.add("3.6", 30); - EXPECT_EQUAL(std::string(attr.getString(1, NULL, 0)), "3.6"); + EXPECT_EQ(std::string(attr.getString(1, NULL, 0)), "3.6"); if (attr.hasMultiValue()) { AttributeVector::WeightedString v[1]; - EXPECT_EQUAL((static_cast<AttributeVector &>(attr)).get(1, v, 1), 1u); - EXPECT_EQUAL(v[0].getValue(), "3.6"); + EXPECT_EQ((static_cast<AttributeVector &>(attr)).get(1, v, 1), 1u); + EXPECT_EQ(v[0].getValue(), "3.6"); if (attr.hasWeightedSetType()) { - EXPECT_EQUAL(v[0].getWeight(), 30); + EXPECT_EQ(v[0].getWeight(), 30); } } } -int -ExtendAttributeTest::Main() -{ - TEST_INIT("extendattribute_test"); +TEST_F(ExtendAttributeTest, single_integer_ext_attribute) +{ SingleIntegerExtAttribute siattr("si1"); - MultiIntegerExtAttribute miattr("mi1"); - WeightedSetIntegerExtAttribute wsiattr("wsi1"); EXPECT_TRUE( ! siattr.hasMultiValue() ); - EXPECT_TRUE( miattr.hasMultiValue() ); - EXPECT_TRUE( wsiattr.hasWeightedSetType() ); testExtendInteger(siattr); +} + +TEST_F(ExtendAttributeTest, array_integer_ext_attribute) +{ + MultiIntegerExtAttribute miattr("mi1"); + EXPECT_TRUE( miattr.hasMultiValue() ); testExtendInteger(miattr); +} + +TEST_F(ExtendAttributeTest, weighted_set_integer_ext_attribute) +{ + WeightedSetIntegerExtAttribute wsiattr("wsi1"); + EXPECT_TRUE( wsiattr.hasWeightedSetType() ); testExtendInteger(wsiattr); +} +TEST_F(ExtendAttributeTest, single_float_ext_attribute) +{ SingleFloatExtAttribute sdattr("sd1"); - MultiFloatExtAttribute mdattr("md1"); - WeightedSetFloatExtAttribute wsdattr("wsd1"); EXPECT_TRUE( ! sdattr.hasMultiValue() ); - EXPECT_TRUE( mdattr.hasMultiValue() ); - EXPECT_TRUE( wsdattr.hasWeightedSetType() ); testExtendFloat(sdattr); +} + +TEST_F(ExtendAttributeTest, array_float_ext_attribute) +{ + MultiFloatExtAttribute mdattr("md1"); + EXPECT_TRUE( mdattr.hasMultiValue() ); testExtendFloat(mdattr); +} + +TEST_F(ExtendAttributeTest, weighted_set_float_ext_attribute) +{ + WeightedSetFloatExtAttribute wsdattr("wsd1"); + EXPECT_TRUE( wsdattr.hasWeightedSetType() ); testExtendFloat(wsdattr); +} +TEST_F(ExtendAttributeTest, single_string_ext_attribute) +{ SingleStringExtAttribute ssattr("ss1"); - MultiStringExtAttribute msattr("ms1"); - WeightedSetStringExtAttribute wssattr("wss1"); EXPECT_TRUE( ! ssattr.hasMultiValue() ); - EXPECT_TRUE( msattr.hasMultiValue() ); - EXPECT_TRUE( wssattr.hasWeightedSetType() ); testExtendString(ssattr); +} + +TEST_F(ExtendAttributeTest, array_string_ext_attribute) +{ + MultiStringExtAttribute msattr("ms1"); + EXPECT_TRUE( msattr.hasMultiValue() ); testExtendString(msattr); - testExtendString(wssattr); +} - TEST_DONE(); +TEST_F(ExtendAttributeTest, weighted_set_string_ext_attribute) +{ + WeightedSetStringExtAttribute wssattr("wss1"); + EXPECT_TRUE( wssattr.hasWeightedSetType() ); + testExtendString(wssattr); } } -TEST_APPHOOK(search::ExtendAttributeTest); +GTEST_MAIN_RUN_ALL_TESTS() diff --git a/searchlib/src/tests/attribute/extendattributes/extendattribute_test.sh b/searchlib/src/tests/attribute/extendattributes/extendattribute_test.sh deleted file mode 100755 index 250725ac052..00000000000 --- a/searchlib/src/tests/attribute/extendattributes/extendattribute_test.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -set -e -$VALGRIND ./searchlib_extendattribute_test_app -rm -rf *.dat diff --git a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt index 2e562b4a54f..79c68ba4fe3 100644 --- a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt @@ -94,6 +94,7 @@ vespa_add_library(searchlib_attribute OBJECT postinglisttraits.cpp postingstore.cpp predicate_attribute.cpp + raw_multi_value_read_view.cpp readerbase.cpp reference_attribute.cpp reference_attribute_saver.cpp diff --git a/searchlib/src/vespa/searchlib/attribute/multivalueattribute.h b/searchlib/src/vespa/searchlib/attribute/multivalueattribute.h index 9eb1a06d042..3844c0f9b02 100644 --- a/searchlib/src/vespa/searchlib/attribute/multivalueattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/multivalueattribute.h @@ -19,8 +19,7 @@ namespace search { */ template <typename B, typename M> class MultiValueAttribute : public B, - public attribute::IMultiValueAttribute, - public attribute::IMultiValueReadView<M> + public attribute::IMultiValueAttribute { protected: typedef typename B::DocId DocId; @@ -80,19 +79,10 @@ public: void onShrinkLidSpace() override ; void onAddDocs(DocId lidLimit) override; - const IMultiValueAttribute* as_multi_value_attribute() const override { - return this; - } + const IMultiValueAttribute* as_multi_value_attribute() const override; // Implements attribute::IMultiValueAttribute - const attribute::IMultiValueReadView<MultiValueType>* as_read_view(attribute::IMultiValueAttribute::Tag<MultiValueType>) const override { - return this; - } - - // Implements attribute::IMultiValueReadView - vespalib::ConstArrayRef<MultiValueType> get_raw_values(uint32_t docid) const override { - return this->_mvMapping.get(docid); - } + const attribute::IMultiValueReadView<MultiValueType>* make_read_view(attribute::IMultiValueAttribute::Tag<MultiValueType>, vespalib::Stash& stash) const override; }; } // namespace search diff --git a/searchlib/src/vespa/searchlib/attribute/multivalueattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multivalueattribute.hpp index 8cf86f66236..04194f662d9 100644 --- a/searchlib/src/vespa/searchlib/attribute/multivalueattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/multivalueattribute.hpp @@ -3,10 +3,12 @@ #pragma once #include "address_space_components.h" +#include "raw_multi_value_read_view.h" #include <vespa/searchlib/attribute/multivalueattribute.h> #include <vespa/vespalib/stllike/hash_map.h> #include <vespa/vespalib/stllike/hash_map.hpp> #include <vespa/vespalib/util/memory_allocator.h> +#include <vespa/vespalib/util/stash.h> namespace search { @@ -289,6 +291,19 @@ MultiValueAttribute<B, M>::onShrinkLidSpace() this->setNumDocs(committedDocIdLimit); } +template <typename B, typename M> +const attribute::IMultiValueAttribute* +MultiValueAttribute<B, M>::as_multi_value_attribute() const +{ + return this; +} + +template <typename B, typename M> +const attribute::IMultiValueReadView<M>* +MultiValueAttribute<B, M>::make_read_view(attribute::IMultiValueAttribute::Tag<MultiValueType>, vespalib::Stash& stash) const +{ + return &stash.create<attribute::RawMultiValueReadView<MultiValueType>>(this->_mvMapping.make_read_view(this->getCommittedDocIdLimit())); +} } // namespace search diff --git a/searchlib/src/vespa/searchlib/attribute/raw_multi_value_read_view.cpp b/searchlib/src/vespa/searchlib/attribute/raw_multi_value_read_view.cpp new file mode 100644 index 00000000000..66e7b7fec9b --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/raw_multi_value_read_view.cpp @@ -0,0 +1,41 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "raw_multi_value_read_view.h" + +namespace search::attribute { + +template <typename MultiValueType> +RawMultiValueReadView<MultiValueType>::RawMultiValueReadView(MultiValueMappingReadView<MultiValueType> mv_mapping_read_view) + : _mv_mapping_read_view(mv_mapping_read_view) +{ +} + +template <typename MultiValueType> +RawMultiValueReadView<MultiValueType>::~RawMultiValueReadView() = default; + +template <typename MultiValueType> +vespalib::ConstArrayRef<MultiValueType> +RawMultiValueReadView<MultiValueType>::get_values(uint32_t docid) const +{ + return _mv_mapping_read_view.get(docid); +} + +template class RawMultiValueReadView<int8_t>; +template class RawMultiValueReadView<int16_t>; +template class RawMultiValueReadView<int32_t>; +template class RawMultiValueReadView<int64_t>; +template class RawMultiValueReadView<float>; +template class RawMultiValueReadView<double>; +template class RawMultiValueReadView<vespalib::datastore::AtomicEntryRef>; + +using multivalue::WeightedValue; + +template class RawMultiValueReadView<WeightedValue<int8_t>>; +template class RawMultiValueReadView<WeightedValue<int16_t>>; +template class RawMultiValueReadView<WeightedValue<int32_t>>; +template class RawMultiValueReadView<WeightedValue<int64_t>>; +template class RawMultiValueReadView<WeightedValue<float>>; +template class RawMultiValueReadView<WeightedValue<double>>; +template class RawMultiValueReadView<WeightedValue<vespalib::datastore::AtomicEntryRef>>; + +} diff --git a/searchlib/src/vespa/searchlib/attribute/raw_multi_value_read_view.h b/searchlib/src/vespa/searchlib/attribute/raw_multi_value_read_view.h new file mode 100644 index 00000000000..dc243c2a24f --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/raw_multi_value_read_view.h @@ -0,0 +1,24 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include "multi_value_mapping_read_view.h" +#include <vespa/searchcommon/attribute/i_multi_value_read_view.h> + +namespace search::attribute { + +/** + * Read view for the raw data stored in a multi-value attribute. + * @tparam MultiValueType The multi-value type of the raw data to access. + */ +template <typename MultiValueType> +class RawMultiValueReadView : public IMultiValueReadView<MultiValueType> +{ + MultiValueMappingReadView<MultiValueType> _mv_mapping_read_view; +public: + RawMultiValueReadView(MultiValueMappingReadView<MultiValueType> mv_mapping_read_view); + ~RawMultiValueReadView() override; + vespalib::ConstArrayRef<MultiValueType> get_values(uint32_t docid) const override; +}; + +} diff --git a/searchlib/src/vespa/searchlib/features/attributefeature.cpp b/searchlib/src/vespa/searchlib/features/attributefeature.cpp index 47445e9e8ee..3b768633dd3 100644 --- a/searchlib/src/vespa/searchlib/features/attributefeature.cpp +++ b/searchlib/src/vespa/searchlib/features/attributefeature.cpp @@ -243,7 +243,7 @@ template <typename BaseType> void MultiAttributeExecutor<BaseType>::execute(uint32_t docId) { - auto values = _array_read_view->get_raw_values(docId); + auto values = _array_read_view->get_values(docId); auto o = outputs().get_bound(); o[0].as_number = __builtin_expect(_idx < values.size(), true) ? multivalue::get_value(values[_idx]) : 0; } @@ -341,10 +341,10 @@ struct MultiValueExecutorCreator { using ArrayReadView = attribute::IArrayReadView<typename T::BaseType>; using ExecType = MultiAttributeExecutor<typename T::BaseType>; MultiValueExecutorCreator() : _array_read_view(nullptr) {} - bool handle(const IAttributeVector *attribute) { + bool handle(vespalib::Stash &stash, const IAttributeVector *attribute) { auto multi_value_attribute = attribute->as_multi_value_attribute(); if (multi_value_attribute != nullptr) { - _array_read_view = multi_value_attribute->as_read_view(attribute::IMultiValueAttribute::Tag<typename T::BaseType>()); + _array_read_view = multi_value_attribute->make_read_view(attribute::IMultiValueAttribute::Tag<typename T::BaseType>(), stash); } return _array_read_view != nullptr; } @@ -422,19 +422,19 @@ createAttributeExecutor(uint32_t numOutputs, const IAttributeVector *attribute, } else if (attribute->isIntegerType()) { if (basicType == BasicType::INT32) { MultiValueExecutorCreator<IntegerAttributeTemplate<int32_t>> creator; - if (creator.handle(attribute)) return creator.create(stash, idx); + if (creator.handle(stash, attribute)) return creator.create(stash, idx); } else if (basicType == BasicType::INT64) { MultiValueExecutorCreator<IntegerAttributeTemplate<int64_t>> creator; - if (creator.handle(attribute)) return creator.create(stash, idx); + if (creator.handle(stash, attribute)) return creator.create(stash, idx); } return stash.create<AttributeExecutor<IntegerContent>>(attribute, idx); } else { // FLOAT if (basicType == BasicType::DOUBLE) { MultiValueExecutorCreator<FloatingPointAttributeTemplate<double>> creator; - if (creator.handle(attribute)) return creator.create(stash, idx); + if (creator.handle(stash, attribute)) return creator.create(stash, idx); } else { MultiValueExecutorCreator<FloatingPointAttributeTemplate<float>> creator; - if (creator.handle(attribute)) return creator.create(stash, idx); + if (creator.handle(stash, attribute)) return creator.create(stash, idx); } return stash.create<AttributeExecutor<FloatContent>>(attribute, idx); } diff --git a/searchlib/src/vespa/searchlib/features/dotproductfeature.cpp b/searchlib/src/vespa/searchlib/features/dotproductfeature.cpp index b279cf6ca08..8f75b6ecc7d 100644 --- a/searchlib/src/vespa/searchlib/features/dotproductfeature.cpp +++ b/searchlib/src/vespa/searchlib/features/dotproductfeature.cpp @@ -145,7 +145,7 @@ template <typename BaseType> vespalib::ConstArrayRef<typename DotProductByWeightedSetReadViewExecutor<BaseType>::AT> DotProductByWeightedSetReadViewExecutor<BaseType>::getAttributeValues(uint32_t docId) { - return _weighted_set_read_view->get_raw_values(docId); + return _weighted_set_read_view->get_values(docId); } namespace { @@ -190,7 +190,7 @@ DotProductExecutorByEnum::~DotProductExecutorByEnum() = default; void DotProductExecutorByEnum::execute(uint32_t docId) { feature_t val = 0; - auto values = _weighted_set_enum_read_view->get_raw_values(docId); + auto values = _weighted_set_enum_read_view->get_values(docId); for (size_t i = 0; i < values.size(); ++i) { auto itr = _queryVector.getDimMap().find(values[i].value_ref().load_relaxed().ref()); if (itr != _end) { @@ -210,7 +210,7 @@ public: {} void execute(uint32_t docId) override { - auto values = _weighted_set_enum_read_view->get_raw_values(docId); + auto values = _weighted_set_enum_read_view->get_values(docId); for (size_t i = 0; i < values.size(); ++i) { if (values[i].value_ref().load_relaxed().ref() == _key) { outputs().set_number(0, values[i].weight()*_value); @@ -236,7 +236,7 @@ public: {} void execute(uint32_t docId) override { - auto values = _weighted_set_read_view->get_raw_values(docId); + auto values = _weighted_set_read_view->get_values(docId); for (size_t i = 0; i < values.size(); ++i) { if (values[i].value() == _key) { outputs().set_number(0, values[i].weight() * _value); @@ -290,7 +290,7 @@ template <typename BaseType> vespalib::ConstArrayRef<BaseType> DotProductByArrayReadViewExecutor<BaseType>::getAttributeValues(uint32_t docId) { - return _array_read_view->get_raw_values(docId); + return _array_read_view->get_values(docId); } template <typename A> @@ -328,7 +328,7 @@ template <typename BaseType> vespalib::ConstArrayRef<BaseType> SparseDotProductByArrayReadViewExecutor<BaseType>::getAttributeValues(uint32_t docid) { - auto allValues = _array_read_view->get_raw_values(docid); + auto allValues = _array_read_view->get_values(docid); size_t i(0); for (; (i < _queryIndexes.size()) && (_queryIndexes[i] < allValues.size()); i++) { _scratch[i] = allValues[_queryIndexes[i]]; @@ -533,11 +533,11 @@ using dotproduct::ArrayParam; template <typename AT> const attribute::IMultiValueReadView<AT>* -get_multi_value_read_view(const IAttributeVector& attribute) +make_multi_value_read_view(const IAttributeVector& attribute, vespalib::Stash& stash) { auto multi_value_attribute = attribute.as_multi_value_attribute(); if (multi_value_attribute != nullptr) { - return multi_value_attribute->as_read_view(attribute::IMultiValueAttribute::Tag<AT>()); + return multi_value_attribute->make_read_view(attribute::IMultiValueAttribute::Tag<AT>(), stash); } return nullptr; } @@ -556,7 +556,7 @@ createForDirectArrayImpl(const IAttributeVector * attribute, const A * iattr = dynamic_cast<const A *>(attribute); using T = typename A::BaseType; using VT = T; - auto array_read_view = get_multi_value_read_view<VT>(*attribute); + auto array_read_view = make_multi_value_read_view<VT>(*attribute, stash); if (indexes.empty()) { if (array_read_view != nullptr) { return stash.create<dotproduct::array::DotProductByArrayReadViewExecutor<T>>(array_read_view, values); @@ -658,7 +658,7 @@ createForDirectWSetImpl(const IAttributeVector * attribute, V && vector, vespali using T = typename A::BaseType; const A * iattr = dynamic_cast<const A *>(attribute); using VT = multivalue::WeightedValue<T>; - auto weighted_set_read_view = get_multi_value_read_view<VT>(*attribute); + auto weighted_set_read_view = make_multi_value_read_view<VT>(*attribute, stash); if (!attribute->isImported() && (iattr != nullptr) && weighted_set_read_view != nullptr) { if (extractSize(vector) == 1) { auto elem = extractElem(vector, 0ul); @@ -719,7 +719,7 @@ createFromObject(const IAttributeVector * attribute, const fef::Anything & objec return stash.create<SingleZeroValueExecutor>(); } using VT = multivalue::WeightedValue<vespalib::datastore::AtomicEntryRef>; - auto* weighted_set_enum_read_view = get_multi_value_read_view<VT>(*attribute); + auto* weighted_set_enum_read_view = make_multi_value_read_view<VT>(*attribute, stash); if (weighted_set_enum_read_view != nullptr) { if (vector.getVector().size() == 1) { const auto & elem = vector.getVector()[0]; @@ -814,7 +814,7 @@ createTypedWsetExecutor(const IAttributeVector * attribute, const Property & pro } vector->syncMap(); using VT = multivalue::WeightedValue<vespalib::datastore::AtomicEntryRef>; - auto* weighted_set_enum_read_view = get_multi_value_read_view<VT>(*attribute); + auto* weighted_set_enum_read_view = make_multi_value_read_view<VT>(*attribute, stash); if (weighted_set_enum_read_view != nullptr) { if (vector->getVector().size() == 1) { const auto & elem = vector->getVector()[0]; diff --git a/searchlib/src/vespa/searchlib/features/internal_max_reduce_prod_join_feature.cpp b/searchlib/src/vespa/searchlib/features/internal_max_reduce_prod_join_feature.cpp index e69c3703c2c..5e3dc727279 100644 --- a/searchlib/src/vespa/searchlib/features/internal_max_reduce_prod_join_feature.cpp +++ b/searchlib/src/vespa/searchlib/features/internal_max_reduce_prod_join_feature.cpp @@ -90,7 +90,7 @@ feature_t maxProduct(const A &array, size_t count, const V &query) { template<typename BaseType> void RawExecutor<BaseType>::execute(uint32_t docId) { - auto values = _array_read_view->get_raw_values(docId); + auto values = _array_read_view->get_values(docId); outputs().set_number(0, maxProduct(values.data(), values.size(), _queryVector)); } @@ -147,7 +147,7 @@ selectTypedExecutor(const IAttributeVector *attribute, V && vector, vespalib::St using VT = BaseType; auto multi_value_attribute = attribute->as_multi_value_attribute(); if (multi_value_attribute != nullptr) { - auto array_read_view = multi_value_attribute->as_read_view(attribute::IMultiValueAttribute::Tag<VT>()); + auto array_read_view = multi_value_attribute->make_read_view(attribute::IMultiValueAttribute::Tag<VT>(), stash); if (array_read_view != nullptr) { return stash.create<RawExecutor<BaseType>>(array_read_view, std::forward<V>(vector)); } |