summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-model-api/abi-spec.json4
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java2
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/OnnxModelCost.java8
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java1
-rw-r--r--container-core/src/main/java/com/yahoo/processing/request/ErrorMessage.java6
-rw-r--r--container-search/abi-spec.json1
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java7
-rw-r--r--container-search/src/main/java/com/yahoo/search/result/ErrorMessage.java8
-rw-r--r--dependency-versions/pom.xml1
-rw-r--r--parent/pom.xml18
-rw-r--r--searchlib/src/tests/query/streaming_query_test.cpp124
-rw-r--r--searchlib/src/vespa/searchlib/query/query_term_simple.cpp146
-rw-r--r--searchlib/src/vespa/searchlib/query/query_term_simple.h59
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/querynode.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/querynoderesultbase.h3
-rw-r--r--streamingvisitors/src/tests/rank_processor/rank_processor_test.cpp2
-rw-r--r--streamingvisitors/src/vespa/searchvisitor/querytermdata.h15
-rw-r--r--streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp114
-rw-r--r--streamingvisitors/src/vespa/searchvisitor/searchvisitor.h13
-rw-r--r--streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp99
-rw-r--r--streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.h17
-rw-r--r--vespa-dependencies-enforcer/allowed-maven-dependencies.txt2
-rw-r--r--zookeeper-server/zookeeper-server/pom.xml8
23 files changed, 341 insertions, 319 deletions
diff --git a/config-model-api/abi-spec.json b/config-model-api/abi-spec.json
index 363ab3918d3..b4bf45d655a 100644
--- a/config-model-api/abi-spec.json
+++ b/config-model-api/abi-spec.json
@@ -1280,9 +1280,7 @@
"public java.util.List ignoredHttpUserAgents()",
"public boolean enableProxyProtocolMixedMode()",
"public java.lang.String logFileCompressionAlgorithm(java.lang.String)",
- "public boolean enableGlobalPhase()",
"public java.lang.String summaryDecodePolicy()",
- "public boolean enableNestedMultivalueGrouping()",
"public int contentLayerMetadataFeatureLevel()",
"public boolean dynamicHeapSize()",
"public java.lang.String unknownConfigDefinition()",
@@ -1459,9 +1457,7 @@
],
"methods" : [
"public abstract long aggregatedModelCostInBytes()",
- "public void registerModel(com.yahoo.config.application.api.ApplicationFile)",
"public abstract void registerModel(com.yahoo.config.application.api.ApplicationFile, com.yahoo.config.model.api.OnnxModelOptions)",
- "public void registerModel(java.net.URI)",
"public abstract void registerModel(java.net.URI, com.yahoo.config.model.api.OnnxModelOptions)",
"public abstract java.util.Map models()",
"public abstract void setRestartOnDeploy()",
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 4ee7b00b79f..31ef1e75acd 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
@@ -106,9 +106,7 @@ public interface ModelContext {
@ModelFeatureFlag(owners = {"arnej", "andreer"}) default List<String> ignoredHttpUserAgents() { return List.of(); }
@ModelFeatureFlag(owners = {"tokle"}) default boolean enableProxyProtocolMixedMode() { return true; }
@ModelFeatureFlag(owners = {"arnej"}) default String logFileCompressionAlgorithm(String defVal) { return defVal; }
- @ModelFeatureFlag(owners = {"arnej, bjorncs"}, removeAfter = "8.262") default boolean enableGlobalPhase() { return true; }
@ModelFeatureFlag(owners = {"baldersheim"}, comment = "Select summary decode type") default String summaryDecodePolicy() { return "eager"; }
- @ModelFeatureFlag(owners = {"baldersheim"}, removeAfter = "8.261") default boolean enableNestedMultivalueGrouping() { return true; }
@ModelFeatureFlag(owners = {"vekterli"}) default int contentLayerMetadataFeatureLevel() { return 0; }
@ModelFeatureFlag(owners = {"bjorncs"}) default boolean dynamicHeapSize() { return false; }
@ModelFeatureFlag(owners = {"hmusum"}) default String unknownConfigDefinition() { return "warn"; }
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/OnnxModelCost.java b/config-model-api/src/main/java/com/yahoo/config/model/api/OnnxModelCost.java
index 69f2b6b6dce..17a0d64aac9 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/OnnxModelCost.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/OnnxModelCost.java
@@ -18,15 +18,7 @@ public interface OnnxModelCost {
interface Calculator {
long aggregatedModelCostInBytes();
- // TODO: Unused, remove when 8.263.7 is oldest model in use
- default void registerModel(ApplicationFile path) {
- registerModel(path, OnnxModelOptions.empty());
- }
void registerModel(ApplicationFile path, OnnxModelOptions onnxModelOptions);
- // TODO: Unused, remove when 8.263.7 is oldest model in use
- default void registerModel(URI uri) {
- registerModel(uri, OnnxModelOptions.empty());
- }
void registerModel(URI uri, OnnxModelOptions onnxModelOptions);
Map<String, ModelInfo> models();
void setRestartOnDeploy();
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
index 2e1c661e09a..6f0254145d6 100644
--- a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
+++ b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
@@ -141,7 +141,6 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
@Override public String summaryDecodePolicy() { return summaryDecodePolicy; }
@Override public Optional<CloudAccount> cloudAccount() { return cloudAccount; }
@Override public boolean allowUserFilters() { return allowUserFilters; }
- @Override public boolean enableGlobalPhase() { return true; } // Enable global-phase by default for unit tests only
@Override public List<DataplaneToken> dataplaneTokens() { return dataplaneTokens; }
@Override public int contentLayerMetadataFeatureLevel() { return contentLayerMetadataFeatureLevel; }
@Override public boolean dynamicHeapSize() { return dynamicHeapSize; }
diff --git a/container-core/src/main/java/com/yahoo/processing/request/ErrorMessage.java b/container-core/src/main/java/com/yahoo/processing/request/ErrorMessage.java
index ca2a00ffe46..9fca0bb0ddb 100644
--- a/container-core/src/main/java/com/yahoo/processing/request/ErrorMessage.java
+++ b/container-core/src/main/java/com/yahoo/processing/request/ErrorMessage.java
@@ -160,7 +160,7 @@ public class ErrorMessage implements Cloneable {
message = getMessage(t);
if (message == null) continue;
if (lastMessage != null && lastMessage.equals(message)) continue;
- if (b.length() > 0)
+ if (!b.isEmpty())
b.append(": ");
b.append(message);
}
@@ -191,9 +191,7 @@ public class ErrorMessage implements Cloneable {
*/
@Override
public boolean equals(Object o) {
- if (!(o instanceof ErrorMessage)) return false;
-
- ErrorMessage other = (ErrorMessage) o;
+ if (!(o instanceof ErrorMessage other)) return false;
if (this.code != other.code) return false;
diff --git a/container-search/abi-spec.json b/container-search/abi-spec.json
index 80833e3e27c..aedccbee46b 100644
--- a/container-search/abi-spec.json
+++ b/container-search/abi-spec.json
@@ -7802,6 +7802,7 @@
"public static com.yahoo.search.result.ErrorMessage createNotFound(java.lang.String)",
"public static com.yahoo.search.result.ErrorMessage createBadRequest(java.lang.String)",
"public static com.yahoo.search.result.ErrorMessage createInternalServerError(java.lang.String)",
+ "public static com.yahoo.search.result.ErrorMessage createInternalServerError(java.lang.String, java.lang.Throwable)",
"public static com.yahoo.search.result.ErrorMessage createSearchReplyError(java.lang.String)",
"public static com.yahoo.search.result.ErrorMessage createDocsumReplyError(java.lang.String)",
"public void setSource(java.lang.String)",
diff --git a/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java b/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
index e20c4271fe0..441c4326355 100644
--- a/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
@@ -270,7 +270,12 @@ public class ClusterSearcher extends Searcher {
Result result = task.get();
mergedResult.mergeWith(result);
mergedResult.hits().addAll(result.hits().asUnorderedHits());
- } catch (ExecutionException | InterruptedException e) {
+ } catch (ExecutionException e) {
+ mergedResult.hits().addError(ErrorMessage.createInternalServerError("Failed querying '" +
+ query.getModel().getRestrict() + "': " +
+ Exceptions.toMessageString(e),
+ e));
+ } catch (InterruptedException e) {
mergedResult.hits().addError(ErrorMessage.createInternalServerError("Failed querying '" +
query.getModel().getRestrict() + "': " +
Exceptions.toMessageString(e)));
diff --git a/container-search/src/main/java/com/yahoo/search/result/ErrorMessage.java b/container-search/src/main/java/com/yahoo/search/result/ErrorMessage.java
index a6f57aa866a..503bbd725c3 100644
--- a/container-search/src/main/java/com/yahoo/search/result/ErrorMessage.java
+++ b/container-search/src/main/java/com/yahoo/search/result/ErrorMessage.java
@@ -163,6 +163,14 @@ public class ErrorMessage extends com.yahoo.processing.request.ErrorMessage {
return new ErrorMessage(INTERNAL_SERVER_ERROR.code, "Internal server error.", detailedMessage);
}
+ /**
+ * Creates an error analog to HTTP internal server error. If this error is present, a
+ * HTTP layer will return 500.
+ */
+ public static ErrorMessage createInternalServerError(String detailedMessage, Throwable cause) {
+ return new ErrorMessage(INTERNAL_SERVER_ERROR.code, "Internal server error.", detailedMessage, cause);
+ }
+
/** Wraps an error message received in a SearchReply packet */
public static ErrorMessage createSearchReplyError(String detailedMessage) {
return new ErrorMessage(RESULT_HAS_ERRORS.code, "Error in search reply.", detailedMessage);
diff --git a/dependency-versions/pom.xml b/dependency-versions/pom.xml
index 4c7f26430ea..7768fdcc52d 100644
--- a/dependency-versions/pom.xml
+++ b/dependency-versions/pom.xml
@@ -114,7 +114,6 @@
<junit.vespa.version>5.10.0</junit.vespa.version>
<junit.platform.vespa.version>1.10.0</junit.platform.vespa.version>
<junit4.vespa.version>4.13.2</junit4.vespa.version>
- <logback.vespa.version>1.2.13</logback.vespa.version>
<luben.zstd.vespa.version>1.5.5-11</luben.zstd.vespa.version>
<lucene.vespa.version>9.9.1</lucene.vespa.version>
<maven-archiver.vespa.version>3.6.1</maven-archiver.vespa.version>
diff --git a/parent/pom.xml b/parent/pom.xml
index 6cc2902136b..3fc520c86c7 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -460,16 +460,6 @@
<version>${huggingface.vespa.version}</version>
</dependency>
<dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <version>${logback.vespa.version}</version>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-core</artifactId>
- <version>${logback.vespa.version}</version>
- </dependency>
- <dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-core</artifactId>
<version>${aws-sdk.vespa.version}</version>
@@ -504,6 +494,14 @@
<artifactId>zookeeper</artifactId>
<version>${zookeeper.client.vespa.version}</version>
<exclusions>
+ <!--
+ Container provides wiring for all common log libraries
+ Duplicate embedding results in various warnings being printed to stderr
+ -->
+ <exclusion>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
diff --git a/searchlib/src/tests/query/streaming_query_test.cpp b/searchlib/src/tests/query/streaming_query_test.cpp
index 08705fa837b..f5370785167 100644
--- a/searchlib/src/tests/query/streaming_query_test.cpp
+++ b/searchlib/src/tests/query/streaming_query_test.cpp
@@ -38,7 +38,7 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, 7);
EXPECT_EQ(ib, 7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, 7);
EXPECT_EQ(db, 7);
}
@@ -48,15 +48,24 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -7);
EXPECT_EQ(ib, -7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7);
EXPECT_EQ(db, -7);
}
+ {
+ QueryTerm q(factory.create(), "+7", "index", TermType::WORD);
+ EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
+ EXPECT_EQ(ia, 7);
+ EXPECT_EQ(ib, 7);
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, 7);
+ EXPECT_EQ(db, 7);
+ }
{
QueryTerm q(factory.create(), "7.5", "index", TermType::WORD);
EXPECT_TRUE(!q.getAsIntegerTerm(ia, ib));
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, 7.5);
EXPECT_EQ(db, 7.5);
}
@@ -64,7 +73,7 @@ TEST(StreamingQueryTest, test_query_language)
{
QueryTerm q(factory.create(), "-7.5", "index", TermType::WORD);
EXPECT_TRUE(!q.getAsIntegerTerm(ia, ib));
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7.5);
EXPECT_EQ(db, -7.5);
}
@@ -74,8 +83,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, 6);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, -std::numeric_limits<double>::max());
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, -std::numeric_limits<double>::infinity());
EXPECT_LT(db, 7);
EXPECT_GT(db, 6.99);
}
@@ -85,8 +94,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, 7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, -std::numeric_limits<double>::max());
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, -std::numeric_limits<double>::infinity());
EXPECT_EQ(db, 7);
}
@@ -95,10 +104,10 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, 8);
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_GT(da, 7);
EXPECT_LT(da, 7.01);
- EXPECT_EQ(db, std::numeric_limits<double>::max());
+ EXPECT_EQ(db, std::numeric_limits<double>::infinity());
}
{
@@ -106,9 +115,9 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, 7);
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, 7);
- EXPECT_EQ(db, std::numeric_limits<double>::max());
+ EXPECT_EQ(db, std::numeric_limits<double>::infinity());
}
{
@@ -116,7 +125,7 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -7);
EXPECT_EQ(ib, 7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7);
EXPECT_EQ(db, 7);
}
@@ -126,7 +135,7 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_FALSE(q.getAsIntegerTerm(ia, ib)); // This is dubious and perhaps a regression.
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7.1);
EXPECT_EQ(db, 7.1);
}
@@ -136,7 +145,7 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_FALSE(q.getAsIntegerTerm(ia, ib)); // This is dubious and perhaps a regression.
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, 500.0);
EXPECT_EQ(db, std::numeric_limits<double>::max());
}
@@ -147,8 +156,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -6);
EXPECT_EQ(ib, 7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, std::nextafterf(minusSeven, seven));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, std::nextafter(minusSeven, seven));
EXPECT_EQ(db, seven);
}
@@ -157,9 +166,9 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -6);
EXPECT_EQ(ib, 6);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, std::nextafterf(minusSeven, seven));
- EXPECT_EQ(db, std::nextafterf(seven, minusSeven));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, std::nextafter(minusSeven, seven));
+ EXPECT_EQ(db, std::nextafter(seven, minusSeven));
}
{
@@ -174,9 +183,9 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -7);
EXPECT_EQ(ib, 6);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, minusSeven);
- EXPECT_EQ(db, std::nextafterf(seven, minusSeven));
+ EXPECT_EQ(db, std::nextafter(seven, minusSeven));
}
{
@@ -184,8 +193,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, -8);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, -std::numeric_limits<double>::max());
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, -std::numeric_limits<double>::infinity());
EXPECT_LT(db, -7);
EXPECT_GT(db, -7.01);
}
@@ -195,8 +204,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, -7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, -std::numeric_limits<double>::max());
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, -std::numeric_limits<double>::infinity());
EXPECT_EQ(db, -7);
}
@@ -205,8 +214,8 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, std::numeric_limits<int64_t>::min());
EXPECT_EQ(ib, -7);
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
- EXPECT_EQ(da, -std::numeric_limits<double>::max());
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
+ EXPECT_EQ(da, -std::numeric_limits<double>::infinity());
EXPECT_EQ(db, -7);
}
@@ -215,10 +224,10 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -6);
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_GT(da, -7);
EXPECT_LT(da, -6.99);
- EXPECT_EQ(db, std::numeric_limits<double>::max());
+ EXPECT_EQ(db, std::numeric_limits<double>::infinity());
}
{
@@ -226,9 +235,9 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -7);
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7);
- EXPECT_EQ(db, std::numeric_limits<double>::max());
+ EXPECT_EQ(db, std::numeric_limits<double>::infinity());
}
{
@@ -236,15 +245,15 @@ TEST(StreamingQueryTest, test_query_language)
EXPECT_TRUE(q.getAsIntegerTerm(ia, ib));
EXPECT_EQ(ia, -7);
EXPECT_EQ(ib, std::numeric_limits<int64_t>::max());
- EXPECT_TRUE(q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(q.getAsFloatTerm(da, db));
EXPECT_EQ(da, -7);
- EXPECT_EQ(db, std::numeric_limits<double>::max());
+ EXPECT_EQ(db, std::numeric_limits<double>::infinity());
}
{
QueryTerm q(factory.create(), "a", "index", TermType::WORD);
EXPECT_TRUE(!q.getAsIntegerTerm(ia, ib));
- EXPECT_TRUE(!q.getAsDoubleTerm(da, db));
+ EXPECT_TRUE(!q.getAsFloatTerm(da, db));
}
{
@@ -287,7 +296,10 @@ TEST(StreamingQueryTest, test_query_language)
class AllowRewrite : public QueryNodeResultFactory
{
public:
- virtual bool getRewriteFloatTerms() const override { return true; }
+ explicit AllowRewrite(vespalib::stringref index) noexcept : _allowedIndex(index) {}
+ bool getRewriteFloatTerms(vespalib::stringref index) const noexcept override { return index == _allowedIndex; }
+private:
+ vespalib::string _allowedIndex;
};
const char TERM_UNIQ = static_cast<char>(ParseItem::ITEM_TERM) | static_cast<char>(ParseItem::IF_UNIQUEID);
@@ -297,12 +309,12 @@ TEST(StreamingQueryTest, e_is_not_rewritten_even_if_allowed)
const char term[6] = {TERM_UNIQ, 3, 1, 'c', 1, 'e'};
vespalib::stringref stackDump(term, sizeof(term));
EXPECT_EQ(6u, stackDump.size());
- AllowRewrite allowRewrite;
+ AllowRewrite allowRewrite("c");
const Query q(allowRewrite, stackDump);
EXPECT_TRUE(q.valid());
const QueryNode & root = q.getRoot();
EXPECT_TRUE(dynamic_cast<const QueryTerm *>(&root) != nullptr);
- const QueryTerm & qt = static_cast<const QueryTerm &>(root);
+ const auto & qt = static_cast<const QueryTerm &>(root);
EXPECT_EQ("c", qt.index());
EXPECT_EQ(vespalib::stringref("e"), qt.getTerm());
EXPECT_EQ(3u, qt.uniqueId());
@@ -313,12 +325,12 @@ TEST(StreamingQueryTest, onedot0e_is_not_rewritten_by_default)
const char term[9] = {TERM_UNIQ, 3, 1, 'c', 4, '1', '.', '0', 'e'};
vespalib::stringref stackDump(term, sizeof(term));
EXPECT_EQ(9u, stackDump.size());
- QueryNodeResultFactory empty;
+ AllowRewrite empty("nix");
const Query q(empty, stackDump);
EXPECT_TRUE(q.valid());
const QueryNode & root = q.getRoot();
EXPECT_TRUE(dynamic_cast<const QueryTerm *>(&root) != nullptr);
- const QueryTerm & qt = static_cast<const QueryTerm &>(root);
+ const auto & qt = static_cast<const QueryTerm &>(root);
EXPECT_EQ("c", qt.index());
EXPECT_EQ(vespalib::stringref("1.0e"), qt.getTerm());
EXPECT_EQ(3u, qt.uniqueId());
@@ -329,34 +341,34 @@ TEST(StreamingQueryTest, onedot0e_is_rewritten_if_allowed_too)
const char term[9] = {TERM_UNIQ, 3, 1, 'c', 4, '1', '.', '0', 'e'};
vespalib::stringref stackDump(term, sizeof(term));
EXPECT_EQ(9u, stackDump.size());
- AllowRewrite empty;
+ AllowRewrite empty("c");
const Query q(empty, stackDump);
EXPECT_TRUE(q.valid());
const QueryNode & root = q.getRoot();
EXPECT_TRUE(dynamic_cast<const EquivQueryNode *>(&root) != nullptr);
- const EquivQueryNode & equiv = static_cast<const EquivQueryNode &>(root);
+ const auto & equiv = static_cast<const EquivQueryNode &>(root);
EXPECT_EQ(2u, equiv.size());
EXPECT_TRUE(dynamic_cast<const QueryTerm *>(equiv[0].get()) != nullptr);
{
- const QueryTerm & qt = static_cast<const QueryTerm &>(*equiv[0]);
+ const auto & qt = static_cast<const QueryTerm &>(*equiv[0]);
EXPECT_EQ("c", qt.index());
EXPECT_EQ(vespalib::stringref("1.0e"), qt.getTerm());
EXPECT_EQ(3u, qt.uniqueId());
}
EXPECT_TRUE(dynamic_cast<const PhraseQueryNode *>(equiv[1].get()) != nullptr);
{
- const PhraseQueryNode & phrase = static_cast<const PhraseQueryNode &>(*equiv[1]);
+ const auto & phrase = static_cast<const PhraseQueryNode &>(*equiv[1]);
EXPECT_EQ(2u, phrase.size());
EXPECT_TRUE(dynamic_cast<const QueryTerm *>(phrase[0].get()) != nullptr);
{
- const QueryTerm & qt = static_cast<const QueryTerm &>(*phrase[0]);
+ const auto & qt = static_cast<const QueryTerm &>(*phrase[0]);
EXPECT_EQ("c", qt.index());
EXPECT_EQ(vespalib::stringref("1"), qt.getTerm());
EXPECT_EQ(0u, qt.uniqueId());
}
EXPECT_TRUE(dynamic_cast<const QueryTerm *>(phrase[1].get()) != nullptr);
{
- const QueryTerm & qt = static_cast<const QueryTerm &>(*phrase[1]);
+ const auto & qt = static_cast<const QueryTerm &>(*phrase[1]);
EXPECT_EQ("c", qt.index());
EXPECT_EQ(vespalib::stringref("0e"), qt.getTerm());
EXPECT_EQ(0u, qt.uniqueId());
@@ -460,7 +472,7 @@ TEST(StreamingQueryTest, test_phrase_evaluate)
terms[1]->add(1, 5, 0, 1);
terms[2]->add(0, 5, 0, 1);
HitList hits;
- PhraseQueryNode * p = static_cast<PhraseQueryNode *>(phrases[0]);
+ auto * p = static_cast<PhraseQueryNode *>(phrases[0]);
p->evaluateHits(hits);
ASSERT_EQ(3u, hits.size());
EXPECT_EQ(hits[0].wordpos(), 2u);
@@ -642,11 +654,11 @@ TEST(StreamingQueryTest, require_that_ascending_range_can_be_specified_with_limi
QueryTerm ascending_query(eqnr.create(), "[;;500]", "index", TermType::WORD);
EXPECT_TRUE(ascending_query.getAsIntegerTerm(low_integer, high_integer));
- EXPECT_TRUE(ascending_query.getAsDoubleTerm(low_double, high_double));
+ EXPECT_TRUE(ascending_query.getAsFloatTerm(low_double, high_double));
EXPECT_EQ(std::numeric_limits<int64_t>::min(), low_integer);
EXPECT_EQ(std::numeric_limits<int64_t>::max(), high_integer);
- EXPECT_EQ(-std::numeric_limits<double>::max(), low_double);
- EXPECT_EQ(std::numeric_limits<double>::max(), high_double);
+ EXPECT_EQ(-std::numeric_limits<double>::infinity(), low_double);
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), high_double);
EXPECT_EQ(500, ascending_query.getRangeLimit());
}
@@ -661,11 +673,11 @@ TEST(StreamingQueryTest, require_that_descending_range_can_be_specified_with_lim
QueryTerm descending_query(eqnr.create(), "[;;-500]", "index", TermType::WORD);
EXPECT_TRUE(descending_query.getAsIntegerTerm(low_integer, high_integer));
- EXPECT_TRUE(descending_query.getAsDoubleTerm(low_double, high_double));
+ EXPECT_TRUE(descending_query.getAsFloatTerm(low_double, high_double));
EXPECT_EQ(std::numeric_limits<int64_t>::min(), low_integer);
EXPECT_EQ(std::numeric_limits<int64_t>::max(), high_integer);
- EXPECT_EQ(-std::numeric_limits<double>::max(), low_double);
- EXPECT_EQ(std::numeric_limits<double>::max(), high_double);
+ EXPECT_EQ(-std::numeric_limits<double>::infinity(), low_double);
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), high_double);
EXPECT_EQ(-500, descending_query.getRangeLimit());
}
@@ -750,7 +762,7 @@ TEST(StreamingQueryTest, require_that_incorrectly_specified_diversity_can_be_par
TEST(StreamingQueryTest, require_that_we_do_not_break_the_stack_on_bad_query)
{
- QueryTermSimple term("<form><iframe+&#09;&#10;&#11;+src=\\\"javascript&#58;alert(1)\\\"&#11;&#10;&#09;;>", TermType::WORD);
+ QueryTermSimple term(R"(<form><iframe+&#09;&#10;&#11;+src=\"javascript&#58;alert(1)\"&#11;&#10;&#09;;>)", TermType::WORD);
EXPECT_FALSE(term.isValid());
}
@@ -759,7 +771,7 @@ TEST(StreamingQueryTest, a_unhandled_sameElement_stack)
const char * stack = "\022\002\026xyz_abcdefghij_xyzxyzxQ\001\vxxxxxx_name\034xxxxxx_xxxx_xxxxxxx_xxxxxxxxE\002\005delta\b<0.00393";
vespalib::stringref stackDump(stack);
EXPECT_EQ(85u, stackDump.size());
- AllowRewrite empty;
+ AllowRewrite empty("");
const Query q(empty, stackDump);
EXPECT_TRUE(q.valid());
const QueryNode & root = q.getRoot();
@@ -793,7 +805,7 @@ TEST(StreamingQueryTest, test_same_element_evaluate)
vespalib::string stackDump = StackDumpCreator::create(*node);
QueryNodeResultFactory empty;
Query q(empty, stackDump);
- SameElementQueryNode * sameElem = dynamic_cast<SameElementQueryNode *>(&q.getRoot());
+ auto * sameElem = dynamic_cast<SameElementQueryNode *>(&q.getRoot());
EXPECT_TRUE(sameElem != nullptr);
EXPECT_EQ("field", sameElem->getIndex());
EXPECT_EQ(3u, sameElem->size());
diff --git a/searchlib/src/vespa/searchlib/query/query_term_simple.cpp b/searchlib/src/vespa/searchlib/query/query_term_simple.cpp
index fb2be58c536..e6cea9c752b 100644
--- a/searchlib/src/vespa/searchlib/query/query_term_simple.cpp
+++ b/searchlib/src/vespa/searchlib/query/query_term_simple.cpp
@@ -4,7 +4,6 @@
#include "base.h"
#include <vespa/vespalib/objects/visit.h>
#include <vespa/vespalib/util/classname.h>
-#include <vespa/vespalib/locale/c.h>
#include <cmath>
#include <limits>
#include <charconv>
@@ -12,11 +11,59 @@
namespace {
template <typename N>
-bool isValidInteger(int64_t value)
+constexpr bool isValidInteger(int64_t value) noexcept
{
- return value >= std::numeric_limits<N>::min() && value <= std::numeric_limits<N>::max();
+ return (value >= std::numeric_limits<N>::min()) &&
+ (value <= std::numeric_limits<N>::max());
}
+constexpr bool isRepresentableByInt64(double d) noexcept {
+ return (d > double(std::numeric_limits<int64_t>::min())) &&
+ (d < double(std::numeric_limits<int64_t>::max()));
+}
+
+bool isFullRange(vespalib::stringref s) noexcept {
+ const size_t sz(s.size());
+ return (sz >= 3u) &&
+ (s[0] == '<' || s[0] == '[') &&
+ (s[sz-1] == '>' || s[sz-1] == ']');
+}
+
+struct IntDecoder {
+ static int64_t fromstr(const char * q, const char * qend, const char ** end) noexcept {
+ int64_t v(0);
+ for (;q < qend && (isspace(*q) || (*q == '+')); q++);
+ std::from_chars_result err = std::from_chars(q, qend, v, 10);
+ if (err.ec == std::errc::result_out_of_range) {
+ v = (*q == '-') ? std::numeric_limits<int64_t>::min() : std::numeric_limits<int64_t>::max();
+ }
+ *end = err.ptr;
+ return v;
+ }
+ static int64_t nearestDownwd(int64_t n, int64_t min) noexcept { return (n > min ? n - 1 : n); }
+ static int64_t nearestUpward(int64_t n, int64_t max) noexcept { return (n < max ? n + 1 : n); }
+};
+
+template <typename T>
+struct FloatDecoder {
+ static T fromstr(const char * q, const char * qend, const char ** end) noexcept {
+ T v(0);
+ for (;q < qend && (isspace(*q) || (*q == '+')); q++);
+ std::from_chars_result err = std::from_chars(q, qend, v);
+ if (err.ec == std::errc::result_out_of_range) {
+ v = (*q == '-') ? -std::numeric_limits<T>::infinity() : std::numeric_limits<T>::infinity();
+ }
+ *end = err.ptr;
+ return v;
+ }
+ static T nearestDownwd(T n, T min) noexcept {
+ return std::nextafter(n, min);
+ }
+ static T nearestUpward(T n, T max) noexcept {
+ return std::nextafter(n, max);
+ }
+};
+
}
namespace search {
@@ -30,15 +77,15 @@ QueryTermSimple::visitMembers(vespalib::ObjectVisitor & visitor) const
template <typename N>
QueryTermSimple::RangeResult<N>
-QueryTermSimple::getFloatRange() const
+QueryTermSimple::getFloatRange() const noexcept
{
- double lowRaw, highRaw;
- bool valid = getAsDoubleTerm(lowRaw, highRaw);
+ N lowRaw, highRaw;
+ bool valid = getAsFloatTerm(lowRaw, highRaw);
RangeResult<N> res;
res.valid = valid;
if (!valid) {
- res.low = std::numeric_limits<N>::max();
- res.high = - std::numeric_limits<N>::max();
+ res.low = std::numeric_limits<N>::infinity();
+ res.high = -std::numeric_limits<N>::infinity();
res.adjusted = true;
} else {
res.low = lowRaw;
@@ -47,25 +94,16 @@ QueryTermSimple::getFloatRange() const
return res;
}
-namespace {
-
-bool isRepresentableByInt64(double d) {
- return (d > double(std::numeric_limits<int64_t>::min()))
- && (d < double(std::numeric_limits<int64_t>::max()));
-}
-
-}
-
bool
-QueryTermSimple::getRangeInternal(int64_t & low, int64_t & high) const
+QueryTermSimple::getRangeInternal(int64_t & low, int64_t & high) const noexcept
{
bool valid = getAsIntegerTerm(low, high);
if ( ! valid ) {
double l(0), h(0);
- valid = getAsDoubleTerm(l, h);
+ valid = getAsFloatTerm(l, h);
if (valid) {
if ((l == h) && isRepresentableByInt64(l)) {
- low = high = std::round(l);
+ low = high = static_cast<int64_t>(std::round(l));
} else {
if (l > double(std::numeric_limits<int64_t>::min())) {
if (l < double(std::numeric_limits<int64_t>::max())) {
@@ -89,7 +127,7 @@ QueryTermSimple::getRangeInternal(int64_t & low, int64_t & high) const
template <typename N>
QueryTermSimple::RangeResult<N>
-QueryTermSimple::getIntegerRange() const
+QueryTermSimple::getIntegerRange() const noexcept
{
int64_t lowRaw, highRaw;
bool valid = getRangeInternal(lowRaw, highRaw);
@@ -122,94 +160,72 @@ QueryTermSimple::getIntegerRange() const
template <>
QueryTermSimple::RangeResult<float>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getFloatRange<float>();
}
template <>
QueryTermSimple::RangeResult<double>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getFloatRange<double>();
}
template <>
QueryTermSimple::RangeResult<int8_t>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getIntegerRange<int8_t>();
}
template <>
QueryTermSimple::RangeResult<int16_t>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getIntegerRange<int16_t>();
}
template <>
QueryTermSimple::RangeResult<int32_t>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getIntegerRange<int32_t>();
}
template <>
QueryTermSimple::RangeResult<int64_t>
-QueryTermSimple::getRange() const
+QueryTermSimple::getRange() const noexcept
{
return getIntegerRange<int64_t>();
}
-struct IntDecoder {
- static int64_t fromstr(const char * q, const char * qend, char ** end) noexcept {
- int64_t v(0);
- for (;q < qend && isspace(*q); q++);
- std::from_chars_result err = std::from_chars(q, qend, v, 10);
- if (err.ec == std::errc::result_out_of_range) {
- v = (*q == '-') ? std::numeric_limits<int64_t>::min() : std::numeric_limits<int64_t>::max();
- }
- *end = const_cast<char *>(err.ptr);
- return v;
- }
- static int64_t nearestDownwd(int64_t n, int64_t min) noexcept { return (n > min ? n - 1 : n); }
- static int64_t nearestUpward(int64_t n, int64_t max) noexcept { return (n < max ? n + 1 : n); }
-};
-
-struct DoubleDecoder {
- static double fromstr(const char * q, const char * qend, char ** end) {
- (void) qend;
- return vespalib::locale::c::strtod(q, end);
- }
- static double nearestDownwd(double n, double min) noexcept { return std::nextafterf(n, min); }
- static double nearestUpward(double n, double max) noexcept { return std::nextafterf(n, max); }
-};
-
-bool QueryTermSimple::getAsIntegerTerm(int64_t & lower, int64_t & upper) const
+bool QueryTermSimple::getAsIntegerTerm(int64_t & lower, int64_t & upper) const noexcept
{
lower = std::numeric_limits<int64_t>::min();
upper = std::numeric_limits<int64_t>::max();
return getAsNumericTerm(lower, upper, IntDecoder());
}
-bool QueryTermSimple::getAsDoubleTerm(double & lower, double & upper) const
+bool QueryTermSimple::getAsFloatTerm(double & lower, double & upper) const noexcept
+{
+ lower = -std::numeric_limits<double>::infinity();
+ upper = std::numeric_limits<double>::infinity();
+ return getAsNumericTerm(lower, upper, FloatDecoder<double>());
+}
+
+bool QueryTermSimple::getAsFloatTerm(float & lower, float & upper) const noexcept
{
- lower = - std::numeric_limits<double>::max();
- upper = std::numeric_limits<double>::max();
- return getAsNumericTerm(lower, upper, DoubleDecoder());
+ lower = -std::numeric_limits<float>::infinity();
+ upper = std::numeric_limits<float>::infinity();
+ return getAsNumericTerm(lower, upper, FloatDecoder<float>());
}
QueryTermSimple::~QueryTermSimple() = default;
namespace {
-bool isFullRange(vespalib::stringref s) {
- const size_t sz(s.size());
- return (sz >= 3u) &&
- (s[0] == '<' || s[0] == '[') &&
- (s[sz-1] == '>' || s[sz-1] == ']');
-}
+
}
@@ -244,7 +260,7 @@ QueryTermSimple::QueryTermSimple(const string & term_, Type type)
}
_valid = (numParts >= 2) && (numParts < NELEMS(parts));
if (_valid && numParts > 2) {
- _rangeLimit = strtol(parts[2].data(), nullptr, 0);
+ _rangeLimit = static_cast<int32_t>(strtol(parts[2].data(), nullptr, 0));
if (numParts > 3) {
_valid = (numParts >= 5);
if (_valid) {
@@ -269,12 +285,12 @@ QueryTermSimple::QueryTermSimple(const string & term_, Type type)
template <typename T, typename D>
bool
-QueryTermSimple::getAsNumericTerm(T & lower, T & upper, D d) const
+QueryTermSimple::getAsNumericTerm(T & lower, T & upper, D d) const noexcept
{
if (empty()) return false;
size_t sz(_term.size());
- char *err(nullptr);
+ const char *err(nullptr);
T low(lower);
T high(upper);
const char * q = _term.c_str();
diff --git a/searchlib/src/vespa/searchlib/query/query_term_simple.h b/searchlib/src/vespa/searchlib/query/query_term_simple.h
index 2b64e3812ab..87bf7c26b80 100644
--- a/searchlib/src/vespa/searchlib/query/query_term_simple.h
+++ b/searchlib/src/vespa/searchlib/query/query_term_simple.h
@@ -33,8 +33,8 @@ public:
N high;
bool valid; // Whether parsing of the range was successful
bool adjusted; // Whether the low and high was adjusted according to min and max limits of the given type.
- RangeResult() : low(), high(), valid(true), adjusted(false) {}
- bool isEqual() const { return low == high; }
+ RangeResult() noexcept : low(), high(), valid(true), adjusted(false) {}
+ bool isEqual() const noexcept { return low == high; }
};
QueryTermSimple(const QueryTermSimple &) = delete;
@@ -47,39 +47,40 @@ public:
* Extracts the content of this query term as a range with low and high values.
*/
template <typename N>
- RangeResult<N> getRange() const;
- int getRangeLimit() const { return _rangeLimit; }
- size_t getMaxPerGroup() const { return _maxPerGroup; }
- size_t getDiversityCutoffGroups() const { return _diversityCutoffGroups; }
- bool getDiversityCutoffStrict() const { return _diversityCutoffStrict; }
- vespalib::stringref getDiversityAttribute() const { return _diversityAttribute; }
- size_t getFuzzyMaxEditDistance() const { return _fuzzyMaxEditDistance; }
- size_t getFuzzyPrefixLength() const { return _fuzzyPrefixLength; }
- bool getAsIntegerTerm(int64_t & lower, int64_t & upper) const;
- bool getAsDoubleTerm(double & lower, double & upper) const;
- const char * getTerm() const { return _term.c_str(); }
- bool isPrefix() const { return (_type == Type::PREFIXTERM); }
- bool isSubstring() const { return (_type == Type::SUBSTRINGTERM); }
- bool isExactstring() const { return (_type == Type::EXACTSTRINGTERM); }
- bool isSuffix() const { return (_type == Type::SUFFIXTERM); }
- bool isWord() const { return (_type == Type::WORD); }
- bool isRegex() const { return (_type == Type::REGEXP); }
- bool isGeoLoc() const { return (_type == Type::GEO_LOCATION); }
- bool isFuzzy() const { return (_type == Type::FUZZYTERM); }
+ RangeResult<N> getRange() const noexcept;
+ int getRangeLimit() const noexcept { return _rangeLimit; }
+ size_t getMaxPerGroup() const noexcept { return _maxPerGroup; }
+ size_t getDiversityCutoffGroups() const noexcept { return _diversityCutoffGroups; }
+ bool getDiversityCutoffStrict() const noexcept { return _diversityCutoffStrict; }
+ vespalib::stringref getDiversityAttribute() const noexcept { return _diversityAttribute; }
+ size_t getFuzzyMaxEditDistance() const noexcept { return _fuzzyMaxEditDistance; }
+ size_t getFuzzyPrefixLength() const noexcept { return _fuzzyPrefixLength; }
+ bool getAsIntegerTerm(int64_t & lower, int64_t & upper) const noexcept;
+ bool getAsFloatTerm(double & lower, double & upper) const noexcept;
+ bool getAsFloatTerm(float & lower, float & upper) const noexcept;
+ const char * getTerm() const noexcept { return _term.c_str(); }
+ bool isPrefix() const noexcept { return (_type == Type::PREFIXTERM); }
+ bool isSubstring() const noexcept { return (_type == Type::SUBSTRINGTERM); }
+ bool isExactstring() const noexcept { return (_type == Type::EXACTSTRINGTERM); }
+ bool isSuffix() const noexcept { return (_type == Type::SUFFIXTERM); }
+ bool isWord() const noexcept { return (_type == Type::WORD); }
+ bool isRegex() const noexcept { return (_type == Type::REGEXP); }
+ bool isGeoLoc() const noexcept { return (_type == Type::GEO_LOCATION); }
+ bool isFuzzy() const noexcept { return (_type == Type::FUZZYTERM); }
bool is_nearest_neighbor() const noexcept { return (_type == Type::NEAREST_NEIGHBOR); }
- bool empty() const { return _term.empty(); }
+ bool empty() const noexcept { return _term.empty(); }
virtual void visitMembers(vespalib::ObjectVisitor &visitor) const;
vespalib::string getClassName() const;
- bool isValid() const { return _valid; }
- const string & getTermString() const { return _term; }
+ bool isValid() const noexcept { return _valid; }
+ const string & getTermString() const noexcept { return _term; }
private:
- bool getRangeInternal(int64_t & low, int64_t & high) const;
+ bool getRangeInternal(int64_t & low, int64_t & high) const noexcept;
template <typename N>
- RangeResult<N> getIntegerRange() const;
+ RangeResult<N> getIntegerRange() const noexcept;
template <typename N>
- RangeResult<N> getFloatRange() const;
- int _rangeLimit;
+ RangeResult<N> getFloatRange() const noexcept;
+ int32_t _rangeLimit;
uint32_t _maxPerGroup;
uint32_t _diversityCutoffGroups;
Type _type;
@@ -88,7 +89,7 @@ private:
string _term;
stringref _diversityAttribute;
template <typename T, typename D>
- bool getAsNumericTerm(T & lower, T & upper, D d) const;
+ bool getAsNumericTerm(T & lower, T & upper, D d) const noexcept;
protected:
uint32_t _fuzzyMaxEditDistance; // set in QueryTerm
diff --git a/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp b/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp
index 6b3aa7a2fd0..9484999f45a 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp
+++ b/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp
@@ -156,7 +156,7 @@ QueryNode::Build(const QueryNode * parent, const QueryNodeResultFactory & factor
qt->setFuzzyMaxEditDistance(queryRep.getFuzzyMaxEditDistance());
qt->setFuzzyPrefixLength(queryRep.getFuzzyPrefixLength());
}
- if (possibleFloat(*qt, ssTerm) && factory.getRewriteFloatTerms() && allowRewrite) {
+ if (allowRewrite && possibleFloat(*qt, ssTerm) && factory.getRewriteFloatTerms(ssIndex)) {
auto phrase = std::make_unique<PhraseQueryNode>();
auto dotPos = ssTerm.find('.');
phrase->addChild(std::make_unique<QueryTerm>(factory.create(), ssTerm.substr(0, dotPos), ssIndex, TermType::WORD));
diff --git a/searchlib/src/vespa/searchlib/query/streaming/querynoderesultbase.h b/searchlib/src/vespa/searchlib/query/streaming/querynoderesultbase.h
index 10f3b7cbf21..d7704fb60e1 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/querynoderesultbase.h
+++ b/searchlib/src/vespa/searchlib/query/streaming/querynoderesultbase.h
@@ -1,6 +1,7 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
+#include <vespa/vespalib/stllike/string.h>
#include <memory>
namespace search::streaming {
@@ -20,7 +21,7 @@ public:
class QueryNodeResultFactory {
public:
virtual ~QueryNodeResultFactory() = default;
- virtual bool getRewriteFloatTerms() const { return false; }
+ virtual bool getRewriteFloatTerms(vespalib::stringref index) const noexcept { (void) index; return false; }
virtual std::unique_ptr<QueryNodeResultBase> create() const { return {}; }
};
}
diff --git a/streamingvisitors/src/tests/rank_processor/rank_processor_test.cpp b/streamingvisitors/src/tests/rank_processor/rank_processor_test.cpp
index 2d138d1d336..93e35e4c6d2 100644
--- a/streamingvisitors/src/tests/rank_processor/rank_processor_test.cpp
+++ b/streamingvisitors/src/tests/rank_processor/rank_processor_test.cpp
@@ -40,7 +40,7 @@ protected:
RankProcessorTest::RankProcessorTest()
: testing::Test(),
- _factory(),
+ _factory(nullptr),
_query(),
_query_wrapper()
{
diff --git a/streamingvisitors/src/vespa/searchvisitor/querytermdata.h b/streamingvisitors/src/vespa/searchvisitor/querytermdata.h
index 8c1c3771917..36176f70d1d 100644
--- a/streamingvisitors/src/vespa/searchvisitor/querytermdata.h
+++ b/streamingvisitors/src/vespa/searchvisitor/querytermdata.h
@@ -17,15 +17,26 @@ private:
search::fef::SimpleTermData _termData;
public:
QueryTermData * clone() const override { return new QueryTermData(); }
- search::fef::SimpleTermData &getTermData() { return _termData; }
+ search::fef::SimpleTermData &getTermData() noexcept { return _termData; }
+};
+
+class SearchMethodInfo {
+public:
+ virtual ~SearchMethodInfo() = default;
+ virtual bool is_text_matching(vespalib::stringref index) const noexcept = 0;
};
class QueryTermDataFactory final : public search::streaming::QueryNodeResultFactory {
public:
+ QueryTermDataFactory(const SearchMethodInfo * searchMethodInfo) noexcept : _searchMethodInfo(searchMethodInfo) {}
std::unique_ptr<search::streaming::QueryNodeResultBase> create() const override {
return std::make_unique<QueryTermData>();
}
- bool getRewriteFloatTerms() const override { return true; }
+ bool getRewriteFloatTerms(vespalib::stringref index ) const noexcept override {
+ return _searchMethodInfo && _searchMethodInfo->is_text_matching(index);
+ }
+private:
+ const SearchMethodInfo * _searchMethodInfo;
};
diff --git a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp
index 4d31c71c0a0..49604135afc 100644
--- a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp
+++ b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.cpp
@@ -91,7 +91,7 @@ ForceWordfolderInit::ForceWordfolderInit()
Fast_NormalizeWordFolder::DO_MULTICHAR_EXPANSION);
}
-static ForceWordfolderInit _G_forceNormWordFolderInit;
+static ForceWordfolderInit G_forceNormWordFolderInit;
// Leftovers from FS4 protocol with limited use here.
enum queryflags {
@@ -238,14 +238,16 @@ SearchVisitor::SummaryGenerator::fillSummary(AttributeVector::DocId lid, const H
return {};
}
-void SearchVisitor::HitsResultPreparator::execute(vespalib::Identifiable & obj)
+void
+SearchVisitor::HitsResultPreparator::execute(vespalib::Identifiable & obj)
{
auto & hitsAggr(static_cast<HitsAggregationResult &>(obj));
hitsAggr.setSummaryGenerator(_summaryGenerator);
_numHitsAggregators++;
}
-bool SearchVisitor::HitsResultPreparator::check(const vespalib::Identifiable & obj) const
+bool
+SearchVisitor::HitsResultPreparator::check(const vespalib::Identifiable & obj) const
{
return obj.getClass().inherits(HitsAggregationResult::classId);
}
@@ -259,7 +261,8 @@ SearchVisitor::GroupingEntry::GroupingEntry(Grouping * grouping) :
SearchVisitor::GroupingEntry::~GroupingEntry() = default;
-void SearchVisitor::GroupingEntry::aggregate(const document::Document & doc, search::HitRank rank)
+void
+SearchVisitor::GroupingEntry::aggregate(const document::Document & doc, search::HitRank rank)
{
if (_count < _limit) {
_grouping->aggregate(doc, rank);
@@ -310,7 +313,21 @@ SearchVisitor::SearchVisitor(StorageComponent& component,
LOG(debug, "Created SearchVisitor");
}
-void SearchVisitor::init(const Parameters & params)
+bool
+SearchVisitor::is_text_matching(vespalib::stringref index) const noexcept {
+ StringFieldIdTMap fieldIdMap;
+ _fieldSearchSpecMap.addFieldsFromIndex(index, fieldIdMap);
+ for (const auto & fieldId : fieldIdMap.map()) {
+ auto found = _fieldSearchSpecMap.specMap().find(fieldId.second);
+ if ((found != _fieldSearchSpecMap.specMap().end()) && found->second.uses_string_search_method()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void
+SearchVisitor::init(const Parameters & params)
{
VISITOR_TRACE(6, "About to lazily init VSM adapter");
_attrMan.add(_documentIdAttributeBacking);
@@ -397,7 +414,14 @@ void SearchVisitor::init(const Parameters & params)
if ( params.lookup("query", queryBlob) ) {
LOG(spam, "Received query blob of %zu bytes", queryBlob.size());
VISITOR_TRACE(9, vespalib::make_string("Setting up for query blob of %zu bytes", queryBlob.size()));
- QueryTermDataFactory addOnFactory;
+ // Create mapping from field name to field id, from field id to search spec,
+ // and from index name to list of field ids
+ _fieldSearchSpecMap.buildFromConfig(_env->get_vsm_fields_config());
+ auto additionalFields = registerAdditionalFields(_env->get_docsum_tools()->getFieldSpecs());
+ // Add extra elements to mapping from field name to field id
+ _fieldSearchSpecMap.buildFromConfig(additionalFields);
+
+ QueryTermDataFactory addOnFactory(this);
_query = Query(addOnFactory, vespalib::stringref(queryBlob.data(), queryBlob.size()));
_searchBuffer->reserve(0x10000);
@@ -408,19 +432,11 @@ void SearchVisitor::init(const Parameters & params)
LOG(warning, "Request without query stack count");
}
- std::vector<vespalib::string> additionalFields;
- registerAdditionalFields(_env->get_docsum_tools()->getFieldSpecs(), additionalFields);
-
- StringFieldIdTMap fieldsInQuery;
- setupFieldSearchers(additionalFields, fieldsInQuery);
-
-
+ StringFieldIdTMap fieldsInQuery = setupFieldSearchers();
setupScratchDocument(fieldsInQuery);
-
_syntheticFieldsController.setup(_fieldSearchSpecMap.nameIdMap(), fieldsInQuery);
setupAttributeVectors();
-
setupAttributeVectorsForSorting(_sortSpec);
_rankController.setRankManagerSnapshot(_env->get_rank_manager_snapshot());
@@ -436,7 +452,6 @@ void SearchVisitor::init(const Parameters & params)
// This depends on _fieldPathMap (from setupScratchDocument),
// and IQueryEnvironment (from setupRankProcessors).
prepare_field_searchers();
-
} else {
LOG(warning, "No query received");
}
@@ -529,10 +544,7 @@ SearchVisitor::PositionInserter::PositionInserter(AttributeVector & attribute, A
SearchVisitor::PositionInserter::~PositionInserter() = default;
void
-SearchVisitor::PositionInserter::onPrimitive(uint32_t, const Content & c)
-{
- (void) c;
-}
+SearchVisitor::PositionInserter::onPrimitive(uint32_t, const Content &) { }
void
SearchVisitor::PositionInserter::onStructStart(const Content & c)
@@ -605,7 +617,6 @@ SearchVisitor::RankController::setupRankProcessors(Query & query,
{
_rankSetup = &_rankManagerSnapshot->getRankSetup(_rankProfile);
_rankProcessor = std::make_unique<RankProcessor>(_rankManagerSnapshot, _rankProfile, query, location, _queryProperties, &attrMan);
- LOG(debug, "Initialize rank processor");
_rankProcessor->initForRanking(wantedHitCount);
// register attribute vectors needed for ranking
processAccessedAttributes(_rankProcessor->get_real_query_env(), true, attrMan, attributeFields);
@@ -637,8 +648,7 @@ SearchVisitor::RankController::rankMatchedDocument(uint32_t docId)
{
_rankProcessor->runRankProgram(docId);
LOG(debug, "Rank score for matched document %u: %f",
- docId,
- _rankProcessor->getRankScore());
+ docId, _rankProcessor->getRankScore());
if (_dumpFeatures) {
_dumpProcessor->runRankProgram(docId);
// we must transfer the score to this match data to make sure that the same hits
@@ -718,9 +728,8 @@ SearchVisitor::SyntheticFieldsController::setup(const StringFieldIdTMap & fieldR
}
void
-SearchVisitor::SyntheticFieldsController::onDocument(StorageDocument & document)
+SearchVisitor::SyntheticFieldsController::onDocument(StorageDocument &)
{
- (void) document;
}
void
@@ -730,10 +739,10 @@ SearchVisitor::SyntheticFieldsController::onDocumentMatch(StorageDocument & docu
document.setField(_documentIdFId, std::make_unique<document::StringFieldValue>(documentId));
}
-void
-SearchVisitor::registerAdditionalFields(const std::vector<vsm::DocsumTools::FieldSpec> & docsumSpec,
- std::vector<vespalib::string> & fieldList)
+std::vector<vespalib::string>
+SearchVisitor::registerAdditionalFields(const std::vector<vsm::DocsumTools::FieldSpec> & docsumSpec)
{
+ std::vector<vespalib::string> fieldList;
for (const vsm::DocsumTools::FieldSpec & spec : docsumSpec) {
fieldList.push_back(spec.getOutputName());
const std::vector<vespalib::string> & inputNames = spec.getInputNames();
@@ -748,25 +757,20 @@ SearchVisitor::registerAdditionalFields(const std::vector<vsm::DocsumTools::Fiel
fieldList.emplace_back("[docid]");
fieldList.emplace_back("[rank]");
fieldList.emplace_back("documentid");
+ return fieldList;
}
-void
-SearchVisitor::setupFieldSearchers(const std::vector<vespalib::string> & additionalFields,
- StringFieldIdTMap & fieldsInQuery)
+StringFieldIdTMap
+SearchVisitor::setupFieldSearchers()
{
- // Create mapping from field name to field id, from field id to search spec,
- // and from index name to list of field ids
- _fieldSearchSpecMap.buildFromConfig(_env->get_vsm_fields_config());
- // Add extra elements to mapping from field name to field id
- _fieldSearchSpecMap.buildFromConfig(additionalFields);
-
// Reconfig field searchers based on the query
_fieldSearchSpecMap.reconfigFromQuery(_query);
// Map field name to field id for all fields in the query
- _fieldSearchSpecMap.buildFieldsInQuery(_query, fieldsInQuery);
+ StringFieldIdTMap fieldsInQuery = _fieldSearchSpecMap.buildFieldsInQuery(_query);
// Connect field names in the query to field searchers
_fieldSearchSpecMap.buildSearcherMap(fieldsInQuery.map(), _fieldSearcherMap);
+ return fieldsInQuery;
}
void
@@ -947,8 +951,7 @@ class SingleDocumentStore : public vsm::IDocSumCache
{
public:
explicit SingleDocumentStore(const StorageDocument & doc) : _doc(doc) { }
- const vsm::Document & getDocSum(const search::DocumentIdT & docId) const override {
- (void) docId;
+ const vsm::Document & getDocSum(const search::DocumentIdT &) const override {
return _doc;
}
private:
@@ -959,19 +962,12 @@ bool
SearchVisitor::compatibleDocumentTypes(const document::DocumentType& typeA,
const document::DocumentType& typeB)
{
- if (&typeA == &typeB) {
- return true;
- } else {
- return (typeA.getName() == typeB.getName());
- }
+ return (&typeA == &typeB) || (typeA.getName() == typeB.getName());
}
void
-SearchVisitor::handleDocuments(const document::BucketId&,
- DocEntryList & entries,
- HitCounter& hitCounter)
+SearchVisitor::handleDocuments(const document::BucketId&, DocEntryList & entries, HitCounter& )
{
- (void) hitCounter;
if (!_init_called) {
init(_params);
}
@@ -1016,37 +1012,25 @@ SearchVisitor::handleDocument(StorageDocument & document)
RankProcessor & rp = *_rankController.getRankProcessor();
vespalib::string documentId(document.docDoc().getId().getScheme().toString());
LOG(debug, "Matched document with id '%s'", documentId.c_str());
-
document.setDocId(rp.getDocId());
-
fillAttributeVectors(documentId, document);
-
_rankController.rankMatchedDocument(rp.getDocId());
-
if (_shouldFillRankAttribute) {
_rankAttribute.add(rp.getRankScore());
}
-
if (_rankController.keepMatchedDocument()) {
-
bool amongTheBest = _rankController.collectMatchedDocument(!_sortList.empty(), *this, _tmpSortBuffer, &document);
-
_syntheticFieldsController.onDocumentMatch(document, documentId);
-
SingleDocumentStore single(document);
_summaryGenerator.setDocsumCache(single);
group(document.docDoc(), rp.getRankScore(), false);
-
if (amongTheBest) {
needToKeepDocument = true;
}
-
} else {
_hitsRejectedCount++;
LOG(debug, "Do not keep document with id '%s' because rank score (%f) <= rank score drop limit (%f)",
- documentId.c_str(),
- rp.getRankScore(),
- _rankController.getRankSetup()->getRankScoreDropLimit());
+ documentId.c_str(), rp.getRankScore(), _rankController.getRankSetup()->getRankScoreDropLimit());
}
} else {
LOG(debug, "Did not match document with id '%s'", document.docDoc().getId().getScheme().toString().c_str());
@@ -1145,7 +1129,8 @@ SearchVisitor::fillSortBuffer()
return pos;
}
-void SearchVisitor::completedBucket(const document::BucketId&, HitCounter&)
+void
+SearchVisitor::completedBucket(const document::BucketId&, HitCounter&)
{
LOG(debug, "Completed bucket");
}
@@ -1157,7 +1142,8 @@ SearchVisitor::generate_query_result(HitCounter& counter)
return std::move(_queryResult);
}
-void SearchVisitor::completedVisitingInternal(HitCounter& hitCounter)
+void
+SearchVisitor::completedVisitingInternal(HitCounter& hitCounter)
{
if (!_init_called) {
init(_params);
diff --git a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.h b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.h
index ef7a41f23a5..709564bcf02 100644
--- a/streamingvisitors/src/vespa/searchvisitor/searchvisitor.h
+++ b/streamingvisitors/src/vespa/searchvisitor/searchvisitor.h
@@ -8,6 +8,7 @@
#include "rankmanager.h"
#include "rankprocessor.h"
#include "searchenvironment.h"
+#include "querytermdata.h"
#include <vespa/vsm/common/docsum.h>
#include <vespa/vsm/common/documenttypemapping.h>
#include <vespa/vsm/common/storagedocument.h>
@@ -42,7 +43,8 @@ class SearchEnvironmentSnapshot;
* @brief Visitor that applies a search query to visitor data and
* converts them to a QueryResultCommand.
**/
-class SearchVisitor : public storage::Visitor {
+class SearchVisitor : public storage::Visitor,
+ public SearchMethodInfo {
public:
SearchVisitor(storage::StorageComponent&, storage::VisitorEnvironment& vEnv,
const vdslib::Parameters & params);
@@ -253,19 +255,15 @@ private:
* @param docsumSpec config with the field names used by the docsum setup.
* @param fieldList list of field names that are built.
**/
- static void registerAdditionalFields(const std::vector<vsm::DocsumTools::FieldSpec> & docsumSpec,
- std::vector<vespalib::string> & fieldList);
+ static std::vector<vespalib::string> registerAdditionalFields(const std::vector<vsm::DocsumTools::FieldSpec> & docsumSpec);
/**
* Setup the field searchers used when matching the query with the stream of documents.
* This includes setting up various mappings in FieldSearchSpecMap and building mapping
* for fields used by the query.
*
- * @param additionalFields list of additional field names used when setting up the mappings.
- * @param fieldsInQuery mapping from field name to field id that are built based on the query.
**/
- void setupFieldSearchers(const std::vector<vespalib::string> & additionalFields,
- vsm::StringFieldIdTMap & fieldsInQuery);
+ vsm::StringFieldIdTMap setupFieldSearchers();
/**
* Prepare the field searchers for the given query.
@@ -488,6 +486,7 @@ private:
vsm::StringFieldIdTMapT _fieldsUnion;
void setupAttributeVector(const vsm::FieldPath &fieldPath);
+ bool is_text_matching(vespalib::stringref index) const noexcept override;
};
class SearchVisitorFactory : public storage::VisitorFactory {
diff --git a/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp b/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp
index e33408a2e26..4b0efd58a56 100644
--- a/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp
+++ b/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.cpp
@@ -28,7 +28,8 @@ namespace vsm {
namespace {
-void setMatchType(FieldSearcherContainer & searcher, vespalib::stringref arg1) {
+void
+setMatchType(FieldSearcherContainer & searcher, vespalib::stringref arg1) {
if (arg1 == "prefix") {
searcher->setMatchType(FieldSearcher::PREFIX);
} else if (arg1 == "substring") {
@@ -44,14 +45,14 @@ void setMatchType(FieldSearcherContainer & searcher, vespalib::stringref arg1) {
}
-FieldSearchSpec::FieldSearchSpec() :
- _id(0),
- _name(),
- _maxLength(0x100000),
- _searcher(),
- _searchMethod(VsmfieldsConfig::Fieldspec::Searchmethod::NONE),
- _arg1(),
- _reconfigured(false)
+FieldSearchSpec::FieldSearchSpec()
+ : _id(0),
+ _name(),
+ _maxLength(0x100000),
+ _searcher(),
+ _searchMethod(VsmfieldsConfig::Fieldspec::Searchmethod::NONE),
+ _arg1(),
+ _reconfigured(false)
{
}
FieldSearchSpec::~FieldSearchSpec() = default;
@@ -150,7 +151,8 @@ FieldSearchSpec::reconfig(const QueryTerm & term)
}
}
-vespalib::asciistream & operator <<(vespalib::asciistream & os, const FieldSearchSpec & f)
+vespalib::asciistream &
+operator <<(vespalib::asciistream & os, const FieldSearchSpec & f)
{
os << f._id << ' ' << f._name << ' ';
if ( ! f._searcher) {
@@ -171,7 +173,8 @@ namespace {
const std::regex _G_array("\\[[0-9]+\\]");
}
-vespalib::string FieldSearchSpecMap::stripNonFields(const vespalib::string & rawIndex)
+vespalib::string
+FieldSearchSpecMap::stripNonFields(vespalib::stringref rawIndex)
{
if ((rawIndex.find('[') != vespalib::string::npos) || (rawIndex.find('{') != vespalib::string::npos)) {
std::string index = std::regex_replace(std::string(rawIndex), _G_map1, _G_value);
@@ -182,44 +185,48 @@ vespalib::string FieldSearchSpecMap::stripNonFields(const vespalib::string & raw
return rawIndex;
}
-bool FieldSearchSpecMap::buildFieldsInQuery(const Query & query, StringFieldIdTMap & fieldsInQuery) const
+void
+FieldSearchSpecMap::addFieldsFromIndex(vespalib::stringref rawIndex, StringFieldIdTMap & fieldIdMap) const {
+ for (const auto & dtm : documentTypeMap()) {
+ const IndexFieldMapT & fim = dtm.second;
+ vespalib::string index(stripNonFields(rawIndex));
+ auto fIt = fim.find(index);
+ if (fIt != fim.end()) {
+ for(FieldIdT fid : fIt->second) {
+ const FieldSearchSpec & spec = specMap().find(fid)->second;
+ LOG(debug, "buildFieldsInQuery = rawIndex='%s', index='%s'", rawIndex.data(), index.c_str());
+ if ((rawIndex != index) && (spec.name().find(index) == 0)) {
+ vespalib::string modIndex(rawIndex);
+ modIndex.append(spec.name().substr(index.size()));
+ fieldIdMap.add(modIndex, spec.id());
+ } else {
+ fieldIdMap.add(spec.name(),spec.id());
+ }
+ }
+ } else {
+ LOG(warning, "No valid indexes registered for index %s", rawIndex.data());
+ }
+ }
+}
+
+StringFieldIdTMap
+FieldSearchSpecMap::buildFieldsInQuery(const Query & query) const
{
- bool retval(true);
+ StringFieldIdTMap fieldsInQuery;
ConstQueryTermList qtl;
query.getLeaves(qtl);
for (const auto & term : qtl) {
- for (const auto & dtm : documentTypeMap()) {
- const IndexFieldMapT & fim = dtm.second;
- vespalib::string rawIndex(term->index());
- vespalib::string index(stripNonFields(rawIndex));
- auto fIt = fim.find(index);
- if (fIt != fim.end()) {
- for(FieldIdT fid : fIt->second) {
- const FieldSearchSpec & spec = specMap().find(fid)->second;
- LOG(debug, "buildFieldsInQuery = rawIndex='%s', index='%s'", rawIndex.c_str(), index.c_str());
- if ((rawIndex != index) && (spec.name().find(index) == 0)) {
- vespalib::string modIndex(rawIndex);
- modIndex.append(spec.name().substr(index.size()));
- fieldsInQuery.add(modIndex, spec.id());
- } else {
- fieldsInQuery.add(spec.name(),spec.id());
- }
- }
- } else {
- LOG(warning, "No valid indexes registered for index %s", term->index().c_str());
- retval = false;
- }
- }
+ addFieldsFromIndex(term->index(), fieldsInQuery);
}
- return retval;
+ return fieldsInQuery;
}
-void FieldSearchSpecMap::buildFromConfig(const std::vector<vespalib::string> & otherFieldsNeeded)
+void
+FieldSearchSpecMap::buildFromConfig(const std::vector<vespalib::string> & otherFieldsNeeded)
{
- for(size_t i(0), m(otherFieldsNeeded.size()); i < m; i++) {
- LOG(debug, "otherFieldsNeeded[%zd] = '%s'", i, otherFieldsNeeded[i].c_str());
- _nameIdMap.add(otherFieldsNeeded[i]);
+ for (const auto & i : otherFieldsNeeded) {
+ _nameIdMap.add(i);
}
}
@@ -253,7 +260,8 @@ buildFieldSet(const VsmfieldsConfig::Documenttype::Index & ci, const FieldSearch
}
-bool FieldSearchSpecMap::buildFromConfig(const VsmfieldsHandle & conf)
+bool
+FieldSearchSpecMap::buildFromConfig(const VsmfieldsHandle & conf)
{
bool retval(true);
LOG(spam, "Parsing %zd fields", conf->fieldspec.size());
@@ -297,12 +305,14 @@ FieldSearchSpecMap::reconfigFromQuery(const Query & query)
}
}
-bool lesserField(const FieldSearcherContainer & a, const FieldSearcherContainer & b)
+bool
+lesserField(const FieldSearcherContainer & a, const FieldSearcherContainer & b)
{
return a->field() < b->field();
}
-void FieldSearchSpecMap::buildSearcherMap(const StringFieldIdTMapT & fieldsInQuery, FieldIdTSearcherMap & fieldSearcherMap)
+void
+FieldSearchSpecMap::buildSearcherMap(const StringFieldIdTMapT & fieldsInQuery, FieldIdTSearcherMap & fieldSearcherMap) const
{
fieldSearcherMap.clear();
for (const auto & entry : fieldsInQuery) {
@@ -331,7 +341,8 @@ FieldSearchSpecMap::get_distance_metric(const vespalib::string& name) const
return vsm::NearestNeighborFieldSearcher::distance_metric_from_string(itr->second.get_arg1());
}
-vespalib::asciistream & operator <<(vespalib::asciistream & os, const FieldSearchSpecMap & df)
+vespalib::asciistream &
+operator <<(vespalib::asciistream & os, const FieldSearchSpecMap & df)
{
os << "DocumentTypeMap = \n";
for (const auto & dtm : df.documentTypeMap()) {
diff --git a/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.h b/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.h
index b0154a82dae..43bb5b04481 100644
--- a/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.h
+++ b/streamingvisitors/src/vespa/vsm/vsm/fieldsearchspec.h
@@ -23,6 +23,11 @@ public:
bool valid() const { return static_cast<bool>(_searcher); }
size_t maxLength() const { return _maxLength; }
bool uses_nearest_neighbor_search_method() const noexcept { return _searchMethod == VsmfieldsConfig::Fieldspec::Searchmethod::NEAREST_NEIGHBOR; }
+ bool uses_string_search_method() const noexcept {
+ return (_searchMethod == VsmfieldsConfig::Fieldspec::Searchmethod::UTF8) ||
+ (_searchMethod == VsmfieldsConfig::Fieldspec::Searchmethod::AUTOUTF8) ||
+ (_searchMethod == VsmfieldsConfig::Fieldspec::Searchmethod::SSE2UTF8);
+ }
const vespalib::string& get_arg1() const noexcept { return _arg1; }
/**
@@ -71,17 +76,13 @@ public:
* Adds a [field name, field id] entry to the given mapping for each field name used in the given query.
* This is achieved by mapping from query term index name -> list of field ids -> [field name, field id] pairs.
**/
- bool buildFieldsInQuery(const search::streaming::Query & query, StringFieldIdTMap & fieldsInQuery) const;
-
- /**
- * Adds a [field name, field id] entry to the given mapping for each field name in the given vector.
- **/
- void buildFieldsInQuery(const std::vector<vespalib::string> & otherFieldsNeeded, StringFieldIdTMap & fieldsInQuery) const;
+ StringFieldIdTMap buildFieldsInQuery(const search::streaming::Query & query) const;
+ void addFieldsFromIndex(vespalib::stringref index, StringFieldIdTMap & fieldIdMap) const;
/**
* Adds a FieldSearcher object to the given field searcher map for each field name in the other map.
**/
- void buildSearcherMap(const StringFieldIdTMapT & fieldsInQuery, FieldIdTSearcherMap & fieldSearcherMap);
+ void buildSearcherMap(const StringFieldIdTMapT & fieldsInQuery, FieldIdTSearcherMap & fieldSearcherMap) const;
const FieldSearchSpecMapT & specMap() const { return _specMap; }
//const IndexFieldMapT & indexMap() const { return _documentTypeMap.begin()->second; }
@@ -89,7 +90,7 @@ public:
const StringFieldIdTMap & nameIdMap() const { return _nameIdMap; }
friend vespalib::asciistream & operator <<(vespalib::asciistream & os, const FieldSearchSpecMap & f);
- static vespalib::string stripNonFields(const vespalib::string & rawIndex);
+ static vespalib::string stripNonFields(vespalib::stringref rawIndex);
search::attribute::DistanceMetric get_distance_metric(const vespalib::string& name) const;
private:
diff --git a/vespa-dependencies-enforcer/allowed-maven-dependencies.txt b/vespa-dependencies-enforcer/allowed-maven-dependencies.txt
index ad044ceca01..472b926b5a1 100644
--- a/vespa-dependencies-enforcer/allowed-maven-dependencies.txt
+++ b/vespa-dependencies-enforcer/allowed-maven-dependencies.txt
@@ -4,8 +4,6 @@ ai.djl.huggingface:tokenizers:${huggingface.vespa.version}
ai.djl:api:${huggingface.vespa.version}
aopalliance:aopalliance:${aopalliance.vespa.version}
backport-util-concurrent:backport-util-concurrent:3.1
-ch.qos.logback:logback-classic:${logback.vespa.version}
-ch.qos.logback:logback-core:${logback.vespa.version}
classworlds:classworlds:1.1-alpha-2
com.amazonaws:aws-java-sdk-core:${aws-sdk.vespa.version}
com.amazonaws:aws-java-sdk-kms:${aws-sdk.vespa.version}
diff --git a/zookeeper-server/zookeeper-server/pom.xml b/zookeeper-server/zookeeper-server/pom.xml
index 77aec63a781..bb4a819b5ac 100644
--- a/zookeeper-server/zookeeper-server/pom.xml
+++ b/zookeeper-server/zookeeper-server/pom.xml
@@ -45,14 +45,6 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- </exclusion>
- <exclusion>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- </exclusion>
</exclusions>
</dependency>
<!-- snappy-java and metrics-core are included here