Skip to content

Commit 7f501a5

Browse files
authored
Add a faster path for single default project retrieving (elastic#123662)
This PR makes single default project retrieving faster by using a single element map instead of a regular hash map.
1 parent 2a17df5 commit 7f501a5

File tree

1 file changed

+23
-9
lines changed
  • server/src/main/java/org/elasticsearch/cluster/metadata

1 file changed

+23
-9
lines changed

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

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import org.elasticsearch.common.xcontent.ChunkedToXContent;
3737
import org.elasticsearch.common.xcontent.ChunkedToXContentHelper;
3838
import org.elasticsearch.common.xcontent.XContentParserUtils;
39-
import org.elasticsearch.core.Assertions;
4039
import org.elasticsearch.core.FixForMultiProject;
4140
import org.elasticsearch.core.Nullable;
4241
import org.elasticsearch.core.Tuple;
@@ -1662,19 +1661,12 @@ public Metadata build() {
16621661
}
16631662

16641663
public Metadata build(boolean skipNameCollisionChecks) {
1665-
if (projectMetadata.isEmpty()) {
1666-
createDefaultProject();
1667-
} else if (Assertions.ENABLED) {
1668-
projectMetadata.forEach((id, project) -> {
1669-
assert project.getId().equals(id) : "project id mismatch key=[" + id + "] builder=[" + project.getId() + "]";
1670-
});
1671-
}
16721664
return new Metadata(
16731665
clusterUUID,
16741666
clusterUUIDCommitted,
16751667
version,
16761668
coordinationMetadata,
1677-
Collections.unmodifiableMap(Maps.transformValues(projectMetadata, m -> m.build(skipNameCollisionChecks))),
1669+
buildProjectMetadata(skipNameCollisionChecks),
16781670
transientSettings,
16791671
persistentSettings,
16801672
Settings.builder().put(persistentSettings).put(transientSettings).build(),
@@ -1684,10 +1676,32 @@ public Metadata build(boolean skipNameCollisionChecks) {
16841676
);
16851677
}
16861678

1679+
private Map<ProjectId, ProjectMetadata> buildProjectMetadata(boolean skipNameCollisionChecks) {
1680+
if (projectMetadata.isEmpty()) {
1681+
createDefaultProject();
1682+
}
1683+
assert assertProjectIdAndProjectMetadataConsistency();
1684+
if (projectMetadata.size() == 1) {
1685+
final var entry = projectMetadata.entrySet().iterator().next();
1686+
// Map.of() with a single entry is highly optimized
1687+
// so we want take advantage of that performance boost for this common case of a single project
1688+
return Map.of(entry.getKey(), entry.getValue().build(skipNameCollisionChecks));
1689+
} else {
1690+
return Collections.unmodifiableMap(Maps.transformValues(projectMetadata, m -> m.build(skipNameCollisionChecks)));
1691+
}
1692+
}
1693+
16871694
private ProjectMetadata.Builder createDefaultProject() {
16881695
return projectMetadata.put(DEFAULT_PROJECT_ID, new ProjectMetadata.Builder(Map.of(), 0).id(DEFAULT_PROJECT_ID));
16891696
}
16901697

1698+
private boolean assertProjectIdAndProjectMetadataConsistency() {
1699+
projectMetadata.forEach((id, project) -> {
1700+
assert project.getId().equals(id) : "project id mismatch key=[" + id + "] builder=[" + project.getId() + "]";
1701+
});
1702+
return true;
1703+
}
1704+
16911705
/**
16921706
* There are a set of specific custom sections that have moved from top-level sections to project-level sections
16931707
* as part of the multi-project refactor. Enumerate them here so we can move them to the right place

0 commit comments

Comments
 (0)