From e62e27699253c9d0e00fd9f66d51f39a82de78a4 Mon Sep 17 00:00:00 2001 From: Sidhant Aggarwal <10743214+sidhant92@users.noreply.github.com> Date: Thu, 9 Feb 2023 00:25:51 +0530 Subject: [PATCH] add caching option --- build.gradle | 1 + .../parser/BoolExpressionParser.java | 2 ++ .../boolparser/parser/antlr/BoolParser.java | 31 +++++++++++++++++-- .../antlr/BooleanFilterBoolParserTest.java | 4 +-- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index a6fb869..6f9eb99 100644 --- a/build.gradle +++ b/build.gradle @@ -40,6 +40,7 @@ dependencies { implementation 'org.apache.maven:maven-artifact:3.5.2' implementation 'org.antlr:antlr4-runtime:4.11.1' implementation 'io.vavr:vavr:0.10.4' + implementation 'com.github.ben-manes.caffeine:caffeine:2.9.3' compileOnly 'org.projectlombok:lombok:1.18.26' annotationProcessor 'org.projectlombok:lombok:1.18.26' diff --git a/src/main/java/com/github/sidhant92/boolparser/parser/BoolExpressionParser.java b/src/main/java/com/github/sidhant92/boolparser/parser/BoolExpressionParser.java index 77e563f..c8ba1fa 100644 --- a/src/main/java/com/github/sidhant92/boolparser/parser/BoolExpressionParser.java +++ b/src/main/java/com/github/sidhant92/boolparser/parser/BoolExpressionParser.java @@ -9,4 +9,6 @@ */ public interface BoolExpressionParser { Try parseExpression(final String expression); + + Try parseExpression(final String expression, final boolean useCache, final int maxCacheSize); } diff --git a/src/main/java/com/github/sidhant92/boolparser/parser/antlr/BoolParser.java b/src/main/java/com/github/sidhant92/boolparser/parser/antlr/BoolParser.java index 89e0a66..e21a167 100644 --- a/src/main/java/com/github/sidhant92/boolparser/parser/antlr/BoolParser.java +++ b/src/main/java/com/github/sidhant92/boolparser/parser/antlr/BoolParser.java @@ -3,25 +3,52 @@ import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTreeWalker; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; import com.github.sidhant92.boolparser.domain.Token; import com.github.sidhant92.boolparser.parser.BoolExpressionParser; import io.vavr.control.Try; public class BoolParser implements BoolExpressionParser { + private boolean useCache; + + private Cache cache; + + private final ParseTreeWalker parseTreeWalker = new ParseTreeWalker(); + + private final BooleanFilterListener listener = new BooleanFilterListener(); + + private static final int MAX_CACHE_SIZE = 500; + @Override public Try parseExpression(final String expression) { + return parseExpression(expression, false, MAX_CACHE_SIZE); + } + + @Override + public Try parseExpression(final String expression, final boolean useCache, final int maxCacheSize) { + this.useCache = useCache; + if (useCache) { + this.cache = Caffeine.newBuilder().maximumSize(maxCacheSize).build(); + } return Try.of(() -> getNode(expression)); } private Token getNode(final String expression) { + if (useCache) { + return cache.get(expression, this::parse); + } + return parse(expression); + } + + private Token parse(final String expression) { BooleanExpressionLexer filterLexer = new BooleanExpressionLexer(CharStreams.fromString(expression)); CommonTokenStream commonTokenStream = new CommonTokenStream(filterLexer); BooleanExpressionParser filterParser = new BooleanExpressionParser(commonTokenStream); BooleanExpressionParser.ParseContext filterContext = filterParser.parse(); - ParseTreeWalker parseTreeWalker = new ParseTreeWalker(); - final BooleanFilterListener listener = new BooleanFilterListener(); parseTreeWalker.walk(listener, filterContext); + return listener.getNode(); } } diff --git a/src/test/java/com/github/sidhant92/boolparser/parser/antlr/BooleanFilterBoolParserTest.java b/src/test/java/com/github/sidhant92/boolparser/parser/antlr/BooleanFilterBoolParserTest.java index 85f0054..76ba452 100644 --- a/src/test/java/com/github/sidhant92/boolparser/parser/antlr/BooleanFilterBoolParserTest.java +++ b/src/test/java/com/github/sidhant92/boolparser/parser/antlr/BooleanFilterBoolParserTest.java @@ -104,7 +104,7 @@ public void testSingleDecimalToken() { @Test public void testSingleIntRangeToken() { - final Try nodeOptional = boolExpressionBoolParser.parseExpression("age: 18 TO 44"); + final Try nodeOptional = boolExpressionBoolParser.parseExpression("age 18 TO 44"); assertTrue(nodeOptional.isSuccess()); assertEquals(nodeOptional.get().getTokenType().name(), TokenType.NUMERIC_RANGE.name()); verifyNumericRangeToken((NumericRangeToken) nodeOptional.get(), "age", 18, 44); @@ -120,7 +120,7 @@ public void testGreaterThan() { @Test public void testSingleDecimalRangeToken() { - final Try nodeOptional = boolExpressionBoolParser.parseExpression("age: 18.4 TO 44.2"); + final Try nodeOptional = boolExpressionBoolParser.parseExpression("age 18.4 TO 44.2"); assertTrue(nodeOptional.isSuccess()); assertEquals(nodeOptional.get().getTokenType().name(), TokenType.NUMERIC_RANGE.name()); verifyNumericRangeToken((NumericRangeToken) nodeOptional.get(), "age", 18.4, 44.2);