summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
Diffstat (limited to 'searchlib')
-rw-r--r--[-rwxr-xr-x]searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/ExpressionFunction.java3
-rw-r--r--[-rwxr-xr-x]searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/EmbracedNode.java3
-rw-r--r--[-rwxr-xr-x]searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/FunctionNode.java3
-rw-r--r--searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/FunctionReferenceContext.java6
-rw-r--r--searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/GeneratorLambdaFunctionNode.java3
-rw-r--r--searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/LambdaFunctionNode.java3
-rw-r--r--searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/NotNode.java3
-rw-r--r--searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/SerializationContext.java6
-rw-r--r--searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TensorFunctionNode.java3
-rw-r--r--searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/UnpackBitsNode.java3
-rw-r--r--[-rwxr-xr-x]searchlib/src/main/javacc/RankingExpressionParser.jj3
-rw-r--r--searchlib/src/test/java/com/yahoo/searchlib/aggregation/GroupTestCase.java3
-rw-r--r--searchlib/src/test/java/com/yahoo/searchlib/aggregation/GroupingTestCase.java26
-rw-r--r--[-rwxr-xr-x]searchlib/src/test/java/com/yahoo/searchlib/aggregation/MergeTestCase.java7
-rw-r--r--searchlib/src/test/java/com/yahoo/searchlib/aggregation/hll/NormalSketchTest.java3
-rw-r--r--searchlib/src/test/java/com/yahoo/searchlib/aggregation/hll/SketchUtils.java6
-rw-r--r--searchlib/src/test/java/com/yahoo/searchlib/expression/IntegerResultNodeTestCase.java3
-rw-r--r--[-rwxr-xr-x]searchlib/src/test/java/com/yahoo/searchlib/expression/ObjectVisitorTestCase.java67
-rw-r--r--searchlib/src/test/java/com/yahoo/searchlib/expression/TimeStampFunctionTestCase.java4
-rw-r--r--[-rwxr-xr-x]searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/FeatureListTestCase.java25
-rw-r--r--[-rwxr-xr-x]searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/RankingExpressionTestCase.java19
-rw-r--r--searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/rule/ArgumentsTestCase.java14
-rw-r--r--searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/rule/ReferenceNodeTestCase.java7
-rw-r--r--searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/transform/SimplifierTestCase.java12
-rw-r--r--searchlib/src/tests/queryeval/flow/queryeval_flow_test.cpp78
-rw-r--r--searchlib/src/tests/queryeval/iterator_benchmark/attribute_ctx_builder.cpp81
-rw-r--r--searchlib/src/tests/queryeval/iterator_benchmark/attribute_ctx_builder.h2
-rw-r--r--searchlib/src/tests/queryeval/iterator_benchmark/benchmark_blueprint_factory.cpp24
-rw-r--r--searchlib/src/tests/queryeval/iterator_benchmark/benchmark_blueprint_factory.h2
-rw-r--r--searchlib/src/tests/queryeval/iterator_benchmark/common.cpp3
-rw-r--r--searchlib/src/tests/queryeval/iterator_benchmark/common.h3
-rw-r--r--searchlib/src/tests/queryeval/iterator_benchmark/iterator_benchmark_test.cpp60
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/flow.h40
33 files changed, 257 insertions, 271 deletions
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/ExpressionFunction.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/ExpressionFunction.java
index 093e65b2e4d..840eacd9dd9 100755..100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/ExpressionFunction.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/ExpressionFunction.java
@@ -15,7 +15,6 @@ import static com.yahoo.searchlib.rankingexpression.Reference.wrapInRankingExpre
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.List;
@@ -50,7 +49,7 @@ public class ExpressionFunction {
* @param body the ranking expression that defines this function
*/
public ExpressionFunction(String name, RankingExpression body) {
- this(name, Collections.emptyList(), body);
+ this(name, List.of(), body);
}
/**
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/EmbracedNode.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/EmbracedNode.java
index 1186541b9c0..c7231ecd800 100755..100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/EmbracedNode.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/EmbracedNode.java
@@ -7,7 +7,6 @@ import com.yahoo.searchlib.rankingexpression.evaluation.Value;
import com.yahoo.tensor.TensorType;
import com.yahoo.tensor.evaluation.TypeContext;
-import java.util.Collections;
import java.util.Deque;
import java.util.List;
import java.util.Objects;
@@ -36,7 +35,7 @@ public final class EmbracedNode extends CompositeNode {
@Override
public List<ExpressionNode> children() {
- return Collections.singletonList(value);
+ return List.of(value);
}
@Override
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/FunctionNode.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/FunctionNode.java
index e7db8848be5..e93edb71ac6 100755..100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/FunctionNode.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/FunctionNode.java
@@ -11,7 +11,6 @@ import com.yahoo.tensor.evaluation.TypeContext;
import com.yahoo.tensor.functions.Join;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Deque;
import java.util.List;
import java.util.Objects;
@@ -34,7 +33,7 @@ public final class FunctionNode extends CompositeNode {
public FunctionNode(Function function, ExpressionNode argument) {
if (function.arity() != 1) throw new IllegalArgumentException(function + " is not unary");
this.function = function;
- this.arguments = new Arguments(Collections.singletonList(argument));
+ this.arguments = new Arguments(List.of(argument));
}
/** Creates a binary function node */
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/FunctionReferenceContext.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/FunctionReferenceContext.java
index a2cf662a255..be0a532128f 100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/FunctionReferenceContext.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/FunctionReferenceContext.java
@@ -4,8 +4,8 @@ package com.yahoo.searchlib.rankingexpression.rule;
import com.yahoo.searchlib.rankingexpression.ExpressionFunction;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -23,12 +23,12 @@ public class FunctionReferenceContext {
/** Create a context for a single serialization task */
public FunctionReferenceContext() {
- this(Collections.emptyList());
+ this(List.of());
}
/** Create a context for a single serialization task */
public FunctionReferenceContext(Collection<ExpressionFunction> functions) {
- this(toMap(functions), Collections.emptyMap());
+ this(toMap(functions), Map.of());
}
public FunctionReferenceContext(Collection<ExpressionFunction> functions, Map<String, String> bindings) {
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/GeneratorLambdaFunctionNode.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/GeneratorLambdaFunctionNode.java
index bef19a656f8..49311b1553b 100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/GeneratorLambdaFunctionNode.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/GeneratorLambdaFunctionNode.java
@@ -8,7 +8,6 @@ import com.yahoo.searchlib.rankingexpression.evaluation.Value;
import com.yahoo.tensor.TensorType;
import com.yahoo.tensor.evaluation.TypeContext;
-import java.util.Collections;
import java.util.Deque;
import java.util.List;
import java.util.Objects;
@@ -39,7 +38,7 @@ public class GeneratorLambdaFunctionNode extends CompositeNode {
@Override
public List<ExpressionNode> children() {
- return Collections.singletonList(generator);
+ return List.of(generator);
}
@Override
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/LambdaFunctionNode.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/LambdaFunctionNode.java
index 0f1331515cc..b84bb655140 100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/LambdaFunctionNode.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/LambdaFunctionNode.java
@@ -9,7 +9,6 @@ import com.yahoo.tensor.TensorType;
import com.yahoo.tensor.evaluation.TypeContext;
import com.yahoo.tensor.functions.Generate;
-import java.util.Collections;
import java.util.Deque;
import java.util.HashSet;
import java.util.List;
@@ -50,7 +49,7 @@ public class LambdaFunctionNode extends CompositeNode {
@Override
public List<ExpressionNode> children() {
- return Collections.singletonList(functionExpression);
+ return List.of(functionExpression);
}
@Override
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/NotNode.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/NotNode.java
index ba8fb10a1cd..dcf1f857832 100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/NotNode.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/NotNode.java
@@ -7,7 +7,6 @@ import com.yahoo.searchlib.rankingexpression.evaluation.Value;
import com.yahoo.tensor.TensorType;
import com.yahoo.tensor.evaluation.TypeContext;
-import java.util.Collections;
import java.util.Deque;
import java.util.List;
import java.util.Objects;
@@ -31,7 +30,7 @@ public class NotNode extends BooleanNode {
@Override
public List<ExpressionNode> children() {
- return Collections.singletonList(value);
+ return List.of(value);
}
@Override
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/SerializationContext.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/SerializationContext.java
index d1cb77fb1b4..271e367c1f4 100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/SerializationContext.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/SerializationContext.java
@@ -9,9 +9,9 @@ import com.yahoo.tensor.evaluation.TypeContext;
import static com.yahoo.searchlib.rankingexpression.Reference.wrapInRankingExpression;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -29,7 +29,7 @@ public class SerializationContext extends FunctionReferenceContext {
/** Create a context for a single serialization task */
public SerializationContext() {
- this(Collections.emptyList(), Collections.emptyMap(), Optional.empty(), new LinkedHashMap<>());
+ this(List.of(), Map.of(), Optional.empty(), new LinkedHashMap<>());
}
/**
@@ -40,7 +40,7 @@ public class SerializationContext extends FunctionReferenceContext {
*/
public SerializationContext(Collection<ExpressionFunction> functions,
Optional<TypeContext<Reference>> typeContext) {
- this(functions, Collections.emptyMap(), typeContext, new LinkedHashMap<>());
+ this(functions, Map.of(), typeContext, new LinkedHashMap<>());
}
/**
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TensorFunctionNode.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TensorFunctionNode.java
index b3f2f265900..202dbebc311 100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TensorFunctionNode.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TensorFunctionNode.java
@@ -19,7 +19,6 @@ import com.yahoo.tensor.functions.TensorFunction;
import com.yahoo.tensor.functions.ToStringContext;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Deque;
import java.util.LinkedHashMap;
import java.util.List;
@@ -238,7 +237,7 @@ public class TensorFunctionNode extends CompositeNode {
.map(ExpressionTensorFunction::new)
.collect(Collectors.toList());
else
- return Collections.emptyList();
+ return List.of();
}
@Override
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/UnpackBitsNode.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/UnpackBitsNode.java
index 81ad09dd880..0a0f48df823 100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/UnpackBitsNode.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/UnpackBitsNode.java
@@ -11,7 +11,6 @@ import com.yahoo.tensor.TensorAddress;
import com.yahoo.tensor.TensorType;
import com.yahoo.tensor.evaluation.TypeContext;
-import java.util.Collections;
import java.util.Deque;
import java.util.List;
import java.util.Objects;
@@ -53,7 +52,7 @@ public class UnpackBitsNode extends CompositeNode {
@Override
public List<ExpressionNode> children() {
- return Collections.singletonList(input);
+ return List.of(input);
}
private static record Meta(TensorType outputType, TensorType outputDenseType, String unpackDimension) {}
diff --git a/searchlib/src/main/javacc/RankingExpressionParser.jj b/searchlib/src/main/javacc/RankingExpressionParser.jj
index 97aa42f79c9..51f433bf67d 100755..100644
--- a/searchlib/src/main/javacc/RankingExpressionParser.jj
+++ b/searchlib/src/main/javacc/RankingExpressionParser.jj
@@ -24,7 +24,6 @@ import com.yahoo.searchlib.rankingexpression.evaluation.StringValue;
import com.yahoo.searchlib.rankingexpression.evaluation.TensorValue;
import com.yahoo.tensor.*;
import com.yahoo.tensor.functions.*;
-import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Arrays;
import java.util.ArrayList;
@@ -893,7 +892,7 @@ List<String> bracedIdentifierList() :
String element;
}
{
- ( element = identifier() { return Collections.singletonList(element); } )
+ ( element = identifier() { return List.of(element); } )
|
( <LBRACE> list = identifierList() <RBRACE> { return list; } )
}
diff --git a/searchlib/src/test/java/com/yahoo/searchlib/aggregation/GroupTestCase.java b/searchlib/src/test/java/com/yahoo/searchlib/aggregation/GroupTestCase.java
index e306d27b6ee..60309db9787 100644
--- a/searchlib/src/test/java/com/yahoo/searchlib/aggregation/GroupTestCase.java
+++ b/searchlib/src/test/java/com/yahoo/searchlib/aggregation/GroupTestCase.java
@@ -10,7 +10,6 @@ import com.yahoo.vespa.objects.BufferSerializer;
import com.yahoo.vespa.objects.Identifiable;
import org.junit.Test;
-import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
@@ -56,7 +55,7 @@ public class GroupTestCase {
group.addOrderBy(bar, false);
assertEquals(2, group.getOrderByExpressions().size());
assertSame(bar, group.getOrderByExpressions().get(1));
- assertEquals(Arrays.asList(1, -2), group.getOrderByIndexes());
+ assertEquals(List.of(1, -2), group.getOrderByIndexes());
}
@Test
diff --git a/searchlib/src/test/java/com/yahoo/searchlib/aggregation/GroupingTestCase.java b/searchlib/src/test/java/com/yahoo/searchlib/aggregation/GroupingTestCase.java
index 66b8a07ac95..a0e6fd32ddc 100644
--- a/searchlib/src/test/java/com/yahoo/searchlib/aggregation/GroupingTestCase.java
+++ b/searchlib/src/test/java/com/yahoo/searchlib/aggregation/GroupingTestCase.java
@@ -1,14 +1,12 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.searchlib.aggregation;
-import com.yahoo.searchlib.expression.FloatResultNode;
import com.yahoo.searchlib.expression.NullResultNode;
import com.yahoo.searchlib.expression.StringBucketResultNode;
import com.yahoo.vespa.objects.BufferSerializer;
import org.junit.Test;
-import java.util.Arrays;
-import java.util.Collections;
+import java.util.List;
import static org.junit.Assert.*;
@@ -30,7 +28,7 @@ public class GroupingTestCase {
assertEquals(9, grouping.getId());
Grouping other = new Grouping(6);
- assertFalse(grouping.equals(other));
+ assertNotEquals(grouping, other);
other.setId(9);
assertEquals(grouping, other);
@@ -46,7 +44,7 @@ public class GroupingTestCase {
assertTrue(grouping.getAll());
Grouping other = new Grouping();
- assertFalse(grouping.equals(other));
+ assertNotEquals(grouping, other);
other.setAll(true);
assertEquals(grouping, other);
@@ -62,7 +60,7 @@ public class GroupingTestCase {
assertEquals(69, grouping.getTopN());
Grouping other = new Grouping();
- assertFalse(grouping.equals(other));
+ assertNotEquals(grouping, other);
other.setTopN(69);
assertEquals(grouping, other);
@@ -78,7 +76,7 @@ public class GroupingTestCase {
assertEquals(69, grouping.getFirstLevel());
Grouping other = new Grouping();
- assertFalse(grouping.equals(other));
+ assertNotEquals(grouping, other);
other.setFirstLevel(69);
assertEquals(grouping, other);
@@ -94,7 +92,7 @@ public class GroupingTestCase {
assertEquals(69, grouping.getLastLevel());
Grouping other = new Grouping();
- assertFalse(grouping.equals(other));
+ assertNotEquals(grouping, other);
other.setLastLevel(69);
assertEquals(grouping, other);
@@ -117,7 +115,7 @@ public class GroupingTestCase {
assertEquals(root, grouping.getRoot());
Grouping other = new Grouping();
- assertFalse(grouping.equals(other));
+ assertNotEquals(grouping, other);
other.setRoot(root);
assertEquals(grouping, other);
@@ -128,7 +126,7 @@ public class GroupingTestCase {
@Test
public void requireThatLevelAccessorsWork() {
Grouping grouping = new Grouping();
- assertEquals(Collections.emptyList(), grouping.getLevels());
+ assertEquals(List.of(), grouping.getLevels());
try {
grouping.addLevel(null);
fail();
@@ -137,10 +135,10 @@ public class GroupingTestCase {
}
GroupingLevel level = new GroupingLevel();
grouping.addLevel(level);
- assertEquals(Arrays.asList(level), grouping.getLevels());
+ assertEquals(List.of(level), grouping.getLevels());
Grouping other = new Grouping();
- assertFalse(grouping.equals(other));
+ assertNotEquals(grouping, other);
other.addLevel(level);
assertEquals(grouping, other);
@@ -155,8 +153,8 @@ public class GroupingTestCase {
@Test
public void requireThatEqualsIsImplemented() {
- assertFalse(new Grouping().equals(new Object()));
- assertTrue(new Grouping().equals(new Grouping()));
+ assertNotEquals(new Grouping(), new Object());
+ assertEquals(new Grouping(), new Grouping());
}
@Test
diff --git a/searchlib/src/test/java/com/yahoo/searchlib/aggregation/MergeTestCase.java b/searchlib/src/test/java/com/yahoo/searchlib/aggregation/MergeTestCase.java
index 610352ff236..838a4d738ac 100755..100644
--- a/searchlib/src/test/java/com/yahoo/searchlib/aggregation/MergeTestCase.java
+++ b/searchlib/src/test/java/com/yahoo/searchlib/aggregation/MergeTestCase.java
@@ -13,7 +13,6 @@ import com.yahoo.searchlib.expression.MultiplyFunctionNode;
import com.yahoo.searchlib.expression.StringResultNode;
import org.junit.Test;
-import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
@@ -725,20 +724,20 @@ public class MergeTestCase {
}
private static void assertMerge(Grouping request, Group lhs, Group rhs, Group expect) {
- assertMerge(Arrays.asList(request.clone().setRoot(lhs.clone()),
+ assertMerge(List.of(request.clone().setRoot(lhs.clone()),
request.clone().setRoot(rhs.clone())),
expect);
}
private static void assertMerge(Grouping request, Group a, Group b, Group c, Group expect) {
- assertMerge(Arrays.asList(request.clone().setRoot(a.clone()),
+ assertMerge(List.of(request.clone().setRoot(a.clone()),
request.clone().setRoot(b.clone()),
request.clone().setRoot(c.clone())),
expect);
}
private static void assertMerge(Grouping lhs, Grouping rhs, Group expect) {
- assertMerge(Arrays.asList(lhs, rhs), expect);
+ assertMerge(List.of(lhs, rhs), expect);
}
private static void assertMerge(List<Grouping> groupingList, Group expect) {
diff --git a/searchlib/src/test/java/com/yahoo/searchlib/aggregation/hll/NormalSketchTest.java b/searchlib/src/test/java/com/yahoo/searchlib/aggregation/hll/NormalSketchTest.java
index d5269611b53..8e54c4598a0 100644
--- a/searchlib/src/test/java/com/yahoo/searchlib/aggregation/hll/NormalSketchTest.java
+++ b/searchlib/src/test/java/com/yahoo/searchlib/aggregation/hll/NormalSketchTest.java
@@ -4,7 +4,6 @@ package com.yahoo.searchlib.aggregation.hll;
import com.yahoo.vespa.objects.BufferSerializer;
import org.junit.Test;
-import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
@@ -98,7 +97,7 @@ public class NormalSketchTest {
NormalSketch sketch = new NormalSketch(10);
// Aggregate multiple values
- sketch.aggregate(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
+ sketch.aggregate(List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
for (int i = 0; i < 10; i++) {
assertBucketEquals(sketch, i, 23);
}
diff --git a/searchlib/src/test/java/com/yahoo/searchlib/aggregation/hll/SketchUtils.java b/searchlib/src/test/java/com/yahoo/searchlib/aggregation/hll/SketchUtils.java
index 9bec86c928b..5bf5294a828 100644
--- a/searchlib/src/test/java/com/yahoo/searchlib/aggregation/hll/SketchUtils.java
+++ b/searchlib/src/test/java/com/yahoo/searchlib/aggregation/hll/SketchUtils.java
@@ -1,7 +1,7 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.searchlib.aggregation.hll;
-import java.util.Arrays;
+import java.util.List;
import static org.junit.Assert.assertEquals;
@@ -16,13 +16,13 @@ public class SketchUtils {
public static SparseSketch createSparseSketch(Integer... values) {
SparseSketch sketch = new SparseSketch();
- sketch.aggregate(Arrays.asList(values));
+ sketch.aggregate(List.of(values));
return sketch;
}
public static NormalSketch createNormalSketch(Integer... values) {
NormalSketch sketch = new NormalSketch();
- sketch.aggregate(Arrays.asList(values));
+ sketch.aggregate(List.of(values));
return sketch;
}
diff --git a/searchlib/src/test/java/com/yahoo/searchlib/expression/IntegerResultNodeTestCase.java b/searchlib/src/test/java/com/yahoo/searchlib/expression/IntegerResultNodeTestCase.java
index c765714a4ab..45d809dcd8a 100644
--- a/searchlib/src/test/java/com/yahoo/searchlib/expression/IntegerResultNodeTestCase.java
+++ b/searchlib/src/test/java/com/yahoo/searchlib/expression/IntegerResultNodeTestCase.java
@@ -4,7 +4,6 @@ package com.yahoo.searchlib.expression;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
-import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertArrayEquals;
@@ -18,7 +17,7 @@ import static org.junit.Assert.assertTrue;
public class IntegerResultNodeTestCase extends ResultNodeTest {
List<NumericResultNode> getResultNodes(long startvalue) {
- return Arrays.asList(new Int8ResultNode((byte)startvalue),
+ return List.of(new Int8ResultNode((byte)startvalue),
new Int16ResultNode((short)startvalue),
new Int32ResultNode((int)startvalue),
new IntegerResultNode(startvalue));
diff --git a/searchlib/src/test/java/com/yahoo/searchlib/expression/ObjectVisitorTestCase.java b/searchlib/src/test/java/com/yahoo/searchlib/expression/ObjectVisitorTestCase.java
index 3c224d06cc3..1346577569b 100755..100644
--- a/searchlib/src/test/java/com/yahoo/searchlib/expression/ObjectVisitorTestCase.java
+++ b/searchlib/src/test/java/com/yahoo/searchlib/expression/ObjectVisitorTestCase.java
@@ -4,6 +4,7 @@ package com.yahoo.searchlib.expression;
import com.yahoo.vespa.objects.ObjectDumper;
import org.junit.Test;
+
import java.util.Arrays;
import static org.junit.Assert.assertEquals;
@@ -18,38 +19,46 @@ public class ObjectVisitorTestCase {
assertDump("test: <NULL>\n", null);
assertDump("test: 1\n", 1);
assertDump("test: 'foo'\n", "foo");
- assertDump("test: List {\n" +
- " [0]: 'foo'\n" +
- " [1]: 69\n" +
- " [2]: <NULL>\n" +
- "}\n",
+ assertDump("""
+ test: List {
+ [0]: 'foo'
+ [1]: 69
+ [2]: <NULL>
+ }
+ """,
Arrays.asList("foo", 69, null));
- assertDump("test: String[] {\n" +
- " [0]: 'foo'\n" +
- " [1]: 'bar'\n" +
- " [2]: 'baz'\n" +
- "}\n",
+ assertDump("""
+ test: String[] {
+ [0]: 'foo'
+ [1]: 'bar'
+ [2]: 'baz'
+ }
+ """,
new String[] { "foo", "bar", "baz" });
- assertDump("test: IntegerResultNode {\n" +
- " classId: 16491\n" +
- " value: 5\n" +
- "}\n",
+ assertDump("""
+ test: IntegerResultNode {
+ classId: 16491
+ value: 5
+ }
+ """,
new IntegerResultNode(5));
- assertDump("test: FixedWidthBucketFunctionNode {\n" +
- " classId: 16461\n" +
- " result: <NULL>\n" +
- " args: List {\n" +
- " [0]: AttributeNode {\n" +
- " classId: 16439\n" +
- " result: <NULL>\n" +
- " attribute: 'foo'\n" +
- " }\n" +
- " }\n" +
- " width: IntegerResultNode {\n" +
- " classId: 16491\n" +
- " value: 5\n" +
- " }\n" +
- "}\n",
+ assertDump("""
+ test: FixedWidthBucketFunctionNode {
+ classId: 16461
+ result: <NULL>
+ args: List {
+ [0]: AttributeNode {
+ classId: 16439
+ result: <NULL>
+ attribute: 'foo'
+ }
+ }
+ width: IntegerResultNode {
+ classId: 16491
+ value: 5
+ }
+ }
+ """,
new FixedWidthBucketFunctionNode(new IntegerResultNode(5), new AttributeNode("foo")));
}
diff --git a/searchlib/src/test/java/com/yahoo/searchlib/expression/TimeStampFunctionTestCase.java b/searchlib/src/test/java/com/yahoo/searchlib/expression/TimeStampFunctionTestCase.java
index 69cea09df81..188603749e2 100644
--- a/searchlib/src/test/java/com/yahoo/searchlib/expression/TimeStampFunctionTestCase.java
+++ b/searchlib/src/test/java/com/yahoo/searchlib/expression/TimeStampFunctionTestCase.java
@@ -3,7 +3,7 @@ package com.yahoo.searchlib.expression;
import org.junit.Test;
-import java.util.Arrays;
+import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
@@ -17,7 +17,7 @@ public class TimeStampFunctionTestCase {
public void requireThatAccessorsWork() {
ExpressionNode arg = new AttributeNode("foo");
for (TimeStampFunctionNode.TimePart part : TimeStampFunctionNode.TimePart.values()) {
- for (Boolean gmt : Arrays.asList(true, false)) {
+ for (Boolean gmt : List.of(true, false)) {
TimeStampFunctionNode node = new TimeStampFunctionNode(arg, part, gmt);
assertSame(arg, node.getArg());
assertEquals(part, node.getTimePart());
diff --git a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/FeatureListTestCase.java b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/FeatureListTestCase.java
index 8de36ee1ec1..0af105885ec 100755..100644
--- a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/FeatureListTestCase.java
+++ b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/FeatureListTestCase.java
@@ -8,7 +8,6 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.Reader;
import java.io.StringReader;
-import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
@@ -22,37 +21,37 @@ public class FeatureListTestCase {
@Test
public void requireThatFeatureListFromStringWorks() throws ParseException {
assertFromString("attribute(foo).out",
- Arrays.asList("attribute(foo).out"));
+ List.of("attribute(foo).out"));
assertFromString("attribute(foo).out attribute ( bar ) . out",
- Arrays.asList("attribute(foo).out", "attribute(bar).out"));
+ List.of("attribute(foo).out", "attribute(bar).out"));
assertFromString("foo\n bar\n \t \t \n baz \n",
- Arrays.asList("foo", "bar", "baz"));
+ List.of("foo", "bar", "baz"));
assertFromString("attribute attribute(foo) attribute(foo).out attribute(bar).out.out",
- Arrays.asList("attribute", "attribute(foo)", "attribute(foo).out", "attribute(bar).out.out"));
+ List.of("attribute", "attribute(foo)", "attribute(foo).out", "attribute(bar).out.out"));
}
@Test
public void requireThatFeatureListFromReaderWorks() throws ParseException {
assertFromReader(new StringReader("attribute(foo).out"),
- Arrays.asList("attribute(foo).out"));
+ List.of("attribute(foo).out"));
assertFromReader(new StringReader("attribute(foo).out attribute ( bar ) . out"),
- Arrays.asList("attribute(foo).out", "attribute(bar).out"));
+ List.of("attribute(foo).out", "attribute(bar).out"));
assertFromReader(new StringReader("foo\n bar\n \t \t \n baz \n"),
- Arrays.asList("foo", "bar", "baz"));
+ List.of("foo", "bar", "baz"));
assertFromReader(new StringReader("attribute attribute(foo) attribute(foo).out attribute(bar).out.out"),
- Arrays.asList("attribute", "attribute(foo)", "attribute(foo).out", "attribute(bar).out.out"));
+ List.of("attribute", "attribute(foo)", "attribute(foo).out", "attribute(bar).out.out"));
}
@Test
public void requireThatFeatureListFromFileWorks() throws ParseException, FileNotFoundException {
assertFromFile(new File("src/test/files/features01.expression"),
- Arrays.asList("attribute(foo).out"));
+ List.of("attribute(foo).out"));
assertFromFile(new File("src/test/files/features02.expression"),
- Arrays.asList("attribute(foo).out", "attribute(bar).out"));
+ List.of("attribute(foo).out", "attribute(bar).out"));
assertFromFile(new File("src/test/files/features03.expression"),
- Arrays.asList("foo", "bar", "baz"));
+ List.of("foo", "bar", "baz"));
assertFromFile(new File("src/test/files/features04.expression"),
- Arrays.asList("attribute", "attribute(foo)", "attribute(foo).out", "attribute(bar).out.out"));
+ List.of("attribute", "attribute(foo)", "attribute(foo).out", "attribute(bar).out.out"));
}
public void assertFromString(String input, List<String> expected) throws ParseException {
diff --git a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/RankingExpressionTestCase.java b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/RankingExpressionTestCase.java
index 8d60f893c7c..13714af8324 100755..100644
--- a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/RankingExpressionTestCase.java
+++ b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/RankingExpressionTestCase.java
@@ -23,7 +23,6 @@ import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -121,28 +120,28 @@ public class RankingExpressionTestCase {
@Test
public void testSerialization() throws ParseException {
List<ExpressionFunction> functions = new ArrayList<>();
- functions.add(new ExpressionFunction("foo", Arrays.asList("arg1", "arg2"), new RankingExpression("min(arg1, pow(arg2, 2))")));
- functions.add(new ExpressionFunction("bar", Arrays.asList("arg1", "arg2"), new RankingExpression("arg1 * arg1 + 2 * arg1 * arg2 + arg2 * arg2")));
- functions.add(new ExpressionFunction("baz", Arrays.asList("arg1", "arg2"), new RankingExpression("foo(1, 2) / bar(arg1, arg2)")));
+ functions.add(new ExpressionFunction("foo", List.of("arg1", "arg2"), new RankingExpression("min(arg1, pow(arg2, 2))")));
+ functions.add(new ExpressionFunction("bar", List.of("arg1", "arg2"), new RankingExpression("arg1 * arg1 + 2 * arg1 * arg2 + arg2 * arg2")));
+ functions.add(new ExpressionFunction("baz", List.of("arg1", "arg2"), new RankingExpression("foo(1, 2) / bar(arg1, arg2)")));
functions.add(new ExpressionFunction("cox", null, new RankingExpression("10 + 08 * 1977")));
- assertSerialization(Arrays.asList(
+ assertSerialization(List.of(
"rankingExpression(foo@e2dc17a89864aed0.12232eb692c6c502) + rankingExpression(foo@af74e3fd9070bd18.a368ed0a5ba3a5d0) * rankingExpression(foo@dbab346efdad5362.e5c39e42ebd91c30)",
"min(5,pow(rankingExpression(foo@d1d1417259cdc651.573bbcd4be18f379),2))",
"min(6,pow(7,2))",
"min(1,pow(2,2))",
"min(3,pow(4,2))",
"min(rankingExpression(foo@84951be88255b0ec.d0303e061b36fab8),pow(8,2))"), "foo(1,2) + foo(3,4) * foo(5, foo(foo(6, 7), 8))", functions);
- assertSerialization(Arrays.asList(
+ assertSerialization(List.of(
"rankingExpression(foo@e2dc17a89864aed0.12232eb692c6c502) + rankingExpression(bar@af74e3fd9070bd18.a368ed0a5ba3a5d0)",
"min(1,pow(2,2))",
"3 * 3 + 2 * 3 * 4 + 4 * 4"), "foo(1, 2) + bar(3, 4)", functions);
- assertSerialization(Arrays.asList(
+ assertSerialization(List.of(
"rankingExpression(baz@e2dc17a89864aed0.12232eb692c6c502)",
"min(1,pow(2,2))",
"rankingExpression(foo@e2dc17a89864aed0.12232eb692c6c502) / rankingExpression(bar@e2dc17a89864aed0.12232eb692c6c502)",
"1 * 1 + 2 * 1 * 2 + 2 * 2"), "baz(1, 2)", functions);
- assertSerialization(Arrays.asList(
+ assertSerialization(List.of(
"rankingExpression(cox)",
"10 + 8 * 1977"), "cox", functions
);
@@ -237,8 +236,8 @@ public class RankingExpressionTestCase {
String expRhs = "(rankingExpression(log10tweetage) * rankingExpression(log10tweetage) * " +
"rankingExpression(log10tweetage)) + 5.0 * attribute(ythl)";
- assertSerialization(Arrays.asList(expLhs + " + " + expRhs, "69"), lhs + " + " + rhs, functions);
- assertSerialization(Arrays.asList(expLhs + " - " + expRhs, "69"), lhs + " - " + rhs, functions);
+ assertSerialization(List.of(expLhs + " + " + expRhs, "69"), lhs + " + " + rhs, functions);
+ assertSerialization(List.of(expLhs + " - " + expRhs, "69"), lhs + " - " + rhs, functions);
}
@Test
diff --git a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/rule/ArgumentsTestCase.java b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/rule/ArgumentsTestCase.java
index df91c78c1b4..af6e4f1b9a9 100644
--- a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/rule/ArgumentsTestCase.java
+++ b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/rule/ArgumentsTestCase.java
@@ -3,8 +3,8 @@ package com.yahoo.searchlib.rankingexpression.rule;
import org.junit.Test;
-import java.util.Arrays;
import java.util.Collections;
+import java.util.List;
import static org.junit.Assert.*;
@@ -23,7 +23,7 @@ public class ArgumentsTestCase {
var foo = new ReferenceNode("foo");
var bar = new ReferenceNode("bar");
- args = new Arguments(Arrays.asList(foo, bar));
+ args = new Arguments(List.of(foo, bar));
assertEquals(2, args.expressions().size());
assertSame(foo, args.expressions().get(0));
assertSame(bar, args.expressions().get(1));
@@ -31,12 +31,12 @@ public class ArgumentsTestCase {
@Test
public void requireThatHashCodeAndEqualsWork() {
- Arguments arg1 = new Arguments(Arrays.asList(new ReferenceNode("foo"), new ReferenceNode("bar")));
- Arguments arg2 = new Arguments(Arrays.asList(new ReferenceNode("foo"), new ReferenceNode("bar")));
- Arguments arg3 = new Arguments(Arrays.asList(new ReferenceNode("foo")));
+ Arguments arg1 = new Arguments(List.of(new ReferenceNode("foo"), new ReferenceNode("bar")));
+ Arguments arg2 = new Arguments(List.of(new ReferenceNode("foo"), new ReferenceNode("bar")));
+ Arguments arg3 = new Arguments(List.of(new ReferenceNode("foo")));
assertEquals(arg1.hashCode(), arg2.hashCode());
- assertTrue(arg1.equals(arg2));
- assertFalse(arg2.equals(arg3));
+ assertEquals(arg1, arg2);
+ assertNotEquals(arg2, arg3);
}
}
diff --git a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/rule/ReferenceNodeTestCase.java b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/rule/ReferenceNodeTestCase.java
index 7d0e0d6da84..10a37ff28df 100644
--- a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/rule/ReferenceNodeTestCase.java
+++ b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/rule/ReferenceNodeTestCase.java
@@ -3,7 +3,6 @@ package com.yahoo.searchlib.rankingexpression.rule;
import org.junit.Test;
-import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
@@ -15,7 +14,7 @@ public class ReferenceNodeTestCase {
@Test
public void requireThatAccessorsWork() {
- ReferenceNode node = new ReferenceNode("foo", Arrays.asList(new ReferenceNode("bar"), new ReferenceNode("baz")), "cox");
+ ReferenceNode node = new ReferenceNode("foo", List.of(new ReferenceNode("bar"), new ReferenceNode("baz")), "cox");
assertEquals("foo", node.getName());
List<ExpressionNode> args = node.getArguments().expressions();
assertEquals(2, args.size());
@@ -23,10 +22,10 @@ public class ReferenceNodeTestCase {
assertEquals(new ReferenceNode("baz"), args.get(1));
assertEquals("cox", node.getOutput());
- node = node.setArguments(Arrays.<ExpressionNode>asList(new ReferenceNode("bar@")));
+ node = node.setArguments(List.of(new ReferenceNode("bar@")));
assertEquals(new ReferenceNode("bar@"), node.getArguments().expressions().get(0));
- node = node.setArguments(Arrays.<ExpressionNode>asList(new ReferenceNode("baz$")));
+ node = node.setArguments(List.of(new ReferenceNode("baz$")));
assertEquals(new ReferenceNode("baz$"), node.getArguments().expressions().get(0));
node = node.setOutput("cox'");
diff --git a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/transform/SimplifierTestCase.java b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/transform/SimplifierTestCase.java
index 0f367bb5425..7736b0e9ac7 100644
--- a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/transform/SimplifierTestCase.java
+++ b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/transform/SimplifierTestCase.java
@@ -12,7 +12,7 @@ import com.yahoo.searchlib.rankingexpression.rule.ConstantNode;
import com.yahoo.searchlib.rankingexpression.rule.NegativeNode;
import org.junit.Test;
-import java.util.Collections;
+import java.util.Map;
import static org.junit.Assert.*;
@@ -24,7 +24,7 @@ public class SimplifierTestCase {
@Test
public void testSimplify() throws ParseException {
Simplifier s = new Simplifier();
- TransformContext c = new TransformContext(Collections.emptyMap(), new MapTypeContext());
+ TransformContext c = new TransformContext(Map.of(), new MapTypeContext());
assertEquals("a + b", s.transform(new RankingExpression("a + b"), c).toString());
assertEquals("6.5", s.transform(new RankingExpression("1.0 + 2.0 + 3.5"), c).toString());
assertEquals("6.5", s.transform(new RankingExpression("1.0 + ( 2.0 + 3.5 )"), c).toString());
@@ -48,7 +48,7 @@ public class SimplifierTestCase {
@Test
public void testNaNExpression() throws ParseException {
Simplifier s = new Simplifier();
- TransformContext c = new TransformContext(Collections.emptyMap(), new MapTypeContext());
+ TransformContext c = new TransformContext(Map.of(), new MapTypeContext());
assertEquals("0 / 0", s.transform(new RankingExpression("0/0"), c).toString());
assertEquals("1 + 0.0 / 0.0", s.transform(new RankingExpression("1 + (1-1)/(2-2)"), c).toString());
}
@@ -56,7 +56,7 @@ public class SimplifierTestCase {
@Test
public void testSimplifyComplexExpression() throws ParseException {
RankingExpression initial = new RankingExpression("sqrt(if (if (INFERRED * 0.9 < INFERRED, GMP, (1 + 1.1) * INFERRED) < INFERRED * INFERRED - INFERRED, if (GMP < 85.80799542793133 * GMP, INFERRED, if (GMP < GMP, tanh(INFERRED), log(76.89956221113943))), tanh(tanh(INFERRED))) * sqrt(sqrt(GMP + INFERRED)) * GMP ) + 13.5 * (1 - GMP) * pow(GMP * 0.1, 2 + 1.1 * 0)");
- TransformContext c = new TransformContext(Collections.emptyMap(), new MapTypeContext());
+ TransformContext c = new TransformContext(Map.of(), new MapTypeContext());
RankingExpression simplified = new Simplifier().transform(initial, c);
Context context = new MapContext();
@@ -81,7 +81,7 @@ public class SimplifierTestCase {
@Test
public void testParenthesisPreservation() throws ParseException {
Simplifier s = new Simplifier();
- TransformContext c = new TransformContext(Collections.emptyMap(), new MapTypeContext());
+ TransformContext c = new TransformContext(Map.of(), new MapTypeContext());
CompositeNode transformed = (CompositeNode)s.transform(new RankingExpression("a + (b + c) / 100000000.0"), c).getRoot();
assertEquals("a + (b + c) / 1.0E8", transformed.toString());
}
@@ -89,7 +89,7 @@ public class SimplifierTestCase {
@Test
public void testOptimizingNegativeConstants() throws ParseException {
Simplifier s = new Simplifier();
- TransformContext c = new TransformContext(Collections.emptyMap(), new MapTypeContext());
+ TransformContext c = new TransformContext(Map.of(), new MapTypeContext());
assertEquals("-3", s.transform(new RankingExpression("-3"), c).toString());
assertEquals("-9.0", s.transform(new RankingExpression("-3 + -6"), c).toString());
assertEquals("-a", s.transform(new RankingExpression("-a"), c).toString());
diff --git a/searchlib/src/tests/queryeval/flow/queryeval_flow_test.cpp b/searchlib/src/tests/queryeval/flow/queryeval_flow_test.cpp
index 181c591ab20..5eb3a2ebf47 100644
--- a/searchlib/src/tests/queryeval/flow/queryeval_flow_test.cpp
+++ b/searchlib/src/tests/queryeval/flow/queryeval_flow_test.cpp
@@ -7,6 +7,7 @@
constexpr size_t loop_cnt = 64;
constexpr size_t max_work = 1; // 500'000'000;
+constexpr bool dump_unexpected = false;
constexpr bool verbose = false;
using namespace search::queryeval;
@@ -40,7 +41,7 @@ double dual_ordered_cost_of(const std::vector<FlowStats> &data, InFlow in_flow,
any_flow.update_cost(total_cost, child_cost);
any_flow.add(item.estimate);
}
- EXPECT_EQ(total_cost, result);
+ EXPECT_DOUBLE_EQ(total_cost, result);
return result;
}
@@ -174,7 +175,7 @@ void verify_flow(auto flow, const std::vector<double> &est_list, const std::vect
AnyFlow any_flow = AnyFlow::create<decltype(flow)>(InFlow(flow.strict(), flow.flow()));
ASSERT_EQ(est_list.size() + 1, expect.size());
for (size_t i = 0; i < est_list.size(); ++i) {
- EXPECT_EQ(any_flow.flow(), flow.flow());
+ EXPECT_DOUBLE_EQ(any_flow.flow(), flow.flow());
EXPECT_EQ(any_flow.strict(), flow.strict());
EXPECT_DOUBLE_EQ(flow.flow(), expect[i].flow);
EXPECT_EQ(flow.strict(), expect[i].strict);
@@ -182,7 +183,7 @@ void verify_flow(auto flow, const std::vector<double> &est_list, const std::vect
any_flow.add(est_list[i]);
flow.add(est_list[i]);
}
- EXPECT_EQ(any_flow.flow(), flow.flow());
+ EXPECT_DOUBLE_EQ(any_flow.flow(), flow.flow());
EXPECT_EQ(any_flow.strict(), flow.strict());
EXPECT_DOUBLE_EQ(flow.flow(), expect.back().flow);
EXPECT_EQ(flow.strict(), expect.back().strict);
@@ -356,10 +357,10 @@ TEST(FlowTest, optimal_and_flow) {
double min_cost = AndFlow::cost_of(data, strict);
double max_cost = 0.0;
AndFlow::sort(data, strict);
- EXPECT_EQ(ordered_cost_of<AndFlow>(data, strict, false), min_cost);
+ EXPECT_DOUBLE_EQ(ordered_cost_of<AndFlow>(data, strict, false), min_cost);
auto check = [&](const std::vector<FlowStats> &my_data) noexcept {
double my_cost = ordered_cost_of<AndFlow>(my_data, strict, false);
- EXPECT_LE(min_cost, my_cost);
+ EXPECT_LE(min_cost, my_cost + 1e-9);
max_cost = std::max(max_cost, my_cost);
};
each_perm(data, check);
@@ -379,7 +380,7 @@ TEST(FlowTest, optimal_or_flow) {
double min_cost = OrFlow::cost_of(data, strict);
double max_cost = 0.0;
OrFlow::sort(data, strict);
- EXPECT_EQ(ordered_cost_of<OrFlow>(data, strict, false), min_cost);
+ EXPECT_DOUBLE_EQ(ordered_cost_of<OrFlow>(data, strict, false), min_cost);
auto check = [&](const std::vector<FlowStats> &my_data) noexcept {
double my_cost = ordered_cost_of<OrFlow>(my_data, strict, false);
EXPECT_LE(min_cost, my_cost + 1e-9);
@@ -451,7 +452,7 @@ void test_strict_AND_sort_strategy(auto my_sort) {
flow.add(item.estimate);
total_cost += child_cost;
}
- EXPECT_EQ(total_cost, ordered_cost_of<AndFlow>(list, true, true));
+ EXPECT_DOUBLE_EQ(total_cost, ordered_cost_of<AndFlow>(list, true, true));
fprintf(stderr, " total cost: %10f\n", total_cost);
};
auto verify_order = [&](const std::vector<FlowStats> &list){
@@ -515,10 +516,7 @@ void test_strict_AND_sort_strategy(auto my_sort) {
};
each_perm(data, check);
double rel_err = 0.0;
- double cost_range = (max_cost - min_cost);
- if (cost_range > 1e-9) {
- rel_err = (est_cost - min_cost) / cost_range;
- }
+ rel_err = (est_cost - min_cost) / min_cost;
if (rel_err > max_rel_err) {
max_rel_err = rel_err;
my_worst_order = my_order;
@@ -526,7 +524,7 @@ void test_strict_AND_sort_strategy(auto my_sort) {
}
sum_rel_err += rel_err;
errs.push_back(rel_err);
- if (verbose && !verify_order(best_order)) {
+ if (dump_unexpected && !verify_order(best_order)) {
fprintf(stderr, " BEST ORDER IS UNEXPECTED:\n");
dump_flow(best_order, best_order);
fprintf(stderr, " UNEXPECTED case, my_order:\n");
@@ -551,60 +549,12 @@ TEST(FlowTest, strict_and_with_allow_force_strict_basic_order) {
test_strict_AND_sort_strategy(my_sort);
}
-TEST(FlowTest, strict_and_with_allow_force_strict_incremental_strict_selection) {
- auto my_sort = [](auto &data) {
- AndFlow::sort(data, true);
- for (size_t next = 1; (next + 1) < data.size(); ++next) {
- auto [idx, score] = flow::select_forced_strict_and_child(flow::DirectAdapter(), data, next);
- if (score >= 0.0) {
- break;
- }
- auto pos = data.begin() + idx;
- std::rotate(data.begin() + next, pos, pos + 1);
- }
- };
- test_strict_AND_sort_strategy(my_sort);
-}
-
-TEST(FlowTest, strict_and_with_allow_force_strict_incremental_strict_selection_with_strict_re_sorting) {
- auto my_sort = [](auto &data) {
- AndFlow::sort(data, true);
- size_t strict_cnt = 1;
- for (; strict_cnt < data.size(); ++strict_cnt) {
- auto [idx, score] = flow::select_forced_strict_and_child(flow::DirectAdapter(), data, strict_cnt);
- if (score >= 0.0) {
- break;
- }
- auto pos = data.begin() + idx;
- std::rotate(data.begin() + strict_cnt, pos, pos + 1);
- }
- std::sort(data.begin(), data.begin() + strict_cnt,
- [](const auto &a, const auto &b){ return (a.estimate < b.estimate); });
- };
- test_strict_AND_sort_strategy(my_sort);
-}
-
-TEST(FlowTest, strict_and_with_allow_force_strict_incremental_strict_selection_with_order) {
- auto my_sort = [](auto &data) {
- AndFlow::sort(data, true);
- for (size_t next = 1; next < data.size(); ++next) {
- auto [idx, target, score] = flow::select_forced_strict_and_child_with_order(flow::DirectAdapter(), data, next);
- if (score >= 0.0) {
- break;
- }
- auto pos = data.begin() + idx;
- std::rotate(data.begin() + target, pos, pos + 1);
- }
- };
- test_strict_AND_sort_strategy(my_sort);
-}
-
-TEST(FlowTest, strict_and_with_allow_force_strict_incremental_strict_selection_with_destructive_order) {
+TEST(FlowTest, strict_and_with_allow_force_strict_incremental_strict_selection_destructive_order_max_3_extra_strict) {
auto my_sort = [](auto &data) {
AndFlow::sort(data, true);
- for (size_t next = 1; next < data.size(); ++next) {
- auto [idx, target, score] = flow::select_forced_strict_and_child_with_destructive_order(flow::DirectAdapter(), data, next);
- if (score >= 0.0) {
+ for (size_t next = 1; next <= 3 && next < data.size(); ++next) {
+ auto [idx, target, diff] = flow::select_forced_strict_and_child(flow::DirectAdapter(), data, next);
+ if (diff >= 0.0) {
break;
}
auto pos = data.begin() + idx;
diff --git a/searchlib/src/tests/queryeval/iterator_benchmark/attribute_ctx_builder.cpp b/searchlib/src/tests/queryeval/iterator_benchmark/attribute_ctx_builder.cpp
index 6a2b306522d..5a0bda49b98 100644
--- a/searchlib/src/tests/queryeval/iterator_benchmark/attribute_ctx_builder.cpp
+++ b/searchlib/src/tests/queryeval/iterator_benchmark/attribute_ctx_builder.cpp
@@ -18,30 +18,71 @@ namespace {
template <typename AttributeType, bool is_string, bool is_multivalue>
void
+update_attribute(AttributeType& attr, uint32_t docid, uint32_t value)
+{
+ if constexpr (is_string) {
+ if constexpr (is_multivalue) {
+ attr.append(docid, std::to_string(value), random_int(1, 100));
+ } else {
+ attr.update(docid, std::to_string(value));
+ }
+ } else {
+ if constexpr (is_multivalue) {
+ attr.append(docid, value, random_int(1, 100));
+ } else {
+ attr.update(docid, value);
+ }
+ }
+}
+
+template <typename AttributeType, bool is_string, bool is_multivalue>
+void
populate_attribute(AttributeType& attr, uint32_t docid_limit, const HitSpecs& hit_specs)
{
for (auto spec : hit_specs) {
auto docids = random_docids(docid_limit, spec.num_hits);
docids->foreach_truebit([&](uint32_t docid) {
- if constexpr (is_string) {
- if constexpr (is_multivalue) {
- attr.append(docid, std::to_string(spec.term_value), random_int(1, 100));
- } else {
- attr.update(docid, std::to_string(spec.term_value));
- }
- } else {
- if constexpr (is_multivalue) {
- attr.append(docid, spec.term_value, random_int(1, 100));
- } else {
- attr.update(docid, spec.term_value);
- }
- }
+ update_attribute<AttributeType, is_string, is_multivalue>(attr, docid, spec.term_value);
});
}
}
+template <typename AttributeType, bool is_string, bool is_multivalue>
+void
+populate_attribute(AttributeType& attr, const std::vector<uint32_t>& values)
+{
+ for (uint32_t docid = 1; docid < values.size(); ++docid) {
+ uint32_t value = values[docid];
+ if (value == 0) {
+ continue;
+ }
+ update_attribute<AttributeType, is_string, is_multivalue>(attr, docid, value);
+ }
+}
+
+template <typename AttributeType, bool is_string, bool is_multivalue>
+void
+populate_attribute(AttributeType& attr, uint32_t docid_limit, const HitSpecs& hit_specs, bool disjunct_terms)
+{
+ if (disjunct_terms) {
+ // Ensure that each term in HitSpecs is matched by a disjunct (random) subset of docids.
+ std::vector<uint32_t> values(docid_limit, 0);
+ uint32_t docid = 1;
+ for (auto spec : hit_specs) {
+ assert((docid + spec.num_hits) <= docid_limit);
+ std::fill_n(values.begin() + docid, spec.num_hits, spec.term_value);
+ docid += spec.num_hits;
+ }
+ std::shuffle(values.begin() + 1, values.end(), get_gen());
+ populate_attribute<AttributeType, is_string, is_multivalue>(attr, values);
+ } else {
+ // For each term in HitSpecs we draw a new random set of docids that will match this term value.
+ populate_attribute<AttributeType, is_string, is_multivalue>(attr, docid_limit, hit_specs);
+ }
+}
+
AttributeVector::SP
-make_attribute(const Config& cfg, vespalib::stringref field_name, uint32_t num_docs, const HitSpecs& hit_specs)
+make_attribute(const Config& cfg, vespalib::stringref field_name, uint32_t num_docs, const HitSpecs& hit_specs, bool disjunct_terms)
{
auto attr = AttributeFactory::createAttribute(field_name, cfg);
attr->addReservedDoc();
@@ -52,16 +93,16 @@ make_attribute(const Config& cfg, vespalib::stringref field_name, uint32_t num_d
if (attr->isStringType()) {
auto& real = dynamic_cast<StringAttribute&>(*attr);
if (is_multivalue) {
- populate_attribute<StringAttribute, true, true>(real, docid_limit, hit_specs);
+ populate_attribute<StringAttribute, true, true>(real, docid_limit, hit_specs, disjunct_terms);
} else {
- populate_attribute<StringAttribute, true, false>(real, docid_limit, hit_specs);
+ populate_attribute<StringAttribute, true, false>(real, docid_limit, hit_specs, disjunct_terms);
}
} else {
auto& real = dynamic_cast<IntegerAttribute&>(*attr);
if (is_multivalue) {
- populate_attribute<IntegerAttribute, false, true>(real, docid_limit, hit_specs);
+ populate_attribute<IntegerAttribute, false, true>(real, docid_limit, hit_specs, disjunct_terms);
} else {
- populate_attribute<IntegerAttribute, false, false>(real, docid_limit, hit_specs);
+ populate_attribute<IntegerAttribute, false, false>(real, docid_limit, hit_specs, disjunct_terms);
}
}
attr->commit(true);
@@ -90,9 +131,9 @@ AttributeContextBuilder::AttributeContextBuilder()
}
void
-AttributeContextBuilder::add(const search::attribute::Config& cfg, vespalib::stringref field_name, uint32_t num_docs, const HitSpecs& hit_specs)
+AttributeContextBuilder::add(const search::attribute::Config& cfg, vespalib::stringref field_name, uint32_t num_docs, const HitSpecs& hit_specs, bool disjunct_terms)
{
- auto attr = make_attribute(cfg, field_name, num_docs, hit_specs);
+ auto attr = make_attribute(cfg, field_name, num_docs, hit_specs, disjunct_terms);
_ctx->add(std::move(attr));
}
diff --git a/searchlib/src/tests/queryeval/iterator_benchmark/attribute_ctx_builder.h b/searchlib/src/tests/queryeval/iterator_benchmark/attribute_ctx_builder.h
index e4a58c91668..7e5236e43be 100644
--- a/searchlib/src/tests/queryeval/iterator_benchmark/attribute_ctx_builder.h
+++ b/searchlib/src/tests/queryeval/iterator_benchmark/attribute_ctx_builder.h
@@ -19,7 +19,7 @@ private:
public:
AttributeContextBuilder();
- void add(const search::attribute::Config& cfg, vespalib::stringref field_name, uint32_t num_docs, const HitSpecs& hit_specs);
+ void add(const search::attribute::Config& cfg, vespalib::stringref field_name, uint32_t num_docs, const HitSpecs& hit_specs, bool disjunct_terms);
std::unique_ptr<BenchmarkSearchable> build();
};
diff --git a/searchlib/src/tests/queryeval/iterator_benchmark/benchmark_blueprint_factory.cpp b/searchlib/src/tests/queryeval/iterator_benchmark/benchmark_blueprint_factory.cpp
index 516a819aae8..0496a0e6dc8 100644
--- a/searchlib/src/tests/queryeval/iterator_benchmark/benchmark_blueprint_factory.cpp
+++ b/searchlib/src/tests/queryeval/iterator_benchmark/benchmark_blueprint_factory.cpp
@@ -42,11 +42,11 @@ calc_hits_per_term(uint32_t num_docs, double op_hit_ratio, uint32_t children, Qu
}
std::unique_ptr<BenchmarkSearchable>
-make_searchable(const FieldConfig& cfg, uint32_t num_docs, const HitSpecs& hit_specs)
+make_searchable(const FieldConfig& cfg, uint32_t num_docs, const HitSpecs& hit_specs, bool disjunct_terms)
{
if (cfg.is_attr()) {
AttributeContextBuilder builder;
- builder.add(cfg.attr_cfg(), field_name, num_docs, hit_specs);
+ builder.add(cfg.attr_cfg(), field_name, num_docs, hit_specs, disjunct_terms);
return builder.build();
} else {
uint32_t docid_limit = num_docs + 1;
@@ -159,14 +159,14 @@ private:
public:
MyFactory(const FieldConfig& field_cfg, QueryOperator query_op,
uint32_t num_docs, uint32_t default_values_per_document,
- double op_hit_ratio, uint32_t children);
+ double op_hit_ratio, uint32_t children, bool disjunct_children);
std::unique_ptr<Blueprint> make_blueprint() override;
};
MyFactory::MyFactory(const FieldConfig& field_cfg, QueryOperator query_op,
uint32_t num_docs, uint32_t default_values_per_document,
- double op_hit_ratio, uint32_t children)
+ double op_hit_ratio, uint32_t children, bool disjunct_children)
: _query_op(query_op),
_docid_limit(num_docs + 1),
_terms(),
@@ -174,9 +174,17 @@ MyFactory::MyFactory(const FieldConfig& field_cfg, QueryOperator query_op,
{
uint32_t hits_per_term = calc_hits_per_term(num_docs, op_hit_ratio, children, query_op);
HitSpecs hit_specs(55555);
- hit_specs.add(default_values_per_document, num_docs);
+ if (!disjunct_children) {
+ hit_specs.add(default_values_per_document, num_docs);
+ }
_terms = hit_specs.add(children, hits_per_term);
- _searchable = make_searchable(field_cfg, num_docs, hit_specs);
+ if (disjunct_children && default_values_per_document != 0) {
+ // This ensures that the remaining docids are populated with a "default value".
+ // Only a single default value is supported.
+ uint32_t op_num_hits = num_docs * op_hit_ratio;
+ hit_specs.add(1, num_docs - op_num_hits);
+ }
+ _searchable = make_searchable(field_cfg, num_docs, hit_specs, disjunct_children);
}
std::unique_ptr<Blueprint>
@@ -190,9 +198,9 @@ MyFactory::make_blueprint()
std::unique_ptr<BenchmarkBlueprintFactory>
make_blueprint_factory(const FieldConfig& field_cfg, QueryOperator query_op,
uint32_t num_docs, uint32_t default_values_per_document,
- double op_hit_ratio, uint32_t children)
+ double op_hit_ratio, uint32_t children, bool disjunct_children)
{
- return std::make_unique<MyFactory>(field_cfg, query_op, num_docs, default_values_per_document, op_hit_ratio, children);
+ return std::make_unique<MyFactory>(field_cfg, query_op, num_docs, default_values_per_document, op_hit_ratio, children, disjunct_children);
}
}
diff --git a/searchlib/src/tests/queryeval/iterator_benchmark/benchmark_blueprint_factory.h b/searchlib/src/tests/queryeval/iterator_benchmark/benchmark_blueprint_factory.h
index d3e529fcd65..423f517ffb0 100644
--- a/searchlib/src/tests/queryeval/iterator_benchmark/benchmark_blueprint_factory.h
+++ b/searchlib/src/tests/queryeval/iterator_benchmark/benchmark_blueprint_factory.h
@@ -21,6 +21,6 @@ public:
std::unique_ptr<BenchmarkBlueprintFactory>
make_blueprint_factory(const FieldConfig& field_cfg, QueryOperator query_op,
uint32_t num_docs, uint32_t default_values_per_document,
- double op_hit_ratio, uint32_t children);
+ double op_hit_ratio, uint32_t children, bool disjunct_children);
}
diff --git a/searchlib/src/tests/queryeval/iterator_benchmark/common.cpp b/searchlib/src/tests/queryeval/iterator_benchmark/common.cpp
index f17403bd33a..c67a5ee1074 100644
--- a/searchlib/src/tests/queryeval/iterator_benchmark/common.cpp
+++ b/searchlib/src/tests/queryeval/iterator_benchmark/common.cpp
@@ -1,7 +1,6 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "common.h"
-#include <random>
#include <sstream>
using search::attribute::CollectionType;
@@ -49,6 +48,8 @@ std::mt19937 gen(default_seed);
}
+std::mt19937& get_gen() { return gen; }
+
BitVector::UP
random_docids(uint32_t docid_limit, uint32_t count)
{
diff --git a/searchlib/src/tests/queryeval/iterator_benchmark/common.h b/searchlib/src/tests/queryeval/iterator_benchmark/common.h
index 45fd82b091c..bf16e6f51d7 100644
--- a/searchlib/src/tests/queryeval/iterator_benchmark/common.h
+++ b/searchlib/src/tests/queryeval/iterator_benchmark/common.h
@@ -5,6 +5,7 @@
#include <vespa/searchcommon/attribute/config.h>
#include <vespa/searchcommon/common/schema.h>
#include <vespa/searchlib/common/bitvector.h>
+#include <random>
#include <variant>
namespace search::queryeval::test {
@@ -78,6 +79,8 @@ public:
auto end() const { return _specs.end(); }
};
+std::mt19937& get_gen();
+
BitVector::UP random_docids(uint32_t docid_limit, uint32_t count);
int32_t random_int(int32_t a, int32_t b);
diff --git a/searchlib/src/tests/queryeval/iterator_benchmark/iterator_benchmark_test.cpp b/searchlib/src/tests/queryeval/iterator_benchmark/iterator_benchmark_test.cpp
index b08fde50d7c..c6dae52fd69 100644
--- a/searchlib/src/tests/queryeval/iterator_benchmark/iterator_benchmark_test.cpp
+++ b/searchlib/src/tests/queryeval/iterator_benchmark/iterator_benchmark_test.cpp
@@ -31,25 +31,22 @@ struct BenchmarkResult {
uint32_t hits;
FlowStats flow;
double actual_cost;
- double alt_cost;
vespalib::string iterator_name;
vespalib::string blueprint_name;
- BenchmarkResult() : BenchmarkResult(0, 0, 0, {0, 0, 0}, 0, 0, "", "") {}
- BenchmarkResult(double time_ms_in, uint32_t seeks_in, uint32_t hits_in, FlowStats flow_in, double actual_cost_in, double alt_cost_in,
+ BenchmarkResult() : BenchmarkResult(0, 0, 0, {0, 0, 0}, 0, "", "") {}
+ BenchmarkResult(double time_ms_in, uint32_t seeks_in, uint32_t hits_in, FlowStats flow_in, double actual_cost_in,
const vespalib::string& iterator_name_in, const vespalib::string& blueprint_name_in)
: time_ms(time_ms_in),
seeks(seeks_in),
hits(hits_in),
flow(flow_in),
actual_cost(actual_cost_in),
- alt_cost(alt_cost_in),
iterator_name(iterator_name_in),
blueprint_name(blueprint_name_in)
{}
~BenchmarkResult();
double ns_per_seek() const { return (time_ms / seeks) * 1000.0 * 1000.0; }
double ms_per_actual_cost() const { return (time_ms / actual_cost); }
- double ms_per_alt_cost() const { return (time_ms / alt_cost); }
};
BenchmarkResult::~BenchmarkResult() = default;
@@ -128,9 +125,6 @@ public:
Stats ms_per_actual_cost_stats() const {
return calc_stats([](const auto& res){ return res.ms_per_actual_cost(); });
}
- Stats ms_per_alt_cost_stats() const {
- return calc_stats([](const auto& res){ return res.ms_per_alt_cost(); });
- }
};
std::string
@@ -222,7 +216,7 @@ strict_search(BenchmarkBlueprintFactory& factory, uint32_t docid_limit)
timer.after();
}
FlowStats flow(ctx.blueprint->estimate(), ctx.blueprint->cost(), ctx.blueprint->strict_cost());
- return {timer.min_time() * 1000.0, hits + 1, hits, flow, flow.strict_cost, flow.strict_cost, get_class_name(*ctx.iterator), get_class_name(*ctx.blueprint)};
+ return {timer.min_time() * 1000.0, hits + 1, hits, flow, flow.strict_cost, get_class_name(*ctx.iterator), get_class_name(*ctx.blueprint)};
}
template <bool do_unpack>
@@ -256,9 +250,7 @@ non_strict_search(BenchmarkBlueprintFactory& factory, uint32_t docid_limit, doub
}
FlowStats flow(ctx.blueprint->estimate(), ctx.blueprint->cost(), ctx.blueprint->strict_cost());
double actual_cost = flow.cost * filter_hit_ratio;
- // This is an attempt to calculate an alternative actual cost for strict / posting list iterators that are used in a non-strict context.
- double alt_cost = flow.strict_cost + 0.5 * filter_hit_ratio;
- return {timer.min_time() * 1000.0, seeks, hits, flow, actual_cost, alt_cost, get_class_name(*ctx.iterator), get_class_name(*ctx.blueprint)};
+ return {timer.min_time() * 1000.0, seeks, hits, flow, actual_cost, get_class_name(*ctx.iterator), get_class_name(*ctx.blueprint)};
}
BenchmarkResult
@@ -413,32 +405,30 @@ to_string(bool val)
void
print_result_header()
{
- std::cout << "| chn | f_ratio | o_ratio | a_ratio | f.est | f.cost | f.scost | hits | seeks | time_ms | act_cost | alt_cost | ns_per_seek | ms_per_act_cost | ms_per_alt_cost | iterator | blueprint |" << std::endl;
+ std::cout << "| chn | f_ratio | o_ratio | a_ratio | f.est | f.cost | f.scost | hits | seeks | time_ms | act_cost | ns_per_seek | ms_per_act_cost | iterator | blueprint |" << std::endl;
}
void
print_result(const BenchmarkResult& res, uint32_t children, double op_hit_ratio, double filter_hit_ratio, uint32_t num_docs)
{
std::cout << std::fixed << std::setprecision(5)
- << "| " << std::setw(4) << children
+ << "| " << std::setw(5) << children
<< " | " << std::setw(7) << filter_hit_ratio
<< " | " << std::setw(7) << op_hit_ratio
<< " | " << std::setw(7) << ((double) res.hits / (double) num_docs)
<< " | " << std::setw(6) << res.flow.estimate
<< std::setprecision(4)
- << " | " << std::setw(7) << res.flow.cost
+ << " | " << std::setw(9) << res.flow.cost
<< " | " << std::setw(7) << res.flow.strict_cost
<< " | " << std::setw(8) << res.hits
<< " | " << std::setw(8) << res.seeks
<< std::setprecision(3)
<< " | " << std::setw(8) << res.time_ms
<< std::setprecision(4)
- << " | " << std::setw(8) << res.actual_cost
- << " | " << std::setw(8) << res.alt_cost
+ << " | " << std::setw(9) << res.actual_cost
<< std::setprecision(2)
<< " | " << std::setw(11) << res.ns_per_seek()
<< " | " << std::setw(15) << res.ms_per_actual_cost()
- << " | " << std::setw(15) << res.ms_per_alt_cost()
<< " | " << res.iterator_name
<< " | " << res.blueprint_name << " |" << std::endl;
}
@@ -449,8 +439,7 @@ print_result(const BenchmarkCaseResult& result)
std::cout << std::fixed << std::setprecision(3)
<< "summary: time_ms=" << result.time_ms_stats().to_string() << std::endl
<< " ns_per_seek=" << result.ns_per_seek_stats().to_string() << std::endl
- << " ms_per_act_cost=" << result.ms_per_actual_cost_stats().to_string() << std::endl
- << " ms_per_alt_cost=" << result.ms_per_alt_cost_stats().to_string() << std::endl << std::endl;
+ << " ms_per_act_cost=" << result.ms_per_actual_cost_stats().to_string() << std::endl << std::endl;
}
struct BenchmarkCase {
@@ -534,6 +523,7 @@ struct BenchmarkCaseSetup {
std::vector<uint32_t> child_counts;
std::vector<double> filter_hit_ratios;
uint32_t default_values_per_document;
+ bool disjunct_children;
double filter_crossover_factor;
BenchmarkCaseSetup(uint32_t num_docs_in,
const BenchmarkCase& bcase_in,
@@ -545,6 +535,7 @@ struct BenchmarkCaseSetup {
child_counts(child_counts_in),
filter_hit_ratios({1.0}),
default_values_per_document(0),
+ disjunct_children(false),
filter_crossover_factor(0.0)
{}
~BenchmarkCaseSetup() {}
@@ -561,6 +552,7 @@ struct BenchmarkSetup {
bool force_strict;
bool unpack_iterator;
uint32_t default_values_per_document;
+ bool disjunct_children;
double filter_crossover_factor;
BenchmarkSetup(uint32_t num_docs_in,
const std::vector<FieldConfig>& field_cfgs_in,
@@ -578,6 +570,7 @@ struct BenchmarkSetup {
force_strict(false),
unpack_iterator(false),
default_values_per_document(0),
+ disjunct_children(false),
filter_crossover_factor(0.0)
{}
BenchmarkSetup(uint32_t num_docs_in,
@@ -592,6 +585,7 @@ struct BenchmarkSetup {
res.bcase.force_strict = force_strict;
res.bcase.unpack_iterator = unpack_iterator;
res.default_values_per_document = default_values_per_document;
+ res.disjunct_children = disjunct_children;
if (!bcase.strict_context) {
// Simulation of a filter is only relevant in a non-strict context.
res.filter_hit_ratios = filter_hit_ratios;
@@ -617,7 +611,7 @@ run_benchmark_case(const BenchmarkCaseSetup& setup)
for (uint32_t children : setup.child_counts) {
auto factory = make_blueprint_factory(setup.bcase.field_cfg, setup.bcase.query_op,
setup.num_docs, setup.default_values_per_document,
- op_hit_ratio, children);
+ op_hit_ratio, children, setup.disjunct_children);
for (double filter_hit_ratio : setup.filter_hit_ratios) {
if (filter_hit_ratio * setup.filter_crossover_factor <= op_hit_ratio) {
auto res = benchmark_search(*factory, setup.num_docs + 1,
@@ -726,6 +720,22 @@ TEST(IteratorBenchmark, analyze_term_search_in_fast_search_attributes)
run_benchmarks(setup, global_summary);
}
+TEST(IteratorBenchmark, analyze_in_operator_non_strict)
+{
+ const std::vector<double> hit_ratios = {0.001, 0.01, 0.1, 0.2, 0.4, 0.6, 0.8};
+ BenchmarkSetup setup(num_docs, {int32_fs}, {QueryOperator::In}, {false}, hit_ratios, {5, 9, 10, 100, 1000, 10000});
+ setup.disjunct_children = true;
+ run_benchmarks(setup);
+}
+
+TEST(IteratorBenchmark, analyze_in_operator_strict)
+{
+ const std::vector<double> hit_ratios = {0.001, 0.01, 0.1, 0.2, 0.4, 0.6, 0.8};
+ BenchmarkSetup setup(num_docs, {int32_fs}, {QueryOperator::In}, {true}, hit_ratios, {5, 9, 10, 100, 1000, 10000});
+ setup.disjunct_children = true;
+ run_benchmarks(setup);
+}
+
TEST(IteratorBenchmark, analyze_complex_leaf_operators)
{
std::vector<FieldConfig> field_cfgs = {int32_array_fs};
@@ -764,18 +774,18 @@ TEST(IteratorBenchmark, or_benchmark)
TEST(IteratorBenchmark, or_vs_filter_crossover)
{
- auto fixed_or = make_blueprint_factory(int32_array_fs, QueryOperator::Or, num_docs, 0, 0.1, 100);
+ auto fixed_or = make_blueprint_factory(int32_array_fs, QueryOperator::Or, num_docs, 0, 0.1, 100, false);
auto variable_term = [](double rate) {
- return make_blueprint_factory(int32_array_fs, QueryOperator::Term, num_docs, 0, rate, 1);
+ return make_blueprint_factory(int32_array_fs, QueryOperator::Term, num_docs, 0, rate, 1, false);
};
analyze_crossover(*fixed_or, variable_term, num_docs + 1, false, 0.0001);
}
TEST(IteratorBenchmark, or_vs_filter_crossover_with_allow_force_strict)
{
- auto fixed_or = make_blueprint_factory(int32_array_fs, QueryOperator::Or, num_docs, 0, 0.1, 100);
+ auto fixed_or = make_blueprint_factory(int32_array_fs, QueryOperator::Or, num_docs, 0, 0.1, 100, false);
auto variable_term = [](double rate) {
- return make_blueprint_factory(int32_array_fs, QueryOperator::Term, num_docs, 0, rate, 1);
+ return make_blueprint_factory(int32_array_fs, QueryOperator::Term, num_docs, 0, rate, 1, false);
};
analyze_crossover(*fixed_or, variable_term, num_docs + 1, true, 0.0001);
}
diff --git a/searchlib/src/vespa/searchlib/queryeval/flow.h b/searchlib/src/vespa/searchlib/queryeval/flow.h
index b57e823f4d7..9ac79244755 100644
--- a/searchlib/src/vespa/searchlib/queryeval/flow.h
+++ b/searchlib/src/vespa/searchlib/queryeval/flow.h
@@ -214,44 +214,39 @@ size_t select_strict_and_child(auto adapter, const auto &children) {
return best_idx;
}
-auto select_forced_strict_and_child_impl(auto adapter, const auto &children, size_t first, auto ordered, auto destructive) {
- auto est_until = [&](size_t limit)noexcept{
- double my_est = 1.0;
- for (size_t i = 0; i < limit; ++i) {
- my_est *= adapter.estimate(children[i]);
- }
- return my_est;
- };
- double est = est_until(first);
+auto select_forced_strict_and_child(auto adapter, const auto &children, size_t first) {
+ double est = 1.0;
double cost = 0.0;
size_t best_idx = first;
size_t best_target = first;
double best_diff = std::numeric_limits<double>::max();
+ for (size_t i = 0; i < first; ++i) {
+ est *= adapter.estimate(children[i]);
+ }
for (size_t idx = first; idx < children.size(); ++idx) {
auto child = FlowStats::from(adapter, children[idx]);
double child_abs_cost = est * child.cost;
double forced_cost = forced_strict_cost(child, est);
double my_diff = (forced_cost + child.estimate * cost) - (cost + child_abs_cost);
size_t target = first;
- while (ordered && target > 0) {
+ while (target > 0) {
size_t candidate = target - 1;
auto other = FlowStats::from(adapter, children[candidate]);
if (other.estimate < child.estimate) {
// do not move past someone with lower estimate
break;
}
- if (!destructive && !should_force_strict(other, (est_until(candidate) * child.estimate))) {
- // no not move past someone who will lose strictness,
- // unless it is explicitly allowed by enabling
- // destructive (re-)ordering
- break;
- }
target = candidate;
my_diff += (0.2 * child.estimate - 0.2 * other.estimate);
if (candidate == 0) {
// the first iterator produces its own in-flow
my_diff += (0.2 * child.estimate - 0.2 * other.estimate);
}
+ // note that 'my_diff' might overestimate the cost
+ // (underestimate the benefit) of inserting 'child' before
+ // 'other' if it leads to 'other' becoming
+ // non-strict. This will also leave 'other' in a
+ // potentially unoptimal location.
}
if (my_diff < best_diff) {
best_diff = my_diff;
@@ -264,19 +259,6 @@ auto select_forced_strict_and_child_impl(auto adapter, const auto &children, siz
return std::make_tuple(best_idx, best_target, best_diff);
}
-auto select_forced_strict_and_child(auto adapter, const auto &children, size_t first) {
- auto [idx, target, diff] = select_forced_strict_and_child_impl(adapter, children, first, std::false_type{}, std::false_type{});
- return std::make_pair(idx, diff);
-}
-
-auto select_forced_strict_and_child_with_order(auto adapter, const auto &children, size_t first) {
- return select_forced_strict_and_child_impl(adapter, children, first, std::true_type{}, std::false_type{});
-}
-
-auto select_forced_strict_and_child_with_destructive_order(auto adapter, const auto &children, size_t first) {
- return select_forced_strict_and_child_impl(adapter, children, first, std::true_type{}, std::true_type{});
-}
-
} // flow
template <typename FLOW>