Skip to content

Commit 3d389ce

Browse files
Some speedups aroud ListSetting (#112447)
Just a random cleanup from debugging test failures. There's a couple of easy to fix slow things in list setting handling here. The biggest win is from not materializing the string list for non-string type setting values during parsing and speeding up `Strings.toString`.
1 parent e1b4209 commit 3d389ce

File tree

7 files changed

+47
-25
lines changed

7 files changed

+47
-25
lines changed

server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ public Iterator<Setting<?>> settings() {
456456
);
457457
public static final Setting.AffixSetting<List<String>> INDEX_ROUTING_INITIAL_RECOVERY_GROUP_SETTING = Setting.prefixKeySetting(
458458
"index.routing.allocation.initial_recovery.",
459-
key -> Setting.stringListSetting(key)
459+
Setting::stringListSetting
460460
);
461461

462462
/**

server/src/main/java/org/elasticsearch/common/Strings.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,18 @@
1212
import org.elasticsearch.ElasticsearchException;
1313
import org.elasticsearch.ExceptionsHelper;
1414
import org.elasticsearch.common.bytes.BytesReference;
15+
import org.elasticsearch.common.io.stream.BytesStream;
1516
import org.elasticsearch.common.util.CollectionUtils;
1617
import org.elasticsearch.common.xcontent.ChunkedToXContent;
1718
import org.elasticsearch.core.Nullable;
1819
import org.elasticsearch.xcontent.ToXContent;
1920
import org.elasticsearch.xcontent.XContentBuilder;
2021
import org.elasticsearch.xcontent.json.JsonXContent;
2122

23+
import java.io.ByteArrayOutputStream;
2224
import java.io.IOException;
25+
import java.io.OutputStream;
26+
import java.nio.charset.StandardCharsets;
2327
import java.util.ArrayList;
2428
import java.util.Arrays;
2529
import java.util.Collection;
@@ -767,7 +771,13 @@ public static String toString(ToXContent toXContent, ToXContent.Params params) {
767771
* @param xContentBuilder builder containing an object to converted to a string
768772
*/
769773
public static String toString(XContentBuilder xContentBuilder) {
770-
return BytesReference.bytes(xContentBuilder).utf8ToString();
774+
xContentBuilder.close();
775+
OutputStream stream = xContentBuilder.getOutputStream();
776+
if (stream instanceof ByteArrayOutputStream baos) {
777+
return baos.toString(StandardCharsets.UTF_8);
778+
} else {
779+
return ((BytesStream) stream).bytes().utf8ToString();
780+
}
771781
}
772782

773783
/**

server/src/main/java/org/elasticsearch/common/settings/Setting.java

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1696,7 +1696,7 @@ public static Setting<List<String>> stringListSetting(String key, Property... pr
16961696
}
16971697

16981698
public static Setting<List<String>> stringListSetting(String key, List<String> defValue, Property... properties) {
1699-
return new ListSetting<>(key, null, s -> defValue, Setting::parseableStringToList, v -> {}, properties) {
1699+
return new ListSetting<>(key, null, s -> defValue, s -> parseableStringToList(s, Function.identity()), v -> {}, properties) {
17001700
@Override
17011701
public List<String> get(Settings settings) {
17021702
checkDeprecation(settings);
@@ -1735,7 +1735,13 @@ public static <T> Setting<List<T>> listSetting(
17351735
final Function<String, T> singleValueParser,
17361736
final Property... properties
17371737
) {
1738-
return listSetting(key, fallbackSetting, singleValueParser, (s) -> parseableStringToList(fallbackSetting.getRaw(s)), properties);
1738+
return listSetting(
1739+
key,
1740+
fallbackSetting,
1741+
singleValueParser,
1742+
s -> parseableStringToList(fallbackSetting.getRaw(s), Function.identity()),
1743+
properties
1744+
);
17391745
}
17401746

17411747
public static <T> Setting<List<T>> listSetting(
@@ -1759,12 +1765,17 @@ public static <T> Setting<List<T>> listSetting(
17591765
if (defaultStringValue.apply(Settings.EMPTY) == null) {
17601766
throw new IllegalArgumentException("default value function must not return null");
17611767
}
1762-
Function<String, List<T>> parser = (s) -> parseableStringToList(s).stream().map(singleValueParser).toList();
1763-
1764-
return new ListSetting<>(key, fallbackSetting, defaultStringValue, parser, validator, properties);
1768+
return new ListSetting<>(
1769+
key,
1770+
fallbackSetting,
1771+
defaultStringValue,
1772+
s -> parseableStringToList(s, singleValueParser),
1773+
validator,
1774+
properties
1775+
);
17651776
}
17661777

1767-
private static List<String> parseableStringToList(String parsableString) {
1778+
private static <T> List<T> parseableStringToList(String parsableString, Function<String, T> singleValueParser) {
17681779
if ("[]".equals(parsableString)) {
17691780
return List.of();
17701781
}
@@ -1773,7 +1784,7 @@ private static List<String> parseableStringToList(String parsableString) {
17731784
xContentParser.nextToken();
17741785
return XContentParserUtils.parseList(xContentParser, p -> {
17751786
XContentParserUtils.ensureExpectedToken(XContentParser.Token.VALUE_STRING, p.currentToken(), p);
1776-
return p.text();
1787+
return singleValueParser.apply(p.text());
17771788
});
17781789
} catch (IOException e) {
17791790
throw new IllegalArgumentException("failed to parse array", e);
@@ -2079,7 +2090,7 @@ public boolean equals(Object o) {
20792090

20802091
@Override
20812092
public int hashCode() {
2082-
return Objects.hash(key);
2093+
return key.hashCode();
20832094
}
20842095

20852096
/**
@@ -2088,8 +2099,7 @@ public int hashCode() {
20882099
* {@link #getConcreteSetting(String)} is used to pull the updater.
20892100
*/
20902101
public static <T> AffixSetting<T> prefixKeySetting(String prefix, Function<String, Setting<T>> delegateFactory) {
2091-
BiFunction<String, String, Setting<T>> delegateFactoryWithNamespace = (ns, k) -> delegateFactory.apply(k);
2092-
return affixKeySetting(new AffixKey(prefix, null, null), delegateFactoryWithNamespace);
2102+
return affixKeySetting(prefix, null, delegateFactory);
20932103
}
20942104

20952105
/**
@@ -2177,7 +2187,7 @@ public boolean equals(Object o) {
21772187

21782188
@Override
21792189
public int hashCode() {
2180-
return Objects.hash(key);
2190+
return key.hashCode();
21812191
}
21822192

21832193
@Override

server/src/main/java/org/elasticsearch/http/HttpTransportSettings.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,26 @@ public final class HttpTransportSettings {
3030
public static final Setting<String> SETTING_CORS_ALLOW_ORIGIN = new Setting<>(
3131
"http.cors.allow-origin",
3232
"",
33-
(value) -> value,
33+
Function.identity(),
3434
Property.NodeScope
3535
);
3636
public static final Setting<Integer> SETTING_CORS_MAX_AGE = intSetting("http.cors.max-age", 1728000, Property.NodeScope);
3737
public static final Setting<String> SETTING_CORS_ALLOW_METHODS = new Setting<>(
3838
"http.cors.allow-methods",
3939
"OPTIONS,HEAD,GET,POST,PUT,DELETE",
40-
(value) -> value,
40+
Function.identity(),
4141
Property.NodeScope
4242
);
4343
public static final Setting<String> SETTING_CORS_ALLOW_HEADERS = new Setting<>(
4444
"http.cors.allow-headers",
4545
"X-Requested-With,Content-Type,Content-Length,Authorization,Accept,User-Agent,X-Elastic-Client-Meta",
46-
(value) -> value,
46+
Function.identity(),
4747
Property.NodeScope
4848
);
4949
public static final Setting<String> SETTING_CORS_EXPOSE_HEADERS = new Setting<>(
5050
"http.cors.expose-headers",
5151
"X-elastic-product",
52-
(value) -> value,
52+
Function.identity(),
5353
Property.NodeScope
5454
);
5555
public static final Setting<Boolean> SETTING_CORS_ALLOW_CREDENTIALS = Setting.boolSetting(

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/user/AnonymousUser.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import java.util.List;
1515
import java.util.Optional;
16+
import java.util.function.Function;
1617

1718
import static org.elasticsearch.xpack.core.security.SecurityField.setting;
1819

@@ -25,7 +26,7 @@ public class AnonymousUser extends ReservedUser {
2526
public static final Setting<String> USERNAME_SETTING = new Setting<>(
2627
setting("authc.anonymous.username"),
2728
DEFAULT_ANONYMOUS_USERNAME,
28-
s -> s,
29+
Function.identity(),
2930
Property.NodeScope
3031
);
3132
public static final Setting<List<String>> ROLES_SETTING = Setting.stringListSetting(

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/crypto/CryptoService.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.Arrays;
2626
import java.util.Base64;
2727
import java.util.List;
28+
import java.util.function.Function;
2829

2930
import javax.crypto.BadPaddingException;
3031
import javax.crypto.Cipher;
@@ -57,7 +58,7 @@ public class CryptoService {
5758
private static final Setting<String> ENCRYPTION_ALGO_SETTING = new Setting<>(
5859
SecurityField.setting("encryption.algorithm"),
5960
s -> DEFAULT_ENCRYPTION_ALGORITHM,
60-
s -> s,
61+
Function.identity(),
6162
Property.NodeScope
6263
);
6364
private static final Setting<Integer> ENCRYPTION_KEY_LENGTH_SETTING = Setting.intSetting(
@@ -68,7 +69,7 @@ public class CryptoService {
6869
private static final Setting<String> ENCRYPTION_KEY_ALGO_SETTING = new Setting<>(
6970
SecurityField.setting("encryption_key.algorithm"),
7071
DEFAULT_KEY_ALGORITH,
71-
s -> s,
72+
Function.identity(),
7273
Property.NodeScope
7374
);
7475
private static final Logger logger = LogManager.getLogger(CryptoService.class);

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrail.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener {
327327
key,
328328
Collections.singletonList("*"),
329329
Function.identity(),
330-
value -> EventFilterPolicy.parsePredicate(value),
330+
EventFilterPolicy::parsePredicate,
331331
Property.NodeScope,
332332
Property.Dynamic
333333
)
@@ -339,7 +339,7 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener {
339339
key,
340340
Collections.singletonList("*"),
341341
Function.identity(),
342-
value -> EventFilterPolicy.parsePredicate(value),
342+
EventFilterPolicy::parsePredicate,
343343
Property.NodeScope,
344344
Property.Dynamic
345345
)
@@ -351,7 +351,7 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener {
351351
key,
352352
Collections.singletonList("*"),
353353
Function.identity(),
354-
value -> EventFilterPolicy.parsePredicate(value),
354+
EventFilterPolicy::parsePredicate,
355355
Property.NodeScope,
356356
Property.Dynamic
357357
)
@@ -363,7 +363,7 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener {
363363
key,
364364
Collections.singletonList("*"),
365365
Function.identity(),
366-
value -> EventFilterPolicy.parsePredicate(value),
366+
EventFilterPolicy::parsePredicate,
367367
Property.NodeScope,
368368
Property.Dynamic
369369
)
@@ -375,7 +375,7 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener {
375375
key,
376376
Collections.singletonList("*"),
377377
Function.identity(),
378-
value -> EventFilterPolicy.parsePredicate(value),
378+
EventFilterPolicy::parsePredicate,
379379
Property.NodeScope,
380380
Property.Dynamic
381381
)

0 commit comments

Comments
 (0)