Skip to content

Commit 3194129

Browse files
committed
add caching option
2 parents e62e276 + f1825e9 commit 3194129

File tree

8 files changed

+189
-16
lines changed

8 files changed

+189
-16
lines changed

build.gradle

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ repositories {
3131
}
3232

3333
dependencies {
34-
testImplementation group: 'junit', name: 'junit', version: '4.12'
35-
3634
implementation 'ch.qos.logback:logback-classic:1.2.3'
3735
implementation 'ch.qos.logback.contrib:logback-json-classic:0.1.5'
3836
implementation 'ch.qos.logback.contrib:logback-jackson:0.1.5'
@@ -41,14 +39,18 @@ dependencies {
4139
implementation 'org.antlr:antlr4-runtime:4.11.1'
4240
implementation 'io.vavr:vavr:0.10.4'
4341
implementation 'com.github.ben-manes.caffeine:caffeine:2.9.3'
42+
implementation 'org.projectlombok:lombok:1.18.26'
4443

45-
compileOnly 'org.projectlombok:lombok:1.18.26'
4644
annotationProcessor 'org.projectlombok:lombok:1.18.26'
45+
testAnnotationProcessor 'org.openjdk.jmh:jmh-generator-annprocess:1.36'
4746

47+
testImplementation 'org.openjdk.jmh:jmh-core:1.35'
48+
testImplementation 'org.openjdk.jmh:jmh-generator-annprocess:1.35'
4849
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.4.2'
4950
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.4.2'
5051
testImplementation group: 'org.mockito', name: 'mockito-junit-jupiter', version: '3.3.3'
5152
testImplementation group: 'org.mock-server', name: 'mockserver-junit-jupiter', version: '5.10.0'
53+
testImplementation group: 'junit', name: 'junit', version: '4.12'
5254
}
5355

5456
test {

src/main/java/com/github/sidhant92/boolparser/parser/BoolExpressionParser.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,4 @@
99
*/
1010
public interface BoolExpressionParser {
1111
Try<Token> parseExpression(final String expression);
12-
13-
Try<Token> parseExpression(final String expression, final boolean useCache, final int maxCacheSize);
1412
}

src/main/java/com/github/sidhant92/boolparser/parser/antlr/BoolParser.java

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,16 @@ public class BoolParser implements BoolExpressionParser {
1616

1717
private final ParseTreeWalker parseTreeWalker = new ParseTreeWalker();
1818

19-
private final BooleanFilterListener listener = new BooleanFilterListener();
20-
21-
private static final int MAX_CACHE_SIZE = 500;
19+
public BoolParser() {
20+
}
2221

23-
@Override
24-
public Try<Token> parseExpression(final String expression) {
25-
return parseExpression(expression, false, MAX_CACHE_SIZE);
22+
public BoolParser(final int maxCacheSize) {
23+
this.useCache = true;
24+
this.cache = Caffeine.newBuilder().maximumSize(maxCacheSize).build();
2625
}
2726

2827
@Override
29-
public Try<Token> parseExpression(final String expression, final boolean useCache, final int maxCacheSize) {
30-
this.useCache = useCache;
31-
if (useCache) {
32-
this.cache = Caffeine.newBuilder().maximumSize(maxCacheSize).build();
33-
}
28+
public Try<Token> parseExpression(final String expression) {
3429
return Try.of(() -> getNode(expression));
3530
}
3631

@@ -47,6 +42,7 @@ private Token parse(final String expression) {
4742
BooleanExpressionParser filterParser = new BooleanExpressionParser(commonTokenStream);
4843
BooleanExpressionParser.ParseContext filterContext = filterParser.parse();
4944

45+
final BooleanFilterListener listener = new BooleanFilterListener();
5046
parseTreeWalker.walk(listener, filterContext);
5147

5248
return listener.getNode();
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.github.sidhant92.boolparser.parser.antlr.benchmark;
2+
3+
import java.io.IOException;
4+
import java.util.Map;
5+
import java.util.concurrent.TimeUnit;
6+
import org.openjdk.jmh.annotations.Benchmark;
7+
import org.openjdk.jmh.annotations.BenchmarkMode;
8+
import org.openjdk.jmh.annotations.Mode;
9+
import org.openjdk.jmh.annotations.OutputTimeUnit;
10+
import org.openjdk.jmh.annotations.Scope;
11+
import org.openjdk.jmh.annotations.Setup;
12+
import org.openjdk.jmh.annotations.State;
13+
import org.openjdk.jmh.annotations.Warmup;
14+
import org.openjdk.jmh.runner.Runner;
15+
import org.openjdk.jmh.runner.RunnerException;
16+
import org.openjdk.jmh.runner.options.Options;
17+
import org.openjdk.jmh.runner.options.OptionsBuilder;
18+
import com.github.sidhant92.boolparser.application.BooleanExpressionEvaluator;
19+
import com.github.sidhant92.boolparser.parser.antlr.BoolParser;
20+
import com.github.sidhant92.boolparser.provider.BoolParserDataProvider;
21+
import lombok.SneakyThrows;
22+
23+
/**
24+
* @author Het Shah
25+
* @since 08/02/2023
26+
*/
27+
@State (Scope.Benchmark)
28+
@OutputTimeUnit (TimeUnit.MICROSECONDS)
29+
public class EvaluationBenchmarkService {
30+
private static Map<String, Object> data;
31+
32+
private static BoolParser parser;
33+
34+
private static BooleanExpressionEvaluator evaluator;
35+
36+
public static void main(String[] args) throws RunnerException, IOException {
37+
38+
Options opt = new OptionsBuilder()
39+
.include(EvaluationBenchmarkService.class.getSimpleName())
40+
.forks(1)
41+
.build();
42+
new Runner(opt).run();
43+
}
44+
45+
@SneakyThrows
46+
@Setup
47+
public void setup() {
48+
data = BoolParserDataProvider.getData();
49+
parser = new BoolParser();
50+
evaluator = new BooleanExpressionEvaluator(parser);
51+
}
52+
53+
@Benchmark
54+
@Warmup(iterations = 2)
55+
@BenchmarkMode (Mode.SampleTime) //change here to check for specific mode
56+
public void benchmarkEvaluation() {
57+
final String rule = "b>0 AND z IN ('c1', 'c2')";
58+
evaluator.evaluate(rule, data);
59+
}
60+
61+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.github.sidhant92.boolparser.parser.antlr.benchmark;
2+
3+
import java.io.IOException;
4+
import java.util.Map;
5+
import java.util.concurrent.TimeUnit;
6+
import org.openjdk.jmh.annotations.Benchmark;
7+
import org.openjdk.jmh.annotations.BenchmarkMode;
8+
import org.openjdk.jmh.annotations.Mode;
9+
import org.openjdk.jmh.annotations.OutputTimeUnit;
10+
import org.openjdk.jmh.annotations.Scope;
11+
import org.openjdk.jmh.annotations.Setup;
12+
import org.openjdk.jmh.annotations.State;
13+
import org.openjdk.jmh.annotations.Warmup;
14+
import org.openjdk.jmh.runner.Runner;
15+
import org.openjdk.jmh.runner.RunnerException;
16+
import org.openjdk.jmh.runner.options.Options;
17+
import org.openjdk.jmh.runner.options.OptionsBuilder;
18+
import com.github.sidhant92.boolparser.parser.antlr.BoolParser;
19+
import com.github.sidhant92.boolparser.provider.BoolParserDataProvider;
20+
import lombok.SneakyThrows;
21+
22+
/**
23+
* @author Het Shah
24+
* @since 09/02/2023
25+
*/
26+
@State (Scope.Benchmark)
27+
@OutputTimeUnit (TimeUnit.MICROSECONDS)
28+
public class ParserBenchmarkService {
29+
private static Map<String, Object> data;
30+
31+
private static BoolParser parser;
32+
33+
34+
public static void main(String[] args) throws RunnerException, IOException {
35+
Options opt = new OptionsBuilder().include(ParserBenchmarkService.class.getSimpleName()).forks(1).build();
36+
new Runner(opt).run();
37+
}
38+
39+
@SneakyThrows
40+
@Setup
41+
public void setup() {
42+
data = BoolParserDataProvider.getData();
43+
parser = new BoolParser();
44+
}
45+
46+
@Benchmark
47+
@Warmup (iterations = 2)
48+
@BenchmarkMode (Mode.SampleTime) //change here to check for specific mode
49+
public void benchmarkEvaluation() {
50+
final String rule = "b>0 AND z IN ('c1', 'c2')";
51+
parser.parseExpression(rule);
52+
}
53+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.github.sidhant92.boolparser.provider;
2+
3+
import java.io.File;
4+
import java.util.Map;
5+
import com.fasterxml.jackson.core.type.TypeReference;
6+
import com.fasterxml.jackson.databind.ObjectMapper;
7+
import io.vavr.control.Try;
8+
9+
/**
10+
* @author Het Shah
11+
* @since 08/02/2023
12+
*/
13+
public class BoolParserDataProvider {
14+
public static Map<String, Object> getData() {
15+
final ObjectMapper objectMapper = CommonsDataProvider.getObjectMapper();
16+
return Try.of(() -> objectMapper.readValue(new File("src/test/resources/data.json"), new TypeReference<Map<String, Object>>() {}))
17+
.getOrElseGet(ex -> null);
18+
}
19+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.github.sidhant92.boolparser.provider;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
5+
6+
/**
7+
* @author Het Shah
8+
* @since 08/02/2023
9+
*/
10+
public class CommonsDataProvider {
11+
public static ObjectMapper getObjectMapper() {
12+
return new ObjectMapper().setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
13+
}
14+
}

src/test/resources/data.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"b":1,
3+
"c":{
4+
"d":[
5+
"x",
6+
"y"
7+
],
8+
"e":"xyz"
9+
},
10+
"f":{
11+
"g":[
12+
"arr1",
13+
"arr2"
14+
],
15+
"h":{
16+
"a":"b",
17+
"c":"d",
18+
"e":true
19+
},
20+
"j":24
21+
},
22+
"x":[
23+
"a1",
24+
"a2",
25+
"a3",
26+
"a4"
27+
],
28+
"y":24,
29+
"z":"c1"
30+
}

0 commit comments

Comments
 (0)