summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Marius Venstad <jonmv@users.noreply.github.com>2022-04-17 13:40:48 +0200
committerGitHub <noreply@github.com>2022-04-17 13:40:48 +0200
commitecc1d05760fedf9c49a24a949160aa7930838dcc (patch)
tree846847b018d480cbfd399921d447a9656b817629
parente593f6bf57a63b71e0e078466104fc110a60d267 (diff)
parent5dd851d5c5fce2e95b236cd1f5385270077f0450 (diff)
Merge branch 'master' into jonmv/no-more-serviceview/v1
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java2
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java3
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java1
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/InstanceList.java5
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java2
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java2
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/Upgrader.java4
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java12
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java12
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java11
-rw-r--r--dist/vespa.spec2
-rw-r--r--searchcommon/src/vespa/searchcommon/attribute/i_multi_value_attribute.h35
-rw-r--r--searchcommon/src/vespa/searchcommon/attribute/i_multi_value_read_view.h6
-rw-r--r--searchlib/src/tests/attribute/extendattributes/CMakeLists.txt4
-rw-r--r--searchlib/src/tests/attribute/extendattributes/extendattribute.cpp175
-rwxr-xr-xsearchlib/src/tests/attribute/extendattributes/extendattribute_test.sh5
-rw-r--r--searchlib/src/vespa/searchlib/attribute/CMakeLists.txt1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multivalueattribute.h16
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multivalueattribute.hpp15
-rw-r--r--searchlib/src/vespa/searchlib/attribute/raw_multi_value_read_view.cpp41
-rw-r--r--searchlib/src/vespa/searchlib/attribute/raw_multi_value_read_view.h24
-rw-r--r--searchlib/src/vespa/searchlib/features/attributefeature.cpp14
-rw-r--r--searchlib/src/vespa/searchlib/features/dotproductfeature.cpp24
-rw-r--r--searchlib/src/vespa/searchlib/features/internal_max_reduce_prod_join_feature.cpp4
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));
}