costin      01/06/07 20:08:26

  Modified:    src/share/org/apache/tomcat/modules/mappers
                        SimpleMapper1.java
  Log:
  Added PrefixMapper as an internal class, it is very specific to
  SimpleMapper ( and not used in other modules ). It is also ugly and
  quite slow, so we'll need a new mapper ( now that many things are tuned
  we can see smaller spots ). In any case PrefixMapper doesn't deserve to
  be in tomcat_util.jar.
  
  Revision  Changes    Path
  1.4       +180 -1    
jakarta-tomcat/src/share/org/apache/tomcat/modules/mappers/SimpleMapper1.java
  
  Index: SimpleMapper1.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/mappers/SimpleMapper1.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SimpleMapper1.java        2001/05/26 17:54:50     1.3
  +++ SimpleMapper1.java        2001/06/08 03:08:23     1.4
  @@ -62,7 +62,7 @@
   import org.apache.tomcat.core.*;
   import org.apache.tomcat.util.buf.MessageBytes;
   import org.apache.tomcat.util.io.FileUtil;
  -import org.apache.tomcat.util.PrefixMapper;
  +//import org.apache.tomcat.util.PrefixMapper;
   import org.apache.tomcat.util.collections.*;
   import java.util.*;
   
  @@ -425,3 +425,182 @@
       
   }
   
  +
  +/** 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 [EMAIL PROTECTED]
  + */
  +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;
  +    }
  +
  +}
  +
  + 
  
  
  

Reply via email to