Skip to content

Commit 0d23a0b

Browse files
Speed up toXContent Collection Serialization in some Spots (#78742) (#78755)
Found this when benchmarking large cluster states. When serializing collections we'd mostly not take any advantage of what we know about the collection contents (like we do in `StreamOutput`). This PR adds a couple of helpers to the x-content-builder similar to what we have on `StreamOutput` to allow for faster serializing by avoiding the writer lookup and some self-reference checks.
1 parent 0a35034 commit 0d23a0b

File tree

50 files changed

+151
-74
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+151
-74
lines changed

client/rest-high-level/src/main/java/org/elasticsearch/client/GeoIpStatsResponse.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ public Map<String, DatabaseInfo> getDatabases() {
156156
@Override
157157
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
158158
builder.startObject();
159-
builder.field("files_in_temp", filesInTemp);
159+
builder.stringListField("files_in_temp", filesInTemp);
160160
builder.field("databases", databases.entrySet().stream()
161161
.sorted(Map.Entry.comparingByKey())
162162
.map(Map.Entry::getValue)

client/rest-high-level/src/main/java/org/elasticsearch/client/ccr/PutAutoFollowPatternRequest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@ public void setFollowIndexNamePattern(String followIndexNamePattern) {
7474
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
7575
builder.startObject();
7676
builder.field(PutFollowRequest.REMOTE_CLUSTER_FIELD.getPreferredName(), remoteCluster);
77-
builder.field(LEADER_PATTERNS_FIELD.getPreferredName(), leaderIndexPatterns);
77+
builder.stringListField(LEADER_PATTERNS_FIELD.getPreferredName(), leaderIndexPatterns);
7878
if (leaderIndexExclusionPatterns.isEmpty() == false) {
79-
builder.field(LEADER_EXCLUSION_PATTERNS_FIELD.getPreferredName(), leaderIndexExclusionPatterns);
79+
builder.stringListField(LEADER_EXCLUSION_PATTERNS_FIELD.getPreferredName(), leaderIndexExclusionPatterns);
8080
}
8181
if (followIndexNamePattern != null) {
8282
builder.field(FOLLOW_PATTERN_FIELD.getPreferredName(), followIndexNamePattern);

client/rest-high-level/src/main/java/org/elasticsearch/client/enrich/PutPolicyRequest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,12 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
9696
{
9797
builder.startObject(type);
9898
{
99-
builder.field(NamedPolicy.INDICES_FIELD.getPreferredName(), indices);
99+
builder.stringListField(NamedPolicy.INDICES_FIELD.getPreferredName(), indices);
100100
if (query != null) {
101101
builder.field(NamedPolicy.QUERY_FIELD.getPreferredName(), asMap(query, XContentType.JSON));
102102
}
103103
builder.field(NamedPolicy.MATCH_FIELD_FIELD.getPreferredName(), matchField);
104-
builder.field(NamedPolicy.ENRICH_FIELDS_FIELD.getPreferredName(), enrichFields);
104+
builder.stringListField(NamedPolicy.ENRICH_FIELDS_FIELD.getPreferredName(), enrichFields);
105105
}
106106
builder.endObject();
107107
}

client/rest-high-level/src/main/java/org/elasticsearch/client/indices/PutIndexTemplateRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
419419
if (template != null) {
420420
builder.field("template", template);
421421
} else {
422-
builder.field("index_patterns", indexPatterns);
422+
builder.stringListField("index_patterns", indexPatterns);
423423
}
424424

425425
builder.field("order", order);

client/rest-high-level/src/main/java/org/elasticsearch/client/ml/EvaluateDataFrameRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public Optional<ValidationException> validate() {
118118
@Override
119119
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
120120
builder.startObject();
121-
builder.array(INDEX.getPreferredName(), indices.toArray());
121+
builder.stringListField(INDEX.getPreferredName(), indices);
122122
if (queryConfig != null) {
123123
builder.field(QUERY.getPreferredName(), queryConfig.getQuery());
124124
}

client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetDatafeedRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
139139
builder.startObject();
140140

141141
if (datafeedIds.isEmpty() == false) {
142-
builder.field(DATAFEED_IDS.getPreferredName(), datafeedIds);
142+
builder.stringListField(DATAFEED_IDS.getPreferredName(), datafeedIds);
143143
}
144144

145145
if (allowNoMatch != null) {

client/rest-high-level/src/main/java/org/elasticsearch/client/ml/GetJobRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
139139
builder.startObject();
140140

141141
if (jobIds.isEmpty() == false) {
142-
builder.field(JOB_IDS.getPreferredName(), jobIds);
142+
builder.stringListField(JOB_IDS.getPreferredName(), jobIds);
143143
}
144144

145145
if (allowNoMatch != null) {

client/rest-high-level/src/main/java/org/elasticsearch/client/ml/UpdateFilterRequest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
103103
builder.field(MlFilter.DESCRIPTION.getPreferredName(), description);
104104
}
105105
if (addItems != null) {
106-
builder.field(ADD_ITEMS.getPreferredName(), addItems);
106+
builder.stringListField(ADD_ITEMS.getPreferredName(), addItems);
107107
}
108108
if (removeItems != null) {
109-
builder.field(REMOVE_ITEMS.getPreferredName(), removeItems);
109+
builder.stringListField(REMOVE_ITEMS.getPreferredName(), removeItems);
110110
}
111111
builder.endObject();
112112
return builder;

client/rest-high-level/src/main/java/org/elasticsearch/client/ml/calendars/Calendar.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public String getDescription() {
7575
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
7676
builder.startObject();
7777
builder.field(ID.getPreferredName(), id);
78-
builder.field(JOB_IDS.getPreferredName(), jobIds);
78+
builder.stringListField(JOB_IDS.getPreferredName(), jobIds);
7979
if (description != null) {
8080
builder.field(DESCRIPTION.getPreferredName(), description);
8181
}

libs/x-content/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
import java.util.Arrays;
2525
import java.util.Base64;
2626
import java.util.Calendar;
27+
import java.util.Collection;
2728
import java.util.Collections;
2829
import java.util.Date;
30+
import java.util.EnumSet;
2931
import java.util.GregorianCalendar;
3032
import java.util.HashMap;
3133
import java.util.IdentityHashMap;
@@ -869,6 +871,58 @@ private XContentBuilder value(ToXContent value, ToXContent.Params params) throws
869871
// Maps & Iterable
870872
//////////////////////////////////
871873

874+
public XContentBuilder stringListField(String name, Collection<String> values) throws IOException {
875+
field(name);
876+
if (values == null) {
877+
return nullValue();
878+
}
879+
startArray();
880+
for (String value : values) {
881+
value(value);
882+
}
883+
endArray();
884+
return this;
885+
}
886+
887+
public XContentBuilder xContentList(String name, Collection<? extends ToXContent> values) throws IOException {
888+
field(name);
889+
if (values == null) {
890+
return nullValue();
891+
}
892+
startArray();
893+
for (ToXContent value : values) {
894+
value(value);
895+
}
896+
endArray();
897+
return this;
898+
}
899+
900+
public XContentBuilder xContentList(String name, ToXContent... values) throws IOException {
901+
field(name);
902+
if (values == null) {
903+
return nullValue();
904+
}
905+
startArray();
906+
for (ToXContent value : values) {
907+
value(value);
908+
}
909+
endArray();
910+
return this;
911+
}
912+
913+
public XContentBuilder enumSet(String name, EnumSet<?> values) throws IOException {
914+
field(name);
915+
if (values == null) {
916+
return nullValue();
917+
}
918+
startArray();
919+
for (Enum<?> value : values) {
920+
value(value);
921+
}
922+
endArray();
923+
return this;
924+
}
925+
872926
public XContentBuilder field(String name, Map<String, Object> values) throws IOException {
873927
return field(name).map(values);
874928
}
@@ -877,6 +931,32 @@ public XContentBuilder map(Map<String, ?> values) throws IOException {
877931
return map(values, true, true);
878932
}
879933

934+
public XContentBuilder stringStringMap(String name, Map<String, String> values) throws IOException {
935+
field(name);
936+
if (values == null) {
937+
return nullValue();
938+
}
939+
startObject();
940+
for (Map.Entry<String, String> value : values.entrySet()) {
941+
field(value.getKey());
942+
value(value.getValue());
943+
}
944+
return endObject();
945+
}
946+
947+
public XContentBuilder xContentValuesMap(String name, Map<String, ? extends ToXContent> values) throws IOException {
948+
field(name);
949+
if (values == null) {
950+
return nullValue();
951+
}
952+
startObject();
953+
for (Map.Entry<String, ? extends ToXContent> value : values.entrySet()) {
954+
field(value.getKey());
955+
value(value.getValue());
956+
}
957+
return endObject();
958+
}
959+
880960
/** writes a map without the start object and end object headers */
881961
public XContentBuilder mapContents(Map<String, ?> values) throws IOException {
882962
return map(values, true, false);
@@ -974,6 +1054,11 @@ public XContentBuilder percentageField(String rawFieldName, String readableField
9741054
return this;
9751055
}
9761056

1057+
public XContentBuilder field(String name, Enum<?> value) throws IOException {
1058+
field(name);
1059+
return value(value == null ? null : value.toString());
1060+
}
1061+
9771062
////////////////////////////////////////////////////////////////////////////
9781063
// Raw fields
9791064
//////////////////////////////////

0 commit comments

Comments
 (0)