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 re...@apache.org on 2015/03/10 18:47:42 UTC

svn commit: r1665634 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java

Author: reschke
Date: Tue Mar 10 17:47:41 2015
New Revision: 1665634

URL: http://svn.apache.org/r1665634
Log:
OAK-2582 - when invalidating the cache, just set the entry as "to be revalidated"

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java?rev=1665634&r1=1665633&r2=1665634&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java Tue Mar 10 17:47:41 2015
@@ -230,13 +230,13 @@ public class RDBDocumentStore implements
     @Override
     public <T extends Document> void remove(Collection<T> collection, String id) {
         delete(collection, id);
-        invalidateCache(collection, id);
+        invalidateCache(collection, id, true);
     }
 
     @Override
     public <T extends Document> void remove(Collection<T> collection, List<String> ids) {
         for (String id : ids) {
-            invalidateCache(collection, id);
+            invalidateCache(collection, id, true);
         }
         delete(collection, ids);
     }
@@ -263,19 +263,37 @@ public class RDBDocumentStore implements
 
     @Override
     public CacheInvalidationStats invalidateCache() {
-        nodesCache.invalidateAll();
+        for (NodeDocument nd : nodesCache.asMap().values()) {
+            nd.markUpToDate(0);
+        }
         return null;
     }
 
     @Override
     public <T extends Document> void invalidateCache(Collection<T> collection, String id) {
+        invalidateCache(collection, id, false);
+    }
+
+    private <T extends Document> void invalidateCache(Collection<T> collection, String id, boolean remove) {
         if (collection == Collection.NODES) {
-            Lock lock = getAndLock(id);
-            try {
-                nodesCache.invalidate(new StringValue(id));
-            } finally {
-                lock.unlock();
+            invalidateNodesCache(id, remove);
+        }
+    }
+
+    private void invalidateNodesCache(String id, boolean remove) {
+        StringValue key = new StringValue(id);
+        Lock lock = getAndLock(id);
+        try {
+            if (remove) {
+                nodesCache.invalidate(key);
+            } else {
+                NodeDocument entry = nodesCache.getIfPresent(key);
+                if (entry != null) {
+                    entry.markUpToDate(0);
+                }
             }
+        } finally {
+            lock.unlock();
         }
     }
 
@@ -680,37 +698,48 @@ public class RDBDocumentStore implements
                 // first try without lock
                 doc = nodesCache.getIfPresent(cacheKey);
                 if (doc != null) {
-                    if (maxCacheAge == Integer.MAX_VALUE || System.currentTimeMillis() - doc.getLastCheckTime() < maxCacheAge) {
-                        return castAsT(unwrap(doc));
+                    long lastCheckTime = doc.getLastCheckTime();
+                    if (lastCheckTime != 0) {
+                        if (maxCacheAge == Integer.MAX_VALUE || System.currentTimeMillis() - lastCheckTime < maxCacheAge) {
+                            return castAsT(unwrap(doc));
+                        }
                     }
                 }
             }
             try {
                 Lock lock = getAndLock(id);
-                final NodeDocument cachedDoc = doc;
                 try {
+                    // caller really wants the cache to be cleared
                     if (maxCacheAge == 0) {
-                        invalidateCache(collection, id);
+                        invalidateNodesCache(id, true);
+                        doc = null;
                     }
-                    while (true) {
-                        doc = nodesCache.get(cacheKey, new Callable<NodeDocument>() {
-                            @Override
-                            public NodeDocument call() throws Exception {
-                                NodeDocument doc = (NodeDocument) readDocumentUncached(collection, id, cachedDoc);
-                                if (doc != null) {
-                                    doc.seal();
-                                }
-                                return wrap(doc);
+                    final NodeDocument cachedDoc = doc;
+                    doc = nodesCache.get(cacheKey, new Callable<NodeDocument>() {
+                        @Override
+                        public NodeDocument call() throws Exception {
+                            NodeDocument doc = (NodeDocument) readDocumentUncached(collection, id, cachedDoc);
+                            if (doc != null) {
+                                doc.seal();
                             }
-                        });
-                        if (maxCacheAge == 0 || maxCacheAge == Integer.MAX_VALUE) {
-                            break;
+                            return wrap(doc);
                         }
-                        if (System.currentTimeMillis() - doc.getLastCheckTime() < maxCacheAge) {
-                            break;
+                    });
+                    // inspect the doc whether it can be used
+                    long lastCheckTime = doc.getLastCheckTime();
+                    if (lastCheckTime != 0 && (maxCacheAge == 0 || maxCacheAge == Integer.MAX_VALUE)) {
+                        // we either just cleared the cache or the caller does
+                        // not care;
+                    } else if (lastCheckTime != 0 && (System.currentTimeMillis() - lastCheckTime < maxCacheAge)) {
+                        // is new enough
+                    } else {
+                        // need to at least revalidate
+                        NodeDocument ndoc = (NodeDocument) readDocumentUncached(collection, id, cachedDoc);
+                        if (ndoc != null) {
+                            ndoc.seal();
                         }
-                        // too old: invalidate, try again
-                        invalidateCache(collection, id);
+                        doc = wrap(ndoc);
+                        nodesCache.put(cacheKey, doc);
                     }
                 } finally {
                     lock.unlock();

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java?rev=1665634&r1=1665633&r2=1665634&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java Tue Mar 10 17:47:41 2015
@@ -561,8 +561,17 @@ public class BasicDocumentStoreTest exte
     }
 
     @Test
-    public void testPerfReadBigDoc() {
-        String id = this.getClass().getName() + ".testReadBigDoc";
+    public void testPerfReadBigDocCached() {
+        perfReadBigDoc(true, this.getClass().getName() + ".testReadBigDocCached");
+    }
+
+    @Test
+    public void testPerfReadBigDocAfterInvalidate() {
+        perfReadBigDoc(false, this.getClass().getName() + ".testReadBigDocAfterInvalidate");
+    }
+
+    private void perfReadBigDoc(boolean cached, String name) {
+        String id = name;
         long duration = 1000;
         int cnt = 0;
 
@@ -577,12 +586,15 @@ public class BasicDocumentStoreTest exte
 
         long end = System.currentTimeMillis() + duration;
         while (System.currentTimeMillis() < end) {
-            NodeDocument d = super.ds.find(Collection.NODES, id, 10); // allow 10ms old entries
+            if (!cached) {
+                super.ds.invalidateCache(Collection.NODES, id);
+            }
+            NodeDocument d = super.ds.find(Collection.NODES, id, 10);
             cnt += 1;
         }
 
-        LOG.info("big doc read from " + super.dsname + " was "
-                + cnt + " in " + duration + "ms (" + (cnt / (duration / 1000f)) + "/s)");
+        LOG.info("big doc read " + (cached ? "" : "(after invalidate) ") + "from " + super.dsname + " was " + cnt + " in "
+                + duration + "ms (" + (cnt / (duration / 1000f)) + "/s)");
     }
 
     @Test