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 <rich...@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-unsubscr...@pinot.apache.org For additional commands, e-mail: commits-h...@pinot.apache.org