Skip to content

Commit 31bea56

Browse files
authored
Memoize pattern match in GetAliases (elastic#113571)
Previously, when GetAliases was called with multiple indices that share an alias, findAliases would recheck the alias against the supplied alias patterns for each index that used it. This change memoizes the pattern check to avoid that redundant work. Closes elastic#102676
1 parent c498dae commit 31bea56

File tree

2 files changed

+34
-18
lines changed

2 files changed

+34
-18
lines changed

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

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -855,7 +855,7 @@ public Map<String, List<DataStreamAlias>> findDataStreamAliases(final String[] a
855855
*
856856
* @param aliases The aliases to look for. Might contain include or exclude wildcards.
857857
* @param possibleMatches The data streams or indices that the aliases must point to in order to be returned
858-
* @param getter A function that is used to get the alises for a given data stream or index
858+
* @param getter A function that is used to get the aliases for a given data stream or index
859859
* @param setter A function that is used to keep track of the found aliases
860860
*/
861861
private void findAliasInfo(final String[] aliases, final String[] possibleMatches, AliasInfoGetter getter, AliasInfoSetter setter) {
@@ -881,24 +881,30 @@ private void findAliasInfo(final String[] aliases, final String[] possibleMatche
881881

882882
boolean matchAllAliases = patterns.length == 0;
883883

884+
// memoize pattern match against aliases to avoid repeatedly matching when multiple indices share an alias
885+
HashMap<String, Boolean> seenAliases = new HashMap<>();
886+
Predicate<String> matcher = alias -> seenAliases.computeIfAbsent(alias, key -> {
887+
boolean matched = matchAllAliases;
888+
for (int i = 0; i < patterns.length; i++) {
889+
if (include[i]) {
890+
if (matched == false) {
891+
String pattern = patterns[i];
892+
matched = ALL.equals(pattern) || Regex.simpleMatch(pattern, key);
893+
}
894+
} else if (matched) {
895+
matched = Regex.simpleMatch(patterns[i], key) == false;
896+
}
897+
}
898+
899+
return matched;
900+
});
901+
884902
for (String index : possibleMatches) {
885903
List<AliasInfo> filteredValues = new ArrayList<>();
886904

887905
List<? extends AliasInfo> entities = getter.get(index);
888906
for (AliasInfo aliasInfo : entities) {
889-
boolean matched = matchAllAliases;
890-
String alias = aliasInfo.getAlias();
891-
for (int i = 0; i < patterns.length; i++) {
892-
if (include[i]) {
893-
if (matched == false) {
894-
String pattern = patterns[i];
895-
matched = ALL.equals(pattern) || Regex.simpleMatch(pattern, alias);
896-
}
897-
} else if (matched) {
898-
matched = Regex.simpleMatch(patterns[i], alias) == false;
899-
}
900-
}
901-
if (matched) {
907+
if (matcher.test(aliasInfo.getAlias())) {
902908
filteredValues.add(aliasInfo);
903909
}
904910
}

server/src/test/java/org/elasticsearch/cluster/metadata/MetadataTests.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,14 @@ public void testFindAliases() {
112112
.putAlias(AliasMetadata.builder("alias1").build())
113113
.putAlias(AliasMetadata.builder("alias2").build())
114114
)
115+
.put(
116+
IndexMetadata.builder("index2")
117+
.settings(Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersion.current()))
118+
.numberOfShards(1)
119+
.numberOfReplicas(0)
120+
.putAlias(AliasMetadata.builder("alias2").build())
121+
.putAlias(AliasMetadata.builder("alias3").build())
122+
)
115123
.build();
116124

117125
{
@@ -135,10 +143,12 @@ public void testFindAliases() {
135143
}
136144
{
137145
GetAliasesRequest request = new GetAliasesRequest("alias*");
138-
Map<String, List<AliasMetadata>> aliases = metadata.findAliases(request.aliases(), new String[] { "index" });
139-
assertThat(aliases, aMapWithSize(1));
140-
List<AliasMetadata> aliasMetadataList = aliases.get("index");
141-
assertThat(aliasMetadataList, transformedItemsMatch(AliasMetadata::alias, contains("alias1", "alias2")));
146+
Map<String, List<AliasMetadata>> aliases = metadata.findAliases(request.aliases(), new String[] { "index", "index2" });
147+
assertThat(aliases, aMapWithSize(2));
148+
List<AliasMetadata> indexAliasMetadataList = aliases.get("index");
149+
assertThat(indexAliasMetadataList, transformedItemsMatch(AliasMetadata::alias, contains("alias1", "alias2")));
150+
List<AliasMetadata> index2AliasMetadataList = aliases.get("index2");
151+
assertThat(index2AliasMetadataList, transformedItemsMatch(AliasMetadata::alias, contains("alias2", "alias3")));
142152
}
143153
{
144154
GetAliasesRequest request = new GetAliasesRequest("alias1");

0 commit comments

Comments
 (0)