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() )    { ... }

Reply via email to