jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From alexparvule...@apache.org
Subject svn commit: r1423962 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/plugins/index/p2/strategy/ test/java/org/apache/jackrabbit/oak/plugins/index/p2/strategy/
Date Wed, 19 Dec 2012 17:15:11 GMT
Author: alexparvulescu
Date: Wed Dec 19 17:15:11 2012
New Revision: 1423962

URL: http://svn.apache.org/viewvc?rev=1423962&view=rev
Log:
OAK-520 IllegalStateException in MemoryNodeBuilder

Added:
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/strategy/
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/strategy/ContentMirrorStoreStrategyTest.java
  (with props)
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/strategy/ContentMirrorStoreStrategy.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/strategy/ContentMirrorStoreStrategy.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/strategy/ContentMirrorStoreStrategy.java?rev=1423962&r1=1423961&r2=1423962&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/strategy/ContentMirrorStoreStrategy.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/strategy/ContentMirrorStoreStrategy.java
Wed Dec 19 17:15:11 2012
@@ -16,11 +16,12 @@
  */
 package org.apache.jackrabbit.oak.plugins.index.p2.strategy;
 
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Queue;
+import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
@@ -38,46 +39,66 @@ public class ContentMirrorStoreStrategy 
             return;
         }
         NodeBuilder child = index.child(key);
-        Queue<NodeBuilder> parentQueue = new LinkedList<NodeBuilder>();
+        Map<String, NodeBuilder> parents = new TreeMap<String, NodeBuilder>(Collections.reverseOrder());
+
         for (String rm : values) {
             if (PathUtils.denotesRoot(rm)) {
                 child.removeProperty("match");
             } else {
-                NodeBuilder indexEntry = child;
-                Iterator<String> segments = PathUtils.elements(rm).iterator();
-                while (segments.hasNext()) {
-                    String segment = segments.next();
-                    if (segments.hasNext()) {
-                        parentQueue.add(indexEntry);
+                String parentPath = PathUtils.getParentPath(rm);
+                String name = PathUtils.getName(rm);
+                NodeBuilder indexEntry = parents.get(parentPath);
+                if (indexEntry == null) {
+                    indexEntry = child;
+                    String segmentPath = "";
+                    Iterator<String> segments = PathUtils.elements(parentPath)
+                            .iterator();
+                    while (segments.hasNext()) {
+                        String segment = segments.next();
+                        segmentPath = PathUtils.concat(segmentPath, segment);
                         indexEntry = indexEntry.child(segment);
-                    } else {
-                        // last segment
-                        if (indexEntry.hasChildNode(segment)) {
-                            indexEntry.removeNode(segment);
-                        }
+                        parents.put(segmentPath, indexEntry);
+                    }
+                }
+                if (indexEntry.hasChildNode(name)) {
+                    NodeBuilder childEntry = indexEntry.child(name);
+                    childEntry.removeProperty("match");
+                    if (childEntry.getChildNodeCount() == 0) {
+                        indexEntry.removeNode(name);
                     }
                 }
             }
         }
         // prune the index: remove all children that have no children
         // and no "match" property progressing bottom up
-        // see OAK-520
-        // while (!parentQueue.isEmpty()) {
-        // NodeBuilder node = parentQueue.poll();
-        // for (String name : node.getChildNodeNames()) {
-        // NodeBuilder segment = node.child(name);
-        // if (segment.getChildNodeCount() == 0
-        // && segment.getProperty("match") == null) {
-        // segment.removeNode(name);
-        // }
-        // }
-        // }
-        // finally remove the index node if empty
-        if (child.getChildNodeCount() == 0) {
+        Iterator<String> it = parents.keySet().iterator();
+        while (it.hasNext()) {
+            String path = it.next();
+            NodeBuilder parent = parents.get(path);
+            pruneNode(parent);
+        }
+
+        // finally prune the index node
+        pruneNode(child);
+        if (child.getChildNodeCount() == 0
+                && child.getProperty("match") == null) {
             index.removeNode(key);
         }
     }
 
+    private void pruneNode(NodeBuilder parent) {
+        if (parent.isRemoved()) {
+            return;
+        }
+        for (String name : parent.getChildNodeNames()) {
+            NodeBuilder segment = parent.child(name);
+            if (segment.getChildNodeCount() == 0
+                    && segment.getProperty("match") == null) {
+                parent.removeNode(name);
+            }
+        }
+    }
+
     @Override
     public void insert(NodeBuilder index, String key, boolean unique,
             Iterable<String> values) throws CommitFailedException {
@@ -85,9 +106,7 @@ public class ContentMirrorStoreStrategy 
 
         for (String add : values) {
             NodeBuilder indexEntry = child;
-            Iterator<String> segments = PathUtils.elements(add).iterator();
-            while (segments.hasNext()) {
-                String segment = segments.next();
+            for(String segment: PathUtils.elements(add)){
                 indexEntry = indexEntry.child(segment);
             }
             indexEntry.setProperty("match", true);

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/strategy/ContentMirrorStoreStrategyTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/strategy/ContentMirrorStoreStrategyTest.java?rev=1423962&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/strategy/ContentMirrorStoreStrategyTest.java
(added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/strategy/ContentMirrorStoreStrategyTest.java
Wed Dec 19 17:15:11 2012
@@ -0,0 +1,113 @@
+/*
+ * 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.oak.plugins.index.p2.strategy;
+
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.common.collect.Sets;
+
+public class ContentMirrorStoreStrategyTest {
+
+    /**
+     * <p>
+     * Tests the index pruning mechanism
+     * </p>
+     * <ul>
+     * <li>
+     * adds a few levels of nodes, nodes with an even index will have the
+     * 'match' property set</li>
+     * 
+     * <li>
+     * pruning in this case means that whatever path that doesn't have a 'match'
+     * property is considered dead weight and should be removed from the index</li>
+     * </ul>
+     */
+    @Test
+    public void testIndexPruning() throws Exception {
+        IndexStoreStrategy store = new ContentMirrorStoreStrategy();
+
+        NodeState root = MemoryNodeState.EMPTY_NODE;
+        NodeBuilder index = root.builder();
+
+        store.insert(index, "key", false,
+                Sets.newHashSet("/", "a/b/c", "a/b/d", "b", "d/e", "d/e/f"));
+        checkPath(index, "key", "", true);
+        checkPath(index, "key", "a/b/c", true);
+        checkPath(index, "key", "a/b/d", true);
+        checkPath(index, "key", "b", true);
+        checkPath(index, "key", "d/e", true);
+        checkPath(index, "key", "d/e/f", true);
+
+        // remove the root key, removes just the "match" property, when the
+        // index is not empty
+        store.remove(index, "key", Sets.newHashSet("/"));
+        checkPath(index, "key", "d/e/f", true);
+
+        // removing intermediary path doesn't remove the entire subtree
+        store.remove(index, "key", Sets.newHashSet("d/e"));
+        checkPath(index, "key", "d/e/f", true);
+
+        // removing intermediary path doesn't remove the entire subtree
+        store.remove(index, "key", Sets.newHashSet("d/e/f"));
+        checkNotPath(index, "key", "d");
+
+        // brother segment removed
+        store.remove(index, "key", Sets.newHashSet("a/b/d", "a/b"));
+        checkPath(index, "key", "a/b/c", true);
+
+        // reinsert root and remove everything else
+        store.insert(index, "key", false, Sets.newHashSet("/"));
+        store.remove(index, "key", Sets.newHashSet("d/e/f", "b", "a/b/c"));
+
+        // remove the root key when the index is empty
+        store.remove(index, "key", Sets.newHashSet("/"));
+        Assert.assertEquals(0, index.getChildNodeCount());
+    }
+
+    private void checkPath(NodeBuilder node, String key, String path,
+            boolean checkMatch) {
+        path = PathUtils.concat(key, path);
+        NodeBuilder check = node;
+        for (String p : PathUtils.elements(path)) {
+            Assert.assertTrue("Missing child node " + p + " on path " + path,
+                    check.hasChildNode(p));
+            check = check.child(p);
+        }
+        if (checkMatch) {
+            Assert.assertNotNull(check.getProperty("match"));
+        }
+    }
+
+    private void checkNotPath(NodeBuilder node, String key, String path) {
+        path = PathUtils.concat(key, path);
+        String parentPath = PathUtils.getParentPath(path);
+        String name = PathUtils.getName(path);
+        NodeBuilder check = node;
+        for (String p : PathUtils.elements(parentPath)) {
+            Assert.assertTrue("Missing child node " + p + " on path " + path,
+                    check.hasChildNode(p));
+            check = check.child(p);
+        }
+        Assert.assertFalse(check.hasChildNode(name));
+    }
+
+}

Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/strategy/ContentMirrorStoreStrategyTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/strategy/ContentMirrorStoreStrategyTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL



Mime
View raw message