Skip to content

Commit

Permalink
eclipse-rdf4jGH-3696 cleanup of refactored optimizers, reimplemented …
Browse files Browse the repository at this point in the history
…fix in new class
  • Loading branch information
abrokenjester committed Jul 17, 2022
1 parent 730ef2b commit 0cf8666
Show file tree
Hide file tree
Showing 19 changed files with 64 additions and 2,248 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,15 @@
*******************************************************************************/
package org.eclipse.rdf4j.query.algebra.evaluation.impl;

import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.Dataset;
import org.eclipse.rdf4j.query.algebra.TupleExpr;
import org.eclipse.rdf4j.query.algebra.Var;
import org.eclipse.rdf4j.query.algebra.evaluation.QueryOptimizer;
import org.eclipse.rdf4j.query.algebra.helpers.AbstractQueryModelVisitor;
import org.eclipse.rdf4j.query.algebra.evaluation.optimizer.BindingAssignerOptimizer;

/**
* Assigns values to variables based on a supplied set of bindings.
*
* @author Arjohn Kampman
* @deprecated since 4.1.0. Use {@link BindingAssignerOptimizer} instead.
*/
@Deprecated(forRemoval = true, since = "4.1.0")
public class BindingAssigner implements QueryOptimizer {
public class BindingAssigner extends org.eclipse.rdf4j.query.algebra.evaluation.optimizer.BindingAssignerOptimizer {

@Override
public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings) {
if (bindings.size() > 0) {
tupleExpr.visit(new VarVisitor(bindings));
}
}

protected static class VarVisitor extends AbstractQueryModelVisitor<RuntimeException> {

protected BindingSet bindings;

public VarVisitor(BindingSet bindings) {
this.bindings = bindings;
}

@Override
public void meet(Var var) {
if (!var.hasValue() && bindings.hasBinding(var.getName())) {
Value value = bindings.getValue(var.getName());
var.setValue(value);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,78 +7,17 @@
*******************************************************************************/
package org.eclipse.rdf4j.query.algebra.evaluation.impl;

import java.util.Iterator;

import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.Dataset;
import org.eclipse.rdf4j.query.algebra.AbstractQueryModelNode;
import org.eclipse.rdf4j.query.algebra.BindingSetAssignment;
import org.eclipse.rdf4j.query.algebra.Filter;
import org.eclipse.rdf4j.query.algebra.LeftJoin;
import org.eclipse.rdf4j.query.algebra.QueryModelNode;
import org.eclipse.rdf4j.query.algebra.TupleExpr;
import org.eclipse.rdf4j.query.algebra.Var;
import org.eclipse.rdf4j.query.algebra.evaluation.QueryOptimizer;
import org.eclipse.rdf4j.query.algebra.helpers.AbstractQueryModelVisitor;
import org.eclipse.rdf4j.query.algebra.evaluation.optimizer.BindingSetAssignmentInlinerOptimizer;

/**
* Optimizes a query model by inlining {@link BindingSetAssignment} values where possible.
*
* @author Jeen Broekstra
* @deprecated since 4.1.0. Use {@link BindingSetAssignmentInlinerOptimizer} instead.
*/
@Deprecated(forRemoval = true, since = "4.1.0")
public class BindingSetAssignmentInliner implements QueryOptimizer {

@Override
public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings) {
BindingSetAssignmentVisitor visitor = new BindingSetAssignmentVisitor();
tupleExpr.visit(visitor);
}

private static class BindingSetAssignmentVisitor extends AbstractQueryModelVisitor<RuntimeException> {

private BindingSet bindingSet;

@Override
public void meet(BindingSetAssignment bsa) {
Iterator<BindingSet> iter = bsa.getBindingSets().iterator();
if (iter.hasNext()) {
BindingSet firstBindingSet = iter.next();
if (!iter.hasNext()) {
bindingSet = firstBindingSet;
}
}
super.meet(bsa);
}

@Override
public void meet(Var var) {
if (bindingSet != null && bindingSet.hasBinding(var.getName())) {
var.setValue(bindingSet.getValue(var.getName()));
}
}

@Override
public void meet(Filter node) throws RuntimeException {
// TODO Auto-generated method stub
super.meet(node);
}

@Override
public void meet(LeftJoin leftJoin) {
leftJoin.getLeftArg().visit(this);
// we can not pre-bind values for the optional part of the left-join
}
public class BindingSetAssignmentInliner
extends org.eclipse.rdf4j.query.algebra.evaluation.optimizer.BindingSetAssignmentInlinerOptimizer {

@Override
protected void meetNode(QueryModelNode node) throws RuntimeException {
// reset if we encounter a scope change (e.g. a subquery or a union)
if (node instanceof AbstractQueryModelNode) {
if (((AbstractQueryModelNode) node).isVariableScopeChange()) {
bindingSet = null;
}
}
super.meetNode(node);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,78 +7,16 @@
*******************************************************************************/
package org.eclipse.rdf4j.query.algebra.evaluation.impl;

import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.Dataset;
import org.eclipse.rdf4j.query.algebra.Compare;
import org.eclipse.rdf4j.query.algebra.Compare.CompareOp;
import org.eclipse.rdf4j.query.algebra.SameTerm;
import org.eclipse.rdf4j.query.algebra.TupleExpr;
import org.eclipse.rdf4j.query.algebra.ValueConstant;
import org.eclipse.rdf4j.query.algebra.ValueExpr;
import org.eclipse.rdf4j.query.algebra.Var;
import org.eclipse.rdf4j.query.algebra.evaluation.QueryOptimizer;
import org.eclipse.rdf4j.query.algebra.helpers.AbstractQueryModelVisitor;

/**
* A query optimizer that replaces {@link Compare} operators with {@link SameTerm}s, if possible.
*
* @author Arjohn Kampman
* @deprecated since 4.1.0. Use {@link org.eclipse.rdf4j.query.algebra.evaluation.optimizer.CompareOptimizer} instead.
*/
@Deprecated(forRemoval = true, since = "4.1.0")
public class CompareOptimizer implements QueryOptimizer {
public class CompareOptimizer extends org.eclipse.rdf4j.query.algebra.evaluation.optimizer.CompareOptimizer {

/**
* Applies generally applicable optimizations to the supplied query: variable assignments are inlined.
*/
@Override
public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings) {
tupleExpr.visit(new CompareVisitor());
}

protected static class CompareVisitor extends AbstractQueryModelVisitor<RuntimeException> {

@Override
public void meet(Compare compare) {
super.meet(compare);

if (compare.getOperator() == CompareOp.EQ) {
ValueExpr leftArg = compare.getLeftArg();
ValueExpr rightArg = compare.getRightArg();

boolean leftIsVar = isVar(leftArg);
boolean rightIsVar = isVar(rightArg);
boolean leftIsResource = isResource(leftArg);
boolean rightIsResource = isResource(rightArg);

if (leftIsVar && rightIsResource || leftIsResource && rightIsVar || leftIsResource && rightIsResource) {
SameTerm sameTerm = new SameTerm(leftArg, rightArg);
compare.replaceWith(sameTerm);
}
}
}

protected boolean isVar(ValueExpr valueExpr) {
if (valueExpr instanceof Var) {
return true;
}

return false;
}

protected boolean isResource(ValueExpr valueExpr) {
if (valueExpr instanceof ValueConstant) {
Value value = ((ValueConstant) valueExpr).getValue();
return value instanceof Resource;
}

if (valueExpr instanceof Var) {
Value value = ((Var) valueExpr).getValue();
return value instanceof Resource;
}

return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,97 +7,16 @@
*******************************************************************************/
package org.eclipse.rdf4j.query.algebra.evaluation.impl;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.Dataset;
import org.eclipse.rdf4j.query.algebra.And;
import org.eclipse.rdf4j.query.algebra.Filter;
import org.eclipse.rdf4j.query.algebra.LeftJoin;
import org.eclipse.rdf4j.query.algebra.TupleExpr;
import org.eclipse.rdf4j.query.algebra.ValueExpr;
import org.eclipse.rdf4j.query.algebra.evaluation.QueryOptimizer;
import org.eclipse.rdf4j.query.algebra.helpers.AbstractQueryModelVisitor;
import org.eclipse.rdf4j.query.algebra.helpers.VarNameCollector;

/**
* Splits conjunctive constraints into seperate constraints.
*
* @author Arjohn Kampman
* @deprecated since 4.1.0. Use
* {@link org.eclipse.rdf4j.query.algebra.evaluation.optimizer.ConjunctiveConstraintSplitterOptimizer}
* instead.
*/
@Deprecated(forRemoval = true, since = "4.1.0")
public class ConjunctiveConstraintSplitter implements QueryOptimizer {

@Override
public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings) {
tupleExpr.visit(new ConstraintVisitor(tupleExpr));
}

protected static class ConstraintVisitor extends AbstractQueryModelVisitor<RuntimeException> {

protected final TupleExpr tupleExpr;

public ConstraintVisitor(TupleExpr tupleExpr) {
this.tupleExpr = tupleExpr;
}

@Override
public void meet(Filter filter) {
super.meet(filter);

List<ValueExpr> conjunctiveConstraints = new ArrayList<>(16);
getConjunctiveConstraints(filter.getCondition(), conjunctiveConstraints);

TupleExpr filterArg = filter.getArg();

for (int i = conjunctiveConstraints.size() - 1; i >= 1; i--) {
Filter newFilter = new Filter(filterArg, conjunctiveConstraints.get(i));
filterArg = newFilter;
}

filter.setCondition(conjunctiveConstraints.get(0));
filter.setArg(filterArg);
}

@Override
public void meet(LeftJoin node) {
super.meet(node);

if (node.getCondition() != null) {
List<ValueExpr> conjunctiveConstraints = new ArrayList<>(16);
getConjunctiveConstraints(node.getCondition(), conjunctiveConstraints);

TupleExpr arg = node.getRightArg();
ValueExpr condition = null;

for (ValueExpr constraint : conjunctiveConstraints) {
if (isWithinBindingScope(constraint, arg)) {
arg = new Filter(arg, constraint);
} else if (condition == null) {
condition = constraint;
} else {
condition = new And(condition, constraint);
}
}

node.setCondition(condition);
node.setRightArg(arg);
}
}

protected void getConjunctiveConstraints(ValueExpr valueExpr, List<ValueExpr> conjunctiveConstraints) {
if (valueExpr instanceof And) {
And and = (And) valueExpr;
getConjunctiveConstraints(and.getLeftArg(), conjunctiveConstraints);
getConjunctiveConstraints(and.getRightArg(), conjunctiveConstraints);
} else {
conjunctiveConstraints.add(valueExpr);
}
}
public class ConjunctiveConstraintSplitter
extends org.eclipse.rdf4j.query.algebra.evaluation.optimizer.ConjunctiveConstraintSplitterOptimizer {

private boolean isWithinBindingScope(ValueExpr condition, TupleExpr node) {
return node.getBindingNames().containsAll(VarNameCollector.process(condition));
}
}
}
Loading

0 comments on commit 0cf8666

Please sign in to comment.