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 2011/09/20 12:38:58 UTC

svn commit: r1173074 - in /jackrabbit/sandbox/microkernel/src: main/java/org/apache/jackrabbit/mk/index/ test/java/org/apache/jackrabbit/mk/index/

Author: thomasm
Date: Tue Sep 20 10:38:57 2011
New Revision: 1173074

URL: http://svn.apache.org/viewvc?rev=1173074&view=rev
Log:
Indexing: automatically reopen existing indexes, and allow to add indexes after content has been added.

Modified:
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/BTree.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/Index.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/Indexer.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/PrefixIndex.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/PropertyIndex.java
    jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/index/IndexTest.java

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/BTree.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/BTree.java?rev=1173074&r1=1173073&r2=1173074&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/BTree.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/BTree.java Tue Sep 20 10:38:57 2011
@@ -37,7 +37,6 @@ public class BTree {
         this.indexer = indexer;
         this.name = name;
         this.unique = unique;
-
         if (!indexer.nodeExists(name)) {
             JsopBuilder jsop = new JsopBuilder();
             jsop.appendTag("+ ").key(name).encodedValue("{}");

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/Index.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/Index.java?rev=1173074&r1=1173073&r2=1173074&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/Index.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/Index.java Tue Sep 20 10:38:57 2011
@@ -26,6 +26,13 @@ import org.apache.jackrabbit.mk.mem.Node
 public interface Index {
 
     /**
+     * Get the unique index name. This is also the name of the index node.
+     *
+     * @return the index name
+     */
+    String getName();
+
+    /**
      * The given node was added or removed.
      *
      * @param node the node including (old or new) data

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/Indexer.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/Indexer.java?rev=1173074&r1=1173073&r2=1173074&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/Indexer.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/Indexer.java Tue Sep 20 10:38:57 2011
@@ -39,7 +39,7 @@ public class Indexer {
     private String revision;
     private String indexRootNode;
     private StringBuilder buffer;
-    private ArrayList<Index> indexes = new ArrayList<Index>();
+    private HashMap<String, Index> indexes = new HashMap<String, Index>();
     private String readRevision;
 
     public Indexer(MicroKernel mk, String indexRootNode) {
@@ -55,7 +55,7 @@ public class Indexer {
             jsop.appendTag("+ ").key(PathUtils.relativize("/", indexRootNode)).encodedValue("{}");
             revision = mk.commit("/", jsop.toString(), revision, null);
         } else {
-            String node = mk.getNodes(indexRootNode, revision, 0, 0, 0);
+            String node = mk.getNodes(indexRootNode, revision, 0, 0, Integer.MAX_VALUE);
             JsopTokenizer t = new JsopTokenizer(node);
             t.read('{');
             HashMap<String, String> map = new HashMap<String, String>();
@@ -70,6 +70,15 @@ public class Indexer {
             if (rev != null) {
                 readRevision = rev;
             }
+            for (String k : map.keySet()) {
+                Index p = PropertyIndex.fromNodeName(this, k);
+                if (p == null) {
+                    p = PrefixIndex.fromNodeName(this, k);
+                }
+                if (p != null) {
+                    indexes.put(p.getName(), p);
+                }
+            }
         }
     }
 
@@ -79,13 +88,21 @@ public class Indexer {
 
     public PropertyIndex createPropertyIndex(String property, boolean unique) {
         PropertyIndex index = new PropertyIndex(this, property, unique);
-        indexes.add(index);
+        PropertyIndex existing = (PropertyIndex) indexes.get(index.getName());
+        if (existing != null) {
+            return existing;
+        }
+        buildAndAddIndex(index);
         return index;
     }
 
     public PrefixIndex createPrefixIndex(String prefix) {
         PrefixIndex index = new PrefixIndex(this, prefix);
-        indexes.add(index);
+        PrefixIndex existing = (PrefixIndex) indexes.get(index.getName());
+        if (existing != null) {
+            return existing;
+        }
+        buildAndAddIndex(index);
         return index;
     }
 
@@ -320,7 +337,7 @@ public class Indexer {
             // don't index the index
             return;
         }
-        for (Index index : indexes) {
+        for (Index index : indexes.values()) {
             if (remove) {
                 index.addOrRemoveNode(n, false);
             }
@@ -334,7 +351,7 @@ public class Indexer {
     }
 
     private boolean isInIndex(String path) {
-        return path.startsWith(indexRootNode);
+        return PathUtils.isParent(indexRootNode, path) || indexRootNode.equals(path);
     }
 
     private void removeProperty(String path, String lastRevision) {
@@ -354,7 +371,7 @@ public class Indexer {
         NodeImpl n = NodeImpl.parse(map, t, 0, path);
         if (n.hasProperty(property)) {
             n.setPath(nodePath);
-            for (Index index : indexes) {
+            for (Index index : indexes.values()) {
                 index.addOrRemoveProperty(nodePath, property, n.getProperty(property), false);
             }
         }
@@ -367,7 +384,7 @@ public class Indexer {
         }
         String nodePath = PathUtils.getParentPath(path);
         String property = PathUtils.getName(path);
-        for (Index index : indexes) {
+        for (Index index : indexes.values()) {
             index.addOrRemoveProperty(nodePath, property, value, true);
         }
     }
@@ -389,4 +406,24 @@ public class Indexer {
         addOrRemoveRecursive(n, true, false);
     }
 
+    private void buildAndAddIndex(Index index) {
+        addRecursive(index, "/");
+        indexes.put(index.getName(), index);
+    }
+
+    private void addRecursive(Index index, String path) {
+        if (isInIndex(path)) {
+            return;
+        }
+        String node = mk.getNodes(path, readRevision, 0, 0, Integer.MAX_VALUE);
+        JsopTokenizer t = new JsopTokenizer(node);
+        NodeMap map = new NodeMap();
+        t.read('{');
+        NodeImpl n = NodeImpl.parse(map, t, 0, path);
+        index.addOrRemoveNode(n, true);
+        for (Iterator<String> it = n.getChildNodeNames(Integer.MAX_VALUE); it.hasNext();) {
+            addRecursive(index, PathUtils.concat(path, it.next()));
+        }
+    }
+
 }

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/PrefixIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/PrefixIndex.java?rev=1173074&r1=1173073&r2=1173074&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/PrefixIndex.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/PrefixIndex.java Tue Sep 20 10:38:57 2011
@@ -36,6 +36,18 @@ public class PrefixIndex implements Inde
         tree.setMinSize(10);
     }
 
+    public static PrefixIndex fromNodeName(Indexer indexer, String nodeName) {
+        if (!nodeName.startsWith("prefix:")) {
+            return null;
+        }
+        String prefix = nodeName.substring("prefix:".length());
+        return new PrefixIndex(indexer, prefix);
+    }
+
+    public String getName() {
+        return tree.getName();
+    }
+
     public void addOrRemoveNode(NodeImpl node, boolean add) {
         String nodePath = node.getPath();
         for (int i = 0, size = node.getPropertyCount(); i < size; i++) {

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/PropertyIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/PropertyIndex.java?rev=1173074&r1=1173073&r2=1173074&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/PropertyIndex.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/index/PropertyIndex.java Tue Sep 20 10:38:57 2011
@@ -34,10 +34,30 @@ public class PropertyIndex implements In
     public PropertyIndex(Indexer indexer, String propertyName, boolean unique) {
         this.indexer = indexer;
         this.propertyName = propertyName;
-        this.tree = new BTree(indexer, "property:" + propertyName, unique);
+        this.tree = new BTree(indexer, "property:" + propertyName + ";" + (unique ? "unique" : "nonUnique"), unique);
         tree.setMinSize(10);
     }
 
+    public static PropertyIndex fromNodeName(Indexer indexer, String nodeName) {
+        if (!nodeName.startsWith("property:")) {
+            return null;
+        }
+        int index = nodeName.lastIndexOf(';');
+        boolean unique;
+        if (index < 0) {
+            unique = true;
+        } else {
+            unique = nodeName.substring(index + 1).equals("unique");
+            nodeName = nodeName.substring(0, index);
+        }
+        String propertyName = nodeName.substring("property:".length());
+        return new PropertyIndex(indexer, propertyName, unique);
+    }
+
+    public String getName() {
+        return tree.getName();
+    }
+
     public void addOrRemoveNode(NodeImpl node, boolean add) {
         String value = node.getProperty(propertyName);
         if (value != null) {

Modified: jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/index/IndexTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/index/IndexTest.java?rev=1173074&r1=1173073&r2=1173074&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/index/IndexTest.java (original)
+++ jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/index/IndexTest.java Tue Sep 20 10:38:57 2011
@@ -35,6 +35,7 @@ public class IndexTest extends TestCase 
     private static final String URL = "mem:;clean";
 
     public void test() {
+        testCreateIndexAfterAddingData(URL);
         testNonUnique(URL);
         testAscending(URL);
         testRandom(URL);
@@ -43,6 +44,23 @@ public class IndexTest extends TestCase 
         testNestedAddNode(URL);
     }
 
+    private void testCreateIndexAfterAddingData(String url) {
+        MicroKernel mk = MicroKernelFactory.getInstance(url);
+        Indexer indexer = new Indexer(mk);
+        PropertyIndex indexOld = indexer.createPropertyIndex("x", false);
+        mk.commit("/", "+ \"test\": { \"test2\": { \"id\": 1 }, \"id\": 1 }", mk.getHeadRevision(), "");
+        mk.commit("/", "+ \"test3\": { \"test2\": { \"id\": 2 }, \"id\": 2 }", mk.getHeadRevision(), "");
+        indexOld.getPath("x", mk.getHeadRevision());
+        PropertyIndex index = indexer.createPropertyIndex("id", false);
+        Iterator<String> it = index.getPaths("1", mk.getHeadRevision());
+        assertTrue(it.hasNext());
+        assertEquals("/test", it.next());
+        assertTrue(it.hasNext());
+        assertEquals("/test/test2", it.next());
+        assertFalse(it.hasNext());
+        mk.dispose();
+    }
+
     private void testNonUnique(String url) {
         MicroKernel mk = MicroKernelFactory.getInstance(url);
         Indexer indexer = new Indexer(mk);