From 2a2150357a997b69c6488869bc8c51d6a6985207 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Fri, 28 Feb 2025 19:34:28 +0100 Subject: [PATCH 1/3] faster lookup --- .../cluster/metadata/ProjectMetadata.java | 108 +++++++++++++++++- 1 file changed, 106 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/ProjectMetadata.java b/server/src/main/java/org/elasticsearch/cluster/metadata/ProjectMetadata.java index 24adeedd7366e..e758b85baa165 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/ProjectMetadata.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/ProjectMetadata.java @@ -46,6 +46,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -1761,7 +1762,7 @@ static SortedMap buildIndicesLookup( if (indices.isEmpty()) { return Collections.emptySortedMap(); } - SortedMap indicesLookup = new TreeMap<>(); + Map indicesLookup = new HashMap<>(); Map indexToDataStreamLookup = new HashMap<>(); collectDataStreams(dataStreamMetadata, indicesLookup, indexToDataStreamLookup); @@ -1769,7 +1770,110 @@ static SortedMap buildIndicesLookup( collectIndices(indices, indexToDataStreamLookup, indicesLookup, aliasToIndices); collectAliases(aliasToIndices, indicesLookup); - return Collections.unmodifiableSortedMap(indicesLookup); + return new SortedMap<>() { + + private final SortedMap map = new TreeMap<>(indicesLookup); + + @Override + public Comparator comparator() { + return map.comparator(); + } + + @Override + public SortedMap subMap(String fromKey, String toKey) { + return Collections.unmodifiableSortedMap(map.subMap(fromKey, toKey)); + } + + @Override + public SortedMap headMap(String toKey) { + return Collections.unmodifiableSortedMap(map.headMap(toKey)); + } + + @Override + public SortedMap tailMap(String fromKey) { + return Collections.unmodifiableSortedMap(map.tailMap(fromKey)); + } + + @Override + public String firstKey() { + return map.firstKey(); + } + + @Override + public String lastKey() { + return map.lastKey(); + } + + @Override + public Set keySet() { + return Collections.unmodifiableSet(map.keySet()); + } + + @Override + public Collection values() { + return Collections.unmodifiableCollection(map.values()); + } + + @Override + public Set> entrySet() { + return Collections.unmodifiableSet(map.entrySet()); + } + + @Override + public int size() { + return indicesLookup.size(); + } + + @Override + public boolean isEmpty() { + return indicesLookup.isEmpty(); + } + + @Override + public boolean containsKey(Object key) { + return indicesLookup.containsKey(key); + } + + @Override + public boolean containsValue(Object value) { + return indicesLookup.containsValue(value); + } + + @Override + public IndexAbstraction get(Object key) { + return indicesLookup.get(key); + } + + @Override + public IndexAbstraction put(String key, IndexAbstraction value) { + throw new UnsupportedOperationException(); + } + + @Override + public IndexAbstraction remove(Object key) { + throw new UnsupportedOperationException(); + } + + @Override + public void putAll(Map m) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean equals(Object obj) { + return indicesLookup.equals(obj); + } + + @Override + public int hashCode() { + return indicesLookup.hashCode(); + } + }; } private static void collectAliases(Map> aliasToIndices, Map indicesLookup) { From d11b5215314b9c8c12ae56b6226d8281ec5ab937 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 3 Mar 2025 13:53:28 +0100 Subject: [PATCH 2/3] cleanup --- .../org/elasticsearch/cluster/metadata/ProjectMetadata.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/ProjectMetadata.java b/server/src/main/java/org/elasticsearch/cluster/metadata/ProjectMetadata.java index e758b85baa165..371af9a165a9b 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/ProjectMetadata.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/ProjectMetadata.java @@ -1770,6 +1770,9 @@ static SortedMap buildIndicesLookup( collectIndices(indices, indexToDataStreamLookup, indicesLookup, aliasToIndices); collectAliases(aliasToIndices, indicesLookup); + // We do a ton of lookups on this map but also need its sorted properties at times. + // Using this hybrid of a sorted and a hash-map trades some heap overhead relative to just using a TreeMap + // for much faster O(1) lookups in large clusters. return new SortedMap<>() { private final SortedMap map = new TreeMap<>(indicesLookup); @@ -1816,7 +1819,7 @@ public Collection values() { @Override public Set> entrySet() { - return Collections.unmodifiableSet(map.entrySet()); + return Collections.unmodifiableSortedMap(map).entrySet(); } @Override From 8dda11244417bfaed7bba88162df64069478037c Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 3 Mar 2025 14:04:35 +0100 Subject: [PATCH 3/3] cr comment + fixup equals --- .../cluster/metadata/ProjectMetadata.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/ProjectMetadata.java b/server/src/main/java/org/elasticsearch/cluster/metadata/ProjectMetadata.java index 371af9a165a9b..5ea0bada50946 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/ProjectMetadata.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/ProjectMetadata.java @@ -1775,51 +1775,53 @@ static SortedMap buildIndicesLookup( // for much faster O(1) lookups in large clusters. return new SortedMap<>() { - private final SortedMap map = new TreeMap<>(indicesLookup); + private final SortedMap sortedMap = Collections.unmodifiableSortedMap( + new TreeMap<>(indicesLookup) + ); @Override public Comparator comparator() { - return map.comparator(); + return sortedMap.comparator(); } @Override public SortedMap subMap(String fromKey, String toKey) { - return Collections.unmodifiableSortedMap(map.subMap(fromKey, toKey)); + return sortedMap.subMap(fromKey, toKey); } @Override public SortedMap headMap(String toKey) { - return Collections.unmodifiableSortedMap(map.headMap(toKey)); + return sortedMap.headMap(toKey); } @Override public SortedMap tailMap(String fromKey) { - return Collections.unmodifiableSortedMap(map.tailMap(fromKey)); + return sortedMap.tailMap(fromKey); } @Override public String firstKey() { - return map.firstKey(); + return sortedMap.firstKey(); } @Override public String lastKey() { - return map.lastKey(); + return sortedMap.lastKey(); } @Override public Set keySet() { - return Collections.unmodifiableSet(map.keySet()); + return sortedMap.keySet(); } @Override public Collection values() { - return Collections.unmodifiableCollection(map.values()); + return sortedMap.values(); } @Override public Set> entrySet() { - return Collections.unmodifiableSortedMap(map).entrySet(); + return sortedMap.entrySet(); } @Override @@ -1869,6 +1871,12 @@ public void clear() { @Override public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } return indicesLookup.equals(obj); }