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"