You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2010/10/19 14:03:20 UTC
svn commit: r1024211 - in
/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join:
ChildNodeJoinMerger.java DescendantNodeJoinMerger.java EquiJoinMerger.java
JoinMerger.java QueryEngine.java SameNodeJoinMerger.java
Author: jukka
Date: Tue Oct 19 12:03:19 2010
New Revision: 1024211
URL: http://svn.apache.org/viewvc?rev=1024211&view=rev
Log:
JCR-2715: Improved join query performance
Add support for offset and limit on join queries.
Better handling of queries with too many or clauses.
Various smaller improvements.
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/ChildNodeJoinMerger.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/DescendantNodeJoinMerger.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/EquiJoinMerger.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/JoinMerger.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/QueryEngine.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/SameNodeJoinMerger.java
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/ChildNodeJoinMerger.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/ChildNodeJoinMerger.java?rev=1024211&r1=1024210&r2=1024211&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/ChildNodeJoinMerger.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/ChildNodeJoinMerger.java Tue Oct 19 12:03:19 2010
@@ -57,10 +57,10 @@ class ChildNodeJoinMerger extends JoinMe
}
@Override
- public Constraint getRightJoinConstraint(List<Row> leftRows)
+ public List<Constraint> getRightJoinConstraints(List<Row> leftRows)
throws RepositoryException {
// TODO Auto-generated method stub
- return null;
+ return Collections.emptyList();
}
private Set<String> getValues(Set<String> selectors, Row row)
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/DescendantNodeJoinMerger.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/DescendantNodeJoinMerger.java?rev=1024211&r1=1024210&r2=1024211&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/DescendantNodeJoinMerger.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/DescendantNodeJoinMerger.java Tue Oct 19 12:03:19 2010
@@ -27,7 +27,6 @@ import javax.jcr.RepositoryException;
import javax.jcr.query.Row;
import javax.jcr.query.qom.Constraint;
import javax.jcr.query.qom.DescendantNodeJoinCondition;
-import javax.jcr.query.qom.EquiJoinCondition;
import javax.jcr.query.qom.Join;
import javax.jcr.query.qom.PropertyValue;
import javax.jcr.query.qom.QueryObjectModelFactory;
@@ -59,10 +58,10 @@ class DescendantNodeJoinMerger extends J
}
@Override
- public Constraint getRightJoinConstraint(List<Row> leftRows)
+ public List<Constraint> getRightJoinConstraints(List<Row> leftRows)
throws RepositoryException {
// TODO Auto-generated method stub
- return null;
+ return Collections.emptyList();
}
private Set<String> getValues(Set<String> selectors, Row row)
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/EquiJoinMerger.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/EquiJoinMerger.java?rev=1024211&r1=1024210&r2=1024211&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/EquiJoinMerger.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/EquiJoinMerger.java Tue Oct 19 12:03:19 2010
@@ -76,7 +76,7 @@ class EquiJoinMerger extends JoinMerger
}
@Override
- public Constraint getRightJoinConstraint(List<Row> leftRows)
+ public List<Constraint> getRightJoinConstraints(List<Row> leftRows)
throws RepositoryException {
Map<String, Literal> literals = new HashMap<String, Literal>();
for (Row leftRow : leftRows) {
@@ -91,8 +91,7 @@ class EquiJoinMerger extends JoinMerger
constraints.add(factory.comparison(
rightProperty, JCR_OPERATOR_EQUAL_TO, literal));
}
-
- return Constraints.or(factory, constraints);
+ return constraints;
}
private Set<String> getValues(PropertyValue property, Row row)
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/JoinMerger.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/JoinMerger.java?rev=1024211&r1=1024210&r2=1024211&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/JoinMerger.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/JoinMerger.java Tue Oct 19 12:03:19 2010
@@ -141,7 +141,7 @@ abstract class JoinMerger {
}
public QueryResult merge(
- RowIterator leftRows, RowIterator rightRows)
+ RowIterator leftRows, RowIterator rightRows, long offset, long limit)
throws RepositoryException {
RowIterator joinRows;
if (JCR_JOIN_TYPE_RIGHT_OUTER.equals(type)) {
@@ -172,6 +172,16 @@ abstract class JoinMerger {
boolean outer = JCR_JOIN_TYPE_LEFT_OUTER.equals(type);
joinRows = mergeLeft(leftRows, map, outer);
}
+ while ((offset-- > 0 || limit == 0) && joinRows.hasNext()) {
+ joinRows.nextRow();
+ }
+ if (limit > 0) {
+ List<Row> rows = new ArrayList<Row>((int) limit);
+ for (int i = 0; i < limit && joinRows.hasNext(); i++) {
+ rows.add(joinRows.nextRow());
+ }
+ joinRows = new RowIteratorAdapter(rows);
+ }
return new SimpleQueryResult(columnNames, selectorNames, joinRows);
}
@@ -252,7 +262,7 @@ abstract class JoinMerger {
public abstract Set<String> getRightValues(Row row)
throws RepositoryException;
- public abstract Constraint getRightJoinConstraint(List<Row> leftRows)
+ public abstract List<Constraint> getRightJoinConstraints(List<Row> leftRows)
throws RepositoryException;
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/QueryEngine.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/QueryEngine.java?rev=1024211&r1=1024210&r2=1024211&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/QueryEngine.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/QueryEngine.java Tue Oct 19 12:03:19 2010
@@ -28,15 +28,12 @@ import static javax.jcr.query.qom.QueryO
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import javax.jcr.Node;
-import javax.jcr.PathNotFoundException;
+import javax.jcr.NodeIterator;
import javax.jcr.PropertyType;
import javax.jcr.RangeIterator;
import javax.jcr.RepositoryException;
@@ -76,6 +73,7 @@ import javax.jcr.query.qom.Source;
import javax.jcr.query.qom.UpperCase;
import org.apache.jackrabbit.commons.JcrUtils;
+import org.apache.jackrabbit.commons.iterator.NodeIteratorAdapter;
import org.apache.jackrabbit.commons.iterator.RangeIteratorAdapter;
import org.apache.jackrabbit.commons.iterator.RowIteratorAdapter;
@@ -150,20 +148,18 @@ public class QueryEngine {
this.evaluator = new OperandEvaluator(valueFactory, variables);
}
- public QueryEngine(Session session) throws RepositoryException {
- this(session, new HashMap<String, Value>());
- }
-
public QueryResult execute(
- Column[] columns, Source source,
- Constraint constraint, Ordering[] orderings)
+ Column[] columns, Source source, Constraint constraint,
+ Ordering[] orderings, long offset, long limit)
throws RepositoryException {
if (source instanceof Selector) {
Selector selector = (Selector) source;
- return execute(columns, selector, constraint, orderings);
+ return execute(
+ columns, selector, constraint, orderings, offset, limit);
} else if (source instanceof Join) {
Join join = (Join) source;
- return execute(columns, join, constraint, orderings);
+ return execute(
+ columns, join, constraint, orderings, offset, limit);
} else {
throw new UnsupportedRepositoryOperationException(
"Unknown source type: " + source);
@@ -171,8 +167,8 @@ public class QueryEngine {
}
protected QueryResult execute(
- Column[] columns, Join join,
- Constraint constraint, Ordering[] orderings)
+ Column[] columns, Join join, Constraint constraint,
+ Ordering[] orderings, long offset, long limit)
throws RepositoryException {
JoinMerger merger = JoinMerger.getJoinMerger(
join, getColumnMap(columns, getSelectorNames(join)),
@@ -183,42 +179,42 @@ public class QueryEngine {
Source left = join.getLeft();
Constraint leftConstraint = splitter.getLeftConstraint();
- System.out.println("FROM " + left + " WHERE " + leftConstraint);
- QueryResult leftResult = execute(null, left, leftConstraint, null);
+ QueryResult leftResult =
+ execute(null, left, leftConstraint, null, 0, -1);
List<Row> leftRows = new ArrayList<Row>();
for (Row row : JcrUtils.getRows(leftResult)) {
- System.out.println(row);
leftRows.add(row);
}
+ RowIterator rightRows;
Source right = join.getRight();
- Constraint rightConstraint = Constraints.and(
- qomFactory,
- merger.getRightJoinConstraint(leftRows),
- splitter.getRightConstraint());
- System.out.println("FROM " + right + " WHERE " + rightConstraint);
- QueryResult rightResult = execute(null, right, rightConstraint, null);
-
- return merger.merge(
- new RowIteratorAdapter(leftRows), rightResult.getRows());
- }
-
- private Set<String> getPaths(
- String selectorName, String relativePath, List<Row> rows)
- throws RepositoryException {
- Set<String> paths = new HashSet<String>();
- for (Row row : rows) {
- try {
- Node node = row.getNode(selectorName);
- if (relativePath != null) {
- node = node.getNode(relativePath);
+ List<Constraint> rightConstraints =
+ merger.getRightJoinConstraints(leftRows);
+ if (rightConstraints.size() < 500) {
+ Constraint rightConstraint = Constraints.and(
+ qomFactory,
+ Constraints.or(qomFactory, rightConstraints),
+ splitter.getRightConstraint());
+ rightRows =
+ execute(null, right, rightConstraint, null, 0, -1).getRows();
+ } else {
+ List<Row> list = new ArrayList<Row>();
+ for (int i = 0; i < rightConstraints.size(); i += 500) {
+ Constraint rightConstraint = Constraints.and(
+ qomFactory,
+ Constraints.or(qomFactory, rightConstraints.subList(
+ i, Math.min(i + 500, rightConstraints.size()))),
+ splitter.getRightConstraint());
+ QueryResult rigthResult =
+ execute(null, right, rightConstraint, null, 0, -1);
+ for (Row row : JcrUtils.getRows(rigthResult)) {
+ list.add(row);
}
- paths.add(node.getPath());
- } catch (PathNotFoundException e) {
- // Node at relative path not found, skip
}
+ rightRows = new RowIteratorAdapter(list);
}
- return paths;
+ return merger.merge(
+ new RowIteratorAdapter(leftRows), rightRows, offset, limit);
}
private String toSqlConstraint(Constraint constraint)
@@ -302,8 +298,8 @@ public class QueryEngine {
}
protected QueryResult execute(
- Column[] columns, Selector selector,
- Constraint constraint, Ordering[] orderings)
+ Column[] columns, Selector selector, Constraint constraint,
+ Ordering[] orderings, long offset, long limit)
throws RepositoryException {
StringBuilder builder = new StringBuilder();
builder.append("SELECT * FROM ");
@@ -312,7 +308,6 @@ public class QueryEngine {
builder.append(" WHERE ");
builder.append(toSqlConstraint(constraint));
}
- System.out.println(builder.toString());
QueryManager manager = session.getWorkspace().getQueryManager();
Query query = manager.createQuery(builder.toString(), Query.SQL);
@@ -326,8 +321,20 @@ public class QueryEngine {
final String[] columnNames =
columnMap.keySet().toArray(new String[columnMap.size()]);
+ NodeIterator nodes = query.execute().getNodes();
+ while ((offset-- > 0 || limit == 0) && nodes.hasNext()) {
+ nodes.next();
+ }
+ if (limit > 0) {
+ List<Node> list = new ArrayList<Node>((int) limit);
+ for (int i = 0; i < limit && nodes.hasNext(); i++) {
+ list.add(nodes.nextNode());
+ }
+ nodes = new NodeIteratorAdapter(list);
+ }
+
final String selectorName = selector.getSelectorName();
- RangeIterator rows = new RangeIteratorAdapter(query.execute().getNodes()) {
+ RangeIterator rows = new RangeIteratorAdapter(nodes) {
@Override
public Object next() {
Node node = (Node) super.next();
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/SameNodeJoinMerger.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/SameNodeJoinMerger.java?rev=1024211&r1=1024210&r2=1024211&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/SameNodeJoinMerger.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/SameNodeJoinMerger.java Tue Oct 19 12:03:19 2010
@@ -60,10 +60,10 @@ class SameNodeJoinMerger extends JoinMer
}
@Override
- public Constraint getRightJoinConstraint(List<Row> leftRows)
+ public List<Constraint> getRightJoinConstraints(List<Row> leftRows)
throws RepositoryException {
// TODO Auto-generated method stub
- return null;
+ return Collections.emptyList();
}
private Set<String> getValues(Set<String> selectors, Row row)