You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ju...@apache.org on 2012/08/09 13:35:58 UTC
svn commit: r1371168 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/kernel/
main/java/org/apache/jackrabbit/oak/plugins/lucene/
main/java/org/apache/jackrabbit/oak/plugins/memory/
main/java/org/apache/jackrabbit/oak/query/...
Author: jukka
Date: Thu Aug 9 11:35:58 2012
New Revision: 1371168
URL: http://svn.apache.org/viewvc?rev=1371168&view=rev
Log:
OAK-233: Query should use the NodeStore abstraction
Add a NodeState argument to Query.executeQuery().
Adjust the TraversingIndex to use the NodeState instead of directly calling the MicroKernel.
Also extend the TraversingIndex to support common PropertyRestrictions
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/lucene/LuceneIndex.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/StringValue.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ResultImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PropertyContentIndex.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingCursor.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/QueryIndex.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/lucene/LuceneEditorTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/TraversingCursorTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java?rev=1371168&r1=1371167&r2=1371168&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeState.java Thu Aug 9 11:35:58 2012
@@ -48,7 +48,7 @@ import com.google.common.collect.Lists;
* Basic {@link NodeState} implementation based on the {@link MicroKernel}
* interface. This class makes an attempt to load data lazily.
*/
-final class KernelNodeState extends AbstractNodeState {
+public final class KernelNodeState extends AbstractNodeState {
/**
* Maximum number of child nodes kept in memory.
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/lucene/LuceneIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/lucene/LuceneIndex.java?rev=1371168&r1=1371167&r2=1371168&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/lucene/LuceneIndex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/lucene/LuceneIndex.java Thu Aug 9 11:35:58 2012
@@ -31,6 +31,7 @@ import org.apache.jackrabbit.oak.spi.Cur
import org.apache.jackrabbit.oak.spi.Filter;
import org.apache.jackrabbit.oak.spi.Filter.PropertyRestriction;
import org.apache.jackrabbit.oak.spi.QueryIndex;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
@@ -76,9 +77,9 @@ public class LuceneIndex implements Quer
}
@Override
- public Cursor query(Filter filter, String revisionId) {
+ public Cursor query(Filter filter, String revisionId, NodeState root) {
try {
- Directory directory = new OakDirectory(store, store.getRoot(), index.getPath());
+ Directory directory = new OakDirectory(store, root, index.getPath());
try {
IndexReader reader = DirectoryReader.open(directory);
try {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/StringValue.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/StringValue.java?rev=1371168&r1=1371167&r2=1371168&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/StringValue.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/StringValue.java Thu Aug 9 11:35:58 2012
@@ -18,7 +18,7 @@ package org.apache.jackrabbit.oak.plugin
import javax.jcr.PropertyType;
-final class StringValue extends MemoryValue {
+public final class StringValue extends MemoryValue {
private final String value;
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java?rev=1371168&r1=1371167&r2=1371168&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java Thu Aug 9 11:35:58 2012
@@ -53,6 +53,7 @@ import org.apache.jackrabbit.oak.query.a
import org.apache.jackrabbit.oak.query.ast.UpperCaseImpl;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.QueryIndex;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
/**
* Represents a parsed query. Lifecycle: use the constructor to create a new
@@ -286,11 +287,11 @@ public class Query {
this.explain = explain;
}
- public ResultImpl executeQuery(String revisionId) {
- return new ResultImpl(this, revisionId);
+ public ResultImpl executeQuery(String revisionId, NodeState root) {
+ return new ResultImpl(this, revisionId, root);
}
- Iterator<ResultRowImpl> getRows(String revisionId) {
+ Iterator<ResultRowImpl> getRows(String revisionId, NodeState root) {
prepare();
Iterator<ResultRowImpl> it;
if (explain) {
@@ -299,7 +300,7 @@ public class Query {
ResultRowImpl r = new ResultRowImpl(this, new String[0], new CoreValue[] { getValueFactory().createValue(plan) }, null);
it = Arrays.asList(r).iterator();
} else {
- it = new RowIterator(revisionId, limit, offset);
+ it = new RowIterator(revisionId, root, limit, offset);
if (orderings != null) {
// TODO "order by" is not necessary if the used index returns
// rows in the same order
@@ -355,12 +356,14 @@ public class Query {
class RowIterator implements Iterator<ResultRowImpl> {
private final String revisionId;
+ private final NodeState root;
private ResultRowImpl current;
private boolean started, end;
private long limit, offset, rowIndex;
- RowIterator(String revisionId, long limit, long offset) {
+ RowIterator(String revisionId, NodeState root, long limit, long offset) {
this.revisionId = revisionId;
+ this.root = root;
this.limit = limit;
this.offset = offset;
}
@@ -374,7 +377,7 @@ public class Query {
return;
}
if (!started) {
- source.execute(revisionId);
+ source.execute(revisionId, root);
started = true;
}
while (true) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java?rev=1371168&r1=1371167&r2=1371168&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java Thu Aug 9 11:35:58 2012
@@ -26,6 +26,7 @@ import org.apache.jackrabbit.oak.api.Con
import org.apache.jackrabbit.oak.api.CoreValue;
import org.apache.jackrabbit.oak.api.CoreValueFactory;
import org.apache.jackrabbit.oak.api.QueryEngine;
+import org.apache.jackrabbit.oak.kernel.KernelNodeState;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.query.index.TraversingIndex;
@@ -109,7 +110,8 @@ public class QueryEngineImpl implements
}
q.setQueryEngine(this);
q.prepare();
- return q.executeQuery(mk.getHeadRevision());
+ String revision = mk.getHeadRevision();
+ return q.executeQuery(revision, new KernelNodeState(mk, "/", revision));
}
public QueryIndex getBestIndex(FilterImpl filter) {
@@ -122,7 +124,7 @@ public class QueryEngineImpl implements
}
}
if (best == null) {
- best = new TraversingIndex(mk);
+ best = new TraversingIndex();
}
return best;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ResultImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ResultImpl.java?rev=1371168&r1=1371167&r2=1371168&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ResultImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ResultImpl.java Thu Aug 9 11:35:58 2012
@@ -22,6 +22,7 @@ import org.apache.jackrabbit.oak.api.Res
import org.apache.jackrabbit.oak.api.ResultRow;
import org.apache.jackrabbit.oak.query.ast.ColumnImpl;
import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
/**
* A query result.
@@ -30,10 +31,12 @@ public class ResultImpl implements Resul
protected final Query query;
protected final String revisionId;
+ protected final NodeState root;
- ResultImpl(Query query, String revisionId) {
+ ResultImpl(Query query, String revisionId, NodeState root) {
this.query = query;
this.revisionId = revisionId;
+ this.root = root;
}
@Override
@@ -62,7 +65,7 @@ public class ResultImpl implements Resul
@Override
public Iterator<ResultRowImpl> iterator() {
- return query.getRows(revisionId);
+ return query.getRows(revisionId, root);
}
};
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java?rev=1371168&r1=1371167&r2=1371168&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java Thu Aug 9 11:35:58 2012
@@ -15,6 +15,7 @@ package org.apache.jackrabbit.oak.query.
import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.oak.query.Query;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
/**
* A join.
@@ -30,6 +31,7 @@ public class JoinImpl extends SourceImpl
private boolean leftNeedNext;
private boolean foundJoinedRow;
private boolean end;
+ private NodeState root;
private String revisionId;
public JoinImpl(SourceImpl left, SourceImpl right, JoinType joinType,
@@ -123,7 +125,8 @@ public class JoinImpl extends SourceImpl
}
@Override
- public void execute(String revisionId) {
+ public void execute(String revisionId, NodeState root) {
+ this.root = root;
this.revisionId = revisionId;
leftNeedExecute = true;
end = false;
@@ -135,7 +138,7 @@ public class JoinImpl extends SourceImpl
return false;
}
if (leftNeedExecute) {
- left.execute(revisionId);
+ left.execute(revisionId, root);
leftNeedExecute = false;
leftNeedNext = true;
}
@@ -149,7 +152,7 @@ public class JoinImpl extends SourceImpl
rightNeedExecute = true;
}
if (rightNeedExecute) {
- right.execute(revisionId);
+ right.execute(revisionId, root);
foundJoinedRow = false;
rightNeedExecute = false;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java?rev=1371168&r1=1371167&r2=1371168&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java Thu Aug 9 11:35:58 2012
@@ -27,6 +27,7 @@ import org.apache.jackrabbit.oak.query.Q
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.Cursor;
import org.apache.jackrabbit.oak.spi.QueryIndex;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
/**
* A selector within a query.
@@ -77,8 +78,8 @@ public class SelectorImpl extends Source
}
@Override
- public void execute(String revisionId) {
- cursor = index.query(createFilter(), revisionId);
+ public void execute(String revisionId, NodeState root) {
+ cursor = index.query(createFilter(), revisionId, root);
}
@Override
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java?rev=1371168&r1=1371167&r2=1371168&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java Thu Aug 9 11:35:58 2012
@@ -20,6 +20,7 @@ package org.apache.jackrabbit.oak.query.
import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.oak.query.Query;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
/**
* The base class of a selector and a join.
@@ -92,8 +93,9 @@ public abstract class SourceImpl extends
* Execute the query. The current node is set to before the first row.
*
* @param revisionId the revision to use
+ * @param root root state of the given revision
*/
- public abstract void execute(String revisionId);
+ public abstract void execute(String revisionId, NodeState root);
/**
* Go to the next node for the given source. This will also filter the
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PropertyContentIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PropertyContentIndex.java?rev=1371168&r1=1371167&r2=1371168&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PropertyContentIndex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PropertyContentIndex.java Thu Aug 9 11:35:58 2012
@@ -24,6 +24,7 @@ import org.apache.jackrabbit.oak.api.Cor
import org.apache.jackrabbit.oak.spi.Cursor;
import org.apache.jackrabbit.oak.spi.Filter;
import org.apache.jackrabbit.oak.spi.QueryIndex;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
/**
* An index that stores the index data in a {@code MicroKernel}.
@@ -59,7 +60,7 @@ public class PropertyContentIndex implem
}
@Override
- public Cursor query(Filter filter, String revisionId) {
+ public Cursor query(Filter filter, String revisionId, NodeState root) {
String propertyName = index.getPropertyName();
Filter.PropertyRestriction restriction = filter.getPropertyRestriction(propertyName);
if (restriction == null) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingCursor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingCursor.java?rev=1371168&r1=1371167&r2=1371168&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingCursor.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingCursor.java Thu Aug 9 11:35:58 2012
@@ -13,43 +13,82 @@
*/
package org.apache.jackrabbit.oak.query.index;
-import org.apache.jackrabbit.mk.api.MicroKernel;
-import org.apache.jackrabbit.mk.simple.NodeImpl;
+import static org.apache.jackrabbit.oak.spi.Filter.PathRestriction.ALL_CHILDREN;
+
+import java.util.Deque;
+import java.util.Iterator;
+
+import javax.jcr.PropertyType;
+
+import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryChildNodeEntry;
+import org.apache.jackrabbit.oak.plugins.memory.StringValue;
import org.apache.jackrabbit.oak.spi.Cursor;
-import java.util.ArrayList;
+import org.apache.jackrabbit.oak.spi.Filter;
+import org.apache.jackrabbit.oak.spi.Filter.PropertyRestriction;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Queues;
/**
* A cursor that reads all nodes in a given subtree.
*/
public class TraversingCursor implements Cursor {
- private final MicroKernel mk;
- private final String revisionId;
- private final int childBlockSize;
+ private final Filter filter;
+
+ private final Deque<Iterator<? extends ChildNodeEntry>> nodes =
+ Queues.newArrayDeque();
+
+ private String parentPath;
- private ArrayList<NodeCursor> nodes = new ArrayList<NodeCursor>();
private String currentPath;
- public TraversingCursor(MicroKernel mk, String revisionId, int childBlockSize, String path) {
- this.mk = mk;
- this.revisionId = revisionId;
- this.childBlockSize = childBlockSize;
- currentPath = path;
- }
+ public TraversingCursor(Filter filter, NodeState root) {
+ this.filter = filter;
- private boolean loadChildren(String path, long offset) {
- String s = mk.getNodes(path, revisionId, 0, offset, childBlockSize, null);
- if (s == null) {
- return false;
+ String path = filter.getPath();
+ parentPath = null;
+ currentPath = "/";
+ NodeState parent = null;
+ NodeState node = root;
+ if (!path.equals("/")) {
+ for (String name : path.substring(1).split("/")) {
+ parentPath = currentPath;
+ currentPath = PathUtils.concat(parentPath, name);
+
+ parent = node;
+ node = parent.getChildNode(name);
+
+ if (node == null) {
+ return; // nothing can match this filter, leave nodes empty
+ }
+ }
+ }
+
+ switch (filter.getPathRestriction()) {
+ case EXACT:
+ case ALL_CHILDREN:
+ nodes.add(Iterators.singletonIterator(
+ new MemoryChildNodeEntry(currentPath, node)));
+ parentPath = "";
+ break;
+ case PARENT:
+ if (parent != null) {
+ nodes.add(Iterators.singletonIterator(
+ new MemoryChildNodeEntry(parentPath, parent)));
+ parentPath = "";
+ }
+ break;
+ case DIRECT_CHILDREN:
+ nodes.add(node.getChildNodeEntries().iterator());
+ parentPath = currentPath;
+ break;
}
- NodeCursor c = new NodeCursor();
- c.node = NodeImpl.parse(s);
- c.node.setPath(path);
- c.pos = offset;
- nodes.add(c);
- String child = c.node.getChildNodeName(0);
- return child != null;
}
@Override
@@ -59,53 +98,104 @@ public class TraversingCursor implements
@Override
public boolean next() {
- if (nodes == null) {
- currentPath = null;
- return false;
- }
- if (nodes.isEmpty()) {
- if (!mk.nodeExists(currentPath, revisionId)) {
- nodes = null;
- currentPath = null;
- return false;
+ while (!nodes.isEmpty()) {
+ Iterator<? extends ChildNodeEntry> iterator = nodes.getLast();
+ if (iterator.hasNext()) {
+ ChildNodeEntry entry = iterator.next();
+ NodeState node = entry.getNodeState();
+
+ String name = entry.getName();
+ currentPath = PathUtils.concat(parentPath, name);
+
+ if (filter.getPathRestriction() == ALL_CHILDREN) {
+ nodes.addLast(node.getChildNodeEntries().iterator());
+ parentPath = currentPath;
+ }
+
+ if (matchesFilter(node, currentPath)) {
+ return true;
+ }
+ } else {
+ nodes.removeLast();
+ parentPath = PathUtils.getParentPath(parentPath);
}
- loadChildren(currentPath, 0);
- return true;
}
- while (!nodes.isEmpty()) {
- // next child node in the deepest level
- NodeCursor c = nodes.get(nodes.size() - 1);
- currentPath = c.node.getPath();
- long pos = c.pos++;
- if (pos >= c.node.getTotalChildNodeCount()) {
- // there are no more child nodes
- nodes.remove(nodes.size() - 1);
+ currentPath = null;
+ return false;
+ }
+
+ private boolean matchesFilter(NodeState node, String path) {
+ for (PropertyRestriction pr : filter.getPropertyRestrictions()) {
+ if ("jcr:path".equals(pr.propertyName)) {
+ if (!matchesValue(new StringValue(path), pr)) {
+ return false;
+ }
} else {
- if (pos > 0 && pos % childBlockSize == 0) {
- // need to load a new block
- nodes.remove(nodes.size() - 1);
- if (loadChildren(currentPath, pos)) {
- c = nodes.get(nodes.size() - 1);
- c.pos++;
+ PropertyState property = getProperty(node, pr.propertyName);
+ if (property == null) {
+ return false;
+ } else if (pr.first != null || pr.last != null) {
+ boolean matches = false;
+ for (CoreValue value : property.getValues()) {
+ if (matchesValue(value, pr)) {
+ matches = true;
+ }
+ }
+ if (!matches) {
+ return false;
}
}
- String childName = c.node.getChildNodeName(pos % childBlockSize);
- currentPath = PathUtils.concat(currentPath, childName);
- loadChildren(currentPath, 0);
- return true;
}
}
- nodes = null;
- currentPath = null;
- return false;
+ return true;
+ }
+
+ private PropertyState getProperty(NodeState node, String path) {
+ int slash = path.indexOf('/');
+ while (slash != -1) {
+ node = node.getChildNode(path.substring(0, slash));
+ if (node == null) {
+ return null;
+ }
+ path = path.substring(slash + 1);
+ slash = path.indexOf('/');
+ }
+ return node.getProperty(path);
}
- /**
- * A pointer to a child node within a node.
- */
- static class NodeCursor {
- NodeImpl node;
- long pos;
+ private boolean matchesValue(CoreValue value, PropertyRestriction pr) {
+ int first = -1;
+ if (pr.first != null) {
+ first = compareValues(pr.first, value, pr.first.getType());
+ }
+ if (first > 0 || (first == 0 && !pr.firstIncluding)) {
+ return false;
+ }
+
+ int last = -1;
+ if (pr.last != null) {
+ last = compareValues(value, pr.last, pr.last.getType());
+ }
+ if (last > 0 || (last == 0 && !pr.lastIncluding)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private int compareValues(CoreValue a, CoreValue b, int type) {
+ if (type == PropertyType.BOOLEAN) {
+ return Boolean.valueOf(a.getBoolean()).compareTo(
+ Boolean.valueOf(b.getBoolean()));
+ } else if (type == PropertyType.DECIMAL) {
+ return a.getDecimal().compareTo(b.getDecimal());
+ } else if (type == PropertyType.DOUBLE) {
+ return Double.compare(a.getDouble(), b.getDouble());
+ } else if (type == PropertyType.LONG) {
+ return Long.signum(a.getLong() - b.getLong());
+ } else {
+ return a.getString().compareTo(b.getString());
+ }
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java?rev=1371168&r1=1371167&r2=1371168&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java Thu Aug 9 11:35:58 2012
@@ -18,31 +18,20 @@
*/
package org.apache.jackrabbit.oak.query.index;
-import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.spi.Cursor;
import org.apache.jackrabbit.oak.spi.Filter;
import org.apache.jackrabbit.oak.spi.QueryIndex;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
/**
* An index that traverses over a given subtree.
*/
public class TraversingIndex implements QueryIndex {
- private final MicroKernel mk;
- private int childBlockSize = 2000;
-
- public TraversingIndex(MicroKernel mk) {
- this.mk = mk;
- }
-
- public void setChildBlockSize(int childBlockSize) {
- this.childBlockSize = childBlockSize;
- }
-
@Override
- public Cursor query(Filter filter, String revisionId) {
- return new TraversingCursor(mk, revisionId, childBlockSize, filter.getPath());
+ public Cursor query(Filter filter, String revisionId, NodeState root) {
+ return new TraversingCursor(filter, root);
}
@Override
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/QueryIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/QueryIndex.java?rev=1371168&r1=1371167&r2=1371168&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/QueryIndex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/QueryIndex.java Thu Aug 9 11:35:58 2012
@@ -18,6 +18,8 @@
*/
package org.apache.jackrabbit.oak.spi;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
/**
* Represents an index. The index should use the data in the filter if possible
* to speed up reading.
@@ -39,9 +41,10 @@ public interface QueryIndex {
*
* @param filter the filter
* @param revisionId the revision
+ * @param root root state of the given revision
* @return a cursor to iterate over the result
*/
- Cursor query(Filter filter, String revisionId);
+ Cursor query(Filter filter, String revisionId, NodeState root);
/**
* Get the query plan for the given filter.
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/lucene/LuceneEditorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/lucene/LuceneEditorTest.java?rev=1371168&r1=1371167&r2=1371168&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/lucene/LuceneEditorTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/lucene/LuceneEditorTest.java Thu Aug 9 11:35:58 2012
@@ -59,7 +59,7 @@ public class LuceneEditorTest {
"foo",
Operator.EQUAL,
MemoryValueFactory.INSTANCE.createValue("bar"));
- Cursor cursor = index.query(filter, null);
+ Cursor cursor = index.query(filter, null, store.getRoot());
assertTrue(cursor.next());
assertEquals("/", cursor.currentPath());
assertFalse(cursor.next());
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/TraversingCursorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/TraversingCursorTest.java?rev=1371168&r1=1371167&r2=1371168&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/TraversingCursorTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/index/TraversingCursorTest.java Thu Aug 9 11:35:58 2012
@@ -26,6 +26,7 @@ import java.util.Collections;
import java.util.List;
import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.mk.core.MicroKernelImpl;
+import org.apache.jackrabbit.oak.kernel.KernelNodeState;
import org.apache.jackrabbit.oak.spi.Cursor;
import org.junit.Test;
@@ -34,22 +35,11 @@ import org.junit.Test;
*/
public class TraversingCursorTest {
- private final MicroKernel mk = new MicroKernelImpl();
-
@Test
public void traverse() throws Exception {
- TraversingIndex t = new TraversingIndex(mk);
- traverse(t);
- }
-
- @Test
- public void traverseBlockwise() throws Exception {
- TraversingIndex t = new TraversingIndex(mk);
- t.setChildBlockSize(2);
- traverse(t);
- }
+ TraversingIndex t = new TraversingIndex();
- private void traverse(TraversingIndex t) {
+ MicroKernel mk = new MicroKernelImpl();
String head = mk.getHeadRevision();
head = mk.commit("/", "+ \"parents\": { \"p0\": {\"id\": \"0\"}, \"p1\": {\"id\": \"1\"}, \"p2\": {\"id\": \"2\"}}", head, "");
head = mk.commit("/", "+ \"children\": { \"c1\": {\"p\": \"1\"}, \"c2\": {\"p\": \"1\"}, \"c3\": {\"p\": \"2\"}, \"c4\": {\"p\": \"3\"}}", head, "");
@@ -57,7 +47,7 @@ public class TraversingCursorTest {
f.setPath("/");
List<String> paths = new ArrayList<String>();
- Cursor c = t.query(f, head);
+ Cursor c = t.query(f, head, new KernelNodeState(mk, "/", head));
while (c.next()) {
paths.add(c.currentPath());
}
@@ -72,7 +62,7 @@ public class TraversingCursorTest {
assertFalse(c.next());
f.setPath("/nowhere");
- c = t.query(f, head);
+ c = t.query(f, head, new KernelNodeState(mk, "/", head));
assertFalse(c.next());
// endure it stays false
assertFalse(c.next());