Author: markt Date: Wed Oct 3 10:00:21 2012 New Revision: 1393381 URL: http://svn.apache.org/viewvc?rev=1393381&view=rev Log: Implement cache expiry during getResource()
Modified: tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/Cache.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=1393381&r1=1393380&r2=1393381&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 Wed Oct 3 10:00:21 2012 @@ -38,7 +38,8 @@ public class Cache { // based on profiler data. private static final long CACHE_ENTRY_SIZE = 500; - private static final long TARGET_FREE_PERCENT = 5; + private static final long TARGET_FREE_PERCENT_GET = 5; + private static final long TARGET_FREE_PERCENT_BACKGROUND = 10; private final StandardRoot root; private final AtomicLong size = new AtomicLong(0); @@ -83,7 +84,20 @@ public class Cache { size.addAndGet(delta); if (size.get() > maxSize) { - // TODO make room + // Process resources unordered for speed. Trades cache + // efficiency (younger entries may be evicted before older + // ones) for speed since this is on the critical path for + // request processing + long targetSize = + maxSize * (100 - TARGET_FREE_PERCENT_GET) / 100; + long newSize = evict( + targetSize, resourceCache.values().iterator()); + if (newSize > maxSize) { + // Unable to create sufficient space for this resource + // Remove it from the cache + removeCacheEntry(path); + log.warn(sm.getString("cache.addFail")); + } } } else { // Another thread added the entry to the cache @@ -96,19 +110,34 @@ public class Cache { } protected void backgroundProcess() { - long targetSize = maxSize * (100 - TARGET_FREE_PERCENT) / 100; - - long now = System.currentTimeMillis(); - // Create an ordered set of all cached resources with the least recently - // used first. + // used first. This is a background process so we can afford to take the + // time to order the elements first TreeSet<CachedResource> orderedResources = new TreeSet<>(new EvictionOrder()); orderedResources.addAll(resourceCache.values()); Iterator<CachedResource> iter = orderedResources.iterator(); - while (targetSize > size.get() && iter.hasNext()) { + long targetSize = + maxSize * (100 - TARGET_FREE_PERCENT_BACKGROUND) / 100; + long newSize = evict(targetSize, iter); + + if (targetSize > newSize) { + log.info(sm.getString("cache.backgroundEvictFail", + Long.valueOf(TARGET_FREE_PERCENT_BACKGROUND), + root.getContext().getName(), + Long.valueOf(newSize / 1024))); + } + } + + private long evict(long targetSize, Iterator<CachedResource> iter) { + + long now = System.currentTimeMillis(); + + long newSize = size.get(); + + while (targetSize > newSize && iter.hasNext()) { CachedResource resource = iter.next(); // Don't expire anything that has been checked within the TTL @@ -118,15 +147,11 @@ public class Cache { // 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))); + newSize = size.get(); } + + return newSize; } private void removeCacheEntry(String path) { 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=1393381&r1=1393380&r2=1393381&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 Wed Oct 3 10:00:21 2012 @@ -16,7 +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. +cache.addFail=Unable to add the resource at [{0}] to the cache because there was insufficient free space available after evicting expired cache entries - consider increasing the maximum size of the cache +cache.backgroundEvictFail=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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org