From 5fdf6b76dcdca51b9be3f04b61a099cc8820a3fb Mon Sep 17 00:00:00 2001 From: Edgar <17509127+nstdio@users.noreply.github.com> Date: Fri, 24 Jan 2025 22:59:39 +0400 Subject: [PATCH] Optimize logical nodes visit methods. (#166) This commit provides memory optimization when visiting `LogicalNode`'s children. Old implementation was invoking `LogicalNode#getChildren` which makes shallow copy of its children nodes to only iterate over it we can use the fact that `LogicalNode` is in fact `java.lang.Iterable` and use enhanced for loop to iterate over it. Using it that way is more memory efficient and does not involve shallow copying because iterator returned by `LogicalNode` is unmodifiable. --- .../rsql/RSQLJPAPredicateConverter.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/RSQLJPAPredicateConverter.java b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/RSQLJPAPredicateConverter.java index be21a17..93d7aef 100644 --- a/rsql-jpa/src/main/java/io/github/perplexhub/rsql/RSQLJPAPredicateConverter.java +++ b/rsql-jpa/src/main/java/io/github/perplexhub/rsql/RSQLJPAPredicateConverter.java @@ -2,7 +2,9 @@ import static io.github.perplexhub.rsql.RSQLOperators.*; +import cz.jirutka.rsql.parser.ast.LogicalNode; import java.util.*; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; @@ -429,14 +431,24 @@ private Predicate equalPredicate(Expression expr, Class type, Object argument) { @Override public Predicate visit(AndNode node, From root) { log.debug("visit(node:{},root:{})", node, root); - - return node.getChildren().stream().map(n -> n.accept(this, root)).collect(Collectors.reducing(builder::and)).get(); + return visitChildren(node, root, builder::and); } @Override public Predicate visit(OrNode node, From root) { log.debug("visit(node:{},root:{})", node, root); + return visitChildren(node, root, builder::or); + } + + private Predicate visitChildren(LogicalNode node, From root, BiFunction reducer) { + Predicate result = null; + + for (var child : node) { + result = result != null + ? reducer.apply(result, child.accept(this, root)) + : child.accept(this, root); + } - return node.getChildren().stream().map(n -> n.accept(this, root)).collect(Collectors.reducing(builder::or)).get(); + return result; } }