Skip to content

Commit 096b8cc

Browse files
Fix TextFieldMapper Retaining a Reference to its Builder (#77251)
Fixes the text field mapper and the analyzers class that also retained parameter references that go really heavy. Makes `TextFieldMapper` take hundreds of bytes compared to multiple kb per instance. closes #73845
1 parent c7130eb commit 096b8cc

File tree

5 files changed

+86
-45
lines changed

5 files changed

+86
-45
lines changed

modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/MatchOnlyTextFieldMapper.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ public Builder(String name, IndexAnalyzers indexAnalyzers) {
8686
public Builder(String name, Version indexCreatedVersion, IndexAnalyzers indexAnalyzers) {
8787
super(name);
8888
this.indexCreatedVersion = indexCreatedVersion;
89-
this.analyzers = new TextParams.Analyzers(indexAnalyzers, m -> ((MatchOnlyTextFieldMapper) m).analyzers);
89+
this.analyzers = new TextParams.Analyzers(indexAnalyzers,
90+
m -> ((MatchOnlyTextFieldMapper) m).indexAnalyzer,
91+
m -> ((MatchOnlyTextFieldMapper) m).positionIncrementGap);
9092
}
9193

9294
@Override
@@ -268,7 +270,9 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, S
268270
}
269271

270272
private final Version indexCreatedVersion;
271-
private final TextParams.Analyzers analyzers;
273+
private final IndexAnalyzers indexAnalyzers;
274+
private final NamedAnalyzer indexAnalyzer;
275+
private final int positionIncrementGap;
272276
private final FieldType fieldType;
273277

274278
private MatchOnlyTextFieldMapper(
@@ -284,12 +288,14 @@ private MatchOnlyTextFieldMapper(
284288
assert mappedFieldType.hasDocValues() == false;
285289
this.fieldType = fieldType;
286290
this.indexCreatedVersion = builder.indexCreatedVersion;
287-
this.analyzers = builder.analyzers;
291+
this.indexAnalyzers = builder.analyzers.indexAnalyzers;
292+
this.indexAnalyzer = builder.analyzers.getIndexAnalyzer();
293+
this.positionIncrementGap = builder.analyzers.positionIncrementGap.getValue();
288294
}
289295

290296
@Override
291297
public FieldMapper.Builder getMergeBuilder() {
292-
return new Builder(simpleName(), indexCreatedVersion, analyzers.indexAnalyzers).init(this);
298+
return new Builder(simpleName(), indexCreatedVersion, indexAnalyzers).init(this);
293299
}
294300

295301
@Override

modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/SearchAsYouTypeFieldMapper.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,11 @@ public static class Builder extends FieldMapper.Builder {
125125

126126
public Builder(String name, IndexAnalyzers indexAnalyzers) {
127127
super(name);
128-
this.analyzers = new TextParams.Analyzers(indexAnalyzers, m -> builder(m).analyzers);
128+
this.analyzers = new TextParams.Analyzers(
129+
indexAnalyzers,
130+
m -> builder(m).analyzers.getIndexAnalyzer(),
131+
m -> builder(m).analyzers.positionIncrementGap.getValue()
132+
);
129133
}
130134

131135
@Override

plugins/mapper-annotated-text/src/main/java/org/elasticsearch/index/mapper/annotatedtext/AnnotatedTextFieldMapper.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ public static class Builder extends FieldMapper.Builder {
8686

8787
public Builder(String name, IndexAnalyzers indexAnalyzers) {
8888
super(name);
89-
this.analyzers = new TextParams.Analyzers(indexAnalyzers, m -> builder(m).analyzers);
89+
this.analyzers = new TextParams.Analyzers(indexAnalyzers,
90+
m -> builder(m).analyzers.getIndexAnalyzer(),
91+
m -> builder(m).analyzers.positionIncrementGap.getValue());
9092
}
9193

9294
@Override

server/src/main/java/org/elasticsearch/index/mapper/TextFieldMapper.java

Lines changed: 64 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,6 @@ public static class Defaults {
106106
public static final int POSITION_INCREMENT_GAP = 100;
107107
}
108108

109-
private static Builder builder(FieldMapper in) {
110-
return ((TextFieldMapper) in).builder;
111-
}
112-
113109
private static final class PrefixConfig implements ToXContent {
114110
final int minChars;
115111
final int maxChars;
@@ -229,27 +225,26 @@ public static class Builder extends FieldMapper.Builder {
229225

230226
private final Version indexCreatedVersion;
231227

232-
private final Parameter<Boolean> index = Parameter.indexParam(m -> builder(m).index.getValue(), true);
233-
private final Parameter<Boolean> store = Parameter.storeParam(m -> builder(m).store.getValue(), false);
228+
private final Parameter<Boolean> index = Parameter.indexParam(m -> ((TextFieldMapper) m).index, true);
229+
private final Parameter<Boolean> store = Parameter.storeParam(m -> ((TextFieldMapper) m).store, false);
234230

235-
final Parameter<SimilarityProvider> similarity
236-
= TextParams.similarity(m -> builder(m).similarity.getValue());
231+
final Parameter<SimilarityProvider> similarity = TextParams.similarity(m -> ((TextFieldMapper) m).similarity);
237232

238-
final Parameter<String> indexOptions = TextParams.indexOptions(m -> builder(m).indexOptions.getValue());
239-
final Parameter<Boolean> norms = TextParams.norms(true, m -> builder(m).norms.getValue());
240-
final Parameter<String> termVectors = TextParams.termVectors(m -> builder(m).termVectors.getValue());
233+
final Parameter<String> indexOptions = TextParams.indexOptions(m -> ((TextFieldMapper) m).indexOptions);
234+
final Parameter<Boolean> norms = TextParams.norms(true, m -> ((TextFieldMapper) m).norms);
235+
final Parameter<String> termVectors = TextParams.termVectors(m -> ((TextFieldMapper) m).termVectors);
241236

242237
final Parameter<Boolean> fieldData
243-
= Parameter.boolParam("fielddata", true, m -> builder(m).fieldData.getValue(), false);
238+
= Parameter.boolParam("fielddata", true, m -> ((TextFieldMapper) m).fieldData, false);
244239
final Parameter<FielddataFrequencyFilter> freqFilter = new Parameter<>("fielddata_frequency_filter", true,
245-
() -> DEFAULT_FILTER, TextFieldMapper::parseFrequencyFilter, m -> builder(m).freqFilter.getValue());
240+
() -> DEFAULT_FILTER, TextFieldMapper::parseFrequencyFilter, m -> ((TextFieldMapper) m).freqFilter);
246241
final Parameter<Boolean> eagerGlobalOrdinals
247-
= Parameter.boolParam("eager_global_ordinals", true, m -> builder(m).eagerGlobalOrdinals.getValue(), false);
242+
= Parameter.boolParam("eager_global_ordinals", true, m -> ((TextFieldMapper) m).eagerGlobalOrdinals, false);
248243

249244
final Parameter<Boolean> indexPhrases
250-
= Parameter.boolParam("index_phrases", false, m -> builder(m).indexPhrases.getValue(), false);
245+
= Parameter.boolParam("index_phrases", false, m -> ((TextFieldMapper) m).indexPhrases, false);
251246
final Parameter<PrefixConfig> indexPrefixes = new Parameter<>("index_prefixes", false,
252-
() -> null, TextFieldMapper::parsePrefixConfig, m -> builder(m).indexPrefixes.getValue()).acceptsNull();
247+
() -> null, TextFieldMapper::parsePrefixConfig, m -> ((TextFieldMapper) m).indexPrefixes).acceptsNull();
253248

254249
private final Parameter<Map<String, String>> meta = Parameter.metaParam();
255250

@@ -262,7 +257,11 @@ public Builder(String name, IndexAnalyzers indexAnalyzers) {
262257
public Builder(String name, Version indexCreatedVersion, IndexAnalyzers indexAnalyzers) {
263258
super(name);
264259
this.indexCreatedVersion = indexCreatedVersion;
265-
this.analyzers = new TextParams.Analyzers(indexAnalyzers, m -> builder(m).analyzers);
260+
this.analyzers = new TextParams.Analyzers(
261+
indexAnalyzers,
262+
m -> ((TextFieldMapper) m).indexAnalyzer,
263+
m -> (((TextFieldMapper) m).positionIncrementGap)
264+
);
266265
}
267266

268267
public Builder index(boolean index) {
@@ -820,7 +819,21 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, S
820819

821820
}
822821

823-
private final Builder builder;
822+
private final Version indexCreatedVersion;
823+
private final boolean index;
824+
private final boolean store;
825+
private final String indexOptions;
826+
private final boolean norms;
827+
private final String termVectors;
828+
private final SimilarityProvider similarity;
829+
private final NamedAnalyzer indexAnalyzer;
830+
private final IndexAnalyzers indexAnalyzers;
831+
private final int positionIncrementGap;
832+
private final boolean eagerGlobalOrdinals;
833+
private final PrefixConfig indexPrefixes;
834+
private final FielddataFrequencyFilter freqFilter;
835+
private final boolean fieldData;
836+
private final boolean indexPhrases;
824837
private final FieldType fieldType;
825838
private final SubFieldInfo prefixFieldInfo;
826839
private final SubFieldInfo phraseFieldInfo;
@@ -840,12 +853,26 @@ protected TextFieldMapper(String simpleName, FieldType fieldType,
840853
this.fieldType = fieldType;
841854
this.prefixFieldInfo = prefixFieldInfo;
842855
this.phraseFieldInfo = phraseFieldInfo;
843-
this.builder = builder;
856+
this.indexCreatedVersion = builder.indexCreatedVersion;
857+
this.indexAnalyzer = builder.analyzers.getIndexAnalyzer();
858+
this.indexAnalyzers = builder.analyzers.indexAnalyzers;
859+
this.positionIncrementGap = builder.analyzers.positionIncrementGap.getValue();
860+
this.index = builder.index.getValue();
861+
this.store = builder.store.getValue();
862+
this.similarity = builder.similarity.getValue();
863+
this.indexOptions = builder.indexOptions.getValue();
864+
this.norms = builder.norms.getValue();
865+
this.termVectors = builder.termVectors.getValue();
866+
this.eagerGlobalOrdinals = builder.eagerGlobalOrdinals.getValue();
867+
this.indexPrefixes = builder.indexPrefixes.getValue();
868+
this.freqFilter = builder.freqFilter.getValue();
869+
this.fieldData = builder.fieldData.get();
870+
this.indexPhrases = builder.indexPhrases.getValue();
844871
}
845872

846873
@Override
847874
public FieldMapper.Builder getMergeBuilder() {
848-
return new Builder(simpleName(), builder.indexCreatedVersion, builder.analyzers.indexAnalyzers).init(this);
875+
return new Builder(simpleName(), indexCreatedVersion, indexAnalyzers).init(this);
849876
}
850877

851878
@Override
@@ -1003,23 +1030,24 @@ protected void doXContentBody(XContentBuilder builder, Params params) throws IOE
10031030
// this is a pain, but we have to do this to maintain BWC
10041031
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
10051032
builder.field("type", contentType());
1006-
this.builder.index.toXContent(builder, includeDefaults);
1007-
this.builder.store.toXContent(builder, includeDefaults);
1033+
final Builder b = (Builder) getMergeBuilder();
1034+
b.index.toXContent(builder, includeDefaults);
1035+
b.store.toXContent(builder, includeDefaults);
10081036
this.multiFields.toXContent(builder, params);
10091037
this.copyTo.toXContent(builder, params);
1010-
this.builder.meta.toXContent(builder, includeDefaults);
1011-
this.builder.indexOptions.toXContent(builder, includeDefaults);
1012-
this.builder.termVectors.toXContent(builder, includeDefaults);
1013-
this.builder.norms.toXContent(builder, includeDefaults);
1014-
this.builder.analyzers.indexAnalyzer.toXContent(builder, includeDefaults);
1015-
this.builder.analyzers.searchAnalyzer.toXContent(builder, includeDefaults);
1016-
this.builder.analyzers.searchQuoteAnalyzer.toXContent(builder, includeDefaults);
1017-
this.builder.similarity.toXContent(builder, includeDefaults);
1018-
this.builder.eagerGlobalOrdinals.toXContent(builder, includeDefaults);
1019-
this.builder.analyzers.positionIncrementGap.toXContent(builder, includeDefaults);
1020-
this.builder.fieldData.toXContent(builder, includeDefaults);
1021-
this.builder.freqFilter.toXContent(builder, includeDefaults);
1022-
this.builder.indexPrefixes.toXContent(builder, includeDefaults);
1023-
this.builder.indexPhrases.toXContent(builder, includeDefaults);
1038+
b.meta.toXContent(builder, includeDefaults);
1039+
b.indexOptions.toXContent(builder, includeDefaults);
1040+
b.termVectors.toXContent(builder, includeDefaults);
1041+
b.norms.toXContent(builder, includeDefaults);
1042+
b.analyzers.indexAnalyzer.toXContent(builder, includeDefaults);
1043+
b.analyzers.searchAnalyzer.toXContent(builder, includeDefaults);
1044+
b.analyzers.searchQuoteAnalyzer.toXContent(builder, includeDefaults);
1045+
b.similarity.toXContent(builder, includeDefaults);
1046+
b.eagerGlobalOrdinals.toXContent(builder, includeDefaults);
1047+
b.analyzers.positionIncrementGap.toXContent(builder, includeDefaults);
1048+
b.fieldData.toXContent(builder, includeDefaults);
1049+
b.freqFilter.toXContent(builder, includeDefaults);
1050+
b.indexPrefixes.toXContent(builder, includeDefaults);
1051+
b.indexPhrases.toXContent(builder, includeDefaults);
10241052
}
10251053
}

server/src/main/java/org/elasticsearch/index/mapper/TextParams.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ public static final class Analyzers {
3636
public final IndexAnalyzers indexAnalyzers;
3737

3838
public Analyzers(IndexAnalyzers indexAnalyzers,
39-
Function<FieldMapper, Analyzers> analyzerInitFunction) {
39+
Function<FieldMapper, NamedAnalyzer> analyzerInitFunction,
40+
Function<FieldMapper, Integer> positionGapInitFunction) {
4041
this.indexAnalyzer = Parameter.analyzerParam("analyzer", false,
41-
m -> analyzerInitFunction.apply(m).indexAnalyzer.get(), indexAnalyzers::getDefaultIndexAnalyzer)
42+
analyzerInitFunction, indexAnalyzers::getDefaultIndexAnalyzer)
4243
.setSerializerCheck((id, ic, a) -> id || ic ||
4344
Objects.equals(a, getSearchAnalyzer()) == false || Objects.equals(a, getSearchQuoteAnalyzer()) == false)
4445
.addValidator(a -> a.checkAllowedInMode(AnalysisMode.INDEX_TIME));
@@ -68,7 +69,7 @@ public Analyzers(IndexAnalyzers indexAnalyzers,
6869
})
6970
.addValidator(a -> a.checkAllowedInMode(AnalysisMode.SEARCH_TIME));
7071
this.positionIncrementGap = Parameter.intParam("position_increment_gap", false,
71-
m -> analyzerInitFunction.apply(m).positionIncrementGap.get(), TextFieldMapper.Defaults.POSITION_INCREMENT_GAP)
72+
positionGapInitFunction, TextFieldMapper.Defaults.POSITION_INCREMENT_GAP)
7273
.addValidator(v -> {
7374
if (v < 0) {
7475
throw new MapperParsingException("[position_increment_gap] must be positive, got [" + v + "]");

0 commit comments

Comments
 (0)