From 206f6a2512f2ca690999b77a5c759ab214536b82 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 8db8442569744..cfd1f0876822e 100644 --- a/libs/grok/src/main/java/org/elasticsearch/grok/Grok.java +++ b/libs/grok/src/main/java/org/elasticsearch/grok/Grok.java @@ -95,11 +95,7 @@ private Grok(Map patternBank, String grokPattern, boolean namedC this.namedCaptures = namedCaptures; this.threadWatchdog = threadWatchdog; - 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); @@ -113,7 +109,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 @@ -123,8 +120,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) { @@ -160,7 +161,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)); } }