From a0d26954bd93b46261d36f194dcbfb7635b40dde Mon Sep 17 00:00:00 2001 From: David Roberts Date: Thu, 1 Jul 2021 14:30:03 +0100 Subject: [PATCH] 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. --- .../java/org/elasticsearch/grok/Grok.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/libs/grok/src/main/java/org/elasticsearch/grok/Grok.java b/libs/grok/src/main/java/org/elasticsearch/grok/Grok.java index 109fd1c0ed145..625a8b3536283 100644 --- a/libs/grok/src/main/java/org/elasticsearch/grok/Grok.java +++ b/libs/grok/src/main/java/org/elasticsearch/grok/Grok.java @@ -79,11 +79,7 @@ private Grok(Map patternBank, String grokPattern, boolean namedC this.namedCaptures = namedCaptures; this.matcherWatchdog = matcherWatchdog; - for (Map.Entry 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 @@ private Grok(Map patternBank, String grokPattern, boolean namedC * 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 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 @@ private void forbidCircularReferences(String patternName, List path, Str } } - // 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 entry : patternBank.entrySet()) { + String name = entry.getKey(); + String pattern = entry.getValue(); + innerForbidCircularReferences(name, new ArrayList<>(), pattern); + } } private void innerForbidCircularReferences(String patternName, List path, String pattern) { @@ -151,7 +152,7 @@ private void innerForbidCircularReferences(String patternName, List path } String otherPatternName = pattern.substring(begin, end); path.add(otherPatternName); - forbidCircularReferences(patternName, path, patternBank.get(otherPatternName)); + innerForbidCircularReferences(patternName, path, patternBank.get(otherPatternName)); } }