@Override public Supplier<Comparable> makeInputRawSupplier(DimensionSelector selector) { return () -> { IndexedInts index = selector.getRow(); return index.size() == 0 ? null : selector.lookupName(index.get(0)); }; } }
/** * Checks if the given selector constantly returns null. This method could be used in the beginning of execution of * some queries and making some aggregations for heuristic shortcuts. */ static boolean isNilSelector(final DimensionSelector selector) { return selector.nameLookupPossibleInAdvance() && selector.getValueCardinality() == 1 && selector.lookupName(0) == null; }
/** * Generic implementation of {@link DimensionSelector#makeValueMatcher(String)}, uses {@link * DimensionSelector#getRow()} of the given {@link DimensionSelector}. "Lazy" DimensionSelectors could delegate * {@code makeValueMatcher()} to this method, but encouraged to implement {@code makeValueMatcher()} themselves, * bypassing the {@link IndexedInts} abstraction. */ public static ValueMatcher makeValueMatcherGeneric(DimensionSelector selector, @Nullable String value) { IdLookup idLookup = selector.idLookup(); if (idLookup != null) { return makeDictionaryEncodedValueMatcherGeneric(selector, idLookup.lookupId(value), value == null); } else if (selector.getValueCardinality() >= 0 && selector.nameLookupPossibleInAdvance()) { // Employ caching BitSet optimization return makeDictionaryEncodedValueMatcherGeneric(selector, Predicates.equalTo(value)); } else { return makeNonDictionaryEncodedValueMatcherGeneric(selector, value); } }
@Override public ValueMatcher makeValueMatcher(final DimensionSelector selector, String value) { if (selector.getValueCardinality() == 0) { return BooleanValueMatcher.of(value == null); } else { return selector.makeValueMatcher(value); } }
public BaseArrayProvider( DimensionSelector dimSelector, TopNQuery query, StorageAdapter storageAdapter ) { this.idLookup = dimSelector.idLookup(); this.query = query; this.storageAdapter = storageAdapter; previousStop = null; ignoreAfterThreshold = false; ignoreFirstN = 0; keepOnlyN = dimSelector.getValueCardinality(); if (keepOnlyN < 0) { throw new IAE("Cannot operate on a dimension with no dictionary"); } }
@Test public void testDecoratorWithBlacklist() { ListFilteredDimensionSpec spec = new ListFilteredDimensionSpec( new DefaultDimensionSpec("foo", "bar"), ImmutableSet.of("c", "g"), false ); DimensionSelector selector = spec.decorate(TestDimensionSelector.instance); Assert.assertEquals(24, selector.getValueCardinality()); IndexedInts row = selector.getRow(); Assert.assertEquals(1, row.size()); Assert.assertEquals(3, row.get(0)); Assert.assertEquals("a", selector.lookupName(0)); Assert.assertEquals("z", selector.lookupName(23)); Assert.assertEquals(0, selector.idLookup().lookupId("a")); Assert.assertEquals(23, selector.idLookup().lookupId("z")); }
@Override public void initColumnValues(ColumnValueSelector selector, int columnIndex, Object[] valuess) { DimensionSelector dimSelector = (DimensionSelector) selector; IndexedInts row = dimSelector.getRow(); valuess[columnIndex] = row; }
@Override public ValueGetter makeValueGetter(final DimensionSelector selector) { if (selector.getValueCardinality() == 0) { return NULL_VALUE_GETTER; } else { return () -> { final IndexedInts row = selector.getRow(); final int size = row.size(); if (size == 0) { return NULL_VALUE; } else { String[] values = new String[size]; for (int i = 0; i < size; ++i) { values[i] = selector.lookupName(row.get(i)); } return values; } }; } } }
@Override public void aggregate() { // note: there might be room for optimization here but behavior must match BloomDimFilter implementation if (selector.getRow().size() > 1) { selector.getRow().forEach(v -> { String value = selector.lookupName(v); if (value == null) { collector.addBytes(null, 0, 0); } else { collector.addString(value); } }); } else { String value = (String) selector.getObject(); if (value == null) { collector.addBytes(null, 0, 0); } else { collector.addString(value); } } } }
); final ValueMatcher nullMatcher = selector.makeValueMatcher((String) null); final ValueMatcher fiveMatcher = selector.makeValueMatcher("5"); final ValueMatcher nonNullMatcher = selector.makeValueMatcher(Predicates.notNull()); Assert.assertEquals(false, fiveMatcher.matches()); Assert.assertEquals(false, nonNullMatcher.matches()); Assert.assertEquals(null, selector.lookupName(selector.getRow().get(0))); Assert.assertEquals(false, fiveMatcher.matches()); Assert.assertEquals(true, nonNullMatcher.matches()); Assert.assertEquals("4.0", selector.lookupName(selector.getRow().get(0))); } else { Assert.assertEquals(false, fiveMatcher.matches()); Assert.assertEquals(false, nonNullMatcher.matches()); Assert.assertEquals(null, selector.lookupName(selector.getRow().get(0))); Assert.assertEquals(false, fiveMatcher.matches()); Assert.assertEquals(true, nonNullMatcher.matches()); Assert.assertEquals("5.1", selector.lookupName(selector.getRow().get(0))); Assert.assertEquals(true, fiveMatcher.matches()); Assert.assertEquals(true, nonNullMatcher.matches()); Assert.assertEquals("5", selector.lookupName(selector.getRow().get(0)));
@Override public void updateSearchResultSet( String outputName, DimensionSelector selector, SearchQuerySpec searchQuerySpec, int limit, final Object2IntRBTreeMap<SearchHit> set ) { if (!DimensionSelector.isNilSelector(selector)) { final IndexedInts row = selector.getRow(); for (int i = 0, rowSize = row.size(); i < rowSize; ++i) { final String dimVal = selector.lookupName(row.get(i)); if (searchQuerySpec.accept(dimVal)) { set.addTo(new SearchHit(outputName, dimVal), 1); if (set.size() >= limit) { return; } } } } } }
private DimensionSelector filterWhiteList(DimensionSelector selector) { final int selectorCardinality = selector.getValueCardinality(); if (selectorCardinality < 0 || (selector.idLookup() == null && !selector.nameLookupPossibleInAdvance())) { return new PredicateFilteredDimensionSelector(selector, Predicates.in(values)); } final int maxPossibleFilteredCardinality = values.size(); int count = 0; final Int2IntOpenHashMap forwardMapping = new Int2IntOpenHashMap(maxPossibleFilteredCardinality); forwardMapping.defaultReturnValue(-1); final int[] reverseMapping = new int[maxPossibleFilteredCardinality]; IdLookup idLookup = selector.idLookup(); if (idLookup != null) { for (String value : values) { int i = idLookup.lookupId(value); if (i >= 0) { forwardMapping.put(i, count); reverseMapping[count++] = i; } } } else { for (int i = 0; i < selectorCardinality; i++) { if (values.contains(NullHandling.nullToEmptyIfNeeded(selector.lookupName(i)))) { forwardMapping.put(i, count); reverseMapping[count++] = i; } } } return new ForwardingFilteredDimensionSelector(selector, forwardMapping, reverseMapping); }
@Override public String lookupName(int id) { return selector.lookupName(reverseMapping[id]); }
@Override public int getValueCardinality() { return selector.getValueCardinality(); }
@Nullable @Override public IdLookup idLookup() { return selector.idLookup(); }
/** * @param selector must return true from {@link DimensionSelector#nameLookupPossibleInAdvance()} * @param forwardMapping must have {@link Int2IntOpenHashMap#defaultReturnValue(int)} configured to -1. */ ForwardingFilteredDimensionSelector( DimensionSelector selector, Int2IntOpenHashMap forwardMapping, int[] reverseMapping ) { this.selector = Preconditions.checkNotNull(selector); if (!selector.nameLookupPossibleInAdvance()) { throw new IAE("selector.nameLookupPossibleInAdvance() should return true"); } this.baseIdLookup = selector.idLookup(); this.forwardMapping = Preconditions.checkNotNull(forwardMapping); if (forwardMapping.defaultReturnValue() != -1) { throw new IAE("forwardMapping.defaultReturnValue() should be -1"); } this.reverseMapping = Preconditions.checkNotNull(reverseMapping); }
/** * Generic implementation of {@link DimensionSelector#makeValueMatcher(Predicate)}, uses {@link * DimensionSelector#getRow()} of the given {@link DimensionSelector}. "Lazy" DimensionSelectors could delegate * {@code makeValueMatcher()} to this method, but encouraged to implement {@code makeValueMatcher()} themselves, * bypassing the {@link IndexedInts} abstraction. */ public static ValueMatcher makeValueMatcherGeneric(DimensionSelector selector, Predicate<String> predicate) { int cardinality = selector.getValueCardinality(); if (cardinality >= 0 && selector.nameLookupPossibleInAdvance()) { return makeDictionaryEncodedValueMatcherGeneric(selector, predicate); } else { return makeNonDictionaryEncodedValueMatcherGeneric(selector, predicate); } }
@Override public Aggregator factorize(final ColumnSelectorFactory metricFactory) { if (metricColumns == null) { // input is sketches, use merge aggregator final BaseObjectColumnValueSelector<ArrayOfDoublesSketch> selector = metricFactory .makeColumnValueSelector(fieldName); if (selector instanceof NilColumnValueSelector) { return new ArrayOfDoublesSketchNoOpAggregator(numberOfValues); } return new ArrayOfDoublesSketchMergeAggregator(selector, nominalEntries, numberOfValues); } // input is raw data (key and array of values), use build aggregator final DimensionSelector keySelector = metricFactory .makeDimensionSelector(new DefaultDimensionSpec(fieldName, fieldName)); if (DimensionSelector.isNilSelector(keySelector)) { return new ArrayOfDoublesSketchNoOpAggregator(numberOfValues); } final List<BaseDoubleColumnValueSelector> valueSelectors = new ArrayList<>(); for (final String column : metricColumns) { final BaseDoubleColumnValueSelector valueSelector = metricFactory.makeColumnValueSelector(column); valueSelectors.add(valueSelector); } return new ArrayOfDoublesSketchBuildAggregator(keySelector, valueSelectors, nominalEntries); }
final int hash = HashBasedNumberedShardSpec.hash( jsonMapper, Collections.singletonList(selector.getObject()) ); cursor.advance();
@Test public void testDecoratorWithWhitelist() { ListFilteredDimensionSpec spec = new ListFilteredDimensionSpec( new DefaultDimensionSpec("foo", "bar"), ImmutableSet.of("c", "g"), true ); DimensionSelector selector = spec.decorate(TestDimensionSelector.instance); Assert.assertEquals(2, selector.getValueCardinality()); IndexedInts row = selector.getRow(); Assert.assertEquals(2, row.size()); Assert.assertEquals(0, row.get(0)); Assert.assertEquals(1, row.get(1)); Assert.assertEquals("c", selector.lookupName(0)); Assert.assertEquals("g", selector.lookupName(1)); Assert.assertEquals(0, selector.idLookup().lookupId("c")); Assert.assertEquals(1, selector.idLookup().lookupId("g")); }