You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by th...@apache.org on 2013/03/01 17:29:04 UTC

svn commit: r1451636 - in /jackrabbit/oak/trunk/oak-mongomk/src: main/java/org/apache/jackrabbit/mongomk/prototype/ test/java/org/apache/jackrabbit/mongomk/prototype/

Author: thomasm
Date: Fri Mar  1 16:29:03 2013
New Revision: 1451636

URL: http://svn.apache.org/r1451636
Log:
OAK-619 Lock-free MongoMK implementation (bugfixes)

Modified:
    jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Commit.java
    jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MongoDocumentStore.java
    jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MongoMK.java
    jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Node.java
    jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Utils.java
    jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/SimpleTest.java

Modified: jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Commit.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Commit.java?rev=1451636&r1=1451635&r2=1451636&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Commit.java (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Commit.java Fri Mar  1 16:29:03 2013
@@ -69,7 +69,7 @@ public class Commit {
     private UpdateOp getUpdateOperationForNode(String path) {
         UpdateOp op = operations.get(path);
         if (op == null) {
-            String id = Node.convertPathToDocumentId(path);
+            String id = Utils.getIdFromPath(path);
             op = new UpdateOp(path, id, false);
             operations.put(path, op);
         }
@@ -90,7 +90,8 @@ public class Commit {
     
     void updateProperty(String path, String propertyName, String value) {
         UpdateOp op = getUpdateOperationForNode(path);
-        op.addMapEntry(propertyName + "." + revision.toString(), value);
+        String key = Utils.escapePropertyName(propertyName);
+        op.addMapEntry(key + "." + revision.toString(), value);
         long increment = mk.getWriteCountIncrement(path);
         op.increment(UpdateOp.WRITE_COUNT, 1 + increment);
     }
@@ -208,7 +209,7 @@ public class Commit {
     
     private UpdateOp[] splitDocument(Map<String, Object> map) {
         String id = (String) map.get(UpdateOp.ID);
-        String path = id.substring(1);
+        String path = Utils.getPathFromId(id);
         Long previous = (Long) map.get(UpdateOp.PREVIOUS);
         if (previous == null) {
             previous = 0L;
@@ -299,7 +300,7 @@ public class Commit {
                     writeCountInc = 0;
                 } else {
                     writeCountInc++;
-                    String id = Node.convertPathToDocumentId(path);
+                    String id = Utils.getIdFromPath(path);
                     Map<String, Object> map = mk.getDocumentStore().find(Collection.NODES, id);
                     Long oldWriteCount = (Long) map.get(UpdateOp.WRITE_COUNT);
                     writeCount = oldWriteCount == null ? 0 : oldWriteCount;
@@ -321,6 +322,9 @@ public class Commit {
     }
 
     private void markChanged(String path) {
+        if (!PathUtils.denotesRoot(path) && !PathUtils.isAbsolute(path)) {
+            throw new IllegalArgumentException("path: " + path);
+        }
         while (true) {
             changedNodes.add(path);
             if (PathUtils.denotesRoot(path)) {

Modified: jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MongoDocumentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MongoDocumentStore.java?rev=1451636&r1=1451635&r2=1451636&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MongoDocumentStore.java (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MongoDocumentStore.java Fri Mar  1 16:29:03 2013
@@ -77,23 +77,25 @@ public class MongoDocumentStore implemen
 
     @Override
     public Map<String, Object> find(Collection collection, String path) {
-        Map<String, Object> result;
         synchronized (cache) {
-            result = cache.get(path);
-        }
-        if (result != null) {
-            return result;
+            // support null values
+            if (cache.containsKey(path)) {
+                return cache.get(path);
+            }
         }
         log("find", path);
         DBCollection dbCollection = getDBCollection(collection);
         long start = start();
         try {
             DBObject doc = dbCollection.findOne(getByPathQuery(path));
+            Map<String, Object> result;
             if (doc == null) {
-                return null;
+                result = null;
+            } else {
+                result = convertFromDBObject(doc);
             }
-            result = convertFromDBObject(doc);
             synchronized (cache) {
+                // support caching null values
                 cache.put(path, result);
             }
             return result;

Modified: jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MongoMK.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MongoMK.java?rev=1451636&r1=1451635&r2=1451636&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MongoMK.java (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MongoMK.java Fri Mar  1 16:29:03 2013
@@ -223,10 +223,10 @@ public class MongoMK implements MicroKer
             return c;
         }
         String from = PathUtils.concat(path, "a");
-        from = Node.convertPathToDocumentId(from);
+        from = Utils.getIdFromPath(from);
         from = from.substring(0, from.length() - 1);
         String to = PathUtils.concat(path, "z");
-        to = Node.convertPathToDocumentId(to);
+        to = Utils.getIdFromPath(to);
         to = to.substring(0, to.length() - 2) + "0";
         List<Map<String, Object>> list = store.query(DocumentStore.Collection.NODES, from, to, limit);
         c = new Node.Children(path, nodeId, rev);
@@ -237,7 +237,7 @@ public class MongoMK implements MicroKer
             }
             // TODO put the whole node in the cache
             String id = e.get(UpdateOp.ID).toString();
-            String p = id.substring(2);
+            String p = Utils.getPathFromId(id);
             c.children.add(p);
         }
         nodeChildrenCache.put(nodeId, c);
@@ -245,7 +245,7 @@ public class MongoMK implements MicroKer
     }
 
     private Node readNode(String path, Revision rev) {
-        String id = Node.convertPathToDocumentId(path);
+        String id = Utils.getIdFromPath(path);
         Map<String, Object> map = store.find(DocumentStore.Collection.NODES, id);
         if (map == null) {
             return null;
@@ -500,11 +500,13 @@ public class MongoMK implements MicroKer
 
             // remove from the cache
             nodeCache.remove(path + "@" + rev);
-
-            Node.Children c = readChildren(path, n.getId(), rev,
-                    Integer.MAX_VALUE);
-            for (String childPath : c.children) {
-                markAsDeleted(childPath, commit, true);
+            
+            if (n != null) {
+                Node.Children c = readChildren(path, n.getId(), rev,
+                        Integer.MAX_VALUE);
+                for (String childPath : c.children) {
+                    markAsDeleted(childPath, commit, true);
+                }
             }
         }
 

Modified: jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Node.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Node.java?rev=1451636&r1=1451635&r2=1451636&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Node.java (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Node.java Fri Mar  1 16:29:03 2013
@@ -66,7 +66,7 @@ public class Node {
      * Create an add node operation for this node.
      */
     UpdateOp asOperation(boolean isNew) {
-        String id = convertPathToDocumentId(path);
+        String id = Utils.getIdFromPath(path);
         UpdateOp op = new UpdateOp(path, id, isNew);
         op.set(UpdateOp.ID, id);
         for (String p : properties.keySet()) {
@@ -76,11 +76,6 @@ public class Node {
         return op;
     }
 
-    static String convertPathToDocumentId(String path) {
-        int depth = Utils.pathDepth(path);
-        return depth + ":" + path;
-    }
-    
     public String getId() {
         return path + "@" + writeCount;        
     }

Modified: jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Utils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Utils.java?rev=1451636&r1=1451635&r2=1451636&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Utils.java (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Utils.java Fri Mar  1 16:29:03 2013
@@ -28,7 +28,16 @@ import org.bson.types.ObjectId;
 public class Utils {
     
     static int pathDepth(String path) {
-        return path.equals("/") ? 0 : path.replaceAll("[^/]", "").length();
+        if (path.equals("/")) {
+            return 0;
+        }
+        int depth = 0;
+        for (int i = 0; i < path.length(); i++) {
+            if (path.charAt(i) == '/') {
+                depth++;
+            }
+        }
+        return depth;
     }
     
     static <K, V> Map<K, V> newMap() {
@@ -84,5 +93,15 @@ public class Utils {
     public static boolean isPropertyName(String key) {
         return !key.startsWith("_") || key.startsWith("__") || key.startsWith("_$");
     }
+
+    public static String getIdFromPath(String path) {
+        int depth = Utils.pathDepth(path);
+        return depth + ":" + path;
+    }
+    
+    public static String getPathFromId(String id) {
+        int index = id.indexOf(':');
+        return id.substring(index + 1);
+    }
     
 }

Modified: jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/SimpleTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/SimpleTest.java?rev=1451636&r1=1451635&r2=1451636&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/SimpleTest.java (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/SimpleTest.java Fri Mar  1 16:29:03 2013
@@ -43,6 +43,26 @@ public class SimpleTest {
     }
     
     @Test
+    public void pathToId() {
+        assertEquals("0:/", Utils.getIdFromPath("/"));
+        assertEquals("/", Utils.getPathFromId("0:/"));
+        assertEquals("1:/test", Utils.getIdFromPath("/test"));
+        assertEquals("/test", Utils.getPathFromId("1:/test"));
+        assertEquals("10:/1/2/3/3/4/6/7/8/9/a", Utils.getIdFromPath("/1/2/3/3/4/6/7/8/9/a"));
+        assertEquals("/1/2/3/3/4/6/7/8/9/a", Utils.getPathFromId("10:/1/2/3/3/4/6/7/8/9/a"));
+    }
+    
+    @Test
+    public void pathDepth() {
+        assertEquals(0, Utils.pathDepth(""));
+        assertEquals(0, Utils.pathDepth("/"));
+        assertEquals(1, Utils.pathDepth("1/"));
+        assertEquals(2, Utils.pathDepth("/a/"));
+        assertEquals(2, Utils.pathDepth("/a/b"));
+        assertEquals(3, Utils.pathDepth("/a/b/c"));
+    }
+    
+    @Test
     public void revision() {
         for (int i = 0; i < 100; i++) {
             Revision r = Revision.newRevision(i);