Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Wilkins2010-10-19 01:47:00 +0000
committerGreg Wilkins2010-10-19 01:47:00 +0000
commitce026a4f118f30161d0f648ee4d1ae959c7e048a (patch)
tree15efeb9e26333cea5f9ba099a58043158626b863
parentbda68489b9acd28e535a3cd1847be993ba6cff4b (diff)
downloadorg.eclipse.jetty.project-ce026a4f118f30161d0f648ee4d1ae959c7e048a.tar.gz
org.eclipse.jetty.project-ce026a4f118f30161d0f648ee4d1ae959c7e048a.tar.xz
org.eclipse.jetty.project-ce026a4f118f30161d0f648ee4d1ae959c7e048a.zip
JETTY-1289 LRU cache for filter chains
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@2362 7e9141cc-0065-0410-87d8-b60c137991c4
-rw-r--r--VERSION.txt1
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java76
2 files changed, 67 insertions, 10 deletions
diff --git a/VERSION.txt b/VERSION.txt
index c92f5ab017..05da1d1d93 100644
--- a/VERSION.txt
+++ b/VERSION.txt
@@ -11,6 +11,7 @@ jetty-7.2.0.RC1 15 October 2010
+ 327601 Multipart Filter handles quoted tokens
+ 327725 Nested ResourceCaches
+ JETTY-1288 Info statement when atypical classloader set on WebAppContext
+ + JETTY-1289 LRU cache for filter chains
jetty-7.2.0.RC0 1 October 2010
+ 314087 Simplified SelectorManager
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
index 1c88fabdad..c73ecc4e79 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
@@ -21,7 +21,10 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentMap;
import org.eclipse.jetty.server.DispatcherType;
import javax.servlet.Filter;
@@ -81,7 +84,7 @@ public class ServletHandler extends ScopedHandler
private FilterHolder[] _filters;
private FilterMapping[] _filterMappings;
private boolean _filterChainsCached=true;
- private int _maxFilterChainsCacheSize=1000;
+ private int _maxFilterChainsCacheSize=512;
private boolean _startWithUnavailable=true;
private IdentityService _identityService;
@@ -95,7 +98,8 @@ public class ServletHandler extends ScopedHandler
private final Map<String,ServletHolder> _servletNameMap=new HashMap<String,ServletHolder>();
private PathMap _servletPathMap;
- protected ConcurrentHashMap<String,FilterChain> _chainCache[];
+ protected final ConcurrentMap<String,FilterChain> _chainCache[] = new ConcurrentMap[FilterMapping.ALL];
+ protected final Queue<String>[] _chainLRU = new Queue[FilterMapping.ALL];
/* ------------------------------------------------------------ */
@@ -147,7 +151,19 @@ public class ServletHandler extends ScopedHandler
updateMappings();
if(_filterChainsCached)
- _chainCache= new ConcurrentHashMap[]{null,new ConcurrentHashMap(),new ConcurrentHashMap(),null,new ConcurrentHashMap(),null,null,null,new ConcurrentHashMap(),null,null,null,null,null,null,null,new ConcurrentHashMap()};
+ {
+ _chainCache[FilterMapping.REQUEST]=new ConcurrentHashMap<String,FilterChain>();
+ _chainCache[FilterMapping.FORWARD]=new ConcurrentHashMap<String,FilterChain>();
+ _chainCache[FilterMapping.INCLUDE]=new ConcurrentHashMap<String,FilterChain>();
+ _chainCache[FilterMapping.ERROR]=new ConcurrentHashMap<String,FilterChain>();
+ _chainCache[FilterMapping.ASYNC]=new ConcurrentHashMap<String,FilterChain>();
+
+ _chainLRU[FilterMapping.REQUEST]=new ConcurrentLinkedQueue<String>();
+ _chainLRU[FilterMapping.FORWARD]=new ConcurrentLinkedQueue<String>();
+ _chainLRU[FilterMapping.INCLUDE]=new ConcurrentLinkedQueue<String>();
+ _chainLRU[FilterMapping.ERROR]=new ConcurrentLinkedQueue<String>();
+ _chainLRU[FilterMapping.ASYNC]=new ConcurrentLinkedQueue<String>();
+ }
super.doStart();
@@ -184,7 +200,6 @@ public class ServletHandler extends ScopedHandler
_filterNameMappings=null;
_servletPathMap=null;
- _chainCache=null;
}
/* ------------------------------------------------------------ */
@@ -402,7 +417,6 @@ public class ServletHandler extends ScopedHandler
baseRequest.setPathInfo(old_path_info);
}
}
-
}
/* ------------------------------------------------------------ */
@@ -618,20 +632,58 @@ public class ServletHandler extends ScopedHandler
if (filters==null)
return null;
+
FilterChain chain = null;
if (_filterChainsCached)
{
- if (LazyList.size(filters) > 0)
- chain= new CachedChain(filters, servletHolder);
- if (_maxFilterChainsCacheSize>0 && _chainCache[dispatch].size()>_maxFilterChainsCacheSize)
- _chainCache[dispatch].clear();
- _chainCache[dispatch].put(key,chain);
+ if (LazyList.size(filters) > 0)
+ chain= new CachedChain(filters, servletHolder);
+
+ final Map<String,FilterChain> cache=_chainCache[dispatch];
+ final Queue<String> lru=_chainLRU[dispatch];
+
+ // Do we have too many cached chains?
+ while (_maxFilterChainsCacheSize>0 && cache.size()>=_maxFilterChainsCacheSize)
+ {
+ // The LRU list is not atomic with the cache map, so be prepared to invalidate if
+ // a key is not found to delete.
+ // Delete by LRU (where U==created)
+ String k=lru.poll();
+ if (k==null)
+ {
+ cache.clear();
+ break;
+ }
+ cache.remove(k);
+ }
+
+ cache.put(key,chain);
+ lru.add(key);
}
else if (LazyList.size(filters) > 0)
chain = new Chain(baseRequest,filters, servletHolder);
return chain;
}
+
+ /* ------------------------------------------------------------ */
+ private void invalidateChainsCache()
+ {
+ if (_chainLRU[FilterMapping.REQUEST]!=null)
+ {
+ _chainLRU[FilterMapping.REQUEST].clear();
+ _chainLRU[FilterMapping.FORWARD].clear();
+ _chainLRU[FilterMapping.INCLUDE].clear();
+ _chainLRU[FilterMapping.ERROR].clear();
+ _chainLRU[FilterMapping.ASYNC].clear();
+
+ _chainCache[FilterMapping.REQUEST].clear();
+ _chainCache[FilterMapping.FORWARD].clear();
+ _chainCache[FilterMapping.INCLUDE].clear();
+ _chainCache[FilterMapping.ERROR].clear();
+ _chainCache[FilterMapping.ASYNC].clear();
+ }
+ }
/* ------------------------------------------------------------ */
/**
@@ -1195,6 +1247,7 @@ public class ServletHandler extends ScopedHandler
getServer().getContainer().update(this,_filterMappings,filterMappings,"filterMapping",true);
_filterMappings = filterMappings;
updateMappings();
+ invalidateChainsCache();
}
/* ------------------------------------------------------------ */
@@ -1204,6 +1257,7 @@ public class ServletHandler extends ScopedHandler
getServer().getContainer().update(this,_filters,holders,"filter",true);
_filters=holders;
updateNameMappings();
+ invalidateChainsCache();
}
/* ------------------------------------------------------------ */
@@ -1216,6 +1270,7 @@ public class ServletHandler extends ScopedHandler
getServer().getContainer().update(this,_servletMappings,servletMappings,"servletMapping",true);
_servletMappings = servletMappings;
updateMappings();
+ invalidateChainsCache();
}
/* ------------------------------------------------------------ */
@@ -1228,6 +1283,7 @@ public class ServletHandler extends ScopedHandler
getServer().getContainer().update(this,_servlets,holders,"servlet",true);
_servlets=holders;
updateNameMappings();
+ invalidateChainsCache();
}

Back to the top