Browse Source

Improve efficiency of Grok circular reference check (#74814)

This change is a tweak to #74581 which removes the N^2
loop that was added in that PR.
David Roberts 4 years ago
parent
commit
a0d26954bd
1 changed files with 10 additions and 9 deletions
  1. 10 9
      libs/grok/src/main/java/org/elasticsearch/grok/Grok.java

+ 10 - 9
libs/grok/src/main/java/org/elasticsearch/grok/Grok.java

@@ -79,11 +79,7 @@ public final class Grok {
         this.namedCaptures = namedCaptures;
         this.matcherWatchdog = matcherWatchdog;
 
-        for (Map.Entry<String, String> entry : patternBank.entrySet()) {
-            String name = entry.getKey();
-            String pattern = entry.getValue();
-            forbidCircularReferences(name, new ArrayList<>(), pattern);
-        }
+        forbidCircularReferences();
 
         String expression = toRegex(grokPattern);
         byte[] expressionBytes = expression.getBytes(StandardCharsets.UTF_8);
@@ -104,7 +100,8 @@ public final class Grok {
      * a reference to another named pattern. This method will navigate to all these named patterns and
      * check for a circular reference.
      */
-    private void forbidCircularReferences(String patternName, List<String> path, String pattern) {
+    private void forbidCircularReferences() {
+
         // first ensure that the pattern bank contains no simple circular references (i.e., any pattern
         // containing an immediate reference to itself) as those can cause the remainder of this algorithm
         // to recurse infinitely
@@ -114,8 +111,12 @@ public final class Grok {
             }
         }
 
-        // next recursively check any other pattern names referenced in the pattern
-        innerForbidCircularReferences(patternName, path, pattern);
+        // next, recursively check any other pattern names referenced in each pattern
+        for (Map.Entry<String, String> entry : patternBank.entrySet()) {
+            String name = entry.getKey();
+            String pattern = entry.getValue();
+            innerForbidCircularReferences(name, new ArrayList<>(), pattern);
+        }
     }
 
     private void innerForbidCircularReferences(String patternName, List<String> path, String pattern) {
@@ -151,7 +152,7 @@ public final class Grok {
             }
             String otherPatternName = pattern.substring(begin, end);
             path.add(otherPatternName);
-            forbidCircularReferences(patternName, path, patternBank.get(otherPatternName));
+            innerForbidCircularReferences(patternName, path, patternBank.get(otherPatternName));
         }
     }