From commits-return-13093-apmail-jackrabbit-commits-archive=jackrabbit.apache.org@jackrabbit.apache.org Thu Mar 1 14:48:06 2012 Return-Path: X-Original-To: apmail-jackrabbit-commits-archive@www.apache.org Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id A10FD918D for ; Thu, 1 Mar 2012 14:48:06 +0000 (UTC) Received: (qmail 20499 invoked by uid 500); 1 Mar 2012 14:48:06 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 20412 invoked by uid 500); 1 Mar 2012 14:48:06 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 20403 invoked by uid 99); 1 Mar 2012 14:48:06 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 01 Mar 2012 14:48:06 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 01 Mar 2012 14:48:04 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 6D296238889B; Thu, 1 Mar 2012 14:47:44 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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/ Date: Thu, 01 Mar 2012 14:47:44 -0000 To: commits@jackrabbit.apache.org From: thomasm@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120301144744.6D296238889B@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 nodes = new ArrayList(); + 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"