Hide NullDimensionSelector from public (#6480)

This commit is contained in:
Roman Leventov 2018-11-02 12:38:21 +01:00 committed by Jihoon Son
parent 23ad3d214c
commit a2a1a1c2c9
10 changed files with 155 additions and 178 deletions

View File

@ -40,7 +40,6 @@ import org.apache.druid.segment.BaseObjectColumnValueSelector;
import org.apache.druid.segment.ColumnSelectorFactory; import org.apache.druid.segment.ColumnSelectorFactory;
import org.apache.druid.segment.ColumnValueSelector; import org.apache.druid.segment.ColumnValueSelector;
import org.apache.druid.segment.DimensionSelector; import org.apache.druid.segment.DimensionSelector;
import org.apache.druid.segment.DimensionSelectorUtils;
import org.apache.druid.segment.NilColumnValueSelector; import org.apache.druid.segment.NilColumnValueSelector;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -101,7 +100,7 @@ public class ArrayOfDoublesSketchAggregatorFactory extends AggregatorFactory
// input is raw data (key and array of values), use build aggregator // input is raw data (key and array of values), use build aggregator
final DimensionSelector keySelector = metricFactory final DimensionSelector keySelector = metricFactory
.makeDimensionSelector(new DefaultDimensionSpec(fieldName, fieldName)); .makeDimensionSelector(new DefaultDimensionSpec(fieldName, fieldName));
if (DimensionSelectorUtils.isNilSelector(keySelector)) { if (DimensionSelector.isNilSelector(keySelector)) {
return new ArrayOfDoublesSketchNoOpAggregator(numberOfValues); return new ArrayOfDoublesSketchNoOpAggregator(numberOfValues);
} }
final List<BaseDoubleColumnValueSelector> valueSelectors = new ArrayList<>(); final List<BaseDoubleColumnValueSelector> valueSelectors = new ArrayList<>();
@ -131,7 +130,7 @@ public class ArrayOfDoublesSketchAggregatorFactory extends AggregatorFactory
// input is raw data (key and array of values), use build aggregator // input is raw data (key and array of values), use build aggregator
final DimensionSelector keySelector = metricFactory final DimensionSelector keySelector = metricFactory
.makeDimensionSelector(new DefaultDimensionSpec(fieldName, fieldName)); .makeDimensionSelector(new DefaultDimensionSpec(fieldName, fieldName));
if (DimensionSelectorUtils.isNilSelector(keySelector)) { if (DimensionSelector.isNilSelector(keySelector)) {
return new ArrayOfDoublesSketchNoOpBufferAggregator(numberOfValues); return new ArrayOfDoublesSketchNoOpBufferAggregator(numberOfValues);
} }
final List<BaseDoubleColumnValueSelector> valueSelectors = new ArrayList<>(); final List<BaseDoubleColumnValueSelector> valueSelectors = new ArrayList<>();

View File

@ -41,7 +41,6 @@ import org.apache.druid.segment.BaseFloatColumnValueSelector;
import org.apache.druid.segment.BaseLongColumnValueSelector; import org.apache.druid.segment.BaseLongColumnValueSelector;
import org.apache.druid.segment.ColumnValueSelector; import org.apache.druid.segment.ColumnValueSelector;
import org.apache.druid.segment.DimensionSelector; import org.apache.druid.segment.DimensionSelector;
import org.apache.druid.segment.DimensionSelectorUtils;
import org.apache.druid.segment.Segment; import org.apache.druid.segment.Segment;
import org.apache.druid.segment.column.ColumnCapabilities; import org.apache.druid.segment.column.ColumnCapabilities;
import org.apache.druid.segment.column.ValueType; import org.apache.druid.segment.column.ValueType;
@ -127,7 +126,7 @@ public class SearchQueryRunner implements QueryRunner<Result<SearchResultValue>>
final Object2IntRBTreeMap<SearchHit> set final Object2IntRBTreeMap<SearchHit> set
) )
{ {
if (!DimensionSelectorUtils.isNilSelector(selector)) { if (!DimensionSelector.isNilSelector(selector)) {
final IndexedInts row = selector.getRow(); final IndexedInts row = selector.getRow();
for (int i = 0, rowSize = row.size(); i < rowSize; ++i) { for (int i = 0, rowSize = row.size(); i < rowSize; ++i) {
final String dimVal = selector.lookupName(row.get(i)); final String dimVal = selector.lookupName(row.get(i));

View File

@ -35,11 +35,11 @@ public class ConstantDimensionSelector implements SingleValueHistoricalDimension
{ {
private final String value; private final String value;
public ConstantDimensionSelector(final String value) ConstantDimensionSelector(final String value)
{ {
if (NullHandling.isNullOrEquivalent(value)) { if (NullHandling.isNullOrEquivalent(value)) {
// There's an optimized implementation for nulls that callers should use instead. // There's an optimized implementation for nulls that callers should use instead.
throw new IllegalArgumentException("Use NullDimensionSelector or DimensionSelectorUtils.constantSelector"); throw new IllegalArgumentException("Use DimensionSelector.constant(null)");
} }
this.value = value; this.value = value;

View File

@ -20,11 +20,17 @@
package org.apache.druid.segment; package org.apache.druid.segment;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.guice.annotations.PublicApi; import org.apache.druid.guice.annotations.PublicApi;
import org.apache.druid.query.extraction.ExtractionFn;
import org.apache.druid.query.filter.ValueMatcher; import org.apache.druid.query.filter.ValueMatcher;
import org.apache.druid.query.monomorphicprocessing.CalledFromHotLoop; import org.apache.druid.query.monomorphicprocessing.CalledFromHotLoop;
import org.apache.druid.query.monomorphicprocessing.HotLoopCallee; import org.apache.druid.query.monomorphicprocessing.HotLoopCallee;
import org.apache.druid.query.monomorphicprocessing.RuntimeShapeInspector;
import org.apache.druid.segment.data.IndexedInts; import org.apache.druid.segment.data.IndexedInts;
import org.apache.druid.segment.data.ZeroIndexedInts;
import org.apache.druid.segment.filter.BooleanValueMatcher;
import org.apache.druid.segment.historical.SingleValueHistoricalDimensionSelector;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Arrays; import java.util.Arrays;
@ -196,4 +202,138 @@ public interface DimensionSelector extends ColumnValueSelector<Object>, HotLoopC
return Arrays.asList(strings); return Arrays.asList(strings);
} }
} }
static DimensionSelector constant(@Nullable final String value)
{
if (NullHandling.isNullOrEquivalent(value)) {
return NullDimensionSelectorHolder.NULL_DIMENSION_SELECTOR;
} else {
return new ConstantDimensionSelector(value);
}
}
static DimensionSelector constant(@Nullable final String value, @Nullable final ExtractionFn extractionFn)
{
if (extractionFn == null) {
return constant(value);
} else {
return constant(extractionFn.apply(value));
}
}
/**
* 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;
}
/**
* This class not a public API. It is needed solely to make NULL_DIMENSION_SELECTOR and NullDimensionSelector private
* and inaccessible even from classes in the same package. It could be removed, when Druid is updated to at least Java
* 9, that supports private members in interfaces.
*/
class NullDimensionSelectorHolder
{
private static final NullDimensionSelector NULL_DIMENSION_SELECTOR = new NullDimensionSelector();
/**
* This class is specially made a nested member of {@link DimensionSelector} interface, and accessible only through
* calling DimensionSelector.constant(null), so that it's impossible to mistakely use NullDimensionSelector in
* instanceof statements. {@link #isNilSelector} method should be used instead.
*/
private static class NullDimensionSelector implements SingleValueHistoricalDimensionSelector, IdLookup
{
private NullDimensionSelector()
{
// Singleton.
}
@Override
public IndexedInts getRow()
{
return ZeroIndexedInts.instance();
}
@Override
public int getRowValue(int offset)
{
return 0;
}
@Override
public IndexedInts getRow(int offset)
{
return getRow();
}
@Override
public ValueMatcher makeValueMatcher(@Nullable String value)
{
return BooleanValueMatcher.of(value == null);
}
@Override
public ValueMatcher makeValueMatcher(Predicate<String> predicate)
{
return BooleanValueMatcher.of(predicate.apply(null));
}
@Override
public int getValueCardinality()
{
return 1;
}
@Override
@Nullable
public String lookupName(int id)
{
assert id == 0 : "id = " + id;
return null;
}
@Override
public boolean nameLookupPossibleInAdvance()
{
return true;
}
@Nullable
@Override
public IdLookup idLookup()
{
return this;
}
@Override
public int lookupId(@Nullable String name)
{
return NullHandling.isNullOrEquivalent(name) ? 0 : -1;
}
@Nullable
@Override
public Object getObject()
{
return null;
}
@Override
public Class classOfObject()
{
return Object.class;
}
@Override
public void inspectRuntimeShape(RuntimeShapeInspector inspector)
{
// nothing to inspect
}
}
}
} }

View File

@ -21,9 +21,7 @@ package org.apache.druid.segment;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.java.util.common.IAE; import org.apache.druid.java.util.common.IAE;
import org.apache.druid.query.extraction.ExtractionFn;
import org.apache.druid.query.filter.ValueMatcher; import org.apache.druid.query.filter.ValueMatcher;
import org.apache.druid.query.monomorphicprocessing.RuntimeShapeInspector; import org.apache.druid.query.monomorphicprocessing.RuntimeShapeInspector;
import org.apache.druid.segment.data.IndexedInts; import org.apache.druid.segment.data.IndexedInts;
@ -265,32 +263,4 @@ public final class DimensionSelectorUtils
} }
return valueIds; return valueIds;
} }
public static DimensionSelector constantSelector(@Nullable final String value)
{
if (NullHandling.isNullOrEquivalent(value)) {
return NullDimensionSelector.instance();
} else {
return new ConstantDimensionSelector(value);
}
}
public static DimensionSelector constantSelector(
@Nullable final String value,
@Nullable final ExtractionFn extractionFn
)
{
if (extractionFn == null) {
return constantSelector(value);
} else {
return constantSelector(extractionFn.apply(value));
}
}
public static boolean isNilSelector(final DimensionSelector selector)
{
return selector.nameLookupPossibleInAdvance()
&& selector.getValueCardinality() == 1
&& selector.lookupName(0) == null;
}
} }

View File

@ -1,128 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.druid.segment;
import com.google.common.base.Predicate;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.query.filter.ValueMatcher;
import org.apache.druid.query.monomorphicprocessing.RuntimeShapeInspector;
import org.apache.druid.segment.data.IndexedInts;
import org.apache.druid.segment.data.ZeroIndexedInts;
import org.apache.druid.segment.filter.BooleanValueMatcher;
import org.apache.druid.segment.historical.SingleValueHistoricalDimensionSelector;
import javax.annotation.Nullable;
public class NullDimensionSelector implements SingleValueHistoricalDimensionSelector, IdLookup
{
private static final NullDimensionSelector INSTANCE = new NullDimensionSelector();
private NullDimensionSelector()
{
// Singleton.
}
public static NullDimensionSelector instance()
{
return INSTANCE;
}
@Override
public IndexedInts getRow()
{
return ZeroIndexedInts.instance();
}
@Override
public int getRowValue(int offset)
{
return 0;
}
@Override
public IndexedInts getRow(int offset)
{
return getRow();
}
@Override
public ValueMatcher makeValueMatcher(@Nullable String value)
{
return BooleanValueMatcher.of(value == null);
}
@Override
public ValueMatcher makeValueMatcher(Predicate<String> predicate)
{
return BooleanValueMatcher.of(predicate.apply(null));
}
@Override
public int getValueCardinality()
{
return 1;
}
@Override
@Nullable
public String lookupName(int id)
{
assert id == 0 : "id = " + id;
return null;
}
@Override
public boolean nameLookupPossibleInAdvance()
{
return true;
}
@Nullable
@Override
public IdLookup idLookup()
{
return this;
}
@Override
public int lookupId(@Nullable String name)
{
return NullHandling.isNullOrEquivalent(name) ? 0 : -1;
}
@Nullable
@Override
public Object getObject()
{
return null;
}
@Override
public Class classOfObject()
{
return Object.class;
}
@Override
public void inspectRuntimeShape(RuntimeShapeInspector inspector)
{
// nothing to inspect
}
}

View File

@ -81,7 +81,7 @@ class QueryableIndexColumnSelectorFactory implements ColumnSelectorFactory
final ColumnHolder columnHolder = index.getColumnHolder(dimension); final ColumnHolder columnHolder = index.getColumnHolder(dimension);
if (columnHolder == null) { if (columnHolder == null) {
return DimensionSelectorUtils.constantSelector(null, extractionFn); return DimensionSelector.constant(null, extractionFn);
} }
if (dimension.equals(ColumnHolder.TIME_COLUMN_NAME)) { if (dimension.equals(ColumnHolder.TIME_COLUMN_NAME)) {
@ -108,7 +108,7 @@ class QueryableIndexColumnSelectorFactory implements ColumnSelectorFactory
//noinspection unchecked //noinspection unchecked
return ((DictionaryEncodedColumn<String>) column).makeDimensionSelector(offset, extractionFn); return ((DictionaryEncodedColumn<String>) column).makeDimensionSelector(offset, extractionFn);
} else { } else {
return DimensionSelectorUtils.constantSelector(null, extractionFn); return DimensionSelector.constant(null, extractionFn);
} }
} }

View File

@ -25,7 +25,6 @@ import org.apache.druid.segment.ColumnSelectorFactory;
import org.apache.druid.segment.ColumnValueSelector; import org.apache.druid.segment.ColumnValueSelector;
import org.apache.druid.segment.DimensionIndexer; import org.apache.druid.segment.DimensionIndexer;
import org.apache.druid.segment.DimensionSelector; import org.apache.druid.segment.DimensionSelector;
import org.apache.druid.segment.DimensionSelectorUtils;
import org.apache.druid.segment.SingleScanTimeDimensionSelector; import org.apache.druid.segment.SingleScanTimeDimensionSelector;
import org.apache.druid.segment.VirtualColumns; import org.apache.druid.segment.VirtualColumns;
import org.apache.druid.segment.column.ColumnCapabilities; import org.apache.druid.segment.column.ColumnCapabilities;
@ -81,7 +80,7 @@ class IncrementalIndexColumnSelectorFactory implements ColumnSelectorFactory
// not a dimension, column may be a metric // not a dimension, column may be a metric
ColumnCapabilities capabilities = getColumnCapabilities(dimension); ColumnCapabilities capabilities = getColumnCapabilities(dimension);
if (capabilities == null) { if (capabilities == null) {
return DimensionSelectorUtils.constantSelector(null, extractionFn); return DimensionSelector.constant(null, extractionFn);
} }
if (capabilities.getType().isNumeric()) { if (capabilities.getType().isNumeric()) {
return capabilities.getType().makeNumericWrappingDimensionSelector( return capabilities.getType().makeNumericWrappingDimensionSelector(
@ -91,7 +90,7 @@ class IncrementalIndexColumnSelectorFactory implements ColumnSelectorFactory
} }
// if we can't wrap the base column, just return a column of all nulls // if we can't wrap the base column, just return a column of all nulls
return DimensionSelectorUtils.constantSelector(null, extractionFn); return DimensionSelector.constant(null, extractionFn);
} else { } else {
final DimensionIndexer indexer = dimensionDesc.getIndexer(); final DimensionIndexer indexer = dimensionDesc.getIndexer();
return indexer.makeDimensionSelector(dimensionSpec, rowHolder, dimensionDesc); return indexer.makeDimensionSelector(dimensionSpec, rowHolder, dimensionDesc);

View File

@ -37,9 +37,7 @@ import org.apache.druid.segment.ColumnSelectorFactory;
import org.apache.druid.segment.ColumnValueSelector; import org.apache.druid.segment.ColumnValueSelector;
import org.apache.druid.segment.ConstantExprEvalSelector; import org.apache.druid.segment.ConstantExprEvalSelector;
import org.apache.druid.segment.DimensionSelector; import org.apache.druid.segment.DimensionSelector;
import org.apache.druid.segment.DimensionSelectorUtils;
import org.apache.druid.segment.NilColumnValueSelector; import org.apache.druid.segment.NilColumnValueSelector;
import org.apache.druid.segment.NullDimensionSelector;
import org.apache.druid.segment.column.ColumnCapabilities; import org.apache.druid.segment.column.ColumnCapabilities;
import org.apache.druid.segment.column.ColumnHolder; import org.apache.druid.segment.column.ColumnHolder;
import org.apache.druid.segment.column.ValueType; import org.apache.druid.segment.column.ValueType;
@ -195,10 +193,10 @@ public class ExpressionSelectors
if (baseSelector instanceof ConstantExprEvalSelector) { if (baseSelector instanceof ConstantExprEvalSelector) {
// Optimization for dimension selectors on constants. // Optimization for dimension selectors on constants.
return DimensionSelectorUtils.constantSelector(baseSelector.getObject().asString(), extractionFn); return DimensionSelector.constant(baseSelector.getObject().asString(), extractionFn);
} else if (baseSelector instanceof NilColumnValueSelector) { } else if (baseSelector instanceof NilColumnValueSelector) {
// Optimization for null dimension selector. // Optimization for null dimension selector.
return NullDimensionSelector.instance(); return DimensionSelector.constant(null);
} else if (extractionFn == null) { } else if (extractionFn == null) {
class DefaultExpressionDimensionSelector extends BaseSingleValueDimensionSelector class DefaultExpressionDimensionSelector extends BaseSingleValueDimensionSelector
{ {

View File

@ -28,13 +28,13 @@ import org.junit.Test;
public class ConstantDimensionSelectorTest public class ConstantDimensionSelectorTest
{ {
private final DimensionSelector NULL_SELECTOR = DimensionSelectorUtils.constantSelector(null); private final DimensionSelector NULL_SELECTOR = DimensionSelector.constant(null);
private final DimensionSelector CONST_SELECTOR = DimensionSelectorUtils.constantSelector("billy"); private final DimensionSelector CONST_SELECTOR = DimensionSelector.constant("billy");
private final DimensionSelector NULL_EXTRACTION_SELECTOR = DimensionSelectorUtils.constantSelector( private final DimensionSelector NULL_EXTRACTION_SELECTOR = DimensionSelector.constant(
null, null,
new StringFormatExtractionFn("billy") new StringFormatExtractionFn("billy")
); );
private final DimensionSelector CONST_EXTRACTION_SELECTOR = DimensionSelectorUtils.constantSelector( private final DimensionSelector CONST_EXTRACTION_SELECTOR = DimensionSelector.constant(
"billybilly", "billybilly",
new SubstringDimExtractionFn(0, 5) new SubstringDimExtractionFn(0, 5)
); );