From cf65a089713d6aa30709e03a7eb6728de8eae640 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 c0ff4ac57a1f5..1f0441da9db43 100644 --- a/libs/grok/src/main/java/org/elasticsearch/grok/Grok.java +++ b/libs/grok/src/main/java/org/elasticsearch/grok/Grok.java @@ -82,11 +82,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); @@ -107,7 +103,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 @@ -117,8 +114,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) { @@ -154,7 +155,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)); } }