Author: thomasm Date: Thu Mar 7 12:28:43 2013 New Revision: 1453808 URL: http://svn.apache.org/r1453808 Log: OAK-619 Lock-free MongoMK implementation (nodeExists returned true before the node was created; warning for reading very old revisions)
Modified: 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/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=1453808&r1=1453807&r2=1453808&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 Thu Mar 7 12:28:43 2013 @@ -64,6 +64,8 @@ public class MongoMK implements MicroKer */ private static final int CACHE_NODES = Integer.getInteger("oak.mongoMK.cacheNodes", 1024); + private static final int WARN_REVISION_AGE = Integer.getInteger("oak.mongoMK.revisionAge", 10000); + private static final Logger LOG = LoggerFactory.getLogger(MongoMK.class); /** @@ -214,6 +216,7 @@ public class MongoMK implements MicroKer * @return the node */ Node getNode(String path, Revision rev) { + checkRevisionAge(rev, path); String key = path + "@" + rev; Node node = nodeCache.get(key); if (node == null) { @@ -225,6 +228,16 @@ public class MongoMK implements MicroKer return node; } + private void checkRevisionAge(Revision r, String path) { + if (headRevision.getTimestamp() - r.getTimestamp() > WARN_REVISION_AGE) { + LOG.warn("Requesting an old revision for path " + path + ", " + + ((headRevision.getTimestamp() - r.getTimestamp()) / 1000) + " seconds old"); + if (LOG.isDebugEnabled()) { + LOG.warn("Requesting an old revision", new Exception()); + } + } + } + private boolean includeRevision(Revision x, Revision requestRevision) { if (x.getClusterId() == this.clusterId && requestRevision.getClusterId() == this.clusterId) { @@ -412,7 +425,7 @@ public class MongoMK implements MicroKer } @Override - public String commit(String rootPath, String json, String revisionId, + public synchronized String commit(String rootPath, String json, String revisionId, String message) throws MicroKernelException { revisionId = revisionId == null ? headRevision.toString() : revisionId; JsopReader t = new JsopTokenizer(json); @@ -556,7 +569,7 @@ public class MongoMK implements MicroKer .get(UpdateOp.DELETED); if (valueMap != null) { String value = getLatestValue(valueMap, rev); - if ("true".equals(value)) { + if (value == null || "true".equals(value)) { return true; } } 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=1453808&r1=1453807&r2=1453808&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 Thu Mar 7 12:28:43 2013 @@ -69,6 +69,7 @@ public class Node { String id = Utils.getIdFromPath(path); UpdateOp op = new UpdateOp(path, id, isNew); op.set(UpdateOp.ID, id); + op.addMapEntry(UpdateOp.DELETED + "." + rev.toString(), "false"); for (String p : properties.keySet()) { String key = Utils.escapePropertyName(p); op.addMapEntry(key + "." + rev.toString(), properties.get(p)); 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=1453808&r1=1453807&r2=1453808&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 Thu Mar 7 12:28:43 2013 @@ -116,6 +116,10 @@ public class Revision { return buff.toString(); } + public long getTimestamp() { + return timestamp; + } + public int hashCode() { return (int) (timestamp >>> 32) ^ (int) timestamp ^ counter ^ clusterId; } @@ -135,5 +139,5 @@ public class Revision { public int getClusterId() { return clusterId; } - + } 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=1453808&r1=1453807&r2=1453808&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 Thu Mar 7 12:28:43 2013 @@ -91,11 +91,18 @@ public class SimpleTest { @Test public void reAddDeleted() { MongoMK mk = createMK(); - String rev = mk.commit("/", "+\"test\":{\"name\": \"Hello\"}", null, null); - rev = mk.commit("/", "-\"test\"", rev, null); - rev = mk.commit("/", "+\"test\":{\"name\": \"Hallo\"}", null, null); - String test = mk.getNodes("/test", rev, 0, 0, Integer.MAX_VALUE, null); - assertEquals("{\"name\":\"Hallo\",\":childNodeCount\":0}", test); + String rev0 = mk.getHeadRevision(); + String rev1 = mk.commit("/", "+\"test\":{\"name\": \"Hello\"}", null, null); + String rev2 = mk.commit("/", "-\"test\"", null, null); + String rev3 = mk.commit("/", "+\"test\":{\"name\": \"Hallo\"}", null, null); + String test0 = mk.getNodes("/test", rev0, 0, 0, Integer.MAX_VALUE, null); + assertNull(null, test0); + String test1 = mk.getNodes("/test", rev1, 0, 0, Integer.MAX_VALUE, null); + assertEquals("{\"name\":\"Hello\",\":childNodeCount\":0}", test1); + String test2 = mk.getNodes("/test", rev2, 0, 0, Integer.MAX_VALUE, null); + assertNull(null, test2); + String test3 = mk.getNodes("/test", rev3, 0, 0, Integer.MAX_VALUE, null); + assertEquals("{\"name\":\"Hallo\",\":childNodeCount\":0}", test3); mk.dispose(); }