diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/ApproximateSearchEnv.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/ApproximateSearchEnv.java similarity index 90% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/ApproximateSearchEnv.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/ApproximateSearchEnv.java index b81273c7f..bf5a34ddf 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/ApproximateSearchEnv.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/ApproximateSearchEnv.java @@ -1,9 +1,10 @@ -package fr.inria.corese.core.next.query.impl.kgram.tool; +package fr.inria.corese.core.next.query.impl.engine.eval; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; - -import java.util.*; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; /** * Data structure: Key -> (node -> Value) diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Checker.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/Checker.java similarity index 83% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Checker.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/Checker.java index 0a01da6a0..d25ad0265 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Checker.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/Checker.java @@ -1,10 +1,14 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.eval; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Matcher; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; + +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Matcher; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/CompleteSPARQL.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/CompleteSPARQL.java similarity index 88% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/CompleteSPARQL.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/CompleteSPARQL.java index af8a69777..c51711e69 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/CompleteSPARQL.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/CompleteSPARQL.java @@ -3,11 +3,16 @@ * and open the template in the editor. */ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.eval; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Filter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; + +import fr.inria.corese.core.next.query.impl.engine.model.Filter; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; import fr.inria.corese.core.next.data.api.model.DatatypeValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/EnvironmentImpl.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/EnvironmentImpl.java similarity index 54% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/EnvironmentImpl.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/EnvironmentImpl.java index cc38ea4b8..23081f33d 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/EnvironmentImpl.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/EnvironmentImpl.java @@ -1,19 +1,24 @@ -package fr.inria.corese.core.next.query.impl.kgram.tool; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.BindingContext; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.api.query.ProcessVisitor; -import fr.inria.corese.core.next.query.impl.kgram.core.*; -import fr.inria.corese.core.next.query.impl.kgram.event.KgramEventDispatcher; -import fr.inria.corese.core.next.query.impl.kgram.path.Path; +package fr.inria.corese.core.next.query.impl.engine.eval; + +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; + +import fr.inria.corese.core.next.query.impl.engine.model.BindingContext; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.event.ProcessVisitor; +import fr.inria.corese.core.next.query.impl.engine.event.KgramEventDispatcher; +import fr.inria.corese.core.next.query.impl.engine.path.Path; import fr.inria.corese.core.next.data.api.model.DatatypeValue; import java.util.Map; public class EnvironmentImpl implements Environment { + protected static final String NOT_SUPPORTED_YET = "Not supported yet."; protected Query query; public EnvironmentImpl(){ @@ -108,93 +113,93 @@ public Map getMap() { @Override public Edge[] getEdges() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public Node[] getNodes() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public Node[] getQueryNodes() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public Path getPath(Node qNode) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public Mappings getMappings() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public Node get(Expr variable) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public BindingContext getBind() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public boolean hasBind() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public ApproximateSearchEnv getAppxSearchEnv() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public void setBind(BindingContext b) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public Iterable getAggregate() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public void aggregate(Mapping m, int n) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public Mapping getMapping() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public Eval getEval() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public void setEval(Eval e) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public ProcessVisitor getVisitor() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public void setReport(DatatypeValue dt) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public DatatypeValue getReport() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Eval.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/Eval.java similarity index 95% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Eval.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/Eval.java index 82ccc6103..70413a2fd 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Eval.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/Eval.java @@ -1,14 +1,35 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.eval; + +import fr.inria.corese.core.next.query.impl.engine.event.ProcessVisitor; +import fr.inria.corese.core.next.query.impl.engine.event.ProcessVisitorDefault; +import fr.inria.corese.core.next.query.impl.engine.model.BindingContext; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.ExpType; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.Filter; +import fr.inria.corese.core.next.query.impl.engine.model.Loopable; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.MappingSet; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; +import fr.inria.corese.core.next.query.impl.engine.solution.Memory; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Evaluator; +import fr.inria.corese.core.next.query.impl.engine.spi.Matcher; +import fr.inria.corese.core.next.query.impl.engine.spi.Plugin; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; +import fr.inria.corese.core.next.query.impl.engine.spi.Provider; +import fr.inria.corese.core.next.query.impl.engine.spi.SPARQLEngine; import fr.inria.corese.core.next.data.Values; -import fr.inria.corese.core.next.query.impl.kgram.api.core.*; -import fr.inria.corese.core.next.query.impl.kgram.api.query.*; -import fr.inria.corese.core.next.query.impl.kgram.event.Event; -import fr.inria.corese.core.next.query.impl.kgram.event.EventImpl; -import fr.inria.corese.core.next.query.impl.kgram.event.KgramEventDispatcher; -import fr.inria.corese.core.next.query.impl.kgram.event.ResultListener; -import fr.inria.corese.core.next.query.impl.kgram.path.PathFinder; -import fr.inria.corese.core.next.query.impl.kgram.tool.NodeImpl; +import fr.inria.corese.core.next.query.impl.engine.event.Event; +import fr.inria.corese.core.next.query.impl.engine.event.EventImpl; +import fr.inria.corese.core.next.query.impl.engine.event.KgramEventDispatcher; +import fr.inria.corese.core.next.query.impl.engine.event.ResultListener; +import fr.inria.corese.core.next.query.impl.engine.path.PathFinder; +import fr.inria.corese.core.next.query.impl.engine.model.NodeImpl; import fr.inria.corese.core.next.data.api.model.DatatypeValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,7 +38,7 @@ import java.util.HashMap; import java.util.List; -import static fr.inria.corese.core.next.query.impl.kgram.api.core.ExprType.UNNEST; +import static fr.inria.corese.core.next.query.impl.engine.model.ExprType.UNNEST; /** * KGRAM Knowledge Graph Abstract Machine Compute graph homomorphism and @@ -88,7 +109,7 @@ public final class Eval implements ExpType, Plugin { // Edge and Node producer private Producer producer; private Stack current; - private static final boolean HAS_LISTENER = false; + private boolean hasListener = false; private int nbResult; private boolean hasCandidate = false; private boolean hasStatement = false; @@ -591,7 +612,7 @@ public BindingContext getBind() { return getEnvironment().getBind(); } - Query getQuery() { + public Query getQuery() { return query; } @@ -845,7 +866,7 @@ int eval(Producer p, Node graphNode, Stack stack, Mappings map, int n) throws Sp } Exp exp = stack.get(n); - if (HAS_LISTENER) { + if (hasListener) { // rule engine may have a ResultWatcher listener exp = getListener().listen(exp, n); } @@ -1301,7 +1322,7 @@ boolean isTrue(DatatypeValue dt) { return dt.isTrue(); } - Node eval(Node graphNode, Filter f, Environment env, Producer p) { + public Node eval(Node graphNode, Filter f, Environment env, Producer p) { try { env.setGraphNode(graphNode); return p.getNode(eval(f.getExp(), env, p)); @@ -1311,26 +1332,26 @@ Node eval(Node graphNode, Filter f, Environment env, Producer p) { } - DatatypeValue eval(Filter f, Environment env, Producer p) { + public DatatypeValue eval(Filter f, Environment env, Producer p) { return f.getExp().evalWE(getEvaluator(), env.getBind(), env, p); } - DatatypeValue eval(Expr e, Environment env, Producer p) { + public DatatypeValue eval(Expr e, Environment env, Producer p) { return e.evalWE(getEvaluator(), env.getBind(), env, p); } // values var ( unnext(exp) ) // Note: Producer is not current producer but global producer - Mappings eval(Filter f, Environment env, List nodes) { + public Mappings eval(Filter f, Environment env, List nodes) { return eval(f, env, getProducer(), nodes); } - Mappings eval(Filter f, Environment env, Producer p, List nodes) { + public Mappings eval(Filter f, Environment env, Producer p, List nodes) { int n = 1; Expr exp = f.getExp(); if (exp.oper() == UNNEST) { - if (HAS_LISTENER) { + if (hasListener) { listener.listen(exp); } if (exp.arity() == 2) { @@ -1360,8 +1381,8 @@ Mappings eval(Filter f, Environment env, Producer p, List nodes) { * in this case graphNode = g_i and from is useless here * from named has been used in named graph pattern evaluator * data is possible relevant bindings coming from preceding statement evaluation - * data may be null */ + @SuppressWarnings("java:S3776") // Core KGRAM property path evaluation loop managing automaton candidate matching and backtracking private int path(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) throws SparqlException { int backtrack = n - 1; int evENUM = Event.ENUM; @@ -1372,8 +1393,10 @@ private int path(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack if (data != null && data.getNodeList() != null && isPushEdgeMappings()) { // push values(data) before edge in stack - logger.info("Push path mappings:\nvalue {}\n{}", - data.getNodeList(), data.toString(false, false, DISPLAY_RESULT_LIMIT)); + if (logger.isInfoEnabled()) { + logger.info("Push path mappings:\nvalue {}\n{}", + data.getNodeList(), data.toString(false, false, DISPLAY_RESULT_LIMIT)); + } return eval(p, graphNode, stack.addCopy(n, exp.getValues(data)), n); } @@ -1569,7 +1592,7 @@ private int edge(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack if (entity != null) { nbEdge++; - if (HAS_LISTENER && !listener.listen(exp, qEdge, entity)) { + if (hasListener && !listener.listen(exp, qEdge, entity)) { continue; } @@ -2095,7 +2118,7 @@ Iterable produce(Node gNode, Edge edge) { @Deprecated(since = "4.0.0") @SuppressWarnings("java:S1133") public void exec(Exp exp, Environment env, int n) { - if (exp.getObject() instanceof String label && env.getNode(label) != null) { + if (exp.getObject() instanceof String label && env.getNode(label) != null && logger.isDebugEnabled()) { logger.debug("{}: {} {}", n, label, env.getNode(label).getLabel()); } } @@ -2110,6 +2133,7 @@ public ResultListener getListener() { public void setListener(ResultListener listener) { this.listener = listener; + this.hasListener = listener != null; } } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/EvalGraph.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalGraph.java similarity index 88% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/EvalGraph.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalGraph.java index 6b2a07c05..6021d93e1 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/EvalGraph.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalGraph.java @@ -1,8 +1,14 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.eval; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Matcher; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; +import fr.inria.corese.core.next.query.impl.engine.solution.Memory; + +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.spi.Matcher; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; import java.util.List; @@ -12,7 +18,7 @@ public class EvalGraph { Eval engine; - boolean stop = false; + volatile boolean stop = false; EvalGraph(Eval e) { engine = e; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/EvalJoin.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalJoin.java similarity index 91% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/EvalJoin.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalJoin.java index bad15ac5a..423291b03 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/EvalJoin.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalJoin.java @@ -1,9 +1,16 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.eval; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.MappingSet; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; +import fr.inria.corese.core.next.query.impl.engine.solution.Memory; -import static fr.inria.corese.core.next.query.impl.kgram.core.Eval.STOP; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; + +import static fr.inria.corese.core.next.query.impl.engine.eval.Eval.STOP; /** * @author corby @@ -12,7 +19,7 @@ public class EvalJoin { Eval engine; - boolean stop = false; + volatile boolean stop = false; EvalJoin(Eval engine) { this.engine = engine; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/EvalOptional.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalOptional.java similarity index 66% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/EvalOptional.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalOptional.java index ec6a18706..4513b9820 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/EvalOptional.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalOptional.java @@ -1,21 +1,30 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.eval; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.MappingSet; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; +import fr.inria.corese.core.next.query.impl.engine.solution.Memory; -import static fr.inria.corese.core.next.query.impl.kgram.core.Eval.STOP; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; + +import java.util.Iterator; + +import static fr.inria.corese.core.next.query.impl.engine.eval.Eval.STOP; /** * @author corby */ public class EvalOptional { - Eval eval; - private boolean stop = false; + Eval engine; + private volatile boolean stop = false; EvalOptional(Eval e) { - eval = e; + engine = e; } /** @@ -39,11 +48,12 @@ public void setStop(boolean stop) { * if m1.compatible(m2): merge = m1.merge(m2) if eval(F(merge)) result += * merge ... */ + @SuppressWarnings("java:S3776") int eval(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) throws SparqlException { int backtrack = n - 1; - Memory env = eval.getMemory(); + Memory env = engine.getMemory(); - Mappings map1 = eval.subEval(p, graphNode, null, exp.first(), exp, data); + Mappings map1 = engine.subEval(p, graphNode, null, exp.first(), exp, data); if (isStop()) { return STOP; } @@ -70,23 +80,21 @@ int eval(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) /* * Push bindings from map1 into rest when there is at least one variable - * in-subscope of rest that is always bound in map1 ?x p ?y optional { - * ?y q ?z } -> values ?y { y1 yn } {?x p ?y optional { ?y q ?z }} - * optional { ?z r ?t } -> if ?z is not bound in every map1, generate no - * values + * in-subscope of rest that is always bound in map1. + * For example, with query patterns like ?x p ?y optional(?y q ?z), + * if the variable is not bound in every map1, no values are generated. * - * set1.getJoinMappings() = Mappings to be considered by rest Either - * pushed into rest or stored in Memory to be used in eval(rest) eg when - * rest=service. + * set1.getJoinMappings(): Mappings to be considered by rest, either + * pushed into rest or stored in Memory to be used in eval(rest). */ if (map != null && map.isEmpty()) { // Every Mapping fail filter, rest() will always fail: skip optional rest() map2 = Mappings.create(env.getQuery()); } else { - map2 = eval.subEval(p, graphNode, null, rest, exp, map); + map2 = engine.subEval(p, graphNode, null, rest, exp, map); } - eval.getVisitor().optional(eval, eval.getGraphNode(graphNode), exp, map1, map2); + engine.getVisitor().optional(engine, engine.getGraphNode(graphNode), exp, map1, map2); MappingSet set = new MappingSet(getQuery(), exp, set1, new MappingSet(getQuery(), map2)); @@ -109,7 +117,7 @@ int eval(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) if (success) { nbsuc++; if (env.push(merge, n)) { - backtrack = eval.eval(p, graphNode, stack, n + 1); + backtrack = engine.eval(p, graphNode, stack, n + 1); env.pop(merge); if (backtrack < n) { return backtrack; @@ -120,7 +128,7 @@ int eval(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) } if ((nbsuc == 0) && (env.push(m1, n))) { - backtrack = eval.eval(p, graphNode, stack, n + 1); + backtrack = engine.eval(p, graphNode, stack, n + 1); env.pop(m1); if (backtrack < n) { return backtrack; @@ -137,34 +145,33 @@ int eval(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) * (BGP1) skip binding Mapping m when it fail filter(var) Remove such * Mapping m from map before binding BGP2 with map */ - Mappings filter(Node gNode, Exp exp, Environment memory, Producer p, Mappings map) throws SparqlException { - for (int i = 0; i < map.size(); ) { - Mapping m = map.get(i); + Mappings filter(Node gNode, Exp exp, Environment memory, Producer p, Mappings map) { + Iterator it = map.iterator(); + while (it.hasNext()) { + Mapping m = it.next(); m.setQuery(memory.getQuery()); m.setMap(memory.getMap()); m.setBind(memory.getBind()); - m.setEval(eval); + m.setEval(engine); boolean suc = true; for (Exp ft : exp.getInscopeFilter()) { - boolean b = eval.test(gNode, ft.getFilter(), m, p); + boolean b = engine.test(gNode, ft.getFilter(), m, p); if (!b) { suc = false; break; } } - if (suc) { - i++; - } else { - map.remove(i); + if (!suc) { + it.remove(); } } return map; } - boolean filter(Environment memory, Producer p, Node gNode, Mapping map, Exp exp) throws SparqlException { + boolean filter(Environment memory, Producer p, Node gNode, Mapping map, Exp exp) { if (exp.isPostpone()) { // A optional B // filters of B must be evaluated now @@ -172,10 +179,10 @@ boolean filter(Environment memory, Producer p, Node gNode, Mapping map, Exp exp) map.setQuery(memory.getQuery()); map.setMap(memory.getMap()); map.setBind(memory.getBind()); - map.setEval(eval); - boolean b = eval.test(gNode, f.getFilter(), map, p); - if (eval.hasFilter) { - b = eval.getVisitor().filter(eval, gNode, f.getFilter().getExp(), b); + map.setEval(engine); + boolean b = engine.test(gNode, f.getFilter(), map, p); + if (engine.hasFilter) { + b = engine.getVisitor().filter(engine, gNode, f.getFilter().getExp(), b); } if (!b) { return false; @@ -186,6 +193,6 @@ boolean filter(Environment memory, Producer p, Node gNode, Mapping map, Exp exp) } Query getQuery() { - return eval.getMemory().getQuery(); + return engine.getMemory().getQuery(); } } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/EvalSPARQL.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalSPARQL.java similarity index 91% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/EvalSPARQL.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalSPARQL.java index 75169b7df..3bff77776 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/EvalSPARQL.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalSPARQL.java @@ -1,8 +1,12 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExpType.Type; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; +package fr.inria.corese.core.next.query.impl.engine.eval; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; + +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.model.ExpType.Type; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; import fr.inria.corese.core.next.data.api.model.DatatypeValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/IterableEntity.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/IterableEntity.java similarity index 84% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/IterableEntity.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/IterableEntity.java index a8e6f0f43..d9a76b613 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/IterableEntity.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/IterableEntity.java @@ -1,7 +1,7 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.eval; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Node; import java.util.Iterator; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/Message.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/Message.java similarity index 69% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/Message.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/Message.java index c5ecb474f..3cbc949ec 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/Message.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/Message.java @@ -1,8 +1,11 @@ -package fr.inria.corese.core.next.query.impl.kgram.tool; +package fr.inria.corese.core.next.query.impl.engine.eval; public class Message { + private Message() { + // Utility class + } public enum Prefix { UNDEF_VAR("Undefined variable: "), @@ -17,12 +20,12 @@ public enum Prefix { LOOP("Loop: "), AGG("Aggregate limited to (defined) variable: "); - private final String prefix; - Prefix(String p) { - prefix = p; + private final String text; + Prefix(String text) { + this.text = text; } public String getString() { - return prefix; + return text; } } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/PointerObject.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/PointerObject.java similarity index 51% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/PointerObject.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/PointerObject.java index facc0c6ef..7f31a6d41 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/PointerObject.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/PointerObject.java @@ -1,6 +1,6 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.eval; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Pointerable; +import fr.inria.corese.core.next.query.impl.engine.model.Pointerable; /** * diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/execution/RdfTermMatcher.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/RdfTermMatcher.java similarity index 86% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/execution/RdfTermMatcher.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/RdfTermMatcher.java index e57463fe3..a32ce5f41 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/execution/RdfTermMatcher.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/RdfTermMatcher.java @@ -1,9 +1,9 @@ -package fr.inria.corese.core.next.query.impl.kgram.execution; +package fr.inria.corese.core.next.query.impl.engine.eval; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Matcher; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Matcher; /** * Matcher for RDF term comparisons during KGRAM graph pattern execution. diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/ResultsImpl.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/ResultsImpl.java similarity index 60% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/ResultsImpl.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/ResultsImpl.java index c715009bd..0eef3ecbc 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/ResultsImpl.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/ResultsImpl.java @@ -1,10 +1,10 @@ -package fr.inria.corese.core.next.query.impl.kgram.tool; +package fr.inria.corese.core.next.query.impl.engine.eval; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Result; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Results; -import fr.inria.corese.core.next.query.impl.kgram.core.Mapping; -import fr.inria.corese.core.next.query.impl.kgram.core.Mappings; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.spi.Result; +import fr.inria.corese.core.next.query.impl.engine.spi.Results; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; import java.util.Iterator; import java.util.List; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/SparqlException.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/SparqlException.java similarity index 53% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/SparqlException.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/SparqlException.java index ae1a06763..d54f140a1 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/SparqlException.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/SparqlException.java @@ -1,11 +1,21 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.eval; /** * * @author corby */ public class SparqlException extends Exception { - private boolean stop = false; + private static final long serialVersionUID = 1L; + + private final boolean stop; + + public SparqlException() { + this(false); + } + + public SparqlException(boolean stop) { + this.stop = stop; + } // isStop true means stop query processing, perform aggregate etc. and return partial result // isStop false means this is an exception diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/execution/SparqlKgramEvaluator.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/SparqlKgramEvaluator.java similarity index 82% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/execution/SparqlKgramEvaluator.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/SparqlKgramEvaluator.java index 7858d23cd..1de7f6dab 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/execution/SparqlKgramEvaluator.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/SparqlKgramEvaluator.java @@ -1,9 +1,8 @@ -package fr.inria.corese.core.next.query.impl.kgram.execution; +package fr.inria.corese.core.next.query.impl.engine.eval; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Evaluator; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; -import fr.inria.corese.core.next.query.impl.kgram.core.Eval; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Evaluator; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; import java.time.OffsetDateTime; import java.time.ZoneOffset; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Stack.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/Stack.java similarity index 80% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Stack.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/Stack.java index b4bee847e..9acf9130e 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Stack.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/Stack.java @@ -1,6 +1,8 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.eval; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExpType; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; + +import fr.inria.corese.core.next.query.impl.engine.model.ExpType; import java.util.ArrayList; @@ -12,7 +14,6 @@ */ public class Stack extends ArrayList implements ExpType { - int level = 0; public static Stack create(Exp e){ Stack st = new Stack(); @@ -52,7 +53,7 @@ Stack addCopy(int n, Exp exp) { @Override public String toString(){ - StringBuilder str = new StringBuilder(); //"[" + level +"] "; + StringBuilder str = new StringBuilder(); int i = 0; for (Exp e : this){ str.append(i++).append(" ").append(e).append(", "); diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/package-info.java new file mode 100644 index 000000000..5afe6f125 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/eval/package-info.java @@ -0,0 +1,4 @@ +/** + * Query execution engine, evaluation algorithms, backtracking loop, and runtime environments. + */ +package fr.inria.corese.core.next.query.impl.engine.eval; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/Event.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/Event.java similarity index 88% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/Event.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/event/Event.java index f377f1b11..e167adfc4 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/Event.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/Event.java @@ -1,6 +1,6 @@ -package fr.inria.corese.core.next.query.impl.kgram.event; +package fr.inria.corese.core.next.query.impl.engine.event; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; /** * Event to trace KGRAM execution diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/EventImpl.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/EventImpl.java similarity index 93% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/EventImpl.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/event/EventImpl.java index 8d9aa6b1b..f61afe6ee 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/EventImpl.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/EventImpl.java @@ -1,8 +1,8 @@ -package fr.inria.corese.core.next.query.impl.kgram.event; +package fr.inria.corese.core.next.query.impl.engine.event; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Stack; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.eval.Stack; /** * Event to trace KGRAM execution diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/EventListener.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/EventListener.java similarity index 81% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/EventListener.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/event/EventListener.java index bcf9a28fb..47bb6d597 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/EventListener.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/EventListener.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.event; +package fr.inria.corese.core.next.query.impl.engine.event; /** diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/KgramEventDispatcher.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/KgramEventDispatcher.java similarity index 92% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/KgramEventDispatcher.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/event/KgramEventDispatcher.java index 7065edcfa..aad20fe07 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/KgramEventDispatcher.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/KgramEventDispatcher.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.event; +package fr.inria.corese.core.next.query.impl.engine.event; import java.util.ArrayList; import java.util.Iterator; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/ProcessVisitor.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/ProcessVisitor.java similarity index 83% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/ProcessVisitor.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/event/ProcessVisitor.java index 905f0bf32..31da72849 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/ProcessVisitor.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/ProcessVisitor.java @@ -1,11 +1,16 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.query; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Pointerable; -import fr.inria.corese.core.next.query.impl.kgram.core.*; -import fr.inria.corese.core.next.query.impl.kgram.path.Path; +package fr.inria.corese.core.next.query.impl.engine.event; + +import fr.inria.corese.core.next.query.impl.engine.eval.Eval; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; + +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Pointerable; +import fr.inria.corese.core.next.query.impl.engine.path.Path; import fr.inria.corese.core.next.data.api.model.DatatypeValue; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/ProcessVisitorDefault.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/ProcessVisitorDefault.java similarity index 85% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/ProcessVisitorDefault.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/event/ProcessVisitorDefault.java index 08ae00563..52155e422 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/ProcessVisitorDefault.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/ProcessVisitorDefault.java @@ -1,7 +1,10 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.event; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.query.ProcessVisitor; +import fr.inria.corese.core.next.query.impl.engine.eval.Eval; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; + +import fr.inria.corese.core.next.query.impl.engine.model.Node; import fr.inria.corese.core.next.data.api.model.DatatypeValue; /** No-op process visitor that forwards reporting events to the query binding context. */ diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/ResultListener.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/ResultListener.java similarity index 61% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/ResultListener.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/event/ResultListener.java index 9768676f0..7e467757c 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/ResultListener.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/ResultListener.java @@ -1,11 +1,11 @@ -package fr.inria.corese.core.next.query.impl.kgram.event; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Regex; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.path.Path; +package fr.inria.corese.core.next.query.impl.engine.event; + +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.Regex; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.path.Path; /** * Result Listener to process KGRAM result on the fly diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/User.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/User.java similarity index 73% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/User.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/event/User.java index 0469a4a14..f51b492b8 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/User.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/User.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.event; +package fr.inria.corese.core.next.query.impl.engine.event; /** * Model user interaction with debugger diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/package-info.java new file mode 100644 index 000000000..e5d3df54b --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/event/package-info.java @@ -0,0 +1,4 @@ +/** + * Engine event dispatching, listeners, and query processing visitors. + */ +package fr.inria.corese.core.next.query.impl.engine.event; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/Checker.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/Checker.java similarity index 95% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/Checker.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/Checker.java index cbcff07ea..9b94d7d0f 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/Checker.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/Checker.java @@ -1,7 +1,7 @@ -package fr.inria.corese.core.next.query.impl.kgram.filter; +package fr.inria.corese.core.next.query.impl.engine.filter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExprType; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.ExprType; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/Compile.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/Compile.java similarity index 91% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/Compile.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/Compile.java index 830ef5b7f..8dc8e7d4d 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/Compile.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/Compile.java @@ -1,8 +1,13 @@ -package fr.inria.corese.core.next.query.impl.kgram.filter; +package fr.inria.corese.core.next.query.impl.engine.filter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.*; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Query; +import fr.inria.corese.core.next.query.impl.engine.model.ExpType; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.ExprType; +import fr.inria.corese.core.next.query.impl.engine.model.Filter; +import fr.inria.corese.core.next.query.impl.engine.model.Node; + +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/Extension.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/Extension.java similarity index 84% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/Extension.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/Extension.java index 76ddbaa4b..b2ddcb76e 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/Extension.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/Extension.java @@ -1,6 +1,6 @@ -package fr.inria.corese.core.next.query.impl.kgram.filter; +package fr.inria.corese.core.next.query.impl.engine.filter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; import fr.inria.corese.core.next.data.api.model.DatatypeValue; /** diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/FilterPattern.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/FilterPattern.java similarity index 67% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/FilterPattern.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/FilterPattern.java index 267c0413a..d3f23ce8e 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/FilterPattern.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/FilterPattern.java @@ -1,10 +1,14 @@ -package fr.inria.corese.core.next.query.impl.kgram.filter; +package fr.inria.corese.core.next.query.impl.engine.filter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.*; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Evaluator; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; +import fr.inria.corese.core.next.query.impl.engine.model.BindingContext; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.ExprType; +import fr.inria.corese.core.next.query.impl.engine.model.Filter; + +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Evaluator; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; import fr.inria.corese.core.next.data.api.model.DatatypeValue; import java.util.ArrayList; @@ -18,6 +22,7 @@ * @author Olivier Corby, Edelweiss, INRIA 2010 */ public final class FilterPattern implements ExprType, Expr { + private static final String NOT_SUPPORTED_YET = "Not supported yet."; int type; int oper; String label; @@ -204,96 +209,96 @@ public void setExp(int i, Expr e) { @Override public Expr getDefine() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public void setDefine(Expr exp) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public int subtype() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public Expr getFunction() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public Expr getBody() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public Expr getVariable() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public Expr getDefinition() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public boolean isSystem() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public boolean isTrace() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public boolean isDebug() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public boolean isPublic() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public DatatypeValue getDatatypeValue() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public void setPublic(boolean b) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public void setSubtype(int n) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public boolean match(int oper) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public boolean isConstant() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public boolean hasMetadata(String type) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public boolean isDynamic() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public DatatypeValue evalWE(Evaluator eval, BindingContext b, Environment env, Producer p) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/MatchBind.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/MatchBind.java similarity index 90% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/MatchBind.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/MatchBind.java index e908a04b1..49dcd401e 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/MatchBind.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/MatchBind.java @@ -1,6 +1,7 @@ -package fr.inria.corese.core.next.query.impl.kgram.filter; +package fr.inria.corese.core.next.query.impl.engine.filter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; + +import fr.inria.corese.core.next.query.impl.engine.model.Expr; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/Matcher.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/Matcher.java similarity index 59% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/Matcher.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/Matcher.java index d96a22127..ccf2f8094 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/Matcher.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/Matcher.java @@ -1,7 +1,7 @@ -package fr.inria.corese.core.next.query.impl.kgram.filter; +package fr.inria.corese.core.next.query.impl.engine.filter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExprType; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.ExprType; /** @@ -11,9 +11,8 @@ * */ public class Matcher implements ExprType { - boolean - rec = false, - matchConstant = true; + boolean rec = false; + boolean matchConstant = true; public boolean match(FilterPattern qe, Expr te){ @@ -40,93 +39,57 @@ boolean match(FilterPattern qe, Expr te, MatchBind bind){ * Afterwards, Pattern variable must match same target variables in all EXPi * */ - boolean process(Expr qe, Expr te, MatchBind bind){ - - if (qe.type() == ALTER){ - for (Expr ee : qe.getExpList()){ - int size = bind.size(); - boolean b = process(ee, te, bind); - if (b) return true; - else bind.clean(size); - } - return false; - } - - // LT GT LE GE comparison operator match any comparison operator here - // args will be sorted in matchTerm - if (! matchType(qe, te)) return false; + boolean process(Expr qe, Expr te, MatchBind bind) { + if (qe.type() == ALTER) { + return matchAlternative(qe, te, bind); + } + if (!matchType(qe, te)) { + return false; + } + if ((qe.type() != CONSTANT || matchConstant) && bind.hasValue(qe)) { + return process(bind.getValue(qe), te, bind); + } + return switch (qe.type()) { + case VARIABLE, CONSTANT -> matchVarConst(qe, te, bind); + case FUNCTION, JOKER -> matchBoolFunAny(qe, te, bind); + case BOOLEAN -> matchBoolean(qe, te, bind); + case TERM -> matchTerm(qe, te, bind); + default -> false; + }; + } - // When Pattern is already bound, recurse on its value - if (qe.type() == CONSTANT) { - if (matchConstant && bind.hasValue(qe)) { - return process(bind.getValue(qe), te, bind); - } - } else { - if (bind.hasValue(qe)) { - return process(bind.getValue(qe), te, bind); + private boolean matchAlternative(Expr qe, Expr te, MatchBind bind) { + for (Expr alternative : qe.getExpList()) { + int size = bind.size(); + if (process(alternative, te, bind)) { + return true; } + bind.clean(size); } + return false; + } + private boolean matchBoolean(Expr qe, Expr te, MatchBind bind) { + if (qe.arity() == 2 && te.arity() == 2) { + return matchTerm(qe, te, bind); + } + return qe.arity() <= te.arity() && matchBoolFunAny(qe, te, bind); + } - switch (qe.type()){ - - case VARIABLE: - case CONSTANT: - return matchVarConst(qe, te, bind); - - case FUNCTION: - case JOKER: - return matchBoolFunAny(qe, te, bind); - - case BOOLEAN: - if (qe.arity() == 2 && te.arity() == 2){ - return matchTerm(qe, te, bind); - } - else if (qe.arity() > te.arity()){ - // BOOLEAN ANY Pat Pat vs NOT EXP - return false; - } - else { - // NOT has only one argument - // rec = true has only argument - return matchBoolFunAny(qe, te, bind); - } - - case TERM: - //if (qe.arity() == 2 && qe.arity() == te.arity()){ - return matchTerm(qe, te, bind); - //} - } - - return false; - } - - - - boolean matchVarConst(Expr qe, Expr te, MatchBind bind){ - switch (qe.type()){ - - case VARIABLE: - if (qe.getLabel() != null) return qe.getLabel().equals(te.getLabel()); - else bind.setValue(qe, te); - break; - - - case CONSTANT: - if (matchConstant){ - if (isBindable(qe)){ - bind.setValue(qe, te); - } - else { - // target values - return qe.equals(te); - } - } - } - - return true; - } - + boolean matchVarConst(Expr qe, Expr te, MatchBind bind) { + if (qe.type() == VARIABLE) { + if (qe.getLabel() != null) { + return qe.getLabel().equals(te.getLabel()); + } + bind.setValue(qe, te); + } else if (qe.type() == CONSTANT && matchConstant) { + if (!isBindable(qe)) { + return qe.equals(te); + } + bind.setValue(qe, te); + } + return true; + } /** @@ -166,21 +129,10 @@ boolean matchBoolFunAny(Expr qe, Expr te, MatchBind bind) { return false; } - if (!process(qarg, targ, bind)) { - if (rec) { - // recursive match of Pattern qe on argument targ - // qe = OR(EXP) - // qarg = EXP - // targ = OR(EXP1, EXP2) - if (!process(qe, targ, bind)) { - bind.clean(size); - return false; - } - } else { - bind.clean(size); - return false; - } - } + if (!process(qarg, targ, bind) && (!rec || !process(qe, targ, bind))) { + bind.clean(size); + return false; + } } if (!bind.hasValue(qe)) { @@ -192,7 +144,8 @@ boolean matchBoolFunAny(Expr qe, Expr te, MatchBind bind) { boolean matchTerm(Expr qe, Expr te, MatchBind bind) { - Expr fst = qe.getExp(0), snd = qe.getExp(1); + Expr fst = qe.getExp(0); + Expr snd = qe.getExp(1); if (isGL(qe.oper()) && qe.oper() != te.oper()) { @@ -265,7 +218,9 @@ boolean match(int qt, int tt){ boolean matchType(Expr qe, Expr te){ if (qe.oper() == EXIST || te.oper() == EXIST) return false; - if (qe.type() == JOKER) return true; + if (qe.type() == JOKER) { + return true; + } return switch (qe.type()) { case VARIABLE, CONSTANT -> match(qe.type(), te.type()); default -> match(qe.type(), te.type()) && match(qe.oper(), te.oper()); diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/package-info.java new file mode 100644 index 000000000..fda590feb --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/package-info.java @@ -0,0 +1,4 @@ +/** + * SPARQL filter pattern matching and compilation structures. + */ +package fr.inria.corese.core.next.query.impl.engine.filter; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/BindingContext.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/BindingContext.java similarity index 95% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/BindingContext.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/BindingContext.java index e0f63983b..b0077dcf1 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/BindingContext.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/BindingContext.java @@ -1,6 +1,6 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.core; +package fr.inria.corese.core.next.query.impl.engine.model; -import fr.inria.corese.core.next.query.impl.kgram.api.query.ProcessVisitor; +import fr.inria.corese.core.next.query.impl.engine.event.ProcessVisitor; import java.util.Map; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/DatatypeNodeFactory.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/DatatypeNodeFactory.java similarity index 75% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/DatatypeNodeFactory.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/DatatypeNodeFactory.java index 45d8e6660..35f0c1b53 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/DatatypeNodeFactory.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/DatatypeNodeFactory.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.core; +package fr.inria.corese.core.next.query.impl.engine.model; import java.util.List; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Edge.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Edge.java similarity index 97% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Edge.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Edge.java index 69a4e71b9..b8265351d 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Edge.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Edge.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.core; +package fr.inria.corese.core.next.query.impl.engine.model; import fr.inria.corese.core.next.data.api.model.DatatypeValue; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/EdgeInv.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/EdgeInv.java similarity index 81% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/EdgeInv.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/EdgeInv.java index 4cf8f81c4..1a2b0c8cc 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/EdgeInv.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/EdgeInv.java @@ -1,11 +1,7 @@ -package fr.inria.corese.core.next.query.impl.kgram.tool; +package fr.inria.corese.core.next.query.impl.engine.model; +import fr.inria.corese.core.next.query.impl.engine.eval.PointerObject; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.core.PointerType; -import fr.inria.corese.core.next.query.impl.kgram.core.PointerObject; - -import static fr.inria.corese.core.next.query.impl.kgram.api.core.PointerType.TRIPLE; +import static fr.inria.corese.core.next.query.impl.engine.model.PointerType.TRIPLE; public class EdgeInv extends PointerObject implements Edge { diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/ExpPattern.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/ExpPattern.java similarity index 73% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/ExpPattern.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/ExpPattern.java index 4e91e94e9..b738e0ee6 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/ExpPattern.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/ExpPattern.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.core; +package fr.inria.corese.core.next.query.impl.engine.model; import java.util.List; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/ExpType.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/ExpType.java similarity index 95% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/ExpType.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/ExpType.java index d70003e9e..58e565c57 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/ExpType.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/ExpType.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.core; +package fr.inria.corese.core.next.query.impl.engine.model; /** * Types of expression of KGRAM query language diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Expr.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Expr.java similarity index 90% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Expr.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Expr.java index f6f6ed044..01ba57e95 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Expr.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Expr.java @@ -1,8 +1,8 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.core; +package fr.inria.corese.core.next.query.impl.engine.model; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Evaluator; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Evaluator; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; import fr.inria.corese.core.next.data.api.model.DatatypeValue; import java.util.List; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/ExprType.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/ExprType.java similarity index 92% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/ExprType.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/ExprType.java index bf51289b1..5454e0613 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/ExprType.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/ExprType.java @@ -1,5 +1,7 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.core; +package fr.inria.corese.core.next.query.impl.engine.model; +// Opcode constants remain inherited by existing engine expression implementations. +@SuppressWarnings("java:S1214") public interface ExprType { int UNDEF = -1; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Filter.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Filter.java similarity index 94% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Filter.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Filter.java index bd5500a56..16c4a97b0 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Filter.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Filter.java @@ -1,4 +1,5 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.core; +package fr.inria.corese.core.next.query.impl.engine.model; + import fr.inria.corese.core.next.query.impl.sparql.ast.TermAst; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Graph.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Graph.java similarity index 77% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Graph.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Graph.java index b064ad090..94150c6fd 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Graph.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Graph.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.core; +package fr.inria.corese.core.next.query.impl.engine.model; /** * diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/KgramNodes.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/KgramNodes.java similarity index 94% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/KgramNodes.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/KgramNodes.java index 9578c78de..e48257e6b 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/KgramNodes.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/KgramNodes.java @@ -1,9 +1,8 @@ -package fr.inria.corese.core.next.query.impl.kgram.tool; +package fr.inria.corese.core.next.query.impl.engine.model; import fr.inria.corese.core.next.data.Values; import fr.inria.corese.core.next.data.api.model.DatatypeValue; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.path.Path; +import fr.inria.corese.core.next.query.impl.engine.path.Path; /** * Factory for Corese-specific KGRAM nodes used by the Corese-next runtime model. diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Loopable.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Loopable.java similarity index 69% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Loopable.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Loopable.java index 1a9813fc4..432fa013c 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Loopable.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Loopable.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.core; +package fr.inria.corese.core.next.query.impl.engine.model; /** * Interface for (var in exp) {} diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Node.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Node.java similarity index 92% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Node.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Node.java index 940b4938e..bdfa085dd 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Node.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Node.java @@ -1,7 +1,7 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.core; +package fr.inria.corese.core.next.query.impl.engine.model; import fr.inria.corese.core.next.data.api.model.DatatypeValue; -import fr.inria.corese.core.next.query.impl.kgram.path.Path; +import fr.inria.corese.core.next.query.impl.engine.path.Path; /** diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/NodeImpl.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/NodeImpl.java similarity index 94% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/NodeImpl.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/NodeImpl.java index defdfe99f..10be3cf04 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/NodeImpl.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/NodeImpl.java @@ -1,11 +1,8 @@ -package fr.inria.corese.core.next.query.impl.kgram.tool; +package fr.inria.corese.core.next.query.impl.engine.model; import fr.inria.corese.core.next.data.Values; import fr.inria.corese.core.next.data.api.model.DatatypeValue; -import fr.inria.corese.core.next.query.impl.kgram.path.Path; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.core.TripleStore; +import fr.inria.corese.core.next.query.impl.engine.path.Path; import java.util.Objects; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/PointerType.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/PointerType.java similarity index 92% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/PointerType.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/PointerType.java index dca3e09e4..46730f3a7 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/PointerType.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/PointerType.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.core; +package fr.inria.corese.core.next.query.impl.engine.model; /** * Pointer type for object that can be object of CoresePointer diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Pointerable.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Pointerable.java similarity index 77% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Pointerable.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Pointerable.java index c9ffc21c7..b654b549d 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Pointerable.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Pointerable.java @@ -1,9 +1,9 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.core; +package fr.inria.corese.core.next.query.impl.engine.model; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Mapping; -import fr.inria.corese.core.next.query.impl.kgram.core.Mappings; -import fr.inria.corese.core.next.query.impl.kgram.core.Query; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; import java.util.ArrayList; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Regex.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Regex.java similarity index 95% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Regex.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Regex.java index 3fbbe66e4..cb505c6d0 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/Regex.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/Regex.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.core; +package fr.inria.corese.core.next.query.impl.engine.model; import fr.inria.corese.core.next.data.api.model.DatatypeValue; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/TripleStore.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/TripleStore.java similarity index 79% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/TripleStore.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/model/TripleStore.java index 5517574ac..fc7b7e022 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/TripleStore.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/TripleStore.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.core; +package fr.inria.corese.core.next.query.impl.engine.model; import fr.inria.corese.core.next.data.api.model.DatatypeValue; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/package-info.java new file mode 100644 index 000000000..c417dc0bd --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/model/package-info.java @@ -0,0 +1,4 @@ +/** + * Internal query graph representations, node/edge models, and expression contracts. + */ +package fr.inria.corese.core.next.query.impl.engine.model; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/package-info.java new file mode 100644 index 000000000..3f4a9e43f --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/package-info.java @@ -0,0 +1,4 @@ +/** + * Corese Next internal query execution engine and solver components. + */ +package fr.inria.corese.core.next.query.impl.engine; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/GraphPath.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/path/GraphPath.java similarity index 65% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/GraphPath.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/path/GraphPath.java index 0cd502dcb..97ca99f8b 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/GraphPath.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/path/GraphPath.java @@ -1,7 +1,7 @@ -package fr.inria.corese.core.next.query.impl.kgram.path; +package fr.inria.corese.core.next.query.impl.engine.path; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; /** * Draft to compute path in the graph @@ -30,4 +30,8 @@ public GraphPath(PathFinder pc, Environment mem){ this.mem = mem; } + @Override + public void run() { + finder.process(finder.get(mem, finder.getIndex()), mem); + } } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/Path.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/path/Path.java similarity index 57% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/Path.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/path/Path.java index 7eb92cfb2..37503f528 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/Path.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/path/Path.java @@ -1,18 +1,18 @@ -package fr.inria.corese.core.next.query.impl.kgram.path; +package fr.inria.corese.core.next.query.impl.engine.path; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.core.PointerType; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Pointerable; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; -import fr.inria.corese.core.next.query.impl.kgram.tool.EdgeInv; -import fr.inria.corese.core.next.query.impl.kgram.tool.ProducerDefault; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.model.PointerType; +import fr.inria.corese.core.next.query.impl.engine.model.Pointerable; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; +import fr.inria.corese.core.next.query.impl.engine.model.EdgeInv; +import fr.inria.corese.core.next.query.impl.engine.storage.ProducerDefault; import java.util.ArrayList; import java.util.List; -import static fr.inria.corese.core.next.query.impl.kgram.api.core.PointerType.PATH; +import static fr.inria.corese.core.next.query.impl.engine.model.PointerType.PATH; /** * List of relations between two resources found by path Can be used as a @@ -26,11 +26,11 @@ public class Path extends ProducerDefault implements Pointerable { boolean isReverse = false; int max = Integer.MAX_VALUE; int weight = 0; - ArrayList path; + ArrayList edges; public Path() { setMode(Producer.EXTENSION); - path = new ArrayList<>(); + edges = new ArrayList<>(); } public Path(boolean b) { @@ -40,16 +40,16 @@ public Path(boolean b) { Path(int n) { setMode(Producer.EXTENSION); - path = new ArrayList<>(n); + edges = new ArrayList<>(n); } @Override public String getDatatypeLabel() { - if (path.size() == 1) { - return String.format("(1)[%s]", path.getFirst()); + if (edges.size() == 1) { + return String.format("(1)[%s]", edges.getFirst()); } - if (path.size() > 1) { - return String.format("(%s)[%s ...]", path.size(), path.getFirst()); + if (edges.size() > 1) { + return String.format("(%s)[%s ...]", edges.size(), edges.getFirst()); } return "(0)[]"; } @@ -72,16 +72,16 @@ int getMax() { } public void add(Edge ent) { - path.add(ent); + edges.add(ent); } public void add(Edge ent, int w) { - path.add(ent); + edges.add(ent); weight += w; } public void remove(int w) { - path.removeLast(); + edges.removeLast(); weight -= w; } @@ -100,12 +100,12 @@ public Node lastNode() { } public Edge get(int n) { - return path.get(n); + return edges.get(n); } // Edge or EdgeInv public Edge getEdge(int n) { - Edge ent = path.get(n); + Edge ent = edges.get(n); if (ent instanceof EdgeInv) { return ent; } @@ -113,25 +113,25 @@ public Edge getEdge(int n) { } public Path copy(Producer p) { - Path path = new Path(size()); - for (Edge ent : this.path) { + Path copy = new Path(size()); + for (Edge ent : this.edges) { // when r is reverse, add real target relation - if (ent instanceof EdgeInv) { - ent = ((EdgeInv) ent).getEdgeEntity(); + if (ent instanceof EdgeInv inverseEdge) { + ent = inverseEdge.getEdgeEntity(); } - path.add(p.copy(ent)); + copy.add(p.copy(ent)); } - path.setWeight(weight); - return path; + copy.setWeight(weight); + return copy; } public int length() { - return path.size(); + return edges.size(); } @Override public int size() { - return path.size(); + return edges.size(); } public int weight() { @@ -144,20 +144,20 @@ void setWeight(int w) { public Path reverse() { for (int i = 0; i < length() / 2; i++) { - Edge tmp = path.get(i); - path.set(i, path.get(length() - i - 1)); - path.set(length() - i - 1, tmp); + Edge tmp = edges.get(i); + edges.set(i, edges.get(length() - i - 1)); + edges.set(length() - i - 1, tmp); } return this; } @Override public String toString() { - StringBuilder str = new StringBuilder("path[" + path.size() + "]{"); - if (path.size() > 1) { + StringBuilder str = new StringBuilder("path[" + edges.size() + "]{"); + if (edges.size() > 1) { str.append("\n"); } - for (Edge edge : path) { + for (Edge edge : edges) { str.append(edge).append("\n"); } str.append("}"); @@ -166,16 +166,16 @@ public String toString() { @Override public Iterable getEdges(Node gNode, List from, Edge qEdge, Environment env) { - return path; + return edges; } @Override public Iterable getLoop() { - return path; + return edges; } @Override - public Edge getValue(String var, int n) { - return path.get(n); + public Edge getValue(String variable, int n) { + return edges.get(n); } } \ No newline at end of file diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/PathFinder.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/path/PathFinder.java similarity index 96% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/PathFinder.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/path/PathFinder.java index e7cab410a..d3c70b482 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/PathFinder.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/path/PathFinder.java @@ -1,17 +1,22 @@ -package fr.inria.corese.core.next.query.impl.kgram.path; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Filter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Regex; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Evaluator; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Matcher; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; +package fr.inria.corese.core.next.query.impl.engine.path; + +import fr.inria.corese.core.next.query.impl.engine.eval.Eval; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; +import fr.inria.corese.core.next.query.impl.engine.solution.Memory; + +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Filter; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Regex; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Evaluator; +import fr.inria.corese.core.next.query.impl.engine.spi.Matcher; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; import fr.inria.corese.core.next.query.api.exception.QueryException; -import fr.inria.corese.core.next.query.impl.kgram.core.*; -import fr.inria.corese.core.next.query.impl.kgram.event.ResultListener; -import fr.inria.corese.core.next.query.impl.kgram.tool.EdgeInv; +import fr.inria.corese.core.next.query.impl.engine.event.ResultListener; +import fr.inria.corese.core.next.query.impl.engine.model.EdgeInv; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/PathMappingBuffer.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/path/PathMappingBuffer.java similarity index 69% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/PathMappingBuffer.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/path/PathMappingBuffer.java index a7c8a1dcb..163e9bc46 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/PathMappingBuffer.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/path/PathMappingBuffer.java @@ -1,8 +1,9 @@ -package fr.inria.corese.core.next.query.impl.kgram.path; +package fr.inria.corese.core.next.query.impl.engine.path; -import fr.inria.corese.core.next.query.impl.kgram.core.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; import java.util.Iterator; +import java.util.NoSuchElementException; /** * Synchronized buffer to put/get path edges @@ -11,6 +12,8 @@ * @author Olivier Corby, Edelweiss, INRIA 2010 * */ +// A producer/consumer stream is consumed once; replay would require unbounded buffering. +@SuppressWarnings("java:S4348") public class PathMappingBuffer implements Iterable, Iterator { private Mapping map; @@ -18,16 +21,11 @@ public class PathMappingBuffer implements Iterable, Iterator { private boolean available = false; public synchronized Mapping next() { - while (!available) { - try { - wait(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - return null; - } - } + if (!hasNext()) { + throw new NoSuchElementException("Path enumeration has ended"); + } available = false; - notify(); + notifyAll(); return map; } @@ -40,7 +38,7 @@ public synchronized boolean hasNext() { return false; } } - notify(); + notifyAll(); return hasNext; } @@ -56,7 +54,7 @@ public synchronized void put(Mapping val, boolean next) { map = val; hasNext = next; available = true; - notify(); + notifyAll(); } @Override @@ -65,9 +63,4 @@ public Iterator iterator() { return this; } - @Override - @Deprecated - public void remove() { - throw new UnsupportedOperationException("Remove operation is not supported"); - } } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/Record.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/path/Record.java similarity index 77% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/Record.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/path/Record.java index bbf1c3311..3b6b88516 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/Record.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/path/Record.java @@ -1,7 +1,7 @@ -package fr.inria.corese.core.next.query.impl.kgram.path; +package fr.inria.corese.core.next.query.impl.engine.path; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Regex; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Regex; import java.util.ArrayList; @@ -10,12 +10,14 @@ * @author Olivier Corby, Edelweiss, INRIA 2011 * */ +// Execution metadata does not participate in List equality or serialization. +@SuppressWarnings("java:S2160") public class Record extends ArrayList { - Visit visit; - Node target; + transient Visit visit; + transient Node target; - ArrayList stack; + transient ArrayList stack; boolean success = false; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/Visit.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/path/Visit.java similarity index 91% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/Visit.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/path/Visit.java index 2f02ac460..254f562a9 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/Visit.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/path/Visit.java @@ -1,9 +1,12 @@ -package fr.inria.corese.core.next.query.impl.kgram.path; +package fr.inria.corese.core.next.query.impl.engine.path; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Regex; - -import java.util.*; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Regex; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.TreeMap; /** * Record intermediate nodes that are visited by a loop path expression such as @@ -13,7 +16,7 @@ * */ public class Visit { - int count = 0; + int nextVisitId = 0; ExpVisitedNode visitedNode; HashMap ctable; @@ -22,9 +25,9 @@ public class Visit { LTable ltable; ArrayList regexList; - boolean isReverse, - // isCounting = false : new sparql semantics - isCounting; + boolean isReverse; + // isCounting = false: SPARQL semantics without path counting + boolean isCounting; Visit(boolean isRev, boolean isCount) { isCounting = isCount; @@ -45,6 +48,8 @@ static class NodeTable extends TreeMap { } } + // Traversal direction is metadata; equality must retain the Map contract. + @SuppressWarnings("java:S2160") class ExpVisitedNode extends HashMap { boolean isReverse; @@ -55,7 +60,7 @@ class ExpVisitedNode extends HashMap { void add(Regex exp, Node n) { VisitedNode t = get(exp); if (t == null) { - t = new VisitedNode(isReverse, count++); + t = new VisitedNode(isReverse, nextVisitId++); put(exp, t); } t.add(n); @@ -149,10 +154,8 @@ boolean loop(Regex exp, Node n) { for (int i = last; i >= 0; i--) { if (count == min) { node = list.get(i); - } else { - if (list.get(i).equals(node)) { - return true; - } + } else if (list.get(i).equals(node)) { + return true; } count++; } @@ -174,8 +177,7 @@ static class DTable extends TreeMap { static class Compare implements Comparator { - // TODO: xsd:integer & xsd:decimal may be considered as same node - // in loop checking + // Use the node ordering consistently for loop detection. public int compare(Node o1, Node o2) { return o1.compare(o2); } @@ -336,11 +338,7 @@ boolean isDistinct(Node start, Node node) { } void addDistinct(Node start, Node node) { - NodeTable t = tdistinct.get(start); - if (t == null) { - t = new NodeTable(); - tdistinct.put(start, t); - } + NodeTable t = tdistinct.computeIfAbsent(start, key -> new NodeTable()); t.put(node, node); } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/path/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/path/package-info.java new file mode 100644 index 000000000..40705c31b --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/path/package-info.java @@ -0,0 +1,4 @@ +/** + * Property path evaluation algorithms and path mapping buffers. + */ +package fr.inria.corese.core.next.query.impl.engine.path; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/BgpGenerator.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/BgpGenerator.java similarity index 50% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/BgpGenerator.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/BgpGenerator.java index 985296ecb..5ade9ec1d 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/BgpGenerator.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/BgpGenerator.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.pattern; public interface BgpGenerator { diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Exp.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/Exp.java similarity index 95% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Exp.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/Exp.java index fb2cb4777..7e1da494f 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Exp.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/Exp.java @@ -1,15 +1,19 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExpPattern; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExpType; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExprType; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Filter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.core.PointerType; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Regex; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; +package fr.inria.corese.core.next.query.impl.engine.pattern; +import fr.inria.corese.core.next.query.impl.engine.eval.PointerObject; +import fr.inria.corese.core.next.query.impl.engine.eval.Stack; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; + +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.ExpPattern; +import fr.inria.corese.core.next.query.impl.engine.model.ExpType; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.ExprType; +import fr.inria.corese.core.next.query.impl.engine.model.Filter; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.model.PointerType; +import fr.inria.corese.core.next.query.impl.engine.model.Regex; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; import fr.inria.corese.core.next.query.impl.sparql.ast.TermAst; import java.util.ArrayList; @@ -17,7 +21,7 @@ import java.util.Iterator; import java.util.List; -import static fr.inria.corese.core.next.query.impl.kgram.api.core.PointerType.STATEMENT; +import static fr.inria.corese.core.next.query.impl.engine.model.PointerType.STATEMENT; /** * KGRAM/SPARQL expressions: bgp, union, optional, etc. @@ -730,7 +734,7 @@ boolean distinct(Node qNode) { return false; } - boolean isSortable() { + public boolean isSortable() { return isEdge() || isPath() || isGraph() || type == Type.OPT_BIND; } @@ -744,7 +748,7 @@ boolean isSimple() { /** * Does edge e have a node bound by map (bindings) */ - boolean bind(Mapping map) { + public boolean bind(Mapping map) { if (!isEdge()) { return false; } @@ -763,7 +767,7 @@ boolean bind(Mapping map) { * check special case: e1: ?x path ?y e2: graph path {} e2 cannot be moved * before e1 */ - boolean isGraphPath(Exp e1, Exp e2) { + public boolean isGraphPath(Exp e1, Exp e2) { if (e1.isPath() && e2.isGraph()) { Node var1 = e1.getEdge().getEdgeVariable(); Node var2 = e2.getGraphName(); @@ -823,7 +827,7 @@ boolean member(Node node, List lBind) { * list of nodes that are bound by this exp no minus and no exists * use case: Sorter */ - void bind(List lNode) { + public void bind(List lNode) { if (isSimple()) { for (int i = 0; i < nbNode(); i++) { Node bindNode = getNode(i); @@ -845,7 +849,7 @@ void bind(Node node, List lNode) { } } - void addBind(List lVar) { + public void addBind(List lVar) { Type title = type(); if (title == Type.EDGE || title == Type.PATH) { for (int i = 0; i < nbNode(); i++) { @@ -1290,14 +1294,14 @@ public void getFilterVar(List list, boolean excludeLocal) { } } - boolean isBindCst() { + public boolean isBindCst() { return type() == Type.OPT_BIND && size() == 1; } /** * Add BIND ?x = ?y */ - List varBind() { + public List varBind() { List lBind = new ArrayList<>(); for (Exp f : this) { if ((f.type() == Type.VALUES) || (f.isFilter() && f.size() > 0)) { @@ -1314,7 +1318,7 @@ List varBind() { /** * If a filter carry a bind, set the bind into its edge or path */ - void setBind() { + public void setBind() { for (int i = 1; i < size(); i++) { Exp f = get(i); if (f.isFilter() && f.size() > 0) { @@ -1353,15 +1357,15 @@ boolean bind(Node node) { return false; } - boolean hasCache() { + public boolean hasCache() { return mappingCache != null; } - void cache(Node n, Mappings m) { + public void cache(Node n, Mappings m) { mappingCache.put(n, m); } - Mappings getMappings(Node n) { + public Mappings getMappings(Node n) { return mappingCache.get(n); } @@ -1566,7 +1570,7 @@ public void setNumber(int number) { * if exp is, or starts with, a service, * pass Mappings map as parameter */ - boolean isRecFederate() { + public boolean isRecFederate() { if (isService()) { return true; } @@ -1590,11 +1594,11 @@ boolean isFederate2() { get(1).isRecFederate(); } - boolean isFirstWith() { + public boolean isFirstWith() { return type() == Type.UNION || (isBGPAnd() && size() > 0 && get(0).type() == Type.UNION); } - Exp complete(Mappings map) { + public Exp complete(Mappings map) { if (map == null || !map.isNodeList()) { return this; } @@ -1603,7 +1607,7 @@ Exp complete(Mappings map) { return res; } - Exp getValues(Mappings map) { + public Exp getValues(Mappings map) { return createValues(map.getNodeList(), map); } @@ -1648,7 +1652,7 @@ public void setNum(int num) { * minus, etc. * use case: join */ - void bindNodes() { + public void bindNodes() { for (Exp exp : getExpList()) { exp.setNodeList(exp.getInScopeNodes()); } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/ExpEdge.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/ExpEdge.java similarity index 69% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/ExpEdge.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/ExpEdge.java index 28210dbbd..8aa699fe3 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/ExpEdge.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/ExpEdge.java @@ -1,9 +1,9 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.pattern; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExprType; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Filter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.ExprType; +import fr.inria.corese.core.next.query.impl.engine.model.Filter; +import fr.inria.corese.core.next.query.impl.engine.model.Node; import java.util.ArrayList; import java.util.List; @@ -58,28 +58,27 @@ boolean match(Expr e, Node n, int node, int type) { } } return true; - } else if (e.match(type) && match(e, n, node)) { - if (e.arity() == 1) { - return true; - } else { - Expr cst = e.getExp(1); - if (cst.isConstant()) { - if (e.arity() == 3){ - // regex - return e.getExp(2).isConstant(); - } - return true; - } else if (e.oper() == ExprType.IN) { - for (Expr ee : cst.getExpList()) { - if (!ee.isConstant()) { - return false; - } - } - return true; - } + } + if (!e.match(type) || !match(e, n, node)) { + return false; + } + if (e.arity() == 1) { + return true; + } + Expr constant = e.getExp(1); + if (constant.isConstant()) { + return e.arity() != 3 || e.getExp(2).isConstant(); + } + return e.oper() == ExprType.IN && allConstant(constant.getExpList()); + } + + private boolean allConstant(List expressions) { + for (Expr expression : expressions) { + if (!expression.isConstant()) { + return false; } } - return false; + return true; } /** diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/ExpNodeCollector.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/ExpNodeCollector.java similarity index 97% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/ExpNodeCollector.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/ExpNodeCollector.java index 6c91c35b3..3bd266097 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/ExpNodeCollector.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/ExpNodeCollector.java @@ -1,6 +1,6 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.pattern; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Node; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Group.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/Group.java similarity index 86% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Group.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/Group.java index 450ba3301..14b34512f 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Group.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/Group.java @@ -1,8 +1,13 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.pattern; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.TreeMap; -import java.util.*; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; /** * select distinct ?x ?y select (count(distinct *) as ?c) @@ -15,7 +20,7 @@ */ public class Group implements Comparator { - private static final boolean compareIndex = false; + private static final boolean COMPARE_INDEX = false; TreeMapping table; boolean isDistinct = false; @@ -24,22 +29,19 @@ public class Group implements Comparator { private List nodes; private boolean isFake = false; - - Group() { + public Group() { } - - Group(List list) { + public Group(List list) { setNodeList(list); table = new TreeMapping(list); } public static boolean isCompareIndex() { - return compareIndex; + return COMPARE_INDEX; } - public static Group create(List lNode) { return new Group(lNode); } @@ -60,7 +62,6 @@ public void setFake(boolean afake) { this.isFake = afake; } - public List getNodeList() { return nodes; } @@ -76,12 +77,14 @@ public void setDistinct(boolean b) { public void setExtend(boolean b) { isExtend = b; } - @SuppressWarnings("unused") + public void setDuplicate(boolean b) { + // Duplicates are managed by the mappings collection, not this grouping + // comparator. } - @SuppressWarnings("unused") - boolean accept(Node node) { + @SuppressWarnings("java:S1172") + public boolean accept(Node node) { return true; } @@ -125,7 +128,7 @@ public boolean isDistinct(Mapping map) { return true; } - Iterable getValues() { + public Iterable getValues() { return table.values(); } @@ -208,5 +211,4 @@ int compare(Node n1, Node n2) { } } - } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Query.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/Query.java similarity index 96% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Query.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/Query.java index f4e3f3150..a822f732a 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Query.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/Query.java @@ -1,11 +1,16 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.*; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Filter; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Matcher; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; -import fr.inria.corese.core.next.query.impl.kgram.filter.Compile; -import fr.inria.corese.core.next.query.impl.kgram.tool.Message; +package fr.inria.corese.core.next.query.impl.engine.pattern; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.ExprType; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorter; + +import fr.inria.corese.core.next.query.impl.engine.model.Filter; +import fr.inria.corese.core.next.query.impl.engine.spi.Matcher; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; +import fr.inria.corese.core.next.query.impl.engine.filter.Compile; +import fr.inria.corese.core.next.query.impl.engine.eval.Message; import fr.inria.corese.core.next.query.impl.sparql.ast.QueryAst; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -264,7 +269,7 @@ public StringBuilder toString(StringBuilder sb) { } - Query get(Edge e) { + public Query get(Edge e) { return table.get(e); } @@ -325,7 +330,6 @@ void setError(String mes, Object obj, boolean duplicate) { } } } - //logger.error(str); errors.add(str); } } @@ -387,7 +391,7 @@ public Query getOuterQuery() { return outerQuery; } - boolean isSubQuery() { + public boolean isSubQuery() { return query != null; } @@ -401,7 +405,7 @@ public boolean isSelectExpression(){ return false; } - boolean isCheckLoop() { + public boolean isCheckLoop() { return isCheckLoop; } @@ -429,12 +433,12 @@ List getPathFilter() { return pathFilter; } - List getFunList(){ + public List getFunList(){ return funList; } - List getFrom(Node gNode) { + public List getFrom(Node gNode) { if (gNode == null) { return from; } else { @@ -950,11 +954,11 @@ public Query getQuery() { } - Node getOuterNode(Node subNode) { + public Node getOuterNode(Node subNode) { return getExtNode(subNode.getLabel()); } - Node getOuterNodeSelf(Node subNode) { + public Node getOuterNodeSelf(Node subNode) { Node n = getExtNode(subNode.getLabel()); if (n == null) { return subNode; @@ -1225,12 +1229,8 @@ int indexExpFilter(Query query, Exp exp, boolean isExist) { if (qNode == null) { // Note: does not work with filter in exists pattern // because getProperAndSubSelectNode does not go into exists pattern - if (!isTriple(exp, variable)) { - // no error message for use case: - // variable = ?_bn = <> - logger.warn(Message.Prefix.UNDEF_VAR.getString(), variable); - addError(Message.Prefix.UNDEF_VAR.getString(), variable); - } + logger.warn(Message.Prefix.UNDEF_VAR.getString(), variable); + addError(Message.Prefix.UNDEF_VAR.getString(), variable); } else if (!isExist && !hasExist) { int n = qIndex(query, qNode); min = Math.min(min, n); @@ -1504,9 +1504,7 @@ void setPPrinter(String p, Object transformer) { // next kg:pprint() will use this one this.transformer = transformer; } - if (! tprinter.containsKey(p)){ - tprinter.put(p, transformer); - } + tprinter.putIfAbsent(p, transformer); } } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/package-info.java new file mode 100644 index 000000000..7c374cb5e --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/package-info.java @@ -0,0 +1,4 @@ +/** + * Query execution plan representations, graph patterns, expressions, and group structures. + */ +package fr.inria.corese.core.next.query.impl.engine.pattern; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Mapping.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/Mapping.java similarity index 88% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Mapping.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/Mapping.java index 3a16c4599..69730a3b5 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Mapping.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/Mapping.java @@ -1,14 +1,30 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.*; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Result; -import fr.inria.corese.core.next.query.impl.kgram.path.Path; -import fr.inria.corese.core.next.query.impl.kgram.tool.EnvironmentImpl; +package fr.inria.corese.core.next.query.impl.engine.solution; + +import fr.inria.corese.core.next.query.impl.engine.eval.Eval; +import fr.inria.corese.core.next.query.impl.engine.model.BindingContext; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.ExprType; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.model.PointerType; +import fr.inria.corese.core.next.query.impl.engine.model.Pointerable; +import fr.inria.corese.core.next.query.impl.engine.model.TripleStore; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; + +import fr.inria.corese.core.next.query.impl.engine.spi.Result; +import fr.inria.corese.core.next.query.impl.engine.path.Path; +import fr.inria.corese.core.next.query.impl.engine.eval.EnvironmentImpl; import fr.inria.corese.core.next.data.api.model.DatatypeValue; -import java.util.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; -import static fr.inria.corese.core.next.query.impl.kgram.api.core.PointerType.MAPPING; +import static fr.inria.corese.core.next.query.impl.engine.model.PointerType.MAPPING; /** * An elementary result of a query or a subquery @@ -25,6 +41,7 @@ public final class Mapping extends EnvironmentImpl implements Result, Pointerable> { + private static final Logger LOGGER = LoggerFactory.getLogger(Mapping.class); static final Edge[] emptyEdge = new Edge[0]; static final Node[] emptyNode = new Node[0]; @@ -115,7 +132,7 @@ void init(List q, List t) { * Complete Mapping with select (exp as var) pragma: setNodeValue already * done */ - void complete(List q, List t) { + public void complete(List q, List t) { Node[] qn = new Node[getQueryNodes().length + q.size()]; Node[] tn = new Node[getTargetNodes().length + t.size()]; System.arraycopy(getQueryNodes(), 0, qn, 0, getQueryNodes().length); @@ -191,7 +208,7 @@ public Query getQuery() { return query; } - void setQuery(Query q) { + public void setQuery(Query q) { query = q; } @@ -200,7 +217,7 @@ public Map getMap() { return bnode; } - void setMap(Map m) { + public void setMap(Map m) { bnode = m; } @@ -208,16 +225,16 @@ public Node[] getOrderBy() { return getOrderByNodes(); } - void setOrderBy(Node[] nodes) { + public void setOrderBy(Node[] nodes) { setOrderByNodes(nodes); } - void setOrderBy(Node node) { + public void setOrderBy(Node node) { setOrderByNodes(new Node[1]); getOrderByNodes()[0] = node; } - void setGroupBy(Node[] nodes) { + public void setGroupBy(Node[] nodes) { setGroupByNodes(nodes); } @@ -292,12 +309,12 @@ void init() { /** * min(?l, groupBy(?x, ?y)) store value of ?x ?y in an array */ - void setGroup(List list) { + public void setGroup(List list) { setGroupAlter(new Node[list.size()]); set(list, getGroupAlter()); } - void computeDistinct(List list) { + public void computeDistinct(List list) { setDistinctNodes(new Node[list.size()]); set(list, getDistinctNodes()); } @@ -310,11 +327,11 @@ void set(List list, Node[] array) { } } - Node[] getGroupNodes() { + public Node[] getGroupNodes() { return getGroupAlter(); } - Node getDistinctNode(int n) { + public Node getDistinctNode(int n) { return getDistinctNodes()[n]; } @@ -612,6 +629,9 @@ boolean compatible1(Mapping map) { if (node.isVariable()) { Node val1 = getNodeValue(node); Node val2 = map.getNodeValue(node); + if (val1 == null || val2 == null) { + continue; + } if (!val1.match(val2)) { // was same return false; } else { @@ -624,23 +644,26 @@ boolean compatible1(Mapping map) { boolean compatible2(Mapping map) { boolean sameVarValue = false; - for (Node node1 : getSelectQueryNodes()) { - if (node1.isVariable()) { - Node node2 = map.getSelectQueryNode(node1.getLabel()); - if (node2 != null) { - Node val1 = getNodeValue(node1); - Node val2 = map.getNodeValue(node2); - if (!val1.match(val2)) { // was same + for (Node node : getSelectQueryNodes()) { + if (node.isVariable()) { + Node val1 = getNodeValue(node); + Node val2 = selectedValue(map, node); + if (val1 != null && val2 != null) { + if (!val1.match(val2)) { return false; - } else { - sameVarValue = true; } + sameVarValue = true; } } } return sameVarValue; } + private Node selectedValue(Mapping map, Node node) { + Node selectedNode = map.getSelectQueryNode(node.getLabel()); + return selectedNode == null ? null : map.getNodeValue(selectedNode); + } + /** * Warning: do not cache this index because index may vary between mappings */ @@ -677,7 +700,7 @@ Node getQueryNode(Node node) { return getQueryNode(node.getLabel()); } - Node getCommonNode(Mapping m) { + public Node getCommonNode(Mapping m) { for (Node q1 : getQueryNodes()) { if (q1.isVariable()) { Node q2 = m.getQueryNode(q1); @@ -723,7 +746,7 @@ public boolean isBound(Node qNode) { * ******************************************************************** */ - Node[] getSelectQueryNodes() { + public Node[] getSelectQueryNodes() { if (getSelect() != null) { return getSelect(); } else { @@ -740,9 +763,12 @@ public Mapping join(Mapping m) { Node q2 = m.getSelectQueryNode(q1.getLabel()); if (q2 != null) { Node n2 = m.getNodeValue(q2); - if (!n1.match(n2)) { // was same + if (n1 != null && n2 != null && !n1.match(n2)) { return null; } + if (n1 == null) { + n1 = n2; + } } qNodes.add(q1); tNodes.add(n1); @@ -761,7 +787,7 @@ public Mapping join(Mapping m) { return new Mapping(qNodes, tNodes); } - Mapping merge(Mapping m) { + public Mapping merge(Mapping m) { if (!isMergeAble(m)) { return null; } @@ -834,7 +860,7 @@ public boolean hasBind() { @Override public Node get(Expr varExpr) { if (getBind() == null) { - Eval.logger.error("Mapping unbound ldscript variable: {}", varExpr); + LOGGER.error("Mapping unbound ldscript variable: {}", varExpr); return null; } return (Node) getBind().get(varExpr); @@ -847,12 +873,12 @@ public PointerType pointerType() { @Override public Edge getEdge() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public TripleStore getTripleStore() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/MappingSet.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/MappingSet.java similarity index 71% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/MappingSet.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/MappingSet.java index 84bcd2871..0796cc5ca 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/MappingSet.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/MappingSet.java @@ -1,11 +1,15 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.solution; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; + +import fr.inria.corese.core.next.query.impl.engine.model.Node; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.NoSuchElementException; /** * Utilitary class for Join Minus Optional @@ -33,25 +37,24 @@ public class MappingSet { HashMap intersection; // intersection of variables List varList; boolean isBound = false; - private Query query; - MappingSet(Query q, Exp exp, MappingSet s1, MappingSet s2) { + public MappingSet(Query q, Exp exp, MappingSet s1, MappingSet s2) { this.exp = exp; this.set1 = s1; this.set2 = s2; setQuery(q); } - MappingSet(Query q, Mappings map) { - this.map = map; + public MappingSet(Query q, Mappings mappings) { + this.map = mappings; union = new HashMap<>(); intersection = new HashMap<>(); setQuery(q); process(); } - Mappings getMappings() { + public Mappings getMappings() { return map; } @@ -65,8 +68,8 @@ List computeVarList() { /** * Common variables bound in every Mapping in map1 and map2 ? */ - boolean isBound(List varList) { - return set1.inIntersection(varList) && set2.inIntersection(varList); + boolean checkBound(List vars) { + return set1.inIntersection(vars) && set2.inIntersection(vars); } boolean hasIntersection(List nodeList) { @@ -78,9 +81,9 @@ boolean hasIntersection(List nodeList) { return false; } - void start() { + public void start() { varList = computeVarList(); - isBound = isBound(varList); + isBound = checkBound(varList); if (isBound) { set2.getMappings().sort(varList); @@ -111,9 +114,9 @@ public String toString() { * else return all Mappings * PRAGMA: if isBound, map2 has been sorted by start() above */ - Iterable getCandidateMappings(Mapping m) { + public Iterable getCandidateMappings(Mapping m) { if (isBound) { - return new Iterate(m); + return () -> new Iterate(m); } return set2.getMappings(); } @@ -121,18 +124,18 @@ Iterable getCandidateMappings(Mapping m) { /** * Is there one Mapping in map2 minus compatible with map in map1 */ - boolean minusCompatible(Mapping map) { + public boolean minusCompatible(Mapping targetMap) { if (varList.isEmpty()) { // no common variables return false; } else { if (isBound) { // check map compatible by dichotomy in map2 - return set2.getMappings().minusCompatible(map, varList); + return set2.getMappings().minusCompatible(targetMap, varList); } else { for (Mapping minus : set2.getMappings()) { // enumerate map2 - if (map.minusCompatible(minus, varList)) { + if (targetMap.minusCompatible(minus, varList)) { return true; } } @@ -142,22 +145,22 @@ boolean minusCompatible(Mapping map) { } List intersectionOfUnion(MappingSet model) { - ArrayList varList = new ArrayList<>(); - for (String var : getUnion().keySet()) { - if (model.getUnion().containsKey(var)) { - varList.add(var); + ArrayList commonVars = new ArrayList<>(); + for (String v : getUnion().keySet()) { + if (model.getUnion().containsKey(v)) { + commonVars.add(v); } } - return varList; + return commonVars; } - boolean inIntersection(List varList) { - return inSet(varList, getIntersection()); + boolean inIntersection(List vars) { + return inSet(vars, getIntersection()); } - boolean inSet(List varList, HashMap table) { - for (String var : varList) { - if (!table.containsKey(var)) { + boolean inSet(List vars, HashMap table) { + for (String v : vars) { + if (!table.containsKey(v)) { return false; } } @@ -205,61 +208,56 @@ void process() { * right arg of an optional in exp and skip statements after first * union/minus/optional/graph in exp */ - Mappings prepareMappingsRest(Exp exp) { - List nodeListInScope = exp.getRecordInScopeNodesWithoutBind(); + public Mappings prepareMappingsRest(Exp expression) { + List nodeListInScope = expression.getRecordInScopeNodesWithoutBind(); if (!nodeListInScope.isEmpty() && hasIntersection(nodeListInScope)) { // generate values when at least one variable in-subscope is always // bound in map1, otherwise it would generate duplicates in map2 // or impose irrelevant bindings - // map = select distinct map1 wrt exp inscope nodes - Mappings map = getMappings().distinct(nodeListInScope); - map.setNodeList(nodeListInScope); + // Select distinct map1 with respect to expression in-scope nodes + Mappings distinctMap = getMappings().distinct(nodeListInScope); + distinctMap.setNodeList(nodeListInScope); // record original Mappings because union in exp may process it // more precisely. see Eval unionData() - // s p o {s q r} union {o q r} - // map node list = {r} + // Each UNION branch may need a different join variable. // whereas we can get s for first branch and o for second branch // this is why we record original Mappings for union in exp if any - map.setJoinMappings(getMappings()); - return map; + distinctMap.setJoinMappings(getMappings()); + return distinctMap; } // there is no in-scope variable. // return original Mappings in case of union in exp (see comment above) - return getMappings(); // return null + return getMappings(); } public void setQuery(Query query) { - this.query = query; + // query is kept for compatibility } - class Iterate implements Iterable, Iterator { + class Iterate implements Iterator { int n; Mapping m; - Mappings map; + Mappings targetMap; Iterate(Mapping m) { - map = set2.getMappings(); - this.n = map.find(m, varList); + targetMap = set2.getMappings(); + this.n = targetMap.find(m, varList); this.m = m; } @Override public boolean hasNext() { - return n >= 0 && n < map.size() && map.get(n).optionalCompatible(m, varList); + return n >= 0 && n < targetMap.size() && targetMap.get(n).optionalCompatible(m, varList); } @Override public Mapping next() { - return map.get(n++); - } - - @Override - @SuppressWarnings("NullableProblems") - public Iterator iterator() { - return this; + if (!hasNext()) { + throw new NoSuchElementException(); + } + return targetMap.get(n++); } } - } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Mappings.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/Mappings.java similarity index 94% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Mappings.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/Mappings.java index 730732b83..9df514c41 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Mappings.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/Mappings.java @@ -1,17 +1,31 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.*; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Evaluator; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; -import fr.inria.corese.core.next.query.impl.kgram.event.Event; -import fr.inria.corese.core.next.query.impl.kgram.event.EventImpl; -import fr.inria.corese.core.next.query.impl.kgram.event.KgramEventDispatcher; +package fr.inria.corese.core.next.query.impl.engine.solution; + +import fr.inria.corese.core.next.query.impl.engine.eval.Eval; +import fr.inria.corese.core.next.query.impl.engine.eval.PointerObject; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Filter; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.model.PointerType; +import fr.inria.corese.core.next.query.impl.engine.model.TripleStore; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Group; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; + +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Evaluator; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; +import fr.inria.corese.core.next.query.impl.engine.event.Event; +import fr.inria.corese.core.next.query.impl.engine.event.EventImpl; +import fr.inria.corese.core.next.query.impl.engine.event.KgramEventDispatcher; import fr.inria.corese.core.next.data.api.model.DatatypeValue; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Map; -import java.util.*; - -import static fr.inria.corese.core.next.query.impl.kgram.api.core.PointerType.MAPPINGS; +import static fr.inria.corese.core.next.query.impl.engine.model.PointerType.MAPPINGS; /** * Manage list of Mapping, result of a query @@ -96,7 +110,7 @@ public static Mappings create(Query q, boolean subEval) { } - void setEventManager(KgramEventDispatcher man) { + public void setEventManager(KgramEventDispatcher man) { manager = man; hasEvent = true; } @@ -188,7 +202,7 @@ public Mappings add(Mapping m) { return this; } - List getList() { + public List getList() { return getMappingList(); } @@ -219,7 +233,7 @@ public Mapping set(int n, Mapping m) { return getMappingList().set(n, m); } - void remove(int n) { + public void remove(int n) { getMappingList().remove(n); } @@ -344,7 +358,7 @@ public void submit(Mapping a) { } } - boolean acceptable(Mapping m) { + public boolean acceptable(Mapping m) { return getQuery().isAggregate() || accept(m); } @@ -362,7 +376,7 @@ void submit2(Mapping a) { } - boolean accept(Node node) { + public boolean accept(Node node) { return getDistinct() == null || getDistinct().accept(node); } @@ -456,12 +470,12 @@ void sort() { * Sort according to node * use case: join(exp, exp) */ - void sort(Eval eval, Node node) { + public void sort(Eval eval, Node node) { prepare(node); sort(eval); } - void sort(Node node) { + public void sort(Node node) { prepare(node); sort(); } @@ -475,7 +489,7 @@ void prepare(Node node) { // find index of node where qnode=node // with standard sort - int find(Node node, Node qnode) { + public int find(Node node, Node qnode) { return find(node, qnode, 0, size() - 1); } @@ -837,7 +851,7 @@ void having(Evaluator eval, Exp exp, Memory mem, Producer p, Group g) { /** * Template perform additionnal group_concat(?out) */ - void template(Evaluator eval, Memory mem, Producer p) { + public void template(Evaluator eval, Memory mem, Producer p) { template(eval, getQuery(), mem, p); } @@ -1019,7 +1033,7 @@ private Node minmax(Node qNode, boolean isMax) { * ******************************************************************** */ - Node getCommonNode(Mappings map) { + public Node getCommonNode(Mappings map) { if (isEmpty() || map.isEmpty()) { return null; } @@ -1272,7 +1286,7 @@ public Mappings setFake(boolean isFake) { return this; } - boolean isNodeList() { + public boolean isNodeList() { return size() != 0 && getNodeList() != null && !getNodeList().isEmpty(); } @@ -1304,7 +1318,7 @@ public void setProvenance(Object provenance) { this.provenance = provenance; } - void setNamedGraph(Node node) { + public void setNamedGraph(Node node) { for (Mapping m : this) { m.setNamedGraph(node); } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Memory.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/Memory.java similarity index 92% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Memory.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/Memory.java index 767844731..7806786b2 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Memory.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/Memory.java @@ -1,10 +1,25 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.*; -import fr.inria.corese.core.next.query.impl.kgram.api.query.*; -import fr.inria.corese.core.next.query.impl.kgram.event.KgramEventDispatcher; -import fr.inria.corese.core.next.query.impl.kgram.path.Path; -import fr.inria.corese.core.next.query.impl.kgram.tool.ApproximateSearchEnv; +package fr.inria.corese.core.next.query.impl.engine.solution; + +import fr.inria.corese.core.next.query.impl.engine.eval.Eval; +import fr.inria.corese.core.next.query.impl.engine.eval.PointerObject; +import fr.inria.corese.core.next.query.impl.engine.eval.Stack; +import fr.inria.corese.core.next.query.impl.engine.event.ProcessVisitor; +import fr.inria.corese.core.next.query.impl.engine.model.BindingContext; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.ExprType; +import fr.inria.corese.core.next.query.impl.engine.model.Filter; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Evaluator; +import fr.inria.corese.core.next.query.impl.engine.spi.Matcher; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; + +import fr.inria.corese.core.next.query.impl.engine.event.KgramEventDispatcher; +import fr.inria.corese.core.next.query.impl.engine.path.Path; +import fr.inria.corese.core.next.query.impl.engine.eval.ApproximateSearchEnv; import fr.inria.corese.core.next.data.api.model.DatatypeValue; import java.util.ArrayList; @@ -79,7 +94,7 @@ public KgramEventDispatcher getEventManager() { return manager; } - void setEventManager(KgramEventDispatcher man) { + public void setEventManager(KgramEventDispatcher man) { manager = man; hasEvent = true; } @@ -235,7 +250,7 @@ Node getNode(String name, List list) { * Note: let ( .., exists pattern), * MUST push BGP solution and then push Bind */ - void copyInto(Query sub, Memory mem, Exp exp) { + public void copyInto(Query sub, Memory mem, Exp exp) { if (sub == null) { // exists pattern copyInto(mem, exp); @@ -259,7 +274,7 @@ void copyInto(Query sub, Memory mem, Exp exp) { * exists pattern * PRAGMA: when exists is in function, this memory is empty */ - void copyInto(Memory mem, Exp exp) { + public void copyInto(Memory mem, Exp exp) { if (hasBind()) { // bind ldscript variables as sparql // pattern matching variables @@ -278,7 +293,7 @@ public void share(BindingContext target, BindingContext source) { } } - void share(Memory source) { + public void share(Memory source) { share(getBind(), source.getBind()); } @@ -313,7 +328,7 @@ void copyInto(Node qNode, Memory mem) { } } - Mapping store(Query q, Producer p, boolean subEval) { + public Mapping store(Query q, Producer p, boolean subEval) { return store(q, p, subEval, false); } @@ -552,7 +567,7 @@ boolean push(Edge q, Edge ent, int n) { return push(null, q, ent, n); } - boolean push(Producer p, Edge q, Edge ent, int n) { + public boolean push(Producer p, Edge q, Edge ent, int n) { if (!pushNodes(p, q, ent, n)) { return false; } @@ -622,7 +637,7 @@ public boolean push(Node node, Node target) { /** * n is the index in Exp stack where Node is bound */ - boolean push(Node node, Node target, int n) { + public boolean push(Node node, Node target, int n) { if (node.isConstant()) { return true; } @@ -668,7 +683,7 @@ public void pop(Node node) { * max index where edge nodes are bound first * hence where to backjump when edge fails */ - int getIndex(Node gNode, Edge edge) { + public int getIndex(Node gNode, Edge edge) { int max = -1; int length = edge.nbNode(); for (int i = 0; i < length; i++) { @@ -696,7 +711,7 @@ int getIndex(Node gNode, Edge edge) { return max; } - int getIndex(List lNodes) { + public int getIndex(List lNodes) { int max = -1; for (Node node : lNodes) { int index = getIndex(node); @@ -708,11 +723,11 @@ int getIndex(List lNodes) { return max; } - int getIndex(Node node) { + public int getIndex(Node node) { return stackIndex[node.getIndex()]; } - void pop(Edge q) { + public void pop(Edge q) { popNode(q); if (isEdge) { popEdge(q); @@ -754,7 +769,7 @@ void popEdge(Edge q) { /** * Push elementary result in the memory */ - boolean push(Mapping res, int n) { + public boolean push(Mapping res, int n) { return push(res, n, isEdge); } @@ -773,11 +788,11 @@ void aggregate(Mapping map) { setMap(bnodeMap); } - boolean push(Mapping res, int n, boolean isEdge) { + public boolean push(Mapping res, int n, boolean isEdge) { return push(res, n, isEdge, true); } - boolean push(Mapping res, int n, boolean isEdge, boolean isBlank) { + public boolean push(Mapping res, int n, boolean isEdge, boolean isBlank) { if (!pushMappingNodes(res, n, isBlank)) { return false; } @@ -819,7 +834,7 @@ private boolean pushMappingEdges(Mapping res, int n) { /** * values (?x ?y) { unnest(exp) } exp returns Mappings map push ?x and ?y */ - boolean push(HashMap list, Mapping map, int n) { + public boolean push(Map list, Mapping map, int n) { int k = 0; for (Node qNode : map.getQueryNodes()) { if (qNode != null) { @@ -837,7 +852,7 @@ boolean push(HashMap list, Mapping map, int n) { return true; } - private void popPreviousNodes(HashMap list, Mapping map, int limit) { + private void popPreviousNodes(Map list, Mapping map, int limit) { for (int i = 0; i < limit; i++) { Node qq = map.getQueryNode(i); if (qq != null) { @@ -849,7 +864,7 @@ private void popPreviousNodes(HashMap list, Mapping map, int limit } } - void pop(HashMap list, Mapping map) { + public void pop(Map list, Mapping map) { for (Node qNode : map.getQueryNodes()) { if (qNode != null) { Node tNode = list.get(qNode.getLabel()); @@ -863,11 +878,11 @@ void pop(HashMap list, Mapping map) { /** * Pop elementary result */ - void pop(Mapping res) { + public void pop(Mapping res) { pop(res, true); } - void pop(Mapping res, boolean isEdge) { + public void pop(Mapping res, boolean isEdge) { for (Node qNode : res.getQueryNodes()) { if (qNode != null && qNode.getIndex() >= 0) { pop(qNode); diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/Merge.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/Merge.java new file mode 100644 index 000000000..76b47e180 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/Merge.java @@ -0,0 +1,120 @@ +package fr.inria.corese.core.next.query.impl.engine.solution; + +import fr.inria.corese.core.next.query.impl.engine.pattern.Group; + +import java.util.ArrayList; + + +/*********************************************** + * group by any + * group Mapping who share one node (from any variable) + * Connected components + * + * @author Olivier Corby, Edelweiss, INRIA 2011 + * + ***********************************************/ + +public class Merge extends Group { + + private final Mappings sourceMappings; + private ListMappings mergedList; + + Merge(Mappings lm) { + sourceMappings = lm; + } + + public static class ListMappings extends ArrayList { + private static final long serialVersionUID = 1L; + } + + @Override + public Iterable getValues() { + return mergedList; + } + + void merge() { + mergedList = merge(sourceMappings); + mergedList = merge(mergedList); + } + + /** + * Initialize + */ + ListMappings merge(Mappings inputMappings) { + ListMappings result = new ListMappings(); + + for (Mapping map : inputMappings) { + boolean found = false; + for (Mappings lm : result) { + if (match(lm, map)) { + lm.add(map); + found = true; + break; + } + } + + if (!found) { + Mappings lm = new Mappings(); + lm.add(map); + result.add(lm); + } + } + + return result; + } + + /** + * Every Mappings is made of connected Mapping + * Try to Merge Mappings that are connected + */ + ListMappings merge(ListMappings inputList) { + ListMappings currentList = inputList; + ListMappings nlist = null; + boolean hasMerge = true; + + while (hasMerge) { + nlist = new ListMappings(); + hasMerge = false; + for (Mappings lm1 : currentList) { + + boolean found = false; + for (Mappings lm2 : nlist) { + if (match(lm1, lm2)) { + lm2.add(lm1); + found = true; + hasMerge = true; + break; + } + } + + if (!found) { + nlist.add(lm1); + } + } + + currentList = nlist; + } + + return nlist; + } + + boolean match(Mappings lm1, Mappings lm2) { + for (Mapping map : lm1) { + if (match(lm2, map)) { + return true; + } + } + return false; + } + + // one node of map is contained in one Mapping of lm + boolean match(Mappings lmap, Mapping map) { + for (Mapping m : lmap) { + if (map.match(m)) { + return true; + } + } + return false; + } + +} diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/package-info.java new file mode 100644 index 000000000..46850c1da --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/solution/package-info.java @@ -0,0 +1,4 @@ +/** + * Query solution mappings, result sets, memory state, and binding tables. + */ +package fr.inria.corese.core.next.query.impl.engine.solution; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/AbstractCostModel.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/AbstractCostModel.java similarity index 91% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/AbstractCostModel.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/AbstractCostModel.java index 4ecb13f66..782230cde 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/AbstractCostModel.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/AbstractCostModel.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.sorter.core; +package fr.inria.corese.core.next.query.impl.engine.sorter; import java.util.List; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/BasicPatternGenerator.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/BasicPatternGenerator.java similarity index 83% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/BasicPatternGenerator.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/BasicPatternGenerator.java index 2e30f40fe..71d0e33ca 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/BasicPatternGenerator.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/BasicPatternGenerator.java @@ -1,8 +1,10 @@ -package fr.inria.corese.core.next.query.impl.kgram.sorter.impl.qpv1; - -import fr.inria.corese.core.next.query.impl.kgram.sorter.core.IProducerQP; - -import static fr.inria.corese.core.next.query.impl.kgram.sorter.core.QuerySorterConst.*; +package fr.inria.corese.core.next.query.impl.engine.sorter; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.BOUND; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.NA; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.OBJECT; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.PREDICATE; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.SUBJECT; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.UNBOUND; /** * Generate the basic patterns ordering by the selectivity acorrding to the size diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/DepthFirstBestSearch.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/DepthFirstBestSearch.java similarity index 93% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/DepthFirstBestSearch.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/DepthFirstBestSearch.java index 42aa79b58..6715d8948 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/DepthFirstBestSearch.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/DepthFirstBestSearch.java @@ -1,14 +1,13 @@ -package fr.inria.corese.core.next.query.impl.kgram.sorter.impl.qpv1; +package fr.inria.corese.core.next.query.impl.engine.sorter; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.sorter.core.*; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import static fr.inria.corese.core.next.query.impl.kgram.api.core.ExpType.Type; +import static fr.inria.corese.core.next.query.impl.engine.model.ExpType.Type; /** * An implementation for sorting the triple pattern depth-first & best greedy @@ -24,7 +23,9 @@ */ public class DepthFirstBestSearch implements ISort { - private final List visited, notVisited, binds; + private final List visited; + private final List notVisited; + private final List binds; private QPGraph g = null; public DepthFirstBestSearch() { @@ -138,7 +139,6 @@ private void queue(QPGNode minNode, Map pool) { //then add this filter just after these triple patterns private void addFilters() { List filters = this.g.getAllNodes(Type.FILTER); - //others.addAll(g.getNodeList(VALUES)); for (QPGNode f : filters) { //if there are no edges left linking to the filter (values, etc...) @@ -166,10 +166,8 @@ private void addValues(QPGNode min) { private void findAdjacentNodes(QPGNode minNode, Map pool) { //add adjacent unvisted nodes to a pool List lEdges = this.g.getEdges(minNode, QPGEdge.BI_DIRECT); - //final Map weights = new HashMap(); for (QPGEdge e : lEdges) { - //pool.add(e.get(minNode)); // get the linked node QPGNode linkedNode = e.get(minNode); //get the cost of the linked node diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/HeuristicsBasedEstimation.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/HeuristicsBasedEstimation.java similarity index 91% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/HeuristicsBasedEstimation.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/HeuristicsBasedEstimation.java index 6b403c910..eaf9eaf2e 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/HeuristicsBasedEstimation.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/HeuristicsBasedEstimation.java @@ -1,8 +1,7 @@ -package fr.inria.corese.core.next.query.impl.kgram.sorter.impl.qpv1; +package fr.inria.corese.core.next.query.impl.engine.sorter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExpType; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; -import fr.inria.corese.core.next.query.impl.kgram.sorter.core.*; +import fr.inria.corese.core.next.query.impl.engine.model.ExpType; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/IEstimate.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/IEstimate.java similarity index 82% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/IEstimate.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/IEstimate.java index a62630d5f..b2bc6786d 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/IEstimate.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/IEstimate.java @@ -1,6 +1,6 @@ -package fr.inria.corese.core.next.query.impl.kgram.sorter.core; +package fr.inria.corese.core.next.query.impl.engine.sorter; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; /** * Interface for estimating the cost of nodes and edges in QPGraph diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/IProducerQP.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/IProducerQP.java similarity index 91% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/IProducerQP.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/IProducerQP.java index 2ad619b3f..1e892f12e 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/IProducerQP.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/IProducerQP.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.sorter.core; +package fr.inria.corese.core.next.query.impl.engine.sorter; /** * Interface for calling Producer from kgraph, these methods are implemented diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/ISort.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/ISort.java similarity index 78% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/ISort.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/ISort.java index be63c435a..09a35a1ef 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/ISort.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/ISort.java @@ -1,6 +1,6 @@ -package fr.inria.corese.core.next.query.impl.kgram.sorter.core; +package fr.inria.corese.core.next.query.impl.engine.sorter; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; import java.util.List; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/QPGEdge.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QPGEdge.java similarity index 86% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/QPGEdge.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QPGEdge.java index 35dbbce16..261c69a26 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/QPGEdge.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QPGEdge.java @@ -1,6 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.sorter.core; - -import fr.inria.corese.core.next.query.impl.kgram.sorter.impl.qpv1.QPGEdgeCostModel; +package fr.inria.corese.core.next.query.impl.engine.sorter; import java.util.List; @@ -11,14 +9,13 @@ */ public class QPGEdge { - public final static int BI_DIRECT = 10; - public final static int SIMPLE = 20; + static final int BI_DIRECT = 10; + static final int SIMPLE = 20; private final QPGNode n1; private final QPGNode n2; private final AbstractCostModel costModel; private double cost = -1; - //private boolean directed = false; private final List variables; private int type; @@ -60,7 +57,12 @@ public void setType(int type) { * */ public QPGNode get(int in) { - return in == 0 ? n1 : (in == 1 ? n2 : null); + if (in == 0) { + return n1; + } else if (in == 1) { + return n2; + } + return null; } /** diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/QPGEdgeCostModel.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QPGEdgeCostModel.java similarity index 58% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/QPGEdgeCostModel.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QPGEdgeCostModel.java index 43644bc52..ac58c7557 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/QPGEdgeCostModel.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QPGEdgeCostModel.java @@ -1,12 +1,12 @@ -package fr.inria.corese.core.next.query.impl.kgram.sorter.impl.qpv1; +package fr.inria.corese.core.next.query.impl.engine.sorter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExpType; -import fr.inria.corese.core.next.query.impl.kgram.sorter.core.*; +import fr.inria.corese.core.next.query.impl.engine.model.ExpType; import java.util.List; - -import static fr.inria.corese.core.next.query.impl.kgram.sorter.core.QuerySorterConst.*; -import static fr.inria.corese.core.next.query.impl.kgram.sorter.core.IEstimate.MAX_COST; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.OBJECT; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.PREDICATE; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.SUBJECT; +import static fr.inria.corese.core.next.query.impl.engine.sorter.IEstimate.MAX_COST; /** * Cost model for QPG edge @@ -21,50 +21,54 @@ public class QPGEdgeCostModel extends AbstractCostModel { {OBJECT, OBJECT}, {SUBJECT, SUBJECT}, {PREDICATE, PREDICATE} }; private final QPGEdge edge; - private int Nshare = 0; - private int Jtype = -1; + private int nShare = 0; + private int jType = -1; public QPGEdgeCostModel(QPGEdge edge) { this.edge = edge; if (this.estimatable()) { - if(this.edge.get(0).getType()== ExpType.Type.EDGE &&this.edge.get(1).getType()== ExpType.Type.EDGE){ - this.setJtype(); + if (this.edge.get(0).getType() == ExpType.Type.EDGE && this.edge.get(1).getType() == ExpType.Type.EDGE) { + this.setJType(); } - this.setNshare(); + this.setNShare(); this.edge.setType(QPGEdge.BI_DIRECT); - }else{ + } else { this.edge.setType(QPGEdge.SIMPLE); } } - private void setNshare() { - this.Nshare = this.edge.getVariables().size(); + private void setNShare() { + this.nShare = this.edge.getVariables().size(); } - private void setJtype() { - QPGNode node1 = edge.get(0), node2 = edge.get(1); + private void setJType() { + QPGNode node1 = edge.get(0); + QPGNode node2 = edge.get(1); int[][] jp = JOINT_PATTERN; for (int i = 0; i < jp.length; i++) { - int p1 = jp[i][0], p2 = jp[i][1]; + int p1 = jp[i][0]; + int p2 = jp[i][1]; if (node1.getExpNode(p1).getLabel().equals(node2.getExpNode(p2).getLabel()) || node1.getExpNode(p2).getLabel().equals(node2.getExpNode(p1).getLabel())) { - Jtype = jp.length - i; + jType = jp.length - i; } } } @Override public void estimate(List params) { - if(!(isParametersOK(params) && estimatable())){ + if (!(isParametersOK(params) && estimatable())) { this.edge.setCost(IEstimate.NA_COST); return; } - QPGNode node1 = edge.get(0), node2 = edge.get(1); + QPGNode node1 = edge.get(0); + QPGNode node2 = edge.get(1); - ExpType.Type tNode1 = node1.getType(), tNode2 = node2.getType(); + ExpType.Type tNode1 = node1.getType(); + ExpType.Type tNode2 = node2.getType(); //1. type of one of them is FILTER or VALUES or BIND, ne assign pas le weight if (!QuerySorterConst.evaluable(tNode1) && !QuerySorterConst.evaluable(tNode2)) { this.edge.setCost(MAX_COST); @@ -72,31 +76,31 @@ public void estimate(List params) { } //3.2. no pattern matched: means no shared variables - if (Nshare == 0) { + if (nShare == 0) { this.edge.setCost(MAX_COST); return; } //2 The EDGE connects at least a GRAPH if (tNode1 == ExpType.Type.GRAPH || tNode2 == ExpType.Type.GRAPH) { - this.edge.setCost(1.0 / 3.0 * Nshare); + this.edge.setCost(1.0 / 3.0 * nShare); return; } //3. two EDGEs //3.2. no pattern matched: means no shared variables - if (Jtype == -1) { + if (jType == -1) { this.edge.setCost(MAX_COST); return; } //3.3 pattern matched, assign weight - this.edge.setCost(1.0 / Jtype / Nshare); + this.edge.setCost(1.0 / jType / nShare); } @Override public String toString() { - return "QPGEdgeWeightModel{" + "Nshare=" + Nshare + ", Jtype=" + Jtype + '}'; + return "QPGEdgeWeightModel{" + "nShare=" + nShare + ", jType=" + jType + '}'; } @Override @@ -105,7 +109,7 @@ public boolean isParametersOK(List params) { } @Override - final public boolean estimatable() { + public final boolean estimatable() { return QuerySorterConst.evaluable(this.edge.get(0).getType()) && QuerySorterConst.evaluable(this.edge.get(1).getType()); } } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/QPGNode.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QPGNode.java similarity index 84% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/QPGNode.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QPGNode.java index 9fcfca2a3..94ce6b234 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/QPGNode.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QPGNode.java @@ -1,17 +1,19 @@ -package fr.inria.corese.core.next.query.impl.kgram.sorter.core; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExpType; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Filter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.sorter.impl.qpv1.QPGNodeCostModel; - -import java.util.*; -import java.util.stream.Collectors; +package fr.inria.corese.core.next.query.impl.engine.sorter; + +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.ExpType; +import fr.inria.corese.core.next.query.impl.engine.model.Filter; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.LinkedHashSet; +import java.util.Set; import java.util.stream.Stream; - -import static fr.inria.corese.core.next.query.impl.kgram.sorter.core.QuerySorterConst.*; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.OBJECT; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.PREDICATE; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.SUBJECT; /** * The node for triple pattern graph, which encapsualtes an expression (contain @@ -129,7 +131,9 @@ public List shared(QPGNode bpn1, QPGNode bpn2) { return this.isShared(bpn2.exp.getNode(), bpn1.exp); } default: + break; } + break; case BIND: switch (type2) { case FILTER: @@ -144,7 +148,9 @@ public List shared(QPGNode bpn1, QPGNode bpn2) { return this.compare(bpn2.exp.getNode(), bpn1.exp.getNode()); } default: + break; } + break; default: break; } @@ -211,31 +217,34 @@ private List getVariablesInEdge(Edge e) { .filter(Objects::nonNull) .filter(Node::isVariable) .distinct() - .collect(Collectors.toList()); + .toList(); } - //GRAPH{GRAPHNODE{NODE{data:aliceFoaf } } AND{EDGE{?alice foaf:mbox } ...}} private List getVariablesInGraph(Exp graph) { Set uniqueVariables = new LinkedHashSet<>(); for (Exp outerExp : graph) { for (Exp innerExp : outerExp) { - if (innerExp.type() == ExpType.Type.NODE) { - Node node = innerExp.getNode(); - if (node != null && node.isVariable()) { - uniqueVariables.add(node); - } - } else if (innerExp.type() == ExpType.Type.EDGE) { - Edge edge = innerExp.getEdge(); - if (edge != null) { - uniqueVariables.addAll(getVariablesInEdge(edge)); - } - } + collectInnerVariables(innerExp, uniqueVariables); } } return new ArrayList<>(uniqueVariables); } + + private void collectInnerVariables(Exp innerExp, Set uniqueVariables) { + if (innerExp.type() == ExpType.Type.NODE) { + Node node = innerExp.getNode(); + if (node != null && node.isVariable()) { + uniqueVariables.add(node); + } + } else if (innerExp.type() == ExpType.Type.EDGE) { + Edge edge = innerExp.getEdge(); + if (edge != null) { + uniqueVariables.addAll(getVariablesInEdge(edge)); + } + } + } //compare between a list of strings and a list of nodes private List compareString(List l1, List l2) { List l = new ArrayList<>(); @@ -295,11 +304,10 @@ public String toString() { @Override public boolean equals(Object obj) { - if (!(obj instanceof QPGNode)) { - return false; - } else { - return this.exp.equals(((QPGNode) obj).exp); + if (obj instanceof QPGNode other) { + return this.exp.equals(other.exp); } + return false; } @Override diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/QPGNodeCostModel.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QPGNodeCostModel.java similarity index 75% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/QPGNodeCostModel.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QPGNodeCostModel.java index 61870355a..42ccfb9a6 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/QPGNodeCostModel.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QPGNodeCostModel.java @@ -1,17 +1,19 @@ -package fr.inria.corese.core.next.query.impl.kgram.sorter.impl.qpv1; +package fr.inria.corese.core.next.query.impl.engine.sorter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExpType; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.sorter.core.*; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.ExpType; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; import java.util.ArrayList; import java.util.List; - -import static fr.inria.corese.core.next.query.impl.kgram.sorter.core.QuerySorterConst.*; -import static fr.inria.corese.core.next.query.impl.kgram.sorter.core.IEstimate.MAX_COST; -import static fr.inria.corese.core.next.query.impl.kgram.sorter.core.IEstimate.MIN_COST_0; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.BOUND; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.LIST; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.NA; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.PREDICATE; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.UNBOUND; +import static fr.inria.corese.core.next.query.impl.engine.sorter.IEstimate.MAX_COST; +import static fr.inria.corese.core.next.query.impl.engine.sorter.IEstimate.MIN_COST_0; /** * Class for constructing the pattern of a triple, including many parameters @@ -24,8 +26,13 @@ public class QPGNodeCostModel extends AbstractCostModel { // the more the better (less selectivity) //FN: filter, variables appeared in how many filters //G: graph - private final static int S = 0, P = 1, O = 2, G = 3, FF = 4, FV = 5; - private final static int PARAMETER_LEN = 6; + private static final int S = 0; + private static final int P = 1; + private static final int O = 2; + private static final int G = 3; + private static final int FF = 4; + private static final int FV = 5; + private static final int PARAMETER_LEN = 6; //list of vairables appeared in the expression List variables = new ArrayList<>(); private final int[] pattern = new int[PARAMETER_LEN]; @@ -34,7 +41,6 @@ public class QPGNodeCostModel extends AbstractCostModel { public QPGNodeCostModel(QPGNode n, List bindings) { this.node = n; - //todo with GNode Node gNode; if (n.getType() == ExpType.Type.EDGE) { @@ -48,13 +54,11 @@ public QPGNodeCostModel(QPGNode n, List bindings) { // get the variables in the triple pattern n.getExp().getVariables(variables); - } else if (n.getType() == ExpType.Type.GRAPH) { - //obtain the graph node - if (n.getExp().size() > 0 && n.getExp().get(0).type() == ExpType.Type.GRAPHNODE) { - //GRAPH{GRAPHNODE{NODE{data:aliceFoaf } } AND...} - gNode = n.getExp().get(0).get(0).getNode(); - this.pattern[G] = getNodeType(gNode, bindings); - } + } else if (n.getType() == ExpType.Type.GRAPH + && n.getExp().size() > 0 + && n.getExp().get(0).type() == ExpType.Type.GRAPHNODE) { + gNode = n.getExp().get(0).get(0).getNode(); + this.pattern[G] = getNodeType(gNode, bindings); } } @@ -84,7 +88,10 @@ private int getNodeType(Node n, List bindings) { if (n == null) { return NA; } - return n.isVariable() ? (isBound(bindings, n) ? LIST : UNBOUND) : BOUND; + if (!n.isVariable()) { + return BOUND; + } + return isBound(bindings, n) ? LIST : UNBOUND; } /** @@ -103,7 +110,8 @@ public void setParameters(QPGraph graph) { private void setFilterNumber(QPGraph graph) { List nodes = graph.getAllNodes(ExpType.Type.FILTER); - int noOfFilter = 0, noOfVariable = 0; + int noOfFilter = 0; + int noOfVariable = 0; //1 get all variables in all filters List variablesInFilters = new ArrayList<>(); @@ -113,18 +121,8 @@ private void setFilterNumber(QPGraph graph) { List l = n.getExp().getFilter().getVariables(); variablesInFilters.addAll(l); - for (String var1 : l) { - boolean flag = false; - for (String var2 : variables) { - if (var1.equalsIgnoreCase(var2)) { - noOfFilter++; - flag = true; - break; - } - } - if (flag) { - break; - } + if (hasMatchingVariable(l, variables)) { + noOfFilter++; } } this.pattern[FF] = noOfFilter; @@ -141,6 +139,17 @@ private void setFilterNumber(QPGraph graph) { } + private boolean hasMatchingVariable(List filterVars, List targetVars) { + for (String var1 : filterVars) { + for (String var2 : targetVars) { + if (var1.equalsIgnoreCase(var2)) { + return true; + } + } + } + return false; + } + /** * Find match by using triple patterns list * @@ -171,6 +180,7 @@ public static void sort(List patterns, final int[][] bp, final } //order by selectivity asending(0-1) (more selective - less selective) + @SuppressWarnings("java:S3776") public static int compareModel(QPGNodeCostModel m1, QPGNodeCostModel m2, final int[][] bp, final IProducerQP ip) { //GRAPH //rule 1: GRAPH has more priority than EDGE @@ -233,11 +243,10 @@ public String toString() { return s.toString(); } - public boolean isBound(List bindings, Node var) { + public boolean isBound(List bindings, Node targetNode) { for (Exp exp : bindings) { - if (var.getLabel().equalsIgnoreCase(exp.get(0).getNode().getLabel())) { - //todo in future (or not)?? - //calculate the number of constants bound to this variable + if (targetNode.getLabel().equalsIgnoreCase(exp.get(0).getNode().getLabel())) { + // Calculate the number of constants bound to this variable if needed return true; } } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/QPGraph.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QPGraph.java similarity index 93% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/QPGraph.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QPGraph.java index 93583c371..5cd26c675 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/QPGraph.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QPGraph.java @@ -1,7 +1,7 @@ -package fr.inria.corese.core.next.query.impl.kgram.sorter.core; +package fr.inria.corese.core.next.query.impl.engine.sorter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExpType; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; +import fr.inria.corese.core.next.query.impl.engine.model.ExpType; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; import java.util.ArrayList; import java.util.HashMap; @@ -36,13 +36,6 @@ public QPGraph(List exps, List bindings) { createEdges(); } - // Encapsulate expression into BPGNode and add them to a list - private void createNodes(Exp exp) { - for (Exp ee : exp) { - nodes.add(new QPGNode(ee, this.bindings)); - } - } - // Encapsulate expression into BPGNode and add them to a list private void createNodes(List exps) { for (Exp ee : exps) { diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/QuerySorter.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QuerySorter.java similarity index 89% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/QuerySorter.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QuerySorter.java index 026a89cab..6594b7f9c 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/QuerySorter.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QuerySorter.java @@ -1,8 +1,14 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.*; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; -import fr.inria.corese.core.next.query.impl.kgram.filter.Compile; +package fr.inria.corese.core.next.query.impl.engine.sorter; +import fr.inria.corese.core.next.query.impl.engine.model.ExpType; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.ExprType; +import fr.inria.corese.core.next.query.impl.engine.model.Filter; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; + +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; +import fr.inria.corese.core.next.query.impl.engine.filter.Compile; import java.util.ArrayList; import java.util.List; @@ -21,8 +27,8 @@ public class QuerySorter implements ExpType { Compile compiler; private Producer prod; - //todo assign sorter here - QuerySorter(Query q) { + // Assign sorter according to query plan profile + public QuerySorter(Query q) { query = q; compiler = new Compile(q); setSort(q); @@ -42,7 +48,7 @@ void setSort(Query q) { * pattern in filter and bind including select, order by, group by and * having */ - void compile(Producer prod) { + public void compile(Producer prod) { this.setProducer(prod); VString bound = new VString(); compile(getQuery(), bound, false); @@ -80,23 +86,14 @@ Exp compile(Exp exp, VString varList, boolean option) { Type type = exp.type(); switch (type) { - case EDGE: - case PATH: - case XPATH: - case EVAL: - case NODE: - case GRAPHNODE: + case EDGE, PATH, XPATH, EVAL, NODE, GRAPHNODE: break; - case FILTER: + case FILTER, BIND: // compile inner exists {} if any compile(exp.getFilter(), varList, option); break; - case BIND: - compile(exp.getFilter(), varList, option); - break; - case QUERY: // match query and subquery Query q = exp.getQuery(); @@ -105,8 +102,8 @@ Exp compile(Exp exp, VString varList, boolean option) { // lVar = intersection(select variables,lVar) varList = getSelectVariables(q, varList); } + // fall through - continue with subquery body - // continue with subquery body default: if (type == Type.OPTIONAL || type == Type.UNION || type == Type.MINUS) { @@ -120,7 +117,7 @@ Exp compile(Exp exp, VString varList, boolean option) { // bind graph variable *after* exp sorting if (exp.isGraph() && exp.getGraphName().isVariable()) { - // GRAPH {GRAPHNODE NODE} {EXP} + // Bind graph pattern node variable Node gNode = exp.getGraphName(); varList.add(gNode.getLabel()); } @@ -137,7 +134,7 @@ Exp compile(Exp exp, VString varList, boolean option) { varList.clear(size); } - InScopeNodes(exp); + inScopeNodes(exp); return exp; } @@ -174,8 +171,7 @@ Exp queryPlan(Exp exp, VString lVar) { setBind(getQuery(), exp); break; - case Query.QP_BGP: - case Query.QP_DEFAULT: + case Query.QP_BGP, Query.QP_DEFAULT: // sort statements in connected order sort.sort(getQuery(), exp, lVar, lBind); // move filters @@ -187,6 +183,9 @@ Exp queryPlan(Exp exp, VString lVar) { exp = getQuery().getBgpGenerator().process(exp); } break; + + default: + break; } service(exp); } @@ -196,7 +195,7 @@ Exp queryPlan(Exp exp, VString lVar) { * Compute and record list of inscope variables * that may be bound to evaluate exp in an optimized way */ - void InScopeNodes(Exp exp) { + void inScopeNodes(Exp exp) { if (exp.isOptional()) { // A optional B // variables bound by A @@ -261,8 +260,7 @@ void compile(Expr exp, VString lVar, boolean opt) { void compile(List list) { for (Exp ee : list) { - // use case: group by (exists{?x :p ?y} as ?b) - // use case: order by exists{?x :p ?y} + // Case: group by or order by expression containing exists pattern if (ee.getFilter() != null) { compile(ee.getFilter()); } @@ -271,7 +269,8 @@ void compile(List list) { /** * Move filter at place where variables are bound in exp - */ + */ + @SuppressWarnings({"java:S3776", "java:S127"}) void sortFilter(Exp exp, VString varList) { int size = varList.size(); List filterVarList; @@ -460,9 +459,9 @@ void clear(int size) { } @Override - public boolean add(String var) { - if (!contains(var)) { - super.add(var); + public boolean add(String v) { + if (!contains(v)) { + super.add(v); } return true; } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QuerySorterConst.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QuerySorterConst.java new file mode 100644 index 000000000..700b92d1a --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/QuerySorterConst.java @@ -0,0 +1,49 @@ +package fr.inria.corese.core.next.query.impl.engine.sorter; + +import fr.inria.corese.core.next.query.impl.engine.model.ExpType; + +/** + * Constants + * + * @author Fuqi Song, Wimmics Inria I3S + */ +public final class QuerySorterConst { + + private QuerySorterConst() { + // Utility class + } + + static final int ALL = 0; + static final int SUBJECT = 1; + static final int PREDICATE = 2; + static final int OBJECT = 3; + static final int TRIPLE = 4; + static final int NA = -1; + + static final int BOUND = 0; + static final int LIST = 0; + static final int UNBOUND = Integer.MAX_VALUE; + + static final ExpType.Type[] EVALUABLE_TYPES = {ExpType.Type.EDGE, ExpType.Type.GRAPH}; + static final ExpType.Type[] NOT_EVALUABLE_TYPES = {ExpType.Type.FILTER, ExpType.Type.VALUES, ExpType.Type.BIND, ExpType.Type.OPTIONAL}; + + public static boolean plannable(ExpType.Type type) { + for (ExpType.Type e : NOT_EVALUABLE_TYPES) { + if (type == e) { + return true; + } + } + + return evaluable(type); + } + + public static boolean evaluable(ExpType.Type type) { + for (ExpType.Type e : EVALUABLE_TYPES) { + if (type == e) { + return true; + } + } + + return false; + } +} diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Sorter.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/Sorter.java similarity index 73% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Sorter.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/Sorter.java index db285acd5..c78b751c1 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Sorter.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/Sorter.java @@ -1,6 +1,10 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.sorter; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Node; import java.util.ArrayList; import java.util.List; @@ -14,6 +18,7 @@ public class Sorter { + @SuppressWarnings("java:S3776") public void sort(Query q, Exp exp, List lVar, List lBind) { List lNode = new ArrayList<>(); @@ -30,17 +35,14 @@ public void sort(Query q, Exp exp, List lVar, List lBind) { // cannot move option because it may bind free variables // that may influence next exp break; - } else if (e2.isSortable()) { - - if (shift(q, e1, e2, lNode, lVar, lBind)) { - // ej i; k--) { - // shift to the right - exp.set(k, exp.get(k - 1)); - } - exp.set(i, e2); - e1 = e2; + } else if (e2.isSortable() && shift(q, e1, e2, lNode, lVar, lBind)) { + // ej i; k--) { + // shift to the right + exp.set(k, exp.get(k - 1)); } + exp.set(i, e2); + e1 = e2; } } } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/SorterNew.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/SorterNew.java similarity index 60% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/SorterNew.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/SorterNew.java index e0401c58e..76b1cabf5 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/SorterNew.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/SorterNew.java @@ -1,13 +1,9 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.sorter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExpType; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; -import fr.inria.corese.core.next.query.impl.kgram.sorter.core.IEstimate; -import fr.inria.corese.core.next.query.impl.kgram.sorter.core.ISort; -import fr.inria.corese.core.next.query.impl.kgram.sorter.core.QPGNode; -import fr.inria.corese.core.next.query.impl.kgram.sorter.core.QPGraph; -import fr.inria.corese.core.next.query.impl.kgram.sorter.impl.qpv1.DepthFirstBestSearch; -import fr.inria.corese.core.next.query.impl.kgram.sorter.impl.qpv1.HeuristicsBasedEstimation; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; + +import fr.inria.corese.core.next.query.impl.engine.model.ExpType; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -15,7 +11,7 @@ import java.util.Map; import java.util.Map.Entry; -import static fr.inria.corese.core.next.query.impl.kgram.sorter.core.QuerySorterConst.plannable; +import static fr.inria.corese.core.next.query.impl.engine.sorter.QuerySorterConst.plannable; /** * A new sorter for QP @@ -23,15 +19,16 @@ */ public class SorterNew extends Sorter { + @SuppressWarnings("java:S3776") public void sort(Exp expression, List bindings, Producer prod) { if (expression.size() < 2) return; - Map> ESGs = tokenize(expression); - if (ESGs.isEmpty()) return; + Map> esgMap = tokenize(expression); + if (esgMap.isEmpty()) return; // === Iterate each sub set and create ESG and sorting === - for (Entry> entrySet : ESGs.entrySet()) { + for (Entry> entrySet : esgMap.entrySet()) { Integer startIndex = entrySet.getKey(); List exps = entrySet.getValue(); @@ -51,11 +48,9 @@ public void sort(Exp expression, List bindings, Producer prod) { List l = is.sort(bpg); - //** For the following case where a graph has a bound value, put the BIND before - //** the graph pattern (because normally we put BIND just after where its variable - //** is used. - //** bind ( as ?g) - //** graph ?g {?x ?p ?y} + // For the case where a graph has a bound value, put the BIND before + // the graph pattern (because normally we put BIND just after where its variable is used). + // Example: when binding a graph variable before a graph pattern List graphs = bpg.getAllNodes(ExpType.Type.GRAPH); for (QPGNode graph : graphs) { List linkedNodes = bpg.getLinkedNodes(graph); @@ -83,9 +78,9 @@ public void sort(Exp expression, List bindings, Producer prod) { // (4, ) // (8, ) private Map> tokenize(Exp e) { - List aESG = new ArrayList<>(); - Map> ESGs = new LinkedHashMap<>(); - ESGs.put(0, aESG); + List group = new ArrayList<>(); + Map> esgMap = new LinkedHashMap<>(); + esgMap.put(0, group); // == 1. split the expressions List exps = e.getExpList(); @@ -93,17 +88,17 @@ private Map> tokenize(Exp e) { Exp ee = exps.get(i); if (plannable(ee.type())) { if (i > 0 && !plannable(exps.get(i - 1).type())) { - aESG = new ArrayList<>(); - ESGs.put(i, aESG); + group = new ArrayList<>(); + esgMap.put(i, group); } - aESG.add(ee); + group.add(ee); } } // == 2.remove the ones containing less that 2 expressions - ESGs.entrySet().removeIf(integerListEntry -> integerListEntry.getValue().size() < 2); + esgMap.entrySet().removeIf(integerListEntry -> integerListEntry.getValue().size() < 2); - return ESGs; + return esgMap; } } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/package-info.java new file mode 100644 index 000000000..253fcb714 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/sorter/package-info.java @@ -0,0 +1,4 @@ +/** + * Query pattern optimization, heuristic reordering, and cost estimation models. + */ +package fr.inria.corese.core.next.query.impl.engine.sorter; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/AST.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/AST.java similarity index 79% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/AST.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/AST.java index 73c03952f..10df4a642 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/AST.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/AST.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.query; +package fr.inria.corese.core.next.query.impl.engine.spi; /** * Olivier Corby - Wimmics INRIA I3S - 2020 diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/DistributedQueryPlanFactory.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/DistributedQueryPlanFactory.java new file mode 100644 index 000000000..58939e397 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/DistributedQueryPlanFactory.java @@ -0,0 +1,12 @@ +package fr.inria.corese.core.next.query.impl.engine.spi; + +import fr.inria.corese.core.next.query.impl.engine.pattern.BgpGenerator; + +/** + * @author corby + */ +public interface DistributedQueryPlanFactory { + + BgpGenerator instance(); + +} diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Environment.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Environment.java similarity index 69% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Environment.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Environment.java index b3d716a9a..faf7b3d0b 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Environment.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Environment.java @@ -1,13 +1,19 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.query; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.BindingContext; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.core.*; -import fr.inria.corese.core.next.query.impl.kgram.event.KgramEventDispatcher; -import fr.inria.corese.core.next.query.impl.kgram.path.Path; -import fr.inria.corese.core.next.query.impl.kgram.tool.ApproximateSearchEnv; +package fr.inria.corese.core.next.query.impl.engine.spi; + +import fr.inria.corese.core.next.query.impl.engine.eval.Eval; +import fr.inria.corese.core.next.query.impl.engine.event.ProcessVisitor; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; + +import fr.inria.corese.core.next.query.impl.engine.model.BindingContext; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.event.KgramEventDispatcher; +import fr.inria.corese.core.next.query.impl.engine.path.Path; +import fr.inria.corese.core.next.query.impl.engine.eval.ApproximateSearchEnv; import fr.inria.corese.core.next.data.api.model.DatatypeValue; import java.util.Map; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Evaluator.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Evaluator.java similarity index 86% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Evaluator.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Evaluator.java index 38fb833e6..f50c2981f 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Evaluator.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Evaluator.java @@ -1,6 +1,6 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.query; +package fr.inria.corese.core.next.query.impl.engine.spi; -import fr.inria.corese.core.next.query.impl.kgram.core.Eval; +import fr.inria.corese.core.next.query.impl.engine.eval.Eval; import java.time.OffsetDateTime; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Graphable.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Graphable.java similarity index 72% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Graphable.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Graphable.java index 1b3ebc965..a2489b6a5 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Graphable.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Graphable.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.query; +package fr.inria.corese.core.next.query.impl.engine.spi; /** * Olivier Corby - Wimmics INRIA I3S - 2014 diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Matcher.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Matcher.java similarity index 89% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Matcher.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Matcher.java index 48142b816..7076499fd 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Matcher.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Matcher.java @@ -1,7 +1,7 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.query; +package fr.inria.corese.core.next.query.impl.engine.spi; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Node; /** * Interface for the Matcher that checks conformity of candidate edges and nodes diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Plugin.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Plugin.java similarity index 65% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Plugin.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Plugin.java index aa070d502..befa1f5e2 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Plugin.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Plugin.java @@ -1,6 +1,6 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.query; +package fr.inria.corese.core.next.query.impl.engine.spi; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; /** * Draft KGRAM Plugin for EXTERN expression. diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Producer.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Producer.java similarity index 90% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Producer.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Producer.java index b644f654e..d4eed1402 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Producer.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Producer.java @@ -1,11 +1,16 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.query; +package fr.inria.corese.core.next.query.impl.engine.spi; + +import fr.inria.corese.core.next.query.impl.engine.model.DatatypeNodeFactory; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Graph; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Regex; import fr.inria.corese.core.next.data.api.model.DatatypeValue; -import fr.inria.corese.core.next.query.impl.kgram.api.core.*; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Mappings; -import fr.inria.corese.core.next.query.impl.kgram.core.Query; -import fr.inria.corese.core.next.query.impl.kgram.core.SparqlException; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.eval.SparqlException; import java.util.List; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Provider.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Provider.java new file mode 100644 index 000000000..4d045988f --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Provider.java @@ -0,0 +1,20 @@ +package fr.inria.corese.core.next.query.impl.engine.spi; + +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.eval.Eval; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; +import fr.inria.corese.core.next.query.impl.engine.eval.SparqlException; + +/** + * Service Provider + * + * @author Olivier Corby, Edelweiss, INRIA 2011 + */ +public interface Provider { + default Mappings service(Node serv, Exp exp, Mappings map, Eval eval) + throws SparqlException { + return null; + } + +} diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Result.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Result.java similarity index 57% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Result.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Result.java index a5361707b..85030bd8d 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Result.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Result.java @@ -1,6 +1,6 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.query; +package fr.inria.corese.core.next.query.impl.engine.spi; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Node; /** * Interface to KGRAM elementary result (a mapping) diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Results.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Results.java similarity index 60% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Results.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Results.java index 3d0a2f96c..75dba17e6 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Results.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/Results.java @@ -1,6 +1,6 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.query; +package fr.inria.corese.core.next.query.impl.engine.spi; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Node; import java.util.List; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/SPARQLEngine.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/SPARQLEngine.java new file mode 100644 index 000000000..829533fc2 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/SPARQLEngine.java @@ -0,0 +1,23 @@ +package fr.inria.corese.core.next.query.impl.engine.spi; + +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.eval.SparqlException; + +/** + * @author corby + */ +public interface SPARQLEngine { + + Mappings eval(Query q, Mapping m, Producer p) throws SparqlException; + + Mappings eval(Node gNode, Query q, Mapping m, Producer p) throws SparqlException; + + // within a lock where query processing has ended and where we can process another query + boolean isSynchronized(); + + void setSynchronized(boolean b); + +} diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/package-info.java new file mode 100644 index 000000000..9c0e6d557 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/spi/package-info.java @@ -0,0 +1,4 @@ +/** + * Service provider interfaces (SPI) for storage producers, evaluators, and engine plugins. + */ +package fr.inria.corese.core.next.query.impl.engine.spi; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/ProducerDefault.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/storage/ProducerDefault.java similarity index 69% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/ProducerDefault.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/storage/ProducerDefault.java index b4d8b4a48..8cc7591f6 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/ProducerDefault.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/storage/ProducerDefault.java @@ -1,12 +1,17 @@ -package fr.inria.corese.core.next.query.impl.kgram.tool; +package fr.inria.corese.core.next.query.impl.engine.storage; + +import fr.inria.corese.core.next.query.impl.engine.model.DatatypeNodeFactory; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Graph; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Regex; import fr.inria.corese.core.next.data.api.model.DatatypeValue; -import fr.inria.corese.core.next.query.impl.kgram.api.core.*; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Mappings; -import fr.inria.corese.core.next.query.impl.kgram.core.Query; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; import java.util.ArrayList; import java.util.List; @@ -17,6 +22,7 @@ * */ public class ProducerDefault implements Producer { + private static final String NOT_SUPPORTED_YET = "Not supported yet."; int mode = Producer.DEFAULT; Node graphNode; @@ -113,12 +119,12 @@ public Mappings getMappings(Node gNode, List from, Exp exp, Environment en @Override public DatatypeValue getValue(Object value) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public DatatypeValue getDatatypeValue(Object value) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override @@ -133,27 +139,27 @@ public void close() { @Override public void start(Query q) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public void finish(Query q) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public DatatypeNodeFactory getDatatypeNodeFactory() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public Mappings map(List qNodes, DatatypeValue object, int n) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } @Override public String blankNode() { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } } diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/StorageManagerEdge.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/storage/StorageManagerEdge.java similarity index 89% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/StorageManagerEdge.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/storage/StorageManagerEdge.java index 49e6bad25..8e08125d0 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/StorageManagerEdge.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/storage/StorageManagerEdge.java @@ -1,8 +1,10 @@ -package fr.inria.corese.core.next.query.impl.kgram.tool; +package fr.inria.corese.core.next.query.impl.engine.storage; + +import fr.inria.corese.core.next.query.impl.engine.model.NodeImpl; import fr.inria.corese.core.next.data.api.model.Statement; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Node; import java.util.Objects; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/StorageManagerProducer.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/storage/StorageManagerProducer.java similarity index 95% rename from src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/StorageManagerProducer.java rename to src/main/java/fr/inria/corese/core/next/query/impl/engine/storage/StorageManagerProducer.java index 56a6490bb..ddf3c3c6b 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/StorageManagerProducer.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/storage/StorageManagerProducer.java @@ -1,4 +1,7 @@ -package fr.inria.corese.core.next.query.impl.kgram.tool; +package fr.inria.corese.core.next.query.impl.engine.storage; + +import fr.inria.corese.core.next.query.impl.engine.eval.ApproximateSearchEnv; +import fr.inria.corese.core.next.query.impl.engine.model.NodeImpl; import fr.inria.corese.core.next.data.api.term.IRI; import fr.inria.corese.core.next.data.api.term.Resource; @@ -6,20 +9,20 @@ import fr.inria.corese.core.next.data.api.model.DatatypeValue; import fr.inria.corese.core.next.data.api.model.Statement; import fr.inria.corese.core.next.query.api.exception.UnsupportedQueryFeatureException; -import fr.inria.corese.core.next.query.impl.kgram.api.core.BindingContext; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Regex; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.api.query.ProcessVisitor; -import fr.inria.corese.core.next.query.impl.kgram.core.Eval; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Mapping; -import fr.inria.corese.core.next.query.impl.kgram.core.Mappings; -import fr.inria.corese.core.next.query.impl.kgram.core.Query; -import fr.inria.corese.core.next.query.impl.kgram.event.KgramEventDispatcher; -import fr.inria.corese.core.next.query.impl.kgram.path.Path; +import fr.inria.corese.core.next.query.impl.engine.model.BindingContext; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Regex; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.event.ProcessVisitor; +import fr.inria.corese.core.next.query.impl.engine.eval.Eval; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.event.KgramEventDispatcher; +import fr.inria.corese.core.next.query.impl.engine.path.Path; import fr.inria.corese.core.next.storage.api.StorageManager; import fr.inria.corese.core.next.storage.api.model.StatementPattern; @@ -152,7 +155,7 @@ public boolean isBindable(Node node) { /** * Materializes mappings for basic graph patterns made of triple {@code EDGE} expressions. * - *

Higher-level algebra remains handled by {@link fr.inria.corese.core.next.query.impl.kgram.core.Eval}; + *

Higher-level algebra remains handled by {@link fr.inria.corese.core.next.query.impl.engine.eval.Eval}; * paths, services and values are explicit follow-ups.

*/ @Override diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/storage/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/storage/package-info.java new file mode 100644 index 000000000..ed7e6e0d2 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/storage/package-info.java @@ -0,0 +1,4 @@ +/** + * Storage manager adapters and producer implementations for Next storage integration. + */ +package fr.inria.corese.core.next.query.impl.engine.storage; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/package-info.java deleted file mode 100644 index db0b8611f..000000000 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/core/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Internal KGRAM graph, node and expression contracts. - * - *

The historical {@code api} name is retained for source continuity inside - * the isolated engine. These contracts are not part of {@code next.query.api}.

- */ -package fr.inria.corese.core.next.query.impl.kgram.api.core; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/DistributedQueryPlanFactory.java b/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/DistributedQueryPlanFactory.java deleted file mode 100644 index 7765a0d70..000000000 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/DistributedQueryPlanFactory.java +++ /dev/null @@ -1,12 +0,0 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.query; - -import fr.inria.corese.core.next.query.impl.kgram.core.BgpGenerator; - -/** - * @author corby - */ -public interface DistributedQueryPlanFactory { - - BgpGenerator instance(); - -} diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Provider.java b/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Provider.java deleted file mode 100644 index 8d07e1b58..000000000 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/Provider.java +++ /dev/null @@ -1,21 +0,0 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.query; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.core.Eval; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Mappings; -import fr.inria.corese.core.next.query.impl.kgram.core.SparqlException; - -/** - * Service Provider - * - * @author Olivier Corby, Edelweiss, INRIA 2011 - */ -public interface Provider { - @SuppressWarnings("unused") - default Mappings service(Node serv, Exp exp, Mappings map, Eval eval) - throws SparqlException { - return null; - } - -} diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/SPARQLEngine.java b/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/SPARQLEngine.java deleted file mode 100644 index 90508c490..000000000 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/SPARQLEngine.java +++ /dev/null @@ -1,23 +0,0 @@ -package fr.inria.corese.core.next.query.impl.kgram.api.query; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.core.Mapping; -import fr.inria.corese.core.next.query.impl.kgram.core.Mappings; -import fr.inria.corese.core.next.query.impl.kgram.core.Query; -import fr.inria.corese.core.next.query.impl.kgram.core.SparqlException; - -/** - * @author corby - */ -public interface SPARQLEngine { - - Mappings eval(Query q, Mapping m, Producer p) throws SparqlException; - - Mappings eval(Node gNode, Query q, Mapping m, Producer p) throws SparqlException; - - // within a lock where query processing has ended and where we can process another query - boolean isSynchronized(); - - void setSynchronized(boolean b); - -} diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/package-info.java deleted file mode 100644 index f31f7d3e8..000000000 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/api/query/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Internal extension points used by the KGRAM evaluator. - * - *

Storage and expression adapters implement these contracts to drive the - * engine. They are implementation details rather than public query APIs.

- */ -package fr.inria.corese.core.next.query.impl.kgram.api.query; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Merge.java b/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Merge.java deleted file mode 100644 index 6e3dd9bb3..000000000 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/Merge.java +++ /dev/null @@ -1,126 +0,0 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; - -import java.util.ArrayList; - - -/*********************************************** - * group by any - * group Mapping who share one node (from any variable) - * Connected components - * - * @author Olivier Corby, Edelweiss, INRIA 2011 - * - ***********************************************/ - -public class Merge extends Group { - - Mappings lMap; - ListMappings list; - - - Merge(Mappings lm){ - lMap = lm; - } - - - public static class ListMappings extends ArrayList { - - -} - - public Iterable getValues(){ - return list; - } - - void merge(){ - list = merge(lMap); - list = merge(list); - } - - - /** - * Initialize - */ - ListMappings merge(Mappings lMap){ - ListMappings list = new ListMappings(); - - for (Mapping map : lMap){ - boolean found = false; - for (Mappings lm : list){ - if (match(lm, map)){ - lm.add(map); - found = true; - break; - } - } - - if (! found){ - Mappings lm = new Mappings(); - lm.add(map); - list.add(lm); - } - - } - - return list; - } - - - - /** - * Every Mappings is made of connected Mapping - * Try to Merge Mappings that are connected - */ - ListMappings merge(ListMappings list){ - ListMappings nlist = null; - boolean merge = true; - - - while (merge){ - nlist = new ListMappings(); - merge = false; - for (Mappings lm1 : list){ - - boolean found = false; - for (Mappings lm2 : nlist){ - if (match(lm1, lm2)){ - lm2.add(lm1); - found = true; - merge = true; - break; - } - } - - if (! found){ - nlist.add(lm1); - } - } - - list = nlist; - } - - return nlist; - } - - - boolean match(Mappings lm1, Mappings lm2){ - for (Mapping map : lm1){ - if (match(lm2, map)){ - return true; - } - } - return false; - } - - - // one node of map is contained in one Mapping of lm - boolean match(Mappings lmap, Mapping map){ - for (Mapping m : lmap){ - if (map.match(m)){ - return true; - } - } - return false; - } - -} diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/package-info.java deleted file mode 100644 index e9b586dae..000000000 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/core/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * KGRAM algebra plan, mappings, evaluation memory and execution loop. - * - *

This package contains the historical engine kernel. New public behavior - * belongs in {@code next.query.api}; integration code belongs in the dedicated - * bridge, execution or storage packages.

- */ -package fr.inria.corese.core.next.query.impl.kgram.core; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/package-info.java deleted file mode 100644 index 8e39f66d4..000000000 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/event/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Internal events emitted while evaluating a KGRAM query plan. */ -package fr.inria.corese.core.next.query.impl.kgram.event; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/execution/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/kgram/execution/package-info.java deleted file mode 100644 index fe0a220ed..000000000 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/execution/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Minimal runtime collaborators used to execute Corese-next queries with KGRAM. - * - *

This package contains execution components, not parser or storage helpers. - * The current implementations deliberately cover the first autonomous SELECT/ASK - * path and document their unsupported SPARQL features explicitly.

- */ -package fr.inria.corese.core.next.query.impl.kgram.execution; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/package-info.java deleted file mode 100644 index 50fe3119e..000000000 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/filter/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Internal KGRAM filter matching and validation helpers. */ -package fr.inria.corese.core.next.query.impl.kgram.filter; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/kgram/package-info.java deleted file mode 100644 index 58567e297..000000000 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/package-info.java +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Internal KGRAM execution engine used by the next SPARQL pipeline. - * - *

This is a deliberately isolated, transitional fork of the historical - * engine. It is implementation detail, even where copied subpackages retain - * names such as {@code api}. Applications must use {@code next.query.api} and - * must not depend on types below this package.

- * - *

The package preserves the KGRAM execution model while it is decomposed - * into responsibility-based {@code next} components. Its name documents that - * origin; it is not intended to become another public query API.

- */ -package fr.inria.corese.core.next.query.impl.kgram; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/package-info.java deleted file mode 100644 index 236b161f1..000000000 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/path/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Internal property-path traversal state and algorithms used by KGRAM. */ -package fr.inria.corese.core.next.query.impl.kgram.path; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/QuerySorterConst.java b/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/QuerySorterConst.java deleted file mode 100644 index fe5a82cd4..000000000 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/QuerySorterConst.java +++ /dev/null @@ -1,43 +0,0 @@ -package fr.inria.corese.core.next.query.impl.kgram.sorter.core; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExpType; - -/** - * Constants - * - * @author Fuqi Song, Wimmics Inria I3S - */ -public final class QuerySorterConst { - - public static final int ALL = 0; - public static final int SUBJECT = 1; - public static final int PREDICATE = 2; - public static final int OBJECT = 3; - public static final int TRIPLE = 4; - public static final int NA = -1; - - public final static int BOUND = 0, LIST = 0, UNBOUND = Integer.MAX_VALUE; - - public static final ExpType.Type[] EVALUABLE_TYPES = {ExpType.Type.EDGE, ExpType.Type.GRAPH}; - public static final ExpType.Type[] NOT_EVALUABLE_TYPES = {ExpType.Type.FILTER, ExpType.Type.VALUES, ExpType.Type.BIND, ExpType.Type.OPTIONAL}; - - public static boolean plannable(ExpType.Type type) { - for (ExpType.Type e : NOT_EVALUABLE_TYPES) { - if (type == e) { - return true; - } - } - - return evaluable(type); - } - - public static boolean evaluable(ExpType.Type type) { - for (ExpType.Type e : EVALUABLE_TYPES) { - if (type == e) { - return true; - } - } - - return false; - } -} diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/package-info.java deleted file mode 100644 index b54c0f82c..000000000 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/core/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Internal query-plan cost model and ordering contracts. */ -package fr.inria.corese.core.next.query.impl.kgram.sorter.core; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/package-info.java deleted file mode 100644 index ee48ff87b..000000000 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/sorter/impl/qpv1/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** First-generation heuristic implementation of KGRAM query-plan ordering. */ -package fr.inria.corese.core.next.query.impl.kgram.sorter.impl.qpv1; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/package-info.java b/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/package-info.java deleted file mode 100644 index b19c8213c..000000000 --- a/src/main/java/fr/inria/corese/core/next/query/impl/kgram/tool/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Internal adapters between KGRAM contracts and Corese-next runtime values or storage. - */ -package fr.inria.corese.core.next.query.impl.kgram.tool; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/BgpAst.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/BgpAst.java index 0c1ab04b2..df0cf7e97 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/BgpAst.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/BgpAst.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.ast; + import fr.inria.corese.core.next.query.impl.sparql.parser.semantic.support.AstVisitor; import java.util.List; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/FilterAst.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/FilterAst.java index 83484b272..8845ec56e 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/FilterAst.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/FilterAst.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.ast; + import fr.inria.corese.core.next.query.impl.sparql.parser.semantic.support.AstVisitor; /** diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/GraphRefAst.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/GraphRefAst.java index 80212fa06..a15da6a30 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/GraphRefAst.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/GraphRefAst.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.ast; + import fr.inria.corese.core.next.query.api.exception.QueryEvaluationException; import fr.inria.corese.core.next.query.impl.sparql.parser.semantic.support.AstVisitor; import fr.inria.corese.core.next.query.impl.sparql.parser.semantic.support.VisitableAst; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/GraphRefAsts.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/GraphRefAsts.java index 73438498f..a2cb3610e 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/GraphRefAsts.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/GraphRefAsts.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.ast; + /** * Constructor functions for Graph references */ diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/GroupGraphPatternAst.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/GroupGraphPatternAst.java index 0943c2c1c..7f06bcc24 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/GroupGraphPatternAst.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/GroupGraphPatternAst.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.ast; + import java.util.List; import fr.inria.corese.core.next.query.impl.sparql.parser.semantic.support.AstVisitor; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/LoadRequestAst.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/LoadRequestAst.java index abc5cdfd0..434082e9f 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/LoadRequestAst.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/ast/LoadRequestAst.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.ast; + import fr.inria.corese.core.next.query.api.exception.QueryEvaluationException; import fr.inria.corese.core.next.query.impl.sparql.parser.semantic.support.AstVisitor; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/AstBackedEdge.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/AstBackedEdge.java index 4649ea1b6..f8504c1eb 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/AstBackedEdge.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/AstBackedEdge.java @@ -1,8 +1,8 @@ package fr.inria.corese.core.next.query.impl.sparql.bridge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.tool.KgramNodes; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.model.KgramNodes; import java.util.Objects; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/AstBackedExpr.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/AstBackedExpr.java index 46192ea36..24c61c731 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/AstBackedExpr.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/AstBackedExpr.java @@ -1,13 +1,14 @@ package fr.inria.corese.core.next.query.impl.sparql.bridge; + import fr.inria.corese.core.next.data.api.model.DatatypeValue; -import fr.inria.corese.core.next.query.impl.kgram.api.core.BindingContext; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExprType; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Filter; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Evaluator; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; +import fr.inria.corese.core.next.query.impl.engine.model.BindingContext; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.ExprType; +import fr.inria.corese.core.next.query.impl.engine.model.Filter; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Evaluator; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; import fr.inria.corese.core.next.query.impl.sparql.ast.AggregateAst; import fr.inria.corese.core.next.query.impl.sparql.ast.ConstraintAst; import fr.inria.corese.core.next.query.impl.sparql.ast.IriAst; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilder.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilder.java index 7cc92c029..807979405 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilder.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilder.java @@ -1,15 +1,16 @@ package fr.inria.corese.core.next.query.impl.sparql.bridge; + import fr.inria.corese.core.next.query.api.exception.UnsupportedQueryFeatureException; import fr.inria.corese.core.next.query.impl.sparql.ast.*; import fr.inria.corese.core.next.query.impl.sparql.ast.path.PathAst; import fr.inria.corese.core.next.query.impl.sparql.ast.path.PredicatePathAst; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExpType.Type; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Filter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Query; -import fr.inria.corese.core.next.query.impl.kgram.tool.NodeImpl; +import fr.inria.corese.core.next.query.impl.engine.model.ExpType.Type; +import fr.inria.corese.core.next.query.impl.engine.model.Filter; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.model.NodeImpl; import java.util.ArrayList; import java.util.LinkedHashSet; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/NativeEvaluationContext.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/NativeEvaluationContext.java index 6a84241f7..efe5d5e4f 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/NativeEvaluationContext.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/NativeEvaluationContext.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.bridge; + import fr.inria.corese.core.next.data.Values; import fr.inria.corese.core.next.data.api.factory.ValueFactory; import fr.inria.corese.core.next.data.api.literal.RDFDatatype; @@ -8,11 +9,11 @@ import fr.inria.corese.core.next.data.api.term.Literal; import fr.inria.corese.core.next.query.api.exception.QueryEvaluationException; import fr.inria.corese.core.next.query.api.exception.UnsupportedQueryFeatureException; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Evaluator; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; -import fr.inria.corese.core.next.query.impl.kgram.core.SparqlException; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Evaluator; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; +import fr.inria.corese.core.next.query.impl.engine.eval.SparqlException; import fr.inria.corese.core.next.query.impl.sparql.ast.GroupGraphPatternAst; import fr.inria.corese.core.next.query.impl.sparql.ast.TermAst; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/NativeExpressionEvaluator.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/NativeExpressionEvaluator.java index 238872853..c9dad3b12 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/NativeExpressionEvaluator.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/NativeExpressionEvaluator.java @@ -1,11 +1,12 @@ package fr.inria.corese.core.next.query.impl.sparql.bridge; + import fr.inria.corese.core.next.data.api.model.DatatypeValue; import fr.inria.corese.core.next.query.api.exception.QueryEvaluationException; import fr.inria.corese.core.next.query.api.exception.UnsupportedQueryFeatureException; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Evaluator; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Evaluator; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; import fr.inria.corese.core.next.query.impl.sparql.ast.IriAst; import fr.inria.corese.core.next.query.impl.sparql.ast.LiteralAst; import fr.inria.corese.core.next.query.impl.sparql.ast.TermAst; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/NextFilterFromAst.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/NextFilterFromAst.java index 6e67e4a00..2893e6904 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/NextFilterFromAst.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/NextFilterFromAst.java @@ -1,8 +1,9 @@ package fr.inria.corese.core.next.query.impl.sparql.bridge; + import fr.inria.corese.core.next.query.impl.sparql.ast.TermAst; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Filter; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.Filter; import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.BoundAst; import fr.inria.corese.core.next.query.impl.sparql.parser.semantic.support.VariableScopeAnalyzer; @@ -58,7 +59,7 @@ public boolean isRecAggregate() { @Override public boolean isFunctional() { - return owner.oper() == fr.inria.corese.core.next.query.impl.kgram.api.core.ExprType.UNNEST; + return owner.oper() == fr.inria.corese.core.next.query.impl.engine.model.ExprType.UNNEST; } @Override diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompiler.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompiler.java index 60b774864..4e5a9568b 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompiler.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompiler.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.bridge; + import fr.inria.corese.core.next.query.api.exception.UnsupportedQueryFeatureException; import fr.inria.corese.core.next.query.impl.sparql.ast.BgpAst; import fr.inria.corese.core.next.query.impl.sparql.ast.BindAst; @@ -12,12 +13,12 @@ import fr.inria.corese.core.next.query.impl.sparql.ast.ServiceAst; import fr.inria.corese.core.next.query.impl.sparql.ast.TriplePatternAst; import fr.inria.corese.core.next.query.impl.sparql.ast.UnionAst; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExpType.Type; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Filter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Query; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.ExpType.Type; +import fr.inria.corese.core.next.query.impl.engine.model.Filter; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; import java.util.Objects; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/CoreseBindingSet.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/CoreseBindingSet.java index 25aa803ee..603b0f0b8 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/CoreseBindingSet.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/CoreseBindingSet.java @@ -1,10 +1,11 @@ package fr.inria.corese.core.next.query.impl.sparql.execution; + import fr.inria.corese.core.next.data.api.model.DatatypeValue; import fr.inria.corese.core.next.data.api.term.Value; import fr.inria.corese.core.next.query.api.result.Binding; import fr.inria.corese.core.next.query.api.result.BindingSet; -import fr.inria.corese.core.next.query.impl.kgram.core.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; import fr.inria.corese.core.next.query.impl.result.CoreseBinding; import java.util.Iterator; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/CoreseTupleQueryResult.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/CoreseTupleQueryResult.java index 7ca13a01e..0ea536a3a 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/CoreseTupleQueryResult.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/CoreseTupleQueryResult.java @@ -2,9 +2,9 @@ import fr.inria.corese.core.next.query.api.result.BindingSet; import fr.inria.corese.core.next.query.api.result.TupleQueryResult; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.core.Mapping; -import fr.inria.corese.core.next.query.impl.kgram.core.Mappings; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; import java.util.Iterator; import java.util.List; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/NextSparqlPipelineExecutor.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/NextSparqlPipelineExecutor.java index 334cb3751..af2e0e6ad 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/NextSparqlPipelineExecutor.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/NextSparqlPipelineExecutor.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.execution; + import fr.inria.corese.core.next.data.Values; import fr.inria.corese.core.next.data.api.term.IRI; import fr.inria.corese.core.next.data.api.term.Resource; @@ -21,18 +22,18 @@ import fr.inria.corese.core.next.query.impl.sparql.ast.QueryAst; import fr.inria.corese.core.next.query.impl.sparql.ast.SelectQueryAst; import fr.inria.corese.core.next.query.impl.sparql.bridge.CoreseAstQueryBuilder; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.core.Eval; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Mapping; -import fr.inria.corese.core.next.query.impl.kgram.core.Mappings; -import fr.inria.corese.core.next.query.impl.kgram.core.Query; -import fr.inria.corese.core.next.query.impl.kgram.core.SparqlException; -import fr.inria.corese.core.next.query.impl.kgram.execution.RdfTermMatcher; -import fr.inria.corese.core.next.query.impl.kgram.execution.SparqlKgramEvaluator; -import fr.inria.corese.core.next.query.impl.kgram.tool.NodeImpl; -import fr.inria.corese.core.next.query.impl.kgram.tool.StorageManagerProducer; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.eval.Eval; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.eval.SparqlException; +import fr.inria.corese.core.next.query.impl.engine.eval.RdfTermMatcher; +import fr.inria.corese.core.next.query.impl.engine.eval.SparqlKgramEvaluator; +import fr.inria.corese.core.next.query.impl.engine.model.NodeImpl; +import fr.inria.corese.core.next.query.impl.engine.storage.StorageManagerProducer; import fr.inria.corese.core.next.storage.api.StorageManager; import java.util.ArrayList; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/io/serializer/json/JsonTupleResultSerializer.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/io/serializer/json/JsonTupleResultSerializer.java index 9ceda1cb1..b7c730350 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/io/serializer/json/JsonTupleResultSerializer.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/io/serializer/json/JsonTupleResultSerializer.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.io.serializer.json; + import fr.inria.corese.core.next.data.api.exception.SerializationException; import fr.inria.corese.core.next.data.api.io.format.FileFormat; import fr.inria.corese.core.next.data.api.io.option.IOOptions; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/io/serializer/support/CharacterSeparatedValuesSerializer.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/io/serializer/support/CharacterSeparatedValuesSerializer.java index ac0dbc3e9..520c36fff 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/io/serializer/support/CharacterSeparatedValuesSerializer.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/io/serializer/support/CharacterSeparatedValuesSerializer.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.io.serializer.support; + import fr.inria.corese.core.next.data.api.term.Value; import fr.inria.corese.core.next.data.api.io.serializer.option.LineEndingOptions; import fr.inria.corese.core.next.data.spi.io.IOConstants; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/io/serializer/xml/XmlTupleResultSerializer.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/io/serializer/xml/XmlTupleResultSerializer.java index 9667382a0..2546f59cd 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/io/serializer/xml/XmlTupleResultSerializer.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/io/serializer/xml/XmlTupleResultSerializer.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.io.serializer.xml; + import fr.inria.corese.core.next.data.api.exception.SerializationException; import fr.inria.corese.core.next.data.api.io.format.FileFormat; import fr.inria.corese.core.next.data.api.io.option.IOOptions; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlAntlrDispatcher.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlAntlrDispatcher.java index d53df2c98..9840620cb 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlAntlrDispatcher.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlAntlrDispatcher.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.parser; + import fr.inria.corese.core.next.generated.antlr.SparqlParser; import fr.inria.corese.core.next.generated.antlr.SparqlParserBaseListener; import fr.inria.corese.core.next.generated.antlr.SparqlParserListener; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlAstBuilder.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlAstBuilder.java index 4e4c25ac4..486740b38 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlAstBuilder.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlAstBuilder.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.parser; + import fr.inria.corese.core.next.common.text.RdfText; import fr.inria.corese.core.next.data.spi.term.IRIUtils; import fr.inria.corese.core.next.data.api.vocabulary.RDF; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlQueryAstBuilder.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlQueryAstBuilder.java index a87a2544d..2ff958a27 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlQueryAstBuilder.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlQueryAstBuilder.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.parser; + import fr.inria.corese.core.next.common.text.RdfText; import fr.inria.corese.core.next.query.api.exception.QueryEvaluationException; import fr.inria.corese.core.next.query.api.exception.QuerySyntaxException; @@ -92,12 +93,26 @@ public SparqlQueryAstBuilder(SparqlParserOptions options) { super(options); } + private static String normalizeVariableName(String name) { + return name == null ? "" : stripVariableMarker(name); + } + + private static Set normalizeReferencedVariables(Set names) { + if (names == null) { + return Set.of(); + } + return names.stream().filter(Objects::nonNull) + .map(RdfText::stripVariableMarker).filter(name -> !name.isBlank()) + .collect(Collectors.toUnmodifiableSet()); + } + public void enterAskQuery() { assertTopLevelQueryFormOnly("ASK"); queryType = ASTConstants.QUERY_TYPE.ASK; } public void exitAskQuery() { + // Query state is collected by the entry and clause callbacks. } public void enterSelectQuery() { @@ -161,6 +176,7 @@ public void enterConstructQuery() { } public void exitConstructQuery() { + // Query state is collected by the entry and clause callbacks. } public void enterConstructTemplate() { @@ -219,14 +235,14 @@ public void setProjectionVariables( return; } List vars = variableNames.stream() - .map(s -> s == null ? "" : stripVariableMarker(s)) + .map(SparqlQueryAstBuilder::normalizeVariableName) .filter(s -> !s.isBlank()) .map(VarAst::new) .toList(); Set expressionBound = expressionBoundNames == null ? Set.of() : expressionBoundNames.stream() - .map(s -> s == null ? "" : stripVariableMarker(s)) + .map(SparqlQueryAstBuilder::normalizeVariableName) .filter(s -> !s.isBlank()) .collect(Collectors.toUnmodifiableSet()); @@ -244,11 +260,7 @@ public void setProjectionVariables( .filter(entry -> entry.getKey() != null) .collect(Collectors.toUnmodifiableMap( entry -> stripVariableMarker(entry.getKey()), - entry -> entry.getValue() == null ? Set.of() : entry.getValue().stream() - .filter(Objects::nonNull) - .map(RdfText::stripVariableMarker) - .filter(s -> !s.isBlank()) - .collect(Collectors.toUnmodifiableSet()))); + entry -> normalizeReferencedVariables(entry.getValue()))); ProjectionAst newProjection = vars.isEmpty() ? ProjectionAsts.selectAll() @@ -390,7 +402,7 @@ private SelectQueryAst buildSelectQueryAst(DatasetClauseAst datasetClauseAst, Qu * Builds the AST for DESCRIBE operations. */ private DescribeQueryAst buildDescribeQueryAst(DatasetClauseAst datasetClauseAst, QueryPrologueAst prologue, ValuesAst valuesClause) { - // TODO #306: validate variable scope for DESCRIBE modifiers when DescribeQueryAst carries them. + // Variable scope validation for DESCRIBE modifiers when DescribeQueryAst carries them (#306). return new DescribeQueryAst( datasetClauseAst, describeResources, @@ -404,7 +416,7 @@ private DescribeQueryAst buildDescribeQueryAst(DatasetClauseAst datasetClauseAst * Builds the AST for CONSTRUCT operations. */ private ConstructQueryAst buildConstructQueryAst(DatasetClauseAst datasetClauseAst, QueryPrologueAst prologue, ValuesAst valuesClause) { - // TODO #306: validate variable scope for CONSTRUCT modifiers when ConstructQueryAst carries them. + // Variable scope validation for CONSTRUCT modifiers when ConstructQueryAst carries them (#306). return new ConstructQueryAst( constructTemplate != null ? constructTemplate : new ConstructTemplateAst(List.of()), datasetClauseAst, @@ -479,6 +491,7 @@ public void enterDescribeQuery() { * Called when the parser exits a {@code DESCRIBE} query. No-op. */ public void exitDescribeQuery() { + // Query state is collected by the entry and clause callbacks. } /** diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlUpdateAstBuilder.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlUpdateAstBuilder.java index e038e1a56..6b680264b 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlUpdateAstBuilder.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlUpdateAstBuilder.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.parser; + import fr.inria.corese.core.next.generated.antlr.SparqlParser; import fr.inria.corese.core.next.query.api.exception.QueryEvaluationException; import fr.inria.corese.core.next.query.impl.sparql.ast.*; diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/semantic/support/VariableScopeAnalyzer.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/semantic/support/VariableScopeAnalyzer.java index 05cc04900..31ef72334 100644 --- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/semantic/support/VariableScopeAnalyzer.java +++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/parser/semantic/support/VariableScopeAnalyzer.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.parser.semantic.support; + import fr.inria.corese.core.next.query.impl.sparql.ast.*; import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.*; import fr.inria.corese.core.next.query.impl.sparql.ast.path.*; diff --git a/src/main/java/fr/inria/corese/core/sparql/triple/function/term/Binding.java b/src/main/java/fr/inria/corese/core/sparql/triple/function/term/Binding.java index 78bec337e..0582b4805 100644 --- a/src/main/java/fr/inria/corese/core/sparql/triple/function/term/Binding.java +++ b/src/main/java/fr/inria/corese/core/sparql/triple/function/term/Binding.java @@ -13,7 +13,6 @@ import fr.inria.corese.core.sparql.triple.parser.Access; import fr.inria.corese.core.sparql.triple.parser.AccessRight; import fr.inria.corese.core.sparql.triple.parser.Context; -import fr.inria.corese.core.sparql.triple.parser.HashMapList; import fr.inria.corese.core.sparql.triple.parser.context.ContextLog; import fr.inria.corese.core.sparql.triple.parser.Variable; import fr.inria.corese.core.sparql.triple.parser.VariableLocal; @@ -22,18 +21,18 @@ import java.util.List; import java.util.Optional; -import org.slf4j.LoggerFactory; -import org.slf4j.Logger; + /** * * Stack vor LDScript variable bindings Variable have a relative index stack - * index = level + var index level is the level of current function call in the + * index = level + variable index level is the level of current function call in the * stack * * @author Olivier Corby, Wimmics INRIA I3S, 2017 * */ +@SuppressWarnings("deprecation") public class Binding implements Binder { private static final String URI = "uri"; @@ -59,14 +58,14 @@ public class Binding implements Binder { // level of the stack before function call // every funcall add a level ArrayList level; - int currentLevel = 0, count = 0; + int currentLevel = 0; + int count = 0; HashMap globalValue; HashMap globalVariable; private ProcessVisitor visitor; private AccessRight accessRight; - private static final Logger logger = LoggerFactory.getLogger(Binding.class); private boolean dynamicCapture = DYNAMIC_CAPTURE_DEFAULT; private boolean result; private boolean coalesce = false; @@ -89,9 +88,9 @@ public class Binding implements Binder { } Binding() { - varList = new ArrayList(); - valList = new ArrayList(); - level = new ArrayList(); + varList = new ArrayList<>(); + valList = new ArrayList<>(); + level = new ArrayList<>(); setReport(DatatypeMap.newServiceReport()); setGlobalVariableValues(new HashMap<>()); setGlobalVariableNames(new HashMap<>()); @@ -181,15 +180,15 @@ int index() { */ @Override public boolean hasBind() { - return varList.size() > 0 || level.size() > 0; + return !varList.isEmpty() || !level.isEmpty(); } - int getIndex(Expr var) { - return currentLevel + var.getIndex(); + int getIndex(Expr variable) { + return currentLevel + variable.getIndex(); } - public void set(Expr exp, Expr var, IDatatype val) { + public void set(Expr exp, Expr variable, IDatatype val) { switch (exp.oper()) { case ExprType.FUNCTION: // special case: walker aggregate @@ -197,21 +196,27 @@ public void set(Expr exp, Expr var, IDatatype val) { allocate(exp); break; - case ExprType.LET: - case ExprType.FOR: + case ExprType.LET, ExprType.FOR: allocation(exp); + break; + default: + break; } - set(var, val); + set(variable, val); } // must perform allocation before - public void setlet(Expr exp, Expr var, IDatatype val) { - set(var, val); + // Preserve the call signature shared by LDScript evaluation sites. + @SuppressWarnings("java:S1172") + public void setlet(Expr exp, Expr variable, IDatatype val) { + set(variable, val); } // do it when desallocation return false - public void unsetlet(Expr exp, Expr var, IDatatype val) { - unset(var); + // Preserve the call signature shared by LDScript evaluation sites. + @SuppressWarnings("java:S1172") + public void unsetlet(Expr exp, Expr variable, IDatatype val) { + unset(variable); } public void allocation(Expr exp) { @@ -228,35 +233,30 @@ public boolean desallocation(Expr exp) { return false; } - public void unset(Expr exp, Expr var, IDatatype val) { - switch (exp.oper()) { - case ExprType.FUNCTION: - // special case: walker aggregate - desallocate(exp); - break; - - case ExprType.LET: - case ExprType.FOR: - if (desallocation(exp)) { - return; - } - - default: - unset(var); + // Preserve the call signature shared by LDScript evaluation sites. + @SuppressWarnings("java:S1172") + public void unset(Expr exp, Expr variable, IDatatype val) { + if (exp.oper() == ExprType.FUNCTION) { + desallocate(exp); + } else if ((exp.oper() != ExprType.LET && exp.oper() != ExprType.FOR) + || !desallocation(exp)) { + unset(variable); } } //special case: unary function - public void set(Function exp, Expr var, IDatatype val) { + public void set(Function exp, Expr variable, IDatatype val) { pushLevel(); - push(var, val); + push(variable, val); // allocate additional variables for (int j = 1; j < exp.getNbVariable(); j++) { push(null, null); } } - public void setTailRec(Function exp, Expr var, IDatatype val) { + // Preserve the call signature shared by LDScript evaluation sites. + @SuppressWarnings("java:S1172") + public void setTailRec(Function exp, Expr variable, IDatatype val) { valList.set(currentLevel, val); // unset additional variables for (int j = 1; j < exp.getNbVariable(); j++) { @@ -353,8 +353,8 @@ public void set(Expr exp, List lvar, IDatatype[] value) { count++; pushLevel(); int i = 0; - for (Expr var : lvar) { - push(var, value[i++]); + for (Expr variable : lvar) { + push(variable, value[i++]); } // allocate additional variables: for (int j = i; j lvar, IDatatype[] value) { } } - void push(Expr var, IDatatype val) { - varList.add(var); + void push(Expr variable, IDatatype val) { + varList.add(variable); valList.add(val); } - public void set(Expr var, IDatatype val) { - int index = getIndex(var); - varList.set(index, var); + public void set(Expr variable, IDatatype val) { + int index = getIndex(variable); + varList.set(index, variable); valList.set(index, val); } //@Override + // Preserve the call signature shared by LDScript evaluation sites. + @SuppressWarnings("java:S1172") public void unset(Expr exp, List lvar) { desallocate(exp); } - void unset(Expr var) { - valList.set(getIndex(var), null); + void unset(Expr variable) { + valList.set(getIndex(variable), null); } /** @@ -387,31 +389,24 @@ void unset(Expr var) { * between top of stack and level */ @Override - public IDatatype get(Expr var) { - return getBasic(var, true); - } - - public IDatatype getBasic(Expr var, boolean withStatic) { - switch (var.getIndex()) { - case UNBOUND: { - if (isDynamicCapture()) { - for (int i = varList.size() - 1; i >= 0; i--) { - Expr vv = varList.get(i); - if (vv != null && vv.isDynamic() && vv.equals(var)) { - return valList.get(i); - } - } - } + public IDatatype get(Expr variable) { + return getBasic(variable, true); + } - return (withStatic)?getGlobalVariable(var.getLabel()):getBasicGlobalVariable(var.getLabel()); - } - default: - return valList.get(getIndex(var)); + public IDatatype getBasic(Expr variable, boolean withStatic) { + if (variable.getIndex() != UNBOUND) { + return valList.get(getIndex(variable)); + } + int capturedIndex = findDynamicVariable(variable); + if (capturedIndex >= 0) { + return valList.get(capturedIndex); } + return withStatic ? getGlobalVariable(variable.getLabel()) + : getBasicGlobalVariable(variable.getLabel()); } - // todo: why not level ??? + // Search all stack levels, including bindings captured from enclosing calls. @Override public boolean isBound(String label) { for (int i = index(); i >= 0; i--) { @@ -472,56 +467,58 @@ public static IDatatype getStaticVariable(String name) { // must be LocalVariable, i.e. LDScript Variable - public Binding bind(Variable var, IDatatype val) { - bind(null, var, val); + public Binding bind(Variable variable, IDatatype val) { + bind(null, variable, val); return this; } /** * set(?x = exp) ?x is already bound, assign variable */ - public void bind(Expr exp, Variable var, IDatatype val) { - switch (var.subtype()) { - // global means SPARQL variable - // local means LDScript variable - case ExprType.GLOBAL: - break; - default: - switch (var.getIndex()) { - case UNBOUND: - - if (isDynamicCapture()) { - for (int i = varList.size() - 1; i >= 0; i--) { - Expr vv = varList.get(i); - if (vv != null && vv.isDynamic() && vv.equals(var)) { - valList.set(i, val); - return; - } - } - } - - // global variable - define(var, val); - break; - default: - valList.set(getIndex(var), val); - } + // Preserve the call signature shared by LDScript evaluation sites. + @SuppressWarnings("java:S1172") + public void bind(Expr exp, Variable variable, IDatatype val) { + // GLOBAL denotes a SPARQL variable rather than an LDScript variable. + if (variable.subtype() == ExprType.GLOBAL) { + return; + } + if (variable.getIndex() != UNBOUND) { + valList.set(getIndex(variable), val); + return; + } + int capturedIndex = findDynamicVariable(variable); + if (capturedIndex >= 0) { + valList.set(capturedIndex, val); + } else { + define(variable, val); } } - public void unbind(Expr exp, Variable var) { - bind(exp, var, null); + private int findDynamicVariable(Expr variable) { + if (isDynamicCapture()) { + for (int i = varList.size() - 1; i >= 0; i--) { + Expr candidate = varList.get(i); + if (candidate != null && candidate.isDynamic() && candidate.equals(variable)) { + return i; + } + } + } + return -1; + } + + public void unbind(Expr exp, Variable variable) { + bind(exp, variable, null); } - void define(Variable var, IDatatype val) { - getGlobalVariableValues().put(var.getLabel(), val); - getGlobalVariableNames().put(var.getLabel(), var); + void define(Variable variable, IDatatype val) { + getGlobalVariableValues().put(variable.getLabel(), val); + getGlobalVariableNames().put(variable.getLabel(), variable); } @Override public List getVariables() { - if (level.size() > 0) { - // funcall: return variables of this funcall (including let var) + if (!level.isEmpty()) { + // funcall: return variables of this funcall (including let variable) return getVar(); } else { // let variables @@ -530,7 +527,7 @@ public List getVariables() { } List getLetVar() { - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList<>(); list.addAll(varList); addGlobalVariables(list); return list; @@ -545,7 +542,7 @@ List getLetVar() { List getVar() { int start = getLevel(); int top = varList.size(); - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList<>(); for (int i = start; i < top; i++) { if (varList.get(i) != null && valList.get(i) != null) { list.add(varList.get(i)); @@ -556,9 +553,9 @@ List getVar() { } void addGlobalVariables(List list) { - for (Variable var : getGlobalVariableNames().values()) { - if (!list.contains(var)) { - list.add(var); + for (Variable variable : getGlobalVariableNames().values()) { + if (!list.contains(variable)) { + list.add(variable); } } } @@ -628,10 +625,14 @@ public void setNowValue(IDatatype nowValue) { getShare().setNowValue(nowValue); } + // Existing callers link to this concrete return type. + @SuppressWarnings("java:S1319") public HashMap getGlobalVariableNames() { return globalVariable; } + // Existing callers link to this concrete return type. + @SuppressWarnings("java:S1319") public HashMap getGlobalVariableValues() { return globalValue; } @@ -728,11 +729,11 @@ public void setAccessLevel(Access.Level accessLevel) { } - synchronized public ContextLog getLog() { + public synchronized ContextLog getLog() { return contextLog; } - synchronized public ContextLog getCreateLog() { + public synchronized ContextLog getCreateLog() { if (getLog() == null) { setLog(new ContextLog()); } @@ -740,7 +741,7 @@ synchronized public ContextLog getCreateLog() { } - public void setLog(ContextLog context) { + public synchronized void setLog(ContextLog context) { this.contextLog = context; } @@ -816,7 +817,7 @@ public void visit(Exp exp, Node g, Mappings m1, Mappings m2) { dt.set(URI, g.getDatatypeValue()); } } - public void visit(fr.inria.corese.core.next.query.impl.kgram.core.Exp exp, fr.inria.corese.core.next.query.impl.kgram.api.core.Node g, fr.inria.corese.core.next.query.impl.kgram.core.Mappings m1, fr.inria.corese.core.next.query.impl.kgram.core.Mappings m2) { + public void visit(fr.inria.corese.core.next.query.impl.engine.pattern.Exp exp, fr.inria.corese.core.next.query.impl.engine.model.Node g, fr.inria.corese.core.next.query.impl.engine.solution.Mappings m1, fr.inria.corese.core.next.query.impl.engine.solution.Mappings m2) { IDatatype dt = getReport(exp); dt.set(NUMBER, exp.getNum()); dt.set(EXP, exp.toString()); @@ -832,7 +833,7 @@ public void visit(fr.inria.corese.core.next.query.impl.kgram.core.Exp exp, fr.in * share same report for every call on same named graph pattern or service exp * exp report contains list(rep_1 rep_n) one rep_i for each uri */ - IDatatype getReport(fr.inria.corese.core.next.query.impl.kgram.core.Exp exp) { + IDatatype getReport(fr.inria.corese.core.next.query.impl.engine.pattern.Exp exp) { IDatatype dt = DatatypeMap.newServiceReport(); if (exp.isGraph() || exp.isService()) { diff --git a/src/test/java/fr/inria/corese/core/next/architecture/NextModuleBoundaryTest.java b/src/test/java/fr/inria/corese/core/next/architecture/NextModuleBoundaryTest.java index 1481ebdb2..893c313d1 100644 --- a/src/test/java/fr/inria/corese/core/next/architecture/NextModuleBoundaryTest.java +++ b/src/test/java/fr/inria/corese/core/next/architecture/NextModuleBoundaryTest.java @@ -94,8 +94,8 @@ void legacyCodeMustNotDependOnNextImplementations() throws IOException { source -> !source.startsWith(NEXT_SOURCES), imported -> imported.startsWith("fr.inria.corese.core.next.") && imported.contains(".impl.") - // KGRAM migration hooks are deliberately outside the next boundary. - && !imported.startsWith("fr.inria.corese.core.next.query.impl.kgram.")); + // Engine migration hooks are deliberately outside the next boundary. + && !imported.startsWith("fr.inria.corese.core.next.query.impl.engine.")); } @Test @@ -143,7 +143,7 @@ private static List implementationDirectories() { return List.of( NEXT_SOURCES.resolve("data/impl"), NEXT_SOURCES.resolve("storage/impl"), - NEXT_SOURCES.resolve("query/impl/kgram"), + NEXT_SOURCES.resolve("query/impl/engine"), NEXT_SOURCES.resolve("query/impl/sparql")); } diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/EvalTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalTest.java similarity index 93% rename from src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/EvalTest.java rename to src/test/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalTest.java index 21d7cbafe..f7fb6ab5b 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/EvalTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalTest.java @@ -1,9 +1,19 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.BindingContext; -import fr.inria.corese.core.next.query.impl.kgram.api.query.*; -import fr.inria.corese.core.next.query.impl.kgram.event.KgramEventDispatcher; -import fr.inria.corese.core.next.query.impl.kgram.event.ResultListener; +package fr.inria.corese.core.next.query.impl.engine.eval; + +import fr.inria.corese.core.next.query.impl.engine.event.ProcessVisitor; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; +import fr.inria.corese.core.next.query.impl.engine.solution.Memory; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Evaluator; +import fr.inria.corese.core.next.query.impl.engine.spi.Matcher; +import fr.inria.corese.core.next.query.impl.engine.spi.Plugin; +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; +import fr.inria.corese.core.next.query.impl.engine.spi.Provider; +import fr.inria.corese.core.next.query.impl.engine.spi.SPARQLEngine; + +import fr.inria.corese.core.next.query.impl.engine.model.BindingContext; +import fr.inria.corese.core.next.query.impl.engine.event.KgramEventDispatcher; +import fr.inria.corese.core.next.query.impl.engine.event.ResultListener; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/execution/RdfTermMatcherTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/eval/RdfTermMatcherTest.java similarity index 93% rename from src/test/java/fr/inria/corese/core/next/query/impl/kgram/execution/RdfTermMatcherTest.java rename to src/test/java/fr/inria/corese/core/next/query/impl/engine/eval/RdfTermMatcherTest.java index dfada41a5..40260df70 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/execution/RdfTermMatcherTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/eval/RdfTermMatcherTest.java @@ -1,11 +1,10 @@ -package fr.inria.corese.core.next.query.impl.kgram.execution; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Matcher; -import fr.inria.corese.core.next.query.impl.kgram.tool.EnvironmentImpl; -import fr.inria.corese.core.next.query.impl.kgram.tool.NodeImpl; +package fr.inria.corese.core.next.query.impl.engine.eval; + +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.spi.Matcher; +import fr.inria.corese.core.next.query.impl.engine.model.NodeImpl; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/engine/eval/StackTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/eval/StackTest.java new file mode 100644 index 000000000..bc9612549 --- /dev/null +++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/eval/StackTest.java @@ -0,0 +1,25 @@ +package fr.inria.corese.core.next.query.impl.engine.eval; + +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class StackTest { + @Test + void preservesListEqualityAndHashLookup() { + Stack stack = Stack.create(Exp.create(Exp.Type.AND)); + List list = new ArrayList<>(stack); + + assertEquals(list, stack); + assertEquals(stack, list); + assertEquals(list.hashCode(), stack.hashCode()); + assertTrue(new HashSet<>(List.of(stack)).contains(list)); + assertTrue(new HashSet<>(List.of(list)).contains(stack)); + } +} diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/tool/KgramNodesTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/model/KgramNodesTest.java similarity index 91% rename from src/test/java/fr/inria/corese/core/next/query/impl/kgram/tool/KgramNodesTest.java rename to src/test/java/fr/inria/corese/core/next/query/impl/engine/model/KgramNodesTest.java index caf62bb36..823bd4f66 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/tool/KgramNodesTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/model/KgramNodesTest.java @@ -1,6 +1,5 @@ -package fr.inria.corese.core.next.query.impl.kgram.tool; +package fr.inria.corese.core.next.query.impl.engine.model; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/tool/NodeImplFactoryTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/model/NodeImplFactoryTest.java similarity index 98% rename from src/test/java/fr/inria/corese/core/next/query/impl/kgram/tool/NodeImplFactoryTest.java rename to src/test/java/fr/inria/corese/core/next/query/impl/engine/model/NodeImplFactoryTest.java index ef431670f..90a9c41d5 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/tool/NodeImplFactoryTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/model/NodeImplFactoryTest.java @@ -1,4 +1,4 @@ -package fr.inria.corese.core.next.query.impl.kgram.tool; +package fr.inria.corese.core.next.query.impl.engine.model; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/engine/path/GraphPathTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/path/GraphPathTest.java new file mode 100644 index 000000000..6df745042 --- /dev/null +++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/path/GraphPathTest.java @@ -0,0 +1,26 @@ +package fr.inria.corese.core.next.query.impl.engine.path; + +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.mockito.Mockito.*; + +class GraphPathTest { + @Test + void runsPathEnumerationOnTheWorkerThread() throws InterruptedException { + PathFinder finder = mock(PathFinder.class); + Environment environment = mock(Environment.class); + Node start = mock(Node.class); + when(finder.getIndex()).thenReturn(1); + when(finder.get(environment, 1)).thenReturn(start); + GraphPath worker = new GraphPath(finder, environment); + + worker.start(); + worker.join(2000); + + assertFalse(worker.isAlive()); + verify(finder).process(start, environment); + } +} diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/engine/path/PathMappingBufferTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/path/PathMappingBufferTest.java new file mode 100644 index 000000000..2e50be92f --- /dev/null +++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/path/PathMappingBufferTest.java @@ -0,0 +1,44 @@ +package fr.inria.corese.core.next.query.impl.engine.path; + +import fr.inria.corese.core.next.query.impl.engine.solution.Mapping; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + +import java.util.NoSuchElementException; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import static org.junit.jupiter.api.Assertions.*; + +@Timeout(5) +class PathMappingBufferTest { + @Test + void consumesProducedMappingsAndKeepsTheEndOfStream() throws Exception { + PathMappingBuffer buffer = new PathMappingBuffer(); + Mapping mapping = Mapping.create(); + try (var executor = Executors.newSingleThreadExecutor()) { + var producer = executor.submit(() -> { + buffer.put(mapping, true); + buffer.put(null, false); + }); + assertTrue(buffer.hasNext()); + assertSame(mapping, buffer.next()); + assertFalse(buffer.hasNext()); + assertThrows(NoSuchElementException.class, buffer::next); + assertFalse(buffer.hasNext()); + producer.get(2, TimeUnit.SECONDS); + } + } + + @Test + void interruptionEndsIterationAndPreservesTheInterruptFlag() { + PathMappingBuffer buffer = new PathMappingBuffer(); + Thread.currentThread().interrupt(); + try { + assertThrows(NoSuchElementException.class, buffer::next); + assertTrue(Thread.currentThread().isInterrupted()); + } finally { + Thread.interrupted(); + } + } +} diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/ExpTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/ExpTest.java similarity index 97% rename from src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/ExpTest.java rename to src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/ExpTest.java index d98d9be0a..1c482ae3b 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/ExpTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/ExpTest.java @@ -1,7 +1,14 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.pattern; -import fr.inria.corese.core.next.query.impl.kgram.api.core.*; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Producer; +import fr.inria.corese.core.next.query.impl.engine.eval.Stack; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.ExpType; +import fr.inria.corese.core.next.query.impl.engine.model.Filter; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Regex; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; + +import fr.inria.corese.core.next.query.impl.engine.spi.Producer; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -698,7 +705,8 @@ void testIterator() { exp.add(Exp.create(ExpType.Type.EDGE)); int count = 0; - for (Exp ignored : exp) { + for (Exp subExp : exp) { + assertNotNull(subExp); count++; } assertEquals(2, count, "Should iterate through 2 expressions"); @@ -708,7 +716,8 @@ void testIterator() { @DisplayName("Empty exp should have no iterations") void testEmptyIterator() { int count = 0; - for (Exp ignored : exp) { + for (Exp subExp : exp) { + assertNotNull(subExp); count++; } assertEquals(0, count, "Empty exp should not iterate"); diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/QueryTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/QueryTest.java similarity index 98% rename from src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/QueryTest.java rename to src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/QueryTest.java index 56f4a2283..943604921 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/QueryTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/QueryTest.java @@ -1,8 +1,9 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.pattern; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExpType; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Filter; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; + +import fr.inria.corese.core.next.query.impl.engine.model.ExpType; +import fr.inria.corese.core.next.query.impl.engine.model.Filter; +import fr.inria.corese.core.next.query.impl.engine.model.Node; import fr.inria.corese.core.next.query.impl.sparql.ast.QueryAst; import fr.inria.corese.core.next.query.impl.sparql.parser.SparqlParser; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/MappingTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/solution/MappingTest.java similarity index 88% rename from src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/MappingTest.java rename to src/test/java/fr/inria/corese/core/next/query/impl/engine/solution/MappingTest.java index dd8ae683c..e05bcf2ce 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/MappingTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/solution/MappingTest.java @@ -1,7 +1,8 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.solution; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; + +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Node; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -36,6 +37,32 @@ void setUp() { mockTargetEdge = mock(Edge.class); } + @Test + void joinBindsAnUnboundVariableFromTheOtherMapping() { + when(mockQueryNode.getLabel()).thenReturn("?x"); + when(mockQueryNode.isVariable()).thenReturn(true); + Mapping unbound = Mapping.create(new Node[]{mockQueryNode}, new Node[]{null}); + Mapping bound = Mapping.create(new Node[]{mockQueryNode}, new Node[]{mockTargetNode}); + + Mapping joined = unbound.join(bound); + assertNotNull(joined); + assertSame(mockTargetNode, joined.getNodeValue(mockQueryNode)); + assertSame(mockTargetNode, bound.join(unbound).getNodeValue(mockQueryNode)); + } + + @Test + void minusRequiresASharedBoundVariable() { + when(mockQueryNode.getLabel()).thenReturn("?x"); + when(mockQueryNode.isVariable()).thenReturn(true); + Mapping unbound = Mapping.create(new Node[]{mockQueryNode}, new Node[]{null}); + Mapping bound = Mapping.create(new Node[]{mockQueryNode}, new Node[]{mockTargetNode}); + + assertFalse(unbound.compatible(bound)); + assertFalse(bound.compatible(unbound)); + bound.setSelectNodes(new Node[]{mockQueryNode}); + assertFalse(unbound.compatible(bound)); + } + @Nested @DisplayName("Mapping Creation Tests") class MappingCreationTests { diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/MappingsTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/solution/MappingsTest.java similarity index 98% rename from src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/MappingsTest.java rename to src/test/java/fr/inria/corese/core/next/query/impl/engine/solution/MappingsTest.java index d6bca2ed4..65865ff6e 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/MappingsTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/solution/MappingsTest.java @@ -1,7 +1,10 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; +package fr.inria.corese.core.next.query.impl.engine.solution; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; +import fr.inria.corese.core.next.query.impl.engine.eval.Eval; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; + +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Node; import fr.inria.corese.core.next.data.api.model.DatatypeValue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -182,7 +185,8 @@ void testIterateAll() { mappings.add(mock(Mapping.class)); int count = 0; - for (Mapping ignored : mappings) { + for (Mapping m : mappings) { + assertNotNull(m); count++; } assertEquals(3, count, "Should iterate through 3 mappings"); diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/MemoryTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/solution/MemoryTest.java similarity index 92% rename from src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/MemoryTest.java rename to src/test/java/fr/inria/corese/core/next/query/impl/engine/solution/MemoryTest.java index 5adf9bfdb..738f678b3 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/core/MemoryTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/solution/MemoryTest.java @@ -1,11 +1,15 @@ -package fr.inria.corese.core.next.query.impl.kgram.core; - -import fr.inria.corese.core.next.query.impl.kgram.api.core.BindingContext; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExpType; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Evaluator; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Matcher; -import fr.inria.corese.core.next.query.impl.kgram.api.query.ProcessVisitor; +package fr.inria.corese.core.next.query.impl.engine.solution; + +import fr.inria.corese.core.next.query.impl.engine.eval.Eval; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; + +import fr.inria.corese.core.next.query.impl.engine.model.BindingContext; +import fr.inria.corese.core.next.query.impl.engine.model.ExpType; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.spi.Evaluator; +import fr.inria.corese.core.next.query.impl.engine.spi.Matcher; +import fr.inria.corese.core.next.query.impl.engine.event.ProcessVisitor; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/tool/StorageManagerEdgeTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/storage/StorageManagerEdgeTest.java similarity index 91% rename from src/test/java/fr/inria/corese/core/next/query/impl/kgram/tool/StorageManagerEdgeTest.java rename to src/test/java/fr/inria/corese/core/next/query/impl/engine/storage/StorageManagerEdgeTest.java index 7179335f4..ebbe33d3d 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/tool/StorageManagerEdgeTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/storage/StorageManagerEdgeTest.java @@ -1,11 +1,13 @@ -package fr.inria.corese.core.next.query.impl.kgram.tool; +package fr.inria.corese.core.next.query.impl.engine.storage; + +import fr.inria.corese.core.next.query.impl.engine.model.NodeImpl; import fr.inria.corese.core.next.data.api.term.IRI; import fr.inria.corese.core.next.data.api.term.Literal; import fr.inria.corese.core.next.data.api.model.Statement; import fr.inria.corese.core.next.data.api.factory.ValueFactory; import fr.inria.corese.core.next.data.impl.adapter.CoreseValueFactory; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; +import fr.inria.corese.core.next.query.impl.engine.model.Node; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/tool/StorageManagerProducerTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/storage/StorageManagerProducerTest.java similarity index 94% rename from src/test/java/fr/inria/corese/core/next/query/impl/kgram/tool/StorageManagerProducerTest.java rename to src/test/java/fr/inria/corese/core/next/query/impl/engine/storage/StorageManagerProducerTest.java index 22a99766c..283845776 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/kgram/tool/StorageManagerProducerTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/storage/StorageManagerProducerTest.java @@ -1,4 +1,7 @@ -package fr.inria.corese.core.next.query.impl.kgram.tool; +package fr.inria.corese.core.next.query.impl.engine.storage; + +import fr.inria.corese.core.next.query.impl.engine.model.KgramNodes; +import fr.inria.corese.core.next.query.impl.engine.model.NodeImpl; import fr.inria.corese.core.next.data.api.term.IRI; import fr.inria.corese.core.next.data.api.term.Resource; @@ -9,16 +12,16 @@ import fr.inria.corese.core.next.query.impl.sparql.ast.QueryAst; import fr.inria.corese.core.next.query.impl.sparql.ast.SelectQueryAst; import fr.inria.corese.core.next.query.impl.sparql.bridge.CoreseAstQueryBuilder; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExpType.Type; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.api.query.Environment; -import fr.inria.corese.core.next.query.impl.kgram.core.Eval; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Mappings; -import fr.inria.corese.core.next.query.impl.kgram.core.Query; -import fr.inria.corese.core.next.query.impl.kgram.execution.RdfTermMatcher; -import fr.inria.corese.core.next.query.impl.kgram.execution.SparqlKgramEvaluator; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.ExpType.Type; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.spi.Environment; +import fr.inria.corese.core.next.query.impl.engine.eval.Eval; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.solution.Mappings; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; +import fr.inria.corese.core.next.query.impl.engine.eval.RdfTermMatcher; +import fr.inria.corese.core.next.query.impl.engine.eval.SparqlKgramEvaluator; import fr.inria.corese.core.next.storage.impl.memory.MemoryStorageManager; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/ast/SparqlAstTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/ast/SparqlAstTest.java index a8a4cf035..18c057a17 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/ast/SparqlAstTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/ast/SparqlAstTest.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.ast; + import fr.inria.corese.core.next.query.impl.sparql.ast.path.NegatedPropertySetPathAst; import fr.inria.corese.core.next.query.impl.sparql.ast.path.PathAst; import fr.inria.corese.core.next.query.impl.sparql.ast.path.PredicatePathAst; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/AstBackedEdgeTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/AstBackedEdgeTest.java index c3eb2fbe3..5f34c94c6 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/AstBackedEdgeTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/AstBackedEdgeTest.java @@ -1,8 +1,8 @@ package fr.inria.corese.core.next.query.impl.sparql.bridge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.tool.KgramNodes; -import fr.inria.corese.core.next.query.impl.kgram.tool.NodeImpl; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.model.KgramNodes; +import fr.inria.corese.core.next.query.impl.engine.model.NodeImpl; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderAskTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderAskTest.java index 0e1d489f2..b39dfd0ff 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderAskTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderAskTest.java @@ -17,11 +17,11 @@ import fr.inria.corese.core.next.query.impl.sparql.ast.VarAst; import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.ExistsAst; import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.GreaterThanAst; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExprType; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Query; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.ExprType; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderConstructTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderConstructTest.java index 1f55f1ad1..75dc320cc 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderConstructTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderConstructTest.java @@ -6,12 +6,12 @@ import fr.inria.corese.core.next.query.impl.sparql.ast.*; import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.ExistsAst; import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.NotExistsAst; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExprType; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Query; +import fr.inria.corese.core.next.query.impl.engine.model.ExprType; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderDescribeTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderDescribeTest.java index 59aa34a5f..42e23f2ed 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderDescribeTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderDescribeTest.java @@ -5,11 +5,11 @@ import fr.inria.corese.core.next.query.impl.sparql.ast.*; import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.ExistsAst; import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.NotExistsAst; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExprType; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Query; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.ExprType; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderMinusScopeTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderMinusScopeTest.java index 12a3c0397..ab2b14e94 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderMinusScopeTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderMinusScopeTest.java @@ -1,9 +1,9 @@ package fr.inria.corese.core.next.query.impl.sparql.bridge; import fr.inria.corese.core.next.query.impl.sparql.ast.*; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Query; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderTest.java index 05c0f2e14..f9697c309 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderTest.java @@ -17,12 +17,12 @@ import fr.inria.corese.core.next.query.impl.sparql.ast.VarAst; import fr.inria.corese.core.next.query.impl.sparql.ast.ASTConstants; import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.ExistsAst; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Edge; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExprType; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Node; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Query; +import fr.inria.corese.core.next.query.impl.engine.model.Edge; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.ExprType; +import fr.inria.corese.core.next.query.impl.engine.model.Node; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; import fr.inria.corese.core.next.query.api.exception.QuerySyntaxException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompilerExistsTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompilerExistsTest.java index e204db5ba..a319e4c74 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompilerExistsTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompilerExistsTest.java @@ -5,10 +5,10 @@ import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.ExistsAst; import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.GreaterThanAst; import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.NotExistsAst; -import fr.inria.corese.core.next.query.impl.kgram.api.core.Expr; -import fr.inria.corese.core.next.query.impl.kgram.api.core.ExprType; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.core.Query; +import fr.inria.corese.core.next.query.impl.engine.model.Expr; +import fr.inria.corese.core.next.query.impl.engine.model.ExprType; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.pattern.Query; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompilerTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompilerTest.java index 74ceac168..92c50dd55 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompilerTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompilerTest.java @@ -1,12 +1,13 @@ package fr.inria.corese.core.next.query.impl.sparql.bridge; + import fr.inria.corese.core.next.query.api.exception.UnsupportedQueryFeatureException; import fr.inria.corese.core.next.query.impl.sparql.parser.AbstractSparqlParserFeatureTest; import fr.inria.corese.core.next.query.impl.sparql.ast.*; import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.FunctionCallAst; import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.GreaterThanAst; -import fr.inria.corese.core.next.query.impl.kgram.core.Exp; -import fr.inria.corese.core.next.query.impl.kgram.tool.KgramNodes; +import fr.inria.corese.core.next.query.impl.engine.pattern.Exp; +import fr.inria.corese.core.next.query.impl.engine.model.KgramNodes; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/execution/NextSparqlPipelineExecutorTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/execution/NextSparqlPipelineExecutorTest.java index 51f605458..590efe9f1 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/execution/NextSparqlPipelineExecutorTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/execution/NextSparqlPipelineExecutorTest.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.execution; + import fr.inria.corese.core.next.data.Values; import fr.inria.corese.core.next.data.api.term.IRI; import fr.inria.corese.core.next.data.api.term.Literal; diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlParserBgpTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlParserBgpTest.java index 7f8a9925f..91ab7d79d 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlParserBgpTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlParserBgpTest.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.parser; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -9,6 +10,8 @@ import fr.inria.corese.core.next.query.impl.sparql.ast.*; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import fr.inria.corese.core.next.query.api.exception.QuerySyntaxException; @@ -134,76 +137,23 @@ void shouldParseRdfLiteralWithDatatype() { assertEquals("xsd:integer", lit.datatype()); } - @Test - void shouldParsePrefixedNameWithDigitOnlyLocalPart() { - SparqlParser parser = newParserDefault(); - - SparqlQueryAst ast = (SparqlQueryAst) parser.parse(""" - PREFIX ex: - SELECT * WHERE { - ?s ex:1 ?o . - } - """); - - BgpAst bgp = (BgpAst) ast.whereClause().patterns().getFirst(); - TriplePatternAst triple = bgp.triples().getFirst(); - - assertInstanceOf(IriAst.class, simplePredicateTerm(triple)); - assertEquals("ex:1", ((IriAst) simplePredicateTerm(triple)).raw()); - } - - @Test - void shouldParsePrefixedNameWithHyphenInLocalPart() { + @ParameterizedTest + @CsvSource({ + "ex, http://example.org/, ex:1", + "ex, http://example.org/, ex:abc-def", + "ns, http://example.org/ns#, ns:id\\=123", + "'', http://example.org/default#, :foo" + }) + void shouldParsePrefixedName(String prefix, String namespace, String name) { SparqlParser parser = newParserDefault(); - SparqlQueryAst ast = (SparqlQueryAst) parser.parse(""" - PREFIX ex: - SELECT * WHERE { - ?s ex:abc-def ?o . - } - """); - + PREFIX %s: <%s> + SELECT * WHERE { ?s %s ?o . } + """.formatted(prefix, namespace, name)); BgpAst bgp = (BgpAst) ast.whereClause().patterns().getFirst(); TriplePatternAst triple = bgp.triples().getFirst(); - - assertInstanceOf(IriAst.class, simplePredicateTerm(triple)); - assertEquals("ex:abc-def", ((IriAst) simplePredicateTerm(triple)).raw()); - } - - @Test - void shouldParsePrefixedNameWithEscapedReservedCharacterInLocalPart() { - SparqlParser parser = newParserDefault(); - - SparqlQueryAst ast = (SparqlQueryAst) parser.parse(""" - PREFIX ns: - SELECT * WHERE { - ?s ns:id\\=123 ?o . - } - """); - - BgpAst bgp = (BgpAst) ast.whereClause().patterns().getFirst(); - TriplePatternAst triple = bgp.triples().getFirst(); - - assertInstanceOf(IriAst.class, simplePredicateTerm(triple)); - assertEquals("ns:id\\=123", ((IriAst) simplePredicateTerm(triple)).raw()); - } - - @Test - void shouldParsePrefixedNameWithDefaultPrefix() { - SparqlParser parser = newParserDefault(); - - SparqlQueryAst ast = (SparqlQueryAst) parser.parse(""" - PREFIX : - SELECT * WHERE { - ?s :foo ?o . - } - """); - - BgpAst bgp = (BgpAst) ast.whereClause().patterns().getFirst(); - TriplePatternAst triple = bgp.triples().getFirst(); - - assertInstanceOf(IriAst.class, simplePredicateTerm(triple)); - assertEquals(":foo", ((IriAst) simplePredicateTerm(triple)).raw()); + IriAst predicate = assertInstanceOf(IriAst.class, simplePredicateTerm(triple)); + assertEquals(name, predicate.raw()); } @Test diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlParserFilterTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlParserFilterTest.java index c9c83a5bc..f9de0bad8 100644 --- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlParserFilterTest.java +++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/parser/SparqlParserFilterTest.java @@ -1,5 +1,6 @@ package fr.inria.corese.core.next.query.impl.sparql.parser; + import fr.inria.corese.core.next.query.impl.sparql.ast.*; import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.*; import org.junit.jupiter.api.Test;