Browse Source

Speed up MappingStats (#79576)

Some trivial fixes to the mapping stats performance:

No need to parse the map out of the mapping source twice
(given that parsing the map is often most of the runtime of this method this gives a significant speedup).
Also, no need to look up from the map in a hot loop, just using the entry-set is a lot faster (especially considering
we're working with a  linked hash map here).

relates #79563
Armin Braun 4 years ago
parent
commit
8191dc77f3

+ 3 - 2
server/src/main/java/org/elasticsearch/action/admin/cluster/stats/MappingStats.java

@@ -59,7 +59,8 @@ public final class MappingStats implements ToXContentFragment, Writeable {
             Set<String> indexRuntimeFieldTypes = new HashSet<>();
             MappingMetadata mappingMetadata = indexMetadata.mapping();
             if (mappingMetadata != null) {
-                MappingVisitor.visitMapping(mappingMetadata.getSourceAsMap(), (field, fieldMapping) -> {
+                final Map<String, Object> map = mappingMetadata.getSourceAsMap();
+                MappingVisitor.visitMapping(map, (field, fieldMapping) -> {
                     concreteFieldNames.add(field);
                     String type = null;
                     Object typeO = fieldMapping.get("type");
@@ -88,7 +89,7 @@ public final class MappingStats implements ToXContentFragment, Writeable {
                     }
                 });
 
-                MappingVisitor.visitRuntimeMapping(mappingMetadata.getSourceAsMap(), (field, fieldMapping) -> {
+                MappingVisitor.visitRuntimeMapping(map, (field, fieldMapping) -> {
                     Object typeObject = fieldMapping.get("type");
                     if (typeObject == null) {
                         return;

+ 14 - 11
server/src/main/java/org/elasticsearch/action/admin/cluster/stats/MappingVisitor.java

@@ -19,31 +19,34 @@ public final class MappingVisitor {
         visitMapping(mapping, "", fieldMappingConsumer);
     }
 
-    private static void visitMapping(Map<String, ?> mapping, String path, BiConsumer<String, Map<String, ?>> fieldMappingConsumer) {
+    private static void visitMapping(final Map<String, ?> mapping,
+                                     final String path,
+                                     final BiConsumer<String, Map<String, ?>> fieldMappingConsumer) {
         Object properties = mapping.get("properties");
         if (properties instanceof Map) {
             @SuppressWarnings("unchecked")
             Map<String, ?> propertiesAsMap = (Map<String, ?>) properties;
-            for (String field : propertiesAsMap.keySet()) {
-                Object v = propertiesAsMap.get(field);
+            for (Map.Entry<String, ?> entry : propertiesAsMap.entrySet()) {
+                final Object v = entry.getValue();
                 if (v instanceof Map) {
 
                     @SuppressWarnings("unchecked")
                     Map<String, ?> fieldMapping = (Map<String, ?>) v;
-                    fieldMappingConsumer.accept(path + field, fieldMapping);
-                    visitMapping(fieldMapping, path + field + ".", fieldMappingConsumer);
+                    final String prefix = path + entry.getKey();
+                    fieldMappingConsumer.accept(prefix, fieldMapping);
+                    visitMapping(fieldMapping, prefix + ".", fieldMappingConsumer);
 
                     // Multi fields
                     Object fieldsO = fieldMapping.get("fields");
                     if (fieldsO instanceof Map) {
                         @SuppressWarnings("unchecked")
                         Map<String, ?> fields = (Map<String, ?>) fieldsO;
-                        for (String subfield : fields.keySet()) {
-                            Object v2 = fields.get(subfield);
+                        for (Map.Entry<String, ?> subfieldEntry : fields.entrySet()) {
+                            Object v2 = subfieldEntry.getValue();
                             if (v2 instanceof Map) {
                                 @SuppressWarnings("unchecked")
                                 Map<String, ?> fieldMapping2 = (Map<String, ?>) v2;
-                                fieldMappingConsumer.accept(path + field + "." + subfield, fieldMapping2);
+                                fieldMappingConsumer.accept(prefix + "." + subfieldEntry.getKey(), fieldMapping2);
                             }
                         }
                     }
@@ -59,14 +62,14 @@ public final class MappingVisitor {
         }
         @SuppressWarnings("unchecked")
         Map<String, ?> runtimeMappings = (Map<String, ?>) runtimeObject;
-        for (String runtimeFieldName : runtimeMappings.keySet()) {
-            Object runtimeFieldMappingObject = runtimeMappings.get(runtimeFieldName);
+        for (Map.Entry<String, ?> entry : runtimeMappings.entrySet()) {
+            final Object runtimeFieldMappingObject = entry.getValue();
             if (runtimeFieldMappingObject instanceof Map == false) {
                 continue;
             }
             @SuppressWarnings("unchecked")
             Map<String, ?> runtimeFieldMapping = (Map<String, ?>) runtimeFieldMappingObject;
-            runtimeFieldMappingConsumer.accept(runtimeFieldName, runtimeFieldMapping);
+            runtimeFieldMappingConsumer.accept(entry.getKey(), runtimeFieldMapping);
         }
     }
 }