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 mr...@apache.org on 2017/10/02 10:22:18 UTC

svn commit: r1810329 - in /jackrabbit/oak/trunk/oak-store-document/src: main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java

Author: mreutegg
Date: Mon Oct  2 10:22:18 2017
New Revision: 1810329

URL: http://svn.apache.org/viewvc?rev=1810329&view=rev
Log:
OAK-6752: Conditional update on _modCount

Modified:
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java

Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java?rev=1810329&r1=1810328&r2=1810329&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java (original)
+++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java Mon Oct  2 10:22:18 2017
@@ -823,20 +823,29 @@ public class MongoDocumentStore implemen
             // perform a conditional update with limited result
             // if we have a matching modCount
             if (modCount != null) {
+                // only perform the conditional update when there are
+                // no conditions and the check is OK. this avoid an
+                // unnecessary call when the conditions do not match
+                if (!checkConditions || UpdateUtils.checkConditions(cachedDoc, updateOp.getConditions())) {
+                    QueryBuilder query = createQueryForUpdate(updateOp.getId(),
+                            updateOp.getConditions());
+                    // below condition may overwrite a user supplied condition
+                    // on _modCount. This fine, because the conditions were
+                    // already checked against the cached document with the
+                    // matching _modCount value. There is no need to check the
+                    // user supplied condition on _modCount again on the server
+                    query.and(Document.MOD_COUNT).is(modCount);
 
-                QueryBuilder query = createQueryForUpdate(updateOp.getId(),
-                        updateOp.getConditions());
-                query.and(Document.MOD_COUNT).is(modCount);
-
-                WriteResult result = dbCollection.update(query.get(), update);
-                if (result.getN() > 0) {
-                    // success, update cached document
-                    if (collection == Collection.NODES) {
-                        NodeDocument newDoc = (NodeDocument) applyChanges(collection, cachedDoc, updateOp);
-                        nodesCache.put(newDoc);
+                    WriteResult result = dbCollection.update(query.get(), update);
+                    if (result.getN() > 0) {
+                        // success, update cached document
+                        if (collection == Collection.NODES) {
+                            NodeDocument newDoc = (NodeDocument) applyChanges(collection, cachedDoc, updateOp);
+                            nodesCache.put(newDoc);
+                        }
+                        // return previously cached document
+                        return cachedDoc;
                     }
-                    // return previously cached document
-                    return cachedDoc;
                 }
             }
 

Modified: jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java?rev=1810329&r1=1810328&r2=1810329&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java (original)
+++ jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java Mon Oct  2 10:22:18 2017
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertNot
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNotNull;
 
 import java.io.UnsupportedEncodingException;
 import java.nio.charset.Charset;
@@ -963,6 +964,50 @@ public class BasicDocumentStoreTest exte
         assertEquals("incorrect result ordering in query result (broken collation handling in persistence?)", expected, result);
     }
 
+    @Test
+    public void modCountCondition() {
+        String id = this.getClass().getName() + ".modCountCondition";
+        removeMe.add(id);
+        UpdateOp op = new UpdateOp(id, true);
+        op.set("p", "a");
+        assertTrue(ds.create(Collection.NODES, Collections.singletonList(op)));
+        NodeDocument doc = ds.find(Collection.NODES, id);
+        assertNotNull(doc);
+        Long modCount = doc.getModCount();
+        // can only proceed if store maintains modCount
+        assumeNotNull(modCount);
+        // check equals (non-matching)
+        op = new UpdateOp(id, false);
+        op.set("p", "b");
+        op.equals(Document.MOD_COUNT, modCount + 1);
+        assertNull(ds.findAndUpdate(Collection.NODES, op));
+        // check equals (matching)
+        op = new UpdateOp(id, false);
+        op.set("p", "b");
+        op.equals(Document.MOD_COUNT, modCount);
+        assertNotNull(ds.findAndUpdate(Collection.NODES, op));
+        // validate
+        doc = ds.find(Collection.NODES, id);
+        assertNotNull(doc);
+        assertEquals("b", doc.get("p"));
+        modCount = doc.getModCount();
+        assertNotNull(modCount);
+        // check not equals (non-matching)
+        op = new UpdateOp(id, false);
+        op.set("p", "c");
+        op.notEquals(Document.MOD_COUNT, modCount);
+        assertNull(ds.findAndUpdate(Collection.NODES, op));
+        // check not equals (matching)
+        op = new UpdateOp(id, false);
+        op.set("p", "c");
+        op.notEquals(Document.MOD_COUNT, modCount + 1);
+        assertNotNull(ds.findAndUpdate(Collection.NODES, op));
+        // validate
+        doc = ds.find(Collection.NODES, id);
+        assertNotNull(doc);
+        assertEquals("c", doc.get("p"));
+    }
+
     private List<String> getKeys(List<NodeDocument> docs) {
         List<String> result = new ArrayList<String>();
         for (NodeDocument doc : docs) {