Skip to content

Commit

Permalink
Improve efficiency of Grok circular reference check (elastic#74814)
Browse files Browse the repository at this point in the history
This change is a tweak to elastic#74581 which removes the N^2
loop that was added in that PR.
  • Loading branch information
droberts195 authored and danhermann committed Jul 1, 2021
1 parent c6d7d58 commit cf65a08
Showing 1 changed file with 10 additions and 9 deletions.
19 changes: 10 additions & 9 deletions libs/grok/src/main/java/org/elasticsearch/grok/Grok.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,7 @@ private Grok(Map<String, String> patternBank, String grokPattern, boolean namedC
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);
Expand All @@ -107,7 +103,8 @@ private Grok(Map<String, String> 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<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
Expand All @@ -117,8 +114,12 @@ private void forbidCircularReferences(String patternName, List<String> 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<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) {
Expand Down Expand Up @@ -154,7 +155,7 @@ private void innerForbidCircularReferences(String patternName, List<String> path
}
String otherPatternName = pattern.substring(begin, end);
path.add(otherPatternName);
forbidCircularReferences(patternName, path, patternBank.get(otherPatternName));
innerForbidCircularReferences(patternName, path, patternBank.get(otherPatternName));
}
}

Expand Down

0 comments on commit cf65a08

Please sign in to comment.