if (bound.getUpper() != null && bound.getLower() != null) { return null; } else if (bound.getUpper() != null) { return new BoundDimFilter( bound.getDimension(), bound.getUpper(), null, !bound.isUpperStrict(), false, null, bound.getExtractionFn(), bound.getOrdering() ); } else { return new BoundDimFilter( bound.getDimension(), null, bound.getLower(), false, !bound.isLowerStrict(), null, bound.getExtractionFn(), bound.getOrdering() );
@Override public DimFilter process(DimFilter filter) { if (filter instanceof BoundDimFilter) { final BoundDimFilter bound = (BoundDimFilter) filter; final StringComparator naturalStringComparator = sourceRowSignature.naturalStringComparator( SimpleExtraction.of(bound.getDimension(), bound.getExtractionFn()) ); if (bound.hasUpperBound() && bound.hasLowerBound() && bound.getUpper().equals(bound.getLower()) && !bound.isUpperStrict() && !bound.isLowerStrict() && bound.getOrdering().equals(naturalStringComparator)) { return new SelectorDimFilter( bound.getDimension(), bound.getUpper(), bound.getExtractionFn() ); } else { return filter; } } else { return filter; } } }
public BoundFilter(final BoundDimFilter boundDimFilter) { this.boundDimFilter = boundDimFilter; this.comparator = boundDimFilter.getOrdering(); this.extractionFn = boundDimFilter.getExtractionFn(); this.longPredicateSupplier = boundDimFilter.getLongPredicateSupplier(); this.floatPredicateSupplier = boundDimFilter.getFloatPredicateSupplier(); this.doublePredicateSupplier = boundDimFilter.getDoublePredicateSupplier(); }
@Override public int hashCode() { int result = getDimension().hashCode(); result = 31 * result + (getUpper() != null ? getUpper().hashCode() : 0); result = 31 * result + (getLower() != null ? getLower().hashCode() : 0); result = 31 * result + (isLowerStrict() ? 1 : 0); result = 31 * result + (isUpperStrict() ? 1 : 0); result = 31 * result + (getExtractionFn() != null ? getExtractionFn().hashCode() : 0); result = 31 * result + getOrdering().hashCode(); return result; }
public static BoundRefKey from(BoundDimFilter filter) { return new BoundRefKey( filter.getDimension(), filter.getExtractionFn(), filter.getOrdering() ); }
public static BoundDimFilter BOUND( final String fieldName, final String lower, final String upper, final boolean lowerStrict, final boolean upperStrict, final ExtractionFn extractionFn, final StringComparator comparator ) { return new BoundDimFilter(fieldName, lower, upper, lowerStrict, upperStrict, null, extractionFn, comparator); }
private boolean doesMatch(String input) { if (input == null) { return (!boundDimFilter.hasLowerBound() || (NullHandling.isNullOrEquivalent(boundDimFilter.getLower()) && !boundDimFilter.isLowerStrict())) // lower bound allows null && (!boundDimFilter.hasUpperBound() || !NullHandling.isNullOrEquivalent(boundDimFilter.getUpper()) || !boundDimFilter.isUpperStrict()); // upper bound allows null } int lowerComparing = 1; int upperComparing = 1; if (boundDimFilter.hasLowerBound()) { lowerComparing = comparator.compare(input, boundDimFilter.getLower()); } if (boundDimFilter.hasUpperBound()) { upperComparing = comparator.compare(boundDimFilter.getUpper(), input); } if (boundDimFilter.isLowerStrict() && boundDimFilter.isUpperStrict()) { return ((lowerComparing > 0)) && (upperComparing > 0); } else if (boundDimFilter.isLowerStrict()) { return (lowerComparing > 0) && (upperComparing >= 0); } else if (boundDimFilter.isUpperStrict()) { return (lowerComparing >= 0) && (upperComparing > 0); } return (lowerComparing >= 0) && (upperComparing >= 0); } }
public static Range<BoundValue> toRange(final BoundDimFilter bound) { final BoundValue upper = bound.getUpper() != null ? new BoundValue(bound.getUpper(), bound.getOrdering()) : null; final BoundValue lower = bound.getLower() != null ? new BoundValue(bound.getLower(), bound.getOrdering()) : null; if (lower == null) { return bound.isUpperStrict() ? Range.lessThan(upper) : Range.atMost(upper); } else if (upper == null) { return bound.isLowerStrict() ? Range.greaterThan(lower) : Range.atLeast(lower); } else { BoundType lowerBoundType = bound.isLowerStrict() ? BoundType.OPEN : BoundType.CLOSED; BoundType upperBoundType = bound.isUpperStrict() ? BoundType.OPEN : BoundType.CLOSED; return Range.range(lower, lowerBoundType, upper, upperBoundType); } }
@Test public void testGetCacheKey() { BoundDimFilter boundDimFilter = new BoundDimFilter("dimension", "12", "15", null, null, true, null, StringComparators.ALPHANUMERIC); BoundDimFilter boundDimFilterCopy = new BoundDimFilter("dimension", "12", "15", false, false, true, null, StringComparators.ALPHANUMERIC); Assert.assertArrayEquals(boundDimFilter.getCacheKey(), boundDimFilterCopy.getCacheKey()); BoundDimFilter anotherBoundDimFilter = new BoundDimFilter("dimension", "12", "15", true, null, false, null, StringComparators.LEXICOGRAPHIC); Assert.assertFalse(Arrays.equals(anotherBoundDimFilter.getCacheKey(), boundDimFilter.getCacheKey())); BoundDimFilter boundDimFilterWithExtract = new BoundDimFilter("dimension", "12", "15", null, null, true, extractionFn, StringComparators.ALPHANUMERIC); BoundDimFilter boundDimFilterWithExtractCopy = new BoundDimFilter("dimension", "12", "15", false, false, true, extractionFn, StringComparators.ALPHANUMERIC); Assert.assertFalse(Arrays.equals(boundDimFilter.getCacheKey(), boundDimFilterWithExtract.getCacheKey())); Assert.assertArrayEquals(boundDimFilterWithExtract.getCacheKey(), boundDimFilterWithExtractCopy.getCacheKey()); }
@Test public void testHashCode() { BoundDimFilter boundDimFilter = new BoundDimFilter("dimension", "12", "15", null, null, true, null, StringComparators.ALPHANUMERIC); BoundDimFilter boundDimFilterWithExtract = new BoundDimFilter("dimension", "12", "15", null, null, true, extractionFn, StringComparators.ALPHANUMERIC); Assert.assertNotEquals(boundDimFilter.hashCode(), boundDimFilterWithExtract.hashCode()); }
@Test public void testGetRequiredColumns() { BoundDimFilter boundDimFilter = new BoundDimFilter("dimension", "12", "15", null, null, true, null, StringComparators.ALPHANUMERIC); Assert.assertEquals(boundDimFilter.getRequiredColumns(), Sets.newHashSet("dimension")); } }
@Override public boolean supportsSelectivityEstimation(ColumnSelector columnSelector, BitmapIndexSelector indexSelector) { return Filters.supportsSelectivityEstimation(this, boundDimFilter.getDimension(), columnSelector, indexSelector); }
private boolean supportShortCircuit() { // Optimization for lexicographic bounds with no extractionFn => binary search through the index return boundDimFilter.getOrdering().equals(StringComparators.LEXICOGRAPHIC) && extractionFn == null; }
private List<DimFilter> makeBoundDimFilters() { List<DimFilter> boundDimFilters = new ArrayList<>(); for (Pair<Long, Long> interval : intervalLongs) { BoundDimFilter boundDimFilter = new BoundDimFilter( dimension, String.valueOf(interval.lhs), String.valueOf(interval.rhs), false, true, null, extractionFn, StringComparators.NUMERIC ); boundDimFilters.add(boundDimFilter); } return boundDimFilters; } }
private static Pair<Integer, Integer> getStartEndIndexes( final BoundDimFilter boundDimFilter, final BitmapIndex bitmapIndex ) { final int startIndex; // inclusive int endIndex; // exclusive if (!boundDimFilter.hasLowerBound()) { startIndex = 0; } else { final int found = bitmapIndex.getIndex(NullHandling.emptyToNullIfNeeded(boundDimFilter.getLower())); if (found >= 0) { startIndex = boundDimFilter.isLowerStrict() ? found + 1 : found; } else { startIndex = -(found + 1); } } if (!boundDimFilter.hasUpperBound()) { endIndex = bitmapIndex.getCardinality(); } else { final int found = bitmapIndex.getIndex(NullHandling.emptyToNullIfNeeded(boundDimFilter.getUpper())); if (found >= 0) { endIndex = boundDimFilter.isUpperStrict() ? found : found + 1; } else { endIndex = -(found + 1); } } endIndex = startIndex > endIndex ? startIndex : endIndex; return new Pair<>(startIndex, endIndex); }
public static Range<BoundValue> toRange(final BoundDimFilter bound) { final BoundValue upper = bound.getUpper() != null ? new BoundValue(bound.getUpper(), bound.getOrdering()) : null; final BoundValue lower = bound.getLower() != null ? new BoundValue(bound.getLower(), bound.getOrdering()) : null; if (lower == null) { return bound.isUpperStrict() ? Range.lessThan(upper) : Range.atMost(upper); } else if (upper == null) { return bound.isLowerStrict() ? Range.greaterThan(lower) : Range.atLeast(lower); } else { return Range.range( lower, bound.isLowerStrict() ? BoundType.OPEN : BoundType.CLOSED, upper, bound.isUpperStrict() ? BoundType.OPEN : BoundType.CLOSED ); } }
public BoundFilter(final BoundDimFilter boundDimFilter) { this.boundDimFilter = boundDimFilter; this.comparator = boundDimFilter.getOrdering(); this.extractionFn = boundDimFilter.getExtractionFn(); this.longPredicateSupplier = boundDimFilter.getLongPredicateSupplier(); this.floatPredicateSupplier = boundDimFilter.getFloatPredicateSupplier(); this.doublePredicateSupplier = boundDimFilter.getDoublePredicateSupplier(); }
public static BoundRefKey from(BoundDimFilter filter) { return new BoundRefKey( filter.getDimension(), filter.getExtractionFn(), filter.getOrdering() ); }
@Override public boolean supportsBitmapIndex(BitmapIndexSelector selector) { return selector.getBitmapIndex(boundDimFilter.getDimension()) != null; }
@Override public DruidFloatPredicate makeFloatPredicate() { if (extractionFn != null) { return input -> doesMatch(extractionFn.apply(input)); } if (boundDimFilter.getOrdering().equals(StringComparators.NUMERIC)) { return floatPredicateSupplier.get(); } return input -> doesMatch(String.valueOf(input)); }