Skip to content

Commit 61175bf

Browse files
Fix TextFieldMapper Retaining a Reference to its Builder (#77251) (#77268)
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 3bd96b8 commit 61175bf

File tree

5 files changed

+88
-46
lines changed

5 files changed

+88
-46
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
@@ -87,7 +87,9 @@ public static class Builder extends FieldMapper.Builder {
8787

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

9395
@Override

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

Lines changed: 66 additions & 37 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<Float> boost = Parameter.boostParam();
255250
private final Parameter<Map<String, String>> meta = Parameter.metaParam();
@@ -263,7 +258,11 @@ public Builder(String name, IndexAnalyzers indexAnalyzers) {
263258
public Builder(String name, Version indexCreatedVersion, IndexAnalyzers indexAnalyzers) {
264259
super(name);
265260
this.indexCreatedVersion = indexCreatedVersion;
266-
this.analyzers = new TextParams.Analyzers(indexAnalyzers, m -> builder(m).analyzers);
261+
this.analyzers = new TextParams.Analyzers(
262+
indexAnalyzers,
263+
m -> ((TextFieldMapper) m).indexAnalyzer,
264+
m -> (((TextFieldMapper) m).positionIncrementGap)
265+
);
267266
}
268267

269268
public Builder index(boolean index) {
@@ -825,7 +824,21 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, S
825824

826825
}
827826

828-
private final Builder builder;
827+
private final Version indexCreatedVersion;
828+
private final boolean index;
829+
private final boolean store;
830+
private final String indexOptions;
831+
private final boolean norms;
832+
private final String termVectors;
833+
private final SimilarityProvider similarity;
834+
private final NamedAnalyzer indexAnalyzer;
835+
private final IndexAnalyzers indexAnalyzers;
836+
private final int positionIncrementGap;
837+
private final boolean eagerGlobalOrdinals;
838+
private final PrefixConfig indexPrefixes;
839+
private final FielddataFrequencyFilter freqFilter;
840+
private final boolean fieldData;
841+
private final boolean indexPhrases;
829842
private final FieldType fieldType;
830843
private final SubFieldInfo prefixFieldInfo;
831844
private final SubFieldInfo phraseFieldInfo;
@@ -845,12 +858,26 @@ protected TextFieldMapper(String simpleName, FieldType fieldType,
845858
this.fieldType = fieldType;
846859
this.prefixFieldInfo = prefixFieldInfo;
847860
this.phraseFieldInfo = phraseFieldInfo;
848-
this.builder = builder;
861+
this.indexCreatedVersion = builder.indexCreatedVersion;
862+
this.indexAnalyzer = builder.analyzers.getIndexAnalyzer();
863+
this.indexAnalyzers = builder.analyzers.indexAnalyzers;
864+
this.positionIncrementGap = builder.analyzers.positionIncrementGap.getValue();
865+
this.index = builder.index.getValue();
866+
this.store = builder.store.getValue();
867+
this.similarity = builder.similarity.getValue();
868+
this.indexOptions = builder.indexOptions.getValue();
869+
this.norms = builder.norms.getValue();
870+
this.termVectors = builder.termVectors.getValue();
871+
this.eagerGlobalOrdinals = builder.eagerGlobalOrdinals.getValue();
872+
this.indexPrefixes = builder.indexPrefixes.getValue();
873+
this.freqFilter = builder.freqFilter.getValue();
874+
this.fieldData = builder.fieldData.get();
875+
this.indexPhrases = builder.indexPhrases.getValue();
849876
}
850877

851878
@Override
852879
public FieldMapper.Builder getMergeBuilder() {
853-
return new Builder(simpleName(), builder.indexCreatedVersion, builder.analyzers.indexAnalyzers).init(this);
880+
return new Builder(simpleName(), indexCreatedVersion, indexAnalyzers).init(this);
854881
}
855882

856883
@Override
@@ -1008,24 +1035,26 @@ protected void doXContentBody(XContentBuilder builder, Params params) throws IOE
10081035
// this is a pain, but we have to do this to maintain BWC
10091036
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
10101037
builder.field("type", contentType());
1011-
this.builder.boost.toXContent(builder, includeDefaults);
1012-
this.builder.index.toXContent(builder, includeDefaults);
1013-
this.builder.store.toXContent(builder, includeDefaults);
1038+
1039+
final Builder b = (Builder) getMergeBuilder();
1040+
b.boost.toXContent(builder, includeDefaults);
1041+
b.index.toXContent(builder, includeDefaults);
1042+
b.store.toXContent(builder, includeDefaults);
10141043
this.multiFields.toXContent(builder, params);
10151044
this.copyTo.toXContent(builder, params);
1016-
this.builder.meta.toXContent(builder, includeDefaults);
1017-
this.builder.indexOptions.toXContent(builder, includeDefaults);
1018-
this.builder.termVectors.toXContent(builder, includeDefaults);
1019-
this.builder.norms.toXContent(builder, includeDefaults);
1020-
this.builder.analyzers.indexAnalyzer.toXContent(builder, includeDefaults);
1021-
this.builder.analyzers.searchAnalyzer.toXContent(builder, includeDefaults);
1022-
this.builder.analyzers.searchQuoteAnalyzer.toXContent(builder, includeDefaults);
1023-
this.builder.similarity.toXContent(builder, includeDefaults);
1024-
this.builder.eagerGlobalOrdinals.toXContent(builder, includeDefaults);
1025-
this.builder.analyzers.positionIncrementGap.toXContent(builder, includeDefaults);
1026-
this.builder.fieldData.toXContent(builder, includeDefaults);
1027-
this.builder.freqFilter.toXContent(builder, includeDefaults);
1028-
this.builder.indexPrefixes.toXContent(builder, includeDefaults);
1029-
this.builder.indexPhrases.toXContent(builder, includeDefaults);
1045+
b.meta.toXContent(builder, includeDefaults);
1046+
b.indexOptions.toXContent(builder, includeDefaults);
1047+
b.termVectors.toXContent(builder, includeDefaults);
1048+
b.norms.toXContent(builder, includeDefaults);
1049+
b.analyzers.indexAnalyzer.toXContent(builder, includeDefaults);
1050+
b.analyzers.searchAnalyzer.toXContent(builder, includeDefaults);
1051+
b.analyzers.searchQuoteAnalyzer.toXContent(builder, includeDefaults);
1052+
b.similarity.toXContent(builder, includeDefaults);
1053+
b.eagerGlobalOrdinals.toXContent(builder, includeDefaults);
1054+
b.analyzers.positionIncrementGap.toXContent(builder, includeDefaults);
1055+
b.fieldData.toXContent(builder, includeDefaults);
1056+
b.freqFilter.toXContent(builder, includeDefaults);
1057+
b.indexPrefixes.toXContent(builder, includeDefaults);
1058+
b.indexPhrases.toXContent(builder, includeDefaults);
10301059
}
10311060
}

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)