Dan


please add yourself as author and start putting the "log: danch : useSoft
ref bla bla bla" in the body of the source.

marcf

|-----Original Message-----
|From: [EMAIL PROTECTED]
|[mailto:[EMAIL PROTECTED]]On Behalf Of
|[EMAIL PROTECTED]
|Sent: Monday, June 18, 2001 10:34 AM
|To: [EMAIL PROTECTED]
|Subject: [JBoss-dev] CVS update:
|jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc JDBCCommand.java
|JDBCCommandFactory.java JDBCFindByCommand.java
|JDBCFindEntitiesCommand.java
|
|
|  User: danch
|  Date: 01/06/18 07:34:27
|
|  Modified:    src/main/org/jboss/ejb/plugins/jaws/jdbc JDBCCommand.java
|                        JDBCCommandFactory.java JDBCFindByCommand.java
|                        JDBCFindEntitiesCommand.java
|  Log:
|  Use SoftReferences for the preloaded data; also, patch #418196
|(creating finders of nested CMP-fields)
|
|  Revision  Changes    Path
|  1.33      +2 -2
|jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCCommand.java
|
|  Index: JDBCCommand.java
|  ===================================================================
|  RCS file:
|/cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCC
|ommand.java,v
|  retrieving revision 1.32
|  retrieving revision 1.33
|  diff -u -r1.32 -r1.33
|  --- JDBCCommand.java 2001/06/06 01:07:40     1.32
|  +++ JDBCCommand.java 2001/06/18 14:34:27     1.33
|  @@ -57,7 +57,7 @@
|    *
|    * @author <a href="mailto:[EMAIL PROTECTED]";>Justin Forder</a>
|    * @author <a href="mailto:[EMAIL PROTECTED]";>Dirk Zimmermann</a>
|  - * @version $Revision: 1.32 $
|  + * @version $Revision: 1.33 $
|    */
|   public abstract class JDBCCommand
|   {
|  @@ -386,7 +386,7 @@
|       protected Object getResultObject(ResultSet rs, int idx,
|Class destination)
|           throws SQLException{
|
|  -log.debug("getting a "+destination.getName()+" from resultset
|at index "+idx);
|  +// log.debug("getting a "+destination.getName()+" from
|resultset at index "+idx);
|           Object result = null;
|
|           Method method = (Method)rsTypes.get(destination.getName());
|
|
|
|  1.10      +142 -58
|jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCCommandFactory.java
|
|  Index: JDBCCommandFactory.java
|  ===================================================================
|  RCS file:
|/cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCC
|ommandFactory.java,v
|  retrieving revision 1.9
|  retrieving revision 1.10
|  diff -u -r1.9 -r1.10
|  --- JDBCCommandFactory.java  2001/06/13 06:52:17     1.9
|  +++ JDBCCommandFactory.java  2001/06/18 14:34:27     1.10
|  @@ -8,11 +8,15 @@
|   package org.jboss.ejb.plugins.jaws.jdbc;
|
|   import java.lang.reflect.Method;
|  +import java.lang.ref.SoftReference;
|  +import java.lang.ref.WeakReference;
|  +import java.lang.ref.ReferenceQueue;
|   import java.util.Map;
|   import java.util.HashMap;
|   import java.util.List;
|   import java.util.LinkedList;
|   import java.util.Iterator;
|  +import java.util.WeakHashMap;
|
|   import javax.naming.Context;
|   import javax.naming.InitialContext;
|  @@ -46,13 +50,25 @@
|
|   import org.jboss.logging.Log;
|   import org.jboss.util.FinderResults;
|  +import org.jboss.util.TimerTask;
|  +import org.jboss.util.TimerQueue;
|
|   /**
|  - * JAWSPersistenceManager JDBCCommandFactory
|  + * Command factory for the JAWS JDBC layer. This class is
|primarily responsible
|  + * for creating instances of the JDBC implementations for the
|various JPM
|  + * commands so that the JAWSPersistenceManager (actually an
|persistence store)
|  + * can delegate to them in a decoupled manner.
|  + * <p>This class also acts as the manager for the read-ahead
|buffer added in
|  + * version 2.3/2.4. In order to manage this buffer, it must
|register itself
|  + * with any transaction that is active when a finder is called
|so that the
|  + * data that was read ahead can be discarded before completion of the
|  + * transaction. The read ahead buffer is managed using Soft
|references, with
|  + * a ReferenceQueue being used to tell when the VM has garbage
|collected an
|  + * object so that we can keep the hashtables clean.
|    *
|    * @author <a href="mailto:[EMAIL PROTECTED]";>Justin Forder</a>
|    * @author <a href="[EMAIL PROTECTED]">danch (Dan Christopherson</a>
|  - * @version $Revision: 1.9 $
|  + * @version $Revision: 1.10 $
|    */
|   public class JDBCCommandFactory implements JPMCommandFactory
|   {
|  @@ -63,7 +79,15 @@
|      private JawsEntityMetaData metadata;
|      private Log log;
|      private boolean debug = false;
|  +
|  +   /** Timer queue used to time polls on the preloadRefQueue on
|all JAWS
|  +    *  handled entities
|  +    */
|  +   private static TimerQueue softRefHandler;
|
|  +   /** Timer queue used to get references to preload data
|who've been GC'ed */
|  +   private ReferenceQueue preloadRefQueue = new ReferenceQueue();
|  +
|      /** a map of data preloaded within some transaction for some
|entity. This map
|       *  is keyed by Transaction and the data are hashmaps with
|key = entityKey and
|       *  data = Object[] containing the entity data.
|  @@ -81,7 +105,13 @@
|      // These support singletons (within the scope of this factory)
|      private JDBCBeanExistsCommand beanExistsCommand;
|      private JPMFindEntitiesCommand findEntitiesCommand;
|  -
|  +
|  +   //static initializer to kick off our softRefhandler
|  +   static {
|  +      softRefHandler = new TimerQueue("JAWS Preload reference handler");
|  +      softRefHandler.start();
|  +   }
|  +
|      // Constructors --------------------------------------------------
|
|      public JDBCCommandFactory(EntityContainer container,
|  @@ -93,24 +123,26 @@
|
|         this.javaCtx = (Context)new
|InitialContext().lookup("java:comp/env");
|
|  -      String ejbName = container.getBeanMetaData().getEjbName();
|  -      ApplicationMetaData amd =
|container.getBeanMetaData().getApplicationMetaData();
|  -      JawsApplicationMetaData jamd =
|(JawsApplicationMetaData)amd.getPluginData("JAWS");
|  -
|  -      if (jamd == null) {
|  -         // we are the first cmp entity to need jaws. Load
|jaws.xml for the whole application
|  -             JawsXmlFileLoader jfl = new JawsXmlFileLoader(amd,
|container.getClassLoader(), container.getLocalClassLoader(), log);
|  -       jamd = jfl.load();
|  -             amd.addPluginData("JAWS", jamd);
|  -      }
|  -     debug = jamd.getDebug();
|  -
|  -      metadata = jamd.getBeanByEjbName(ejbName);
|  -      if (metadata == null) {
|  -              throw new DeploymentException("No metadata found
|for bean " + ejbName);
|  -      }
|  +      String ejbName = container.getBeanMetaData().getEjbName();
|  +      ApplicationMetaData amd =
|container.getBeanMetaData().getApplicationMetaData();
|  +      JawsApplicationMetaData jamd =
|(JawsApplicationMetaData)amd.getPluginData("JAWS");
|  +
|  +      if (jamd == null) {
|  +         // we are the first cmp entity to need jaws. Load
|jaws.xml for the whole application
|  +         JawsXmlFileLoader jfl = new JawsXmlFileLoader(amd,
|container.getClassLoader(), container.getLocalClassLoader(), log);
|  +         jamd = jfl.load();
|  +         amd.addPluginData("JAWS", jamd);
|  +      }
|  +      debug = jamd.getDebug();
|  +
|  +      metadata = jamd.getBeanByEjbName(ejbName);
|  +      if (metadata == null) {
|  +         throw new DeploymentException("No metadata found for
|bean " + ejbName);
|  +      }
|  +
|  +      tm = (TransactionManager) container.getTransactionManager();
|
|  -     tm = (TransactionManager) container.getTransactionManager();
|  +      softRefHandler.schedule(new PreloadRefQueueHandlerTask(), 50);
|      }
|
|      // Public --------------------------------------------------------
|  @@ -262,10 +294,10 @@
|         try {
|            trans = tm.getTransaction();
|         } catch (javax.transaction.SystemException sysE) {
|  -         log.warning("System exception getting transaction for
|preload - can't get preloaded data for "+entityKey);
|  +         log.warning("System exception getting transaction for
|preload - can't preload data for "+entityKey);
|            return;
|         }
|  -//log.debug("PRELOAD: adding preload for "+entityKey+" in
|transaction "+(trans != null ? trans.toString() : "NONE"));
|  +//log.debug("PRELOAD: adding preload for "+entityKey+" in
|transaction "+(trans != null ? trans.toString() : "NONE")+"
|entityData="+entityData);
|
|         if (trans != null) {
|            synchronized (preloadedData) {
|  @@ -283,11 +315,13 @@
|                  entitiesInTransaction = new HashMap();
|                  preloadedData.put(trans, entitiesInTransaction);
|               }
|  -            entitiesInTransaction.put(entityKey, entityData);
|  +            PreloadData preloadData = new PreloadData(trans,
|entityKey, entityData, preloadRefQueue);
|  +            entitiesInTransaction.put(entityKey, preloadData);
|            }
|         } else {
|            synchronized (nonTransactionalPreloadData) {
|  -            nonTransactionalPreloadData.put(entityKey, entityData);
|  +            PreloadData preloadData = new PreloadData(null,
|entityKey, entityData, preloadRefQueue);
|  +            nonTransactionalPreloadData.put(entityKey, preloadData);
|            }
|         }
|      }
|  @@ -306,19 +340,36 @@
|         }
|
|         Object[] result = null;
|  +      PreloadData preloadData = null;
|         if (trans != null) {
|  -         synchronized (preloadedData) {
|  -            Map entitiesInTransaction = (Map)preloadedData.get(trans);
|  -            if (entitiesInTransaction != null)
|  -               result = (Object[])entitiesInTransaction.get(entityKey);
|  -            //remove it now?
|  +         Map entitiesInTransaction = null;
|  +         // Do we really need this to be syncrhonized? What is
|the effect of
|  +         //    another thread trying to modify this map? It
|won't be to remove
|  +         //    our transaction (we're in it here!, trying to
|call a business
|  +         //    method), and who cares if another is added/removed?
|  +//         synchronized (preloadedData) {
|  +            entitiesInTransaction = (Map)preloadedData.get(trans);
|  +//         }
|  +         if (entitiesInTransaction != null) {
|  +            synchronized (entitiesInTransaction) {
|  +               preloadData =
|(PreloadData)entitiesInTransaction.get(entityKey);
|  +               entitiesInTransaction.remove(entityKey);
|  +            }
|            }
|         } else {
|            synchronized (nonTransactionalPreloadData) {
|  -            result =
|(Object[])nonTransactionalPreloadData.get(entityKey);
|  +            preloadData =
|(PreloadData)nonTransactionalPreloadData.get(entityKey);
|  +            nonTransactionalPreloadData.remove(entityKey);
|            }
|         }
|  -//log.debug("PRELOAD: returning "+result+" as preload for "+entityKey);
|  +      if (preloadData != null) {
|  +         result = preloadData.getData();
|  +      } /*else {
|  +         log.debug("PRELOAD: preloadData == null for "+entityKey);
|  +      }
|  +if (result == null)
|  +   log.debug("PRELOAD: returning null as preload for "+entityKey);
|  +   */
|         return result;
|      }
|
|  @@ -333,38 +384,71 @@
|
|
|      // Private -------------------------------------------------------
|  -   /** an inner class used to key the FinderResults by their
|finder method and
|  -    *  the transaction they're invoked within
|  +
|  +   /** Inner class that handles our reference queue. I didn't
|think this would
|  +    *  be neccessary, but for some reason the VM won't call an
|override of
|  +    *  Reference.clear()
|  +   */
|  +   private class PreloadRefQueueHandlerTask extends TimerTask {
|  +    public void execute() throws Exception {
|  +         PreloadData preloadData = (PreloadData)preloadRefQueue.poll();
|  +         int handled = 0;
|  +         while (preloadData != null && handled < 10) {
|  +            log.debug("PRELOAD: clearing "+preloadData.getKey());
|  +            if (preloadData.getTransaction() != null) {
|  +               Map entitiesInTransaction = null;
|  +               // Do we really need this to be syncrhonized?
|What is the effect of
|  +               //    another thread trying to modify this map?
|It won't be to remove
|  +               //    our transaction (we're in it here!, trying
|to call a business
|  +               //    method), and who cares if another is added/removed?
|  +      //         synchronized (preloadedData) {
|  +                  entitiesInTransaction =
|(Map)preloadedData.get(preloadData.getTransaction());
|  +      //         }
|  +               if (entitiesInTransaction != null) {
|  +                  synchronized (entitiesInTransaction) {
|  +                     entitiesInTransaction.remove(preloadData.getKey());
|  +                  }
|  +               }
|  +            } else {
|  +               synchronized (nonTransactionalPreloadData) {
|  +
|nonTransactionalPreloadData.remove(preloadData.getKey());
|  +               }
|  +            }
|  +            preloadData.empty();
|  +            handled++;
|  +
|  +            preloadData = (PreloadData)preloadRefQueue.poll();
|  +         }
|  +      }
|  +   }
|  +   /** Inner class used in the preload Data hashmaps so that we
|can wrap a
|  +    *  SoftReference around the data and still have enough
|information to remove
|  +    *  the reference from the appropriate hashMap.
|       */
|  -   private static class PreloadDataKey {
|  -      private Object entityKey;
|  -      private Transaction transaction;
|  -
|  -      private int hashCode;
|  +   private class PreloadData extends SoftReference {
|  +      private Object key;
|  +      private Transaction trans;
|
|  -      public PreloadDataKey(Object entityKey, Transaction transaction) {
|  -         this.entityKey = entityKey;
|  -         this.transaction = transaction;
|  -
|  -         //accumulate the hashcode.
|  -         /** @todo investigate ways of combining these that
|will give the least collisions */
|  -         this.hashCode = entityKey.hashCode();
|  -         if (transaction != null)
|  -            this.hashCode += transaction.hashCode();
|  +      PreloadData(Transaction trans, Object key, Object[] data,
|ReferenceQueue queue) {
|  +         super(data, queue);
|  +         this.trans = trans;
|  +         this.key = key;
|         }
|
|  -      public int hashCode() {
|  -         return hashCode;
|  +      Transaction getTransaction() {
|  +         return trans;
|         }
|  -      public boolean equals(Object o) {
|  -         if (o instanceof PreloadDataKey) {
|  -            PreloadDataKey other = (PreloadDataKey)o;
|  -            return (other.entityKey.equals(this.entityKey)) &&
|  -                   ( (other.transaction == null &&
|this.transaction == null) ||
|  -                     ( (other.transaction != null &&
|this.transaction != null) &&
|  -                       (other.transaction.equals(this.transaction)) ) );
|  -         }
|  -         return false;
|  +      Object getKey() {
|  +         return key;
|  +      }
|  +      Object[] getData() {
|  +         return (Object[])get();
|  +      }
|  +
|  +      /** Named empty to not collide with superclass clear */
|  +      public void empty() {
|  +         key = null;
|  +         trans = null;
|         }
|      }
|
|
|
|
|  1.10      +5 -2
|jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCFindByCommand.java
|
|  Index: JDBCFindByCommand.java
|  ===================================================================
|  RCS file:
|/cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCF
|indByCommand.java,v
|  retrieving revision 1.9
|  retrieving revision 1.10
|  diff -u -r1.9 -r1.10
|  --- JDBCFindByCommand.java   2001/06/13 06:52:17     1.9
|  +++ JDBCFindByCommand.java   2001/06/18 14:34:27     1.10
|  @@ -27,7 +27,8 @@
|    * @author <a href="mailto:[EMAIL PROTECTED]";>Joe Shevland</a>
|    * @author <a href="mailto:[EMAIL PROTECTED]";>Justin Forder</a>
|    * @author <a href="mailto:[EMAIL PROTECTED]";>danch (Dan
|Christopherson)</a>
|  - * @version $Revision: 1.9 $
|  + * @author <a href="mailto:[EMAIL PROTECTED]";>Torben J�ger</a>
|  + * @version $Revision: 1.10 $
|    */
|   public class JDBCFindByCommand extends JDBCFinderCommand
|   {
|  @@ -55,7 +56,9 @@
|         {
|            CMPFieldMetaData fi = (CMPFieldMetaData)iter.next();
|
|  -         if (cmpFieldName.equals(fi.getName().toLowerCase()))
|  +         String lastComponentOfName =
|  +
|CMPFieldMetaData.getLastComponent(fi.getName()).toLowerCase();
|  +         if (cmpFieldName.equals(lastComponentOfName))
|            {
|               cmpField = fi;
|            }
|
|
|
|  1.10      +3 -2
|jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCFindEntitiesCommand.java
|
|  Index: JDBCFindEntitiesCommand.java
|  ===================================================================
|  RCS file:
|/cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCF
|indEntitiesCommand.java,v
|  retrieving revision 1.9
|  retrieving revision 1.10
|  diff -u -r1.9 -r1.10
|  --- JDBCFindEntitiesCommand.java     2001/05/27 00:49:15     1.9
|  +++ JDBCFindEntitiesCommand.java     2001/06/18 14:34:27     1.10
|  @@ -33,7 +33,7 @@
|    * @author <a href="mailto:[EMAIL PROTECTED]";>Marc Fleury</a>
|    * @author <a href="mailto:[EMAIL PROTECTED]";>Joe Shevland</a>
|    * @author <a href="mailto:[EMAIL PROTECTED]";>Justin Forder</a>
|  - * @version $Revision: 1.9 $
|  + * @version $Revision: 1.10 $
|    */
|   public class JDBCFindEntitiesCommand implements JPMFindEntitiesCommand
|   {
|  @@ -74,7 +74,8 @@
|                        }
|                 }
|         } catch (Exception e) {
|  -            // for some reason, this failed; try to use defined
|or automatic instead
|  +        // for some reason, this failed; try to use defined or
|automatic instead
|  +        factory.getLog().warning("Error initializing custom
|finder "+e.getMessage());
|         }
|
|         // Make commands for the defined finders
|
|
|
|
|_______________________________________________
|Jboss-development mailing list
|[EMAIL PROTECTED]
|http://lists.sourceforge.net/lists/listinfo/jboss-development



_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to