use of org.apache.druid.segment.AbstractDimensionSelector in project druid by druid-io.
the class StringDictionaryEncodedColumn method makeDimensionSelector.
@Override
public HistoricalDimensionSelector makeDimensionSelector(final ReadableOffset offset, @Nullable final ExtractionFn extractionFn) {
abstract class QueryableDimensionSelector extends AbstractDimensionSelector implements HistoricalDimensionSelector, IdLookup {
@Override
public int getValueCardinality() {
/*
This is technically wrong if
extractionFn != null && (extractionFn.getExtractionType() != ExtractionFn.ExtractionType.ONE_TO_ONE ||
!extractionFn.preservesOrdering())
However current behavior allows some GroupBy-V1 queries to work that wouldn't work otherwise and doesn't
cause any problems due to special handling of extractionFn everywhere.
See https://github.com/apache/druid/pull/8433
*/
return getCardinality();
}
@Override
public String lookupName(int id) {
final String value = StringDictionaryEncodedColumn.this.lookupName(id);
return extractionFn == null ? value : extractionFn.apply(value);
}
@Nullable
@Override
public ByteBuffer lookupNameUtf8(int id) {
return StringDictionaryEncodedColumn.this.lookupNameUtf8(id);
}
@Override
public boolean supportsLookupNameUtf8() {
return true;
}
@Override
public boolean nameLookupPossibleInAdvance() {
return true;
}
@Nullable
@Override
public IdLookup idLookup() {
return extractionFn == null ? this : null;
}
@Override
public int lookupId(String name) {
if (extractionFn != null) {
throw new UnsupportedOperationException("cannot perform lookup when applying an extraction function");
}
return StringDictionaryEncodedColumn.this.lookupId(name);
}
}
if (hasMultipleValues()) {
class MultiValueDimensionSelector extends QueryableDimensionSelector {
@Override
public IndexedInts getRow() {
return multiValueColumn.get(offset.getOffset());
}
@Override
public IndexedInts getRow(int offset) {
return multiValueColumn.get(offset);
}
@Override
public ValueMatcher makeValueMatcher(@Nullable String value) {
return DimensionSelectorUtils.makeValueMatcherGeneric(this, value);
}
@Override
public ValueMatcher makeValueMatcher(Predicate<String> predicate) {
return DimensionSelectorUtils.makeValueMatcherGeneric(this, predicate);
}
@Nullable
@Override
public Object getObject() {
return defaultGetObject();
}
@Override
public Class classOfObject() {
return Object.class;
}
@Override
public void inspectRuntimeShape(RuntimeShapeInspector inspector) {
inspector.visit("multiValueColumn", multiValueColumn);
inspector.visit("offset", offset);
inspector.visit("extractionFn", extractionFn);
}
}
return new MultiValueDimensionSelector();
} else {
class SingleValueQueryableDimensionSelector extends QueryableDimensionSelector implements SingleValueHistoricalDimensionSelector {
private final SingleIndexedInt row = new SingleIndexedInt();
@Override
public IndexedInts getRow() {
row.setValue(getRowValue());
return row;
}
public int getRowValue() {
return column.get(offset.getOffset());
}
@Override
public IndexedInts getRow(int offset) {
row.setValue(getRowValue(offset));
return row;
}
@Override
public int getRowValue(int offset) {
return column.get(offset);
}
@Override
public ValueMatcher makeValueMatcher(@Nullable final String value) {
if (extractionFn == null) {
final int valueId = lookupId(value);
if (valueId >= 0) {
return new ValueMatcher() {
@Override
public boolean matches() {
return getRowValue() == valueId;
}
@Override
public void inspectRuntimeShape(RuntimeShapeInspector inspector) {
inspector.visit("column", StringDictionaryEncodedColumn.this);
}
};
} else {
return BooleanValueMatcher.of(false);
}
} else {
// Employ caching BitSet optimization
return makeValueMatcher(Predicates.equalTo(value));
}
}
@Override
public ValueMatcher makeValueMatcher(final Predicate<String> predicate) {
final BitSet checkedIds = new BitSet(getCardinality());
final BitSet matchingIds = new BitSet(getCardinality());
// Lazy matcher; only check an id if matches() is called.
return new ValueMatcher() {
@Override
public boolean matches() {
final int id = getRowValue();
if (checkedIds.get(id)) {
return matchingIds.get(id);
} else {
final boolean matches = predicate.apply(lookupName(id));
checkedIds.set(id);
if (matches) {
matchingIds.set(id);
}
return matches;
}
}
@Override
public void inspectRuntimeShape(RuntimeShapeInspector inspector) {
inspector.visit("column", StringDictionaryEncodedColumn.this);
}
};
}
@Override
public Object getObject() {
return lookupName(getRowValue());
}
@Override
public Class classOfObject() {
return String.class;
}
@Override
public void inspectRuntimeShape(RuntimeShapeInspector inspector) {
inspector.visit("column", column);
inspector.visit("offset", offset);
inspector.visit("extractionFn", extractionFn);
}
}
return new SingleValueQueryableDimensionSelector();
}
}
use of org.apache.druid.segment.AbstractDimensionSelector in project druid by druid-io.
the class FilteredAggregatorTest method makeColumnSelector.
private ColumnSelectorFactory makeColumnSelector(final TestFloatColumnSelector selector) {
return new ColumnSelectorFactory() {
@Override
public DimensionSelector makeDimensionSelector(DimensionSpec dimensionSpec) {
final String dimensionName = dimensionSpec.getDimension();
if ("dim".equals(dimensionName)) {
return dimensionSpec.decorate(new AbstractDimensionSelector() {
@Override
public IndexedInts getRow() {
SingleIndexedInt row = new SingleIndexedInt();
if (selector.getIndex() % 3 == 2) {
row.setValue(1);
} else {
row.setValue(0);
}
return row;
}
@Override
public ValueMatcher makeValueMatcher(String value) {
return DimensionSelectorUtils.makeValueMatcherGeneric(this, value);
}
@Override
public ValueMatcher makeValueMatcher(Predicate<String> predicate) {
return DimensionSelectorUtils.makeValueMatcherGeneric(this, predicate);
}
@Override
public int getValueCardinality() {
return 2;
}
@Override
public String lookupName(int id) {
switch(id) {
case 0:
return "a";
case 1:
return "b";
default:
throw new IllegalArgumentException();
}
}
@Override
public boolean nameLookupPossibleInAdvance() {
return true;
}
@Nullable
@Override
public IdLookup idLookup() {
return new IdLookup() {
@Override
public int lookupId(String name) {
switch(name) {
case "a":
return 0;
case "b":
return 1;
default:
throw new IllegalArgumentException();
}
}
};
}
@Override
public Class classOfObject() {
return Object.class;
}
@Override
public void inspectRuntimeShape(RuntimeShapeInspector inspector) {
// Don't care about runtime shape in tests
}
});
} else {
throw new UnsupportedOperationException();
}
}
@Override
public ColumnValueSelector<?> makeColumnValueSelector(String columnName) {
if ("value".equals(columnName)) {
return selector;
} else {
throw new UnsupportedOperationException();
}
}
@Override
public ColumnCapabilities getColumnCapabilities(String columnName) {
ColumnCapabilitiesImpl caps;
if ("value".equals(columnName)) {
caps = new ColumnCapabilitiesImpl();
caps.setType(ColumnType.FLOAT);
caps.setDictionaryEncoded(false);
caps.setHasBitmapIndexes(false);
} else {
caps = new ColumnCapabilitiesImpl();
caps.setType(ColumnType.STRING);
caps.setDictionaryEncoded(true);
caps.setHasBitmapIndexes(true);
}
return caps;
}
};
}
Aggregations