use of org.apache.druid.segment.RowBasedColumnSelectorFactory in project druid by druid-io.
the class IncrementalIndex method makeColumnSelectorFactory.
/**
* Column selector used at ingestion time for inputs to aggregators.
*
* @param agg the aggregator
* @param in ingestion-time input row supplier
* @param deserializeComplexMetrics whether complex objects should be deserialized by a {@link ComplexMetricExtractor}
*
* @return column selector factory
*/
public static ColumnSelectorFactory makeColumnSelectorFactory(final VirtualColumns virtualColumns, final AggregatorFactory agg, final Supplier<InputRow> in, final boolean deserializeComplexMetrics) {
// we use RowSignature.empty() because ColumnInspector here should be the InputRow schema, not the
// IncrementalIndex schema, because we are reading values from the InputRow
final RowBasedColumnSelectorFactory<InputRow> baseSelectorFactory = RowBasedColumnSelectorFactory.create(RowAdapters.standardRow(), in::get, RowSignature.empty(), true);
class IncrementalIndexInputRowColumnSelectorFactory implements ColumnSelectorFactory {
@Override
public ColumnValueSelector<?> makeColumnValueSelector(final String column) {
final boolean isComplexMetric = agg.getIntermediateType().is(ValueType.COMPLEX);
final ColumnValueSelector selector = baseSelectorFactory.makeColumnValueSelector(column);
if (!isComplexMetric || !deserializeComplexMetrics) {
return selector;
} else {
// Wrap selector in a special one that uses ComplexMetricSerde to modify incoming objects.
// For complex aggregators that read from multiple columns, we wrap all of them. This is not ideal but it
// has worked so far.
final String complexTypeName = agg.getIntermediateType().getComplexTypeName();
final ComplexMetricSerde serde = ComplexMetrics.getSerdeForType(complexTypeName);
if (serde == null) {
throw new ISE("Don't know how to handle type[%s]", complexTypeName);
}
final ComplexMetricExtractor extractor = serde.getExtractor();
return new ColumnValueSelector() {
@Override
public boolean isNull() {
return selector.isNull();
}
@Override
public long getLong() {
return selector.getLong();
}
@Override
public float getFloat() {
return selector.getFloat();
}
@Override
public double getDouble() {
return selector.getDouble();
}
@Override
public Class classOfObject() {
return extractor.extractedClass();
}
@Nullable
@Override
public Object getObject() {
// Here is where the magic happens: read from "in" directly, don't go through the normal "selector".
return extractor.extractValue(in.get(), column, agg);
}
@Override
public void inspectRuntimeShape(RuntimeShapeInspector inspector) {
inspector.visit("in", in);
inspector.visit("selector", selector);
inspector.visit("extractor", extractor);
}
};
}
}
@Override
public DimensionSelector makeDimensionSelector(DimensionSpec dimensionSpec) {
return baseSelectorFactory.makeDimensionSelector(dimensionSpec);
}
@Nullable
@Override
public ColumnCapabilities getColumnCapabilities(String columnName) {
return baseSelectorFactory.getColumnCapabilities(columnName);
}
}
return virtualColumns.wrap(new IncrementalIndexInputRowColumnSelectorFactory());
}
Aggregations