User: fleury  
  Date: 00/09/26 11:53:56

  Modified:    src/main/org/jboss/ejb/plugins
                        NoPassivationEntityInstanceCache.java
  Log:
  No more locking done outside.  Advanced cache algo such as Simone ones go here
  
  Revision  Changes    Path
  1.10      +166 -350  
jboss/src/main/org/jboss/ejb/plugins/NoPassivationEntityInstanceCache.java
  
  Index: NoPassivationEntityInstanceCache.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/NoPassivationEntityInstanceCache.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- NoPassivationEntityInstanceCache.java     2000/08/25 02:01:16     1.9
  +++ NoPassivationEntityInstanceCache.java     2000/09/26 18:53:55     1.10
  @@ -1,350 +1,166 @@
  -/*
  -* jBoss, the OpenSource EJB server
  -*
  -* Distributable under GPL license.
  -* See terms of license at gnu.org.
  -*/
  -package org.jboss.ejb.plugins;
  -
  -import java.rmi.RemoteException;
  -import java.rmi.ServerException;
  -import java.util.Map;
  -import java.util.HashMap;
  -import java.util.Stack;    
  -import java.util.LinkedList;
  -import java.util.Collections;
  -import java.util.Iterator;
  -
  -import javax.transaction.SystemException;
  -
  -import org.jboss.ejb.Container;
  -import org.jboss.ejb.EntityContainer;
  -import org.jboss.ejb.EntityInstanceCache;
  -import org.jboss.ejb.InstanceCache;
  -import org.jboss.ejb.InstancePool;
  -import org.jboss.ejb.InstancePoolContainer;
  -import org.jboss.ejb.EntityPersistenceManager;
  -import org.jboss.ejb.EnterpriseContext;
  -import org.jboss.ejb.EntityEnterpriseContext;
  -import org.jboss.util.FastKey;
  -import org.jboss.ejb.CacheKey;
  -
  -import org.jboss.metadata.EntityMetaData;
  -
  -/**
  -*    <description> 
  -*      
  -*    @see <related>
  -*    @author Rickard �berg ([EMAIL PROTECTED])
  -*   @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  -*   @author <a href="mailto:[EMAIL PROTECTED]">Andy Schaefer</a>
  -*    @version $Revision: 1.9 $
  -*/
  -public class NoPassivationEntityInstanceCache
  -implements EntityInstanceCache
  -{
  -    // Constants -----------------------------------------------------
  -    
  -    // Attributes ----------------------------------------------------
  -    Container con;
  -    
  -    Map cache = Collections.synchronizedMap(new HashMap());
  -    Map cacheKeys = Collections.synchronizedMap(new HashMap());
  -    boolean isReentrant;
  -    
  -    // Static --------------------------------------------------------
  -    
  -    // Constructors --------------------------------------------------
  -    
  -    // Public --------------------------------------------------------
  -    
  -    /**
  -    *   Set the callback to the container. This is for initialization.
  -    *   The IM may extract the configuration from the container.
  -    *
  -    * @param   c  
  -    */
  -    public void setContainer(Container c)
  -    {
  -        this.con = c;
  -    }
  -    
  -    public void init()
  -    throws Exception
  -    {
  -        isReentrant = ((EntityMetaData)con.getBeanMetaData()).isReentrant();
  -    }
  -    
  -    public void start()
  -    throws Exception
  -    {
  -    }
  -    
  -    public void stop()
  -    {
  -    }
  -    
  -    public void destroy()
  -    {
  -    }
  -    
  -    public Object createCacheKey( Object id ) {
  -             // If no fastkey then just return id
  -             // Here is where you supply the implementation of the cache you need
  -             // This could be done from configuration.
  -             
  -             return new FastKey( id );
  -     }
  -     
  -    /**
  -    *  get(Object CacheKey)
  -    * 
  -     *
  -    * MF FIXME: The synchronization is probably very f*cked up, someone needs to 
think
  -    * through the use cases of this puppy.  I know it is most probably broken as is.
  -    */
  -    
  -    public synchronized EnterpriseContext get(Object id)
  -    throws RemoteException
  -    {
  -        
  -        // Use the FastKey for the rest of the method
  -        CacheKey cacheKey = (CacheKey) id;
  -        
  -        // TODO: minimize synchronization of IM
  -        
  -        EntityEnterpriseContext ctx;
  -        InstanceInfo info = null;
  -        while ((ctx = (EntityEnterpriseContext)cache.get(cacheKey)) != null)
  -        {
  -            synchronized(ctx)
  -            {
  -                info = (InstanceInfo)ctx.getCacheContext();
  -                if (!info.isLocked())
  -                break;
  -                //DEBUG            Logger.log("Cache is waiting for 
"+id+"("+info.isLocked()+","+ctx.getTransaction()+")");
  -                
  -                // Check if same tx; reentrant call
  -                try                                          
  -                {
  -                    if (ctx.getTransaction() != null && 
ctx.getTransaction().equals(con.getTransactionManager().getTransaction()))
  -                    {
  -                        if (isReentrant)
  -                        {
  -                            break;
  -                        } else
  -                        {
  -                            // MF FIXME
  -                            // This is wrong but doing it right requires time
  -                            // The problem is that the entity EJB calls from an 
instance
  -                            // come back on the instance and in the presence of a 
  -                            // transaction it throws the exception....
  -                            // Since I suspect most people will use the EJBObject 
method calls before they set the reentrant right :)
  -                            // I would rather bypass the default for now. 
  -                            
  -                            //throw new RemoteException("Reentrant call not 
allowed");
  -                            break;
  -                        }
  -                    }
  -                } catch (SystemException e)
  -                {
  -                    throw new ServerException("Could not check for re-entrancy", e);
  -                }
  -                
  -                
  -                // Wait for previous tx to finish
  -                try 
  -                { 
  -                    ctx.wait(5000); 
  -                } catch (InterruptedException e) 
  -                { 
  -                    // Someone else is using this id right now
  -                    throw new ServerException("Time out",e); 
  -                }
  -            }
  -        }
  -        
  -        if (ctx == null) // Not in fast cache under that fastKey
  -        {
  -            //Maybe it is in the cache but under another cacheKey, check for the DB 
id
  -                     // Also if cache is virtual work from the id
  -            if (cacheKeys.containsKey(cacheKey.id) || cacheKey.isVirtual) {
  -                
  -                
  -                             // Ok, the instance is in Cache but under another 
cacheKey
  -                             
  -                // retrieve the List of Keys for that instance
  -                LinkedList keysList = (LinkedList) cacheKeys.get(cacheKey.id);
  -                
  -                // Get the context for the first one (they are all associated to 
that context)
  -                ctx = (EntityEnterpriseContext) cache.get(keysList.getFirst());
  -                
  -                             // Only if we have a real cache key, corresponding to 
the client
  -                             if (!cacheKey.isVirtual) {
  -                     // Add the fastkey to the List
  -                     keysList.addLast(cacheKey);
  -                     
  -                     // Store the context in the cache under the new cacheKey
  -                     cache.put(cacheKey, ctx);
  -                             }
  -                             
  -                // Redo the call the previous cache will work the synchronization
  -                return get(cacheKey);
  -            }
  -            
  -            // The instance is brand new and not known to the cache structures
  -            else {
  -                
  -                // Get new instance from pool
  -                ctx = 
(EntityEnterpriseContext)((InstancePoolContainer)con).getInstancePool().get();
  -                
  -                // The context only knows about the Database id
  -                ctx.setId(cacheKey.id);
  -                
  -                // Activate it
  -                ((EntityContainer)con).getPersistenceManager().activateEntity(ctx);
  -                
  -                // Initiate the fastKeys List for this Id
  -                //LinkedList keysList = (LinkedList) 
Collections.synchronizedList(new LinkedList());
  -                LinkedList keysList = new LinkedList();
  -                
  -                // Add this fastKey at least
  -                keysList.addLast(cacheKey);
  -                
  -                // Keep the list under the DB ID
  -                cacheKeys.put(cacheKey.id, keysList);
  -                
  -                             // Give the cacheKey to the context
  -                             ctx.setCacheKey(cacheKey);
  -                             
  -                // insert
  -                insert(ctx);
  -            }
  -        } else
  -        {
  -            // Lock the instance
  -            info.lock();
  -        }
  -        
  -        // At this point we own the instance with the given identity
  -        //      Logger.log("Got entity:"+ctx.getId());
  -             
  -             // Tell the context the key 
  -             ctx.setCacheKey(cacheKey);
  -             
  -        return ctx;
  -    }
  -    
  -     public synchronized void insert (EnterpriseContext ctx) {
  -             
  -             InstanceInfo info = createInstanceInfo(ctx);
  -        ((EntityEnterpriseContext)ctx).setCacheContext(info);
  -        info.lock();
  -        
  -        // Cache can know about the instance now
  -        cache.put(((EntityEnterpriseContext) ctx).getCacheKey(), ctx);
  -    
  -     }
  -     
  -    public void release(EnterpriseContext ctx)
  -    {
  -        // This context is now available for other threads
  -        synchronized(ctx)
  -        {
  -            
((InstanceInfo)((EntityEnterpriseContext)ctx).getCacheContext()).unlock();
  -            //         Logger.log("Release entity:"+ctx.getId());
  -            if 
(!((InstanceInfo)((EntityEnterpriseContext)ctx).getCacheContext()).isLocked())
  -                ctx.notifyAll();
  -        }
  -    }
  -    
  -    /*
  -     * This needs the id hash and equals to work
  -    *
  -    */
  -    public synchronized void remove(Object id)
  -    {
  -        // remote the List of keys from the ID map, it returns the list
  -        LinkedList list = (LinkedList) cacheKeys.remove(id);
  -        
  -        // If the cacheKey weren't used there is no link to a context
  -        if (list == null) return ;
  -            
  -        Iterator keysIterator = list.listIterator();
  -        
  -        // We need to remove all the associations that exists with the context
  -        Object ctx = null;
  -        
  -        while (keysIterator.hasNext()) {
  -            
  -            Object currentCacheKey = keysIterator.next();
  -            
  -            // remove the cacheKey from cache 
  -            ctx = cache.remove(currentCacheKey);
  -        }
  -        
  -        
  -        // We will need notification (MF FIXME actually not anymore imho)
  -        synchronized(ctx)
  -        {
  -            ctx.notifyAll();
  -        }
  -    }
  -    
  -    // Z implementation ----------------------------------------------
  -    
  -    // Package protected ---------------------------------------------
  -    
  -    // Protected -----------------------------------------------------
  -    protected InstanceInfo createInstanceInfo(EnterpriseContext ctx)
  -    {
  -        return new InstanceInfo(ctx);
  -    }
  -    
  -    // Private -------------------------------------------------------
  -    
  -    // Inner classes -------------------------------------------------
  -    class InstanceInfo
  -    {
  -        int locked = 0; // 0 == unlocked, >0 == locked
  -        
  -             CacheKey key ;
  -             
  -        EntityEnterpriseContext ctx;
  -        
  -        InstanceInfo(EnterpriseContext ctx)
  -        {
  -            this.ctx = (EntityEnterpriseContext)ctx;
  -        }
  -        
  -        public void lock()
  -        {
  -            locked++;
  -        }
  -        
  -        public void unlock()
  -        {
  -            locked--;
  -        }
  -        
  -        public boolean isLocked()
  -        {
  -            return locked > 0;
  -        }
  -        
  -        public EntityEnterpriseContext getContext()
  -        {
  -            return ctx;
  -        }
  -             
  -             public void setCacheKey(CacheKey key) {
  -                     
  -                     this.key = key;
  -     }
  -             
  -             public CacheKey getCacheKey() {
  -                     
  -                     return key;
  -             }
  -    }
  -}
  +/*
  +* jBoss, the OpenSource EJB server
  +*
  +* Distributable under GPL license.
  +* See terms of license at gnu.org.
  +*/
  +package org.jboss.ejb.plugins;
  +
  +import java.rmi.RemoteException;
  +import java.rmi.ServerException;
  +import java.util.Map;
  +import java.util.HashMap;
  +import java.util.Stack;    
  +import java.util.LinkedList;
  +import java.util.Collections;
  +import java.util.Iterator;
  +
  +import javax.transaction.SystemException;
  +
  +import org.jboss.ejb.Container;
  +import org.jboss.ejb.EntityContainer;
  +import org.jboss.ejb.EntityInstanceCache;
  +import org.jboss.ejb.InstanceCache;
  +import org.jboss.ejb.InstancePool;
  +import org.jboss.ejb.InstancePoolContainer;
  +import org.jboss.ejb.EntityPersistenceManager;
  +import org.jboss.ejb.EnterpriseContext;
  +import org.jboss.ejb.EntityEnterpriseContext;
  +import org.jboss.ejb.CacheKey;
  +
  +import org.jboss.metadata.EntityMetaData;
  +
  +/**
  +*    <description> 
  +*      
  +*    @see <related>
  +*    @author Rickard �berg ([EMAIL PROTECTED])
  +*   @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  +*   @author <a href="mailto:[EMAIL PROTECTED]">Andy Schaefer</a>
  +*    @version $Revision: 1.10 $
  +*/
  +public class NoPassivationEntityInstanceCache
  +implements EntityInstanceCache
  +{
  +    // Constants -----------------------------------------------------
  +    
  +    // Attributes ----------------------------------------------------
  +    Container con;
  +    
  +    Map cache = Collections.synchronizedMap(new HashMap());
  +    
  +    // Static --------------------------------------------------------
  +    
  +    // Constructors --------------------------------------------------
  +    
  +    // Public --------------------------------------------------------
  +    
  +    /**
  +    *   Set the callback to the container. This is for initialization.
  +    *   The IM may extract the configuration from the container.
  +    *
  +    * @param   c  
  +    */
  +    public void setContainer(Container c)
  +    {
  +        this.con = c;
  +    }
  +    
  +    public void init()
  +    throws Exception
  +    {
  +    }
  +    
  +    public void start()
  +    throws Exception
  +    {
  +    }
  +    
  +    public void stop()
  +    {
  +    }
  +    
  +    public void destroy()
  +    {
  +    }
  +    
  +    public Object createCacheKey( Object id ) {
  +       
  +       return new CacheKey( id );
  +    }
  +    
  +    /**
  +    *  get(Object CacheKey)
  +    * 
  +    * We base our lookups on the CacheKey. 
  +    */
  +    
  +    public synchronized EnterpriseContext get(Object id)
  +    throws RemoteException
  +    {
  +        
  +        // Use the CacheKey for the rest of the method
  +        CacheKey cacheKey = (CacheKey) id;
  +        
  +        EntityEnterpriseContext ctx;
  +      
  +       // Lookup the instance 
  +       ctx = (EntityEnterpriseContext)cache.get(cacheKey);
  +       
  +        if (ctx == null) // Not in fast cache under that cacheKey
  +        {
  +            
  +            // Get new instance from pool
  +            ctx = 
(EntityEnterpriseContext)((InstancePoolContainer)con).getInstancePool().get();
  +            
  +            // The context only knows about the Database id
  +            ctx.setId(cacheKey.id);
  +            
  +            // Activate it
  +            ((EntityContainer)con).getPersistenceManager().activateEntity(ctx);
  +              
  +            // insert
  +            cache.put(cacheKey, ctx);
  +        }
  +        
  +       
  +        // At this point we own the instance with the given identity
  +        
  +       // Tell the context the key 
  +       ctx.setCacheKey(cacheKey);
  +       
  +        // DEBUG Logger.log("Got entity:"+ctx.getId());
  +       
  +        return ctx;
  +    }
  +    
  +    public synchronized void insert (EnterpriseContext ctx) {
  +    
  +        // Cache can know about the instance now
  +        cache.put(((EntityEnterpriseContext) ctx).getCacheKey(), ctx);
  +    }
  +    
  +    /*
  +    * Remove works with the cachekey that the cache constructs.  Leakage will 
happen if the cache key 
  +    * doesn't consistently see 
  +    * m1 = new CacheKey(id); and 
  +    * m2 = new CacheKey(id);
  +    * as hashCode equals and equals.  The implementation of org.jboss.CacheKey 
behaves correctly
  +    *
  +    */
  +    public synchronized void remove(Object id)
  +    {
  +        // remove usually comes with the id of the db instance
  +        cache.remove(createCacheKey(id));                         
  +    }
  +    
  +    // Z implementation ----------------------------------------------
  +    
  +    // Package protected ---------------------------------------------
  +    
  +    // Protected -----------------------------------------------------
  +    
  +    // Private -------------------------------------------------------
  +    
  +    // Inner classes -------------------------------------------------
  +}
  
  
  

Reply via email to