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
This commit is contained in:
Greg Wilkins 2010-10-19 01:47:00 +00:00
parent bda68489b9
commit ce026a4f11
2 changed files with 67 additions and 10 deletions

View File

@ -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

View File

@ -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,14 +632,33 @@ 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);
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);
@ -633,6 +666,25 @@ public class ServletHandler extends ScopedHandler
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();
}
}
/* ------------------------------------------------------------ */
/**
* @return true if the handler is started and there are no unavailable servlets
@ -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();
}