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/03/13 10:40:21 UTC
svn commit: r1455851 -
/jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MongoDocumentStore.java
Author: chetanm
Date: Wed Mar 13 09:40:21 2013
New Revision: 1455851
URL: http://svn.apache.org/r1455851
Log:
OAK-619 - Lock-free MongoMK implementation (WIP)
Using Guava cache instead of custom cache implementation
Modified:
jackrabbit/oak/trunk/oak-mongomk/src/main/java/org/apache/jackrabbit/mongomk/prototype/MongoDocumentStore.java
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=1455851&r1=1455850&r2=1455851&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 Wed Mar 13 09:40:21 2013
@@ -18,12 +18,16 @@ package org.apache.jackrabbit.mongomk.pr
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
import org.apache.jackrabbit.mk.api.MicroKernelException;
-import org.apache.jackrabbit.mongomk.prototype.MongoMK.Cache;
import org.apache.jackrabbit.mongomk.prototype.UpdateOp.Operation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,12 +55,20 @@ public class MongoDocumentStore implemen
private long time;
- private Cache<String, Map<String, Object>> cache =
- new Cache<String, Map<String, Object>>(MongoMK.CACHE_DOCUMENTS);
+ private final Cache<String, Map<String, Object>> cache;
+
+ /**
+ * Marker instance to be used as a value in cache to indicate that no value exist for given key as Guava
+ * cache does not allow null values
+ */
+ private static final Map<String, Object> NULL_VAL = Collections.emptyMap();
public MongoDocumentStore(DB db) {
nodesCollection = db.getCollection(Collection.NODES.toString());
ensureIndex();
+ cache = CacheBuilder.newBuilder()
+ .maximumSize(MongoMK.CACHE_DOCUMENTS)
+ .build();
}
private static long start() {
@@ -69,38 +81,43 @@ public class MongoDocumentStore implemen
}
}
- public void finalize() {
+ public void finalize() throws Throwable {
+ super.finalize();
// TODO should not be needed, but it seems
// oak-jcr doesn't call dispose()
dispose();
}
@Override
- public Map<String, Object> find(Collection collection, String path) {
- synchronized (cache) {
- // support null values
- if (cache.containsKey(path)) {
- return cache.get(path);
- }
- }
- log("find", path);
- DBCollection dbCollection = getDBCollection(collection);
- long start = start();
+ public Map<String, Object> find(final Collection collection, final String path) {
try {
- DBObject doc = dbCollection.findOne(getByPathQuery(path));
- Map<String, Object> result;
- if (doc == null) {
- result = null;
- } else {
- result = convertFromDBObject(doc);
- }
- synchronized (cache) {
- // support caching null values
- cache.put(path, result);
- }
- return result;
- } finally {
- end(start);
+ Map<String, Object> returnVal = cache.get(path,new Callable<Map<String, Object>>() {
+ @Override
+ public Map<String, Object> call() throws Exception {
+ DBCollection dbCollection = getDBCollection(collection);
+ long start = start();
+ try {
+ DBObject doc = dbCollection.findOne(getByPathQuery(path));
+ Map<String, Object> result;
+ if (doc == null) {
+ //TODO Look into null handling. It might happen that some
+ //other cluster node create a node at given path. So caching
+ //this info can cause issue
+
+ //In case of null let be cached as well
+ result = NULL_VAL;
+ } else {
+ result = convertFromDBObject(doc);
+ }
+ return result;
+ } finally {
+ end(start);
+ }
+ }
+ });
+ return returnVal == NULL_VAL ? null : returnVal;
+ } catch (ExecutionException e) {
+ throw new IllegalStateException( "Failed to load node " + path, e);
}
}
@@ -121,9 +138,7 @@ public class MongoDocumentStore implemen
DBObject o = cursor.next();
Map<String, Object> map = convertFromDBObject(o);
String path = (String) map.get(UpdateOp.ID);
- synchronized (cache) {
- cache.put(path, map);
- }
+ cache.put(path, map);
list.add(map);
}
return list;
@@ -138,9 +153,7 @@ public class MongoDocumentStore implemen
DBCollection dbCollection = getDBCollection(collection);
long start = start();
try {
- synchronized (cache) {
- cache.remove(path);
- }
+ cache.invalidate(path);
WriteResult writeResult = dbCollection.remove(getByPathQuery(path), WriteConcern.SAFE);
if (writeResult.getError() != null) {
throw new MicroKernelException("Remove failed: " + writeResult.getError());
@@ -208,10 +221,8 @@ public class MongoDocumentStore implemen
true /*upsert*/);
Map<String, Object> map = convertFromDBObject(oldNode);
String path = (String) map.get(UpdateOp.ID);
- synchronized (cache) {
- cache.put(path, map);
- }
- log("createOrUpdate returns ", map);
+ cache.put(path, map);
+ log("createOrUpdate returns ", map);
return map;
} catch (Exception e) {
throw new MicroKernelException(e);
@@ -266,13 +277,9 @@ public class MongoDocumentStore implemen
if (writeResult.getError() != null) {
return false;
}
- synchronized (cache) {
- for (Map<String, Object> map : maps) {
- String path = (String) map.get(UpdateOp.ID);
- synchronized (cache) {
- cache.put(path, map);
- }
- }
+ for (Map<String, Object> map : maps) {
+ String path = (String) map.get(UpdateOp.ID);
+ cache.put(path, map);
}
return true;
} catch (MongoException e) {