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/25 12:00:14 UTC
svn commit: r1449658 - 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 25 11:00:14 2013
New Revision: 1449658
URL: http://svn.apache.org/r1449658
Log:
OAK-619 Lock-free MongoMK implementation (formatting, node cache)
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/DocumentStore.java
jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MemoryDocumentStore.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/Revision.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/BlobTest.java
jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/MongoDocumentStoreTest.java
jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/MongoUtils.java
jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/SimpleTest.java
jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/setup.txt
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=1449658&r1=1449657&r2=1449658&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 11:00:14 2013
@@ -19,7 +19,6 @@ package org.apache.jackrabbit.mongomk.pr
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Set;
import org.apache.jackrabbit.mk.api.MicroKernelException;
import org.apache.jackrabbit.mk.json.JsopStream;
@@ -116,6 +115,14 @@ public class Commit {
store.createOrUpdate(Collection.NODES, root);
}
}
+
+ public void apply(MongoMK mk) {
+ // increment write counters
+ for (String path : changedParents) {
+ mk.incrementWriteCount(path);
+ }
+ // TODO update the cache
+ }
public void removeNode(String path) {
diff.tag('-').value(path).newline();
@@ -139,9 +146,5 @@ public class Commit {
path = PathUtils.getParentPath(path);
}
}
-
- public Set<String> getChangedParents() {
- return changedParents;
- }
}
Modified: jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/DocumentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/DocumentStore.java?rev=1449658&r1=1449657&r2=1449658&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/DocumentStore.java (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/DocumentStore.java Mon Feb 25 11:00:14 2013
@@ -24,6 +24,9 @@ import java.util.Map;
*/
public interface DocumentStore {
+ /**
+ * The list of collections.
+ */
enum Collection { NODES }
Map<String, Object> find(Collection collection, String key);
Modified: jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MemoryDocumentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MemoryDocumentStore.java?rev=1449658&r1=1449657&r2=1449658&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MemoryDocumentStore.java (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MemoryDocumentStore.java Mon Feb 25 11:00:14 2013
@@ -145,45 +145,49 @@ public class MemoryDocumentStore impleme
// update the document
// (document level operations are synchronized)
synchronized (n) {
- for (Entry<String, Operation> e : update.changes.entrySet()) {
- String k = e.getKey();
- Object old = n.get(k);
- Operation op = e.getValue();
- switch (op.type) {
- case SET: {
- n.put(k, op.value);
- break;
- }
- case INCREMENT: {
- Long x = (Long) op.value;
- if (old == null) {
- old = 0L;
- }
- n.put(k, ((Long) old) + x);
- break;
- }
- case ADD_MAP_ENTRY: {
- @SuppressWarnings("unchecked")
- Map<String, String> m = (Map<String, String>) old;
- if (m == null) {
- m = Utils.newMap();
- n.put(k, m);
- }
- m.put(op.subKey.toString(), op.value.toString());
- break;
+ applyChanges(n, update);
+ }
+ return oldNode;
+ }
+
+ public static void applyChanges(Map<String, Object> target, UpdateOp update) {
+ for (Entry<String, Operation> e : update.changes.entrySet()) {
+ String k = e.getKey();
+ Object old = target.get(k);
+ Operation op = e.getValue();
+ switch (op.type) {
+ case SET: {
+ target.put(k, op.value);
+ break;
+ }
+ case INCREMENT: {
+ Long x = (Long) op.value;
+ if (old == null) {
+ old = 0L;
}
- case REMOVE_MAP_ENTRY: {
- @SuppressWarnings("unchecked")
- Map<String, String> m = (Map<String, String>) old;
- if (m != null) {
- m.remove(op.subKey.toString());
- }
- break;
+ target.put(k, ((Long) old) + x);
+ break;
+ }
+ case ADD_MAP_ENTRY: {
+ @SuppressWarnings("unchecked")
+ Map<String, String> m = (Map<String, String>) old;
+ if (m == null) {
+ m = Utils.newMap();
+ target.put(k, m);
}
+ m.put(op.subKey.toString(), op.value.toString());
+ break;
+ }
+ case REMOVE_MAP_ENTRY: {
+ @SuppressWarnings("unchecked")
+ Map<String, String> m = (Map<String, String>) old;
+ if (m != null) {
+ m.remove(op.subKey.toString());
}
+ break;
+ }
}
}
- return oldNode;
}
@Override
@@ -196,10 +200,10 @@ public class MemoryDocumentStore impleme
public String toString() {
StringBuilder buff = new StringBuilder();
buff.append("Nodes:\n");
- for(String p : nodes.keySet()) {
+ for (String p : nodes.keySet()) {
buff.append("Path: ").append(p).append('\n');
Map<String, Object> e = nodes.get(p);
- for(String prop : e.keySet()) {
+ for (String prop : e.keySet()) {
buff.append(prop).append('=').append(e.get(prop)).append('\n');
}
buff.append("\n");
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=1449658&r1=1449657&r2=1449658&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 Mon Feb 25 11:00:14 2013
@@ -23,6 +23,7 @@ import java.util.Map;
import java.util.Map.Entry;
import org.apache.jackrabbit.mk.api.MicroKernelException;
+import org.apache.jackrabbit.mongomk.prototype.MongoMK.Cache;
import org.apache.jackrabbit.mongomk.prototype.UpdateOp.Operation;
import com.mongodb.BasicDBObject;
@@ -34,22 +35,29 @@ import com.mongodb.QueryBuilder;
import com.mongodb.WriteConcern;
import com.mongodb.WriteResult;
+/**
+ * A document store that uses MongoDB as the backend.
+ */
public class MongoDocumentStore implements DocumentStore {
public static final String KEY_PATH = "_id";
+
+ private static final boolean LOG = true;
+ private static final boolean LOG_TIME = true;
private final DBCollection nodesCollection;
- private final boolean LOG = false;
- private final boolean LOG_TIME = true;
private long time;
+
+ private Cache<String, Map<String, Object>> cache =
+ new Cache<String, Map<String, Object>>(1024);
public MongoDocumentStore(DB db) {
nodesCollection = db.getCollection(Collection.NODES.toString());
ensureIndex();
}
- private long start() {
+ private static long start() {
return LOG_TIME ? System.currentTimeMillis() : 0;
}
@@ -67,6 +75,13 @@ 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;
+ }
log("find", path);
DBCollection dbCollection = getDBCollection(collection);
long start = start();
@@ -75,7 +90,11 @@ public class MongoDocumentStore implemen
if (doc == null) {
return null;
}
- return convertFromDBObject(doc);
+ result = convertFromDBObject(doc);
+ synchronized (cache) {
+ cache.put(path, result);
+ }
+ return result;
} finally {
end(start);
}
@@ -94,9 +113,13 @@ public class MongoDocumentStore implemen
try {
DBCursor cursor = dbCollection.find(query);
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
- for (int i=0; i<limit && cursor.hasNext(); i++) {
+ for (int i = 0; i < limit && cursor.hasNext(); i++) {
DBObject o = cursor.next();
Map<String, Object> map = convertFromDBObject(o);
+ String path = (String) map.get("_id");
+ synchronized (cache) {
+ cache.put(path, map);
+ }
list.add(map);
}
return list;
@@ -111,6 +134,9 @@ public class MongoDocumentStore implemen
DBCollection dbCollection = getDBCollection(collection);
long start = start();
try {
+ synchronized (cache) {
+ cache.remove(path);
+ }
WriteResult writeResult = dbCollection.remove(getByPathQuery(path), WriteConcern.SAFE);
if (writeResult.getError() != null) {
throw new MicroKernelException("Remove failed: " + writeResult.getError());
@@ -167,9 +193,14 @@ public class MongoDocumentStore implemen
long start = start();
try {
DBObject oldNode = dbCollection.findAndModify(query, null /*fields*/,
- null /*sort*/, false /*remove*/, update, false /*returnNew*/,
+ null /*sort*/, false /*remove*/, update, true /*returnNew*/,
true /*upsert*/);
- return convertFromDBObject(oldNode);
+ Map<String, Object> map = convertFromDBObject(oldNode);
+ String path = (String) map.get("_id");
+ synchronized (cache) {
+ cache.put(path, map);
+ }
+ return map;
} catch (Exception e) {
throw new MicroKernelException(e);
} finally {
@@ -179,12 +210,17 @@ public class MongoDocumentStore implemen
@Override
public void create(Collection collection, List<UpdateOp> updateOps) {
- log("create", updateOps);
+ log("create", updateOps);
+ ArrayList<Map<String, Object>> maps = new ArrayList<Map<String, Object>>();
DBObject[] inserts = new DBObject[updateOps.size()];
for (int i = 0; i < updateOps.size(); i++) {
inserts[i] = new BasicDBObject();
- for (Entry<String, Operation> entry : updateOps.get(i).changes.entrySet()) {
+ UpdateOp update = updateOps.get(i);
+ Map<String, Object> target = Utils.newMap();
+ MemoryDocumentStore.applyChanges(target, update);
+ maps.add(target);
+ for (Entry<String, Operation> entry : update.changes.entrySet()) {
String k = entry.getKey();
Operation op = entry.getValue();
switch (op.type) {
@@ -216,6 +252,14 @@ public class MongoDocumentStore implemen
if (writeResult.getError() != null) {
throw new MicroKernelException("Batch create failed: " + writeResult.getError());
}
+ synchronized (cache) {
+ for (Map<String, Object> map : maps) {
+ String path = (String) map.get("_id");
+ synchronized (cache) {
+ cache.put(path, map);
+ }
+ }
+ }
} finally {
end(start);
}
@@ -264,7 +308,7 @@ public class MongoDocumentStore implemen
nodesCollection.getDB().getMongo().close();
}
- private void log(Object... args) {
+ private static void log(Object... args) {
if (LOG) {
System.out.println(Arrays.toString(args));
}
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=1449658&r1=1449657&r2=1449658&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 11:00:14 2013
@@ -43,6 +43,23 @@ import com.mongodb.DB;
* A MicroKernel implementation that stores the data in a MongoDB.
*/
public class MongoMK implements MicroKernel {
+
+ /**
+ * The delay for asynchronous operations (delayed commit propagation and
+ * cache update).
+ */
+ protected static final long ASYNC_DELAY = 1000;
+
+ /**
+ * For revisions that are older than this many seconds, the MongoMK will
+ * assume the revision is valid. For more recent changes, the MongoMK needs
+ * to verify it first (by reading the revision root). The default is
+ * Integer.MAX_VALUE, meaning no revisions are trusted. Once the garbage
+ * collector removes old revisions, this value is changed.
+ */
+ private static final int trustedRevisionAge = Integer.MAX_VALUE;
+
+ AtomicBoolean isDisposed = new AtomicBoolean();
/**
* The MongoDB store (might be used by multiple MongoMKs).
@@ -72,22 +89,6 @@ public class MongoMK implements MicroKer
* The unsaved write count increments.
*/
private final Map<String, Long> writeCountIncrements = new HashMap<String, Long>();
-
- /**
- * For revisions that are older than this many seconds, the MongoMK will
- * assume the revision is valid. For more recent changes, the MongoMK needs
- * to verify it first (by reading the revision root). The default is
- * Integer.MAX_VALUE, meaning no revisions are trusted. Once the garbage
- * collector removes old revisions, this value is changed.
- */
- private static final int trustedRevisionAge = Integer.MAX_VALUE;
-
- /**
- * The delay for asynchronous operations (delayed commit propagation and
- * cache update).
- */
- protected static final long ASYNC_DELAY = 1000;
-
/**
* The set of known valid revision.
* The key is the revision id, the value is 1 (because a cache can't be a set).
@@ -99,12 +100,13 @@ public class MongoMK implements MicroKer
*/
private Revision headRevision;
- AtomicBoolean isDisposed = new AtomicBoolean();
-
private Thread backgroundThread;
private final Map<String, String> branchCommits = new HashMap<String, String>();
+ private Cache<String, Node.Children> nodeChildrenCache =
+ new Cache<String, Node.Children>(1024);
+
/**
* Create a new in-memory MongoMK used for testing.
*/
@@ -135,8 +137,6 @@ public class MongoMK implements MicroKer
this.store = store;
this.blobStore = blobStore;
this.clusterId = clusterId;
- // ensure the MK can be garbage collected
- final WeakReference<MongoMK> ref = new WeakReference<MongoMK>(this);
backgroundThread = new Thread(
new BackgroundOperation(this, isDisposed),
"MongoMK background thread");
@@ -206,7 +206,17 @@ public class MongoMK implements MicroKer
return x.compareRevisionTime(requestRevision) >= 0;
}
- public Node.Children readChildren(String path, Revision rev, int limit) {
+ private boolean isRevisionNewer(Revision x, Revision previous) {
+ // TODO currently we only compare the timestamps
+ return x.compareRevisionTime(previous) >= 0;
+ }
+
+ public Node.Children readChildren(String path, String nodeId, Revision rev, int limit) {
+ Node.Children c;
+ c = nodeChildrenCache.get(nodeId);
+ if (c != null) {
+ return c;
+ }
String from = PathUtils.concat(path, "a");
from = Node.convertPathToDocumentId(from);
from = from.substring(0, from.length() - 1);
@@ -214,10 +224,10 @@ public class MongoMK implements MicroKer
to = Node.convertPathToDocumentId(to);
to = to.substring(0, to.length() - 2) + "0";
List<Map<String, Object>> list = store.query(DocumentStore.Collection.NODES, from, to, limit);
- Node.Children c = new Node.Children(path, rev);
+ c = new Node.Children(path, nodeId, rev);
for (Map<String, Object> e : list) {
- //Filter out deleted children
- if(isDeleted(e,rev)){
+ // Filter out deleted children
+ if (isDeleted(e, rev)) {
continue;
}
// TODO put the whole node in the cache
@@ -225,6 +235,7 @@ public class MongoMK implements MicroKer
String p = id.substring(2);
c.children.add(p);
}
+ nodeChildrenCache.put(nodeId, c);
return c;
}
@@ -234,13 +245,13 @@ public class MongoMK implements MicroKer
if (map == null) {
return null;
}
- if(isDeleted(map,rev)){
+ if (isDeleted(map, rev)) {
return null;
}
Node n = new Node(path, rev);
Long w = writeCountIncrements.get(path);
long writeCount = w == null ? 0 : w;
- for(String key : map.keySet()) {
+ for (String key : map.keySet()) {
if (key.equals("_writeCount")) {
writeCount += (Long) map.get(key);
}
@@ -252,10 +263,14 @@ public class MongoMK implements MicroKer
@SuppressWarnings("unchecked")
Map<String, String> valueMap = (Map<String, String>) v;
if (valueMap != null) {
+ Revision latestRev = null;
for (String r : valueMap.keySet()) {
Revision propRev = Revision.fromString(r);
if (includeRevision(propRev, rev)) {
- n.setProperty(key, valueMap.get(r));
+ if (latestRev == null || isRevisionNewer(propRev, latestRev)) {
+ latestRev = propRev;
+ n.setProperty(key, valueMap.get(r));
+ }
}
}
}
@@ -337,7 +352,7 @@ public class MongoMK implements MicroKer
includeId = filter != null && filter.contains(":hash");
json.object();
n.append(json, includeId);
- Children c = readChildren(path, rev, maxChildNodes);
+ Children c = readChildren(path, n.getId(), rev, maxChildNodes);
for (String s : c.children) {
String name = PathUtils.getName(s);
json.key(name).object().endObject();
@@ -373,7 +388,7 @@ public class MongoMK implements MicroKer
case '-':
// TODO support remove operations
commit.removeNode(path);
- markAsDeleted(path,commit,rev);
+ markAsDeleted(path, commit, rev);
break;
case '^':
t.read(':');
@@ -481,25 +496,30 @@ public class MongoMK implements MicroKer
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
+ // 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);
+ }
+ }
+
+ private boolean isDeleted(Map<String, Object> nodeProps, Revision rev) {
+ @SuppressWarnings("unchecked")
+ 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;
- }
+ if ("true".equals(e.getValue())) {
+ return true;
+ }
}
}
}
@@ -512,11 +532,7 @@ public class MongoMK implements MicroKer
return;
}
commit.apply(store);
- for(String path : commit.getChangedParents()) {
- Long value = writeCountIncrements.get(path);
- value = value == null ? 1 : value + 1;
- writeCountIncrements.put(path, value);
- }
+ commit.apply(this);
}
public static void parseAddNode(Commit commit, JsopReader t, String path) {
@@ -602,6 +618,12 @@ public class MongoMK implements MicroKer
return store;
}
+ /**
+ * A simple cache.
+ *
+ * @param <K> the key type
+ * @param <V> the value type
+ */
static class Cache<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = 1L;
@@ -618,9 +640,12 @@ public class MongoMK implements MicroKer
}
+ /**
+ * A background thread.
+ */
static class BackgroundOperation implements Runnable {
- private final AtomicBoolean isDisposed;
final WeakReference<MongoMK> ref;
+ private final AtomicBoolean isDisposed;
BackgroundOperation(MongoMK mk, AtomicBoolean isDisposed) {
ref = new WeakReference<MongoMK>(mk);
this.isDisposed = isDisposed;
@@ -642,4 +667,10 @@ public class MongoMK implements MicroKer
}
}
+ public void incrementWriteCount(String path) {
+ Long value = writeCountIncrements.get(path);
+ value = value == null ? 1 : value + 1;
+ writeCountIncrements.put(path, value);
+ }
+
}
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=1449658&r1=1449657&r2=1449658&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 11:00:14 2013
@@ -73,25 +73,34 @@ public class Node {
int depth = Utils.pathDepth(path);
return depth + ":" + path;
}
+
+ public String getId() {
+ return path + "@" + writeCount;
+ }
public void append(JsopWriter json, boolean includeId) {
if (includeId) {
- json.key(":id").value(path + "@" + writeCount);
+ json.key(":id").value(getId());
}
for (String p : properties.keySet()) {
json.key(p).encodedValue(properties.get(p));
}
}
+ /**
+ * A list of children for a node.
+ */
static class Children {
final String path;
+ final String id;
final Revision rev;
final ArrayList<String> children = new ArrayList<String>();
- Children(String path, Revision rev) {
+ Children(String path, String id, Revision rev) {
this.path = path;
+ this.id = id;
this.rev = rev;
}
Modified: jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Revision.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Revision.java?rev=1449658&r1=1449657&r2=1449658&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Revision.java (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/Revision.java Mon Feb 25 11:00:14 2013
@@ -20,6 +20,10 @@ package org.apache.jackrabbit.mongomk.pr
* A revision.
*/
public class Revision {
+
+ static long timestampOffset = java.sql.Timestamp.valueOf("2013-01-01 00:00:00.0").getTime() / 100;
+ static volatile long lastTimestamp;
+ static volatile int count;
/**
* The timestamp in milliseconds since 2013 (unlike in seconds since 1970 as
@@ -38,10 +42,6 @@ public class Revision {
*/
private int clusterId;
- static long timestampOffset = java.sql.Timestamp.valueOf("2013-01-01 00:00:00.0").getTime() / 100;
- static volatile long lastTimestamp;
- static volatile int count;
-
public Revision(long timestamp, int counter, int clusterId) {
this.timestamp = timestamp;
this.counter = counter;
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=1449658&r1=1449657&r2=1449658&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 Mon Feb 25 11:00:14 2013
@@ -1,8 +1,27 @@
+/*
+ * 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.mongomk.prototype;
import java.util.Map;
import java.util.TreeMap;
+/**
+ * Utility methods.
+ */
public class Utils {
static int pathDepth(String path) {
Modified: jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/BlobTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/BlobTest.java?rev=1449658&r1=1449657&r2=1449658&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/BlobTest.java (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/BlobTest.java Mon Feb 25 11:00:14 2013
@@ -30,13 +30,13 @@ import com.mongodb.DB;
*/
public class BlobTest {
- // private static boolean MONGO_DB = true;
- // private static long TOTAL_SIZE = 1 * 1024 * 1024 * 1024;
- // private static int DOCUMENT_COUNT = 10;
+// private static final boolean MONGO_DB = true;
+// private static final long TOTAL_SIZE = 1 * 1024 * 1024 * 1024;
+// private static final int DOCUMENT_COUNT = 10;
- private static boolean MONGO_DB = false;
- private static long TOTAL_SIZE = 1 * 1024 * 1024;
- private static int DOCUMENT_COUNT = 10;
+ private static final boolean MONGO_DB = false;
+ private static final long TOTAL_SIZE = 1 * 1024 * 1024;
+ private static final int DOCUMENT_COUNT = 10;
DB openMongoConnection() {
return MONGO_DB ? MongoUtils.getConnection().getDB() : null;
Modified: jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/MongoDocumentStoreTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/MongoDocumentStoreTest.java?rev=1449658&r1=1449657&r2=1449658&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/MongoDocumentStoreTest.java (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/MongoDocumentStoreTest.java Mon Feb 25 11:00:14 2013
@@ -34,12 +34,16 @@ import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+/**
+ * Tests the document store.
+ */
public class MongoDocumentStoreTest {
- private static boolean MONGO_DB = false;
-
-// private final static int NODE_COUNT = 2000;
- private static int NODE_COUNT = 10;
+// private static final boolean MONGO_DB = true;
+// private static final int NODE_COUNT = 2000;
+
+ private static final boolean MONGO_DB = false;
+ private static final int NODE_COUNT = 10;
DocumentStore openDocumentStore() {
if (MONGO_DB) {
@@ -73,7 +77,7 @@ public class MongoDocumentStoreTest {
Long value2 = (Long) obj.get("property2");
assertEquals(Long.valueOf(1), value2);
- String value3 = (String)obj.get("property3");
+ String value3 = (String) obj.get("property3");
assertEquals("value3", value3);
docStore.remove(Collection.NODES, "/");
@@ -182,6 +186,9 @@ public class MongoDocumentStoreTest {
System.out.println(s);
}
+ /**
+ * Task to create / update nodes.
+ */
private static class AddAndUpdateNodesTask implements Runnable {
private final DocumentStore docStore;
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=1449658&r1=1449657&r2=1449658&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 25 11:00:14 2013
@@ -36,8 +36,6 @@ public class MongoUtils {
protected static final String DB =
System.getProperty("mongo.db", "MongoMKDB");
- protected static MongoConnection mongoConnection;
-
protected static Exception exception;
/**
@@ -51,6 +49,7 @@ public class MongoUtils {
if (exception != null) {
return null;
}
+ MongoConnection mongoConnection = null;
if (mongoConnection == null) {
try {
mongoConnection = new MongoConnection(HOST, PORT, DB);
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=1449658&r1=1449657&r2=1449658&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 11:00:14 2013
@@ -25,11 +25,15 @@ import org.apache.jackrabbit.mongomk.pro
import org.junit.Test;
import com.google.common.collect.Lists;
+import com.mongodb.DB;
/**
* A set of simple tests.
*/
public class SimpleTest {
+
+// private static final boolean MONGO_DB = true;
+ private static final boolean MONGO_DB = false;
@Test
public void test() {
@@ -39,7 +43,7 @@ public class SimpleTest {
@Test
public void revision() {
- for (int i=0; i<100; i++) {
+ for (int i = 0; i < 100; i++) {
Revision r = Revision.newRevision(i);
// System.out.println(r);
Revision r2 = Revision.fromString(r.toString());
@@ -75,10 +79,10 @@ public class SimpleTest {
rev = mk.commit("/test", "+\"b\":{\"name\": \"!\"}", null, null);
test = mk.getNodes("/test", rev, 0, 0, Integer.MAX_VALUE, null);
Children c;
- c = mk.readChildren("/",
+ c = mk.readChildren("/", "1",
Revision.fromString(rev), Integer.MAX_VALUE);
assertEquals("/: [/test]", c.toString());
- c = mk.readChildren("/test",
+ c = mk.readChildren("/test", "2",
Revision.fromString(rev), Integer.MAX_VALUE);
assertEquals("/test: [/test/a, /test/b]", c.toString());
@@ -86,37 +90,41 @@ public class SimpleTest {
test = mk.getNodes("/", rev, 0, 0, Integer.MAX_VALUE, null);
assertEquals("{\"test\":1,\"test\":{},\":childNodeCount\":1}", test);
- System.out.println(test);
+ // System.out.println(test);
mk.dispose();
}
@Test
- public void testDeletion(){
+ public void testDeletion() {
MongoMK mk = createMK();
- String rev = mk.commit("/", "+\"testDel\":{\"name\": \"Hello\"}", null, null);
+ 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());
+ Children c = mk.readChildren("/testDel", "1", 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());
+ c = mk.readChildren("/testDel", "2", 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));
+ Node n = mk.getNode("/testDel", Revision.fromString(rev));
assertNull(n);
}
- private MongoMK createMK() {
+ private static MongoMK createMK() {
+ if (MONGO_DB) {
+ DB db = MongoUtils.getConnection().getDB();
+ MongoUtils.dropCollections(db);
+ return new MongoMK(db, 0);
+ }
return new MongoMK();
-// return new MongoMK(MongoUtils.getConnection().getDB(),0);
}
- // TODO run Damians tests
-
}
Modified: jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/setup.txt
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/setup.txt?rev=1449658&r1=1449657&r2=1449658&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/setup.txt (original)
+++ jackrabbit/oak/trunk/oak-mongomk/src/test/java/org/apache/jackrabbit/mongomk/prototype/setup.txt Mon Feb 25 11:00:14 2013
@@ -51,6 +51,12 @@ sh.shardCollection("MongoMKDB.nodes", {
sh.shardCollection("MongoMKDB.blobs", { "_id": 1 }, true)
exit
+=== Just one
+
+rm -rf db
+mkdir db
+./mongod --dbpath db --port 27017
+
=== Other
Display sharding status: