Skip to content

Commit 2e74205

Browse files
authored
Use HashMap for IndexMetadata.inSyncAllocationIds (#86403)
The in sync allocation ids is a mapping from shard to the set of ids currently being processed. When being built, the metadata uses a sparse map, only filling a value for a shard as they are put into the builder. When the final metadata is built, the map is made dense. This commit converts to using a HashMap instead of ImmutableOpenIntMap. The boxed keys should not cause allocations, as long as number of shards is lower than 128. Long term the map itself should become an array, as we know the number of shards (much like the dense primaryTerms array here). However, that change will be a little trickier to make, since we will need to be backward compatible with how diffs are built, currently using Map differences. relates #86239
1 parent 3c8eab5 commit 2e74205

File tree

1 file changed

+17
-19
lines changed

1 file changed

+17
-19
lines changed

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

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import org.elasticsearch.cluster.routing.allocation.IndexMetadataUpdater;
2323
import org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider;
2424
import org.elasticsearch.cluster.routing.allocation.decider.ShardsLimitAllocationDecider;
25-
import org.elasticsearch.common.collect.ImmutableOpenIntMap;
2625
import org.elasticsearch.common.collect.ImmutableOpenMap;
2726
import org.elasticsearch.common.collect.MapBuilder;
2827
import org.elasticsearch.common.compress.CompressedXContent;
@@ -58,6 +57,7 @@
5857
import java.util.Arrays;
5958
import java.util.Collections;
6059
import java.util.EnumSet;
60+
import java.util.HashMap;
6161
import java.util.HashSet;
6262
import java.util.Iterator;
6363
import java.util.List;
@@ -516,7 +516,7 @@ public Iterator<Setting<?>> settings() {
516516

517517
private final ImmutableOpenMap<String, DiffableStringMap> customData;
518518

519-
private final ImmutableOpenIntMap<Set<String>> inSyncAllocationIds;
519+
private final Map<Integer, Set<String>> inSyncAllocationIds;
520520

521521
private final transient int totalNumberOfShards;
522522

@@ -571,7 +571,7 @@ private IndexMetadata(
571571
final MappingMetadata mapping,
572572
final ImmutableOpenMap<String, AliasMetadata> aliases,
573573
final ImmutableOpenMap<String, DiffableStringMap> customData,
574-
final ImmutableOpenIntMap<Set<String>> inSyncAllocationIds,
574+
final Map<Integer, Set<String>> inSyncAllocationIds,
575575
final DiscoveryNodeFilters requireFilters,
576576
final DiscoveryNodeFilters initialRecoveryFilters,
577577
final DiscoveryNodeFilters includeFilters,
@@ -889,7 +889,7 @@ public Map<String, String> getCustomData(final String key) {
889889
return this.customData.get(key);
890890
}
891891

892-
public ImmutableOpenIntMap<Set<String>> getInSyncAllocationIds() {
892+
public Map<Integer, Set<String>> getInSyncAllocationIds() {
893893
return inSyncAllocationIds;
894894
}
895895

@@ -1031,7 +1031,7 @@ private static class IndexMetadataDiff implements Diff<IndexMetadata> {
10311031
private final Diff<ImmutableOpenMap<String, MappingMetadata>> mappings;
10321032
private final Diff<ImmutableOpenMap<String, AliasMetadata>> aliases;
10331033
private final Diff<ImmutableOpenMap<String, DiffableStringMap>> customData;
1034-
private final Diff<ImmutableOpenIntMap<Set<String>>> inSyncAllocationIds;
1034+
private final Diff<Map<Integer, Set<String>>> inSyncAllocationIds;
10351035
private final Diff<ImmutableOpenMap<String, RolloverInfo>> rolloverInfos;
10361036
private final boolean isSystem;
10371037
private final IndexLongFieldRange timestampRange;
@@ -1095,7 +1095,7 @@ private static class IndexMetadataDiff implements Diff<IndexMetadata> {
10951095
mappings = DiffableUtils.readImmutableOpenMapDiff(in, DiffableUtils.getStringKeySerializer(), MAPPING_DIFF_VALUE_READER);
10961096
aliases = DiffableUtils.readImmutableOpenMapDiff(in, DiffableUtils.getStringKeySerializer(), ALIAS_METADATA_DIFF_VALUE_READER);
10971097
customData = DiffableUtils.readImmutableOpenMapDiff(in, DiffableUtils.getStringKeySerializer(), CUSTOM_DIFF_VALUE_READER);
1098-
inSyncAllocationIds = DiffableUtils.readImmutableOpenIntMapDiff(
1098+
inSyncAllocationIds = DiffableUtils.readJdkMapDiff(
10991099
in,
11001100
DiffableUtils.getVIntKeySerializer(),
11011101
DiffableUtils.StringSetValueSerializer.getInstance()
@@ -1153,7 +1153,7 @@ public IndexMetadata apply(IndexMetadata part) {
11531153
).get(MapperService.SINGLE_MAPPING_NAME);
11541154
builder.aliases.putAllFromMap(aliases.apply(part.aliases));
11551155
builder.customMetadata.putAllFromMap(customData.apply(part.customData));
1156-
builder.inSyncAllocationIds.putAll((Map<Integer, Set<String>>) inSyncAllocationIds.apply(part.inSyncAllocationIds));
1156+
builder.inSyncAllocationIds.putAll(inSyncAllocationIds.apply(part.inSyncAllocationIds));
11571157
builder.rolloverInfos.putAllFromMap(rolloverInfos.apply(part.rolloverInfos));
11581158
builder.system(isSystem);
11591159
builder.timestampRange(timestampRange);
@@ -1309,7 +1309,7 @@ public static class Builder {
13091309
private MappingMetadata mapping;
13101310
private final ImmutableOpenMap.Builder<String, AliasMetadata> aliases;
13111311
private final ImmutableOpenMap.Builder<String, DiffableStringMap> customMetadata;
1312-
private final ImmutableOpenIntMap.Builder<Set<String>> inSyncAllocationIds;
1312+
private final Map<Integer, Set<String>> inSyncAllocationIds;
13131313
private final ImmutableOpenMap.Builder<String, RolloverInfo> rolloverInfos;
13141314
private Integer routingNumShards;
13151315
private boolean isSystem;
@@ -1320,7 +1320,7 @@ public Builder(String index) {
13201320
this.index = index;
13211321
this.aliases = ImmutableOpenMap.builder();
13221322
this.customMetadata = ImmutableOpenMap.builder();
1323-
this.inSyncAllocationIds = ImmutableOpenIntMap.builder();
1323+
this.inSyncAllocationIds = new HashMap<>();
13241324
this.rolloverInfos = ImmutableOpenMap.builder();
13251325
this.isSystem = false;
13261326
}
@@ -1338,7 +1338,7 @@ public Builder(IndexMetadata indexMetadata) {
13381338
this.aliases = ImmutableOpenMap.builder(indexMetadata.aliases);
13391339
this.customMetadata = ImmutableOpenMap.builder(indexMetadata.customData);
13401340
this.routingNumShards = indexMetadata.routingNumShards;
1341-
this.inSyncAllocationIds = ImmutableOpenIntMap.builder(indexMetadata.inSyncAllocationIds);
1341+
this.inSyncAllocationIds = new HashMap<>(indexMetadata.inSyncAllocationIds);
13421342
this.rolloverInfos = ImmutableOpenMap.builder(indexMetadata.rolloverInfos);
13431343
this.isSystem = indexMetadata.isSystem;
13441344
this.timestampRange = indexMetadata.timestampRange;
@@ -1466,7 +1466,7 @@ public Set<String> getInSyncAllocationIds(int shardId) {
14661466
}
14671467

14681468
public Builder putInSyncAllocationIds(int shardId, Set<String> allocationIds) {
1469-
inSyncAllocationIds.put(shardId, new HashSet<>(allocationIds));
1469+
inSyncAllocationIds.put(shardId, Set.copyOf(allocationIds));
14701470
return this;
14711471
}
14721472

@@ -1595,13 +1595,11 @@ public IndexMetadata build() {
15951595
}
15961596

15971597
// fill missing slots in inSyncAllocationIds with empty set if needed and make all entries immutable
1598-
ImmutableOpenIntMap.Builder<Set<String>> filledInSyncAllocationIds = ImmutableOpenIntMap.builder();
1598+
@SuppressWarnings({ "unchecked", "rawtypes" })
1599+
Map.Entry<Integer, Set<String>> denseInSyncAllocationIds[] = new Map.Entry[numberOfShards];
15991600
for (int i = 0; i < numberOfShards; i++) {
1600-
if (inSyncAllocationIds.containsKey(i)) {
1601-
filledInSyncAllocationIds.put(i, Set.copyOf(inSyncAllocationIds.get(i)));
1602-
} else {
1603-
filledInSyncAllocationIds.put(i, Collections.emptySet());
1604-
}
1601+
Set<String> allocIds = inSyncAllocationIds.getOrDefault(i, Set.of());
1602+
denseInSyncAllocationIds[i] = Map.entry(i, allocIds);
16051603
}
16061604
var requireMap = INDEX_ROUTING_REQUIRE_GROUP_SETTING.getAsMap(settings);
16071605
final DiscoveryNodeFilters requireFilters;
@@ -1697,7 +1695,7 @@ public IndexMetadata build() {
16971695
mapping,
16981696
aliases.build(),
16991697
newCustomMetadata,
1700-
filledInSyncAllocationIds.build(),
1698+
Map.ofEntries(denseInSyncAllocationIds),
17011699
requireFilters,
17021700
initialRecoveryFilters,
17031701
includeFilters,
@@ -2019,7 +2017,7 @@ public static IndexMetadata legacyFromXContent(XContentParser parser) throws IOE
20192017
allocationIds.add(parser.text());
20202018
}
20212019
}
2022-
builder.putInSyncAllocationIds(Integer.valueOf(shardId), allocationIds);
2020+
builder.putInSyncAllocationIds(Integer.parseInt(shardId), allocationIds);
20232021
} else {
20242022
throw new IllegalArgumentException("Unexpected token: " + token);
20252023
}

0 commit comments

Comments
 (0)