From 8580bfe21c0179e87a3971e305705415d7ccd15c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Avard=20Ottestad?= Date: Sat, 16 Dec 2023 13:27:07 +0100 Subject: [PATCH] GH-4819 code cleanup and add javadocs --- .../common/iteration/DualUnionIteration.java | 9 ++- .../common/order/AvailableStatementOrder.java | 3 + .../rdf4j/common/order/StatementOrder.java | 3 + .../evaluation/RDFStarTripleSource.java | 2 +- .../algebra/evaluation/TripleSource.java | 56 +++++++++++++++---- .../evaluation/impl/EvaluationStatistics.java | 2 +- .../evaluation/util/ValueComparator.java | 8 +-- .../rdf4j/query/algebra/TupleExpr.java | 4 ++ .../contextaware/ContextAwareConnection.java | 4 +- .../eclipse/rdf4j/sail/SailConnection.java | 37 ++++++++++++ .../rdf4j/sail/base/UnionSailDataset.java | 2 +- 11 files changed, 108 insertions(+), 22 deletions(-) diff --git a/core/common/iterator/src/main/java/org/eclipse/rdf4j/common/iteration/DualUnionIteration.java b/core/common/iterator/src/main/java/org/eclipse/rdf4j/common/iteration/DualUnionIteration.java index 801b8b72e96..62ec2d38183 100644 --- a/core/common/iterator/src/main/java/org/eclipse/rdf4j/common/iteration/DualUnionIteration.java +++ b/core/common/iterator/src/main/java/org/eclipse/rdf4j/common/iteration/DualUnionIteration.java @@ -14,6 +14,7 @@ import java.util.Comparator; import java.util.NoSuchElementException; +import org.eclipse.rdf4j.common.annotation.Experimental; import org.eclipse.rdf4j.common.order.StatementOrder; import org.eclipse.rdf4j.model.Value; @@ -40,6 +41,7 @@ private DualUnionIteration(CloseableIteration iteration1, this.cmp = null; } + @Experimental public DualUnionIteration(StatementOrder statementOrder, Comparator cmp, CloseableIteration iteration1, CloseableIteration iteration2) { this.iteration1 = iteration1; @@ -51,7 +53,7 @@ public DualUnionIteration(StatementOrder statementOrder, Comparator cmp, throw new UnsupportedOperationException("Not implemented yet"); } - public static CloseableIteration getWildcardInstance( + public static CloseableIteration getWildcardInstance( CloseableIteration leftIteration, CloseableIteration rightIteration) { if (rightIteration instanceof EmptyIteration) { @@ -63,7 +65,8 @@ public static CloseableIteration getWildca } } - public static CloseableIteration getWildcardInstance(StatementOrder order, + @Experimental + public static CloseableIteration getWildcardInstance(StatementOrder order, Comparator cmp, CloseableIteration leftIteration, CloseableIteration rightIteration) { @@ -84,7 +87,7 @@ public static CloseableIteration getWildca } } - public static CloseableIteration getInstance(CloseableIteration leftIteration, + public static CloseableIteration getInstance(CloseableIteration leftIteration, CloseableIteration rightIteration) { if (rightIteration instanceof EmptyIteration) { diff --git a/core/common/order/src/main/java/org/eclipse/rdf4j/common/order/AvailableStatementOrder.java b/core/common/order/src/main/java/org/eclipse/rdf4j/common/order/AvailableStatementOrder.java index 843e79651c1..246be1f91e9 100644 --- a/core/common/order/src/main/java/org/eclipse/rdf4j/common/order/AvailableStatementOrder.java +++ b/core/common/order/src/main/java/org/eclipse/rdf4j/common/order/AvailableStatementOrder.java @@ -13,11 +13,14 @@ import java.util.Set; +import org.eclipse.rdf4j.common.annotation.Experimental; import org.eclipse.rdf4j.model.IRI; import org.eclipse.rdf4j.model.Resource; import org.eclipse.rdf4j.model.Value; +@Experimental public interface AvailableStatementOrder { + @Experimental Set getSupportedOrders(Resource subj, IRI pred, Value obj, Resource... contexts); } diff --git a/core/common/order/src/main/java/org/eclipse/rdf4j/common/order/StatementOrder.java b/core/common/order/src/main/java/org/eclipse/rdf4j/common/order/StatementOrder.java index 8a3d3af4084..97785413f20 100644 --- a/core/common/order/src/main/java/org/eclipse/rdf4j/common/order/StatementOrder.java +++ b/core/common/order/src/main/java/org/eclipse/rdf4j/common/order/StatementOrder.java @@ -13,9 +13,11 @@ import java.util.Comparator; +import org.eclipse.rdf4j.common.annotation.Experimental; import org.eclipse.rdf4j.model.Statement; import org.eclipse.rdf4j.model.Value; +@Experimental public enum StatementOrder { S, @@ -23,6 +25,7 @@ public enum StatementOrder { O, C; + @Experimental public Comparator getComparator(Comparator comparator) { switch (this) { case S: diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/RDFStarTripleSource.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/RDFStarTripleSource.java index eb52e4ed199..881285d0235 100644 --- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/RDFStarTripleSource.java +++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/RDFStarTripleSource.java @@ -23,7 +23,7 @@ public interface RDFStarTripleSource extends TripleSource { * indicate wildcards. * * @param subj A Resource specifying the triple's subject, or null for a wildcard. - * @param pred A URI specifying the triple's predicate, or null for a wildcard. + * @param pred A IRI specifying the triple's predicate, or null for a wildcard. * @param obj A Value specifying the triple's object, or null for a wildcard. * @return An iterator over the relevant triples. * @throws QueryEvaluationException If the rdf star triple source failed to get the statements. diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/TripleSource.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/TripleSource.java index 7b83a004a08..407c0f743a4 100644 --- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/TripleSource.java +++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/TripleSource.java @@ -14,6 +14,7 @@ import java.util.EnumSet; import java.util.Set; +import org.eclipse.rdf4j.common.annotation.Experimental; import org.eclipse.rdf4j.common.iteration.CloseableIteration; import org.eclipse.rdf4j.common.iteration.EmptyIteration; import org.eclipse.rdf4j.common.order.AvailableStatementOrder; @@ -33,7 +34,6 @@ public interface TripleSource extends AvailableStatementOrder { EmptyIteration EMPTY_ITERATION = new EmptyIteration<>(); - EmptyIteration EMPTY_TRIPLE_ITERATION = new EmptyIteration<>(); /** * Gets all statements that have a specific subject, predicate and/or object. All three parameters may be null to @@ -41,7 +41,7 @@ public interface TripleSource extends AvailableStatementOrder { * to statements matching one or more of the specified contexts. * * @param subj A Resource specifying the subject, or null for a wildcard. - * @param pred A URI specifying the predicate, or null for a wildcard. + * @param pred A IRI specifying the predicate, or null for a wildcard. * @param obj A Value specifying the object, or null for a wildcard. * @param contexts The context(s) to get the statements from. Note that this parameter is a vararg and as such is * optional. If no contexts are supplied the method operates on the entire repository. @@ -55,34 +55,70 @@ CloseableIteration getStatements(Resource subj, IRI pred, * Gets all statements that have a specific subject, predicate and/or object. All three parameters may be null to * indicate wildcards. Optionally a (set of) context(s) may be specified in which case the result will be restricted * to statements matching one or more of the specified contexts. + *

+ * Statements are returned in the order specified by the statementOrder parameter. Use + * {@link #getSupportedOrders(Resource, IRI, Value, Resource...)} to first retrieve the statement orders supported + * by this store for this statement pattern. + *

+ * Note that this method is experimental and may be changed or removed without notice. * + * @param order The order in which the statements should be returned. * @param subj A Resource specifying the subject, or null for a wildcard. - * @param pred A URI specifying the predicate, or null for a wildcard. + * @param pred A IRI specifying the predicate, or null for a wildcard. * @param obj A Value specifying the object, or null for a wildcard. * @param contexts The context(s) to get the statements from. Note that this parameter is a vararg and as such is * optional. If no contexts are supplied the method operates on the entire repository. - * @return An iterator over the relevant statements. + * @return An ordered iterator over the relevant statements. * @throws QueryEvaluationException If the triple source failed to get the statements. */ + @Experimental default CloseableIteration getStatements(StatementOrder order, Resource subj, IRI pred, Value obj, Resource... contexts) throws QueryEvaluationException { throw new UnsupportedOperationException( "StatementOrder is not supported by this TripleSource: " + this.getClass().getName()); } - default Set getSupportedOrders(Resource subj, IRI pred, - Value obj, Resource... contexts) throws QueryEvaluationException { + /** + * The underlying store may support some, but not all, statement orders based on the statement pattern. This method + * can be used to determine which orders are supported for a given statement pattern. The supported orders can be + * used to retrieve statements in a specific order using + * {@link #getStatements(StatementOrder, Resource, IRI, Value, Resource...)} . + *

+ * Note that this method is experimental and may be changed or removed without notice. + * + * @param subj A Resource specifying the subject, or null for a wildcard. + * @param pred A IRI specifying the predicate, or null for a wildcard. + * @param obj A Value specifying the object, or null for a wildcard. + * @param contexts The context(s) to get the data from. Note that this parameter is a vararg and as such is + * optional. If no contexts are specified the method operates on the entire repository. A + * null value can be used to match context-less statements. + * @return a set of supported statement orders + */ + @Experimental + default Set getSupportedOrders(Resource subj, IRI pred, Value obj, Resource... contexts) { return Set.of(); } /** - * Gets a ValueFactory object that can be used to create URI-, blank node- and literal objects. + * Different underlying datastructures may have different ways of ordering statements. On-disk stores typically use + * a long to represent a value and only stores the actual value in a dictionary, in this case the order would be the + * order that values where inserted into the dictionary. Stores that instead store values in SPARQL-order can return + * an instance of {@link org.eclipse.rdf4j.query.algebra.evaluation.util.ValueComparator} which may allow for + * further optimizations. + *

+ * Note that this method is experimental and may be changed or removed without notice. * - * @return a ValueFactory object for this TripleSource. + * @return a comparator that matches the order of values in the store */ - ValueFactory getValueFactory(); - + @Experimental default Comparator getComparator() { return null; } + + /** + * Gets a ValueFactory object that can be used to create IRI-, blank node- and literal objects. + * + * @return a ValueFactory object for this TripleSource. + */ + ValueFactory getValueFactory(); } diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/EvaluationStatistics.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/EvaluationStatistics.java index 8645802a68a..5cce4ce088d 100644 --- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/EvaluationStatistics.java +++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/EvaluationStatistics.java @@ -129,7 +129,7 @@ public void meet(ArbitraryLengthPath node) { @Override public void meet(Service node) { if (!node.getServiceRef().hasValue()) { - // the URI is not available, may be computed in the course of the + // the IRI is not available, may be computed in the course of the // query // => use high cost to order the SERVICE node late in the query plan cardinality = UNBOUND_SERVICE_CARDINALITY; diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/util/ValueComparator.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/util/ValueComparator.java index fc5b709e004..6d75dba6219 100644 --- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/util/ValueComparator.java +++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/util/ValueComparator.java @@ -63,7 +63,7 @@ public int compare(Value o1, Value o2) { boolean iri1 = o1.isIRI(); boolean iri2 = o2.isIRI(); if (iri1 && iri2) { - return compareURIs((IRI) o1, (IRI) o2); + return compareIRIs((IRI) o1, (IRI) o2); } if (iri1) { return -1; @@ -101,8 +101,8 @@ private int compareBNodes(BNode leftBNode, BNode rightBNode) { return leftBNode.getID().compareTo(rightBNode.getID()); } - private int compareURIs(IRI leftURI, IRI rightURI) { - return leftURI.toString().compareTo(rightURI.toString()); + private int compareIRIs(IRI leftIRI, IRI rightIRI) { + return leftIRI.toString().compareTo(rightIRI.toString()); } private int compareLiterals(Literal leftLit, Literal rightLit) { @@ -211,7 +211,7 @@ private int compareDatatypes(CoreDatatype.XSD leftDatatype, CoreDatatype.XSD rig } // incompatible or unordered datatype - return compareURIs(leftDatatypeIRI, rightDatatypeIRI); + return compareIRIs(leftDatatypeIRI, rightDatatypeIRI); } diff --git a/core/queryalgebra/model/src/main/java/org/eclipse/rdf4j/query/algebra/TupleExpr.java b/core/queryalgebra/model/src/main/java/org/eclipse/rdf4j/query/algebra/TupleExpr.java index 89c506e9bb2..d0971eb448c 100644 --- a/core/queryalgebra/model/src/main/java/org/eclipse/rdf4j/query/algebra/TupleExpr.java +++ b/core/queryalgebra/model/src/main/java/org/eclipse/rdf4j/query/algebra/TupleExpr.java @@ -12,6 +12,7 @@ import java.util.Set; +import org.eclipse.rdf4j.common.annotation.Experimental; import org.eclipse.rdf4j.common.order.AvailableStatementOrder; /** @@ -37,9 +38,12 @@ public interface TupleExpr extends QueryModelNode { @Override TupleExpr clone(); + @Experimental Set getSupportedOrders(AvailableStatementOrder tripleSource); + @Experimental void setOrder(Var var); + @Experimental Var getOrder(); } diff --git a/core/repository/contextaware/src/main/java/org/eclipse/rdf4j/repository/contextaware/ContextAwareConnection.java b/core/repository/contextaware/src/main/java/org/eclipse/rdf4j/repository/contextaware/ContextAwareConnection.java index 0b4903c968d..0503e5222f7 100644 --- a/core/repository/contextaware/src/main/java/org/eclipse/rdf4j/repository/contextaware/ContextAwareConnection.java +++ b/core/repository/contextaware/src/main/java/org/eclipse/rdf4j/repository/contextaware/ContextAwareConnection.java @@ -458,7 +458,7 @@ public void exportStatements(Resource subj, IRI pred, Value obj, boolean include * optionally restricted to the specified set of named contexts. * * @param subj A Resource specifying the subject, or null for a wildcard. - * @param pred A URI specifying the predicate, or null for a wildcard. + * @param pred A IRI specifying the predicate, or null for a wildcard. * @param obj A Value specifying the object, or null for a wildcard. * @return The statements matching the specified pattern. The result object is a {@link RepositoryResult} object, a * lazy Iterator-like object containing {@link Statement}s and optionally throwing a @@ -511,7 +511,7 @@ public boolean hasStatement(Statement st, boolean includeInferred, Resource... c * the specified contexts. * * @param subj A Resource specifying the subject, or null for a wildcard. - * @param pred A URI specifying the predicate, or null for a wildcard. + * @param pred A IRI specifying the predicate, or null for a wildcard. * @param obj A Value specifying the object, or null for a wildcard. * @return true If a matching statement is in the repository in the specified context, false otherwise. * @see #getReadContexts() diff --git a/core/sail/api/src/main/java/org/eclipse/rdf4j/sail/SailConnection.java b/core/sail/api/src/main/java/org/eclipse/rdf4j/sail/SailConnection.java index da6cfde2ae4..55b2afbf1c2 100644 --- a/core/sail/api/src/main/java/org/eclipse/rdf4j/sail/SailConnection.java +++ b/core/sail/api/src/main/java/org/eclipse/rdf4j/sail/SailConnection.java @@ -125,6 +125,13 @@ CloseableIteration getStatements(Resource subj, IRI pred, V * Gets all statements from the specified contexts that have a specific subject, predicate and/or object. All three * parameters may be null to indicate wildcards. The includeInferred parameter can be used to control * which statements are fetched: all statements or only the statements that have been added explicitly. + *

+ * Statements are returned in the order specified by the statementOrder parameter. Use + * {@link #getSupportedOrders(Resource, IRI, Value, Resource...)} to first retrieve the statement orders supported + * by this store for this statement pattern. + *

+ * Note that this method is experimental and may be changed or removed without notice. + * * * @param statementOrder The order that the statements should be returned in. * @param subj A Resource specifying the subject, or null for a wildcard. @@ -139,6 +146,7 @@ CloseableIteration getStatements(Resource subj, IRI pred, V * @throws SailException If the Sail object encountered an error or unexpected situation internally. * @throws IllegalStateException If the connection has been closed. */ + @Experimental default CloseableIteration getStatements(StatementOrder statementOrder, Resource subj, IRI pred, Value obj, boolean includeInferred, Resource... contexts) throws SailException { @@ -468,10 +476,39 @@ default Explanation explain(Explanation.Level level, TupleExpr tupleExpr, Datase throw new UnsupportedOperationException(); } + /** + * The underlying store may support some, but not all, statement orders based on the statement pattern. This method + * can be used to determine which orders are supported for a given statement pattern. The supported orders can be + * used to retrieve statements in a specific order using + * {@link #getStatements(StatementOrder, Resource, IRI, Value, boolean, Resource...)}. + *

+ * Note that this method is experimental and may be changed or removed without notice. + * + * @param subj A Resource specifying the subject, or null for a wildcard. + * @param pred A URI specifying the predicate, or null for a wildcard. + * @param obj A Value specifying the object, or null for a wildcard. + * @param contexts The context(s) to get the data from. Note that this parameter is a vararg and as such is + * optional. If no contexts are specified the method operates on the entire repository. A + * null value can be used to match context-less statements. + * @return a set of supported statement orders + */ + @Experimental default Set getSupportedOrders(Resource subj, IRI pred, Value obj, Resource... contexts) { return Set.of(); } + /** + * Different underlying datastructures may have different ways of ordering statements. On-disk stores typically use + * a long to represent a value and only stores the actual value in a dictionary, in this case the order would be the + * order that values where inserted into the dictionary. Stores that instead store values in SPARQL-order can return + * an instance of {@link org.eclipse.rdf4j.query.algebra.evaluation.util.ValueComparator} which may allow for + * further optimizations. + *

+ * Note that this method is experimental and may be changed or removed without notice. + * + * @return a comparator that matches the order of values in the store + */ + @Experimental default Comparator getComparator() { return null; } diff --git a/core/sail/base/src/main/java/org/eclipse/rdf4j/sail/base/UnionSailDataset.java b/core/sail/base/src/main/java/org/eclipse/rdf4j/sail/base/UnionSailDataset.java index 337bba70d6e..4635ce8ca24 100644 --- a/core/sail/base/src/main/java/org/eclipse/rdf4j/sail/base/UnionSailDataset.java +++ b/core/sail/base/src/main/java/org/eclipse/rdf4j/sail/base/UnionSailDataset.java @@ -176,7 +176,7 @@ private CloseableIteration union( return DualUnionIteration.getWildcardInstance(iteration1, iteration2); } - private CloseableIteration union(StatementOrder order, Comparator cmp, + private CloseableIteration union(StatementOrder order, Comparator cmp, CloseableIteration iteration1, CloseableIteration iteration2) { return DualUnionIteration.getWildcardInstance(order, cmp, iteration1, iteration2);