aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Musum <musum@yahooinc.com>2023-09-25 14:40:55 +0200
committerHarald Musum <musum@yahooinc.com>2023-09-25 14:40:55 +0200
commit7c37396177a488ebed5cef7694aa996783e257ff (patch)
tree39bf4a2f64437350be00b31ac176b2610227382f
parent8b80c2bb7ba62960dfeebed27d4cc08f9475234d (diff)
parent7facdd6177063f772c497000b9c12e4653a2db83 (diff)
Merge branch 'master' into hmusum/add-feature-flag-3
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/ApplicationClusterEndpoint.java75
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/UrlConfigValidator.java50
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java78
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFiles.java14
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/UrlConfigValidatorTest.java107
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java59
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFilesTest.java6
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/model/LbServicesProducerTest.java5
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CertificatePoolMaintainer.java2
-rw-r--r--searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp99
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp5
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp19
-rw-r--r--searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.h6
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.h2
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/weighted_set_term_search.cpp8
18 files changed, 455 insertions, 93 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ApplicationClusterEndpoint.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ApplicationClusterEndpoint.java
index 215439aa42a..69749ee6f96 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/ApplicationClusterEndpoint.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ApplicationClusterEndpoint.java
@@ -2,8 +2,15 @@
package com.yahoo.config.model.api;
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.SystemName;
+
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* Represents one endpoint for an application cluster
@@ -147,21 +154,83 @@ public class ApplicationClusterEndpoint {
}
- public record DnsName(String name) implements Comparable<DnsName> {
+ public static class DnsName implements Comparable<DnsName> {
+
+ private static final int MAX_LABEL_LENGTH = 63;
+
+ private final String name;
+
+ private DnsName(String name) {
+ this.name = name;
+ }
public String value() {
return name;
}
+ public static DnsName sharedNameFrom(SystemName systemName, ClusterSpec.Id cluster, ApplicationId applicationId, String suffix) {
+ String name = dnsParts(systemName, cluster, applicationId)
+ .filter(Objects::nonNull) // remove null values that were "default"
+ .collect(Collectors.joining("--"));
+ return new DnsName(sanitize(name) + suffix); // Need to sanitize name since it is considered one label
+ }
+
+ public static DnsName sharedL4NameFrom(SystemName systemName, ClusterSpec.Id cluster, ApplicationId applicationId, String suffix) {
+ String name = dnsParts(systemName, cluster, applicationId)
+ .filter(Objects::nonNull) // remove null values that were "default"
+ .map(DnsName::sanitize)
+ .collect(Collectors.joining("."));
+ return new DnsName(name + suffix);
+ }
+
public static DnsName from(String name) {
return new DnsName(name);
}
+ private static Stream<String> dnsParts(SystemName systemName, ClusterSpec.Id cluster, ApplicationId applicationId) {
+ return Stream.of(
+ nullIfDefault(cluster.value()),
+ systemPart(systemName),
+ nullIfDefault(applicationId.instance().value()),
+ applicationId.application().value(),
+ applicationId.tenant().value()
+ );
+ }
+
+ /**
+ * Remove any invalid characters from the hostnames
+ */
+ private static String sanitize(String id) {
+ return shortenIfNeeded(id.toLowerCase()
+ .replace('_', '-')
+ .replaceAll("[^a-z0-9-]*", ""));
+ }
+
+ /**
+ * Truncate the given string at the front so its length does not exceed 63 characters.
+ */
+ private static String shortenIfNeeded(String id) {
+ return id.substring(Math.max(0, id.length() - MAX_LABEL_LENGTH));
+ }
+
+ private static String nullIfDefault(String string) {
+ return Optional.of(string).filter(s -> !s.equals("default")).orElse(null);
+ }
+
+ private static String systemPart(SystemName systemName) {
+ return "cd".equals(systemName.value()) ? systemName.value() : null;
+ }
+
+ @Override
+ public String toString() {
+ return "DnsName{" +
+ "name='" + name + '\'' +
+ '}';
+ }
+
@Override
public int compareTo(DnsName o) {
return name.compareTo(o.name);
}
-
}
-
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/UrlConfigValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/UrlConfigValidator.java
new file mode 100644
index 00000000000..d9dd3729bd3
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/UrlConfigValidator.java
@@ -0,0 +1,50 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.application.validation;
+
+import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.vespa.model.VespaModel;
+import com.yahoo.vespa.model.container.ApplicationContainerCluster;
+
+/**
+ * Validates that config using s3:// urls is used in public system and with nodes that are exclusive.
+ *
+ * @author hmusum
+ */
+public class UrlConfigValidator extends Validator {
+
+ @Override
+ public void validate(VespaModel model, DeployState state) {
+ if (! state.isHostedTenantApplication(model.getAdmin().getApplicationType())) return;
+
+ model.getContainerClusters().forEach((__, cluster) -> {
+ var isExclusive = hasExclusiveNodes(model, cluster);
+ validateS3UlsInConfig(state, cluster, isExclusive);
+ });
+ }
+
+ private static boolean hasExclusiveNodes(VespaModel model, ApplicationContainerCluster cluster) {
+ return model.hostSystem().getHosts()
+ .stream()
+ .flatMap(hostResource -> hostResource.spec().membership().stream())
+ .filter(membership -> membership.cluster().id().equals(cluster.id()))
+ .anyMatch(membership -> membership.cluster().isExclusive());
+ }
+
+ private static void validateS3UlsInConfig(DeployState state, ApplicationContainerCluster cluster, boolean isExclusive) {
+ if (hasS3UrlInConfig(cluster)) {
+ // TODO: Would be even better if we could add which config/field the url is set for in the error message
+ String message = "Found s3:// urls in config for container cluster " + cluster.getName();
+ if ( ! state.zone().system().isPublic())
+ throw new IllegalArgumentException(message + ". This is only supported in public systems");
+ else if ( ! isExclusive)
+ throw new IllegalArgumentException(message + ". Nodes in the cluster need to be 'exclusive'," +
+ " see https://cloud.vespa.ai/en/reference/services#nodes");
+ }
+ }
+
+ private static boolean hasS3UrlInConfig(ApplicationContainerCluster cluster) {
+ return cluster.userConfiguredUrls().all().stream()
+ .anyMatch(url -> url.startsWith("s3://"));
+ }
+
+}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
index b9ecf7c2d22..30aafe67be7 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
@@ -87,6 +87,7 @@ public class Validation {
new AccessControlFilterExcludeValidator().validate(model, deployState);
new CloudUserFilterValidator().validate(model, deployState);
new CloudHttpConnectorValidator().validate(model, deployState);
+ new UrlConfigValidator().validate(model, deployState);
new JvmHeapSizeValidator().validate(model, deployState);
additionalValidators.forEach(v -> v.validate(model, deployState));
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
index a4ed187206d..8d9ef84ef71 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
@@ -11,11 +11,13 @@ import com.yahoo.config.application.api.ComponentInfo;
import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.config.model.api.ApplicationClusterEndpoint;
import com.yahoo.config.model.api.ApplicationClusterInfo;
+import com.yahoo.config.model.api.ContainerEndpoint;
import com.yahoo.config.model.api.Model;
import com.yahoo.config.model.api.OnnxModelCost;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.producer.TreeConfigProducer;
import com.yahoo.config.provision.AllocatedHosts;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.container.bundle.BundleInstantiationSpecification;
import com.yahoo.container.di.config.ApplicationBundlesConfig;
@@ -43,6 +45,7 @@ import com.yahoo.vespa.model.filedistribution.UserConfiguredFiles;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
@@ -104,6 +107,8 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
private List<ApplicationClusterEndpoint> endpoints = List.of();
+ private final UserConfiguredUrls userConfiguredUrls = new UserConfiguredUrls();
+
public ApplicationContainerCluster(TreeConfigProducer<?> parent, String configSubId, String clusterId, DeployState deployState) {
super(parent, configSubId, clusterId, deployState, true, 10);
this.tlsClientAuthority = deployState.tlsClientAuthority();
@@ -134,6 +139,8 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
logger = deployState.getDeployLogger();
}
+ public UserConfiguredUrls userConfiguredUrls() { return userConfiguredUrls; }
+
@Override
protected void doPrepare(DeployState deployState) {
super.doPrepare(deployState);
@@ -156,7 +163,8 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
// Files referenced from user configs to all components.
UserConfiguredFiles files = new UserConfiguredFiles(deployState.getFileRegistry(),
deployState.getDeployLogger(),
- deployState.featureFlags());
+ deployState.featureFlags(),
+ userConfiguredUrls);
for (Component<?, ?> component : getAllComponents()) {
files.register(component);
}
@@ -218,23 +226,49 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
private void createEndpoints(DeployState deployState) {
if (!deployState.isHosted()) return;
if (deployState.getProperties().applicationId().instance().isTester()) return;
- // Add endpoints provided by the controller
- List<String> hosts = getContainers().stream().map(AbstractService::getHostName).sorted().toList();
List<ApplicationClusterEndpoint> endpoints = new ArrayList<>();
- deployState.getEndpoints().stream()
- .filter(ce -> ce.clusterId().equals(getName()))
- .forEach(ce -> ce.names().forEach(
- name -> endpoints.add(ApplicationClusterEndpoint.builder()
- .scope(ce.scope())
- .weight(ce.weight().orElse(1))
- .routingMethod(ce.routingMethod())
- .dnsName(ApplicationClusterEndpoint.DnsName.from(name))
- .hosts(hosts)
- .clusterId(getName())
- .authMethod(ce.authMethod())
- .build())
- ));
- this.endpoints = Collections.unmodifiableList(endpoints);
+
+ List<String> hosts = getContainers().stream()
+ .map(AbstractService::getHostName)
+ .sorted()
+ .toList();
+
+ Set<ContainerEndpoint> endpointsFromController = deployState.getEndpoints();
+ // Add zone-scoped endpoints if not provided by the controller
+ // TODO(mpolden): Remove this when controller always includes zone-scope endpoints, and config models < 8.230 are gone
+ if (endpointsFromController.stream().noneMatch(endpoint -> endpoint.scope() == ApplicationClusterEndpoint.Scope.zone)) {
+ for (String suffix : deployState.getProperties().zoneDnsSuffixes()) {
+ ApplicationClusterEndpoint.DnsName l4Name = ApplicationClusterEndpoint.DnsName.sharedL4NameFrom(
+ deployState.zone().system(),
+ ClusterSpec.Id.from(getName()),
+ deployState.getProperties().applicationId(),
+ suffix);
+ endpoints.add(ApplicationClusterEndpoint.builder()
+ .zoneScope()
+ .sharedL4Routing()
+ .dnsName(l4Name)
+ .hosts(hosts)
+ .clusterId(getName())
+ .authMethod(ApplicationClusterEndpoint.AuthMethod.mtls)
+ .build());
+ }
+ }
+
+ // Include all endpoints provided by controller
+ endpointsFromController.stream()
+ .filter(ce -> ce.clusterId().equals(getName()))
+ .forEach(ce -> ce.names().forEach(
+ name -> endpoints.add(ApplicationClusterEndpoint.builder()
+ .scope(ce.scope())
+ .weight(ce.weight().orElse(1)) // Default to weight=1 if not set
+ .routingMethod(ce.routingMethod())
+ .dnsName(ApplicationClusterEndpoint.DnsName.from(name))
+ .hosts(hosts)
+ .clusterId(getName())
+ .authMethod(ce.authMethod())
+ .build())
+ ));
+ this.endpoints = List.copyOf(endpoints);
}
@Override
@@ -384,4 +418,14 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
}
}
+ public static class UserConfiguredUrls {
+
+ private final Set<String> urls = new HashSet<>();
+
+ public void add(String url) { urls.add(url); }
+
+ public Set<String> all() { return urls; }
+
+ }
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFiles.java b/config-model/src/main/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFiles.java
index 60afb491be2..0095dec8079 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFiles.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFiles.java
@@ -12,6 +12,7 @@ import com.yahoo.path.Path;
import com.yahoo.vespa.config.ConfigDefinition;
import com.yahoo.vespa.config.ConfigDefinitionKey;
import com.yahoo.vespa.config.ConfigPayloadBuilder;
+
import com.yahoo.yolean.Exceptions;
import java.io.File;
@@ -22,6 +23,8 @@ import java.util.Map;
import java.util.Optional;
import java.util.logging.Level;
+import static com.yahoo.vespa.model.container.ApplicationContainerCluster.UserConfiguredUrls;
+
/**
* Utility methods for registering file distribution of files/paths/urls/models defined by the user.
*
@@ -31,11 +34,15 @@ public class UserConfiguredFiles implements Serializable {
private final FileRegistry fileRegistry;
private final DeployLogger logger;
+ private final UserConfiguredUrls userConfiguredUrls;
private final String unknownConfigDefinition;
- public UserConfiguredFiles(FileRegistry fileRegistry, DeployLogger logger, ModelContext.FeatureFlags featureFlags) {
+ public UserConfiguredFiles(FileRegistry fileRegistry, DeployLogger logger,
+ ModelContext.FeatureFlags featureFlags,
+ UserConfiguredUrls userConfiguredUrls) {
this.fileRegistry = fileRegistry;
this.logger = logger;
+ this.userConfiguredUrls = userConfiguredUrls;
this.unknownConfigDefinition = featureFlags.unknownConfigDefinition();
}
@@ -139,7 +146,10 @@ public class UserConfiguredFiles implements Serializable {
Path path;
if (isModelType) {
var modelReference = ModelReference.valueOf(builder.getValue());
- if (modelReference.path().isEmpty()) return;
+ if (modelReference.path().isEmpty()) {
+ modelReference.url().ifPresent(url -> userConfiguredUrls.add(url.value()));
+ return;
+ }
path = Path.fromString(modelReference.path().get().value());
}
else {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/UrlConfigValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/UrlConfigValidatorTest.java
new file mode 100644
index 00000000000..cef4d8c27dd
--- /dev/null
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/UrlConfigValidatorTest.java
@@ -0,0 +1,107 @@
+package com.yahoo.vespa.model.application.validation;
+
+import com.yahoo.config.application.api.ApplicationPackage;
+import com.yahoo.config.model.NullConfigModelRegistry;
+import com.yahoo.config.model.api.ConfigDefinitionRepo;
+import com.yahoo.config.model.application.provider.MockFileRegistry;
+import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.config.model.deploy.TestProperties;
+import com.yahoo.config.model.test.MockApplicationPackage;
+import com.yahoo.config.provision.RegionName;
+import com.yahoo.config.provision.SystemName;
+import com.yahoo.config.provision.Zone;
+import com.yahoo.embedding.BertBaseEmbedderConfig;
+import com.yahoo.vespa.config.ConfigDefinitionKey;
+import com.yahoo.vespa.config.buildergen.ConfigDefinition;
+import com.yahoo.vespa.model.VespaModel;
+import org.junit.jupiter.api.Test;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.yahoo.config.provision.Environment.prod;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class UrlConfigValidatorTest {
+
+ @Test
+ void failsWhenContainerNodesNotExclusive() throws IOException, SAXException {
+ runValidatorOnApp(true, SystemName.Public); // Exclusive nodes in public => success
+
+ assertEquals("Found s3:// urls in config for container cluster default. This is only supported in public systems",
+ assertThrows(IllegalArgumentException.class,
+ () -> runValidatorOnApp(false, SystemName.main))
+ .getMessage());
+
+ assertEquals("Found s3:// urls in config for container cluster default. This is only supported in public systems",
+ assertThrows(IllegalArgumentException.class,
+ () -> runValidatorOnApp(true, SystemName.main))
+ .getMessage());
+
+ assertEquals("Found s3:// urls in config for container cluster default. Nodes in the cluster need to be 'exclusive',"
+ + " see https://cloud.vespa.ai/en/reference/services#nodes",
+ assertThrows(IllegalArgumentException.class,
+ () -> runValidatorOnApp(false, SystemName.Public))
+ .getMessage());
+ }
+
+ private static String containerXml(boolean isExclusive) {
+ return """
+ <container version='1.0' id='default'>
+ <component id='transformer' class='ai.vespa.embedding.BertBaseEmbedder' bundle='model-integration'>
+ <config name='embedding.bert-base-embedder'>
+ <transformerModel url='s3://models/minilm-l6-v2/sentence_all_MiniLM_L6_v2.onnx' path='foo'/>
+ <tokenizerVocab url='s3://models/bert-base-uncased.txt'/>
+ </config>
+ </component>
+ <search/>
+ <document-api/>
+ <nodes count='2' exclusive='%s' />
+ </container>
+ """.formatted(Boolean.toString(isExclusive));
+ }
+
+ private static void runValidatorOnApp(boolean isExclusive, SystemName systemName) throws IOException, SAXException {
+ String container = containerXml(isExclusive);
+ String servicesXml = """
+ <services version='1.0'>
+ %s
+ </services>
+ """.formatted(container);
+ ApplicationPackage app = new MockApplicationPackage.Builder()
+ .withServices(servicesXml)
+ .build();
+ DeployState deployState = createDeployState(app, systemName);
+ VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState);
+ new UrlConfigValidator().validate(model, deployState);
+ }
+
+ private static DeployState createDeployState(ApplicationPackage app, SystemName systemName) {
+ boolean isHosted = true;
+ var builder = new DeployState.Builder()
+ .applicationPackage(app)
+ .zone(new Zone(systemName, prod, RegionName.from("us-east-3")))
+ .properties(new TestProperties().setHostedVespa(isHosted))
+ .fileRegistry(new MockFileRegistry());
+
+ Map<ConfigDefinitionKey, ConfigDefinition> defs = new HashMap<>();
+ defs.put(new ConfigDefinitionKey(BertBaseEmbedderConfig.CONFIG_DEF_NAME, BertBaseEmbedderConfig.CONFIG_DEF_NAMESPACE),
+ new ConfigDefinition(BertBaseEmbedderConfig.CONFIG_DEF_NAME, BertBaseEmbedderConfig.CONFIG_DEF_SCHEMA));
+ builder.configDefinitionRepo(new ConfigDefinitionRepo() {
+ @Override
+ public Map<ConfigDefinitionKey, com.yahoo.vespa.config.buildergen.ConfigDefinition> getConfigDefinitions() {
+ return defs;
+ }
+
+ @Override
+ public com.yahoo.vespa.config.buildergen.ConfigDefinition get(ConfigDefinitionKey key) {
+ return defs.get(key);
+ }
+ });
+ return builder.build();
+ }
+
+}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
index 3bdb60a0a8d..894fc55c014 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
@@ -42,14 +42,14 @@ import java.util.Objects;
import java.util.OptionalInt;
import java.util.Set;
+import static com.yahoo.config.model.api.ApplicationClusterEndpoint.RoutingMethod.exclusive;
+import static com.yahoo.config.model.api.ApplicationClusterEndpoint.RoutingMethod.shared;
import static com.yahoo.config.model.api.ApplicationClusterEndpoint.RoutingMethod.sharedLayer4;
import static com.yahoo.config.model.api.ApplicationClusterEndpoint.Scope.application;
import static com.yahoo.config.model.api.ApplicationClusterEndpoint.Scope.global;
-import static com.yahoo.config.model.api.ApplicationClusterEndpoint.Scope.zone;
+import static com.yahoo.config.provision.SystemName.cd;
import static com.yahoo.config.provision.SystemName.main;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.*;
/**
* @author Simon Thoresen Hult
@@ -365,23 +365,62 @@ public class ContainerClusterTest {
@Test
void generatesCorrectRoutingInfo() {
+ // main system:
assertNames(main,
ApplicationId.from("t1", "a1", "i1"),
- Set.of(new ContainerEndpoint("search-cluster", zone, List.of("search-cluster.i1.a1.t1.endpoint.suffix"), OptionalInt.empty(), sharedLayer4)),
+ Set.of(),
List.of("search-cluster.i1.a1.t1.endpoint.suffix"));
assertNames(main,
ApplicationId.from("t1", "a1", "default"),
- Set.of(new ContainerEndpoint("not-in-this-cluster", global, List.of("foo", "bar")),
- new ContainerEndpoint("search-cluster", zone, List.of("search-cluster.a1.t1.endpoint.suffix"), OptionalInt.empty(), sharedLayer4)),
+ Set.of(),
+ List.of("search-cluster.a1.t1.endpoint.suffix"));
+
+ assertNames(main,
+ ApplicationId.from("t1", "default", "default"),
+ Set.of(),
+ List.of("search-cluster.default.t1.endpoint.suffix"));
+
+ assertNames(main,
+ ApplicationId.from("t1", "a1", "default"),
+ Set.of(new ContainerEndpoint("not-in-this-cluster", global, List.of("foo", "bar"))),
List.of("search-cluster.a1.t1.endpoint.suffix"));
assertNames(main,
ApplicationId.from("t1", "a1", "default"),
- Set.of(new ContainerEndpoint("search-cluster", global, List.of("rotation-1.x.y.z", "rotation-2.x.y.z"), OptionalInt.empty(), sharedLayer4),
- new ContainerEndpoint("search-cluster", application, List.of("app-rotation.x.y.z"), OptionalInt.of(3), sharedLayer4),
- new ContainerEndpoint("search-cluster", zone, List.of("search-cluster.a1.t1.endpoint.suffix"), OptionalInt.empty(), sharedLayer4)),
+ Set.of(new ContainerEndpoint("search-cluster", global, List.of("rotation-1.x.y.z", "rotation-2.x.y.z"), OptionalInt.empty(), sharedLayer4),
+ new ContainerEndpoint("search-cluster", application, List.of("app-rotation.x.y.z"), OptionalInt.of(3), sharedLayer4)),
List.of("search-cluster.a1.t1.endpoint.suffix", "rotation-1.x.y.z", "rotation-2.x.y.z", "app-rotation.x.y.z"));
+
+ // cd system:
+ assertNames(cd,
+ ApplicationId.from("t1", "a1", "i1"),
+ Set.of(),
+ List.of("search-cluster.cd.i1.a1.t1.endpoint.suffix"));
+
+ assertNames(cd,
+ ApplicationId.from("t1", "a1", "default"),
+ Set.of(),
+ List.of("search-cluster.cd.a1.t1.endpoint.suffix"));
+
+ assertNames(cd,
+ ApplicationId.from("t1", "default", "default"),
+ Set.of(),
+ List.of("search-cluster.cd.default.t1.endpoint.suffix"));
+
+ assertNames(cd,
+ ApplicationId.from("t1", "a1", "default"),
+ Set.of(new ContainerEndpoint("not-in-this-cluster", global, List.of("foo", "bar"))),
+ List.of("search-cluster.cd.a1.t1.endpoint.suffix"));
+
+ assertNames(cd,
+ ApplicationId.from("t1", "a1", "default"),
+ Set.of(new ContainerEndpoint("search-cluster", global, List.of("rotation-1.x.y.z", "rotation-2.x.y.z"), OptionalInt.empty(), sharedLayer4),
+ new ContainerEndpoint("search-cluster", global, List.of("a.b.x.y.z", "rotation-2.x.y.z"), OptionalInt.empty(), shared),
+ new ContainerEndpoint("search-cluster", application, List.of("app-rotation.x.y.z"), OptionalInt.of(3), sharedLayer4),
+ new ContainerEndpoint("not-supported", global, List.of("not.supported"), OptionalInt.empty(), exclusive)),
+ List.of("search-cluster.cd.a1.t1.endpoint.suffix", "rotation-1.x.y.z", "rotation-2.x.y.z", "app-rotation.x.y.z"));
+
}
private void assertNames(SystemName systemName, ApplicationId appId, Set<ContainerEndpoint> globalEndpoints, List<String> expectedSharedL4Names) {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFilesTest.java b/config-model/src/test/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFilesTest.java
index 7dde969b8b3..653bdbccf15 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFilesTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/filedistribution/UserConfiguredFilesTest.java
@@ -14,6 +14,7 @@ import com.yahoo.vespa.config.ConfigDefinition;
import com.yahoo.vespa.config.ConfigDefinitionKey;
import com.yahoo.vespa.config.ConfigPayloadBuilder;
import com.yahoo.vespa.model.SimpleConfigProducer;
+import com.yahoo.vespa.model.container.ApplicationContainerCluster;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
@@ -69,7 +70,10 @@ public class UserConfiguredFilesTest {
}
private UserConfiguredFiles userConfiguredFiles() {
- return new UserConfiguredFiles(fileRegistry, new BaseDeployLogger(), new TestProperties());
+ return new UserConfiguredFiles(fileRegistry,
+ new BaseDeployLogger(),
+ new TestProperties(),
+ new ApplicationContainerCluster.UserConfiguredUrls());
}
@BeforeEach
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/model/LbServicesProducerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/model/LbServicesProducerTest.java
index 8d1b0fefbaf..ca2f9da3273 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/model/LbServicesProducerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/model/LbServicesProducerTest.java
@@ -50,11 +50,10 @@ import static org.junit.Assert.assertTrue;
public class LbServicesProducerTest {
private static final Set<ContainerEndpoint> endpoints = Set.of(
- new ContainerEndpoint("mydisc", ApplicationClusterEndpoint.Scope.zone, List.of("mydisc.foo.foo.endpoint1.suffix")),
- new ContainerEndpoint("mydisc", ApplicationClusterEndpoint.Scope.zone, List.of("mydisc.foo.foo.endpoint2.suffix")),
new ContainerEndpoint("mydisc", ApplicationClusterEndpoint.Scope.global, List.of("rotation-1", "rotation-2")),
new ContainerEndpoint("mydisc", ApplicationClusterEndpoint.Scope.application, List.of("app-endpoint"))
);
+ private static final List<String> zoneDnsSuffixes = List.of(".endpoint1.suffix", ".endpoint2.suffix");
private final InMemoryFlagSource flagSource = new InMemoryFlagSource();
@@ -229,7 +228,7 @@ public class LbServicesProducerTest {
private TestProperties getTestproperties(ApplicationId applicationId) {
return new TestProperties()
.setHostedVespa(true)
+ .setZoneDnsSuffixes(zoneDnsSuffixes)
.setApplicationId(applicationId);
}
-
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CertificatePoolMaintainer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CertificatePoolMaintainer.java
index 70eeb2b9f6c..ed383175cc3 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CertificatePoolMaintainer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CertificatePoolMaintainer.java
@@ -69,7 +69,7 @@ public class CertificatePoolMaintainer extends ControllerMaintainer {
// Create metric for available certificates in the pool as a fraction of configured size
int poolSize = certPoolSize.value();
long available = certificatePool.stream().filter(c -> c.state() == UnassignedCertificate.State.ready).count();
- metric.set(ControllerMetrics.CERTIFICATE_POOL_AVAILABLE.baseName(), (poolSize > 0 ? (available/poolSize) : 1.0), metric.createContext(Map.of()));
+ metric.set(ControllerMetrics.CERTIFICATE_POOL_AVAILABLE.baseName(), (poolSize > 0 ? ((double)available/poolSize) : 1.0), metric.createContext(Map.of()));
if (certificatePool.size() < poolSize) {
provisionRandomizedCertificate();
diff --git a/searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp b/searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp
index d7a854e0afc..6c6f05fd5e2 100644
--- a/searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp
+++ b/searchlib/src/tests/attribute/searchable/attribute_weighted_set_blueprint_test.cpp
@@ -29,14 +29,14 @@ using namespace search::attribute::test;
namespace {
void
-setupAttributeManager(MockAttributeManager &manager)
+setupAttributeManager(MockAttributeManager &manager, bool isFilter)
{
AttributeVector::DocId docId;
{
- AttributeVector::SP attr_sp = AttributeFactory::createAttribute("integer", Config(BasicType("int64")));
+ AttributeVector::SP attr_sp = AttributeFactory::createAttribute("integer", Config(BasicType("int64")).setIsFilter(isFilter));
manager.addAttribute(attr_sp);
- IntegerAttribute *attr = (IntegerAttribute*)(attr_sp.get());
+ auto *attr = (IntegerAttribute*)(attr_sp.get());
for (size_t i = 1; i < 10; ++i) {
attr->addDoc(docId);
assert(i == docId);
@@ -45,10 +45,10 @@ setupAttributeManager(MockAttributeManager &manager)
}
}
{
- AttributeVector::SP attr_sp = AttributeFactory::createAttribute("string", Config(BasicType("string")));
+ AttributeVector::SP attr_sp = AttributeFactory::createAttribute("string", Config(BasicType("string")).setIsFilter(isFilter));
manager.addAttribute(attr_sp);
- StringAttribute *attr = (StringAttribute*)(attr_sp.get());
+ auto *attr = (StringAttribute*)(attr_sp.get());
for (size_t i = 1; i < 10; ++i) {
attr->addDoc(docId);
assert(i == docId);
@@ -58,9 +58,9 @@ setupAttributeManager(MockAttributeManager &manager)
}
{
AttributeVector::SP attr_sp = AttributeFactory::createAttribute(
- "multi", Config(BasicType("int64"), search::attribute::CollectionType("array")));
+ "multi", Config(BasicType("int64"), search::attribute::CollectionType("array")).setIsFilter(isFilter));
manager.addAttribute(attr_sp);
- IntegerAttribute *attr = (IntegerAttribute*)(attr_sp.get());
+ auto *attr = (IntegerAttribute*)(attr_sp.get());
for (size_t i = 1; i < 10; ++i) {
attr->addDoc(docId);
assert(i == docId);
@@ -78,35 +78,43 @@ struct WS {
TermFieldHandle handle;
std::vector<std::pair<std::string, uint32_t> > tokens;
- WS(IAttributeManager & manager) : attribute_manager(manager), layout(), handle(layout.allocTermField(fieldId)), tokens() {
+ explicit WS(IAttributeManager & manager)
+ : attribute_manager(manager),
+ layout(), handle(layout.allocTermField(fieldId)),
+ tokens()
+ {
MatchData::UP tmp = layout.createMatchData();
ASSERT_TRUE(tmp->resolveTermField(handle)->getFieldId() == fieldId);
}
WS &add(const std::string &token, uint32_t weight) {
- tokens.push_back(std::make_pair(token, weight));
+ tokens.emplace_back(token, weight);
return *this;
}
Node::UP createNode() const {
- SimpleWeightedSetTerm *node = new SimpleWeightedSetTerm(tokens.size(), "view", 0, Weight(0));
- for (size_t i = 0; i < tokens.size(); ++i) {
- node->addTerm(tokens[i].first, Weight(tokens[i].second));
+ auto *node = new SimpleWeightedSetTerm(tokens.size(), "view", 0, Weight(0));
+ for (const auto & token : tokens) {
+ node->addTerm(token.first, Weight(token.second));
}
return Node::UP(node);
}
- bool isGenericSearch(Searchable &searchable, const std::string &field, bool strict) const {
+ SearchIterator::UP
+ createSearch(Searchable &searchable, const std::string &field, bool strict) const {
AttributeContext ac(attribute_manager);
FakeRequestContext requestContext(&ac);
MatchData::UP md = layout.createMatchData();
Node::UP node = createNode();
FieldSpecList fields;
- fields.add(FieldSpec(field, fieldId, handle));
+ fields.add(FieldSpec(field, fieldId, handle, ac.getAttribute(field)->getIsFilter()));
queryeval::Blueprint::UP bp = searchable.createBlueprint(requestContext, fields, *node);
bp->fetchPostings(queryeval::ExecuteInfo::create(strict));
SearchIterator::UP sb = bp->createSearch(*md, strict);
- return (dynamic_cast<WeightedSetTermSearch*>(sb.get()) != 0);
+ return sb;
+ }
+ bool isWeightedSetTermSearch(Searchable &searchable, const std::string &field, bool strict) const {
+ return dynamic_cast<WeightedSetTermSearch *>(createSearch(searchable, field, strict).get()) != nullptr;
}
FakeResult search(Searchable &searchable, const std::string &field, bool strict) const {
@@ -140,23 +148,58 @@ struct WS {
} // namespace <unnamed>
+void test_tokens(bool isFilter, const std::vector<uint32_t> & docs) {
+ MockAttributeManager manager;
+ setupAttributeManager(manager, isFilter);
+ AttributeBlueprintFactory adapter;
+
+ FakeResult expect = FakeResult();
+ WS ws = WS(manager);
+ for (uint32_t doc : docs) {
+ auto docS = vespalib::stringify(doc);
+ int32_t weight = doc * 10;
+ expect.doc(doc).weight(weight).pos(0);
+ ws.add(docS, weight);
+ }
+
+ EXPECT_TRUE(ws.isWeightedSetTermSearch(adapter, "integer", true));
+ EXPECT_TRUE(!ws.isWeightedSetTermSearch(adapter, "integer", false));
+ EXPECT_TRUE(ws.isWeightedSetTermSearch(adapter, "string", true));
+ EXPECT_TRUE(!ws.isWeightedSetTermSearch(adapter, "string", false));
+ EXPECT_TRUE(ws.isWeightedSetTermSearch(adapter, "multi", true));
+ EXPECT_TRUE(ws.isWeightedSetTermSearch(adapter, "multi", false));
+
+ EXPECT_EQUAL(expect, ws.search(adapter, "integer", true));
+ EXPECT_EQUAL(expect, ws.search(adapter, "integer", false));
+ EXPECT_EQUAL(expect, ws.search(adapter, "string", true));
+ EXPECT_EQUAL(expect, ws.search(adapter, "string", false));
+ EXPECT_EQUAL(expect, ws.search(adapter, "multi", true));
+ EXPECT_EQUAL(expect, ws.search(adapter, "multi", false));
+}
TEST("attribute_weighted_set_test") {
+ test_tokens(false, {3, 5, 7});
+ test_tokens(true, {3, 5, 7});
+ test_tokens(false, {3});
+}
+
+TEST("attribute_weighted_set_single_token_filter_lifted_out") {
MockAttributeManager manager;
- setupAttributeManager(manager);
+ setupAttributeManager(manager, true);
AttributeBlueprintFactory adapter;
- FakeResult expect = FakeResult()
- .doc(3).elem(0).weight(30).pos(0)
- .doc(5).elem(0).weight(50).pos(0)
- .doc(7).elem(0).weight(70).pos(0);
- WS ws = WS(manager).add("7", 70).add("5", 50).add("3", 30);
-
- EXPECT_TRUE(ws.isGenericSearch(adapter, "integer", true));
- EXPECT_TRUE(!ws.isGenericSearch(adapter, "integer", false));
- EXPECT_TRUE(ws.isGenericSearch(adapter, "string", true));
- EXPECT_TRUE(!ws.isGenericSearch(adapter, "string", false));
- EXPECT_TRUE(ws.isGenericSearch(adapter, "multi", true));
- EXPECT_TRUE(ws.isGenericSearch(adapter, "multi", false));
+ FakeResult expect = FakeResult().doc(3).elem(0).weight(30).pos(0);
+ WS ws = WS(manager).add("3", 30);
+
+ EXPECT_EQUAL("search::FilterAttributeIteratorStrict<search::attribute::SingleNumericSearchContext<long, search::attribute::NumericMatcher<long> > >",
+ ws.createSearch(adapter, "integer", true)->getClassName());
+ EXPECT_EQUAL("search::FilterAttributeIteratorT<search::attribute::SingleNumericSearchContext<long, search::attribute::NumericMatcher<long> > >",
+ ws.createSearch(adapter, "integer", false)->getClassName());
+ EXPECT_EQUAL("search::FilterAttributeIteratorStrict<search::attribute::SingleEnumSearchContext<char const*, search::attribute::StringSearchContext> >",
+ ws.createSearch(adapter, "string", true)->getClassName());
+ EXPECT_EQUAL("search::FilterAttributeIteratorT<search::attribute::SingleEnumSearchContext<char const*, search::attribute::StringSearchContext> >",
+ ws.createSearch(adapter, "string", false)->getClassName());
+ EXPECT_TRUE(ws.isWeightedSetTermSearch(adapter, "multi", true));
+ EXPECT_TRUE(ws.isWeightedSetTermSearch(adapter, "multi", false));
EXPECT_EQUAL(expect, ws.search(adapter, "integer", true));
EXPECT_EQUAL(expect, ws.search(adapter, "integer", false));
diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp
index 1519bb14554..b4cdd621b71 100644
--- a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp
@@ -337,10 +337,7 @@ public:
if (tfmda.size() == 1) {
// search in exactly one field
fef::TermFieldMatchData &tfmd = *tfmda[0];
- return search::common::create_location_iterator(tfmd,
- _attribute.getNumDocs(),
- strict,
- _location);
+ return common::create_location_iterator(tfmd, _attribute.getNumDocs(), strict, _location);
} else {
LOG(debug, "wrong size tfmda: %zu (fallback to old location iterator)\n", tfmda.size());
}
diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp
index 108128eeb39..94c560a0dae 100644
--- a/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/attribute_weighted_set_blueprint.cpp
@@ -30,7 +30,7 @@ protected:
const attribute::IAttributeVector &attribute() const { return _attr; }
public:
- UseAttr(const attribute::IAttributeVector & attr)
+ explicit UseAttr(const attribute::IAttributeVector & attr)
: _attr(attr) {}
};
@@ -40,7 +40,7 @@ class UseStringEnum : public UseAttr
{
public:
using TokenT = uint32_t;
- UseStringEnum(const IAttributeVector & attr)
+ explicit UseStringEnum(const IAttributeVector & attr)
: UseAttr(attr) {}
auto mapToken(const ISearchContext &context) const {
return attribute().findFoldedEnums(context.queryTerm()->getTerm());
@@ -56,7 +56,7 @@ class UseInteger : public UseAttr
{
public:
using TokenT = uint64_t;
- UseInteger(const IAttributeVector & attr) : UseAttr(attr) {}
+ explicit UseInteger(const IAttributeVector & attr) : UseAttr(attr) {}
std::vector<int64_t> mapToken(const ISearchContext &context) const {
std::vector<int64_t> result;
Int64Range range(context.getAsIntegerTerm());
@@ -157,6 +157,10 @@ AttributeWeightedSetBlueprint::createLeafSearch(const fef::TermFieldMatchDataArr
assert(tfmda.size() == 1);
assert(getState().numFields() == 1);
fef::TermFieldMatchData &tfmd = *tfmda[0];
+ bool field_is_filter = getState().fields()[0].isFilter();
+ if (field_is_filter && (_contexts.size() == 1)) {
+ return _contexts[0]->createIterator(&tfmd, strict);
+ }
if (strict) { // use generic weighted set search
fef::MatchDataLayout layout;
auto handle = layout.allocTermField(tfmd.getFieldId());
@@ -167,7 +171,6 @@ AttributeWeightedSetBlueprint::createLeafSearch(const fef::TermFieldMatchDataArr
// TODO: pass ownership with unique_ptr
children[i] = _contexts[i]->createIterator(child_tfmd, true).release();
}
- bool field_is_filter = getState().fields()[0].isFilter();
return queryeval::WeightedSetTermSearch::create(children, tfmd, field_is_filter, _weights, std::move(match_data));
} else { // use attribute filter optimization
bool isString = (_attr.isStringType() && _attr.hasEnum());
@@ -182,18 +185,16 @@ AttributeWeightedSetBlueprint::createLeafSearch(const fef::TermFieldMatchDataArr
}
queryeval::SearchIterator::UP
-AttributeWeightedSetBlueprint::createFilterSearch(bool strict, FilterConstraint constraint) const
+AttributeWeightedSetBlueprint::createFilterSearch(bool strict, FilterConstraint) const
{
- (void) constraint;
std::vector<std::unique_ptr<queryeval::SearchIterator>> children;
children.reserve(_contexts.size());
for (auto& context : _contexts) {
- auto wrapper = std::make_unique<search::queryeval::FilterWrapper>(1);
+ auto wrapper = std::make_unique<queryeval::FilterWrapper>(1);
wrapper->wrap(context->createIterator(wrapper->tfmda()[0], strict));
children.emplace_back(std::move(wrapper));
}
- search::queryeval::UnpackInfo unpack_info;
- return search::queryeval::OrSearch::create(std::move(children), strict, unpack_info);
+ return queryeval::OrSearch::create(std::move(children), strict, queryeval::UnpackInfo());
}
void
diff --git a/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.cpp b/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.cpp
index 3c0bae00047..e2566c94f1c 100644
--- a/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.cpp
@@ -11,8 +11,8 @@ class DocumentWeightOrFilterSearchImpl : public DocumentWeightOrFilterSearch
{
AttributeIteratorPack _children;
public:
- DocumentWeightOrFilterSearchImpl(AttributeIteratorPack&& children);
- ~DocumentWeightOrFilterSearchImpl();
+ explicit DocumentWeightOrFilterSearchImpl(AttributeIteratorPack&& children);
+ ~DocumentWeightOrFilterSearchImpl() override;
void doSeek(uint32_t docId) override;
@@ -67,7 +67,7 @@ DocumentWeightOrFilterSearchImpl::doUnpack(uint32_t)
{
}
-std::unique_ptr<search::queryeval::SearchIterator>
+std::unique_ptr<queryeval::SearchIterator>
DocumentWeightOrFilterSearch::create(std::vector<DocumentWeightIterator>&& children)
{
if (children.empty()) {
diff --git a/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.h b/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.h
index 62be883ab52..c601856573f 100644
--- a/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.h
+++ b/searchlib/src/vespa/searchlib/attribute/document_weight_or_filter_search.h
@@ -9,15 +9,15 @@ namespace search::attribute {
* Filter iterator on top of document weight iterators with OR semantics used during
* calculation of global filter for weighted set terms, wand terms and dot product terms.
*/
-class DocumentWeightOrFilterSearch : public search::queryeval::SearchIterator
+class DocumentWeightOrFilterSearch : public queryeval::SearchIterator
{
protected:
DocumentWeightOrFilterSearch()
- : search::queryeval::SearchIterator()
+ : queryeval::SearchIterator()
{
}
public:
- static std::unique_ptr<search::queryeval::SearchIterator> create(std::vector<DocumentWeightIterator>&& children);
+ static std::unique_ptr<queryeval::SearchIterator> create(std::vector<DocumentWeightIterator>&& children);
};
}
diff --git a/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp
index 77d9875bf69..97f6bc2e6f8 100644
--- a/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp
+++ b/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.cpp
@@ -33,10 +33,8 @@ WeightedSetTermMatchingElementsSearch::WeightedSetTermMatchingElementsSearch(con
_search()
{
_tfmda.add(&_tfmd);
- auto generic_search = bp.createLeafSearch(_tfmda, false);
- auto weighted_set_term_search = dynamic_cast<WeightedSetTermSearch *>(generic_search.get());
- generic_search.release();
- _search.reset(weighted_set_term_search);
+ _search.reset(static_cast<WeightedSetTermSearch *>(bp.createLeafSearch(_tfmda, false).release()));
+
}
WeightedSetTermMatchingElementsSearch::~WeightedSetTermMatchingElementsSearch() = default;
diff --git a/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.h b/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.h
index 0e3c82444d7..9c8d6d88329 100644
--- a/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.h
+++ b/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_blueprint.h
@@ -18,7 +18,7 @@ class WeightedSetTermBlueprint : public ComplexLeafBlueprint
std::vector<Blueprint::UP> _terms;
public:
- WeightedSetTermBlueprint(const FieldSpec &field);
+ explicit WeightedSetTermBlueprint(const FieldSpec &field);
WeightedSetTermBlueprint(const WeightedSetTermBlueprint &) = delete;
WeightedSetTermBlueprint &operator=(const WeightedSetTermBlueprint &) = delete;
~WeightedSetTermBlueprint() override;
diff --git a/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_search.cpp b/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_search.cpp
index ee3978705cf..8478a0d3c35 100644
--- a/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_search.cpp
+++ b/searchlib/src/vespa/searchlib/queryeval/weighted_set_term_search.cpp
@@ -21,7 +21,7 @@ private:
struct CmpDocId {
const uint32_t *termPos;
- CmpDocId(const uint32_t *tp) : termPos(tp) {}
+ explicit CmpDocId(const uint32_t *tp) : termPos(tp) {}
bool operator()(const ref_t &a, const ref_t &b) const {
return (termPos[a] < termPos[b]);
}
@@ -29,7 +29,7 @@ private:
struct CmpWeight {
const int32_t *weight;
- CmpWeight(const int32_t *w) : weight(w) {}
+ explicit CmpWeight(const int32_t *w) : weight(w) {}
bool operator()(const ref_t &a, const ref_t &b) const {
return (weight[a] > weight[b]);
}
@@ -61,7 +61,7 @@ private:
}
public:
- WeightedSetTermSearchImpl(search::fef::TermFieldMatchData &tmd,
+ WeightedSetTermSearchImpl(fef::TermFieldMatchData &tmd,
bool field_is_filter,
const std::vector<int32_t> &weights,
IteratorPack &&iteratorPack)
@@ -180,7 +180,7 @@ WeightedSetTermSearch::create(const std::vector<SearchIterator *> &children,
//-----------------------------------------------------------------------------
SearchIterator::UP
-WeightedSetTermSearch::create(search::fef::TermFieldMatchData &tmd,
+WeightedSetTermSearch::create(fef::TermFieldMatchData &tmd,
bool field_is_filter,
const std::vector<int32_t> &weights,
std::vector<DocumentWeightIterator> &&iterators)