You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by th...@apache.org on 2012/03/01 15:47:44 UTC
svn commit: r1295598 - in /jackrabbit/sandbox/jackrabbit-microkernel/src:
main/java/org/apache/jackrabbit/query/qom/tree/
main/java/org/apache/jackrabbit/query/reader/
test/java/org/apache/jackrabbit/query/reader/ test/resources/
Author: thomasm
Date: Thu Mar 1 14:47:43 2012
New Revision: 1295598
URL: http://svn.apache.org/viewvc?rev=1295598&view=rev
Log:
Query implementation (WIP)
Added:
jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/reader/
jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/reader/TraversingCursorTest.java
Modified:
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/EquiJoinConditionImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/TraversingCursor.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/TraversingReader.java
jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/EquiJoinConditionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/EquiJoinConditionImpl.java?rev=1295598&r1=1295597&r2=1295598&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/EquiJoinConditionImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/EquiJoinConditionImpl.java Thu Mar 1 14:47:43 2012
@@ -64,7 +64,7 @@ public class EquiJoinConditionImpl exten
public String toString() {
// TODO quote property names?
- return getSelector1Name() + '.' + getProperty2Name()
+ return getSelector1Name() + '.' + getProperty1Name()
+ " = " + getSelector2Name() + '.' + getProperty2Name();
}
@@ -88,7 +88,7 @@ public class EquiJoinConditionImpl exten
}
// TODO data type mapping
NodeImpl n2 = selector2.currentNode();
- String v2 = n2.getProperty(property1Name);
+ String v2 = n2.getProperty(property2Name);
if (v2 == null) {
return false;
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/TraversingCursor.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/TraversingCursor.java?rev=1295598&r1=1295597&r2=1295598&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/TraversingCursor.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/TraversingCursor.java Thu Mar 1 14:47:43 2012
@@ -23,73 +23,88 @@ import org.apache.jackrabbit.mk.util.Pat
*/
public class TraversingCursor implements Cursor {
- private static final int CHILD_COUNT = 2000;
+ private final MicroKernel mk;
+ private final String revisionId;
+ private final int childBlockSize;
- private MicroKernel mk;
- private String revisionId;
private ArrayList<NodeCursor> nodes = new ArrayList<NodeCursor>();
+ private String currentPath;
private NodeImpl currentNode;
- private String currentNodeName;
- public TraversingCursor(MicroKernel mk, String revisionId, String path) {
+ public TraversingCursor(MicroKernel mk, String revisionId, int childBlockSize, String path) {
this.mk = mk;
this.revisionId = revisionId;
- loadDepth(path, 0);
+ this.childBlockSize = childBlockSize;
+ this.currentPath = path;
}
- private void loadDepth(String path, long offset) {
- while (true) {
- String s = mk.getNodes(path, revisionId, 0, offset, CHILD_COUNT);
- NodeCursor c = new NodeCursor();
- c.node = NodeImpl.parse(s);
- c.node.setPath(path);
- nodes.add(c);
- String child = c.node.getChildNodeName(0);
- if (child != null) {
- path = PathUtils.concat(path, child);
- } else {
- break;
- }
- }
+ private boolean loadChildren(String path, long offset) {
+ String s = mk.getNodes(path, revisionId, 0, offset, childBlockSize);
+ 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
public NodeImpl currentNode() {
if (currentNode == null) {
- currentNode = NodeImpl.parse(mk.getNodes(currentPath(), revisionId));
+ currentNode = NodeImpl.parse(mk.getNodes(currentPath, revisionId));
}
return currentNode;
}
@Override
public String currentPath() {
- NodeCursor c = nodes.get(nodes.size() - 1);
- return PathUtils.concat(c.node.getPath(), currentNodeName);
+ return currentPath;
}
@Override
public boolean next() {
currentNode = null;
- while (true) {
- if (nodes.size() == 0) {
+ if (nodes == null) {
+ return false;
+ }
+ if (nodes.size() == 0) {
+ if (!mk.nodeExists(currentPath, revisionId)) {
+ nodes = null;
return false;
}
+ loadChildren(currentPath, 0);
+ return true;
+ }
+ while (nodes.size() > 0) {
+ // next child node in the deepest level
NodeCursor c = nodes.get(nodes.size() - 1);
- long pos = c.pos++ % CHILD_COUNT;
- currentNodeName = c.node.getChildNodeName(pos);
- if (currentNodeName != null) {
+ currentPath = c.node.getPath();
+ long pos = c.pos++;
+ if (pos >= c.node.getTotalChildNodeCount()) {
+ // there are no more child nodes
+ nodes.remove(nodes.size() - 1);
+ } 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++;
+ }
+ }
+ String childName = c.node.getChildNodeName(pos % childBlockSize);
+ currentPath = PathUtils.concat(currentPath, childName);
+ loadChildren(currentPath, 0);
return true;
- }
- nodes.remove(nodes.size() - 1);
- if (c.pos <= c.node.getTotalChildNodeCount()) {
- loadDepth(c.node.getPath(), c.pos);
- }
+ }
}
+ nodes = null;
+ return false;
}
static class NodeCursor {
NodeImpl node;
- long offset;
long pos;
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/TraversingReader.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/TraversingReader.java?rev=1295598&r1=1295597&r2=1295598&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/TraversingReader.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/TraversingReader.java Thu Mar 1 14:47:43 2012
@@ -24,14 +24,19 @@ import org.apache.jackrabbit.mk.util.Pat
public class TraversingReader implements NodeReader {
private final MicroKernel mk;
+ private int childBlockSize = 2000;
public TraversingReader(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, filter.getPath());
+ return new TraversingCursor(mk, revisionId, childBlockSize, filter.getPath());
}
@Override
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/reader/TraversingCursorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/reader/TraversingCursorTest.java?rev=1295598&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/reader/TraversingCursorTest.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/reader/TraversingCursorTest.java Thu Mar 1 14:47:43 2012
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * \"License\"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.query.reader;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import org.apache.jackrabbit.mk.MicroKernelFactory;
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests the TraversingCursor.
+ */
+public class TraversingCursorTest {
+
+ MicroKernel mk;
+ String head;
+
+ @Before
+ public void setUp() {
+ mk = MicroKernelFactory.getInstance("simple:/target/temp;clear");
+ head = mk.getHeadRevision();
+ }
+
+ @After
+ public void tearDown() {
+ mk.dispose();
+ }
+
+ @Test
+ public void traverse() throws Exception {
+ TraversingReader r = new TraversingReader(mk);
+ traverse(r);
+ }
+
+ @Test
+ public void traverseBlockwise() throws Exception {
+ TraversingReader r = new TraversingReader(mk);
+ r.setChildBlockSize(2);
+ traverse(r);
+ }
+
+ private void traverse(TraversingReader r) {
+ 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, "");
+ Filter f = new Filter();
+ Cursor c;
+ f.setPath("/");
+ c = r.query(f, head);
+ String[] list = {"/", "/parents", "/parents/p0", "/parents/p1", "/parents/p2",
+ "/children", "/children/c1", "/children/c2", "/children/c3", "/children/c4"};
+ for (String s : list) {
+ assertTrue(c.next());
+ assertEquals(s, c.currentPath());
+ }
+ assertFalse(c.next());
+ assertFalse(c.next());
+ f.setPath("/nowhere");
+ c = r.query(f, head);
+ assertFalse(c.next());
+ assertFalse(c.next());
+ }
+
+}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt?rev=1295598&r1=1295597&r2=1295598&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt Thu Mar 1 14:47:43 2012
@@ -8,8 +8,8 @@
+ "parents": { "p0": {"id": "0"}, "p1": {"id": "1"}, "p2": {"id": "2"}}
+ "children": { "c1": {"p": "1"}, "c2": {"p": "1"}, "c3": {"p": "2"}, "c4": {"p": "3"}}
-select * from [nt:base] as p inner join [nt:base] as c on p.id = c.id
-/parents/p0
+select * from [nt:base] as p inner join [nt:base] as c on p.id = c.p
+/parents/p1
/parents/p1
/parents/p2
@@ -20,9 +20,10 @@ select * from [nt:base] as p inner join
+ "test2": { "id":"1", "x": "2" }
select * from [nt:base]
+/
+/test
/test/hello
/test/world
-/test
/test2
select * from [nt:base] where id = '1'
@@ -36,10 +37,12 @@ select * from [nt:base] where id = '1' o
/test2
select * from [nt:base] where not (id = '1' or x = '2')
-/test/hello
+/
/test
+/test/hello
select * from [nt:base] where x is null
+/
/test
- "test"