瀏覽代碼

Security: improve exact index matching performance (#36017)

This commit improves the efficiency of exact index name matching by
separating exact matches from those that include wildcards or regular
expressions. Internally, exact matching is done using a HashSet instead
of adding the exact matches to the automata. For the wildcard and
regular expression matches, the underlying implementation has not
changed.
Jay Modi 6 年之前
父節點
當前提交
ba3ee98943

+ 30 - 0
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/IndicesPermission.java

@@ -64,6 +64,36 @@ public final class IndicesPermission implements Iterable<IndicesPermission.Group
     }
 
     static Predicate<String> indexMatcher(List<String> indices) {
+        Set<String> exactMatch = new HashSet<>();
+        List<String> nonExactMatch = new ArrayList<>();
+        for (String indexPattern : indices) {
+            if (indexPattern.startsWith("/") || indexPattern.contains("*") || indexPattern.contains("?")) {
+                nonExactMatch.add(indexPattern);
+            } else {
+                exactMatch.add(indexPattern);
+            }
+        }
+
+        if (exactMatch.isEmpty() && nonExactMatch.isEmpty()) {
+            return s -> false;
+        } else if (exactMatch.isEmpty()) {
+            return buildAutomataPredicate(nonExactMatch);
+        } else if (nonExactMatch.isEmpty()) {
+            return buildExactMatchPredicate(exactMatch);
+        } else {
+            return buildExactMatchPredicate(exactMatch).or(buildAutomataPredicate(nonExactMatch));
+        }
+    }
+
+    private static Predicate<String> buildExactMatchPredicate(Set<String> indices) {
+        if (indices.size() == 1) {
+            final String singleValue = indices.iterator().next();
+            return singleValue::equals;
+        }
+        return indices::contains;
+    }
+
+    private static Predicate<String> buildAutomataPredicate(List<String> indices) {
         try {
             return Automatons.predicate(indices);
         } catch (TooComplexToDeterminizeException e) {