@Override
 public Builder fieldDataSettings(Settings fieldDataSettings) {
   Settings settings =
       Settings.builder()
           .put(childJoinFieldType.fieldDataType().getSettings())
           .put(fieldDataSettings)
           .build();
   childJoinFieldType.setFieldDataType(
       new FieldDataType(childJoinFieldType.fieldDataType().getType(), settings));
   return this;
 }
  @Override
  public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
    if (!active()) {
      return builder;
    }
    boolean includeDefaults = params.paramAsBoolean("include_defaults", false);

    builder.startObject(CONTENT_TYPE);
    builder.field("type", parentType);
    if (includeDefaults || joinFieldHasCustomFieldDataSettings()) {
      builder.field("fielddata", (Map) childJoinFieldType.fieldDataType().getSettings().getAsMap());
    }
    builder.endObject();
    return builder;
  }
 @Override
 public IndexFieldData<AtomicNumericFieldData> build(
     Index index,
     @IndexSettings Settings indexSettings,
     MappedFieldType fieldType,
     IndexFieldDataCache cache,
     CircuitBreakerService breakerService,
     MapperService mapperService) {
   return new PackedArrayIndexFieldData(
       index,
       indexSettings,
       fieldType.names(),
       fieldType.fieldDataType(),
       cache,
       numericType,
       breakerService);
 }
 private boolean joinFieldHasCustomFieldDataSettings() {
   return childJoinFieldType != null
       && childJoinFieldType.fieldDataType() != null
       && childJoinFieldType.fieldDataType().equals(Defaults.JOIN_FIELD_TYPE.fieldDataType())
           == false;
 }
  @SuppressWarnings("unchecked")
  public <IFD extends IndexFieldData<?>> IFD getForField(MappedFieldType fieldType) {
    final Names fieldNames = fieldType.names();
    final FieldDataType type = fieldType.fieldDataType();
    if (type == null) {
      throw new IllegalArgumentException(
          "found no fielddata type for field [" + fieldNames.fullName() + "]");
    }
    final boolean docValues = fieldType.hasDocValues();
    IndexFieldData.Builder builder = null;
    String format = type.getFormat(indexSettings);
    if (format != null && FieldDataType.DOC_VALUES_FORMAT_VALUE.equals(format) && !docValues) {
      logger.warn(
          "field ["
              + fieldNames.fullName()
              + "] has no doc values, will use default field data format");
      format = null;
    }
    if (format != null) {
      builder = buildersByTypeAndFormat.get(Tuple.tuple(type.getType(), format));
      if (builder == null) {
        logger.warn(
            "failed to find format ["
                + format
                + "] for field ["
                + fieldNames.fullName()
                + "], will use default");
      }
    }
    if (builder == null && docValues) {
      builder = docValuesBuildersByType.get(type.getType());
    }
    if (builder == null) {
      builder = buildersByType.get(type.getType());
    }
    if (builder == null) {
      throw new IllegalArgumentException(
          "failed to find field data builder for field "
              + fieldNames.fullName()
              + ", and type "
              + type.getType());
    }

    IndexFieldDataCache cache;
    synchronized (this) {
      cache = fieldDataCaches.get(fieldNames.indexName());
      if (cache == null) {
        //  we default to node level cache, which in turn defaults to be unbounded
        // this means changing the node level settings is simple, just set the bounds there
        String cacheType =
            type.getSettings()
                .get("cache", indexSettings.get(FIELDDATA_CACHE_KEY, FIELDDATA_CACHE_VALUE_NODE));
        if (FIELDDATA_CACHE_VALUE_NODE.equals(cacheType)) {
          cache = indicesFieldDataCache.buildIndexFieldDataCache(listener, index, fieldNames, type);
        } else if ("none".equals(cacheType)) {
          cache = new IndexFieldDataCache.None();
        } else {
          throw new IllegalArgumentException(
              "cache type not supported ["
                  + cacheType
                  + "] for field ["
                  + fieldNames.fullName()
                  + "]");
        }
        fieldDataCaches.put(fieldNames.indexName(), cache);
      }
    }

    return (IFD)
        builder.build(index, indexSettings, fieldType, cache, circuitBreakerService, mapperService);
  }