You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2014/05/24 23:30:03 UTC
svn commit: r1597358 - in /jena/trunk/jena-arq: ReleaseNotes.txt
src/main/java/com/hp/hpl/jena/sparql/path/eval/PathEngine.java
Author: andy
Date: Sat May 24 21:30:02 2014
New Revision: 1597358
URL: http://svn.apache.org/r1597358
Log:
JENA-631 -- general property functions possible in a property path.
Modified:
jena/trunk/jena-arq/ReleaseNotes.txt
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/path/eval/PathEngine.java
Modified: jena/trunk/jena-arq/ReleaseNotes.txt
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/ReleaseNotes.txt?rev=1597358&r1=1597357&r2=1597358&view=diff
==============================================================================
--- jena/trunk/jena-arq/ReleaseNotes.txt (original)
+++ jena/trunk/jena-arq/ReleaseNotes.txt Sat May 24 21:30:02 2014
@@ -4,6 +4,7 @@ ChangeLog for ARQ
==== Jena 2.11.2
++ JENA-631 : rdfs:member supported in property paths.
+ JENA-671 : More filter placement optimization
See also JENA-619, JENA-627, JENA-628, JENA-653
+ JENA-638 : Improve coverage of TopN optimziation
Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/path/eval/PathEngine.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/path/eval/PathEngine.java?rev=1597358&r1=1597357&r2=1597358&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/path/eval/PathEngine.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/path/eval/PathEngine.java Sat May 24 21:30:02 2014
@@ -18,6 +18,7 @@
package com.hp.hpl.jena.sparql.path.eval ;
+import java.util.ArrayList ;
import java.util.Collection ;
import java.util.Iterator ;
import java.util.List ;
@@ -28,12 +29,17 @@ import org.apache.jena.atlas.iterator.Tr
import com.hp.hpl.jena.graph.Graph ;
import com.hp.hpl.jena.graph.Node ;
import com.hp.hpl.jena.graph.Triple ;
+import com.hp.hpl.jena.query.ARQ ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.engine.ExecutionContext ;
+import com.hp.hpl.jena.sparql.engine.QueryIterator ;
import com.hp.hpl.jena.sparql.engine.binding.Binding ;
import com.hp.hpl.jena.sparql.engine.binding.BindingFactory ;
+import com.hp.hpl.jena.sparql.engine.iterator.QueryIterRoot ;
import com.hp.hpl.jena.sparql.path.P_NegPropSet ;
import com.hp.hpl.jena.sparql.path.Path ;
import com.hp.hpl.jena.sparql.path.eval.PathEvaluator.FilterExclude ;
-import com.hp.hpl.jena.sparql.pfunction.PropertyFunctionRegistry ;
+import com.hp.hpl.jena.sparql.pfunction.* ;
import com.hp.hpl.jena.sparql.util.Context ;
import com.hp.hpl.jena.sparql.util.graph.GraphContainerUtils ;
import com.hp.hpl.jena.sparql.util.graph.GraphList ;
@@ -42,12 +48,22 @@ import com.hp.hpl.jena.vocabulary.RDFS ;
abstract public class PathEngine
{
+ private final boolean doingRDFSmember ;
+ private final boolean doingListMember ;
private final Graph graph ;
private final Context context ;
private final PropertyFunctionRegistry registry ;
protected PathEngine(Graph graph, Context context) {
this.registry = PropertyFunctionRegistry.chooseRegistry(context) ;
+ if ( registry != null ) {
+ doingRDFSmember = ( registry.get(RDFSmember.getURI()) != null ) ;
+ doingListMember = ( registry.get(ListMember.getURI()) != null ) ;
+ } else {
+ doingRDFSmember = false ;
+ doingListMember = false ;
+ }
+
this.graph = graph ;
this.context = context ;
}
@@ -179,60 +195,66 @@ abstract public class PathEngine
private static Node RDFSmember = RDFS.Nodes.member ;
private static Node ListMember = ListPFunction.nListMember ;
- private/* package */static Iterator<Triple> graphFind(Graph graph, Node s, Node p, Node o, Context context) {
+ private /*static*/ Iterator<Triple> graphFind(Graph graph, Node s, Node p, Node o, Context context) {
// This is the only place this is called.
// It means we can add property functions here.
- if ( RDFSmember.equals(p) )
+
+ // Fast-path common cases.
+ if ( doingRDFSmember && RDFSmember.equals(p) )
return GraphContainerUtils.rdfsMember(graph, s, o) ;
- if ( ListMember.equals(p) )
+ if ( doingListMember && ListMember.equals(p) )
return GraphList.listMember(graph, s, o) ;
+ // Potentially just allow the cases above.
+ //return graph.find(s, p, o) ;
+ return graphFind2(graph, s, p, o, context) ;
+ }
+
+ /* As general as possible property function inclusion */
+ private Iterator<Triple> graphFind2(Graph graph, Node s, Node p, Node o, Context context) {
+ // Not all property functions make sense in property path
+ // For example, ones taking list arguments only make sense at
+ // the start or finish, and then only in simple paths
+ // (e.g. ?x .../propertyFunction ?z)
+ // which would have been packaged by the optimizer.
+ if ( p != null && p.isURI() && registry != null ) {
+ PropertyFunctionFactory f = registry.get(p.getURI()) ;
+ if ( f != null )
+ return graphFindWorker(graph, s, f, p, o, context) ;
+ }
+
return graph.find(s, p, o) ;
}
-
- // Not all property functions make sense in property path
- // For example, ones taking list arguments only make sense at
- // the start or finish, and then only in simple paths
- // (e.g. ?x .../propertyFunction ?z)
- // which would have been packaged by the optimizer.
-
-// if ( p != null && p.isURI() ) {
-// // XXX This is heavy weight
-// PropertyFunctionRegistry reg = PropertyFunctionRegistry.chooseRegistry(context) ;
-// PropertyFunctionFactory f = reg.get(p.getURI()) ;
-// if ( f != null ) {
-// // Expensive.
-// PropertyFunction pf = f.create(p.getURI()) ;
-// // Must be a PFuncSimple -- no list arguments to the property function.
-// if ( pf instanceof PFuncSimple) {
-// PFuncSimple pfs = (PFuncSimple)pf ;
-// Node sv = arg(s, "S") ;
-// Node ov = arg(o, "O") ;
-// QueryIterator qIter = pfs.execEvaluated(binding, sv, p, ov, new ExecutionContext(ARQ.getContext(), graph, null, null)) ;
-// if ( ! qIter.hasNext() )
-// return Iter.nullIterator() ;
-// List<Triple> array = new ArrayList<Triple>() ;
-// for ( ; qIter.hasNext() ; ) {
-// Binding b = qIter.next() ;
-// Node st = value(sv, b) ;
-// Node ot = value(ov, b) ;
-// array.add(Triple.create(st, p, ot)) ;
-// }
-// return array.iterator() ;
-// }
-// }
-// }
-//
-// return graph.find(s, p, o) ;
-// }
-//
-// private static Node arg(Node x, String name) {
-// if ( x == null || Node.ANY.equals(x) ) { return Var.alloc(name) ; }
-// return x ;
-// }
-//
-// private static Node value(Node x, Binding b) {
-// if ( !Var.isVar(x) )
-// return x ;
-// return b.get(Var.alloc(x)) ;
-// }
+
+ private Iterator<Triple> graphFindWorker(Graph graph, Node s, PropertyFunctionFactory f, Node p, Node o, Context context) {
+ // Expensive?
+ PropertyFunction pf = f.create(p.getURI()) ;
+ PropFuncArg sv = arg(s, "S") ;
+ PropFuncArg ov = arg(o, "O") ;
+ QueryIterator r = QueryIterRoot.create(new ExecutionContext(context, graph, null, null)) ;
+ QueryIterator qIter = pf.exec(r, sv, p, ov, new ExecutionContext(ARQ.getContext(), graph, null, null)) ;
+ if ( ! qIter.hasNext() )
+ return Iter.nullIterator() ;
+ List<Triple> array = new ArrayList<Triple>() ;
+ for ( ; qIter.hasNext() ; ) {
+ Binding b = qIter.next() ;
+ Node st = value(sv, b) ;
+ Node ot = value(ov, b) ;
+ array.add(Triple.create(st, p, ot)) ;
+ }
+ // Materialise so the inner QueryIterators are used up.
+ return array.iterator() ;
+ }
+
+ private static PropFuncArg arg(Node x, String name) {
+ if ( x == null || Node.ANY.equals(x) )
+ { return new PropFuncArg(Var.alloc(name)) ; }
+ return new PropFuncArg(x) ;
+ }
+
+ private static Node value(PropFuncArg arg, Binding b) {
+ Node x = arg.getArg() ;
+ if ( !Var.isVar(x) )
+ return x ;
+ return b.get(Var.alloc(x)) ;
+ }
}