You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2012/10/02 12:50:53 UTC

svn commit: r1392832 - in /tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources: Cache.java CachedResource.java LocalStrings.properties

Author: markt
Date: Tue Oct  2 10:50:52 2012
New Revision: 1392832

URL: http://svn.apache.org/viewvc?rev=1392832&view=rev
Log:
Implement the background cache expiry

Modified:
    tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/Cache.java
    tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/CachedResource.java
    tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/LocalStrings.properties

Modified: tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/Cache.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/Cache.java?rev=1392832&r1=1392831&r2=1392832&view=diff
==============================================================================
--- tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/Cache.java (original)
+++ tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/Cache.java Tue Oct  2 10:50:52 2012
@@ -16,14 +16,24 @@
  */
 package org.apache.catalina.webresources;
 
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.catalina.WebResource;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.res.StringManager;
 
 public class Cache {
 
+    private static final Log log = LogFactory.getLog(Cache.class);
+    protected static final StringManager sm =
+            StringManager.getManager(Constants.Package);
+
     // Estimate (on high side to be safe) of average size excluding content
     // based on profiler data.
     private static final long CACHE_ENTRY_SIZE = 500;
@@ -44,6 +54,9 @@ public class Cache {
     }
 
     protected WebResource getResource(String path) {
+
+        // TODO Should some resources be excluded from caching?
+
         CachedResource cacheEntry = resourceCache.get(path);
 
         if (cacheEntry != null && !cacheEntry.validate()) {
@@ -85,8 +98,34 @@ public class Cache {
     protected void backgroundProcess() {
         long targetSize = maxSize * (100 - TARGET_FREE_PERCENT) / 100;
 
-        while (targetSize > size.get()) {
-            // TODO ID resources to remove
+        long now = System.currentTimeMillis();
+
+        // Create an ordered set of all cached resources with the least recently
+        // used first.
+        TreeSet<CachedResource> orderedResources =
+                new TreeSet<>(new EvictionOrder());
+        orderedResources.addAll(resourceCache.values());
+
+        Iterator<CachedResource> iter = orderedResources.iterator();
+
+        while (targetSize > size.get() && iter.hasNext()) {
+            CachedResource resource = iter.next();
+
+            // Don't expire anything that has been checked within the TTL
+            if (resource.getNextCheck() > now) {
+                continue;
+            }
+
+            // Remove the entry from the cache
+            removeCacheEntry(resource.getWebappPath());
+        }
+
+        long cacheSize = size.get();
+        if (targetSize > cacheSize) {
+            log.info(sm.getString("cache.backgroundEvict",
+                    Long.valueOf(TARGET_FREE_PERCENT),
+                    root.getContext().getName(),
+                    Long.valueOf(cacheSize / 1024)));
         }
     }
 
@@ -116,4 +155,23 @@ public class Cache {
     public void setMaxSize(long maxSize) {
         this.maxSize = maxSize;
     }
+
+    private static class EvictionOrder implements Comparator<CachedResource> {
+
+        @Override
+        public int compare(CachedResource cr1, CachedResource cr2) {
+            long nc1 = cr1.getNextCheck();
+            long nc2 = cr2.getNextCheck();
+
+            // Oldest resource should be first (so iterator goes from oldest to
+            // youngest.
+            if (nc1 == nc2) {
+                return 0;
+            } else if (nc1 > nc2) {
+                return -1;
+            } else {
+                return 1;
+            }
+        }
+    }
 }

Modified: tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/CachedResource.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/CachedResource.java?rev=1392832&r1=1392831&r2=1392832&view=diff
==============================================================================
--- tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/CachedResource.java (original)
+++ tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/CachedResource.java Tue Oct  2 10:50:52 2012
@@ -82,6 +82,9 @@ public class CachedResource implements W
         return true;
     }
 
+    protected long getNextCheck() {
+        return nextCheck;
+    }
 
     @Override
     public long getLastModified() {

Modified: tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/LocalStrings.properties?rev=1392832&r1=1392831&r2=1392832&view=diff
==============================================================================
--- tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/LocalStrings.properties (original)
+++ tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/LocalStrings.properties Tue Oct  2 10:50:52 2012
@@ -16,6 +16,8 @@
 abstractResource.getContentFail=Unable to return [{0}] as a byte array
 abstractResource.getContentTooLarge=Unable to return [{0}] as a byte array since the resource is [{1}] bytes in size which is larger than the maximum size of a byte array
 
+cache.backgroundEvict=The background cache eviction process was unable to free [{0}] percent of the cache for Context [{1}] - consider increasing the maximum size of the cache. After eviction approximately [{2}] KB of data remained in the cache.
+
 dirResourceSet.writeExists=The target of the write already exists
 dirResourceSet.writeNpe=The input stream may not be null
 



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org