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 ca...@apache.org on 2015/12/02 22:25:02 UTC

svn commit: r1717683 - in /jackrabbit/oak/branches/1.2: ./ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/ oak-core/src/test/java/org/apache/jackrabbit/oak/plug...

Author: catholicon
Date: Wed Dec  2 21:25:02 2015
New Revision: 1717683

URL: http://svn.apache.org/viewvc?rev=1717683&view=rev
Log:
OAK-3223: Remove MongoDiffCache
(backporting r1695571 into 1.2 branch)
OAK-3494: MemoryDiffCache should also check parent paths before falling to Loader (or returning null)
(backporting r1707509 and r1710800 into 1.2 branch)


Removed:
    jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDiffCache.java
    jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDiffCacheTest.java
Modified:
    jackrabbit/oak/branches/1.2/   (props changed)
    jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DiffCache.java
    jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
    jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
    jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
    jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LocalDiffCache.java
    jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MemoryDiffCache.java
    jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/TieredDiffCache.java
    jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AmnesiaDiffCache.java
    jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalEntryTest.java
    jackrabbit/oak/branches/1.2/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/random/RandomOpCompare.java

Propchange: jackrabbit/oak/branches/1.2/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Dec  2 21:25:02 2015
@@ -1,3 +1,3 @@
 /jackrabbit/oak/branches/1.0:1665962
-/jackrabbit/oak/trunk:1672350,1672468,1672537,1672603,1672642,1672644,1672834-1672835,1673351,1673410,1673414-1673415,1673436,1673644,1673662-1673664,1673669,1673695,1673713,1673738,1673787,1673791,1674046,1674065,1674075,1674107,1674228,1674780,1674880,1675054-1675055,1675319,1675332,1675354,1675357,1675382,1675555,1675566,1675593,1676198,1676237,1676407,1676458,1676539,1676670,1676693,1676703,1676725,1677579,1677581,1677609,1677611,1677774,1677788,1677797,1677804,1677806,1677939,1677991,1678023,1678095-1678096,1678124,1678171,1678173,1678211,1678323,1678758,1678938,1678954,1679144,1679165,1679191,1679232,1679235,1679503,1679958,1679961,1680170,1680172,1680182,1680222,1680232,1680236,1680461,1680633,1680643,1680747,1680805-1680806,1680903,1681282,1681767,1681918,1681921,1681955,1682042,1682218,1682235,1682437,1682494,1682555,1682855,1682904,1683059,1683089,1683213,1683249,1683259,1683278,1683323,1683687,1683700,1684174-1684175,1684186,1684376,1684442,1684561,1684570,1684601,1684618
 ,1684820,1684868,1685023,1685075,1685370,1685552,1685589-1685590,1685840,1685964,1685977,1685989,1685999,1686023,1686032,1686097,1686162,1686229,1686234,1686253,1686414,1686780,1686854,1686857,1686971,1687053-1687055,1687175,1687196,1687198,1687220,1687239-1687240,1687301,1687441,1687553,1688089-1688090,1688172,1688179,1688349,1688421,1688436,1688453,1688616,1688622,1688634,1688636,1688817,1689003-1689004,1689008,1689577,1689581,1689623,1689810,1689828,1689831,1689833,1689903,1690017,1690043,1690047,1690057,1690247,1690249,1690634-1690637,1690650,1690669,1690674,1690885,1690941,1691139,1691151,1691159,1691167,1691183,1691188,1691210,1691280,1691307,1691331-1691333,1691345,1691384-1691385,1691401,1691509,1692133-1692134,1692156,1692250,1692274,1692363,1692382,1692478,1692955,1693002,1693030,1693050,1693209,1693421,1693525-1693526,1694007,1694393-1694394,1694651,1694653-1694654,1695032,1695050,1695122,1695280,1695299,1695420,1695457,1695482,1695492,1695507,1695521,1695540,1695905,1696
 190,1696194,1696242,1696285,1696375,1696522,1696578,1696759,1696916,1697363,1697373,1697410,1697582,1697589,1697616,1697672,1700191,1700231,1700397,1700403,1700506,1700571,1700718,1700727,1700749,1700769,1700775,1701065,1701619,1701733,1701743,1701750,1701768,1701806,1701810,1701814,1701948,1701955,1701959,1701965,1701986,1702014,1702022,1702045,1702051,1702241,1702272,1702387,1702405,1702423,1702860,1702942,1702960,1703212,1703382,1703395,1703411,1703428,1703430,1703568,1703592,1703758,1703858,1703878,1704256,1704282,1704285,1704457,1704479,1704490,1704614,1704629,1704636,1704655,1704670,1704886,1705005,1705027,1705043,1705055,1705250,1705268,1705273,1705323,1705677,1705701,1705871,1705992,1705998,1706009,1706037,1706059,1706212,1706218,1706270,1706764,1706772,1707049,1707191,1707435,1708105,1708315,1708546,1708592,1708766,1709012,1709852,1709978,1710013,1710031,1710049,1710205,1710242,1710559,1710575,1710590,1710614,1710637,1710789,1710811,1710816,1710972,1711248,1711282,1711296,1
 711498,1712018,1712042,1712319,1712490,1712531,1712730,1712785,1712963,1713008,1713439,1713461,1713580,1713586,1713599-1713600,1713626,1713698,1713803,1713809,1714034,1714061,1714084,1714170,1714213,1714229,1714238,1714519-1714520,1714543-1714544,1714730,1714739,1714779,1714956,1714961,1715010,1715191,1715346,1715767,1715771,1715888,1715898,1716178,1716426,1716576,1716596,1716616,1716703,1716712,1716815,1716823,1716830,1716883,1717277,1717462,1717632
+/jackrabbit/oak/trunk:1672350,1672468,1672537,1672603,1672642,1672644,1672834-1672835,1673351,1673410,1673414-1673415,1673436,1673644,1673662-1673664,1673669,1673695,1673713,1673738,1673787,1673791,1674046,1674065,1674075,1674107,1674228,1674780,1674880,1675054-1675055,1675319,1675332,1675354,1675357,1675382,1675555,1675566,1675593,1676198,1676237,1676407,1676458,1676539,1676670,1676693,1676703,1676725,1677579,1677581,1677609,1677611,1677774,1677788,1677797,1677804,1677806,1677939,1677991,1678023,1678095-1678096,1678124,1678171,1678173,1678211,1678323,1678758,1678938,1678954,1679144,1679165,1679191,1679232,1679235,1679503,1679958,1679961,1680170,1680172,1680182,1680222,1680232,1680236,1680461,1680633,1680643,1680747,1680805-1680806,1680903,1681282,1681767,1681918,1681921,1681955,1682042,1682218,1682235,1682437,1682494,1682555,1682855,1682904,1683059,1683089,1683213,1683249,1683259,1683278,1683323,1683687,1683700,1684174-1684175,1684186,1684376,1684442,1684561,1684570,1684601,1684618
 ,1684820,1684868,1685023,1685075,1685370,1685552,1685589-1685590,1685840,1685964,1685977,1685989,1685999,1686023,1686032,1686097,1686162,1686229,1686234,1686253,1686414,1686780,1686854,1686857,1686971,1687053-1687055,1687175,1687196,1687198,1687220,1687239-1687240,1687301,1687441,1687553,1688089-1688090,1688172,1688179,1688349,1688421,1688436,1688453,1688616,1688622,1688634,1688636,1688817,1689003-1689004,1689008,1689577,1689581,1689623,1689810,1689828,1689831,1689833,1689903,1690017,1690043,1690047,1690057,1690247,1690249,1690634-1690637,1690650,1690669,1690674,1690885,1690941,1691139,1691151,1691159,1691167,1691183,1691188,1691210,1691280,1691307,1691331-1691333,1691345,1691384-1691385,1691401,1691509,1692133-1692134,1692156,1692250,1692274,1692363,1692382,1692478,1692955,1693002,1693030,1693050,1693209,1693421,1693525-1693526,1694007,1694393-1694394,1694651,1694653-1694654,1695032,1695050,1695122,1695280,1695299,1695420,1695457,1695482,1695492,1695507,1695521,1695540,1695571,1695
 905,1696190,1696194,1696242,1696285,1696375,1696522,1696578,1696759,1696916,1697363,1697373,1697410,1697582,1697589,1697616,1697672,1700191,1700231,1700397,1700403,1700506,1700571,1700718,1700727,1700749,1700769,1700775,1701065,1701619,1701733,1701743,1701750,1701768,1701806,1701810,1701814,1701948,1701955,1701959,1701965,1701986,1702014,1702022,1702045,1702051,1702241,1702272,1702387,1702405,1702423,1702860,1702942,1702960,1703212,1703382,1703395,1703411,1703428,1703430,1703568,1703592,1703758,1703858,1703878,1704256,1704282,1704285,1704457,1704479,1704490,1704614,1704629,1704636,1704655,1704670,1704886,1705005,1705027,1705043,1705055,1705250,1705268,1705273,1705323,1705677,1705701,1705871,1705992,1705998,1706009,1706037,1706059,1706212,1706218,1706270,1706764,1706772,1707049,1707191,1707435,1707509,1708105,1708315,1708546,1708592,1708766,1709012,1709852,1709978,1710013,1710031,1710049,1710205,1710242,1710559,1710575,1710590,1710614,1710637,1710789,1710800,1710811,1710816,1710972,1
 711248,1711282,1711296,1711498,1712018,1712042,1712319,1712490,1712531,1712730,1712785,1712963,1713008,1713439,1713461,1713580,1713586,1713599-1713600,1713626,1713698,1713803,1713809,1714034,1714061,1714084,1714170,1714213,1714229,1714238,1714519-1714520,1714543-1714544,1714730,1714739,1714779,1714956,1714961,1715010,1715191,1715346,1715767,1715771,1715888,1715898,1716178,1716426,1716576,1716596,1716616,1716703,1716712,1716815,1716823,1716830,1716883,1717277,1717462,1717632
 /jackrabbit/trunk:1345480

Modified: jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DiffCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DiffCache.java?rev=1717683&r1=1717682&r2=1717683&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DiffCache.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DiffCache.java Wed Dec  2 21:25:02 2015
@@ -21,11 +21,15 @@ import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 import org.apache.jackrabbit.oak.cache.CacheStats;
+import org.apache.jackrabbit.oak.commons.json.JsopReader;
+import org.apache.jackrabbit.oak.commons.json.JsopTokenizer;
+
+import static org.apache.jackrabbit.oak.plugins.document.util.Utils.unshareString;
 
 /**
  * A cache for child node diffs.
  */
-public interface DiffCache {
+abstract class DiffCache {
 
     /**
      * Returns a jsop diff for the child nodes at the given path. The returned
@@ -45,10 +49,10 @@ public interface DiffCache {
      * @return the diff or {@code null} if unknown and no loader was passed.
      */
     @CheckForNull
-    String getChanges(@Nonnull Revision from,
-                      @Nonnull Revision to,
-                      @Nonnull String path,
-                      @Nullable Loader loader);
+    abstract String getChanges(@Nonnull Revision from,
+                               @Nonnull Revision to,
+                               @Nonnull String path,
+                               @Nullable Loader loader);
 
     /**
      * Starts a new cache entry for the diff cache. Actual changes are added
@@ -61,15 +65,70 @@ public interface DiffCache {
      * @return the cache entry.
      */
     @Nonnull
-    Entry newEntry(@Nonnull Revision from,
-                   @Nonnull Revision to,
-                   boolean local);
+    abstract Entry newEntry(@Nonnull Revision from,
+                            @Nonnull Revision to,
+                            boolean local);
 
     /**
      * @return the statistics for this cache.
      */
     @Nonnull
-    Iterable<CacheStats> getStats();
+    abstract Iterable<CacheStats> getStats();
+
+    /**
+     * Parses the jsop diff returned by
+     * {@link #getChanges(Revision, Revision, String, Loader)} and reports the
+     * changes by calling the appropriate methods on {@link Diff}.
+     *
+     * @param jsop the jsop diff to parse.
+     * @param diff the diff handler.
+     * @return {@code true} it the complete jsop was processed or {@code false}
+     *      if one of the {@code diff} callbacks requested a stop.
+     * @throws IllegalArgumentException if {@code jsop} is malformed.
+     */
+    static boolean parseJsopDiff(@Nonnull String jsop,
+                                 @Nonnull Diff diff) {
+        if (jsop.trim().isEmpty()) {
+            return true;
+        }
+        JsopTokenizer t = new JsopTokenizer(jsop);
+        boolean continueComparison = true;
+        while (continueComparison) {
+            int r = t.read();
+            if (r == JsopReader.END) {
+                break;
+            }
+            switch (r) {
+                case '+': {
+                    String name = unshareString(t.readString());
+                    t.read(':');
+                    t.read('{');
+                    while (t.read() != '}') {
+                        // skip properties
+                    }
+                    continueComparison = diff.childNodeAdded(name);
+                    break;
+                }
+                case '-': {
+                    String name = unshareString(t.readString());
+                    continueComparison = diff.childNodeDeleted(name);
+                    break;
+                }
+                case '^': {
+                    String name = unshareString(t.readString());
+                    t.read(':');
+                    t.read('{');
+                    t.read('}');
+                    continueComparison = diff.childNodeChanged(name);
+                    break;
+                }
+                default:
+                    throw new IllegalArgumentException("jsonDiff: illegal token '"
+                            + t.getToken() + "' at pos: " + t.getLastPos() + ' ' + jsop);
+            }
+        }
+        return continueComparison;
+    }
 
     interface Entry {
 
@@ -96,4 +155,14 @@ public interface DiffCache {
 
         String call();
     }
+
+    interface Diff {
+
+        boolean childNodeAdded(String name);
+
+        boolean childNodeChanged(String name);
+
+        boolean childNodeDeleted(String name);
+
+    }
 }

Modified: jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java?rev=1717683&r1=1717682&r2=1717683&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java Wed Dec  2 21:25:02 2015
@@ -542,11 +542,9 @@ public class DocumentMK implements Micro
          * Use the given MongoDB as backend storage for the DocumentNodeStore.
          *
          * @param db the MongoDB connection
-         * @param changesSizeMB the size in MB of the capped collection backing
-         *                      the MongoDiffCache.
          * @return this
          */
-        public Builder setMongoDB(DB db, int changesSizeMB, int blobCacheSizeMB) {
+        public Builder setMongoDB(DB db, int blobCacheSizeMB) {
             if (db != null) {
                 if (this.documentStore == null) {
                     this.documentStore = new MongoDocumentStore(db, this);
@@ -571,7 +569,7 @@ public class DocumentMK implements Micro
          * @return this
          */
         public Builder setMongoDB(DB db) {
-            return setMongoDB(db, 8, 16);
+            return setMongoDB(db, 16);
         }
 
         /**

Modified: jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1717683&r1=1717682&r2=1717683&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java Wed Dec  2 21:25:02 2015
@@ -34,7 +34,6 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.plugins.document.util.Utils.asStringValueIterable;
 import static org.apache.jackrabbit.oak.plugins.document.util.Utils.getIdFromPath;
 import static org.apache.jackrabbit.oak.plugins.document.util.Utils.pathToId;
-import static org.apache.jackrabbit.oak.plugins.document.util.Utils.unshareString;
 
 import java.io.Closeable;
 import java.io.IOException;
@@ -2077,67 +2076,45 @@ public final class DocumentNodeStore
         }
     }
 
-    private boolean dispatch(@Nonnull String jsonDiff,
-                             @Nonnull DocumentNodeState node,
-                             @Nonnull DocumentNodeState base,
-                             @Nonnull NodeStateDiff diff) {
-        if (jsonDiff.trim().isEmpty()) {
-            return true;
-        }
-        JsopTokenizer t = new JsopTokenizer(jsonDiff);
-        boolean continueComparison = true;
-        while (continueComparison) {
-            int r = t.read();
-            if (r == JsopReader.END) {
-                break;
+    private boolean dispatch(@Nonnull final String jsonDiff,
+                             @Nonnull final DocumentNodeState node,
+                             @Nonnull final DocumentNodeState base,
+                             @Nonnull final NodeStateDiff diff) {
+        return DiffCache.parseJsopDiff(jsonDiff, new DiffCache.Diff() {
+            @Override
+            public boolean childNodeAdded(String name) {
+                return diff.childNodeAdded(name,
+                        node.getChildNode(name));
             }
-            switch (r) {
-                case '+': {
-                    String name = unshareString(t.readString());
-                    t.read(':');
-                    t.read('{');
-                    while (t.read() != '}') {
-                        // skip properties
-                    }
-                    continueComparison = diff.childNodeAdded(name,
-                            node.getChildNode(name));
-                    break;
-                }
-                case '-': {
-                    String name = unshareString(t.readString());
-                    continueComparison = diff.childNodeDeleted(name,
-                            base.getChildNode(name));
-                    break;
-                }
-                case '^': {
-                    String name = unshareString(t.readString());
-                    t.read(':');
-                    t.read('{');
-                    t.read('}');
-                    NodeState baseChild = base.getChildNode(name);
-                    NodeState nodeChild = node.getChildNode(name);
-                    if (baseChild.exists()) {
-                        if (nodeChild.exists()) {
-                            continueComparison = diff.childNodeChanged(name,
-                                    baseChild, nodeChild);
-                        } else {
-                            continueComparison = diff.childNodeDeleted(name,
-                                    baseChild);
-                        }
+
+            @Override
+            public boolean childNodeChanged(String name) {
+                boolean continueComparison = true;
+                NodeState baseChild = base.getChildNode(name);
+                NodeState nodeChild = node.getChildNode(name);
+                if (baseChild.exists()) {
+                    if (nodeChild.exists()) {
+                        continueComparison = diff.childNodeChanged(name,
+                                baseChild, nodeChild);
                     } else {
-                        if (nodeChild.exists()) {
-                            continueComparison = diff.childNodeAdded(name,
-                                    nodeChild);
-                        }
+                        continueComparison = diff.childNodeDeleted(name,
+                                baseChild);
+                    }
+                } else {
+                    if (nodeChild.exists()) {
+                        continueComparison = diff.childNodeAdded(name,
+                                nodeChild);
                     }
-                    break;
                 }
-                default:
-                    throw new IllegalArgumentException("jsonDiff: illegal token '"
-                            + t.getToken() + "' at pos: " + t.getLastPos() + ' ' + jsonDiff);
+                return continueComparison;
             }
-        }
-        return continueComparison;
+
+            @Override
+            public boolean childNodeDeleted(String name) {
+                return diff.childNodeDeleted(name,
+                        base.getChildNode(name));
+            }
+        });
     }
 
     /**

Modified: jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java?rev=1717683&r1=1717682&r2=1717683&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java Wed Dec  2 21:25:02 2015
@@ -99,7 +99,6 @@ public class DocumentNodeStoreService {
     private static final String DEFAULT_URI = "mongodb://localhost:27017/oak";
     private static final int DEFAULT_CACHE = 256;
     private static final int DEFAULT_OFF_HEAP_CACHE = 0;
-    private static final int DEFAULT_CHANGES_SIZE = 256;
     private static final int DEFAULT_BLOB_CACHE_SIZE = 16;
     private static final String DEFAULT_DB = "oak";
     private static final String DEFAULT_PERSISTENT_CACHE = "";
@@ -183,13 +182,6 @@ public class DocumentNodeStoreService {
 
     private static final String PROP_OFF_HEAP_CACHE = "offHeapCache";
 
-    @Property(intValue =  DEFAULT_CHANGES_SIZE,
-            label = "Mongo Changes Collection Size (in MB)",
-            description = "With the MongoDB backend, the DocumentNodeStore uses a capped collection to cache the diff. " +
-                    "This value is used to determine the size of that capped collection"
-    )
-    private static final String PROP_CHANGES_SIZE = "changesSize";
-
     @Property(intValue =  DEFAULT_BLOB_CACHE_SIZE,
             label = "Blob Cache Size (in MB)",
             description = "Cache size to store blobs in memory. Used only with default BlobStore " +
@@ -360,7 +352,6 @@ public class DocumentNodeStoreService {
         int childrenCachePercentage = toInteger(prop(PROP_CHILDREN_CACHE_PERCENTAGE), DEFAULT_CHILDREN_CACHE_PERCENTAGE);
         int docChildrenCachePercentage = toInteger(prop(PROP_DOC_CHILDREN_CACHE_PERCENTAGE), DEFAULT_DOC_CHILDREN_CACHE_PERCENTAGE);
         int diffCachePercentage = toInteger(prop(PROP_DIFF_CACHE_PERCENTAGE), DEFAULT_DIFF_CACHE_PERCENTAGE);
-        int changesSize = toInteger(prop(PROP_CHANGES_SIZE), DEFAULT_CHANGES_SIZE);
         int blobCacheSize = toInteger(prop(PROP_BLOB_CACHE_SIZE), DEFAULT_BLOB_CACHE_SIZE);
         String persistentCache = PropertiesUtil.toString(prop(PROP_PERSISTENT_CACHE), DEFAULT_PERSISTENT_CACHE);
         int cacheSegmentCount = toInteger(prop(PROP_CACHE_SEGMENT_COUNT), DEFAULT_CACHE_SEGMENT_COUNT);
@@ -410,8 +401,8 @@ public class DocumentNodeStoreService {
                 // Take care around not logging the uri directly as it
                 // might contain passwords
                 log.info("Starting DocumentNodeStore with host={}, db={}, cache size (MB)={}, persistentCache={}, " +
-                                "'changes' collection size (MB)={}, blobCacheSize (MB)={}, maxReplicationLagInSecs={}",
-                        mongoURI.getHosts(), db, cacheSize, persistentCache, changesSize, blobCacheSize, maxReplicationLagInSecs);
+                                "blobCacheSize (MB)={}, maxReplicationLagInSecs={}",
+                        mongoURI.getHosts(), db, cacheSize, persistentCache, blobCacheSize, maxReplicationLagInSecs);
                 log.info("Mongo Connection details {}", MongoConnection.toString(mongoURI.getOptions()));
             }
 
@@ -419,7 +410,7 @@ public class DocumentNodeStoreService {
             DB mongoDB = client.getDB(db);
 
             mkBuilder.setMaxReplicationLag(maxReplicationLagInSecs, TimeUnit.SECONDS);
-            mkBuilder.setMongoDB(mongoDB, changesSize, blobCacheSize);
+            mkBuilder.setMongoDB(mongoDB, blobCacheSize);
 
             log.info("Connected to database {}", mongoDB);
         }

Modified: jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LocalDiffCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LocalDiffCache.java?rev=1717683&r1=1717682&r2=1717683&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LocalDiffCache.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LocalDiffCache.java Wed Dec  2 21:25:02 2015
@@ -36,7 +36,7 @@ import org.apache.jackrabbit.oak.plugins
 /**
  * A diff cache, which is pro-actively filled after a commit.
  */
-public class LocalDiffCache implements DiffCache {
+public class LocalDiffCache extends DiffCache {
 
     /**
      * Limit is arbitrary for now i.e. 16 MB. Same as in MongoDiffCache

Modified: jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MemoryDiffCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MemoryDiffCache.java?rev=1717683&r1=1717682&r2=1717683&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MemoryDiffCache.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MemoryDiffCache.java Wed Dec  2 21:25:02 2015
@@ -30,11 +30,14 @@ import org.apache.jackrabbit.oak.plugins
 import com.google.common.cache.Cache;
 
 import static com.google.common.base.Preconditions.checkNotNull;
+import static org.apache.jackrabbit.oak.commons.PathUtils.denotesRoot;
+import static org.apache.jackrabbit.oak.commons.PathUtils.getName;
+import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;
 
 /**
  * An in-memory diff cache implementation.
  */
-public class MemoryDiffCache implements DiffCache {
+public class MemoryDiffCache extends DiffCache {
 
     /**
      * Diff cache.
@@ -53,20 +56,27 @@ public class MemoryDiffCache implements
 
     @CheckForNull
     @Override
-    public String getChanges(@Nonnull Revision from,
-                             @Nonnull Revision to,
-                             @Nonnull String path,
-                             final @Nullable Loader loader) {
+    public String getChanges(@Nonnull final Revision from,
+                             @Nonnull final Revision to,
+                             @Nonnull final String path,
+                             @Nullable final Loader loader) {
         PathRev key = diffCacheKey(path, from, to);
         StringValue diff;
         if (loader == null) {
             diff = diffCache.getIfPresent(key);
+            if (diff == null && isUnchanged(from, to, path)) {
+                diff = new StringValue("");
+            }
         } else {
             try {
                 diff = diffCache.get(key, new Callable<StringValue>() {
                     @Override
                     public StringValue call() throws Exception {
-                        return new StringValue(loader.call());
+                        if (isUnchanged(from, to, path)) {
+                            return new StringValue("");
+                        } else {
+                            return new StringValue(loader.call());
+                        }
                     }
                 });
             } catch (ExecutionException e) {
@@ -119,4 +129,61 @@ public class MemoryDiffCache implements
         return new PathRev(from + path, to);
     }
 
+    /**
+     * Returns {@code true} if it can be inferred from cache entries on
+     * ancestors of the given {@code path} that the node was not changed between
+     * the two revisions. This method returns {@code false} if there are no
+     * matching cache entries for the given revision range or one of them
+     * indicates that the node at the given path may have been modified.
+     *
+     * @param from the from revision.
+     * @param to the to revision.
+     * @param path the path of the node to check.
+     * @return {@code true} if there are cache entries that indicate the node
+     *      at the given path was modified between the two revisions.
+     */
+    private boolean isUnchanged(@Nonnull final Revision from,
+                                @Nonnull final Revision to,
+                                @Nonnull final String path) {
+        return !denotesRoot(path)
+                && isChildUnchanged(from, to, getParentPath(path), getName(path));
+    }
+
+    private boolean isChildUnchanged(@Nonnull final Revision from,
+                                     @Nonnull final Revision to,
+                                     @Nonnull final String parent,
+                                     @Nonnull final String name) {
+        PathRev parentKey = diffCacheKey(parent, from, to);
+        StringValue parentCachedEntry = diffCache.getIfPresent(parentKey);
+        boolean unchanged;
+        if (parentCachedEntry == null) {
+            if (denotesRoot(parent)) {
+                // reached root and we don't know whether name
+                // changed between from and to
+                unchanged = false;
+            } else {
+                // recurse down
+                unchanged = isChildUnchanged(from, to,
+                        getParentPath(parent), getName(parent));
+            }
+        } else {
+            unchanged = parseJsopDiff(parentCachedEntry.asString(), new Diff() {
+                @Override
+                public boolean childNodeAdded(String n) {
+                    return !name.equals(n);
+                }
+
+                @Override
+                public boolean childNodeChanged(String n) {
+                    return !name.equals(n);
+                }
+
+                @Override
+                public boolean childNodeDeleted(String n) {
+                    return !name.equals(n);
+                }
+            });
+        }
+        return unchanged;
+    }
 }

Modified: jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/TieredDiffCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/TieredDiffCache.java?rev=1717683&r1=1717682&r2=1717683&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/TieredDiffCache.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/TieredDiffCache.java Wed Dec  2 21:25:02 2015
@@ -27,7 +27,7 @@ import org.apache.jackrabbit.oak.cache.C
  * Implements a tiered diff cache which consists of a {@link LocalDiffCache} and
  * a {@link MemoryDiffCache}.
  */
-class TieredDiffCache implements DiffCache {
+class TieredDiffCache extends DiffCache {
 
     private final DiffCache localCache;
     private final DiffCache memoryCache;

Modified: jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AmnesiaDiffCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AmnesiaDiffCache.java?rev=1717683&r1=1717682&r2=1717683&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AmnesiaDiffCache.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AmnesiaDiffCache.java Wed Dec  2 21:25:02 2015
@@ -26,7 +26,7 @@ import org.apache.jackrabbit.oak.cache.C
 /**
  * A diff cache implementation, which immediately forgets the diff.
  */
-class AmnesiaDiffCache implements DiffCache {
+class AmnesiaDiffCache extends DiffCache {
 
     static final DiffCache INSTANCE = new AmnesiaDiffCache();
 

Modified: jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalEntryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalEntryTest.java?rev=1717683&r1=1717682&r2=1717683&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalEntryTest.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalEntryTest.java Wed Dec  2 21:25:02 2015
@@ -21,6 +21,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Random;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
@@ -34,7 +35,9 @@ import org.junit.Test;
 
 import static org.apache.jackrabbit.oak.plugins.document.Collection.JOURNAL;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -65,6 +68,46 @@ public class JournalEntryTest {
         sort.close();
     }
 
+    //OAK-3494
+    @Test
+    public void useParentDiff() throws Exception {
+        DiffCache cache = new MemoryDiffCache(new DocumentMK.Builder());
+        Revision from = new Revision(1, 0, 1);
+        Revision to = new Revision(2, 0, 1);
+        Revision unjournalled = new Revision(3, 0, 1);
+
+        //Put one entry for (from, to, "/a/b")->["c1", "c2"] manually
+        DiffCache.Entry entry = cache.newEntry(from, to, false);
+        entry.append("/a/b", "^\"c1\":{}^\"c2\":{}");
+        entry.done();
+
+        //NOTE: calling validateCacheUsage fills the cache with an empty diff for the path being validated.
+        //So, we need to make sure that each validation is done on a separate path.
+
+        //Cases that cache can answer (only c1 and c2 sub-trees are possibly changed)
+        validateCacheUsage(cache, from, to, "/a/b/c3", true);
+        validateCacheUsage(cache, from, to, "/a/b/c4/e/f/g", true);
+
+        //Cases that cache can't answer
+        validateCacheUsage(cache, from, to, "/a/b/c1", false); //cached entry says that c1 sub-tree is changed
+        validateCacheUsage(cache, from, to, "/a/b/c2/d", false); //cached entry says that c2 sub-tree is changed
+        validateCacheUsage(cache, from, to, "/c", false);//there is no cache entry for the whole hierarchy
+
+        //Fill cache using journal
+        List<String> paths = Lists.newArrayList("/content/changed", "/content/changed1/child1");
+        StringSort sort = JournalEntry.newSorter();
+        add(sort, paths);
+        sort.sort();
+        JournalEntry.applyTo(sort, cache, from, to);
+
+        validateCacheUsage(cache, from, to, "/topUnchanged", true);
+        validateCacheUsage(cache, from, to, "/content/changed/unchangedLeaf", true);
+        validateCacheUsage(cache, from, to, "/content/changed1/child2", true);
+
+        //check against an unjournalled revision (essentially empty cache)
+        validateCacheUsage(cache, from, unjournalled, "/unjournalledPath", false);
+    }
+
     @Test
     public void fillExternalChanges() throws Exception {
         DocumentStore store = new MemoryDocumentStore();
@@ -146,4 +189,24 @@ public class JournalEntryTest {
             }
         }
     }
+
+    private void validateCacheUsage(DiffCache cache, Revision from, Revision to, String path, boolean cacheExpected) {
+        String nonLoaderDiff = cache.getChanges(from, to, path, null);
+        final AtomicBoolean loaderCalled = new AtomicBoolean(false);
+        cache.getChanges(from, to, path, new DiffCache.Loader() {
+            @Override
+            public String call() {
+                loaderCalled.set(true);
+                return "";
+            }
+        });
+
+        if (cacheExpected) {
+            assertNotNull(nonLoaderDiff);
+            assertFalse(loaderCalled.get());
+        } else {
+            assertNull(nonLoaderDiff);
+            assertTrue(loaderCalled.get());
+        }
+    }
 }

Modified: jackrabbit/oak/branches/1.2/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/random/RandomOpCompare.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/random/RandomOpCompare.java?rev=1717683&r1=1717682&r2=1717683&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/random/RandomOpCompare.java (original)
+++ jackrabbit/oak/branches/1.2/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/random/RandomOpCompare.java Wed Dec  2 21:25:02 2015
@@ -142,7 +142,7 @@ public class RandomOpCompare {
                 DB mongoDB = connection.getDB();                
                 return new DocumentMK.Builder().
                             memoryCacheSize(0).
-                            setMongoDB(mongoDB, 1, 16).
+                            setMongoDB(mongoDB, 16).
                             setPersistentCache("target/persistentCache,time").
                             getNodeStore();
             }