use of org.apache.druid.segment.column.ColumnCapabilities in project druid by apache.
the class RowBasedStorageAdapterTest method test_getColumnCapabilities_complex.
@Test
public void test_getColumnCapabilities_complex() {
final RowBasedStorageAdapter<Integer> adapter = createIntAdapter(0, 1, 2);
final ColumnCapabilities capabilities = adapter.getColumnCapabilities(ValueType.COMPLEX.name());
// Note: unlike numeric types, COMPLEX-typed columns report that they are incomplete.
Assert.assertEquals(ColumnType.UNKNOWN_COMPLEX, capabilities.toColumnType());
Assert.assertTrue(capabilities.hasMultipleValues().isUnknown());
}
use of org.apache.druid.segment.column.ColumnCapabilities in project druid by apache.
the class RowBasedStorageAdapterTest method test_getColumnCapabilities_double.
@Test
public void test_getColumnCapabilities_double() {
final RowBasedStorageAdapter<Integer> adapter = createIntAdapter(0, 1, 2);
final ColumnCapabilities capabilities = adapter.getColumnCapabilities(ValueType.DOUBLE.name());
Assert.assertEquals(ValueType.DOUBLE, capabilities.getType());
Assert.assertFalse(capabilities.hasMultipleValues().isMaybeTrue());
}
use of org.apache.druid.segment.column.ColumnCapabilities in project druid by apache.
the class ColumnProcessors method makeProcessorInternal.
/**
* Creates "column processors", which are objects that wrap a single input column and provide some
* functionality on top of it.
*
* @param inputCapabilitiesFn function that returns capabilities of the column being processed. The type provided
* by these capabilities will be used to determine what kind of selector to create. If
* this function returns null, then processorFactory.defaultType() will be
* used to construct a set of assumed capabilities.
* @param dimensionSelectorFn function that creates a DimensionSelector for the column being processed. Will be
* called if the column type is string.
* @param valueSelectorFunction function that creates a ColumnValueSelector for the column being processed. Will be
* called if the column type is long, float, double, or complex.
* @param processorFactory object that encapsulates the knowledge about how to create processors
* @param selectorFactory column selector factory used for creating the vector processor
*/
private static <T> T makeProcessorInternal(final Function<ColumnSelectorFactory, ColumnCapabilities> inputCapabilitiesFn, final Function<ColumnSelectorFactory, DimensionSelector> dimensionSelectorFn, final Function<ColumnSelectorFactory, ColumnValueSelector<?>> valueSelectorFunction, final ColumnProcessorFactory<T> processorFactory, final ColumnSelectorFactory selectorFactory) {
final ColumnCapabilities capabilities = inputCapabilitiesFn.apply(selectorFactory);
final TypeSignature<ValueType> effectiveType = capabilities != null ? capabilities : processorFactory.defaultType();
switch(effectiveType.getType()) {
case STRING:
return processorFactory.makeDimensionProcessor(dimensionSelectorFn.apply(selectorFactory), mayBeMultiValue(capabilities));
case LONG:
return processorFactory.makeLongProcessor(valueSelectorFunction.apply(selectorFactory));
case FLOAT:
return processorFactory.makeFloatProcessor(valueSelectorFunction.apply(selectorFactory));
case DOUBLE:
return processorFactory.makeDoubleProcessor(valueSelectorFunction.apply(selectorFactory));
case COMPLEX:
return processorFactory.makeComplexProcessor(valueSelectorFunction.apply(selectorFactory));
default:
throw new ISE("Unsupported type[%s]", effectiveType.asTypeString());
}
}
use of org.apache.druid.segment.column.ColumnCapabilities in project druid by apache.
the class TopNQueryEngine method getMapFn.
/**
* Choose the best {@link TopNAlgorithm} for the given query.
*/
private TopNMapFn getMapFn(final TopNQuery query, final StorageAdapter adapter, @Nullable final TopNQueryMetrics queryMetrics) {
final String dimension = query.getDimensionSpec().getDimension();
final int cardinality = adapter.getDimensionCardinality(dimension);
if (queryMetrics != null) {
queryMetrics.dimensionCardinality(cardinality);
}
int numBytesPerRecord = 0;
for (AggregatorFactory aggregatorFactory : query.getAggregatorSpecs()) {
numBytesPerRecord += aggregatorFactory.getMaxIntermediateSizeWithNulls();
}
final TopNAlgorithmSelector selector = new TopNAlgorithmSelector(cardinality, numBytesPerRecord);
query.initTopNAlgorithmSelector(selector);
final ColumnCapabilities columnCapabilities = query.getVirtualColumns().getColumnCapabilitiesWithFallback(adapter, dimension);
final TopNAlgorithm<?, ?> topNAlgorithm;
if (canUsePooledAlgorithm(selector, query, columnCapabilities)) {
// pool based algorithm selection, if we can
if (selector.isAggregateAllMetrics()) {
// if sorted by dimension we should aggregate all metrics in a single pass, use the regular pooled algorithm for
// this
topNAlgorithm = new PooledTopNAlgorithm(adapter, query, bufferPool);
} else if (selector.isAggregateTopNMetricFirst() || query.getContextBoolean("doAggregateTopNMetricFirst", false)) {
// for high cardinality dimensions with larger result sets we aggregate with only the ordering aggregation to
// compute the first 'n' values, and then for the rest of the metrics but for only the 'n' values
topNAlgorithm = new AggregateTopNMetricFirstAlgorithm(adapter, query, bufferPool);
} else {
// anything else, use the regular pooled algorithm
topNAlgorithm = new PooledTopNAlgorithm(adapter, query, bufferPool);
}
} else {
// heap based algorithm selection, if we must
if (selector.isHasExtractionFn() && dimension.equals(ColumnHolder.TIME_COLUMN_NAME)) {
// TimeExtractionTopNAlgorithm can work on any single-value dimension of type long.
// We might be able to use this for any long column with an extraction function, that is
// ValueType.LONG.equals(columnCapabilities.getType())
// but this needs investigation to ensure that it is an improvement over HeapBasedTopNAlgorithm
// A special TimeExtractionTopNAlgorithm is required since HeapBasedTopNAlgorithm
// currently relies on the dimension cardinality to support lexicographic sorting
topNAlgorithm = new TimeExtractionTopNAlgorithm(adapter, query);
} else {
topNAlgorithm = new HeapBasedTopNAlgorithm(adapter, query);
}
}
if (queryMetrics != null) {
queryMetrics.algorithm(topNAlgorithm);
}
return new TopNMapFn(query, topNAlgorithm);
}
use of org.apache.druid.segment.column.ColumnCapabilities in project druid by apache.
the class ExpressionVectorSelectors method createVectorBindings.
private static Expr.VectorInputBinding createVectorBindings(Expr.BindingAnalysis bindingAnalysis, VectorColumnSelectorFactory vectorColumnSelectorFactory) {
ExpressionVectorInputBinding binding = new ExpressionVectorInputBinding(vectorColumnSelectorFactory.getReadableVectorInspector());
final List<String> columns = bindingAnalysis.getRequiredBindingsList();
for (String columnName : columns) {
final ColumnCapabilities columnCapabilities = vectorColumnSelectorFactory.getColumnCapabilities(columnName);
// null capabilities should be backed by a nil vector selector since it means the column effectively doesnt exist
if (columnCapabilities != null) {
switch(columnCapabilities.getType()) {
case FLOAT:
case DOUBLE:
binding.addNumeric(columnName, ExpressionType.DOUBLE, vectorColumnSelectorFactory.makeValueSelector(columnName));
break;
case LONG:
binding.addNumeric(columnName, ExpressionType.LONG, vectorColumnSelectorFactory.makeValueSelector(columnName));
break;
default:
binding.addObjectSelector(columnName, ExpressionType.STRING, vectorColumnSelectorFactory.makeObjectSelector(columnName));
}
}
}
return binding;
}
Aggregations