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 ch...@apache.org on 2013/02/22 13:40:03 UTC
svn commit: r1449018 - in /jackrabbit/oak/trunk/oak-mongomk/src:
main/java/org/apache/jackrabbit/mongomk/prototype/MongoMK.java
test/java/org/apache/jackrabbit/mongomk/prototype/SimpleTest.java
Author: chetanm
Date: Fri Feb 22 12:40:03 2013
New Revision: 1449018
URL: http://svn.apache.org/r1449018
Log:
OAK-619 - Lock-free MongoMK implementation
Adding initial support for node deletion. Deleted nodes have '_deleted' set to true in versioned manner and retrieval logic check for this property for finding valid nodes.
This impl though would not work well for deletion of deep node hierarchies.
Modified:
jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MongoMK.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/MongoMK.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MongoMK.java?rev=1449018&r1=1449017&r2=1449018&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 Feb 22 12:40:03 2013
@@ -216,6 +216,10 @@ public class MongoMK implements MicroKer
List<Map<String, Object>> list = store.query(DocumentStore.Collection.NODES, from, to, limit);
Node.Children c = new Node.Children(path, rev);
for (Map<String, Object> e : list) {
+ //Filter out deleted children
+ if(isDeleted(e,rev)){
+ continue;
+ }
// TODO put the whole node in the cache
String id = e.get("_id").toString();
String p = id.substring(2);
@@ -230,6 +234,9 @@ public class MongoMK implements MicroKer
if (map == null) {
return null;
}
+ if(isDeleted(map,rev)){
+ return null;
+ }
Node n = new Node(path, rev);
Long w = writeCountIncrements.get(path);
long writeCount = w == null ? 0 : w;
@@ -366,6 +373,7 @@ public class MongoMK implements MicroKer
case '-':
// TODO support remove operations
commit.removeNode(path);
+ markAsDeleted(path,commit,rev);
break;
case '^':
t.read(':');
@@ -466,8 +474,38 @@ public class MongoMK implements MicroKer
}
applyCommit(commit);
return rev.toString();
- }
-
+ }
+
+ private void markAsDeleted(String path, Commit commit, Revision rev) {
+ 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
+ //relooked
+ Node.Children c = readChildren(path,rev,Integer.MAX_VALUE);
+ for(String childPath : c.children){
+ markAsDeleted(childPath,commit, rev);
+ }
+ }
+
+ private boolean isDeleted(Map<String, Object> nodeProps,Revision rev){
+ Map<String,String> valueMap = (Map<String, String>) nodeProps.get("_deleted");
+ if(valueMap != null){
+ for (Map.Entry<String,String> e : valueMap.entrySet()) {
+ //TODO What if multiple revisions are there?. Should we sort them and then
+ //determine include revision based on that
+ Revision propRev = Revision.fromString(e.getKey());
+ if (includeRevision(propRev, rev)) {
+ if("true".equals(e.getValue())){
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
private void applyCommit(Commit commit) {
headRevision = commit.getRevision();
if (commit.isEmpty()) {
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=1449018&r1=1449017&r2=1449018&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 Feb 22 12:40:03 2013
@@ -17,6 +17,7 @@
package org.apache.jackrabbit.mongomk.prototype;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.apache.jackrabbit.mongomk.prototype.DocumentStore.Collection;
@@ -64,10 +65,9 @@ public class SimpleTest {
@Test
public void commit() {
- MongoMK mk = new MongoMK();
-
- String rev;
- rev = mk.commit("/", "+\"test\":{\"name\": \"Hello\"}", null, null);
+ MongoMK mk = createMK();
+
+ String rev = mk.commit("/", "+\"test\":{\"name\": \"Hello\"}", null, null);
String test = mk.getNodes("/test", rev, 0, 0, Integer.MAX_VALUE, null);
assertEquals("{\"name\":\"Hello\",\":childNodeCount\":0}", test);
@@ -89,7 +89,34 @@ public class SimpleTest {
System.out.println(test);
mk.dispose();
}
-
+
+ @Test
+ public void testDeletion(){
+ MongoMK mk = createMK();
+
+ String rev = mk.commit("/", "+\"testDel\":{\"name\": \"Hello\"}", null, null);
+ rev = mk.commit("/testDel", "+\"a\":{\"name\": \"World\"}", null, null);
+ rev = mk.commit("/testDel", "+\"b\":{\"name\": \"!\"}", null, null);
+ rev = mk.commit("/testDel", "+\"c\":{\"name\": \"!\"}", null, null);
+
+ Children c = mk.readChildren("/testDel",
+ Revision.fromString(rev), Integer.MAX_VALUE);
+ assertEquals(3,c.children.size());
+
+ rev = mk.commit("/testDel", "-\"c\"", null, null);
+ c = mk.readChildren("/testDel", Revision.fromString(rev), Integer.MAX_VALUE);
+ assertEquals(2,c.children.size());
+
+ rev = mk.commit("/", "-\"testDel\"", null, null);
+ Node n = mk.getNode("/testDel",Revision.fromString(rev));
+ assertNull(n);
+ }
+
+ private MongoMK createMK() {
+ return new MongoMK();
+// return new MongoMK(MongoUtils.getConnection().getDB(),0);
+ }
+
// TODO run Damians tests
}