public DimensionSelector makeDimensionSelector()

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();
  }