This is an automated email from the ASF dual-hosted git repository.
Jackie-Jiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new 673828c7c2e Replace SingleValueVisitor/MultiValueVisitor with
per-predicate visitors (#18297)
673828c7c2e is described below
commit 673828c7c2effcff254a36ac81614b431d798dd3
Author: Xiaotian (Jackie) Jiang <[email protected]>
AuthorDate: Thu Apr 23 00:20:38 2026 -0700
Replace SingleValueVisitor/MultiValueVisitor with per-predicate visitors
(#18297)
Each raw predicate evaluator (EQ, NOT_EQ, IN, NOT_IN, RANGE) now defines its
own nested Visitor<R> interface whose methods match the shape of the
predicate:
- EQ/NOT_EQ: single (non-)matching value
- IN/NOT_IN: (non-)matching values delivered as the underlying typed set
(IntSet, LongSet, ..., SortedSet<BigDecimal>, Set<String>,
Set<ByteArray>),
avoiding array conversions at the accept callsite
- RANGE: inclusive bounds for int/long/float/double; lower/upper with
inclusivity flags for BigDecimal/String/Bytes (new - RANGE previously had
no visitor)
Removed the shared SingleValueVisitor and MultiValueVisitor interfaces from
pinot-spi along with their never-reached
visitBoolean/visitTimestamp/visitJson
methods (BOOLEAN/TIMESTAMP/JSON are always routed through the
Int/Long/String
evaluators).
Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
---
.../predicate/EqualsPredicateEvaluatorFactory.java | 47 +++++-----
.../predicate/InPredicateEvaluatorFactory.java | 57 ++++++++-----
.../NotEqualsPredicateEvaluatorFactory.java | 42 +++++----
.../predicate/NotInPredicateEvaluatorFactory.java | 57 ++++++++-----
.../predicate/RangePredicateEvaluatorFactory.java | 98 +++++++++++++++++++--
.../predicate/InPredicateEvaluatorFactoryTest.java | 79 ++++++++---------
.../apache/pinot/spi/data/MultiValueVisitor.java | 99 ----------------------
.../apache/pinot/spi/data/SingleValueVisitor.java | 45 ----------
8 files changed, 248 insertions(+), 276 deletions(-)
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/EqualsPredicateEvaluatorFactory.java
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/EqualsPredicateEvaluatorFactory.java
index d99b8249d45..1bfe549b00e 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/EqualsPredicateEvaluatorFactory.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/EqualsPredicateEvaluatorFactory.java
@@ -28,8 +28,6 @@ import
org.apache.pinot.core.operator.filter.predicate.traits.IntValue;
import org.apache.pinot.core.operator.filter.predicate.traits.LongValue;
import org.apache.pinot.segment.spi.index.reader.Dictionary;
import org.apache.pinot.spi.data.FieldSpec.DataType;
-import org.apache.pinot.spi.data.MultiValueVisitor;
-import org.apache.pinot.spi.data.SingleValueVisitor;
import org.apache.pinot.spi.utils.BooleanUtils;
import org.apache.pinot.spi.utils.BytesUtils;
import org.apache.pinot.spi.utils.TimestampUtils;
@@ -147,16 +145,24 @@ public class EqualsPredicateEvaluatorFactory {
super(predicate);
}
- /**
- * Visits the matching value of this predicate.
- */
- public abstract <R> R accept(SingleValueVisitor<R> visitor);
+ /// Visits the matching value of this predicate.
+ public abstract <R> R accept(Visitor<R> visitor);
- /**
- * Visits the matching value of this predicate, which will be transformed
into an array with a single value.
- */
- public <R> R accept(MultiValueVisitor<R> visitor) {
- return accept(visitor.asSingleValueVisitor());
+ /// Visitor for the matching value of an EQ predicate, dispatched by the
stored value type.
+ public interface Visitor<R> {
+ R visitInt(int matchingValue);
+
+ R visitLong(long matchingValue);
+
+ R visitFloat(float matchingValue);
+
+ R visitDouble(double matchingValue);
+
+ R visitBigDecimal(BigDecimal matchingValue);
+
+ R visitString(String matchingValue);
+
+ R visitBytes(byte[] matchingValue);
}
}
@@ -169,7 +175,7 @@ public class EqualsPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(SingleValueVisitor<R> visitor) {
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visitInt(_matchingValue);
}
@@ -217,15 +223,10 @@ public class EqualsPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(SingleValueVisitor<R> visitor) {
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visitLong(_matchingValue);
}
- @Override
- public <R> R accept(MultiValueVisitor<R> visitor) {
- return visitor.asSingleValueVisitor().visitLong(_matchingValue);
- }
-
@Override
public int getNumMatchingItems() {
return 1;
@@ -270,7 +271,7 @@ public class EqualsPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(SingleValueVisitor<R> visitor) {
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visitFloat(_matchingValue);
}
@@ -318,7 +319,7 @@ public class EqualsPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(SingleValueVisitor<R> visitor) {
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visitDouble(_matchingValue);
}
@@ -365,7 +366,7 @@ public class EqualsPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(SingleValueVisitor<R> visitor) {
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visitBigDecimal(_matchingValue);
}
@@ -394,7 +395,7 @@ public class EqualsPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(SingleValueVisitor<R> visitor) {
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visitString(_matchingValue);
}
@@ -423,7 +424,7 @@ public class EqualsPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(SingleValueVisitor<R> visitor) {
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visitBytes(_matchingValue);
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/InPredicateEvaluatorFactory.java
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/InPredicateEvaluatorFactory.java
index ed7fb5273ff..ebf6b5839fd 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/InPredicateEvaluatorFactory.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/InPredicateEvaluatorFactory.java
@@ -31,6 +31,7 @@ import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
+import java.util.SortedSet;
import java.util.TreeSet;
import javax.annotation.Nullable;
import org.apache.pinot.common.request.context.predicate.InPredicate;
@@ -39,7 +40,6 @@ import org.apache.pinot.common.utils.HashUtil;
import org.apache.pinot.core.query.request.context.QueryContext;
import org.apache.pinot.segment.spi.index.reader.Dictionary;
import org.apache.pinot.spi.data.FieldSpec.DataType;
-import org.apache.pinot.spi.data.MultiValueVisitor;
import org.apache.pinot.spi.utils.ByteArray;
@@ -206,10 +206,28 @@ public class InPredicateEvaluatorFactory {
super(predicate);
}
- /**
- * Visits the matching value of this predicate.
- */
- public abstract <R> R accept(MultiValueVisitor<R> visitor);
+ /// Visits the matching values of this predicate.
+ public abstract <R> R accept(Visitor<R> visitor);
+
+ /// Visitor for the matching values of an IN predicate, dispatched by the
stored value type.
+ ///
+ /// The `BigDecimal` matching values are delivered in a [SortedSet]
because `BigDecimal`'s `compareTo` is not
+ /// consistent with `equals` (e.g. `3.0` and `3` compare equal).
+ public interface Visitor<R> {
+ R visitInt(IntSet matchingValues);
+
+ R visitLong(LongSet matchingValues);
+
+ R visitFloat(FloatSet matchingValues);
+
+ R visitDouble(DoubleSet matchingValues);
+
+ R visitBigDecimal(SortedSet<BigDecimal> matchingValues);
+
+ R visitString(Set<String> matchingValues);
+
+ R visitBytes(Set<ByteArray> matchingValues);
+ }
}
private static final class IntRawValueBasedInPredicateEvaluator extends
InRawPredicateEvaluator {
@@ -249,8 +267,8 @@ public class InPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(MultiValueVisitor<R> visitor) {
- return visitor.visitInt(_matchingValues.toIntArray());
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitInt(_matchingValues);
}
}
@@ -291,8 +309,8 @@ public class InPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(MultiValueVisitor<R> visitor) {
- return visitor.visitLong(_matchingValues.toLongArray());
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitLong(_matchingValues);
}
}
@@ -333,8 +351,8 @@ public class InPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(MultiValueVisitor<R> visitor) {
- return visitor.visitFloat(_matchingValues.toFloatArray());
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitFloat(_matchingValues);
}
}
@@ -375,8 +393,8 @@ public class InPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(MultiValueVisitor<R> visitor) {
- return visitor.visitDouble(_matchingValues.toDoubleArray());
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitDouble(_matchingValues);
}
}
@@ -410,8 +428,8 @@ public class InPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(MultiValueVisitor<R> visitor) {
- return visitor.visitBigDecimal(_matchingValues.toArray(new
BigDecimal[0]));
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitBigDecimal(_matchingValues);
}
}
@@ -439,8 +457,8 @@ public class InPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(MultiValueVisitor<R> visitor) {
- return visitor.visitString(_matchingValues.toArray(new String[0]));
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitString(_matchingValues);
}
}
@@ -468,9 +486,8 @@ public class InPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(MultiValueVisitor<R> visitor) {
- byte[][] bytes =
_matchingValues.stream().map(ByteArray::getBytes).toArray(byte[][]::new);
- return visitor.visitBytes(bytes);
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitBytes(_matchingValues);
}
}
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/NotEqualsPredicateEvaluatorFactory.java
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/NotEqualsPredicateEvaluatorFactory.java
index 742b69c1b19..e5539076e26 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/NotEqualsPredicateEvaluatorFactory.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/NotEqualsPredicateEvaluatorFactory.java
@@ -24,8 +24,6 @@ import
org.apache.pinot.common.request.context.predicate.NotEqPredicate;
import org.apache.pinot.common.request.context.predicate.Predicate;
import org.apache.pinot.segment.spi.index.reader.Dictionary;
import org.apache.pinot.spi.data.FieldSpec.DataType;
-import org.apache.pinot.spi.data.MultiValueVisitor;
-import org.apache.pinot.spi.data.SingleValueVisitor;
import org.apache.pinot.spi.utils.BooleanUtils;
import org.apache.pinot.spi.utils.BytesUtils;
import org.apache.pinot.spi.utils.TimestampUtils;
@@ -137,16 +135,24 @@ public class NotEqualsPredicateEvaluatorFactory {
super(predicate);
}
- /**
- * Visits the not matching value of this predicate.
- */
- public abstract <R> R accept(SingleValueVisitor<R> visitor);
+ /// Visits the non-matching value of this predicate.
+ public abstract <R> R accept(Visitor<R> visitor);
- /**
- * Visits the not matching value of this predicate, which will be
transformed into an array with a single value.
- */
- public <R> R accept(MultiValueVisitor<R> visitor) {
- return accept(visitor.asSingleValueVisitor());
+ /// Visitor for the non-matching value of a NOT_EQ predicate, dispatched
by the stored value type.
+ public interface Visitor<R> {
+ R visitInt(int nonMatchingValue);
+
+ R visitLong(long nonMatchingValue);
+
+ R visitFloat(float nonMatchingValue);
+
+ R visitDouble(double nonMatchingValue);
+
+ R visitBigDecimal(BigDecimal nonMatchingValue);
+
+ R visitString(String nonMatchingValue);
+
+ R visitBytes(byte[] nonMatchingValue);
}
}
@@ -187,7 +193,7 @@ public class NotEqualsPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(SingleValueVisitor<R> visitor) {
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visitInt(_nonMatchingValue);
}
}
@@ -229,7 +235,7 @@ public class NotEqualsPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(SingleValueVisitor<R> visitor) {
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visitLong(_nonMatchingValue);
}
}
@@ -271,7 +277,7 @@ public class NotEqualsPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(SingleValueVisitor<R> visitor) {
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visitFloat(_nonMatchingValue);
}
}
@@ -313,7 +319,7 @@ public class NotEqualsPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(SingleValueVisitor<R> visitor) {
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visitDouble(_nonMatchingValue);
}
}
@@ -342,7 +348,7 @@ public class NotEqualsPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(SingleValueVisitor<R> visitor) {
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visitBigDecimal(_nonMatchingValue);
}
}
@@ -371,7 +377,7 @@ public class NotEqualsPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(SingleValueVisitor<R> visitor) {
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visitString(_nonMatchingValue);
}
}
@@ -400,7 +406,7 @@ public class NotEqualsPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(SingleValueVisitor<R> visitor) {
+ public <R> R accept(Visitor<R> visitor) {
return visitor.visitBytes(_nonMatchingValue);
}
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/NotInPredicateEvaluatorFactory.java
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/NotInPredicateEvaluatorFactory.java
index daabde10694..2cdf47874e5 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/NotInPredicateEvaluatorFactory.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/NotInPredicateEvaluatorFactory.java
@@ -31,6 +31,7 @@ import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
+import java.util.SortedSet;
import java.util.TreeSet;
import javax.annotation.Nullable;
import org.apache.pinot.common.request.context.predicate.NotInPredicate;
@@ -39,7 +40,6 @@ import org.apache.pinot.common.utils.HashUtil;
import org.apache.pinot.core.query.request.context.QueryContext;
import org.apache.pinot.segment.spi.index.reader.Dictionary;
import org.apache.pinot.spi.data.FieldSpec.DataType;
-import org.apache.pinot.spi.data.MultiValueVisitor;
import org.apache.pinot.spi.utils.ByteArray;
@@ -211,10 +211,28 @@ public class NotInPredicateEvaluatorFactory {
super(predicate);
}
- /**
- * Visits the not matching value of this predicate.
- */
- public abstract <R> R accept(MultiValueVisitor<R> visitor);
+ /// Visits the non-matching values of this predicate.
+ public abstract <R> R accept(Visitor<R> visitor);
+
+ /// Visitor for the non-matching values of a NOT_IN predicate, dispatched
by the stored value type.
+ ///
+ /// The `BigDecimal` non-matching values are delivered in a [SortedSet]
because `BigDecimal`'s `compareTo` is not
+ /// consistent with `equals` (e.g. `3.0` and `3` compare equal).
+ public interface Visitor<R> {
+ R visitInt(IntSet nonMatchingValues);
+
+ R visitLong(LongSet nonMatchingValues);
+
+ R visitFloat(FloatSet nonMatchingValues);
+
+ R visitDouble(DoubleSet nonMatchingValues);
+
+ R visitBigDecimal(SortedSet<BigDecimal> nonMatchingValues);
+
+ R visitString(Set<String> nonMatchingValues);
+
+ R visitBytes(Set<ByteArray> nonMatchingValues);
+ }
}
private static final class IntRawValueBasedNotInPredicateEvaluator extends
NotInRawPredicateEvaluator {
@@ -254,8 +272,8 @@ public class NotInPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(MultiValueVisitor<R> visitor) {
- return visitor.visitInt(_nonMatchingValues.toIntArray());
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitInt(_nonMatchingValues);
}
}
@@ -296,8 +314,8 @@ public class NotInPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(MultiValueVisitor<R> visitor) {
- return visitor.visitLong(_nonMatchingValues.toLongArray());
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitLong(_nonMatchingValues);
}
}
@@ -338,8 +356,8 @@ public class NotInPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(MultiValueVisitor<R> visitor) {
- return visitor.visitFloat(_nonMatchingValues.toFloatArray());
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitFloat(_nonMatchingValues);
}
}
@@ -380,8 +398,8 @@ public class NotInPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(MultiValueVisitor<R> visitor) {
- return visitor.visitDouble(_nonMatchingValues.toDoubleArray());
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitDouble(_nonMatchingValues);
}
}
@@ -411,8 +429,8 @@ public class NotInPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(MultiValueVisitor<R> visitor) {
- return visitor.visitBigDecimal(_nonMatchingValues.toArray(new
BigDecimal[0]));
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitBigDecimal(_nonMatchingValues);
}
}
@@ -440,8 +458,8 @@ public class NotInPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(MultiValueVisitor<R> visitor) {
- return visitor.visitString(_nonMatchingValues.toArray(new String[0]));
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitString(_nonMatchingValues);
}
}
@@ -469,9 +487,8 @@ public class NotInPredicateEvaluatorFactory {
}
@Override
- public <R> R accept(MultiValueVisitor<R> visitor) {
- byte[][] bytes =
_nonMatchingValues.stream().map(ByteArray::getBytes).toArray(byte[][]::new);
- return visitor.visitBytes(bytes);
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitBytes(_nonMatchingValues);
}
}
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/RangePredicateEvaluatorFactory.java
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/RangePredicateEvaluatorFactory.java
index e9bd3b4b0a7..6b7c12be359 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/RangePredicateEvaluatorFactory.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/RangePredicateEvaluatorFactory.java
@@ -21,6 +21,8 @@ package org.apache.pinot.core.operator.filter.predicate;
import com.google.common.base.Preconditions;
import it.unimi.dsi.fastutil.ints.IntSet;
import java.math.BigDecimal;
+import javax.annotation.Nullable;
+import org.apache.pinot.common.request.context.predicate.Predicate;
import org.apache.pinot.common.request.context.predicate.RangePredicate;
import org.apache.pinot.core.operator.filter.predicate.traits.DoubleRange;
import org.apache.pinot.core.operator.filter.predicate.traits.FloatRange;
@@ -65,7 +67,7 @@ public class RangePredicateEvaluatorFactory {
* @param dataType Data type for the column
* @return Raw value based RANGE predicate evaluator
*/
- public static BaseRawValueBasedPredicateEvaluator
newRawValueBasedEvaluator(RangePredicate rangePredicate,
+ public static RangeRawPredicateEvaluator
newRawValueBasedEvaluator(RangePredicate rangePredicate,
DataType dataType) {
String lowerBound = rangePredicate.getLowerBound();
String upperBound = rangePredicate.getUpperBound();
@@ -323,7 +325,40 @@ public class RangePredicateEvaluatorFactory {
}
}
- private static final class IntRawValueBasedRangePredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator
+ public static abstract class RangeRawPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ public RangeRawPredicateEvaluator(Predicate predicate) {
+ super(predicate);
+ }
+
+ /// Visits the bounds of this predicate.
+ public abstract <R> R accept(Visitor<R> visitor);
+
+ /// Visitor for the bounds of a RANGE predicate, dispatched by the stored
value type.
+ ///
+ /// For integral and floating point types, exclusive bounds are normalized
to inclusive bounds, and unbounded
+ /// sides are normalized to the data type's min/max. For `BigDecimal`,
`String`, and `byte[]`, the raw bounds are
+ /// passed through together with their inclusivity flags, and unbounded
sides are represented by a `null` bound.
+ public interface Visitor<R> {
+ R visitInt(int inclusiveLowerBound, int inclusiveUpperBound);
+
+ R visitLong(long inclusiveLowerBound, long inclusiveUpperBound);
+
+ R visitFloat(float inclusiveLowerBound, float inclusiveUpperBound);
+
+ R visitDouble(double inclusiveLowerBound, double inclusiveUpperBound);
+
+ R visitBigDecimal(@Nullable BigDecimal lowerBound, @Nullable BigDecimal
upperBound, boolean lowerInclusive,
+ boolean upperInclusive);
+
+ R visitString(@Nullable String lowerBound, @Nullable String upperBound,
boolean lowerInclusive,
+ boolean upperInclusive);
+
+ R visitBytes(@Nullable byte[] lowerBound, @Nullable byte[] upperBound,
boolean lowerInclusive,
+ boolean upperInclusive);
+ }
+ }
+
+ private static final class IntRawValueBasedRangePredicateEvaluator extends
RangeRawPredicateEvaluator
implements IntRange {
final int _inclusiveLowerBound;
final int _inclusiveUpperBound;
@@ -377,9 +412,14 @@ public class RangePredicateEvaluatorFactory {
}
return matches;
}
+
+ @Override
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitInt(_inclusiveLowerBound, _inclusiveUpperBound);
+ }
}
- private static final class LongRawValueBasedRangePredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator
+ private static final class LongRawValueBasedRangePredicateEvaluator extends
RangeRawPredicateEvaluator
implements LongRange {
final long _inclusiveLowerBound;
final long _inclusiveUpperBound;
@@ -433,9 +473,14 @@ public class RangePredicateEvaluatorFactory {
}
return matches;
}
+
+ @Override
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitLong(_inclusiveLowerBound, _inclusiveUpperBound);
+ }
}
- private static final class FloatRawValueBasedRangePredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator
+ private static final class FloatRawValueBasedRangePredicateEvaluator extends
RangeRawPredicateEvaluator
implements FloatRange {
final float _inclusiveLowerBound;
final float _inclusiveUpperBound;
@@ -489,9 +534,14 @@ public class RangePredicateEvaluatorFactory {
}
return matches;
}
+
+ @Override
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitFloat(_inclusiveLowerBound, _inclusiveUpperBound);
+ }
}
- private static final class DoubleRawValueBasedRangePredicateEvaluator
extends BaseRawValueBasedPredicateEvaluator
+ private static final class DoubleRawValueBasedRangePredicateEvaluator
extends RangeRawPredicateEvaluator
implements DoubleRange {
final double _inclusiveLowerBound;
final double _inclusiveUpperBound;
@@ -545,11 +595,18 @@ public class RangePredicateEvaluatorFactory {
}
return matches;
}
+
+ @Override
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitDouble(_inclusiveLowerBound, _inclusiveUpperBound);
+ }
}
- public static final class BigDecimalRawValueBasedRangePredicateEvaluator
extends BaseRawValueBasedPredicateEvaluator {
+ public static final class BigDecimalRawValueBasedRangePredicateEvaluator
extends RangeRawPredicateEvaluator {
final BigDecimal _lowerBound;
final BigDecimal _upperBound;
+ final boolean _lowerInclusive;
+ final boolean _upperInclusive;
final int _lowerComparisonValue;
final int _upperComparisonValue;
@@ -558,6 +615,8 @@ public class RangePredicateEvaluatorFactory {
super(rangePredicate);
_lowerBound = lowerBound;
_upperBound = upperBound;
+ _lowerInclusive = lowerInclusive;
+ _upperInclusive = upperInclusive;
_lowerComparisonValue = lowerInclusive ? 0 : 1;
_upperComparisonValue = upperInclusive ? 0 : -1;
}
@@ -572,11 +631,18 @@ public class RangePredicateEvaluatorFactory {
return (_lowerBound == null || value.compareTo(_lowerBound) >=
_lowerComparisonValue) && (_upperBound == null
|| value.compareTo(_upperBound) <= _upperComparisonValue);
}
+
+ @Override
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitBigDecimal(_lowerBound, _upperBound,
_lowerInclusive, _upperInclusive);
+ }
}
- private static final class StringRawValueBasedRangePredicateEvaluator
extends BaseRawValueBasedPredicateEvaluator {
+ private static final class StringRawValueBasedRangePredicateEvaluator
extends RangeRawPredicateEvaluator {
final String _lowerBound;
final String _upperBound;
+ final boolean _lowerInclusive;
+ final boolean _upperInclusive;
final int _lowerComparisonValue;
final int _upperComparisonValue;
@@ -585,6 +651,8 @@ public class RangePredicateEvaluatorFactory {
super(rangePredicate);
_lowerBound = lowerBound;
_upperBound = upperBound;
+ _lowerInclusive = lowerInclusive;
+ _upperInclusive = upperInclusive;
_lowerComparisonValue = lowerInclusive ? 0 : 1;
_upperComparisonValue = upperInclusive ? 0 : -1;
}
@@ -599,11 +667,18 @@ public class RangePredicateEvaluatorFactory {
return (_lowerBound == null || value.compareTo(_lowerBound) >=
_lowerComparisonValue) && (_upperBound == null
|| value.compareTo(_upperBound) <= _upperComparisonValue);
}
+
+ @Override
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitString(_lowerBound, _upperBound, _lowerInclusive,
_upperInclusive);
+ }
}
- private static final class BytesRawValueBasedRangePredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ private static final class BytesRawValueBasedRangePredicateEvaluator extends
RangeRawPredicateEvaluator {
final byte[] _lowerBound;
final byte[] _upperBound;
+ final boolean _lowerInclusive;
+ final boolean _upperInclusive;
final int _lowerComparisonValue;
final int _upperComparisonValue;
@@ -612,6 +687,8 @@ public class RangePredicateEvaluatorFactory {
super(rangePredicate);
_lowerBound = lowerBound;
_upperBound = upperBound;
+ _lowerInclusive = lowerInclusive;
+ _upperInclusive = upperInclusive;
_lowerComparisonValue = lowerInclusive ? 0 : 1;
_upperComparisonValue = upperInclusive ? 0 : -1;
}
@@ -626,5 +703,10 @@ public class RangePredicateEvaluatorFactory {
return (_lowerBound == null || ByteArray.compare(value, _lowerBound) >=
_lowerComparisonValue) && (
_upperBound == null || ByteArray.compare(value, _upperBound) <=
_upperComparisonValue);
}
+
+ @Override
+ public <R> R accept(Visitor<R> visitor) {
+ return visitor.visitBytes(_lowerBound, _upperBound, _lowerInclusive,
_upperInclusive);
+ }
}
}
diff --git
a/pinot-core/src/test/java/org/apache/pinot/core/operator/filter/predicate/InPredicateEvaluatorFactoryTest.java
b/pinot-core/src/test/java/org/apache/pinot/core/operator/filter/predicate/InPredicateEvaluatorFactoryTest.java
index 8e83e2b2177..bea79ab3569 100644
---
a/pinot-core/src/test/java/org/apache/pinot/core/operator/filter/predicate/InPredicateEvaluatorFactoryTest.java
+++
b/pinot-core/src/test/java/org/apache/pinot/core/operator/filter/predicate/InPredicateEvaluatorFactoryTest.java
@@ -19,11 +19,19 @@
package org.apache.pinot.core.operator.filter.predicate;
import com.google.common.collect.Lists;
+import it.unimi.dsi.fastutil.doubles.DoubleSet;
+import it.unimi.dsi.fastutil.floats.FloatSet;
+import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
+import it.unimi.dsi.fastutil.ints.IntSet;
+import it.unimi.dsi.fastutil.longs.LongSet;
import java.math.BigDecimal;
+import java.util.Set;
+import java.util.SortedSet;
import org.apache.pinot.common.request.context.ExpressionContext;
import org.apache.pinot.common.request.context.predicate.InPredicate;
+import
org.apache.pinot.core.operator.filter.predicate.InPredicateEvaluatorFactory.InRawPredicateEvaluator;
import org.apache.pinot.spi.data.FieldSpec;
-import org.apache.pinot.spi.data.MultiValueVisitor;
+import org.apache.pinot.spi.utils.ByteArray;
import org.mockito.Mockito;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -31,56 +39,41 @@ import org.testng.annotations.Test;
public class InPredicateEvaluatorFactoryTest {
- MultiValueVisitor<Integer> createValueLengthVisitor() {
- return new MultiValueVisitor<Integer>() {
+ InRawPredicateEvaluator.Visitor<Integer> createValueSizeVisitor() {
+ return new InRawPredicateEvaluator.Visitor<>() {
@Override
- public Integer visitInt(int[] value) {
- return value.length;
+ public Integer visitInt(IntSet matchingValues) {
+ return matchingValues.size();
}
@Override
- public Integer visitLong(long[] value) {
- return value.length;
+ public Integer visitLong(LongSet matchingValues) {
+ return matchingValues.size();
}
@Override
- public Integer visitFloat(float[] value) {
- return value.length;
+ public Integer visitFloat(FloatSet matchingValues) {
+ return matchingValues.size();
}
@Override
- public Integer visitDouble(double[] value) {
- return value.length;
+ public Integer visitDouble(DoubleSet matchingValues) {
+ return matchingValues.size();
}
@Override
- public Integer visitBigDecimal(BigDecimal[] value) {
- return value.length;
+ public Integer visitBigDecimal(SortedSet<BigDecimal> matchingValues) {
+ return matchingValues.size();
}
@Override
- public Integer visitBoolean(boolean[] value) {
- return value.length;
+ public Integer visitString(Set<String> matchingValues) {
+ return matchingValues.size();
}
@Override
- public Integer visitTimestamp(long[] value) {
- return value.length;
- }
-
- @Override
- public Integer visitString(String[] value) {
- return value.length;
- }
-
- @Override
- public Integer visitJson(String[] value) {
- return value.length;
- }
-
- @Override
- public Integer visitBytes(byte[][] value) {
- return value.length;
+ public Integer visitBytes(Set<ByteArray> matchingValues) {
+ return matchingValues.size();
}
};
}
@@ -88,7 +81,7 @@ public class InPredicateEvaluatorFactoryTest {
@Test
void canBeVisited() {
// Given a visitor
- MultiValueVisitor<Integer> valueLengthVisitor =
Mockito.spy(createValueLengthVisitor());
+ InRawPredicateEvaluator.Visitor<Integer> valueSizeVisitor =
Mockito.spy(createValueSizeVisitor());
// When int predicate is used
InPredicate predicate = new
InPredicate(ExpressionContext.forIdentifier("ident"), Lists.newArrayList("1",
"2"));
@@ -96,20 +89,20 @@ public class InPredicateEvaluatorFactoryTest {
InPredicateEvaluatorFactory.InRawPredicateEvaluator intEvaluator =
InPredicateEvaluatorFactory.newRawValueBasedEvaluator(predicate,
FieldSpec.DataType.INT);
- // Only the int[] method is called
- int length = intEvaluator.accept(valueLengthVisitor);
- Assert.assertEquals(length, 2);
- Mockito.verify(valueLengthVisitor).visitInt(new int[] {2, 1});
- Mockito.verifyNoMoreInteractions(valueLengthVisitor);
+ // Only the IntSet method is called
+ int size = intEvaluator.accept(valueSizeVisitor);
+ Assert.assertEquals(size, 2);
+ Mockito.verify(valueSizeVisitor).visitInt(new IntOpenHashSet(new int[] {1,
2}));
+ Mockito.verifyNoMoreInteractions(valueSizeVisitor);
// And given a string predicate
InPredicateEvaluatorFactory.InRawPredicateEvaluator strEvaluator =
InPredicateEvaluatorFactory.newRawValueBasedEvaluator(predicate,
FieldSpec.DataType.STRING);
- // Only the string[] method is called
- length = strEvaluator.accept(valueLengthVisitor);
- Assert.assertEquals(length, 2);
- Mockito.verify(valueLengthVisitor).visitString(new String[] {"2", "1"});
- Mockito.verifyNoMoreInteractions(valueLengthVisitor);
+ // Only the Set<String> method is called
+ size = strEvaluator.accept(valueSizeVisitor);
+ Assert.assertEquals(size, 2);
+ Mockito.verify(valueSizeVisitor).visitString(Set.of("1", "2"));
+ Mockito.verifyNoMoreInteractions(valueSizeVisitor);
}
}
diff --git
a/pinot-spi/src/main/java/org/apache/pinot/spi/data/MultiValueVisitor.java
b/pinot-spi/src/main/java/org/apache/pinot/spi/data/MultiValueVisitor.java
deleted file mode 100644
index 13fc4d3568b..00000000000
--- a/pinot-spi/src/main/java/org/apache/pinot/spi/data/MultiValueVisitor.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.pinot.spi.data;
-
-import java.math.BigDecimal;
-
-
-public interface MultiValueVisitor<R> {
-
- R visitInt(int[] value);
-
- R visitLong(long[] value);
-
- R visitFloat(float[] value);
-
- R visitDouble(double[] value);
-
- R visitBigDecimal(BigDecimal[] value);
-
- R visitBoolean(boolean[] value);
-
- R visitTimestamp(long[] value);
-
- R visitString(String[] value);
-
- R visitJson(String[] value);
-
- R visitBytes(byte[][] value);
-
- default SingleValueVisitor<R> asSingleValueVisitor() {
- return new SingleValueVisitor<R>() {
- @Override
- public R visitInt(int value) {
- return MultiValueVisitor.this.visitInt(new int[] {value});
- }
-
- @Override
- public R visitLong(long value) {
- return MultiValueVisitor.this.visitLong(new long[] {value});
- }
-
- @Override
- public R visitFloat(float value) {
- return MultiValueVisitor.this.visitFloat(new float[] {value});
- }
-
- @Override
- public R visitDouble(double value) {
- return MultiValueVisitor.this.visitDouble(new double[] {value});
- }
-
- @Override
- public R visitBigDecimal(BigDecimal value) {
- return MultiValueVisitor.this.visitBigDecimal(new BigDecimal[]
{value});
- }
-
- @Override
- public R visitBoolean(boolean value) {
- return MultiValueVisitor.this.visitBoolean(new boolean[] {value});
- }
-
- @Override
- public R visitTimestamp(long value) {
- return MultiValueVisitor.this.visitLong(new long[] {value});
- }
-
- @Override
- public R visitString(String value) {
- return MultiValueVisitor.this.visitString(new String[] {value});
- }
-
- @Override
- public R visitJson(String value) {
- return MultiValueVisitor.this.visitString(new String[] {value});
- }
-
- @Override
- public R visitBytes(byte[] value) {
- return MultiValueVisitor.this.visitBytes(new byte[][] {value});
- }
- };
- }
-}
diff --git
a/pinot-spi/src/main/java/org/apache/pinot/spi/data/SingleValueVisitor.java
b/pinot-spi/src/main/java/org/apache/pinot/spi/data/SingleValueVisitor.java
deleted file mode 100644
index 6184bbf057a..00000000000
--- a/pinot-spi/src/main/java/org/apache/pinot/spi/data/SingleValueVisitor.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.pinot.spi.data;
-
-import java.math.BigDecimal;
-
-
-public interface SingleValueVisitor<R> {
-
- R visitInt(int value);
-
- R visitLong(long value);
-
- R visitFloat(float value);
-
- R visitDouble(double value);
-
- R visitBigDecimal(BigDecimal value);
-
- R visitBoolean(boolean value);
-
- R visitTimestamp(long value);
-
- R visitString(String value);
-
- R visitJson(String value);
-
- R visitBytes(byte[] value);
-}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]