Search in sources :

Example 1 with RangeIndexedInts

use of org.apache.druid.segment.data.RangeIndexedInts in project druid by druid-io.

the class RowBasedColumnSelectorFactory method makeDimensionSelectorUndecorated.

private DimensionSelector makeDimensionSelectorUndecorated(DimensionSpec dimensionSpec) {
    final String dimension = dimensionSpec.getDimension();
    final ExtractionFn extractionFn = dimensionSpec.getExtractionFn();
    if (ColumnHolder.TIME_COLUMN_NAME.equals(dimensionSpec.getDimension())) {
        if (extractionFn == null) {
            throw new UnsupportedOperationException("time dimension must provide an extraction function");
        }
        final ToLongFunction<T> timestampFunction = adapter.timestampFunction();
        return new BaseSingleValueDimensionSelector() {

            private long currentId = NO_ID;

            private String currentValue;

            @Override
            protected String getValue() {
                updateCurrentValue();
                return currentValue;
            }

            @Override
            public void inspectRuntimeShape(RuntimeShapeInspector inspector) {
                inspector.visit("row", rowSupplier);
                inspector.visit("extractionFn", extractionFn);
            }

            private void updateCurrentValue() {
                if (rowIdSupplier == null || rowIdSupplier.getAsLong() != currentId) {
                    currentValue = extractionFn.apply(timestampFunction.applyAsLong(rowSupplier.get()));
                    if (rowIdSupplier != null) {
                        currentId = rowIdSupplier.getAsLong();
                    }
                }
            }
        };
    } else {
        final Function<T, Object> dimFunction = adapter.columnFunction(dimension);
        return new DimensionSelector() {

            private long currentId = NO_ID;

            private List<String> dimensionValues;

            private final RangeIndexedInts indexedInts = new RangeIndexedInts();

            @Override
            public IndexedInts getRow() {
                updateCurrentValues();
                indexedInts.setSize(dimensionValues.size());
                return indexedInts;
            }

            @Override
            public ValueMatcher makeValueMatcher(@Nullable final String value) {
                return new ValueMatcher() {

                    @Override
                    public boolean matches() {
                        updateCurrentValues();
                        if (dimensionValues.isEmpty()) {
                            return value == null;
                        }
                        for (String dimensionValue : dimensionValues) {
                            if (Objects.equals(NullHandling.emptyToNullIfNeeded(dimensionValue), value)) {
                                return true;
                            }
                        }
                        return false;
                    }

                    @Override
                    public void inspectRuntimeShape(RuntimeShapeInspector inspector) {
                        inspector.visit("row", rowSupplier);
                        inspector.visit("extractionFn", extractionFn);
                    }
                };
            }

            @Override
            public ValueMatcher makeValueMatcher(final Predicate<String> predicate) {
                final boolean matchNull = predicate.apply(null);
                return new ValueMatcher() {

                    @Override
                    public boolean matches() {
                        updateCurrentValues();
                        if (dimensionValues.isEmpty()) {
                            return matchNull;
                        }
                        for (String dimensionValue : dimensionValues) {
                            if (predicate.apply(NullHandling.emptyToNullIfNeeded(dimensionValue))) {
                                return true;
                            }
                        }
                        return false;
                    }

                    @Override
                    public void inspectRuntimeShape(RuntimeShapeInspector inspector) {
                        inspector.visit("row", rowSupplier);
                        inspector.visit("predicate", predicate);
                        inspector.visit("extractionFn", extractionFn);
                    }
                };
            }

            @Override
            public int getValueCardinality() {
                return DimensionDictionarySelector.CARDINALITY_UNKNOWN;
            }

            @Override
            public String lookupName(int id) {
                updateCurrentValues();
                return NullHandling.emptyToNullIfNeeded(dimensionValues.get(id));
            }

            @Override
            public boolean nameLookupPossibleInAdvance() {
                return false;
            }

            @Nullable
            @Override
            public IdLookup idLookup() {
                return null;
            }

            @Nullable
            @Override
            public Object getObject() {
                updateCurrentValues();
                if (dimensionValues.size() == 1) {
                    return dimensionValues.get(0);
                }
                return dimensionValues;
            }

            @Override
            public Class classOfObject() {
                return Object.class;
            }

            @Override
            public void inspectRuntimeShape(RuntimeShapeInspector inspector) {
                inspector.visit("row", rowSupplier);
                inspector.visit("extractionFn", extractionFn);
            }

            private void updateCurrentValues() {
                if (rowIdSupplier == null || rowIdSupplier.getAsLong() != currentId) {
                    try {
                        final Object rawValue = dimFunction.apply(rowSupplier.get());
                        if (rawValue == null || rawValue instanceof String) {
                            final String s = NullHandling.emptyToNullIfNeeded((String) rawValue);
                            if (extractionFn == null) {
                                dimensionValues = Collections.singletonList(s);
                            } else {
                                dimensionValues = Collections.singletonList(extractionFn.apply(s));
                            }
                        } else if (rawValue instanceof List) {
                            // Consistent behavior with Rows.objectToStrings, but applies extractionFn too.
                            // noinspection rawtypes
                            final List<String> values = new ArrayList<>(((List) rawValue).size());
                            // noinspection rawtypes
                            for (final Object item : ((List) rawValue)) {
                                // commonly used when retrieving strings from input-row-like objects.
                                if (extractionFn == null) {
                                    values.add(String.valueOf(item));
                                } else {
                                    values.add(extractionFn.apply(String.valueOf(item)));
                                }
                            }
                            dimensionValues = values;
                        } else {
                            final List<String> nonExtractedValues = Rows.objectToStrings(rawValue);
                            dimensionValues = new ArrayList<>(nonExtractedValues.size());
                            for (final String value : nonExtractedValues) {
                                final String s = NullHandling.emptyToNullIfNeeded(value);
                                if (extractionFn == null) {
                                    dimensionValues.add(s);
                                } else {
                                    dimensionValues.add(extractionFn.apply(s));
                                }
                            }
                        }
                    } catch (Throwable e) {
                        currentId = NO_ID;
                        throw e;
                    }
                    if (rowIdSupplier != null) {
                        currentId = rowIdSupplier.getAsLong();
                    }
                }
            }
        };
    }
}
Also used : ValueMatcher(org.apache.druid.query.filter.ValueMatcher) ArrayList(java.util.ArrayList) RuntimeShapeInspector(org.apache.druid.query.monomorphicprocessing.RuntimeShapeInspector) RangeIndexedInts(org.apache.druid.segment.data.RangeIndexedInts) Predicate(com.google.common.base.Predicate) ExtractionFn(org.apache.druid.query.extraction.ExtractionFn) ArrayList(java.util.ArrayList) List(java.util.List) Nullable(javax.annotation.Nullable)

Example 2 with RangeIndexedInts

use of org.apache.druid.segment.data.RangeIndexedInts in project druid by druid-io.

the class ExpressionMultiValueDimensionSelector method getRow.

@Override
public IndexedInts getRow() {
    ExprEval evaluated = getEvaluated();
    if (evaluated.isArray()) {
        RangeIndexedInts ints = new RangeIndexedInts();
        Object[] evaluatedArray = evaluated.asArray();
        ints.setSize(evaluatedArray != null ? evaluatedArray.length : 0);
        return ints;
    }
    return ZeroIndexedInts.instance();
}
Also used : ExprEval(org.apache.druid.math.expr.ExprEval) RangeIndexedInts(org.apache.druid.segment.data.RangeIndexedInts)

Aggregations

RangeIndexedInts (org.apache.druid.segment.data.RangeIndexedInts)2 Predicate (com.google.common.base.Predicate)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Nullable (javax.annotation.Nullable)1 ExprEval (org.apache.druid.math.expr.ExprEval)1 ExtractionFn (org.apache.druid.query.extraction.ExtractionFn)1 ValueMatcher (org.apache.druid.query.filter.ValueMatcher)1 RuntimeShapeInspector (org.apache.druid.query.monomorphicprocessing.RuntimeShapeInspector)1