This is an automated email from the ASF dual-hosted git repository. andy pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/jena.git
commit 6d7e0f0c6f5627b69bd846d07165e133871e6da5 Author: Andy Seaborne <[email protected]> AuthorDate: Sun Aug 24 20:53:03 2025 +0100 GH-3395: Calculate-once Expr.getVarsMentioned --- .../main/java/org/apache/jena/sparql/expr/ExprNode.java | 16 +++++++++++++++- .../main/java/org/apache/jena/sparql/expr/ExprNone.java | 8 ++++++++ .../main/java/org/apache/jena/sparql/expr/ExprVar.java | 8 +++++++- .../main/java/org/apache/jena/sparql/expr/ExprVars.java | 14 ++++++++++++++ .../main/java/org/apache/jena/sparql/expr/NodeValue.java | 7 +++++++ 5 files changed, 51 insertions(+), 2 deletions(-) diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprNode.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprNode.java index d365ca3a28..949d458b0b 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprNode.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprNode.java @@ -36,6 +36,10 @@ import org.apache.jena.sparql.sse.writers.WriterExpr; public abstract class ExprNode implements Expr { + private Set<Var> varsMentioned = null; + + protected ExprNode() {} + @Override public boolean isSatisfied(Binding binding, FunctionEnv funcEnv) { try { @@ -60,9 +64,19 @@ public abstract class ExprNode implements Expr @Override public abstract NodeValue eval(Binding binding, FunctionEnv env); + // Theer are some overrides of this method for simple cases including + // NodeValue ( = "ExprConstant") + // ExprVar @Override public Set<Var> getVarsMentioned() { - return ExprVars.getVarsMentioned(this); + // Calculate once, delayed until first use. + if ( varsMentioned == null ) { + synchronized(this) { + if ( varsMentioned == null ) + varsMentioned = ExprVars.getVarsMentioned(this); + } + } + return varsMentioned; } @Override diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprNone.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprNone.java index c5b6a2323c..7a44baffd8 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprNone.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprNone.java @@ -18,7 +18,10 @@ package org.apache.jena.sparql.expr; +import java.util.Set; + import org.apache.jena.atlas.lib.InternalErrorException ; +import org.apache.jena.sparql.core.Var; import org.apache.jena.sparql.engine.binding.Binding ; import org.apache.jena.sparql.function.FunctionEnv ; import org.apache.jena.sparql.graph.NodeTransform ; @@ -37,6 +40,11 @@ public class ExprNone extends ExprNode { throw new InternalErrorException("Attempt to eval ExprNone") ; } + @Override + public Set<Var> getVarsMentioned() { + return Set.of(); + } + @Override public int hashCode() { return -999999 ; diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprVar.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprVar.java index dec63dc6e2..1acbbf6bc4 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprVar.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprVar.java @@ -18,6 +18,8 @@ package org.apache.jena.sparql.expr; +import java.util.Set; + import org.apache.jena.atlas.io.IndentedWriter; import org.apache.jena.graph.Node; import org.apache.jena.query.Query; @@ -31,7 +33,6 @@ import org.apache.jena.sparql.graph.NodeTransform; public class ExprVar extends ExprNode { - // AKA ExprFunction0 protected final Var varNode; public ExprVar(String name) { varNode = Var.alloc(name); } @@ -46,6 +47,11 @@ public class ExprVar extends ExprNode varNode = v; } + @Override + public Set<Var> getVarsMentioned() { + return Set.of(varNode); + } + @Override public NodeValue eval(Binding binding, FunctionEnv env) { return eval(varNode, binding, env); diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprVars.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprVars.java index a504d330cf..d7c3ed4ba2 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprVars.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprVars.java @@ -37,6 +37,11 @@ public class ExprVars // Collect variables / ExprList public static Set<Var> getVarsMentioned(Expr expr) { + // Short cut some simple cases. + if ( expr instanceof NodeValue ) + return Set.of(); + if ( expr instanceof Var nVar ) + return Set.of(nVar); Set<Var> acc = new HashSet<>(); varsMentioned(acc, expr); return acc; @@ -51,6 +56,15 @@ public class ExprVars private static Action<Var> accVar = (a, var) -> a.add(var) ; public static void varsMentioned(Collection<Var> acc, Expr expr) { + //Java21 - switch + type pattern + // Short cut some simple cases. + if ( expr instanceof NodeValue ) + return; + if ( expr instanceof Var nVar ) { + acc.add(nVar); + } + + ExprVarsWorker<Var> vv = new ExprVarsWorker<>(acc, accVar) ; Walker.walk(expr, vv) ; } diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java index 47d0d5df54..3384d93d6e 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java @@ -26,6 +26,7 @@ import static org.apache.jena.sparql.expr.ValueSpace.VSPACE_UNKNOWN; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Calendar; +import java.util.Set; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.Duration; @@ -44,6 +45,7 @@ import org.apache.jena.graph.TextDirection; import org.apache.jena.graph.impl.LiteralLabel; import org.apache.jena.sparql.ARQInternalErrorException; import org.apache.jena.sparql.SystemARQ; +import org.apache.jena.sparql.core.Var; import org.apache.jena.sparql.engine.ExecutionContext; import org.apache.jena.sparql.engine.binding.Binding; import org.apache.jena.sparql.expr.nodevalue.*; @@ -148,6 +150,11 @@ public abstract class NodeValue extends ExprNode protected NodeValue() { super(); } protected NodeValue(Node n) { super(); node = n; } + @Override + public Set<Var> getVarsMentioned() { + return Set.of(); + } + // protected makeNodeValue(NodeValue nv) // { // if ( v.isNode() ) { ... }
