in processing/src/main/java/org/apache/druid/segment/nested/NestedFieldDictionaryEncodedColumn.java [288:526]
public DimensionSelector makeDimensionSelector(
ReadableOffset offset,
@Nullable ExtractionFn extractionFn
)
{
// copy everywhere all the time
class StringDimensionSelector extends AbstractDimensionSelector
implements SingleValueHistoricalDimensionSelector, IdLookup
{
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 float getFloat()
{
final int localId = getRowValue();
final int globalId = dictionary.get(localId);
if (globalId == 0) {
// zero
return 0f;
} else if (globalId < adjustLongId) {
// try to convert string to float
Float f = Floats.tryParse(StringUtils.fromUtf8(globalDictionary.get(globalId)));
return f == null ? 0f : f;
} else if (globalId < adjustDoubleId) {
return globalLongDictionary.get(globalId - adjustLongId).floatValue();
} else {
return globalDoubleDictionary.get(globalId - adjustDoubleId).floatValue();
}
}
@Override
public double getDouble()
{
final int localId = getRowValue();
final int globalId = dictionary.get(localId);
if (globalId == 0) {
// zero
return 0.0;
} else if (globalId < adjustLongId) {
// try to convert string to double
Double d = Doubles.tryParse(StringUtils.fromUtf8(globalDictionary.get(globalId)));
return d == null ? 0.0 : d;
} else if (globalId < adjustDoubleId) {
return globalLongDictionary.get(globalId - adjustLongId).doubleValue();
} else {
return globalDoubleDictionary.get(globalId - adjustDoubleId);
}
}
@Override
public long getLong()
{
final int localId = getRowValue();
final int globalId = dictionary.get(localId);
if (globalId == 0) {
// zero
return 0L;
} else if (globalId < adjustLongId) {
// try to convert string to long
Long l = GuavaUtils.tryParseLong(StringUtils.fromUtf8(globalDictionary.get(globalId)));
return l == null ? 0L : l;
} else if (globalId < adjustDoubleId) {
return globalLongDictionary.get(globalId - adjustLongId);
} else {
return globalDoubleDictionary.get(globalId - adjustDoubleId).longValue();
}
}
@Override
public boolean isNull()
{
if (dictionary.get(getRowValue()) == 0) {
return true;
}
return DimensionHandlerUtils.isNumericNull(getObject());
}
@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(final @Nullable String value)
{
if (extractionFn == null) {
final int valueId = lookupId(value);
if (valueId >= 0) {
return new ValueMatcher()
{
@Override
public boolean matches(boolean includeUnknown)
{
final int rowId = getRowValue();
return (includeUnknown && rowId == 0) || rowId == valueId;
}
@Override
public void inspectRuntimeShape(RuntimeShapeInspector inspector)
{
inspector.visit("column", NestedFieldDictionaryEncodedColumn.this);
}
};
} else {
return new ValueMatcher()
{
@Override
public boolean matches(boolean includeUnknown)
{
return includeUnknown && getRowValue() == 0;
}
@Override
public void inspectRuntimeShape(RuntimeShapeInspector inspector)
{
inspector.visit("column", NestedFieldDictionaryEncodedColumn.this);
}
};
}
} else {
// Employ caching BitSet optimization
return makeValueMatcher(StringPredicateDruidPredicateFactory.equalTo(value));
}
}
@Override
public ValueMatcher makeValueMatcher(final DruidPredicateFactory predicateFactory)
{
final BitSet checkedIds = new BitSet(getCardinality());
final BitSet matchingIds = new BitSet(getCardinality());
final DruidObjectPredicate<String> predicate = predicateFactory.makeStringPredicate();
// Lazy matcher; only check an id if matches() is called.
return new ValueMatcher()
{
@Override
public boolean matches(boolean includeUnknown)
{
final int id = getRowValue();
if (checkedIds.get(id)) {
return matchingIds.get(id);
} else {
final String rowVal = lookupName(id);
final boolean matches = predicate.apply(rowVal).matches(includeUnknown);
checkedIds.set(id);
if (matches) {
matchingIds.set(id);
}
return matches;
}
}
@Override
public void inspectRuntimeShape(RuntimeShapeInspector inspector)
{
inspector.visit("column", NestedFieldDictionaryEncodedColumn.this);
}
};
}
@Override
public Object getObject()
{
return NestedFieldDictionaryEncodedColumn.this.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);
}
@Override
public int getValueCardinality()
{
return getCardinality();
}
@Override
public String lookupName(int id)
{
final String value = NestedFieldDictionaryEncodedColumn.this.lookupName(id);
return extractionFn == null ? value : extractionFn.apply(value);
}
@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) {
return NestedFieldDictionaryEncodedColumn.this.lookupId(name);
}
throw new UnsupportedOperationException("cannot perform lookup when applying an extraction function");
}
}
return new StringDimensionSelector();
}