jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From chet...@apache.org
Subject svn commit: r1449798 - in /jackrabbit/oak/trunk/oak-mongomk/src: main/java/org/apache/jackrabbit/mongomk/prototype/ test/java/org/apache/jackrabbit/mongomk/prototype/
Date Mon, 25 Feb 2013 18:27:03 GMT
Author: chetanm
Date: Mon Feb 25 18:27:02 2013
New Revision: 1449798

URL: http://svn.apache.org/r1449798
Log:
OAK-619 - Lock-free MongoMK implementation

 Adding initial support for node move which simply copies existing node to new path and mark
old nodes for deletion

 This impl though would not work well for move of deep node hierarchies.

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/MongoMK.java
    jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Node.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=1449798&r1=1449797&r2=1449798&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
Mon Feb 25 18:27:02 2013
@@ -59,6 +59,10 @@ public class Commit {
             throw new MicroKernelException("Node already added: " + n.path);
         }
         operations.put(n.path, n.asOperation(true));
+    }
+
+    void addNodeWithDiff(Node n) {
+        addNode(n);
         diff.tag('+').key(n.path);
         diff.object();
         n.append(diff, false);
@@ -128,6 +132,10 @@ public class Commit {
         diff.tag('-').value(path).newline();
     }
 
+    public void moveNode(String sourcePath, String targetPath) {
+        diff.tag('>').key(sourcePath).value(targetPath);
+    }
+
     public JsopWriter getDiff() {
         return diff;
     }
@@ -147,4 +155,5 @@ public class Commit {
         }
     }
 
+
 }

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=1449798&r1=1449797&r2=1449798&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
Mon Feb 25 18:27:02 2013
@@ -386,9 +386,8 @@ public class MongoMK implements MicroKer
                 parseAddNode(commit, t, path);
                 break;
             case '-':
-                // TODO support remove operations
                 commit.removeNode(path);
-                markAsDeleted(path, commit, rev);
+                markAsDeleted(path, commit,true);
                 break;
             case '^':
                 t.read(':');
@@ -408,57 +407,13 @@ public class MongoMK implements MicroKer
                 break;
             case '>': {
                 t.read(':');
-                String name = PathUtils.getName(path);
-                String position, target, to;
-                boolean rename;
-                if (t.matches('{')) {
-                    rename = false;
-                    position = t.readString();
-                    t.read(':');
-                    target = t.readString();
-                    t.read('}');
-                    if (!PathUtils.isAbsolute(target)) {
-                        target = PathUtils.concat(rootPath, target);
-                    }
-                } else {
-                    rename = true;
-                    position = null;
-                    target = t.readString();
-                    if (!PathUtils.isAbsolute(target)) {
-                        target = PathUtils.concat(rootPath, target);
-                    }
-                }
-                boolean before = false;
-                if ("last".equals(position)) {
-                    target = PathUtils.concat(target, name);
-                    position = null;
-                } else if ("first".equals(position)) {
-                    target = PathUtils.concat(target, name);
-                    position = null;
-                    before = true;
-                } else if ("before".equals(position)) {
-                    position = PathUtils.getName(target);
-                    target = PathUtils.getParentPath(target);
-                    target = PathUtils.concat(target, name);
-                    before = true;
-                } else if ("after".equals(position)) {
-                    position = PathUtils.getName(target);
-                    target = PathUtils.getParentPath(target);
-                    target = PathUtils.concat(target, name);
-                } else if (position == null) {
-                    // move
-                } else {
-                    throw new MicroKernelException("position: " + position);
+                String sourcePath = path;
+                String targetPath = t.readString();
+                if (!PathUtils.isAbsolute(targetPath)) {
+                    targetPath = PathUtils.concat(path, targetPath);
                 }
-                to = PathUtils.relativize("/", target);
-                boolean inPlaceRename = false;
-                if (rename) {
-                    if (PathUtils.getParentPath(path).equals(PathUtils.getParentPath(to)))
{
-                        inPlaceRename = true;
-                        position = PathUtils.getName(path);
-                    }
-                }
-                // TODO support move operations
+                commit.moveNode(sourcePath, targetPath);
+                moveNode(sourcePath, targetPath, commit);
                 break;
             }
             case '*': {
@@ -491,20 +446,53 @@ public class MongoMK implements MicroKer
         return rev.toString();
     }
 
-    private void markAsDeleted(String path, Commit commit, Revision rev) {
+    private void moveNode(String sourcePath, String targetPath, Commit commit) {
+        //TODO Optimize - Move logic would not work well with very move of very large subtrees
+        //At minimum we can optimize by traversing breadth wise and collect node id
+        //and fetch them via '$in' queries
+
+        //TODO Transient Node - Current logic does not account for operations which are part
+        //of this commit i.e. transient nodes. If its required it would need to be looked
+        //into
+
+        Node n = getNode(sourcePath, commit.getRevision());
+
+        //Node might be deleted already
+        if(n == null){
+            return;
+        }
+
+        Node newNode = new Node(targetPath,commit.getRevision());
+        n.copyTo(newNode);
+
+        commit.addNode(newNode);
+        markAsDeleted(sourcePath,commit,false);
+        Node.Children c = readChildren(sourcePath, n.getId(),
+                commit.getRevision(), Integer.MAX_VALUE);
+        for (String srcChildPath : c.children) {
+            String childName = PathUtils.getName(srcChildPath);
+            String destChildPath = PathUtils.concat(targetPath, childName);
+            moveNode(srcChildPath,destChildPath,commit);
+        }
+    }
+
+    private void markAsDeleted(String path, Commit commit, boolean subTreeAlso) {
+        Revision rev = commit.getRevision();
         UpdateOp op = commit.getUpdateOperationForNode(path);
         op.addMapEntry("_deleted", rev.toString(), "true");
         op.increment("_writeCount", 1);
-
-        // TODO Would cause issue with large number of children. 
-        // Need to be changed
-        Node n = getNode(path, rev);
         nodeCache.remove(path + "@" + rev);
-        Node.Children c = readChildren(path, n.getId(), rev, Integer.MAX_VALUE);
-        for (String childPath : c.children) {
-            markAsDeleted(childPath, commit, rev);
+
+        if(subTreeAlso){
+            // TODO Would cause issue with large number of children.
+            // Need to be changed
+            Node n = getNode(path, rev);
+            Node.Children c = readChildren(path, n.getId(), rev, Integer.MAX_VALUE);
+            for (String childPath : c.children) {
+                markAsDeleted(childPath, commit,true);
+            }
         }
- }
+    }
 
     private boolean isDeleted(Map<String, Object> nodeProps, Revision rev) {
         @SuppressWarnings("unchecked")
@@ -551,7 +539,7 @@ public class MongoMK implements MicroKer
             } while (t.matches(','));
             t.read('}');
         }
-        commit.addNode(n);
+        commit.addNodeWithDiff(n);
     }
 
     @Override

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=1449798&r1=1449797&r2=1449798&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
Mon Feb 25 18:27:02 2013
@@ -42,8 +42,16 @@ public class Node {
     
     public String getProperty(String propertyName) {
         return properties.get(propertyName);
-    }    
-    
+    }
+
+    public void copyTo(Node newNode){
+        for(Map.Entry<String,String> e : properties.entrySet()){
+            if(!filter(e.getKey())){
+                newNode.setProperty(e.getKey(),e.getValue());
+            }
+        }
+    }
+
     public String toString() {
         StringBuilder buff = new StringBuilder();
         buff.append("path: ").append(path).append('\n');
@@ -86,6 +94,16 @@ public class Node {
             json.key(p).encodedValue(properties.get(p));
         }
     }
+
+    /**
+     * Determines if the key is system generated
+     */
+    private static boolean filter(String key) {
+        //TODO We need to move node properties to a sub key
+        //so that all other top level props can be considered as
+        //system generated and handled in a better way
+        return key.startsWith("_");
+    }
     
     /**
      * A list of children for a node.

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=1449798&r1=1449797&r2=1449798&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
Mon Feb 25 18:27:02 2013
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.mongomk.prototype;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
@@ -118,6 +119,25 @@ public class SimpleTest {
         assertNull(n);
     }
 
+    @Test
+    public void testAddAndMove() {
+        MongoMK mk = createMK();
+
+        String head = mk.getHeadRevision();
+        head = mk.commit("",
+                "+\"/root\":{}\n" +
+                        "+\"/root/a\":{}\n"+
+                        "+\"/root/a/b\":{}\n",
+                head, "");
+
+        head = mk.commit("",
+                ">\"/root/a\":\"/root/c\"\n",
+                head, "");
+
+        assertFalse(mk.nodeExists("/root/a", head));
+        assertTrue(mk.nodeExists("/root/c/b", head));
+    }
+
     private static MongoMK createMK() {
         if (MONGO_DB) {
             DB db = MongoUtils.getConnection().getDB();



Mime
View raw message