You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by ri...@apache.org on 2022/05/24 12:41:52 UTC
[pinot] branch master updated: vectorize predicate evaluation (#8759)
This is an automated email from the ASF dual-hosted git repository.
richardstartin 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 cfce5e1c7e vectorize predicate evaluation (#8759)
cfce5e1c7e is described below
commit cfce5e1c7ec650f08059fb4c31b199a75f5c677f
Author: Richard Startin <ri...@startree.ai>
AuthorDate: Tue May 24 14:41:44 2022 +0200
vectorize predicate evaluation (#8759)
* vectorize predicate evaluation
* explain why applySV is reimplemented, don't mutate values for now
* add benchmark for filtered scan
---
.../dociditerators/SVScanDocIdIterator.java | 67 ++++++++++++++++--
.../predicate/EqualsPredicateEvaluatorFactory.java | 65 ++++++++++++++++++
.../FSTBasedRegexpPredicateEvaluatorFactory.java | 13 ++++
.../predicate/InPredicateEvaluatorFactory.java | 65 ++++++++++++++++++
.../NotEqualsPredicateEvaluatorFactory.java | 65 ++++++++++++++++++
.../predicate/NotInPredicateEvaluatorFactory.java | 65 ++++++++++++++++++
.../filter/predicate/PredicateEvaluator.java | 80 ++++++++++++++++++++++
.../predicate/RangePredicateEvaluatorFactory.java | 65 ++++++++++++++++++
.../RegexpLikePredicateEvaluatorFactory.java | 13 ++++
.../org/apache/pinot/perf/BenchmarkQueries.java | 6 +-
10 files changed, 498 insertions(+), 6 deletions(-)
diff --git a/pinot-core/src/main/java/org/apache/pinot/core/operator/dociditerators/SVScanDocIdIterator.java b/pinot-core/src/main/java/org/apache/pinot/core/operator/dociditerators/SVScanDocIdIterator.java
index d386f05caa..d462b3b6ed 100644
--- a/pinot-core/src/main/java/org/apache/pinot/core/operator/dociditerators/SVScanDocIdIterator.java
+++ b/pinot-core/src/main/java/org/apache/pinot/core/operator/dociditerators/SVScanDocIdIterator.java
@@ -82,13 +82,13 @@ public final class SVScanDocIdIterator implements ScanBasedDocIdIterator {
int[] buffer = new int[OPTIMAL_ITERATOR_BATCH_SIZE];
while (docIdIterator.hasNext()) {
int limit = docIdIterator.nextBatch(buffer);
- for (int i = 0; i < limit; i++) {
- int nextDocId = buffer[i];
- _numEntriesScanned++;
- if (_valueMatcher.doesValueMatch(nextDocId)) {
- result.add(nextDocId);
+ if (limit > 0) {
+ int firstMismatch = _valueMatcher.matchValues(limit, buffer);
+ for (int i = 0; i < firstMismatch; i++) {
+ result.add(buffer[i]);
}
}
+ _numEntriesScanned += limit;
}
return result.get();
}
@@ -129,46 +129,103 @@ public final class SVScanDocIdIterator implements ScanBasedDocIdIterator {
* Returns {@code true} if the value for the given document id matches the predicate, {@code false} Otherwise.
*/
boolean doesValueMatch(int docId);
+
+ /**
+ * Filters out non matching values and compacts matching docIds in the start of the array.
+ * @param limit how much of the input to read
+ * @param docIds the docIds to match - may be modified by this method so take a copy if necessary.
+ * @return the index in the array of the first non-matching element - all elements before this index match.
+ */
+ default int matchValues(int limit, int[] docIds) {
+ int matchCount = 0;
+ for (int i = 0; i < limit; i++) {
+ int docId = docIds[i];
+ if (doesValueMatch(docId)) {
+ docIds[matchCount++] = docId;
+ }
+ }
+ return matchCount;
+ }
}
private class DictIdMatcher implements ValueMatcher {
+ private final int[] _buffer = new int[OPTIMAL_ITERATOR_BATCH_SIZE];
+
@Override
public boolean doesValueMatch(int docId) {
return _predicateEvaluator.applySV(_reader.getDictId(docId, _readerContext));
}
+
+ @Override
+ public int matchValues(int limit, int[] docIds) {
+ _reader.readDictIds(docIds, limit, _buffer, _readerContext);
+ return _predicateEvaluator.applySV(limit, docIds, _buffer);
+ }
}
private class IntMatcher implements ValueMatcher {
+ private final int[] _buffer = new int[OPTIMAL_ITERATOR_BATCH_SIZE];
+
@Override
public boolean doesValueMatch(int docId) {
return _predicateEvaluator.applySV(_reader.getInt(docId, _readerContext));
}
+
+ @Override
+ public int matchValues(int limit, int[] docIds) {
+ _reader.readValuesSV(docIds, limit, _buffer, _readerContext);
+ return _predicateEvaluator.applySV(limit, docIds, _buffer);
+ }
}
private class LongMatcher implements ValueMatcher {
+ private final long[] _buffer = new long[OPTIMAL_ITERATOR_BATCH_SIZE];
+
@Override
public boolean doesValueMatch(int docId) {
return _predicateEvaluator.applySV(_reader.getLong(docId, _readerContext));
}
+
+ @Override
+ public int matchValues(int limit, int[] docIds) {
+ _reader.readValuesSV(docIds, limit, _buffer, _readerContext);
+ return _predicateEvaluator.applySV(limit, docIds, _buffer);
+ }
}
private class FloatMatcher implements ValueMatcher {
+ private final float[] _buffer = new float[OPTIMAL_ITERATOR_BATCH_SIZE];
+
@Override
public boolean doesValueMatch(int docId) {
return _predicateEvaluator.applySV(_reader.getFloat(docId, _readerContext));
}
+
+ @Override
+ public int matchValues(int limit, int[] docIds) {
+ _reader.readValuesSV(docIds, limit, _buffer, _readerContext);
+ return _predicateEvaluator.applySV(limit, docIds, _buffer);
+ }
}
private class DoubleMatcher implements ValueMatcher {
+ private final double[] _buffer = new double[OPTIMAL_ITERATOR_BATCH_SIZE];
+
@Override
public boolean doesValueMatch(int docId) {
return _predicateEvaluator.applySV(_reader.getDouble(docId, _readerContext));
}
+
+ @Override
+ public int matchValues(int limit, int[] docIds) {
+ _reader.readValuesSV(docIds, limit, _buffer, _readerContext);
+ return _predicateEvaluator.applySV(limit, docIds, _buffer);
+ }
}
private class BigDecimalMatcher implements ValueMatcher {
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 71761c93d1..6df3d89b54 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
@@ -106,6 +106,19 @@ public class EqualsPredicateEvaluatorFactory {
return _matchingDictId == dictId;
}
+ @Override
+ public int applySV(int limit, int[] docIds, int[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ int value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
+
@Override
public int[] getMatchingDictIds() {
return _matchingDictIds;
@@ -129,6 +142,19 @@ public class EqualsPredicateEvaluatorFactory {
public boolean applySV(int value) {
return _matchingValue == value;
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, int[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ int value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class LongRawValueBasedEqPredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
@@ -148,6 +174,19 @@ public class EqualsPredicateEvaluatorFactory {
public boolean applySV(long value) {
return (_matchingValue == value);
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, long[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ long value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class FloatRawValueBasedEqPredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
@@ -167,6 +206,19 @@ public class EqualsPredicateEvaluatorFactory {
public boolean applySV(float value) {
return _matchingValue == value;
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, float[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ float value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class DoubleRawValueBasedEqPredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
@@ -186,6 +238,19 @@ public class EqualsPredicateEvaluatorFactory {
public boolean applySV(double value) {
return _matchingValue == value;
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, double[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ double value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class BigDecimalRawValueBasedEqPredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
diff --git a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/FSTBasedRegexpPredicateEvaluatorFactory.java b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/FSTBasedRegexpPredicateEvaluatorFactory.java
index 2be5a94a24..b1a0559a92 100644
--- a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/FSTBasedRegexpPredicateEvaluatorFactory.java
+++ b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/FSTBasedRegexpPredicateEvaluatorFactory.java
@@ -76,6 +76,19 @@ public class FSTBasedRegexpPredicateEvaluatorFactory {
return _dictIds.contains(dictId);
}
+ @Override
+ public int applySV(int limit, int[] docIds, int[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ int value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
+
@Override
public int[] getMatchingDictIds() {
return _dictIds.toArray();
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 1acace2a89..4724fefbaf 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
@@ -179,6 +179,19 @@ public class InPredicateEvaluatorFactory {
}
return _matchingDictIds;
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, int[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ int value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class IntRawValueBasedInPredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
@@ -198,6 +211,19 @@ public class InPredicateEvaluatorFactory {
public boolean applySV(int value) {
return _matchingValues.contains(value);
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, int[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ int value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class LongRawValueBasedInPredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
@@ -217,6 +243,19 @@ public class InPredicateEvaluatorFactory {
public boolean applySV(long value) {
return _matchingValues.contains(value);
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, long[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ long value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class FloatRawValueBasedInPredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
@@ -236,6 +275,19 @@ public class InPredicateEvaluatorFactory {
public boolean applySV(float value) {
return _matchingValues.contains(value);
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, float[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ float value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class DoubleRawValueBasedInPredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
@@ -255,6 +307,19 @@ public class InPredicateEvaluatorFactory {
public boolean applySV(double value) {
return _matchingValues.contains(value);
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, double[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ double value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class BigDecimalRawValueBasedInPredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
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 01b0bc31c8..0c27596730 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
@@ -109,6 +109,19 @@ public class NotEqualsPredicateEvaluatorFactory {
return _nonMatchingDictId != dictId;
}
+ @Override
+ public int applySV(int limit, int[] docIds, int[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ int value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
+
@Override
public int[] getMatchingDictIds() {
if (_matchingDictIds == null) {
@@ -154,6 +167,19 @@ public class NotEqualsPredicateEvaluatorFactory {
public boolean applySV(int value) {
return _nonMatchingValue != value;
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, int[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ int value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class LongRawValueBasedNeqPredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
@@ -173,6 +199,19 @@ public class NotEqualsPredicateEvaluatorFactory {
public boolean applySV(long value) {
return _nonMatchingValue != value;
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, long[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ long value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class FloatRawValueBasedNeqPredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
@@ -192,6 +231,19 @@ public class NotEqualsPredicateEvaluatorFactory {
public boolean applySV(float value) {
return _nonMatchingValue != value;
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, float[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ float value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class DoubleRawValueBasedNeqPredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
@@ -211,6 +263,19 @@ public class NotEqualsPredicateEvaluatorFactory {
public boolean applySV(double value) {
return _nonMatchingValue != value;
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, double[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ double value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class BigDecimalRawValueBasedNeqPredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
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 9fe4696a6e..3407754ee9 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
@@ -170,6 +170,19 @@ public class NotInPredicateEvaluatorFactory {
return !_nonMatchingDictIdSet.contains(dictId);
}
+ @Override
+ public int applySV(int limit, int[] docIds, int[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ int value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
+
@Override
public int[] getMatchingDictIds() {
if (_matchingDictIds == null) {
@@ -216,6 +229,19 @@ public class NotInPredicateEvaluatorFactory {
public boolean applySV(int value) {
return !_nonMatchingValues.contains(value);
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, int[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ int value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class LongRawValueBasedNotInPredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
@@ -235,6 +261,19 @@ public class NotInPredicateEvaluatorFactory {
public boolean applySV(long value) {
return !_nonMatchingValues.contains(value);
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, long[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ long value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class FloatRawValueBasedNotInPredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
@@ -254,6 +293,19 @@ public class NotInPredicateEvaluatorFactory {
public boolean applySV(float value) {
return !_nonMatchingValues.contains(value);
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, float[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ float value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class DoubleRawValueBasedNotInPredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
@@ -273,6 +325,19 @@ public class NotInPredicateEvaluatorFactory {
public boolean applySV(double value) {
return !_nonMatchingValues.contains(value);
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, double[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ double value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
private static final class BigDecimalRawValueBasedNotInPredicateEvaluator
diff --git a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/PredicateEvaluator.java b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/PredicateEvaluator.java
index 0ba28dede3..8e54e130c9 100644
--- a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/PredicateEvaluator.java
+++ b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/PredicateEvaluator.java
@@ -72,6 +72,26 @@ public interface PredicateEvaluator {
*/
boolean applySV(int value);
+ /**
+ * Apply the predicate to a batch of single-value entries.
+ * Compact matching entries into the prefix of the docIds array.
+ *
+ * @param limit How much of the input to consume.
+ * @param docIds The docIds associated with the values - may be modified by invocation.
+ * @param values Batch of dictionary ids or raw values.
+ * @return the index of the first non-matching entry.
+ */
+ default int applySV(int limit, int[] docIds, int[] values) {
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ int value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
+
/**
* Apply a multi-value entry to the predicate.
*
@@ -117,6 +137,26 @@ public interface PredicateEvaluator {
*/
boolean applySV(long value);
+ /**
+ * Apply the predicate to a batch of single-value entries.
+ * Compact matching entries into the prefix of the docIds array.
+ *
+ * @param limit How much of the input to consume.
+ * @param docIds The docIds associated with the values - may be modified by invocation.
+ * @param values Batch of raw values - may be modified by invocation.
+ * @return the index of the first non-matching entry.
+ */
+ default int applySV(int limit, int[] docIds, long[] values) {
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ long value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
+
/**
* Apply a multi-value entry to the predicate.
*
@@ -134,6 +174,26 @@ public interface PredicateEvaluator {
*/
boolean applySV(float value);
+ /**
+ * Apply the predicate to a batch of single-value entries.
+ * Compact matching entries into the prefix of the docIds array.
+ *
+ * @param limit How much of the input to consume.
+ * @param docIds The docIds associated with the values - may be modified by invocation.
+ * @param values Batch of raw values - may be modified by invocation.
+ * @return the index of the first non-matching entry.
+ */
+ default int applySV(int limit, int[] docIds, float[] values) {
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ float value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
+
/**
* Apply a multi-value entry to the predicate.
*
@@ -151,6 +211,26 @@ public interface PredicateEvaluator {
*/
boolean applySV(double value);
+ /**
+ * Apply the predicate to a batch of single-value entries.
+ * Compact matching entries into the prefix of the docIds array.
+ *
+ * @param limit How much of the input to consume.
+ * @param docIds The docIds associated with the values - may be modified by invocation.
+ * @param values Batch of raw values - may be modified by invocation.
+ * @return the index of the first non-matching entry.
+ */
+ default int applySV(int limit, int[] docIds, double[] values) {
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ double value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
+
/**
* Apply a multi-value entry to the predicate.
*
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 b2e71270a5..151ab5f941 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
@@ -177,6 +177,19 @@ public class RangePredicateEvaluatorFactory {
return _startDictId <= dictId && _endDictId > dictId;
}
+ @Override
+ public int applySV(int limit, int[] docIds, int[] dictIds) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ int dictId = dictIds[i];
+ if (applySV(dictId)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
+
@Override
public int getNumMatchingDictIds() {
return _numMatchingDictIds;
@@ -309,6 +322,19 @@ public class RangePredicateEvaluatorFactory {
public boolean applySV(int value) {
return value >= _inclusiveLowerBound && value <= _inclusiveUpperBound;
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, int[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ int value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
public static final class LongRawValueBasedRangePredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
@@ -349,6 +375,19 @@ public class RangePredicateEvaluatorFactory {
public boolean applySV(long value) {
return value >= _inclusiveLowerBound && value <= _inclusiveUpperBound;
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, long[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ long value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
public static final class FloatRawValueBasedRangePredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
@@ -389,6 +428,19 @@ public class RangePredicateEvaluatorFactory {
public boolean applySV(float value) {
return value >= _inclusiveLowerBound && value <= _inclusiveUpperBound;
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, float[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ float value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
public static final class DoubleRawValueBasedRangePredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
@@ -429,6 +481,19 @@ public class RangePredicateEvaluatorFactory {
public boolean applySV(double value) {
return value >= _inclusiveLowerBound && value <= _inclusiveUpperBound;
}
+
+ @Override
+ public int applySV(int limit, int[] docIds, double[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ double value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
}
public static final class BigDecimalRawValueBasedRangePredicateEvaluator extends BaseRawValueBasedPredicateEvaluator {
diff --git a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/RegexpLikePredicateEvaluatorFactory.java b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/RegexpLikePredicateEvaluatorFactory.java
index f245b54d89..a3af9de194 100644
--- a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/RegexpLikePredicateEvaluatorFactory.java
+++ b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/RegexpLikePredicateEvaluatorFactory.java
@@ -79,6 +79,19 @@ public class RegexpLikePredicateEvaluatorFactory {
return _matcher.reset(_dictionary.getStringValue(dictId)).find();
}
+ @Override
+ public int applySV(int limit, int[] docIds, int[] values) {
+ // reimplemented here to ensure applySV can be inlined
+ int matches = 0;
+ for (int i = 0; i < limit; i++) {
+ int value = values[i];
+ if (applySV(value)) {
+ docIds[matches++] = docIds[i];
+ }
+ }
+ return matches;
+ }
+
@Override
public int[] getMatchingDictIds() {
if (_matchingDictIds == null) {
diff --git a/pinot-perf/src/main/java/org/apache/pinot/perf/BenchmarkQueries.java b/pinot-perf/src/main/java/org/apache/pinot/perf/BenchmarkQueries.java
index f1059b94d9..32696caf5f 100644
--- a/pinot-perf/src/main/java/org/apache/pinot/perf/BenchmarkQueries.java
+++ b/pinot-perf/src/main/java/org/apache/pinot/perf/BenchmarkQueries.java
@@ -122,6 +122,9 @@ public class BenchmarkQueries extends BaseQueriesTest {
public static final String NO_INDEX_LIKE_QUERY = "SELECT RAW_INT_COL FROM MyTable "
+ "WHERE NO_INDEX_STRING_COL LIKE '%foo%'";
+ public static final String FILTERING_BITMAP_SCAN_QUERY = "SELECT RAW_INT_COL FROM MyTable "
+ + "WHERE INT_COL = 1 AND RAW_INT_COL IN (0, 1, 2)";
+
public static final String MULTI_GROUP_BY_ORDER_BY = "SELECT NO_INDEX_STRING_COL,INT_COL,COUNT(*) "
+ "FROM MyTable GROUP BY NO_INDEX_STRING_COL,INT_COL ORDER BY NO_INDEX_STRING_COL, INT_COL ASC";
@@ -168,7 +171,8 @@ public class BenchmarkQueries extends BaseQueriesTest {
MULTI_GROUP_BY_WITH_RAW_QUERY, MULTI_GROUP_BY_WITH_RAW_QUERY_2, FILTERED_QUERY, NON_FILTERED_QUERY,
SUM_QUERY, NO_INDEX_LIKE_QUERY, MULTI_GROUP_BY_ORDER_BY, MULTI_GROUP_BY_ORDER_BY_LOW_HIGH, TIME_GROUP_BY,
RAW_COLUMN_SUMMARY_STATS, COUNT_OVER_BITMAP_INDEX_IN, COUNT_OVER_BITMAP_INDEXES,
- COUNT_OVER_BITMAP_AND_SORTED_INDEXES, COUNT_OVER_BITMAP_INDEX_EQUALS, STARTREE_SUM_QUERY, STARTREE_FILTER_QUERY
+ COUNT_OVER_BITMAP_AND_SORTED_INDEXES, COUNT_OVER_BITMAP_INDEX_EQUALS, STARTREE_SUM_QUERY, STARTREE_FILTER_QUERY,
+ FILTERING_BITMAP_SCAN_QUERY
})
String _query;
private IndexSegment _indexSegment;
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org