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/02/18 17:31:26 UTC

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

Author: thomasm
Date: Mon Feb 18 16:31:26 2013
New Revision: 1447379

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

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/MongoUtils.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=1447379&r1=1447378&r2=1447379&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 18 16:31:26 2013
@@ -20,6 +20,8 @@ import java.util.ArrayList;
 import java.util.HashMap;
 
 import org.apache.jackrabbit.mk.api.MicroKernelException;
+import org.apache.jackrabbit.mk.json.JsopStream;
+import org.apache.jackrabbit.mk.json.JsopWriter;
 import org.apache.jackrabbit.mongomk.prototype.DocumentStore.Collection;
 import org.apache.jackrabbit.oak.commons.PathUtils;
 
@@ -30,6 +32,7 @@ public class Commit {
     
     private final Revision revision;
     private HashMap<String, UpdateOp> operations = new HashMap<String, UpdateOp>();
+    private JsopWriter diff = new JsopStream();
     
     Commit(Revision revision) {
         this.revision = revision;
@@ -54,6 +57,9 @@ public class Commit {
             throw new MicroKernelException("Node already added: " + n.path);
         }
         operations.put(n.path, n.asOperation(true));
+        diff.tag('+').key(n.path);
+        n.append(diff, false);
+        diff.newline();
     }
 
     void apply(DocumentStore store) {
@@ -98,4 +104,12 @@ public class Commit {
         }
     }
 
+    public void removeNode(String path) {
+        diff.tag('-').value(path).newline();
+    }
+
+    public JsopWriter getDiff() {
+        return diff;
+    }
+
 }

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=1447379&r1=1447378&r2=1447379&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 18 16:31:26 2013
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.mongomk.prototype;
 
 import java.io.InputStream;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -88,11 +89,13 @@ public class MongoMK implements MicroKer
     /**
      * The last known head revision. This is the last-known revision.
      */
-    private String headRevision;
+    private Revision headRevision;
     
     AtomicBoolean isDisposed = new AtomicBoolean();
     
     private Thread backgroundThread;
+    
+    private final Map<String, String> branchCommits = new HashMap<String, String>();
 
     /**
      * Create a new in-memory MongoMK used for testing.
@@ -140,6 +143,15 @@ public class MongoMK implements MicroKer
         }, "MongoMK background thread");
         backgroundThread.setDaemon(true);
         backgroundThread.start();
+        headRevision = Revision.newRevision(clusterId);
+        Node n = readNode("/", headRevision);
+        if (n == null) {
+            // root node is missing: repository is not initialized
+            Commit commit = new Commit(headRevision);
+            n = new Node("/", headRevision);
+            commit.addNode(n);
+            commit.apply(store);
+        }
     }
     
     Revision newRevision() {
@@ -207,12 +219,19 @@ public class MongoMK implements MicroKer
                 // TODO property name escaping
                 continue;
             }
+            Object v = map.get(key);
+            if (!(v instanceof Map)) {
+                int test;
+                System.out.println("??");
+            }
             @SuppressWarnings("unchecked")
-            Map<String, String> valueMap = (Map<String, String>) map.get(key);
-            for (String r : valueMap.keySet()) {
-                Revision propRev = Revision.fromString(r);
-                if (includeRevision(propRev, rev)) {
-                    n.setProperty(key, valueMap.get(r));
+            Map<String, String> valueMap = (Map<String, String>) v;
+            if (valueMap != null) {
+                for (String r : valueMap.keySet()) {
+                    Revision propRev = Revision.fromString(r);
+                    if (includeRevision(propRev, rev)) {
+                        n.setProperty(key, valueMap.get(r));
+                    }
                 }
             }
         }
@@ -221,33 +240,36 @@ public class MongoMK implements MicroKer
 
     @Override
     public String getHeadRevision() throws MicroKernelException {
-        return headRevision;
+        return headRevision.toString();
     }
 
     @Override
     public String getRevisionHistory(long since, int maxEntries, String path)
             throws MicroKernelException {
-        // TODO implement if needed
-        return null;
+        // not currently called by oak-core
+        throw new MicroKernelException("Not implemented");
     }
 
     @Override
     public String waitForCommit(String oldHeadRevisionId, long timeout)
             throws MicroKernelException, InterruptedException {
-        // TODO implement if needed
-        return null;
+        // not currently called by oak-core
+        throw new MicroKernelException("Not implemented");
     }
 
     @Override
     public String getJournal(String fromRevisionId, String toRevisionId,
             String path) throws MicroKernelException {
-        // TODO implement if needed
-        return null;
+        // not currently called by oak-core
+        throw new MicroKernelException("Not implemented");
     }
 
     @Override
     public String diff(String fromRevisionId, String toRevisionId, String path,
             int depth) throws MicroKernelException {
+        if (fromRevisionId.equals(toRevisionId)) {
+            return "";
+        }
         // TODO implement if needed
         return null;
     }
@@ -263,26 +285,33 @@ public class MongoMK implements MicroKer
     @Override
     public long getChildNodeCount(String path, String revisionId)
             throws MicroKernelException {
-        // TODO implement if needed
-        return 0;
+        // not currently called by oak-core
+        throw new MicroKernelException("Not implemented");
     }
 
     @Override
     public String getNodes(String path, String revisionId, int depth,
             long offset, int maxChildNodes, String filter)
             throws MicroKernelException {
+        if (depth != 0) {
+            throw new MicroKernelException("Only depth 0 is supported, depth is " + depth);
+        }
+        if (revisionId.startsWith("b")) {
+            // reading from the branch is reading from the trunk currently
+            revisionId = revisionId.substring(1).replace('+', ' ').trim();
+        }
         Revision rev = Revision.fromString(revisionId);
         Node n = getNode(path, rev);
         JsopStream json = new JsopStream();
-        n.append(json);
+        n.append(json, true);
         return json.toString();
     }
 
     @Override
     public String commit(String rootPath, String json, String revisionId,
             String message) throws MicroKernelException {
+        revisionId = revisionId == null ? headRevision.toString() : revisionId;
         JsopReader t = new JsopTokenizer(json);
-        revisionId = revisionId == null ? headRevision : revisionId;
         Revision rev = Revision.newRevision(clusterId);
         Commit commit = new Commit(rev);
         while (true) {
@@ -299,19 +328,22 @@ public class MongoMK implements MicroKer
                 break;
             case '-':
                 // TODO support remove operations
+                commit.removeNode(path);
                 break;
             case '^':
                 t.read(':');
                 String value;
                 if (t.matches(JsopReader.NULL)) {
                     value = null;
+                    commit.getDiff().tag('^').key(path).value(null);
                 } else {
                     value = t.readRawValue().trim();
+                    commit.getDiff().tag('^').key(path).value(null);
                 }
                 String p = PathUtils.getParentPath(path);
                 String propertyName = PathUtils.getName(path);
                 UpdateOp op = commit.getUpdateOperationForNode(p);
-                op.set(propertyName, value);
+                op.addMapEntry(propertyName, rev.toString(), value);
                 break;
             case '>': {
                 t.read(':');
@@ -383,9 +415,21 @@ public class MongoMK implements MicroKer
                 throw new MicroKernelException("token: " + (char) t.getTokenType());
             }
         }
+        if (revisionId.startsWith("b")) {
+            // just commit to head currently
+            commit.apply(store);
+            headRevision = rev;
+            return "b" + rev.toString();
+            
+            // String jsonBranch = branchCommits.remove(revisionId);
+            // jsonBranch += commit.getDiff().toString();
+            // String branchRev = revisionId + "+";
+            // branchCommits.put(branchRev, jsonBranch);
+            // return branchRev;
+        }
         commit.apply(store);
-        headRevision = rev.toString();
-        return headRevision;
+        headRevision = rev;
+        return rev.toString();
     }    
     
     public static void parseAddNode(Commit commit, JsopReader t, String path) {
@@ -409,23 +453,34 @@ public class MongoMK implements MicroKer
 
     @Override
     public String branch(String trunkRevisionId) throws MicroKernelException {
-        // TODO implement if needed
-        return null;
+        // TODO improve implementation if needed
+        String branchId = "b" + trunkRevisionId;
+        // branchCommits.put(branchId, "");
+        return branchId;
     }
 
     @Override
     public String merge(String branchRevisionId, String message)
             throws MicroKernelException {
-        // TODO implement if needed
-        return null;
+        // reading from the branch is reading from the trunk currently
+        String revisionId = branchRevisionId.substring(1).replace('+', ' ').trim();
+        return revisionId;
+        
+        // TODO improve implementation if needed
+        // if (!branchRevisionId.startsWith("b")) {
+        //     throw new MicroKernelException("Not a branch: " + branchRevisionId);
+        // }
+        // 
+        // String commit = branchCommits.remove(branchRevisionId);
+        // return commit("", commit, null, null);
     }
 
     @Override
     @Nonnull
-    public String rebase(@Nonnull String branchRevisionId, String newBaseRevisionId)
+    public String rebase(String branchRevisionId, String newBaseRevisionId)
             throws MicroKernelException {
-        // TODO implement if needed
-        return null;
+        // TODO improve implementation if needed
+        return branchRevisionId;
     }
 
     @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=1447379&r1=1447378&r2=1447379&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 18 16:31:26 2013
@@ -18,7 +18,7 @@ package org.apache.jackrabbit.mongomk.pr
 
 import java.util.Map;
 
-import org.apache.jackrabbit.mk.json.JsopStream;
+import org.apache.jackrabbit.mk.json.JsopWriter;
 
 /**
  * Represents a node held in memory (in the cache for example).
@@ -72,8 +72,11 @@ public class Node {
         return depth + ":" + path;
     }
 
-    public void append(JsopStream json) {
+    public void append(JsopWriter json, boolean includeId) {
         json.object();
+        if (includeId) {
+            json.key(":id").value(path + "@" + rev);
+        }
         for (String p : properties.keySet()) {
             json.key(p).encodedValue(properties.get(p));
         }

Modified: jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/MongoUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/MongoUtils.java?rev=1447379&r1=1447378&r2=1447379&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/MongoUtils.java (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/MongoUtils.java Mon Feb 18 16:31:26 2013
@@ -55,7 +55,7 @@ public class MongoUtils {
             try {
                 mongoConnection = new MongoConnection(HOST, PORT, DB);
                 mongoConnection.getDB().command(new BasicDBObject("ping", 1));
-                dropCollections(mongoConnection.getDB());
+                // dropCollections(mongoConnection.getDB());
             } catch (Exception e) {
                 exception = e;
             }