Skip to content

Speed up toXContent Collection Serialization in some Spots #78742

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public Map<String, DatabaseInfo> getDatabases() {
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field("files_in_temp", filesInTemp);
builder.stringListField("files_in_temp", filesInTemp);
builder.field("databases", databases.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.map(Map.Entry::getValue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ public void setFollowIndexNamePattern(String followIndexNamePattern) {
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field(PutFollowRequest.REMOTE_CLUSTER_FIELD.getPreferredName(), remoteCluster);
builder.field(LEADER_PATTERNS_FIELD.getPreferredName(), leaderIndexPatterns);
builder.stringListField(LEADER_PATTERNS_FIELD.getPreferredName(), leaderIndexPatterns);
if (leaderIndexExclusionPatterns.isEmpty() == false) {
builder.field(LEADER_EXCLUSION_PATTERNS_FIELD.getPreferredName(), leaderIndexExclusionPatterns);
builder.stringListField(LEADER_EXCLUSION_PATTERNS_FIELD.getPreferredName(), leaderIndexExclusionPatterns);
}
if (followIndexNamePattern != null) {
builder.field(FOLLOW_PATTERN_FIELD.getPreferredName(), followIndexNamePattern);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,12 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
{
builder.startObject(type);
{
builder.field(NamedPolicy.INDICES_FIELD.getPreferredName(), indices);
builder.stringListField(NamedPolicy.INDICES_FIELD.getPreferredName(), indices);
if (query != null) {
builder.field(NamedPolicy.QUERY_FIELD.getPreferredName(), asMap(query, XContentType.JSON));
}
builder.field(NamedPolicy.MATCH_FIELD_FIELD.getPreferredName(), matchField);
builder.field(NamedPolicy.ENRICH_FIELDS_FIELD.getPreferredName(), enrichFields);
builder.stringListField(NamedPolicy.ENRICH_FIELDS_FIELD.getPreferredName(), enrichFields);
}
builder.endObject();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ public final PutIndexTemplateRequest masterNodeTimeout(String timeout) {

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.field("index_patterns", indexPatterns);
builder.stringListField("index_patterns", indexPatterns);
builder.field("order", order);
if (version != null) {
builder.field("version", version);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public Optional<ValidationException> validate() {
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.array(INDEX.getPreferredName(), indices.toArray());
builder.stringListField(INDEX.getPreferredName(), indices);
if (queryConfig != null) {
builder.field(QUERY.getPreferredName(), queryConfig.getQuery());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.startObject();

if (datafeedIds.isEmpty() == false) {
builder.field(DATAFEED_IDS.getPreferredName(), datafeedIds);
builder.stringListField(DATAFEED_IDS.getPreferredName(), datafeedIds);
}

if (allowNoMatch != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.startObject();

if (jobIds.isEmpty() == false) {
builder.field(JOB_IDS.getPreferredName(), jobIds);
builder.stringListField(JOB_IDS.getPreferredName(), jobIds);
}

if (allowNoMatch != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.field(MlFilter.DESCRIPTION.getPreferredName(), description);
}
if (addItems != null) {
builder.field(ADD_ITEMS.getPreferredName(), addItems);
builder.stringListField(ADD_ITEMS.getPreferredName(), addItems);
}
if (removeItems != null) {
builder.field(REMOVE_ITEMS.getPreferredName(), removeItems);
builder.stringListField(REMOVE_ITEMS.getPreferredName(), removeItems);
}
builder.endObject();
return builder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public String getDescription() {
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field(ID.getPreferredName(), id);
builder.field(JOB_IDS.getPreferredName(), jobIds);
builder.stringListField(JOB_IDS.getPreferredName(), jobIds);
if (description != null) {
builder.field(DESCRIPTION.getPreferredName(), description);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
import java.util.Arrays;
import java.util.Base64;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.IdentityHashMap;
Expand Down Expand Up @@ -921,6 +923,58 @@ private XContentBuilder value(ToXContent value, ToXContent.Params params) throws
// Maps & Iterable
//////////////////////////////////

public XContentBuilder stringListField(String name, Collection<String> values) throws IOException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: maybe just array(String name, Collection<String> values) ? Same remark for the other new methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't do that unfortunately because we have:

    public XContentBuilder field(String name, Iterable<?> values) throws IOException {
        return field(name).value(values);
    }

which collides with it. Same with the other cases, these super generic ? or Object type methods collide with everything.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right, I did not see this one. Let's keep like it is then.

field(name);
if (values == null) {
return nullValue();
}
startArray();
for (String value : values) {
value(value);
}
endArray();
return this;
}

public XContentBuilder xContentList(String name, Collection<? extends ToXContent> values) throws IOException {
field(name);
if (values == null) {
return nullValue();
}
startArray();
for (ToXContent value : values) {
value(value);
}
endArray();
return this;
}

public XContentBuilder xContentList(String name, ToXContent... values) throws IOException {
field(name);
if (values == null) {
return nullValue();
}
startArray();
for (ToXContent value : values) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe check for non null array here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh right TIL, I I always figured I'd get [null] here if passed a null but turns out you actually get the null :)

value(value);
}
endArray();
return this;
}

public XContentBuilder enumSet(String name, EnumSet<?> values) throws IOException {
field(name);
if (values == null) {
return nullValue();
}
startArray();
for (Enum<?> value : values) {
value(value);
}
endArray();
return this;
}

public XContentBuilder field(String name, Map<String, Object> values) throws IOException {
return field(name).map(values);
}
Expand All @@ -929,6 +983,32 @@ public XContentBuilder map(Map<String, ?> values) throws IOException {
return map(values, true, true);
}

public XContentBuilder stringStringMap(String name, Map<String, String> values) throws IOException {
field(name);
if (values == null) {
return nullValue();
}
startObject();
for (Map.Entry<String, String> value : values.entrySet()) {
field(value.getKey());
value(value.getValue());
}
return endObject();
}

public XContentBuilder xContentValuesMap(String name, Map<String, ? extends ToXContent> values) throws IOException {
field(name);
if (values == null) {
return nullValue();
}
startObject();
for (Map.Entry<String, ? extends ToXContent> value : values.entrySet()) {
field(value.getKey());
value(value.getValue());
}
return endObject();
}

/** writes a map without the start object and end object headers */
public XContentBuilder mapContents(Map<String, ?> values) throws IOException {
return map(values, true, false);
Expand Down Expand Up @@ -1026,6 +1106,11 @@ public XContentBuilder percentageField(String rawFieldName, String readableField
return this;
}

public XContentBuilder field(String name, Enum<?> value) throws IOException {
field(name);
return value(value == null ? null : value.toString());
}

////////////////////////////////////////////////////////////////////////////
// Raw fields
//////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -405,9 +405,9 @@ public void writeTo(StreamOutput out) throws IOException {
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field(INDICES_FIELD.getPreferredName(), indices);
builder.field(ALIASES_FIELD.getPreferredName(), aliases);
builder.field(DATA_STREAMS_FIELD.getPreferredName(), dataStreams);
builder.xContentList(INDICES_FIELD.getPreferredName(), indices);
builder.xContentList(ALIASES_FIELD.getPreferredName(), aliases);
builder.xContentList(DATA_STREAMS_FIELD.getPreferredName(), dataStreams);
builder.endObject();
return builder;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
for (Map.Entry<String, List<String>> entry : overlappingTemplates.entrySet()) {
builder.startObject();
builder.field(NAME.getPreferredName(), entry.getKey());
builder.field(INDEX_PATTERNS.getPreferredName(), entry.getValue());
builder.stringListField(INDEX_PATTERNS.getPreferredName(), entry.getValue());
builder.endObject();
}
builder.endArray();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,13 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.field(SEARCHABLE_FIELD.getPreferredName(), isSearchable);
builder.field(AGGREGATABLE_FIELD.getPreferredName(), isAggregatable);
if (indices != null) {
builder.field(INDICES_FIELD.getPreferredName(), indices);
builder.array(INDICES_FIELD.getPreferredName(), indices);
}
if (nonSearchableIndices != null) {
builder.field(NON_SEARCHABLE_INDICES_FIELD.getPreferredName(), nonSearchableIndices);
builder.array(NON_SEARCHABLE_INDICES_FIELD.getPreferredName(), nonSearchableIndices);
}
if (nonAggregatableIndices != null) {
builder.field(NON_AGGREGATABLE_INDICES_FIELD.getPreferredName(), nonAggregatableIndices);
builder.array(NON_AGGREGATABLE_INDICES_FIELD.getPreferredName(), nonAggregatableIndices);
}
if (meta.isEmpty() == false) {
builder.startObject("meta");
Expand All @@ -140,7 +140,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
for (Map.Entry<String, Set<String>> entry : entries) {
List<String> values = new ArrayList<>(entry.getValue());
values.sort(String::compareTo); // provide predictable order
builder.field(entry.getKey(), values);
builder.stringListField(entry.getKey(), values);
}
builder.endObject();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public FieldCapabilitiesFailure(StreamInput in) throws IOException {
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
{
builder.field(INDICES_FIELD.getPreferredName(), indices);
builder.stringListField(INDICES_FIELD.getPreferredName(), indices);
builder.startObject(FAILURE_FIELD.getPreferredName());
{
ElasticsearchException.generateFailureXContent(builder, params, exception, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,11 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
throw new IllegalStateException("cannot serialize non-merged response");
}
builder.startObject();
builder.field(INDICES_FIELD.getPreferredName(), indices);
builder.array(INDICES_FIELD.getPreferredName(), indices);
builder.field(FIELDS_FIELD.getPreferredName(), responseMap);
if (this.failures.size() > 0) {
builder.field(FAILED_INDICES_FIELD.getPreferredName(), getFailedIndices().length);
builder.field(FAILURES_FIELD.getPreferredName(), failures);
builder.xContentList(FAILURES_FIELD.getPreferredName(), failures);
}
builder.endObject();
return builder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.field(INDEX.getPreferredName(), index);
builder.field(ID.getPreferredName(), id);
builder.field(ROUTING.getPreferredName(), routing);
builder.field(STORED_FIELDS.getPreferredName(), storedFields);
builder.array(STORED_FIELDS.getPreferredName(), storedFields);
builder.field(VERSION.getPreferredName(), version);
builder.field(VERSION_TYPE.getPreferredName(), VersionType.toString(versionType));
builder.field(SOURCE.getPreferredName(), fetchSourceContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
.field(TERM_PARSE_FIELD.getPreferredName(), term)
.field(LAST_COMMITTED_CONFIGURATION_FIELD.getPreferredName(), lastCommittedConfiguration)
.field(LAST_ACCEPTED_CONFIGURATION_FIELD.getPreferredName(), lastAcceptedConfiguration)
.field(VOTING_CONFIG_EXCLUSIONS_FIELD.getPreferredName(), votingConfigExclusions);
.xContentList(VOTING_CONFIG_EXCLUSIONS_FIELD.getPreferredName(), votingConfigExclusions);
}

public static CoordinationMetadata fromXContent(XContentParser parser) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,12 @@ public void writeTo(StreamOutput out) throws IOException {
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field(INDEX_PATTERNS.getPreferredName(), this.indexPatterns);
builder.stringListField(INDEX_PATTERNS.getPreferredName(), this.indexPatterns);
if (this.template != null) {
builder.field(TEMPLATE.getPreferredName(), this.template);
}
if (this.componentTemplates != null) {
builder.field(COMPOSED_OF.getPreferredName(), this.componentTemplates);
builder.stringListField(COMPOSED_OF.getPreferredName(), this.componentTemplates);
}
if (this.priority != null) {
builder.field(PRIORITY.getPreferredName(), priority);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.startObject();
builder.field(NAME_FIELD.getPreferredName(), name);
builder.field(TIMESTAMP_FIELD_FIELD.getPreferredName(), timeStampField);
builder.field(INDICES_FIELD.getPreferredName(), indices);
builder.xContentList(INDICES_FIELD.getPreferredName(), indices);
builder.field(GENERATION_FIELD.getPreferredName(), generation);
if (metadata != null) {
builder.field(METADATA_FIELD.getPreferredName(), metadata);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ public static DataStreamAlias fromXContent(XContentParser parser) throws IOExcep
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(name);
builder.field(DATA_STREAMS_FIELD.getPreferredName(), dataStreams);
builder.stringListField(DATA_STREAMS_FIELD.getPreferredName(), dataStreams);
if (writeDataStream != null) {
builder.field(WRITE_DATA_STREAM_FIELD.getPreferredName(), writeDataStream);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,7 @@ public static DataStreamMetadata fromXContent(XContentParser parser) throws IOEx

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(DATA_STREAM.getPreferredName());
for (Map.Entry<String, DataStream> dataStream : dataStreams.entrySet()) {
builder.field(dataStream.getKey(), dataStream.getValue());
}
builder.endObject();
builder.xContentValuesMap(DATA_STREAM.getPreferredName(), dataStreams);
builder.startObject(DATA_STREAM_ALIASES.getPreferredName());
for (Map.Entry<String, DataStreamAlias> dataStream : dataStreamAliases.entrySet()) {
dataStream.getValue().toXContent(builder, params);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1396,8 +1396,7 @@ public static void toXContent(IndexMetadata indexMetadata, XContentBuilder build
}

for (ObjectObjectCursor<String, DiffableStringMap> cursor : indexMetadata.customData) {
builder.field(cursor.key);
builder.map(cursor.value);
builder.stringStringMap(cursor.key, cursor.value);
}

if (context != Metadata.XContentContext.API) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ private static void toInnerXContent(IndexTemplateMetadata indexTemplateMetadata,
if (indexTemplateMetadata.version() != null) {
builder.field("version", indexTemplateMetadata.version());
}
builder.field("index_patterns", indexTemplateMetadata.patterns());
builder.stringListField("index_patterns", indexTemplateMetadata.patterns());

builder.startObject("settings");
indexTemplateMetadata.settings().toXContent(builder, params);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,13 @@ public Set<String> getComposableTemplates() {
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
if (this.indices != null) {
builder.field("indices", this.indices);
builder.stringListField("indices", this.indices);
}
if (this.dataStreams != null) {
builder.field("data_streams", this.dataStreams);
builder.stringListField("data_streams", this.dataStreams);
}
if (this.composableTemplates != null) {
builder.field("composable_templates", this.composableTemplates);
builder.stringListField("composable_templates", this.composableTemplates);
}
builder.endObject();
return builder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.field(CURRENT_TERM_PARSE_FIELD.getPreferredName(), currentTerm);
builder.field(CLUSTER_STATE_VERSION_PARSE_FIELD.getPreferredName(), clusterStateVersion);
builder.field(GENERATION_PARSE_FIELD.getPreferredName(), globalGeneration);
builder.array(INDEX_GENERATIONS_PARSE_FIELD.getPreferredName(), indexEntryList().toArray());
builder.xContentList(INDEX_GENERATIONS_PARSE_FIELD.getPreferredName(), indexEntryList());
return builder;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.field("failed_attempts", failedAllocations);
}
if (failedNodeIds.isEmpty() == false) {
builder.field("failed_nodes", failedNodeIds);
builder.stringListField("failed_nodes", failedNodeIds);
}
builder.field("delayed", delayed);
String details = getDetails();
Expand Down
Loading