[jboss-cvs] JBossCache/src/org/jboss/cache ...

Manik Surtani msurtani at jboss.com
Wed Nov 15 10:16:40 EST 2006


  User: msurtani
  Date: 06/11/15 10:16:40

  Modified:    src/org/jboss/cache     Region.java TreeCache.java
                        RegionImpl.java RegionManager.java
  Log:
  Updated to fix failures after patching up region managers
  
  Revision  Changes    Path
  1.7       +2 -2      JBossCache/src/org/jboss/cache/Region.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: Region.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/Region.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -b -r1.6 -r1.7
  --- Region.java	14 Nov 2006 14:17:11 -0000	1.6
  +++ Region.java	15 Nov 2006 15:16:40 -0000	1.7
  @@ -88,7 +88,7 @@
       * 
       * @see #unmarkNodeCurrentlyInUse(Fqn)
       */
  -   void markNodeCurrentlyInUse(long timeout);
  +   void markNodeCurrentlyInUse(Fqn fqn, long timeout);
   
      /**
       * Add an event to the eviction queue indicating that a node is no longer in use.
  @@ -97,7 +97,7 @@
       * 
       * @see #markNodeCurrentlyInUse(Fqn, long)
       */
  -   void unmarkNodeCurrentlyInUse();
  +   void unmarkNodeCurrentlyInUse(Fqn fqn);
   
      Fqn getFqn();
   }
  
  
  
  1.269     +327 -77   JBossCache/src/org/jboss/cache/TreeCache.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: TreeCache.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/TreeCache.java,v
  retrieving revision 1.268
  retrieving revision 1.269
  diff -u -b -r1.268 -r1.269
  --- TreeCache.java	14 Nov 2006 19:56:09 -0000	1.268
  +++ TreeCache.java	15 Nov 2006 15:16:40 -0000	1.269
  @@ -39,8 +39,8 @@
   import org.jboss.cache.notifications.Notifier;
   import org.jboss.cache.optimistic.DataVersion;
   import org.jboss.cache.statetransfer.StateTransferManager;
  -import org.jboss.util.stream.MarshalledValueInputStream;
   import org.jboss.util.stream.MarshalledValueOutputStream;
  +import org.jboss.util.stream.MarshalledValueInputStream;
   import org.jgroups.Address;
   import org.jgroups.Channel;
   import org.jgroups.ChannelClosedException;
  @@ -72,7 +72,6 @@
   import java.io.OutputStream;
   import java.lang.reflect.Method;
   import java.util.ArrayList;
  -import java.util.Arrays;
   import java.util.Collection;
   import java.util.Collections;
   import java.util.HashMap;
  @@ -83,6 +82,7 @@
   import java.util.Map;
   import java.util.Set;
   import java.util.Vector;
  +import java.util.Arrays;
   
   /**
    * A tree-like structure that is replicated across several members. Updates are
  @@ -94,7 +94,7 @@
    * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
    * @author Brian Stansberry
    * @author Daniel Huang (dhuang at jboss.org)
  - * @version $Id: TreeCache.java,v 1.268 2006/11/14 19:56:09 vblagojevic Exp $
  + * @version $Id: TreeCache.java,v 1.269 2006/11/15 15:16:40 msurtani Exp $
    *          <p/>
    * @see <a href="http://labs.jboss.com/portal/jbosscache/docs">JBossCache doc</a>
    */
  @@ -111,7 +111,7 @@
       */
      protected DataNode root = NodeFactory.getInstance().createRootDataNode(NodeFactory.NODE_TYPE_TREENODE, this);
   
  -   private RegionManager regionManager = null;
  +   private RegionManager regionManager = new RegionManager(this);
   
   
      final static Object NULL = new Object();
  @@ -156,8 +156,6 @@
       */
      private final Map lock_table = new ConcurrentHashMap();
   
  -   protected boolean usingEviction = false;
  -
      /**
       * Set<Fqn> of Fqns of the topmost node of internal regions that should
       * not included in standard state transfers.
  @@ -260,6 +258,12 @@
   
      private ThreadLocal<InvocationContext> invocationContextContainer = new ThreadLocal<InvocationContext>();
   
  +   /**
  +    * Set of Fqns of nodes that are currently being processed by
  +    * activateReqion or inactivateRegion.  Requests for these fqns
  +    * will be ignored by _getState().
  +    */
  +   protected final Set activationChangeNodes = Collections.synchronizedSet(new HashSet());
      public boolean started;
   
      public Configuration getConfiguration()
  @@ -288,7 +292,6 @@
      {
         notifier = new Notifier(this);
         this.configuration = configuration;
  -      regionManager = new RegionManager(this);
      }
   
      /**
  @@ -297,7 +300,6 @@
      public TreeCache() throws Exception
      {
         notifier = new Notifier(this);
  -      regionManager = new RegionManager(this);
      }
   
      /**
  @@ -307,7 +309,6 @@
      {
         notifier = new Notifier(this);
         this.channel = channel;
  -      regionManager = new RegionManager(this);
      }
   
      /**
  @@ -466,16 +467,6 @@
         return this.evictionInterceptorClass;
      }
   
  -   public boolean isUsingEviction()
  -   {
  -      return this.usingEviction;
  -   }
  -
  -   public void setIsUsingEviction(boolean usingEviction)
  -   {
  -      this.usingEviction = usingEviction;
  -   }
  -
      private void setUseReplQueue(boolean flag)
      {
         if (flag)
  @@ -918,13 +909,12 @@
         if (configuration.getEvictionConfig() != null
                 && configuration.getEvictionConfig().isValidConfig())
         {
  -         //evictionRegionManager_.configure(this);
  -         if (true) throw new RuntimeException("Fixme: configure the region manager for evictions");
  -         this.usingEviction = true;
  +         regionManager.setEvictionConfig(configuration.getEvictionConfig());
  +         regionManager.setUsingEvictions(true);
         }
         else
         {
  -         this.usingEviction = false;
  +         regionManager.setUsingEvictions(false);
            log.debug("Not using an EvictionPolicy");
         }
      }
  @@ -1012,6 +1002,133 @@
      }
   
      /**
  +    * Causes the cache to transfer state for the subtree rooted at
  +    * <code>subtreeFqn</code> and to begin accepting replication messages
  +    * for that subtree.
  +    * <p/>
  +    * <strong>NOTE:</strong> This method will cause the creation of a node
  +    * in the local tree at <code>subtreeFqn</code> whether or not that
  +    * node exists anywhere else in the cluster.  If the node does not exist
  +    * elsewhere, the local node will be empty.  The creation of this node will
  +    * not be replicated.
  +    *
  +    * @param subtreeFqn Fqn string indicating the uppermost node in the
  +    *                   portion of the tree that should be activated.
  +    * @throws RegionNotEmptyException if the node <code>subtreeFqn</code>
  +    *                                 exists and has either data or children
  +    */
  +   public void activateRegion(String subtreeFqn) throws RegionNameConflictException, CacheException
  +   {
  +      Fqn fqn = Fqn.fromString(subtreeFqn);
  +
  +      // Check whether the node already exists and has data
  +      DataNode subtreeRoot = findNode(fqn);
  +      if (!(isNodeEmpty(subtreeRoot)))
  +      {
  +         throw new RegionNotEmptyException("Node " + subtreeRoot.getFqn() + " already exists and is not empty");
  +      }
  +
  +      if (log.isDebugEnabled())
  +      {
  +         log.debug("activating " + fqn);
  +      }
  +
  +      try
  +      {
  +
  +         // Add this fqn to the set of those we are activating
  +         // so calls to _getState for the fqn can return quickly
  +         activationChangeNodes.add(fqn);
  +
  +         Region region = regionManager.getRegion(fqn, true);
  +
  +         // If a classloader is registered for the node's region, use it
  +         ClassLoader cl = region.getClassLoader();
  +
  +         // Request partial state from the cluster and integrate it
  +         if (buddyManager == null)
  +         {
  +            // Get the state from any node that has it and put it
  +            // in the main tree
  +            if (subtreeRoot == null)
  +            {
  +               // We'll update this node with the state we receive
  +               subtreeRoot = createSubtreeRootNode(fqn);
  +            }
  +
  +            Object[] mbrArray = getMembers().toArray();
  +            getStateTransferManager().loadState(subtreeRoot.getFqn(), subtreeRoot, mbrArray, cl);
  +         }
  +         else
  +         {
  +            // Get the state from each DataOwner and integrate in their
  +            // respective buddy backup tree
  +            List buddies = buddyManager.getBuddyAddresses();
  +            for (Iterator it = buddies.iterator(); it.hasNext();)
  +            {
  +               Address buddy = (Address) it.next();
  +               Object[] sources = {buddy};
  +               Fqn base = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, BuddyManager.getGroupNameFromAddress(buddy));
  +               Fqn buddyRoot = new Fqn(base, fqn);
  +               subtreeRoot = findNode(buddyRoot);
  +               if (subtreeRoot == null)
  +               {
  +                  // We'll update this node with the state we receive
  +                  subtreeRoot = createSubtreeRootNode(buddyRoot);
  +               }
  +               getStateTransferManager().loadState(fqn, subtreeRoot, sources, cl);
  +            }
  +         }
  +
  +         region.activate();
  +
  +      }
  +      catch (Throwable t)
  +      {
  +         log.error("failed to activate " + subtreeFqn, t);
  +
  +         // "Re-deactivate" the region
  +         try
  +         {
  +            inactivateRegion(subtreeFqn);
  +         }
  +         catch (Exception e)
  +         {
  +            log.error("failed inactivating " + subtreeFqn, e);
  +            // just swallow this one and throw the first one
  +         }
  +
  +         // Throw the exception on, wrapping if necessary
  +         if (t instanceof RegionNameConflictException)
  +         {
  +            throw(RegionNameConflictException) t;
  +         }
  +         else if (t instanceof RegionNotEmptyException)
  +         {
  +            throw(RegionNotEmptyException) t;
  +         }
  +         else if (t instanceof CacheException)
  +         {
  +            throw(CacheException) t;
  +         }
  +         else
  +         {
  +            throw new CacheException(t.getClass().getName() + " " +
  +                    t.getLocalizedMessage(), t);
  +         }
  +      }
  +      finally
  +      {
  +         activationChangeNodes.remove(fqn);
  +      }
  +   }
  +
  +   public boolean isActivatingDeactivating(Fqn fqn)
  +   {
  +      return activationChangeNodes.contains(fqn);
  +   }
  +
  +   /**
       * Returns whether the given node is empty; i.e. has no key/value pairs
       * in its data map and has no children.
       *
  @@ -1019,7 +1136,7 @@
       * @return <code>true</code> if <code>node</code> is <code>null</code> or
       *         empty; <code>false</code> otherwise.
       */
  -   protected boolean isNodeEmpty(DataNode node)
  +   private boolean isNodeEmpty(DataNode node)
      {
         boolean empty = true;
         if (node != null)
  @@ -1100,6 +1217,138 @@
      }
   
      /**
  +    * Causes the cache to stop accepting replication events for the subtree
  +    * rooted at <code>subtreeFqn</code> and evict all nodes in that subtree.
  +    *
  +    * @param subtreeFqn Fqn string indicating the uppermost node in the
  +    *                   portion of the tree that should be activated.
  +    * @throws RegionNameConflictException if <code>subtreeFqn</code> indicates
  +    *                                     a node that is part of another
  +    *                                     subtree that is being specially
  +    *                                     managed (either by activate/inactiveRegion()
  +    *                                     or by registerClassLoader())
  +    * @throws CacheException              if there is a problem evicting nodes
  +    * @throws IllegalStateException       if {@link Configuration#isUseRegionBasedMarshalling()} is <code>false</code>
  +    */
  +   public void inactivateRegion(String subtreeFqn) throws RegionNameConflictException, CacheException
  +   {
  +      if (!configuration.isUseRegionBasedMarshalling())
  +      {
  +         throw new IllegalStateException("TreeCache.deactivate(). useRegionBasedMarshalling flag is not set!");
  +      }
  +
  +      Fqn fqn = Fqn.fromString(subtreeFqn);
  +      DataNode parent = null;
  +      DataNode subtreeRoot = null;
  +      boolean parentLocked = false;
  +      boolean subtreeLocked = false;
  +      try
  +      {
  +         // Record that this fqn is in status change, so can't provide state
  +         activationChangeNodes.add(fqn);
  +
  +         boolean inactive = marshaller_.isInactive(subtreeFqn);
  +         if (!inactive)
  +         {
  +            regionManager.deactivate(subtreeFqn);
  +         }
  +
  +         // Create a list with the Fqn in the main tree and any buddy backup trees
  +         ArrayList list = new ArrayList();
  +         list.add(fqn);
  +         if (buddyManager != null)
  +         {
  +            Set buddies = getChildrenNames(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN);
  +            if (buddies != null)
  +            {
  +               for (Iterator it = buddies.iterator(); it.hasNext();)
  +               {
  +                  Fqn base = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, it.next());
  +                  list.add(new Fqn(base, fqn));
  +               }
  +            }
  +         }
  +
  +         // Remove the subtree from the main tree  and any buddy backup trees
  +         for (Iterator it = list.iterator(); it.hasNext();)
  +         {
  +            Fqn subtree = (Fqn) it.next();
  +            subtreeRoot = findNode(subtree);
  +            if (subtreeRoot != null)
  +            {
  +               // Acquire locks
  +               Object owner = getOwnerForLock();
  +               subtreeRoot.acquireAll(owner, stateFetchTimeout, DataNode.LockType.WRITE);
  +               subtreeLocked = true;
  +
  +               // Lock the parent, as we're about to write to it
  +               parent = (DataNode) subtreeRoot.getParent();
  +               if (parent != null)
  +               {
  +                  parent.acquire(owner, stateFetchTimeout, DataNode.LockType.WRITE);
  +                  parentLocked = true;
  +               }
  +
  +               // Remove the subtree
  +               _evictSubtree(subtree);
  +
  +               // Release locks
  +               if (parent != null)
  +               {
  +                  log.debug("forcing release of locks in parent");
  +                  parent.releaseAllForce();
  +               }
  +
  +               parentLocked = false;
  +
  +               log.debug("forcing release of all locks in subtree");
  +               subtreeRoot.releaseAllForce();
  +               subtreeLocked = false;
  +            }
  +         }
  +      }
  +      catch (InterruptedException ie)
  +      {
  +         throw new CacheException("Interrupted while acquiring lock", ie);
  +      }
  +      finally
  +      {
  +         // If we didn't succeed, undo the marshalling change
  +         // NO. Since we inactivated, we may have missed changes
  +         //if (!success && !inactive)
  +         //   marshaller_.activate(subtreeFqn);
  +
  +         // If necessary, release locks
  +         if (parentLocked)
  +         {
  +            log.debug("forcing release of locks in parent");
  +            try
  +            {
  +               parent.releaseAllForce();
  +            }
  +            catch (Throwable t)
  +            {
  +               log.error("failed releasing locks", t);
  +            }
  +         }
  +         if (subtreeLocked)
  +         {
  +            log.debug("forcing release of all locks in subtree");
  +            try
  +            {
  +               subtreeRoot.releaseAllForce();
  +            }
  +            catch (Throwable t)
  +            {
  +               log.error("failed releasing locks", t);
  +            }
  +         }
  +
  +         activationChangeNodes.remove(fqn);
  +      }
  +   }
  +
  +   /**
       * Evicts the node at <code>subtree</code> along with all descendant nodes.
       *
       * @param subtree Fqn indicating the uppermost node in the
  @@ -3367,14 +3616,19 @@
   
         public void setState(byte[] new_state)
         {
  +         try
  +         {
  +
            if (new_state == null)
            {
               my_log.debug("transferred state is null (may be first member in cluster)");
               return;
            }
  -         try
  +            else
            {
               getStateTransferManager().setState(new_state, Fqn.ROOT, null);
  +            }
  +
               isStateSet = true;
            }
            catch (Throwable t)
  @@ -3462,14 +3716,16 @@
   
         public void setState(InputStream istream)
         {
  +         try
  +         {
  +
            if (istream == null)
            {
               my_log.debug("stream is null (may be first member in cluster)");
               return;
            }
  -         try
  -         {           
               getStateTransferManager().setState(istream, Fqn.ROOT, null);           
  +
               isStateSet = true;
            }
            catch (Throwable t)
  @@ -3492,6 +3748,7 @@
                  stateLock.notifyAll();
               }
            }
  +
         }
   
         public void setState(String state_id, byte[] state)
  @@ -3902,13 +4159,6 @@
   
      public RegionManager getRegionManager()
      {
  -      if (regionManager == null)
  -      {
  -         synchronized (this)
  -         {
  -            if (regionManager == null) regionManager = new RegionManager(this);
  -         }
  -      }
         return regionManager;
      }
   
  
  
  
  1.9       +24 -10    JBossCache/src/org/jboss/cache/RegionImpl.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: RegionImpl.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/RegionImpl.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -b -r1.8 -r1.9
  --- RegionImpl.java	14 Nov 2006 19:56:09 -0000	1.8
  +++ RegionImpl.java	15 Nov 2006 15:16:40 -0000	1.9
  @@ -31,7 +31,7 @@
      BoundedLinkedQueue nodeEventQueue_;
      int checkCapacityCount = 0;
      int capacityWarnThreshold = 0;
  -   EvictionRegionConfig configuration;
  +   EvictionRegionConfig configuration = new EvictionRegionConfig();
      EvictionPolicy policy;
   
      /**
  @@ -72,13 +72,13 @@
   
      public void activate()
      {
  -         regionManager.activateRegion(fqn.toString());        
  +      regionManager.activate(fqn.toString());
            active = true;      
      }
   
      public void deactivate()
      {
  -      regionManager.inactivateRegion(fqn.toString());
  +      regionManager.deactivate(fqn.toString());
         active = false;
      }
   
  @@ -100,14 +100,14 @@
   
      // -------- eviction stuff -----
   
  -   public void markNodeCurrentlyInUse(long timeout)
  +   public void markNodeCurrentlyInUse(Fqn fqn, long timeout)
      {
         EvictedEventNode markUse = new EvictedEventNode(fqn, NodeEventType.MARK_IN_USE_EVENT);
         markUse.setInUseTimeout(timeout);
         putNodeEvent(markUse);
      }
   
  -   public void unmarkNodeCurrentlyInUse()
  +   public void unmarkNodeCurrentlyInUse(Fqn fqn)
      {
         EvictedEventNode markNoUse = new EvictedEventNode(fqn, NodeEventType.UNMARK_USE_EVENT);
         putNodeEvent(markNoUse);
  @@ -159,6 +159,7 @@
   
      public void putNodeEvent(EvictedEventNode event)
      {
  +      if (nodeEventQueue_ == null) createQueue();
         try
         {
            // Don't check capacity every time as this is an expensive operation for
  @@ -250,10 +251,23 @@
   
      public void setEvictionPolicy(EvictionPolicyConfig evictionPolicyConfig)
      {
  -      //To change body of implemented methods use File | Settings | File Templates.
  +      configuration.setEvictionPolicyConfig(evictionPolicyConfig);
  +      policy = createPolicy(evictionPolicyConfig.getEvictionPolicyClass());
      }
   
  -
  -
  -
  +   private EvictionPolicy createPolicy(String className)
  +   {
  +      try
  +      {
  +         if (log.isTraceEnabled()) log.trace("Instantiating " + className);         
  +         EvictionPolicy ep = (EvictionPolicy) Class.forName(className).newInstance();
  +         ep.configure(regionManager.treeCache);
  +         return ep;
  +      }
  +      catch (Exception e)
  +      {
  +         log.fatal("Unable to instantiate eviction policy class " + className, e);
  +         return null;
  +      }
  +   }
   }
  
  
  
  1.6       +73 -302   JBossCache/src/org/jboss/cache/RegionManager.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: RegionManager.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/RegionManager.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -b -r1.5 -r1.6
  --- RegionManager.java	14 Nov 2006 19:56:09 -0000	1.5
  +++ RegionManager.java	15 Nov 2006 15:16:40 -0000	1.6
  @@ -1,23 +1,19 @@
   package org.jboss.cache;
   
  +import org.apache.commons.logging.Log;
  +import org.apache.commons.logging.LogFactory;
  +import org.jboss.cache.buddyreplication.BuddyManager;
  +import org.jboss.cache.config.EvictionConfig;
  +import org.jboss.cache.config.EvictionRegionConfig;
  +import org.jboss.cache.config.ConfigurationException;
  +import org.jboss.cache.eviction.RegionNameConflictException;
  +
   import java.util.ArrayList;
   import java.util.Collections;
  -import java.util.HashSet;
  -import java.util.Iterator;
   import java.util.List;
   import java.util.Map;
  -import java.util.Set;
  -import java.util.Vector;
   import java.util.concurrent.ConcurrentHashMap;
   
  -import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogFactory;
  -import org.jboss.cache.buddyreplication.BuddyManager;
  -import org.jboss.cache.config.Configuration;
  -import org.jboss.cache.marshall.RegionNameConflictException;
  -import org.jboss.cache.marshall.VersionAwareMarshaller;
  -import org.jgroups.Address;
  -
   /**
    * Encapsulates the concept of a {@link Region}, and manages instances of such regions.
    *
  @@ -27,21 +23,35 @@
   public class RegionManager
   {
      /**
  +    * The default region used in XML configuration files when defining eviction policies.  Any
  +    * eviction settings bound under this 'default' Fqn is appplied to {@link org.jboss.cache.Fqn#ROOT} internally so
  +    * any region that is not explicitly defined comes under the settings defined for this default.
  +    */
  +   public static final Fqn DEFAULT_REGION = Fqn.fromString("/_default_");
  +   /**
       * A registry of regions that have been defined.
       */
      Map<Fqn, Region> regionsRegistry = new ConcurrentHashMap<Fqn, Region>();
      boolean defaultInactive;
      private Log log = LogFactory.getLog(RegionManager.class);
  +   TreeCache treeCache;
  +   private boolean usingEvictions;
  +   private EvictionConfig evictionConfig;
      
  -   protected final Set activationChangeNodes = Collections.synchronizedSet(new HashSet());
      
  -   TreeCache cache;
   
  -   public RegionManager(){}
  +   public RegionManager()
  +   {
  +   }
  +
  +   public boolean isUsingEvictions()
  +   {
  +      return usingEvictions;
  +   }
      
  -   public RegionManager(TreeCache cache)
  +   public RegionManager(TreeCache treeCache)
      {
  -      this.cache = cache;
  +      this.treeCache = treeCache;
      }
   
      public boolean isDefaultInactive()
  @@ -54,6 +64,8 @@
         this.defaultInactive = defaultInactive;
      }
   
  +
  +
      /**
       * Helper utility that checks for a classloader registered for the
       * given Fqn, and if found sets it as the TCCL. If the given Fqn is
  @@ -98,20 +110,29 @@
   
      public Region getRegion(Fqn fqn, boolean createIfAbsent)
      {
  +      Fqn fqnToUse = fqn;
  +      if (DEFAULT_REGION.equals(fqnToUse)) fqnToUse = Fqn.ROOT; 
         // first see if a region for this specific Fqn exists
  -      if (regionsRegistry.containsKey(fqn)) return regionsRegistry.get(fqn);
  +      if (regionsRegistry.containsKey(fqnToUse)) return regionsRegistry.get(fqnToUse);
   
         // if not, attempt to create one ...
         if (createIfAbsent)
         {
  -         Region r = new RegionImpl(fqn, this);
  -         regionsRegistry.put(fqn, r);
  +         Region r = new RegionImpl(fqnToUse, this);
  +         regionsRegistry.put(fqnToUse, r);
            return r;
         }
  +      else
  +      {
  +         // first test if the default region has been defined.  If not, and if eviction regions
  +         // are in use, throw an exception since it is required.
  +         if (isUsingEvictions() && !regionsRegistry.containsKey(Fqn.ROOT))
  +            throw new RuntimeException("No default eviction region defined!");
  +      }
   
         // else try and find a parent which has a defined region, may return null if nothing is defined.
         Region r = null;
  -      Fqn nextFqn = fqn;
  +      Fqn nextFqn = fqnToUse;
   
         while (r == null)
         {
  @@ -121,7 +142,6 @@
         }
   
         return r;
  -
      }
   
      /**
  @@ -224,282 +244,6 @@
      }
      
      /**
  -    * Causes the cache to transfer state for the subtree rooted at
  -    * <code>subtreeFqn</code> and to begin accepting replication messages
  -    * for that subtree.
  -    * <p/>
  -    * <strong>NOTE:</strong> This method will cause the creation of a node
  -    * in the local tree at <code>subtreeFqn</code> whether or not that
  -    * node exists anywhere else in the cluster.  If the node does not exist
  -    * elsewhere, the local node will be empty.  The creation of this node will
  -    * not be replicated.
  -    *
  -    * @param subtreeFqn Fqn string indicating the uppermost node in the
  -    *                   portion of the tree that should be activated.
  -    * @throws RegionNotEmptyException if the node <code>subtreeFqn</code>
  -    *                                 exists and has either data or children
  -    */
  -   public void activateRegion(String subtreeFqn) throws CacheException
  -   {
  -      Fqn fqn = Fqn.fromString(subtreeFqn);
  -
  -      // Check whether the node already exists and has data
  -      DataNode subtreeRoot = cache.findNode(fqn);
  -      if (!(cache.isNodeEmpty(subtreeRoot)))
  -      {
  -         throw new RegionNotEmptyException("Node " + subtreeRoot.getFqn() + " already exists and is not empty");
  -      }
  -
  -      if(isActivatingDeactivating(fqn))
  -      {
  -         throw new CacheException("Region " + subtreeRoot.getFqn() + " is already being activated/deactivated");
  -      }
  -      
  -      if (log.isDebugEnabled())
  -      {
  -         log.debug("activating " + fqn);
  -      }
  -
  -      try
  -      {
  -
  -         // Add this fqn to the set of those we are activating
  -         // so calls to _getState for the fqn can return quickly
  -         activationChangeNodes.add(fqn);
  -
  -         Region region = getRegion(fqn, true);
  -
  -         // If a classloader is registered for the node's region, use it
  -         ClassLoader cl = region.getClassLoader();
  -
  -         BuddyManager buddyManager = cache.getBuddyManager();
  -         // Request partial state from the cluster and integrate it
  -         if (buddyManager == null)
  -         {
  -            // Get the state from any node that has it and put it
  -            // in the main tree
  -            if (subtreeRoot == null)
  -            {
  -               // We'll update this node with the state we receive
  -               subtreeRoot = cache.createSubtreeRootNode(fqn);
  -            }
  -
  -            Address [] groupMembers = null;
  -            Vector<Address> members = cache.getMembers();
  -            synchronized (members)
  -            {
  -               groupMembers = members.toArray(new Address[members.size()]);
  -            }
  -            if (groupMembers.length < 2)
  -            {
  -               if (log.isDebugEnabled())
  -                  log.debug("No nodes able to give state");
  -            }
  -            else
  -            {
  -               cache.fetchPartialState(groupMembers, subtreeRoot.getFqn());
  -            }       
  -         }
  -         else
  -         {
  -            // Get the state from each DataOwner and integrate in their
  -            // respective buddy backup tree
  -            List buddies = buddyManager.getBuddyAddresses();
  -            for (Iterator it = buddies.iterator(); it.hasNext();)
  -            {
  -               Address buddy = (Address) it.next();
  -               Object sources[] = new Object[]{buddy};               
  -               Fqn base = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, BuddyManager.getGroupNameFromAddress(buddy));
  -               Fqn buddyRoot = new Fqn(base, fqn);
  -               subtreeRoot = cache.findNode(buddyRoot);
  -               if (subtreeRoot == null)
  -               {
  -                  // We'll update this node with the state we receive
  -                  subtreeRoot = cache.createSubtreeRootNode(buddyRoot);
  -               }
  -               cache.fetchPartialState(sources, subtreeRoot.getFqn());                
  -            }
  -         }        
  -      }
  -      catch (Throwable t)
  -      {
  -         log.error("failed to activate " + subtreeFqn, t);
  -
  -         // "Re-deactivate" the region
  -         try
  -         {
  -            inactivateRegion(subtreeFqn);
  -         }
  -         catch (Exception e)
  -         {
  -            log.error("failed inactivating " + subtreeFqn, e);
  -            // just swallow this one and throw the first one
  -         }
  -
  -         // Throw the exception on, wrapping if necessary         
  -         if (t instanceof RegionNotEmptyException)
  -         {
  -            throw(RegionNotEmptyException) t;
  -         }
  -         else if (t instanceof CacheException)
  -         {
  -            throw(CacheException) t;
  -         }
  -         else
  -         {
  -            throw new CacheException(t.getClass().getName() + " " +
  -                    t.getLocalizedMessage(), t);
  -         }
  -      }
  -      finally
  -      {
  -         activationChangeNodes.remove(fqn);
  -      }
  -   }
  -   
  -   /**
  -    * Causes the cache to stop accepting replication events for the subtree
  -    * rooted at <code>subtreeFqn</code> and evict all nodes in that subtree.
  -    *
  -    * @param subtreeFqn Fqn string indicating the uppermost node in the
  -    *                   portion of the tree that should be activated.
  -    * @throws RegionNameConflictException if <code>subtreeFqn</code> indicates
  -    *                                     a node that is part of another
  -    *                                     subtree that is being specially
  -    *                                     managed (either by activate/inactiveRegion()
  -    *                                     or by registerClassLoader())
  -    * @throws CacheException              if there is a problem evicting nodes
  -    * @throws IllegalStateException       if {@link Configuration#isUseRegionBasedMarshalling()} is <code>false</code>
  -    */
  -   public void inactivateRegion(String subtreeFqn) throws CacheException
  -   {     
  -      Fqn fqn = Fqn.fromString(subtreeFqn);
  -      DataNode parent = null;
  -      DataNode subtreeRoot = null;
  -      boolean parentLocked = false;
  -      boolean subtreeLocked = false;
  -      
  -      if(isActivatingDeactivating(fqn))
  -      {
  -         throw new CacheException("Region " + subtreeRoot.getFqn() + " is already being activated/deactivated");
  -      }
  -      
  -      try
  -      {
  -         // Record that this fqn is in status change, so can't provide state
  -         activationChangeNodes.add(fqn);
  -
  -         VersionAwareMarshaller marshaller = cache.getMarshaller();
  -         boolean inactive = marshaller.isInactive(subtreeFqn);
  -         if (!inactive)
  -         {
  -            deactivate(subtreeFqn);
  -         }
  -
  -         // Create a list with the Fqn in the main tree and any buddy backup trees
  -         BuddyManager buddyManager = cache.getBuddyManager();
  -         ArrayList list = new ArrayList();
  -         list.add(fqn);
  -         
  -         if (buddyManager != null)
  -         {
  -            Set buddies = cache.getChildrenNames(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN);
  -            if (buddies != null)
  -            {
  -               for (Iterator it = buddies.iterator(); it.hasNext();)
  -               {
  -                  Fqn base = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, it.next());
  -                  list.add(new Fqn(base, fqn));
  -               }
  -            }
  -         }
  -
  -         long stateFetchTimeout = cache.getConfiguration().getLockAcquisitionTimeout() + 5000;
  -         // Remove the subtree from the main tree  and any buddy backup trees
  -         for (Iterator it = list.iterator(); it.hasNext();)
  -         {
  -            Fqn subtree = (Fqn) it.next();
  -            subtreeRoot = cache.findNode(subtree);
  -            if (subtreeRoot != null)
  -            {
  -               // Acquire locks
  -               Object owner = cache.getOwnerForLock();
  -               subtreeRoot.acquireAll(owner, stateFetchTimeout, DataNode.LockType.WRITE);
  -               subtreeLocked = true;
  -
  -               // Lock the parent, as we're about to write to it
  -               parent = (DataNode) subtreeRoot.getParent();
  -               if (parent != null)
  -               {
  -                  parent.acquire(owner, stateFetchTimeout, DataNode.LockType.WRITE);
  -                  parentLocked = true;
  -               }
  -
  -               // Remove the subtree
  -               cache._evictSubtree(subtree);
  -
  -               // Release locks
  -               if (parent != null)
  -               {
  -                  log.debug("forcing release of locks in parent");
  -                  parent.releaseAllForce();
  -               }
  -
  -               parentLocked = false;
  -
  -               log.debug("forcing release of all locks in subtree");
  -               subtreeRoot.releaseAllForce();
  -               subtreeLocked = false;
  -            }
  -         }
  -      }
  -      catch (InterruptedException ie)
  -      {
  -         throw new CacheException("Interrupted while acquiring lock", ie);
  -      }
  -      finally
  -      {
  -         // If we didn't succeed, undo the marshalling change
  -         // NO. Since we inactivated, we may have missed changes
  -         //if (!success && !inactive)
  -         //   marshaller_.activate(subtreeFqn);
  -
  -         // If necessary, release locks
  -         if (parentLocked)
  -         {
  -            log.debug("forcing release of locks in parent");
  -            try
  -            {
  -               parent.releaseAllForce();
  -            }
  -            catch (Throwable t)
  -            {
  -               log.error("failed releasing locks", t);
  -            }
  -         }
  -         if (subtreeLocked)
  -         {
  -            log.debug("forcing release of all locks in subtree");
  -            try
  -            {
  -               subtreeRoot.releaseAllForce();
  -            }
  -            catch (Throwable t)
  -            {
  -               log.error("failed releasing locks", t);
  -            }
  -         }
  -
  -         activationChangeNodes.remove(fqn);
  -      }
  -   }
  -   
  -   public boolean isActivatingDeactivating(Fqn fqn)
  -   {
  -      return activationChangeNodes.contains(fqn);
  -   }
  -
  -   /**
       * Overloaded form of {@link #activate(Fqn)}
       *
       * @param fqn
  @@ -597,6 +341,33 @@
   
         return regions;
      }
  +
  +   public void setUsingEvictions(boolean usingEvictions)
  +   {
  +      this.usingEvictions = usingEvictions;
  +   }
  +
  +   public void setEvictionConfig(EvictionConfig evictionConfig)
  +   {
  +      this.evictionConfig = evictionConfig;
  +      boolean setDefault = false;
  +      // create regions for the regions defined in the evictionConfig.
  +      for (EvictionRegionConfig erc : evictionConfig.getEvictionRegionConfigs())
  +      {
  +         Fqn fqn = erc.getRegionFqn();
  +         if (log.isTraceEnabled()) log.trace("Creating eviction region " + fqn);
  +
  +         if (fqn.equals(DEFAULT_REGION))
  +         {
  +            if (setDefault) throw new ConfigurationException("A default region for evictions has already been set for this cache");
  +            if (log.isTraceEnabled()) log.trace("Applying settings for " + DEFAULT_REGION + " to Fqn.ROOT");
  +            fqn = Fqn.ROOT;
  +            setDefault = true;
  +         }
  +         Region r = getRegion(fqn, true);
  +         r.setEvictionPolicy(erc.getEvictionPolicyConfig());
  +      }      
  +   }
   }
   
   
  @@ -614,7 +385,7 @@
    * @author Ben Wang 02-2004
    * @author Daniel Huang (dhuang at jboss.org)
    * @author Brian Stansberry
  - * @version $Id: RegionManager.java,v 1.5 2006/11/14 19:56:09 vblagojevic Exp $
  + * @version $Id: RegionManager.java,v 1.6 2006/11/15 15:16:40 msurtani Exp $
    */
   /*public class ERegionManager
   {
  
  
  



More information about the jboss-cvs-commits mailing list