commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bali...@apache.org
Subject cvs commit: jakarta-commons-sandbox/dbutils/src/java/org/apache/commons/dbutils ProcedureUtils.java
Date Fri, 14 Mar 2003 19:53:43 GMT
baliuka     2003/03/14 11:53:43

  Modified:    dbutils/src/java/org/apache/commons/dbutils
                        ProcedureUtils.java
  Log:
  added trivial cache
  
  Revision  Changes    Path
  1.9       +194 -5    jakarta-commons-sandbox/dbutils/src/java/org/apache/commons/dbutils/ProcedureUtils.java
  
  Index: ProcedureUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/dbutils/src/java/org/apache/commons/dbutils/ProcedureUtils.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ProcedureUtils.java	14 Mar 2003 17:27:33 -0000	1.8
  +++ ProcedureUtils.java	14 Mar 2003 19:53:43 -0000	1.9
  @@ -59,10 +59,15 @@
   
   import java.util.*;
   import java.lang.reflect.*;
  +import java.lang.ref.*;
   import java.sql.*;
   import java.io.*;
   import java.text.MessageFormat;
   
  +
  +
  +
  +
   import com.thoughtworks.qdox.JavaDocBuilder;
   import com.thoughtworks.qdox.model.*;
   
  @@ -75,8 +80,11 @@
       private static final Map PROCEDURES = new HashMap();
       private static final Map PREDEFINED_HANDLERS = new HashMap();
       private static final ResultSetHandler SCALAR_HANDLER = new ScalarHandler();
  +    private static final SoftRefMemoryCache CACHE = new SoftRefMemoryCache();
       private static final String UPDATE_TAG = "update";
       private static final String QUERY_TAG = "query";
  +    private static final String CACHE_TAG = "useCache";
  +    private static final String FLUSH_TAG = "flushCache";
       
       
       static class ProcedureDescriptor{
  @@ -153,7 +161,7 @@
       }
       
       static ProcedureDescriptor compile(Method proc, String sqlStr,
  -    ResultSetHandler handler, boolean update){
  +    ResultSetHandler handler, boolean update, boolean cache, boolean flush){
           
           StringBuffer sb = new StringBuffer();
           List indexes = parseSQL( sqlStr, sb );
  @@ -189,6 +197,8 @@
           descriptor.handler = handler;
           descriptor.jdbcSQL = sb.toString();
           descriptor.update  = update;
  +        descriptor.cached = cache;
  +        descriptor.flushOnExecute = flush;
           
           return descriptor;
       }
  @@ -335,7 +345,11 @@
               }
               
               desctiptors.put( method,
  -            compile(  method, sql, handler, update  ));
  +            compile(  method, sql, handler, update, 
  +            jmethods[i].getTagByName(CACHE_TAG) != null,
  +            jmethods[i].getTagByName(FLUSH_TAG) != null
  +              )
  +            );
           }
           
           return desctiptors;
  @@ -366,6 +380,53 @@
           
       }
       
  +    static class CacheKey{
  +     Method method;
  +     Object[] args;   
  +     int hash ;
  +     
  +      CacheKey( Method method, Object[] args ){
  +       this.method = method;
  +       this.args   = args;
  +       hash = method.hashCode();
  +       for(int i=0; i< args.length; i++){
  +         hash += 3*(args[i] == null ? 0 : args[i].hashCode());
  +       }
  +       
  +      }
  +      
  +    public int hashCode(){
  +        return hash;
  +     }
  +    public boolean equals( Object obj ){
  +        if(obj != null && ( obj instanceof  CacheKey)){
  +            
  +            CacheKey key = (CacheKey)obj;
  +            if(key.method == method || key.method.equals(method)){
  +                
  +              for( int i = 0; i < args.length; i++ ){
  +                 if( args[i] == key.args[i] ){
  +                      continue;
  +                 }
  +                 if( args[i] == null || key.args[i] == null || 
  +                             !args[i].equals(key.args[i]) ){
  +                   return false;
  +                 }
  +              }
  +              return true;
  +               
  +            }else{
  +                return false;
  +            }
  +        
  +        }else{
  +           return false;
  +        }
  +     }
  +      
  +      
  +    }
  +    
       static class Invocation implements InvocationHandler{
           
           Connection connection;
  @@ -403,18 +464,33 @@
                   }
                   
                   if(!descriptor.update){
  -                    return convert( method.getReturnType(), DbUtils.executeQuery(  connection,
  +                    CacheKey key = null;
  +                    Object value = null;
  +                    if(descriptor.cached){
  +                      key = new CacheKey(method,args);
  +                      value = CACHE.get(key);
  +                      if( value != null ){
  +                         return value;
  +                      }
  +                    } 
  +                    value = convert( method.getReturnType(), DbUtils.executeQuery(  connection,
                       descriptor.dynamic ? MessageFormat.format(descriptor.jdbcSQL,args)
: descriptor.jdbcSQL,
                       prepareArgs(descriptor,args),
                       descriptor.handler,
  -                    args
  +                    null,args
                       ));
  +                   if(descriptor.cached || value != null){
  +                     CACHE.put(key,value);
  +                   } 
  +                   return value; 
                   }else{
                       int updateCount = DbUtils.executeUpdate(  connection,
                       descriptor.dynamic ? MessageFormat.format(descriptor.jdbcSQL,args)
: descriptor.jdbcSQL,
                       prepareArgs(descriptor,args)
                       );
  -                    
  +                    if(descriptor.flushOnExecute){
  +                      CACHE.clear();
  +                    }
                       if(method.getReturnType() == Void.TYPE ){
                           return null;
                       }else {
  @@ -442,4 +518,117 @@
           
       }
       
  +}
  +
  +/**
  + *@author     Juozas Baliuka <a href="mailto:baliuka@mwm.lt">
  + *      baliuka@mwm.lt</a>
  + *@author     Gerhard Froehlich <a href="mailto:g-froehlich@gmx.de">
  + *      g-froehlich@gmx.de</a>
  + *@version    $Id$
  + */
  +final class SoftRefMemoryCache {
  +
  +    
  +
  +    private int m_current = 0;
  +    private int m_maxStrongRefCount;
  +    private Map m_map = new Hashtable();
  +    private Object[] m_strongRefs;
  +    private ReferenceQueue m_queue = new ReferenceQueue();
  +    
  +    SoftRefMemoryCache(){
  +      this(256);
  +    }
  +
  +    /**
  +     * Creates new SoftRefMemoryCache
  +     *
  +     *@param  map
  +     *@param  maxStrongRefCount
  +     */
  +     SoftRefMemoryCache( int maxStrongRefCount) {
  +
  +        if (maxStrongRefCount < 0) {
  +            throw new java.lang.IllegalArgumentException();
  +        }
  +        this.m_maxStrongRefCount = maxStrongRefCount;
  +
  +        if (maxStrongRefCount > 0) {
  +            m_strongRefs = new Object[maxStrongRefCount];
  +        }
  +    }
  +
  +
  +    /**
  +     * Get the object associated to the given unique key.
  +     *
  +     *@param  key  the Key Object
  +     *@return      requested object or null
  +     */
  +     Object get(Object key) {
  +        removeSoftRef();
  +        Object object = null;
  +        SoftRef ref = (SoftRef) m_map.get(key);
  +
  +        if (ref != null) {
  +            object = ref.get();
  +        }
  +
  +        addStrongRef(object);
  +        return object;
  +    }
  +
  +    /**
  +     * Cache the object associated to the given unique key.
  +     *
  +     *@param  key     the key object
  +     *@param  object
  +     */
  +     void put(Object key, Object object) {
  +        removeSoftRef();
  +        internalStoreObject(key, object);
  +    }
  +
  +    void clear(){
  +       m_map.clear();
  +       if(m_strongRefs != null){
  +         Arrays.fill(m_strongRefs, null);
  +       }
  +    } 
  +    
  +    private SoftRef makeValue(Object key, Object value, ReferenceQueue queue) {
  +        return new SoftRef(key, value, queue);
  +    }
  +
  +    // remove unused keys
  +    private void removeSoftRef() {
  +        SoftRef ref = (SoftRef) m_queue.poll();
  +
  +        while (ref != null) {
  +            m_map.remove(ref.key);
  +            ref = (SoftRef) m_queue.poll();
  +        }
  +    }
  +
  +    private void addStrongRef(Object object) {
  +        if (m_strongRefs != null) {
  +            m_strongRefs[(m_current++) % m_maxStrongRefCount] = object;
  +        }
  +    }
  +
  +    private void internalStoreObject(Object key, Object object) {
  +        SoftRef ref = makeValue(key, object, m_queue);
  +        addStrongRef(ref.get());
  +        m_map.put(key, ref);
  +    }
  +
  +  final  static class SoftRef extends SoftReference {
  +       private Object key;
  +
  +        private SoftRef(Object key, Object object, ReferenceQueue queue) {
  +            super(object, queue);
  +            this.key = key;
  +        }
  +    }
   }
  
  
  

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


Mime
View raw message