|
What this is
Other links
The source code
/*
* $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/PrefixMapper.java,v 1.12 2004/02/25 07:47:50 billbarker Exp $
* $Revision: 1.12 $
* $Date: 2004/02/25 07:47:50 $
*
*
* Copyright 1999-2004 The Apache Sofware Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.tomcat.util;
import java.util.Enumeration;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.collections.SimpleHashtable;
import org.apache.tomcat.util.io.FileUtil;
/** Prefix and exact mapping alghoritm.
*XXX finish factoring out the creation of the map ( right now direct field access is
* used, since the code was just cut out from SimpleMapper).
* XXX make sure the code is useable as a general path mapper - or at least a bridge
* can be created between SimpleMapper and a patern matcher like the one in XPath
*
* @author costin@costin.dnt.ro
*/
public class PrefixMapper {
// host -> PrefixMapper for virtual hosts
// hosts are stored in lower case ( the "common" case )
SimpleHashtable vhostMaps=new SimpleHashtable();
SimpleHashtable prefixMappedServlets;
SimpleHashtable exactMappedServlets;
// Cache the most recent mappings
// Disabled by default ( since we haven't implemented
// capacity and remove ).
SimpleHashtable mapCache;
// By using TreeMap instead of SimpleMap you go from 143 to 161 RPS
// ( at least on my machine )
// Interesting - even if SimpleHashtable is faster than Hashtable
// most of the time, the average is very close for both - it seems
// that while the synchronization in Hashtable is locking, GC have
// a chance to work, while in SimpleHashtable case GC creates big
// peeks. That will go away with more reuse, so we should use SH.
// An alternative to explore after everything works is to use specialized
// mappers ( extending this one for example ) using 1.2 collections
// TreeMap mapCache;
boolean mapCacheEnabled=false;
public PrefixMapper() {
prefixMappedServlets=new SimpleHashtable();
exactMappedServlets=new SimpleHashtable();
mapCache=new SimpleHashtable();
}
public void setMapCache( boolean v ) {
mapCacheEnabled=v;
}
/** Remove all mappings matching path
*/
public void removeAllMappings( String host, String path ) {
PrefixMapper vmap=this;
if( host!=null ) {
host=host.toLowerCase();
vmap=(PrefixMapper)vhostMaps.get(host);
}
// remove all paths starting with path
Enumeration en=vmap.prefixMappedServlets.keys();
while( en.hasMoreElements() ) {
String s=(String)en.nextElement();
if( s.startsWith( path ))
vmap.prefixMappedServlets.remove( s );
}
en=vmap.exactMappedServlets.keys();
while( en.hasMoreElements() ) {
String s=(String)en.nextElement();
if( s.startsWith( path ))
vmap.exactMappedServlets.remove( s );
}
// reset the cache
mapCache=new SimpleHashtable();
}
/**
*/
void addMapping( String path, Object target ) {
prefixMappedServlets.put( path, target);
}
/**
*/
void addExactMapping( String path, Object target ) {
exactMappedServlets.put( path, target);
}
/**
*/
public void addMapping( String host, String path, Object target ) {
if( host == null )
prefixMappedServlets.put( path, target);
else {
host=host.toLowerCase();
PrefixMapper vmap=(PrefixMapper)vhostMaps.get( host );
if( vmap == null ) {
vmap=new PrefixMapper();
vhostMaps.put( host, vmap );
vmap.setMapCache( mapCacheEnabled );
}
vmap.addMapping( path, target );
}
}
/**
*/
public void addExactMapping( String host, String path, Object target ) {
if( host==null )
exactMappedServlets.put( path, target);
else {
host=host.toLowerCase();
PrefixMapper vmap=(PrefixMapper)vhostMaps.get( host );
if( vmap == null ) {
vmap=new PrefixMapper();
vhostMaps.put( host, vmap );
}
vmap.addExactMapping( path, target );
}
}
// -------------------- Implementation --------------------
/** Match a prefix rule - /foo/bar/index.html/abc
*/
public Object getLongestPrefixMatch( MessageBytes hostMB,
MessageBytes pathMB )
{
// XXX fixme
String host=hostMB.toString();
String path=pathMB.toString();
Object container = null;
String s = path;
PrefixMapper myMap=null;
if( host!=null ) {
myMap=(PrefixMapper)vhostMaps.get( host );
if( myMap==null ) {
myMap=(PrefixMapper)vhostMaps.get( host.toLowerCase() );
}
}
if( myMap==null ) myMap = this; // default server
container=myMap.exactMappedServlets.get( path );
if( container != null ) return container; // and we're done!
/** Cache for request results - exploit the fact that few
* request are more "popular" than other.
* Disable it if you want to benchmark the mapper !!!
*/
if( myMap.mapCacheEnabled ) {
container=myMap.mapCache.get(path);
if( container!=null ) return container;
}
while (s.length() >= 0) {
//if(debug>8) context.log( "Prefix: " + s );
container = myMap.prefixMappedServlets.get(s);
if (container == null) {
// if empty string didn't map, time to give up
if ( s.length() == 0 )
break;
s=FileUtil.removeLast( s );
} else {
if( myMap.mapCacheEnabled ) {
// XXX implement LRU or another replacement alghoritm
myMap.mapCache.put( path, container );
}
return container;
}
}
return container;
}
}
|
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.