tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ma...@apache.org
Subject svn commit: r1391362 - in /tomcat/sandbox/trunk-resources: java/org/apache/catalina/ java/org/apache/catalina/core/ java/org/apache/catalina/webresources/ test/org/apache/catalina/webresources/
Date Fri, 28 Sep 2012 08:40:38 GMT
Author: markt
Date: Fri Sep 28 08:40:38 2012
New Revision: 1391362

URL: http://svn.apache.org/viewvc?rev=1391362&view=rev
Log:
Further work on the caching implementation
- If a CachedResource fails validation, remove it from the cache and replace it rather than
update it as this makes it much easier to track the current cache size.
- Track the current cache size
- Add configuration for the maximum cache size
- Start implementing (not finished) the background expiration

Modified:
    tomcat/sandbox/trunk-resources/java/org/apache/catalina/WebResourceRoot.java
    tomcat/sandbox/trunk-resources/java/org/apache/catalina/core/StandardContext.java
    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/StandardRoot.java
    tomcat/sandbox/trunk-resources/test/org/apache/catalina/webresources/TesterWebResourceRoot.java

Modified: tomcat/sandbox/trunk-resources/java/org/apache/catalina/WebResourceRoot.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/trunk-resources/java/org/apache/catalina/WebResourceRoot.java?rev=1391362&r1=1391361&r2=1391362&view=diff
==============================================================================
--- tomcat/sandbox/trunk-resources/java/org/apache/catalina/WebResourceRoot.java (original)
+++ tomcat/sandbox/trunk-resources/java/org/apache/catalina/WebResourceRoot.java Fri Sep 28
08:40:38 2012
@@ -255,6 +255,9 @@ public interface WebResourceRoot extends
      */
     long getCacheTtl();
 
+    void setCacheMaxSize(long cacheMaxSize);
+    long getCacheMaxSize();
+
     /**
      * This method will be invoked by the context on a periodic basis and allows
      * the implementation a method that executes periodic tasks, such as purging

Modified: tomcat/sandbox/trunk-resources/java/org/apache/catalina/core/StandardContext.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/trunk-resources/java/org/apache/catalina/core/StandardContext.java?rev=1391362&r1=1391361&r2=1391362&view=diff
==============================================================================
--- tomcat/sandbox/trunk-resources/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/sandbox/trunk-resources/java/org/apache/catalina/core/StandardContext.java Fri
Sep 28 08:40:38 2012
@@ -4773,13 +4773,13 @@ public class StandardContext extends Con
 
         resources.setAllowLinking(isAllowLinking());
 
-        resources.setCacheTtl(getCacheTTL());
         resources.setCachingAllowed(isCachingAllowed());
+        resources.setCacheTtl(getCacheTTL());
+        resources.setCacheMaxSize(getCacheMaxSize());
 
         resources.start();
 
         // TODO: Implement caching.
-        // getCacheMaxSize()
         // getCacheMaxObjectSize()
 
         if (effectiveMajorVersion >=3 && addWebinfClassesResources) {

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=1391362&r1=1391361&r2=1391362&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 Fri Sep
28 08:40:38 2012
@@ -18,14 +18,23 @@ package org.apache.catalina.webresources
 
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.catalina.WebResource;
 
 public class Cache {
 
+    // Estimate (on high side to be safe) of average size excluding content
+    // based on profiler data.
+    private static final long CACHE_ENTRY_SIZE = 500;
+
+    private static final long TARGET_FREE_PERCENT = 5;
+
     private final StandardRoot root;
+    private final AtomicLong size = new AtomicLong(0);
 
     private long ttl = 5000;
+    private long maxSize = 10 * 1024 * 1024;
 
     private ConcurrentMap<String,CachedResource> resourceCache =
             new ConcurrentHashMap<>();
@@ -35,25 +44,61 @@ public class Cache {
     }
 
     protected WebResource getResource(String path) {
-        // Multiple concurrent callers will end up with the same CachedResource
-        // instance
-        CachedResource newCacheEntry = new CachedResource(root, path, ttl);
-        CachedResource result =
-                resourceCache.putIfAbsent(path, newCacheEntry);
+        CachedResource cacheEntry = resourceCache.get(path);
 
-        if (result == null) {
-            result = newCacheEntry;
+        if (cacheEntry != null && !cacheEntry.validate()) {
+            removeCacheEntry(path);
+            cacheEntry = null;
         }
 
-        // TODO check cache size and do minimum necessary to make room
-        // TODO Cache size configuration
-        result.validate();
+        if (cacheEntry == null) {
+            // Concurrent callers will end up with the same CachedResource
+            // instance
+            CachedResource newCacheEntry = new CachedResource(root, path, ttl);
+            cacheEntry = resourceCache.putIfAbsent(path, newCacheEntry);
+
+            if (cacheEntry == null) {
+                // newCacheEntry was inserted into the cache - validate it
+                cacheEntry = newCacheEntry;
+                cacheEntry.validate();
+
+                // Assume that the cache entry will include the content.
+                // This isn't always the case but it makes tracking the
+                // current cache size easier.
+                long delta = CACHE_ENTRY_SIZE;
+                delta += cacheEntry.getContentLength();
+                size.addAndGet(delta);
+
+                if (size.get() > maxSize) {
+                    // TODO make room
+                }
+            } else {
+                // Another thread added the entry to the cache
+                // Make sure it is validated
+                cacheEntry.validate();
+            }
+        }
 
-        return result;
+        return cacheEntry;
     }
 
     protected void backgroundProcess() {
-        // TODO expiration
+        long targetSize = maxSize * (100 - TARGET_FREE_PERCENT) / 100;
+
+        while (targetSize > size.get()) {
+            // TODO ID resources to remove
+        }
+    }
+
+    private void removeCacheEntry(String path) {
+        // With concurrent calls for the same path, the entry is only removed
+        // once and the cache size is only updated once.
+        CachedResource cachedResource = resourceCache.remove(path);
+        if (cachedResource != null) {
+            long delta =
+                    0 - CACHE_ENTRY_SIZE - cachedResource.getContentLength();
+            size.addAndGet(delta);
+        }
     }
 
     public long getTtl() {
@@ -63,4 +108,12 @@ public class Cache {
     public void setTtl(long ttl) {
         this.ttl = ttl;
     }
+
+    public long getMaxSize() {
+        return maxSize;
+    }
+
+    public void setMaxSize(long maxSize) {
+        this.maxSize = maxSize;
+    }
 }

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=1391362&r1=1391361&r2=1391362&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
Fri Sep 28 08:40:38 2012
@@ -52,43 +52,34 @@ public class CachedResource implements W
         this.ttl = ttl;
     }
 
-    protected void validate() {
+    protected boolean validate() {
         long now = System.currentTimeMillis();
 
         if (webResource == null) {
             synchronized (this) {
                 if (webResource == null) {
-                    WebResource result = root.getResourceInternal(webAppPath);
-                    webResource = result;
+                    webResource = root.getResourceInternal(webAppPath);
+                    getLastModified();
+                    getContentLength();
                     nextCheck = ttl + now;
-                    return;
+                    return true;
                 }
             }
         }
 
         if (now < nextCheck) {
-            return;
+            return true;
         }
 
-        synchronized (this) {
-            if (now < nextCheck) {
-                return;
-            }
-
-            if (webResource.getLastModified() + ttl >= nextCheck) {
-                WebResource result = root.getResourceInternal(webAppPath);
-                webResource = result;
-
-                cachedContent = null;
-                cachedContentLength = null;
-                cachedExists = null;
-                cachedIsDirectory = null;
-                cachedIsFile = null;
-                cachedLastModified = null;
-                cachedLastModifiedHttp = null;
-            }
-            nextCheck = ttl + now;
+        // If modified date or length change - resource has changed / been
+        // removed etc.
+        if (webResource.getLastModified() != getLastModified() ||
+                webResource.getContentLength() != getContentLength()) {
+            return false;
         }
+
+        nextCheck = ttl + now;
+        return true;
     }
 
 

Modified: tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/StandardRoot.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/StandardRoot.java?rev=1391362&r1=1391361&r2=1391362&view=diff
==============================================================================
--- tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/StandardRoot.java
(original)
+++ tomcat/sandbox/trunk-resources/java/org/apache/catalina/webresources/StandardRoot.java
Fri Sep 28 08:40:38 2012
@@ -321,6 +321,16 @@ public class StandardRoot extends Lifecy
     }
 
     @Override
+    public long getCacheMaxSize() {
+        return cache.getMaxSize();
+    }
+
+    @Override
+    public void setCacheMaxSize(long cacheMaxSize) {
+        cache.setMaxSize(cacheMaxSize);
+    }
+
+    @Override
     public Context getContext() {
         return context;
     }

Modified: tomcat/sandbox/trunk-resources/test/org/apache/catalina/webresources/TesterWebResourceRoot.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/trunk-resources/test/org/apache/catalina/webresources/TesterWebResourceRoot.java?rev=1391362&r1=1391361&r2=1391362&view=diff
==============================================================================
--- tomcat/sandbox/trunk-resources/test/org/apache/catalina/webresources/TesterWebResourceRoot.java
(original)
+++ tomcat/sandbox/trunk-resources/test/org/apache/catalina/webresources/TesterWebResourceRoot.java
Fri Sep 28 08:40:38 2012
@@ -167,6 +167,16 @@ public class TesterWebResourceRoot imple
     }
 
     @Override
+    public void setCacheMaxSize(long cacheMaxSize) {
+        // NO-OP
+    }
+
+    @Override
+    public long getCacheMaxSize() {
+        return 0;
+    }
+
+    @Override
     public void addPreResources(WebResourceSet webResourceSet) {
         // NO-OP
     }



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


Mime
View raw message